2

I am trying to write client and server code to do SSL handshake using openSSL API.

Client code contains:

 // 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); 

Server code contains:

 // 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);   

I ran the code using destination address as loop back address (127.0.0.1), as can be seen from the code shown above. The client and server programs executed on same machine worked fine.

But, when I run the client and server programs on different machines (VMWare VMs - Ubuntu Linux), the code fails.

 Client VM IP:192.168.181.188
 Server VM IP:192.168.181.180

Using the IP of server VM (e.g. 192.168.181.180) as address in client code, I get the following error at server:

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

I have created my own CA on my Linux machine and shared the CA public key file with both client and server VMs. The client and server certificates are signed by this CA.

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

The client is able to verify server certificate (I can even get server certificate and check CN is indeed 'Server'), but server can't get client certificate,so handshake fails.

Can anyone suggest a solution to this problem?

Thanks a lot.

4

2 に答える 2

0

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

あなたの場合、クライアント証明書には次の件名が含まれる可能性があります。

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

この修正について100%確信はありません。しかし、壁を壊す前に、それを試してみてください。

于 2012-04-17T10:57:34.703 に答える
0

わかりました...以下が完全な解決策であるかどうかはわかりません。現在のプロジェクトで見つかった修正にすぎません。まだ答えに満足していません。

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

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

于 2012-04-17T20:21:30.213 に答える