我正在尝试编写客户端和服务器代码以使用 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 VM - 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 确实是“服务器”),但服务器无法获取客户端证书,因此握手失败。
任何人都可以提出解决这个问题的方法吗?
非常感谢。