Loading CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,10 @@ Daniel S (3 Dec 2007) - Now libcurl (built with OpenSSL) doesn't return error anymore if the remote SSL-based server doesn't present a certificate when the request is told to ignore certificate verification anyway. - Michal Marek introduced CURLOPT_PROXY_TRANSFER_MODE which is used to control the appending of the "type=" thing on FTP URLs when they are passed to a HTTP proxy. Some proxies just don't like that appending (which is done Loading lib/ssluse.c +84 −53 Original line number Diff line number Diff line Loading @@ -1569,60 +1569,26 @@ Curl_ossl_connect_step2(struct connectdata *conn, } } static CURLcode Curl_ossl_connect_step3(struct connectdata *conn, int sockindex) /* * Get the server cert, verify it and show it etc, only call failf() if the * 'strict' argument is TRUE as otherwise all this is for informational * purposes only! * * We check certificates to authenticate the server; otherwise we risk * man-in-the-middle attack. */ static CURLcode servercert(struct connectdata *conn, struct ssl_connect_data *connssl, bool strict) { CURLcode retcode = CURLE_OK; CURLcode retcode; char *str; long lerr; ASN1_TIME *certdate; void *ssl_sessionid=NULL; struct SessionHandle *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); if(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { /* Since this is not a cached session ID, then we want to stach this one in the cache! */ SSL_SESSION *our_ssl_sessionid; #ifdef HAVE_SSL_GET1_SESSION our_ssl_sessionid = SSL_get1_session(connssl->handle); /* SSL_get1_session() will increment the reference count and the session will stay in memory until explicitly freed with SSL_SESSION_free(3), regardless of its state. This function was introduced in openssl 0.9.5a. */ #else our_ssl_sessionid = SSL_get_session(connssl->handle); /* if SSL_get1_session() is unavailable, use SSL_get_session(). This is an inferior option because the session can be flushed at any time by openssl. It is included only so curl compiles under versions of openssl < 0.9.5a. WARNING: How curl behaves if it's session is flushed is untested. */ #endif retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0 /* unknown size */); if(retcode) { failf(data, "failed to store ssl session"); return retcode; } } /* Get server's certificate (note: beware of dynamic allocation) - opt */ /* major serious hack alert -- we should check certificates * to authenticate the server; otherwise we risk man-in-the-middle * attack */ connssl->server_cert = SSL_get_peer_certificate(connssl->handle); if(!connssl->server_cert) { if(strict) failf(data, "SSL: couldn't get peer certificate!"); return CURLE_PEER_FAILED_VERIFICATION; } Loading @@ -1631,6 +1597,7 @@ Curl_ossl_connect_step3(struct connectdata *conn, str = X509_NAME_oneline(X509_get_subject_name(connssl->server_cert), NULL, 0); if(!str) { if(strict) failf(data, "SSL: couldn't get X509-subject!"); X509_free(connssl->server_cert); connssl->server_cert = NULL; Loading @@ -1657,6 +1624,7 @@ Curl_ossl_connect_step3(struct connectdata *conn, str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert), NULL, 0); if(!str) { if(strict) failf(data, "SSL: couldn't get X509-issuer name!"); retcode = CURLE_SSL_CONNECT_ERROR; } Loading @@ -1673,6 +1641,7 @@ Curl_ossl_connect_step3(struct connectdata *conn, if(data->set.ssl.verifypeer) { /* We probably never reach this, because SSL_connect() will fail and we return earlyer if verifypeer is set? */ if(strict) failf(data, "SSL certificate verify result: %s (%ld)", X509_verify_cert_error_string(lerr), lerr); retcode = CURLE_PEER_FAILED_VERIFICATION; Loading @@ -1689,6 +1658,68 @@ Curl_ossl_connect_step3(struct connectdata *conn, X509_free(connssl->server_cert); connssl->server_cert = NULL; connssl->connecting_state = ssl_connect_done; return retcode; } static CURLcode Curl_ossl_connect_step3(struct connectdata *conn, int sockindex) { CURLcode retcode = CURLE_OK; void *ssl_sessionid=NULL; struct SessionHandle *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); if(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { /* Since this is not a cached session ID, then we want to stach this one in the cache! */ SSL_SESSION *our_ssl_sessionid; #ifdef HAVE_SSL_GET1_SESSION our_ssl_sessionid = SSL_get1_session(connssl->handle); /* SSL_get1_session() will increment the reference count and the session will stay in memory until explicitly freed with SSL_SESSION_free(3), regardless of its state. This function was introduced in openssl 0.9.5a. */ #else our_ssl_sessionid = SSL_get_session(connssl->handle); /* if SSL_get1_session() is unavailable, use SSL_get_session(). This is an inferior option because the session can be flushed at any time by openssl. It is included only so curl compiles under versions of openssl < 0.9.5a. WARNING: How curl behaves if it's session is flushed is untested. */ #endif retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0 /* unknown size */); if(retcode) { failf(data, "failed to store ssl session"); return retcode; } } /* * We check certificates to authenticate the server; otherwise we risk * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to * verify the peer ignore faults and failures from the server cert * operations. */ if(!data->set.ssl.verifypeer) (void)servercert(conn, connssl, FALSE); else retcode = servercert(conn, connssl, TRUE); if(CURLE_OK == retcode) connssl->connecting_state = ssl_connect_done; return retcode; } Loading Loading
CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,10 @@ Daniel S (3 Dec 2007) - Now libcurl (built with OpenSSL) doesn't return error anymore if the remote SSL-based server doesn't present a certificate when the request is told to ignore certificate verification anyway. - Michal Marek introduced CURLOPT_PROXY_TRANSFER_MODE which is used to control the appending of the "type=" thing on FTP URLs when they are passed to a HTTP proxy. Some proxies just don't like that appending (which is done Loading
lib/ssluse.c +84 −53 Original line number Diff line number Diff line Loading @@ -1569,60 +1569,26 @@ Curl_ossl_connect_step2(struct connectdata *conn, } } static CURLcode Curl_ossl_connect_step3(struct connectdata *conn, int sockindex) /* * Get the server cert, verify it and show it etc, only call failf() if the * 'strict' argument is TRUE as otherwise all this is for informational * purposes only! * * We check certificates to authenticate the server; otherwise we risk * man-in-the-middle attack. */ static CURLcode servercert(struct connectdata *conn, struct ssl_connect_data *connssl, bool strict) { CURLcode retcode = CURLE_OK; CURLcode retcode; char *str; long lerr; ASN1_TIME *certdate; void *ssl_sessionid=NULL; struct SessionHandle *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); if(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { /* Since this is not a cached session ID, then we want to stach this one in the cache! */ SSL_SESSION *our_ssl_sessionid; #ifdef HAVE_SSL_GET1_SESSION our_ssl_sessionid = SSL_get1_session(connssl->handle); /* SSL_get1_session() will increment the reference count and the session will stay in memory until explicitly freed with SSL_SESSION_free(3), regardless of its state. This function was introduced in openssl 0.9.5a. */ #else our_ssl_sessionid = SSL_get_session(connssl->handle); /* if SSL_get1_session() is unavailable, use SSL_get_session(). This is an inferior option because the session can be flushed at any time by openssl. It is included only so curl compiles under versions of openssl < 0.9.5a. WARNING: How curl behaves if it's session is flushed is untested. */ #endif retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0 /* unknown size */); if(retcode) { failf(data, "failed to store ssl session"); return retcode; } } /* Get server's certificate (note: beware of dynamic allocation) - opt */ /* major serious hack alert -- we should check certificates * to authenticate the server; otherwise we risk man-in-the-middle * attack */ connssl->server_cert = SSL_get_peer_certificate(connssl->handle); if(!connssl->server_cert) { if(strict) failf(data, "SSL: couldn't get peer certificate!"); return CURLE_PEER_FAILED_VERIFICATION; } Loading @@ -1631,6 +1597,7 @@ Curl_ossl_connect_step3(struct connectdata *conn, str = X509_NAME_oneline(X509_get_subject_name(connssl->server_cert), NULL, 0); if(!str) { if(strict) failf(data, "SSL: couldn't get X509-subject!"); X509_free(connssl->server_cert); connssl->server_cert = NULL; Loading @@ -1657,6 +1624,7 @@ Curl_ossl_connect_step3(struct connectdata *conn, str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert), NULL, 0); if(!str) { if(strict) failf(data, "SSL: couldn't get X509-issuer name!"); retcode = CURLE_SSL_CONNECT_ERROR; } Loading @@ -1673,6 +1641,7 @@ Curl_ossl_connect_step3(struct connectdata *conn, if(data->set.ssl.verifypeer) { /* We probably never reach this, because SSL_connect() will fail and we return earlyer if verifypeer is set? */ if(strict) failf(data, "SSL certificate verify result: %s (%ld)", X509_verify_cert_error_string(lerr), lerr); retcode = CURLE_PEER_FAILED_VERIFICATION; Loading @@ -1689,6 +1658,68 @@ Curl_ossl_connect_step3(struct connectdata *conn, X509_free(connssl->server_cert); connssl->server_cert = NULL; connssl->connecting_state = ssl_connect_done; return retcode; } static CURLcode Curl_ossl_connect_step3(struct connectdata *conn, int sockindex) { CURLcode retcode = CURLE_OK; void *ssl_sessionid=NULL; struct SessionHandle *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); if(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { /* Since this is not a cached session ID, then we want to stach this one in the cache! */ SSL_SESSION *our_ssl_sessionid; #ifdef HAVE_SSL_GET1_SESSION our_ssl_sessionid = SSL_get1_session(connssl->handle); /* SSL_get1_session() will increment the reference count and the session will stay in memory until explicitly freed with SSL_SESSION_free(3), regardless of its state. This function was introduced in openssl 0.9.5a. */ #else our_ssl_sessionid = SSL_get_session(connssl->handle); /* if SSL_get1_session() is unavailable, use SSL_get_session(). This is an inferior option because the session can be flushed at any time by openssl. It is included only so curl compiles under versions of openssl < 0.9.5a. WARNING: How curl behaves if it's session is flushed is untested. */ #endif retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0 /* unknown size */); if(retcode) { failf(data, "failed to store ssl session"); return retcode; } } /* * We check certificates to authenticate the server; otherwise we risk * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to * verify the peer ignore faults and failures from the server cert * operations. */ if(!data->set.ssl.verifypeer) (void)servercert(conn, connssl, FALSE); else retcode = servercert(conn, connssl, TRUE); if(CURLE_OK == retcode) connssl->connecting_state = ssl_connect_done; return retcode; } Loading