在Ubuntu 14中编译时,SSL握手不起作用

时间:2014-05-01 22:16:18

标签: c++ ubuntu openssl handshake ubuntu-14.04

这是我使用SSL设置HTTPS服务器的流程。

Windows,OS X和Ubuntu 13 上完美运行。但它只能在 Ubuntu 14 上工作,我不知道为什么。

一旦它非常大,这不是完整的代码,但如果有必要,我可以完成更多细节。

SSL_library_init();

m_sslContext = SSL_CTX_new( SSLv23_server_method() );

SSL_CTX_use_certificate_chain_file( m_sslContext, "path/to/certificate.crt" );
SSL_CTX_use_PrivateKey_file( m_sslContext, "path/to/privatekey.pem", SSL_FILETYPE_PEM );

m_mainSocket = ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ) );

...

::listen( m_mainSocket, SOMAXCONN );

...

SOCKET childSocketHandle;

while ( ( childSocketHandle = ::accept( m_mainSocket, ... ) ) > 0 )
{
    sslChildSocket = SSL_new( m_sslContext );
    SSL_set_fd( sslChildSocket, childSocketHandle );
    SSL_set_accept_state( sslChildSocket );
    ...
    SSL_read( sslChildSocket, bufferIn, sizeof( bufferIn ) );
    ...
    SSL_write( sslChildSocket, bufferOut, sizeof( bufferOut ) ) );
}

问题是:当我尝试从浏览器(Google Chrom)连接时,它说:

  

无法与服务器建立安全连接。这可能是一个   服务器问题,或者可能需要客户端   您没有的身份验证证书。错误代码:   ERR_SSL_PROTOCOL_ERROR

其他浏览器也说类似的消息......

当我尝试从wget连接时,我得到:

wget https://example.com:443/
--2014-05-01 17:01:33--  https://example.com:443/
Resolving example.com (example.com)... 127.0.1.1
Connecting to example.com (example.com)|127.0.1.1|:443... connected.
ERROR: cannot verify example.com's certificate, issued by ‘/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=00000000’:
  Unable to locally verify the issuer's authority.
