@@ -32,10 +32,11 @@ # pragma clang diagnostic ignored "-Wdocumentation" #endif #include #include +#include #include #if defined(__clang__) # pragma clang diagnostic pop #endif @@ -44,11 +45,10 @@ #import #import #import #import -#import #import #import #import #import #import @@ -56,13 +56,15 @@ #import #import #import "SSLSocket.h" -#import "SSLInvalidCertificateException.h" #import "X509Certificate.h" +#import "SSLConnectionFailedException.h" +#import "SSLInvalidCertificateException.h" + #ifndef INVALID_SOCKET # define INVALID_SOCKET -1 #endif static SSL_CTX *ctx; @@ -173,30 +175,40 @@ - (void)SSL_startTLSWithExpectedHost: (OFString*)host port: (uint16_t)port { of_string_encoding_t encoding; - if ((_SSL = SSL_new(ctx)) == NULL || !SSL_set_fd(_SSL, _socket)) { + if ((_SSL = SSL_new(ctx)) == NULL || SSL_set_fd(_SSL, _socket) != 1) { + unsigned long error = ERR_get_error(); + [super close]; - @throw [OFConnectionFailedException + + @throw [SSLConnectionFailedException exceptionWithHost: host port: port - socket: self]; + socket: self + SSLError: error]; } if (_certificateVerificationEnabled) { X509_VERIFY_PARAM *param = SSL_get0_param(_SSL); X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); if (X509_VERIFY_PARAM_set1_host(param, - [host UTF8String], [host UTF8StringLength]) == 0) - @throw [OFConnectionFailedException + [host UTF8String], [host UTF8StringLength]) != 1) { + unsigned long error = ERR_get_error(); + + [self close]; + + @throw [SSLConnectionFailedException exceptionWithHost: host port: port - socket: self]; + socket: self + SSLError: error]; + } SSL_set_verify(_SSL, SSL_VERIFY_PEER, NULL); } SSL_set_connect_state(_SSL); @@ -206,16 +218,41 @@ if ((_privateKeyFile != nil && !SSL_use_PrivateKey_file(_SSL, [_privateKeyFile cStringWithEncoding: encoding], SSL_FILETYPE_PEM)) || (_certificateFile != nil && !SSL_use_certificate_file(_SSL, [_certificateFile cStringWithEncoding: encoding], - SSL_FILETYPE_PEM)) || SSL_connect(_SSL) != 1) { + SSL_FILETYPE_PEM))) { + unsigned long error = ERR_get_error(); + [super close]; - @throw [OFConnectionFailedException + + @throw [SSLConnectionFailedException exceptionWithHost: host port: port - socket: self]; + socket: self + SSLError: error]; + } + + if (SSL_connect(_SSL) != 1) { + unsigned long error = ERR_get_error(); + long res; + + [super close]; + + if ((res = SSL_get_verify_result(_SSL)) != X509_V_OK) + @throw [SSLConnectionFailedException + exceptionWithHost: host + port: port + socket: self + SSLError: error + verifyResult: res]; + else + @throw [SSLConnectionFailedException + exceptionWithHost: host + port: port + socket: self + SSLError: error]; } } - (void)startTLSWithExpectedHost: (OFString*)host {