C openSSL:握手失败-服务器无法获取客户端证书

C openSSL:握手失败-服务器无法获取客户端证书,c,linux,openssl,vmware,public-key-encryption,C,Linux,Openssl,Vmware,Public Key Encryption,我正在尝试编写客户端和服务器代码,以使用openSSL API进行SSL握手 客户端代码包含: // 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) <=

我正在尝试编写客户端和服务器代码,以使用openSSL API进行SSL握手

客户端代码包含:

 // 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);   
使用服务器VM的IP(例如192.168.181.180)作为客户端代码中的地址,我在服务器上得到以下错误:

 140890B2: SSL3_GET_CLIENT_CERTIFICATE:no certificate returned: s3_srvr.c:2602:
我在Linux机器上创建了自己的CA,并与客户机和服务器VM共享了CA公钥文件。客户端和服务器证书由此CA签名

 CA : CA123
 Client CN: Client (signed by CA123)
 Server CN: Server (signed by CA123)
客户端能够验证服务器证书,我甚至可以获取服务器证书,并检查CN是否确实是“服务器”,但服务器无法获取客户端证书,因此握手失败

有人能提出解决这个问题的办法吗

非常感谢。

检查客户证书的主题。有时,CN common name字段应该具有客户端主机的IP或主机名

在您的情况下,客户端证书可能具有以下主题:

Subject: C=xxx, ST=xxx, L=xxx, O=xxx, OU=xxx, CN=192.168.181.180
我不是100%确定这个修复。但是在打破这堵墙之前,试一下

检查客户端证书的主题。有时,CN common name字段应该具有客户端主机的IP或主机名

在您的情况下,客户端证书可能具有以下主题:

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

我不是100%确定这个修复。但是在打破这堵墙之前,试一下

好的。。。我不确定以下是一个完整的解决方案,它只是一个修复,一个为我目前的项目发现,我仍然不满意我的答案

因此,通过阅读我的问题,您会发现我提到CA是在linux机器上创建的,客户端和服务器的证书由该CA签名。该主机是另一个VMWare VM,称为VM3。所以,我在VM3上为客户机和服务器使用CA123生成的证书在客户机VM上不起作用,请将其称为VM1,服务器VM称为VM2。出于好奇,我尝试在VM2上设置CA,签署客户端和服务器证书,并将客户端证书复制到客户端VM。令我惊讶的是,它起作用了,但我不知道为什么。我无法回答我在VM3上创建了什么样的依赖关系


请随意发布更准确、更完整的答案。

好的。。。我不确定以下是一个完整的解决方案,它只是一个修复,一个为我目前的项目发现,我仍然不满意我的答案

因此,通过阅读我的问题,您会发现我提到CA是在linux机器上创建的,客户端和服务器的证书由该CA签名。该主机是另一个VMWare VM,称为VM3。所以,我在VM3上为客户机和服务器使用CA123生成的证书在客户机VM上不起作用,请将其称为VM1,服务器VM称为VM2。出于好奇,我尝试在VM2上设置CA,签署客户端和服务器证书,并将客户端证书复制到客户端VM。令我惊讶的是,它起作用了,但我不知道为什么。我无法回答我在VM3上创建了什么样的依赖关系


请随意发布更准确、更完整的答案。

我查看了CN,不是IP。我已经在我的Linux机器上创建了我自己的CA,并用该CA签署了我的服务器和客户端证书。客户端CN是客户端,服务器CN是服务器。CA是CA123。我查了CN,不是IP。我已经在我的Linux机器上创建了我自己的CA,并用该CA签署了我的服务器和客户端证书。客户端CN是客户端,服务器CN是服务器。CA是CA123,你终于弄明白了吗?我猜生成CA和证书的命令行可能很重要。请把它寄出去。你终于弄明白了吗?我猜生成CA和证书的命令行可能很重要。请把它寄出去。