To connect to example.com insecurely, use `--no-check-certificate'.

我刚刚将证书的序列更改为00000000。

所以...如果我最终按照wget消息做...

wget https://example.com:443/ --no-check-certificate

...那么服务器运行正常!

因此,我得出的结论是:服务器本身正在工作,但握手在SSL证书上存在一些问题。证书是有效的,在其他服务器中使用,Apache完全接受它,正如我所说,再一次,这个相同的实现适用于Windows,OS X和Ubuntu 13.这个问题只发生在Ubuntu 14上。

我试图做的事情:

  1. 我试图更新OpenSSL [由我自己编译]但没有任何内容 发生了。
  2. 我试图尝试其他方法而不是SSLv23_server_method(),没有发生任何事情
  3. 我在Ubuntu 13中编译并在Ubuntu 14中执行(并且已经工作了!)
  4. Weard(第3项)是如果我在Ubuntu 13中编译并在Ubuntu 14上运行,它就可以了!那么也许一些Ubuntu 14静态库存在问题?

    我的SSL实施是否正确?还有什么可以做的,所以我可以为Ubuntu 14解决它,我的服务器到处工作?

    -

    我做openssl s_client -connect example.com:443并得到:

    CONNECTED(00000003)
    140735262471008:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
    ---
    no peer certificate available
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 0 bytes and written 322 bytes
    ---
    New, (NONE), Cipher is (NONE)
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    ---
    

1 个答案:

答案 0 :(得分:1)

It works perfectly on Windows, OS X and Ubuntu 13. But it's failing to work on Ubuntu 14 only and I don't know why.
...
ERR_SSL_PROTOCOL_ERROR

ERR_SSL_PROTOCOL_ERROR表示客户端和服务器无法就协议达成一致 - SSLv3,TLS 1.0等。我认为它对应于TLS的protocol_version警报。请参阅RFC 5246, Section 7.2

自1.0.1以来,OpenSSL一直是TLS 1.2。请参阅OpenSSL CHANGELOG。但是,由于互操作原因,Ubuntu在14之前禁用了TLS 1.1和TLS 1.2。见Ubuntu 12.04 LTS: OpenSSL downlevel version and does not support TLS 1.2。 Ubuntu 14(及其后续版本)启用了TLS 1.1和TLS 1.2。 (TLS 1.3即将来临:The Transport Layer Security (TLS) Protocol Version 1.3(draft-ietf-tls-rfc5246-bis-00))。

如果你必须通过代理,可能还有其他问题。该问题与ClientHello大小有关。由于额外的密码套件,因此ClientHello大小随着TLS 1.1和TLS 1.2的增加而增加(更准确地说,TLS 1.2因为TLS 1.1没有添加任何密码套件)。大小应该无关紧要,除了一些代理具有固定大小的缓冲区和其他简单的破坏交换的硬编码限制。这是一些F5和Ironport设备的问题。

您可以使用ClientHello测试TLS 1.2和s_client尺寸敏感度:

openssl s_client -tls1_2 -connect <server>:<port> -servername <server> \
    -cipher "SSL_RSA_WITH_3DES_EDE_CBC_SHA:TLS_RSA_WITH_3DES_EDE_CBC_SHA"

以上连接TLS 1.2并仅使用2个密码套件(4个字节)。如果它与2个密码套件连接,则删除-cipher并查看它是否与内置的80+(超过160个字节)连接。

如果与TLS 1.2连接,请尝试-tls1-ssl3

编辑:您的问题是古老的服务器以及TLS 1.1和TLS 1.2。请参阅下面有关隔离问题的步骤。

您有三种可能的修复方法。

<强>第一

第一个解决方案是让服务器升级到不古老的东西。如果是代理,则修复代理。

<强>第二

如果您需要修改协议版本,请执行以下操作以仅获取SSLv3或YLS 1.0:

m_sslContext = SSL_CTX_new( SSLv23_server_method() );
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
SSL_CTX_set_options(m_sslContext, flags);

<强>第三

如果您需要修改密码套件列表:

m_sslContext = SSL_CTX_new( SSLv23_server_method() );
const char* const PREFERRED_CIPHERS = "kEECDH:kEDH:kRSA:AESGCM:AES256:AES128:3DES:"
    "SHA256:SHA84:SHA1:!aNULL:!eNULL:HIGH:!RC4:!MD5:!SRP:!PSK:!ADH:!AECDH";
res = SSL_CTX_set_cipher_list(m_sslContext, PREFERRED_CIPHERS);

编辑:您的问题是古老的服务器以及TLS 1.1和TLS 1.2。您需要使用上面的(1),或上面的(2)。理想情况下,古代服务器将被修复,以便每个人都能受益。

TLS 1.2不起作用

$ openssl s_client -tls1_2 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
140735211598300:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
...

TLS 1.1不起作用

$ openssl s_client -tls1_1 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
140735211598300:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
...

TLS 1.0确实有效

$ openssl s_client -tls1 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
...

SSL v3可以正常工作

$ openssl s_client -ssl3 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
...

When I try to connect from wget, I get:
...
Unable to locally verify the issuer's authority.
...
So... If I finally follow the wget message and do...

wget https://mydomain.com:443/ --no-check-certificate

... THEN the server works perfectly!

这是一个不同的问题。 wget可能通过合并上述修复之一来避免此问题。 Wirehsark描述会告诉你。

此外,如果您提供了真实的服务器名称,我们可以帮助您识别您应该使用的根CA(以避免Unable to locally verify the issuer's authority)。

以下是我在s_client看到的内容:

$ openssl s_client -connect www.example.com:443
CONNECTED(00000003)
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certificates.godaddy.com/repository, CN = Go Daddy Secure Certification Authority, serialNumber = 07969287
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.example.com
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...

所以你需要 Go Daddy Class 2 Certification Authority 。你可以从Go Daddy Repository, SSL Certificate Information获得。该文件为gd-class2-root.crt,您可以将其传递给s_client,结果为Verify return code: 0 (ok)

$ openssl s_client -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certificates.godaddy.com/repository, CN = Go Daddy Secure Certification Authority, serialNumber = 07969287
verify return:1
depth=0 OU = Domain Control Validated, CN = *.example.com
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.example.com
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFRTCCBC2gAwIBAgIHKyKXfFXVZjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
ODcwHhcNMTQwMzIxMTYyMjU2WhcNMTUwMzIxMTYyMjU2WjA8MSEwHwYDVQQLExhE
b21haW4gQ29udHJvbCBWYWxpZGF0ZWQxFzAVBgNVBAMMDiouc3RheWZpbG0uY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyRsNuqBROD+6RsmkJk7S
KtTpFO5ke92AfWnEnZuKCbbRo/WjmtCPNLQC7fAQxPJb6i/cCt9cusQqlpFjHTg/
lD5Dqoqn/GXMe4hfKbV8VV3NAjWr8f0M/M1ftaL+zo5UtRjdAEIC9ysfbKqqBOxP
hqGPiL0QpkKQ5YZMiz3S4UZzwQ1Unjj43xH4IZFffsdwY5uJqfeoOl/6qBNAQIyg
1Hk00er/+1UlO2hpMe/qjiCZvGSRUat/O51AgyCPFGDmhSEi6rjyeLvEgpILzgR7
K1/BsCe2Kxi+SRIt8UK2jFjXSRnCQyjtgOitbk/sM0afhUUIb7ns95RWAiXt5CpD
0QIDAQABo4IBuzCCAbcwDwYDVR0TAQH/BAUwAwEBADAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQDAgWgMDQGA1UdHwQtMCswKaAnoCWG
I2h0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2RzMS0xMDYuY3JsMFMGA1UdIARMMEow
SAYLYIZIAYb9bQEHFwEwOTA3BggrBgEFBQcCARYraHR0cDovL2NlcnRpZmljYXRl
cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzCBgAYIKwYBBQUHAQEEdDByMCQGCCsG
AQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wSgYIKwYBBQUHMAKGPmh0
dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZF9pbnRl
cm1lZGlhdGUuY3J0MB8GA1UdIwQYMBaAFP2sYTKTbEXW4u6FX5q653aZaMznMCcG
A1UdEQQgMB6CDiouc3RheWZpbG0uY29tggxzdGF5ZmlsbS5jb20wHQYDVR0OBBYE
FOZLbPozya++C27Grhs5pPUut4WFMA0GCSqGSIb3DQEBBQUAA4IBAQBPv85UBt3g
1XGHwZ9ARxpG9InoHRQledSbRckchU35awnIXuXd6pE+kZ7RctR6BywiPRrQnmYm
0D7wHP+BVoN2cZIkTHHgx/hILGTYk47CKyVcL9+WyDd5UXkJYyfdMzfia6dnG4wZ
ucsdR8Ete2do35yZmCZHU5L9KwXarQRuNexbiOqb4kBjUaIhN79NZs1h812QWLLB
+uRhvHOfQuSleEx1ggou/rwaYKNGYrIJl4/kpCquDXbqebkR1B+ad49GD+yBMyOm
/AOfGSU6YTUfZRGjzS2yAozs+QZFUrZTDHyt6Z93OLD+4O07SSAfTD3AlQlG/V1M
KwHuBUl22QD4
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.example.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
---
No client certificate CA names sent
---
SSL handshake has read 2765 bytes and written 843 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: 990D00002F519EEFC297CD4CB157B2F7...
    Session-ID-ctx: 
    Master-Key: A4B16EA84F4CD1E8D56A0B601A678AEE...
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1399002932
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)