2012-04-17 14 views
2

OpenSSL APIを使用してSSLハンドシェイクを行うためのクライアントコードとサーバーコードを記述しようとしています。openSSL:ハンドシェイク失敗 - サーバーがクライアント証明書を取得できない

クライアントコードが含まれています

// Part of client code: 
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); 
SSL_CTX_load_verify_locations(ctx,"ca.pem",NULL); 
... 
if (SSL_CTX_use_certificate_file(ctx, "cli.crt" , SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
    } 

    if (SSL_CTX_use_PrivateKey_file(ctx, "cli.key", SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
    } 
... 
sd = socket (AF_INET, SOCK_STREAM, 0); 
sa.sin_family  = AF_INET; 
sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); 
sa.sin_port  = htons (44444); 
... 
ssl = SSL_new (ctx);    
SSL_set_fd (ssl, sd); 
err = SSL_connect (ssl); 

サーバーコードが含まれています

// Part of server code: 
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); 
SSL_CTX_load_verify_locations(ctx,"ca.pem",NULL); 
... 
if (SSL_CTX_use_certificate_file(ctx, "serv.crt", SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
} 
if (SSL_CTX_use_PrivateKey_file(ctx, "serv.key", SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
    } 
... 
listen_sd = socket (AF_INET, SOCK_STREAM, 0); 
memset (&sa_serv, '\0', sizeof(sa_serv)); 
sa_serv.sin_family  = AF_INET; 
sa_serv.sin_addr.s_addr = INADDR_ANY; 
sa_serv.sin_port  = htons (44444); 

err = bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv));       
err = listen (listen_sd, 5);  
client_len = sizeof(sa_cli); 
sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); 
close (listen_sd); 
.... 
ssl = SSL_new (ctx);       
SSL_set_fd (ssl, sd); 
err = SSL_accept (ssl); 

コードからわかるように、私は、ループバックアドレス(127.0.0.1)と宛先アドレスを使用してコードを実行しました上に示しました。同じマシン上で実行されたクライアントプログラムとサーバープログラムは正常に動作しました。

しかし、別のマシン(VMWare VM - Ubuntu Linux)でクライアントとサーバープログラムを実行すると、コードは失敗します。クライアントコードでアドレスとして、サーバのIP VM(例えば192.168.181.180)を使用して

Client VM IP:192.168.181.188 
Server VM IP:192.168.181.180 

、私は、サーバーで次のエラーを取得する:私は私のLinuxマシン上で自分自身のCAを作成している

140890B2: SSL3_GET_CLIENT_CERTIFICATE:no certificate returned: s3_srvr.c:2602: 

CA公開鍵ファイルをクライアントVMとサーバVMの両方と共有しました。クライアントとサーバーの証明書は、このCAによって署名されています。

CA : CA123 
Client CN: Client (signed by CA123) 
Server CN: Server (signed by CA123) 

クライアントが(私もサーバー証明書を取得し、CNは、「サーバ」確かに確認することができます)が、サーバーがクライアント証明書を取得することはできませんので、ハンドシェイクが失敗したサーバー証明書を確認することができます。

誰でもこの問題の解決策を提案できますか?

ありがとうございます。

答えて

0

クライアント証明書のsubjectを確認してください。 CN(共通名)フィールドには、クライアントホストのIPまたはホスト名が必要な場合があります。

Subject: C=xxx, ST=xxx, L=xxx, O=xxx, OU=xxx, CN=192.168.181.180 

私はこの修正プログラムがわからない100%午前:あなたのケースでは

は、クライアント証明書では、次の内容を持つことができます。しかし、壁を壊す前にそれを試してみてください。

+0

私は、IPではなく、CNをチェックしました。自分のLinuxマシンに自分のCAを作成し、そのCAでサーバー証明書とクライアント証明書に署名しました。クライアントCNは「クライアント」であり、サーバCNは「サーバ」である。 CAは「CA123」です。 – Jake

0

わかりました。以下は完全な解決策であり、私の現在のプロジェクトで見つかったばかりの解決策であるとは確信できません。私はまだ私の答えに満足していません。

私の質問を読んで、あなたはCAがLinuxマシン上で作られ、クライアントとサーバーの証明書がそのCAによって署名されたことに気づくでしょう。そのホストは別のVMWare VMです。これを "VM3"と呼びます。したがって、クライアントとサーバ用の「VM3」の「CA123」を使用して生成した証明書は、クライアントVM(「VM1」と呼ぶ)とサーバVM(「VM2」と呼ぶ)では動作しませんでした。私は、好奇心のためにVM2でCAをセットアップし、クライアント証明書とサーバー証明書に署名し、クライアント証明書をクライアントVMにコピーしようとしました。驚いたことに、それは動作しますが、私は理由を知らない。 VM3でどのような依存関係を作成したのですか?

もっと正確で完全な回答を自由に投稿してください。

+0

あなたは最終的にそれを理解しましたか?私はおそらくCAと証明書を生成するコマンドラインが重要だと思います。投稿してください。 – tedyyu

関連する問題