Georg Horn's fixes to do different CA cert verifications. They can now be

done even if the result is ignored, as some sites seem to require that.
This commit is contained in:
Daniel Stenberg 2003-10-23 07:44:55 +00:00
parent 5987791516
commit 14f795816d

View File

@ -975,21 +975,46 @@ Curl_SSLConnect(struct connectdata *conn)
} }
} }
if(data->set.ssl.verifypeer) { if (data->set.ssl.CAfile || data->set.ssl.CApath) {
SSL_CTX_set_verify(conn->ssl.ctx, /* tell SSL where to find CA certificates that are used to verify
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT| the servers certificate. */
SSL_VERIFY_CLIENT_ONCE, if (!SSL_CTX_load_verify_locations(conn->ssl.ctx, data->set.ssl.CAfile,
cert_verify_callback);
if((data->set.ssl.CAfile || data->set.ssl.CApath) &&
!SSL_CTX_load_verify_locations(conn->ssl.ctx,
data->set.ssl.CAfile,
data->set.ssl.CApath)) { data->set.ssl.CApath)) {
failf(data,"error setting certificate verify locations"); if (data->set.ssl.verifypeer) {
/* Fail if we insist on successfully verifying the server. */
failf(data,"error setting certificate verify locations:\n"
" CAfile: %s\n CApath: %s\n",
data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
data->set.ssl.CApath ? data->set.ssl.CApath : "none");
return CURLE_SSL_CACERT; return CURLE_SSL_CACERT;
} }
else {
/* Just continue with a warning if no strict certificate verification
is required. */
infof(data,"error setting certificate verify locations,"
" continuing anyway:\n");
infof(data, " CAfile: %s\n",
data->set.ssl.CAfile ? data->set.ssl.CAfile : "none");
infof(data, " CApath: %s\n",
data->set.ssl.CApath ? data->set.ssl.CApath : "none");
} }
else }
SSL_CTX_set_verify(conn->ssl.ctx, SSL_VERIFY_NONE, cert_verify_callback); else {
/* Everything is fine. */
infof(data,"successfully set certificate verify locations:\n");
infof(data, " CAfile: %s\n",
data->set.ssl.CAfile ? data->set.ssl.CAfile : "none");
infof(data, " CApath: %s\n",
data->set.ssl.CApath ? data->set.ssl.CApath : "none");
}
}
/* SSL always tries to verify the peer, this only says whether it should
* fail to connect if the verification fails, or if it should continue
* anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */
SSL_CTX_set_verify(conn->ssl.ctx,
data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
cert_verify_callback);
/* give application a chance to interfere with SSL set up. */ /* give application a chance to interfere with SSL set up. */
if(data->set.ssl.fsslctx) { if(data->set.ssl.fsslctx) {
@ -1175,33 +1200,41 @@ Curl_SSLConnect(struct connectdata *conn)
if(data->set.ssl.verifyhost) { if(data->set.ssl.verifyhost) {
retcode = verifyhost(conn); retcode = verifyhost(conn);
if(retcode) if(retcode) {
X509_free(conn->ssl.server_cert);
return retcode; return retcode;
} }
}
str = X509_NAME_oneline(X509_get_issuer_name(conn->ssl.server_cert), str = X509_NAME_oneline(X509_get_issuer_name(conn->ssl.server_cert),
NULL, 0); NULL, 0);
if(!str) { if(!str) {
failf(data, "SSL: couldn't get X509-issuer name!"); failf(data, "SSL: couldn't get X509-issuer name!");
X509_free(conn->ssl.server_cert); retcode = CURLE_SSL_CONNECT_ERROR;
return CURLE_SSL_CONNECT_ERROR;
} }
else {
infof(data, "\t issuer: %s\n", str); infof(data, "\t issuer: %s\n", str);
CRYPTO_free(str); CRYPTO_free(str);
/* We could do all sorts of certificate verification stuff here before /* We could do all sorts of certificate verification stuff here before
deallocating the certificate. */ deallocating the certificate. */
if(data->set.ssl.verifypeer) {
data->set.ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle); data->set.ssl.certverifyresult=SSL_get_verify_result(conn->ssl.handle);
if(data->set.ssl.certverifyresult != X509_V_OK) { if(data->set.ssl.certverifyresult != X509_V_OK) {
if(data->set.ssl.verifypeer) {
/* We probably never reach this, because SSL_connect() will fail
and we return earlyer if verifypeer is set? */
failf(data, "SSL certificate verify result: %d", failf(data, "SSL certificate verify result: %d",
data->set.ssl.certverifyresult); data->set.ssl.certverifyresult);
retcode = CURLE_SSL_PEER_CERTIFICATE; retcode = CURLE_SSL_PEER_CERTIFICATE;
} }
else
infof(data, "SSL certificate verify result: %d, continuing anyway.\n",
data->set.ssl.certverifyresult);
} }
else else
data->set.ssl.certverifyresult=0; infof(data, "SSL certificate verify ok.\n");
}
X509_free(conn->ssl.server_cert); X509_free(conn->ssl.server_cert);
#else /* USE_SSLEAY */ #else /* USE_SSLEAY */