我正在尝试使用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);
我使用目标地址作为回送地址(127.0.0.1)运行代码,从上面显示的代码可以看出。在同一台机器上执行的客户端和服务器程序工作正常。
但是,当我在不同的机器(VMWare VMs - Ubuntu Linux)上运行客户端和服务器程序时,代码会失败。
Client VM IP:192.168.181.188
Server VM IP:192.168.181.180
使用服务器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确实是'服务器'),但是服务器无法获得客户端证书,因此握手失败。
有人可以建议解决这个问题吗?
非常感谢。
答案 0 :(得分:0)
检查客户端证书的subject
。有时,CN(公用名)字段应具有客户端主机的IP或主机名。
在您的情况下,客户证书可能具有以下主题:
Subject: C=xxx, ST=xxx, L=xxx, O=xxx, OU=xxx, CN=192.168.181.180
我不是100%肯定这个修复。但在破墙之前,试一试。
答案 1 :(得分:0)
好的......我不确定以下是一个完整的解决方案,它只是我当前项目的修复,我仍然不满意我的答案。
因此,通过阅读我的问题,你会发现我提到CA是在linux机器上制作的,客户端和服务器的证书是由CA签署的。该主机是另一个VMWare VM,称之为“VM3”。因此,我在“VM3”上为客户端和服务器使用“CA123”生成的证书在客户端VM(称为“VM1”)和服务器VM(称为“VM2”)上不起作用。出于好奇,我尝试在VM2上设置CA,并签署客户端和服务器证书,并将客户端证书复制到客户端VM。令我惊讶的是,它有效,但我不知道为什么。我无法回答我在VM3上创建了哪种依赖?
随意发布更准确,更完整的答案。