2017-05-31 195 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'? –