2017-05-31 91 views
0

我正在写一个接受SSL连接的服务器。我已经生成的自签名证书:没有可用自签名证书的对等证书

openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem -subj "/CN=myhostname" 

SSL_accept失败,此消息:

140121764049248:error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher:s3_srvr.c:1417: 

这里是服务器代码的一部分:

sslCtx = (SSL_CTX_new(SSLv23_server_method()); 
    if (!sslCtx){ 
     ERR_print_errors_fp(stderr); 
    throw runtime_error("SSL_CTX_new failed"); 
    } 
    ssl = SSL_new(sslCtx); 
    if (!ssl) 
    throw runtime_error("SSL_new failed"); 

    if (SSL_CTX_use_PrivateKey_file(sslCtx, keyFile.c_str(), 
            SSL_FILETYPE_PEM) != 1) 
    throw runtime_error("Unable to load private key file" + keyFile); 

    if (SSL_CTX_use_certificate_file(sslCtx, certFile.c_str(), 
            SSL_FILETYPE_PEM) != 1) 
    throw runtime_error("Unable to load certificate file" + certFile); 


    if (SSL_set_fd(ssl, socket) != 1) 
    throw runtime_error("SSL_set_fd failed"); 

    if (SSL_accept(ssl) != 1){ 
    ERR_print_errors_fp(stderr); 
    throw runtime_error("SSL_accept failed"); 
    } 

我试图测试服务器:

openssl s_client -cipher RSA -connect myhostname:33221 -tls1 -CApath . -servername myhostname 

并得到了

CONNECTED(00000003) 
139898773520408:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1487:SSL alert number 40 
139898773520408:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:656: 
--- 
no peer certificate available 
--- 
No client certificate CA names sent 
--- 
SSL handshake has read 7 bytes and written 0 bytes 
--- 
New, (NONE), Cipher is (NONE) 
Secure Renegotiation IS NOT supported 
Compression: NONE 
Expansion: NONE 
No ALPN negotiated 
SSL-Session: 
    Protocol : TLSv1 
    Cipher : 0000 
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg : None 
    PSK identity: None 
    PSK identity hint: None 
    SRP username: None 
    Start Time: 1496232544 
    Timeout : 7200 (sec) 
    Verify return code: 0 (ok) 
--- 

我使用的是OpenSSL 1.0.2g。

+0

***'CN = myhostname' ***可能是错误的。主机名始终在* SAN *中。如果它存在于* CN *中,那么它也必须存在于* SAN *中(在这种情况下,您必须列出它两次)。有关更多规则和原因,请参阅[如何使用您的证书颁发机构签署证书签名请求](http://stackoverflow.com/a/21340898/608639)和[如何使用openssl创建自签名证书?]( http://stackoverflow.com/q/10175812/608639)您还需要将自签名证书放入适当的信任库中。 – jww

+0

请提供您用于连接服务器的URL,并发布'openssl s_client -connect -tls1 -servername | openssl x509 -text -noout'。另请参阅OpenSSL wiki上的[TLS客户端](https://wiki.openssl.org/index.php/SSL/TLS_Client)。它向您展示了如何在客户端上下文中配置SSL_CTX。它大部分也适用于服务器。另外,这可能会给你带来麻烦:'if(SSL_accept(ssl)!= 1)',特别是在非阻塞套接字上。我似乎记得非阻塞套接字经常返回'-1',并且它不是错误。 – jww

回答

0

尝试SSL_new,只有在完全设置上下文并确保在程序开始时有OpenSSL_add_ssl_algorithms。 1.0.2文档说它“继承”,但不确定这是否意味着它在当时复制了设置,并且未应用进一步的更改。

https://www.openssl.org/docs/man1.0.2/ssl/SSL_new.html

新的结构继承底层上下文CTX的设置:连接方法(的SSLv2/V3 /使用TLSv1),选项,验证设定,超时设置。

还有对OpenSSL wiki

一个例子没有错误处理的线沿线的云:

// General initialisation 
SSL_load_error_strings(); 
OpenSSL_add_ssl_algorithms(); 
// Context for a server socket 
ctx = SSL_CTX_new(SSLv23_server_method()); //Note SSLv23_server_method in example is deprecated in favour of TLS_server_method for new versions. TLSv1_2_server_method will force TLS 1.2. 
SSL_CTX_set_ecdh_auto(ctx, 1); 
SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM); 
SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM); 
// Only after all certificates, and other config is set 
ssl = SSL_new(ctx); 
SSL_set_fd(ssl, client_socket); 
SSL_accept(ssl); 
// Use SSL_write and SSL_read 
SSL_free(ssl); 
close(client_socket); 
// OpenSSL cleanup 
EVP_cleanup(); 
+0

仍然收到相同的错误。也许我应该将证书复制到特定位置? – robert

+0

您试试示例代码?如果没有给出一个有效的文件(它是一个正常的文件路径,'/绝对'或其他相对于当前目录),'SSL_CTX_use_certificate_file'等应该会导致错误。所以,如果你没有在服务器代码中发现错误,看起来你做了一些与这个例子不同的东西。示例代码和'openssl s_client'在同一个系统上使用您显示的自签名命令行给我“验证返回码:18(自签名证书)”。 –

+0

您是否可以在您发布的代码之外跳过一些OpenSSL设置步骤?例如'OpenSSL_add_ssl_algorithms'? –