Loading RELEASE-NOTES +2 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ Curl and libcurl 7.26.1 This release includes the following changes: o nss: use human-readable error messages provided by NSS o This release includes the following bugfixes: Loading lib/nss.c +57 −71 Original line number Diff line number Diff line Loading @@ -186,6 +186,11 @@ static const char* nss_error_to_name(PRErrorCode code) return "unknown error"; } static void nss_print_error_message(struct SessionHandle *data, PRUint32 err) { failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); } static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model, char *cipher_list) { Loading Loading @@ -612,61 +617,6 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig, return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer); } static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) { SECStatus result = SECFailure; struct connectdata *conn = (struct connectdata *)arg; PRErrorCode err = PR_GetError(); CERTCertificate *cert = NULL; char *subject, *subject_cn, *issuer; conn->data->set.ssl.certverifyresult=err; cert = SSL_PeerCertificate(sock); subject = CERT_NameToAscii(&cert->subject); subject_cn = CERT_GetCommonName(&cert->subject); issuer = CERT_NameToAscii(&cert->issuer); CERT_DestroyCertificate(cert); switch(err) { case SEC_ERROR_CA_CERT_INVALID: infof(conn->data, "Issuer certificate is invalid: '%s'\n", issuer); break; case SEC_ERROR_UNTRUSTED_ISSUER: infof(conn->data, "Certificate is signed by an untrusted issuer: '%s'\n", issuer); break; case SSL_ERROR_BAD_CERT_DOMAIN: if(conn->data->set.ssl.verifyhost) { failf(conn->data, "SSL: certificate subject name '%s' does not match " "target host name '%s'", subject_cn, conn->host.dispname); } else { result = SECSuccess; infof(conn->data, "warning: SSL: certificate subject name '%s' does not " "match target host name '%s'\n", subject_cn, conn->host.dispname); } break; case SEC_ERROR_EXPIRED_CERTIFICATE: infof(conn->data, "Remote Certificate has expired.\n"); break; case SEC_ERROR_UNKNOWN_ISSUER: infof(conn->data, "Peer's certificate issuer is not recognized: '%s'\n", issuer); break; default: infof(conn->data, "Bad certificate received. Subject = '%s', " "Issuer = '%s'\n", subject, issuer); break; } if(result == SECSuccess) infof(conn->data, "SSL certificate verify ok.\n"); PR_Free(subject); PR_Free(subject_cn); PR_Free(issuer); return result; } /** * Inform the application that the handshake is complete. */ Loading Loading @@ -728,6 +678,31 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock) return; } static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) { struct connectdata *conn = (struct connectdata *)arg; struct SessionHandle *data = conn->data; PRErrorCode err = PR_GetError(); CERTCertificate *cert; /* remember the cert verification result */ data->set.ssl.certverifyresult = err; if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost) /* we are asked not to verify the host name */ return SECSuccess; /* print only info about the cert, the error is printed off the callback */ cert = SSL_PeerCertificate(sock); if(cert) { infof(data, "Server certificate:\n"); display_cert_info(data, cert); CERT_DestroyCertificate(cert); } return SECFailure; } /** * * Check that the Peer certificate's issuer certificate matches the one found Loading Loading @@ -1108,20 +1083,17 @@ int Curl_nss_close_all(struct SessionHandle *data) return 0; } /* handle client certificate related errors if any; return false otherwise */ static bool handle_cc_error(PRInt32 err, struct SessionHandle *data) /* return true if the given error code is related to a client certificate */ static bool is_cc_error(PRInt32 err) { switch(err) { case SSL_ERROR_BAD_CERT_ALERT: failf(data, "SSL error: SSL_ERROR_BAD_CERT_ALERT"); return true; case SSL_ERROR_REVOKED_CERT_ALERT: failf(data, "SSL error: SSL_ERROR_REVOKED_CERT_ALERT"); return true; case SSL_ERROR_EXPIRED_CERT_ALERT: failf(data, "SSL error: SSL_ERROR_EXPIRED_CERT_ALERT"); return true; default: Loading Loading @@ -1460,11 +1432,15 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) data->state.ssl_connect_retry = FALSE; err = PR_GetError(); if(handle_cc_error(err, data)) if(is_cc_error(err)) curlerr = CURLE_SSL_CERTPROBLEM; else /* print the error number and error string */ infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err)); /* print a human-readable message describing the error if available */ nss_print_error_message(data, err); if(model) PR_Close(model); Loading Loading @@ -1496,12 +1472,17 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) *curlcode = CURLE_AGAIN; else if(handle_cc_error(err, conn->data)) *curlcode = CURLE_SSL_CERTPROBLEM; else { /* print the error number and error string */ const char *err_name = nss_error_to_name(err); failf(conn->data, "SSL write: error %d (%s)", err, err_name); *curlcode = CURLE_SEND_ERROR; infof(conn->data, "SSL write: error %d (%s)\n", err, err_name); /* print a human-readable message describing the error if available */ nss_print_error_message(conn->data, err); *curlcode = (is_cc_error(err)) ? CURLE_SSL_CERTPROBLEM : CURLE_SEND_ERROR; } return -1; } Loading @@ -1523,12 +1504,17 @@ static ssize_t nss_recv(struct connectdata * conn, /* connection data */ if(err == PR_WOULD_BLOCK_ERROR) *curlcode = CURLE_AGAIN; else if(handle_cc_error(err, conn->data)) *curlcode = CURLE_SSL_CERTPROBLEM; else { /* print the error number and error string */ const char *err_name = nss_error_to_name(err); failf(conn->data, "SSL read: errno %d (%s)", err, err_name); *curlcode = CURLE_RECV_ERROR; infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name); /* print a human-readable message describing the error if available */ nss_print_error_message(conn->data, err); *curlcode = (is_cc_error(err)) ? CURLE_SSL_CERTPROBLEM : CURLE_RECV_ERROR; } return -1; } Loading Loading
RELEASE-NOTES +2 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ Curl and libcurl 7.26.1 This release includes the following changes: o nss: use human-readable error messages provided by NSS o This release includes the following bugfixes: Loading
lib/nss.c +57 −71 Original line number Diff line number Diff line Loading @@ -186,6 +186,11 @@ static const char* nss_error_to_name(PRErrorCode code) return "unknown error"; } static void nss_print_error_message(struct SessionHandle *data, PRUint32 err) { failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); } static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model, char *cipher_list) { Loading Loading @@ -612,61 +617,6 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig, return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer); } static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) { SECStatus result = SECFailure; struct connectdata *conn = (struct connectdata *)arg; PRErrorCode err = PR_GetError(); CERTCertificate *cert = NULL; char *subject, *subject_cn, *issuer; conn->data->set.ssl.certverifyresult=err; cert = SSL_PeerCertificate(sock); subject = CERT_NameToAscii(&cert->subject); subject_cn = CERT_GetCommonName(&cert->subject); issuer = CERT_NameToAscii(&cert->issuer); CERT_DestroyCertificate(cert); switch(err) { case SEC_ERROR_CA_CERT_INVALID: infof(conn->data, "Issuer certificate is invalid: '%s'\n", issuer); break; case SEC_ERROR_UNTRUSTED_ISSUER: infof(conn->data, "Certificate is signed by an untrusted issuer: '%s'\n", issuer); break; case SSL_ERROR_BAD_CERT_DOMAIN: if(conn->data->set.ssl.verifyhost) { failf(conn->data, "SSL: certificate subject name '%s' does not match " "target host name '%s'", subject_cn, conn->host.dispname); } else { result = SECSuccess; infof(conn->data, "warning: SSL: certificate subject name '%s' does not " "match target host name '%s'\n", subject_cn, conn->host.dispname); } break; case SEC_ERROR_EXPIRED_CERTIFICATE: infof(conn->data, "Remote Certificate has expired.\n"); break; case SEC_ERROR_UNKNOWN_ISSUER: infof(conn->data, "Peer's certificate issuer is not recognized: '%s'\n", issuer); break; default: infof(conn->data, "Bad certificate received. Subject = '%s', " "Issuer = '%s'\n", subject, issuer); break; } if(result == SECSuccess) infof(conn->data, "SSL certificate verify ok.\n"); PR_Free(subject); PR_Free(subject_cn); PR_Free(issuer); return result; } /** * Inform the application that the handshake is complete. */ Loading Loading @@ -728,6 +678,31 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock) return; } static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) { struct connectdata *conn = (struct connectdata *)arg; struct SessionHandle *data = conn->data; PRErrorCode err = PR_GetError(); CERTCertificate *cert; /* remember the cert verification result */ data->set.ssl.certverifyresult = err; if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost) /* we are asked not to verify the host name */ return SECSuccess; /* print only info about the cert, the error is printed off the callback */ cert = SSL_PeerCertificate(sock); if(cert) { infof(data, "Server certificate:\n"); display_cert_info(data, cert); CERT_DestroyCertificate(cert); } return SECFailure; } /** * * Check that the Peer certificate's issuer certificate matches the one found Loading Loading @@ -1108,20 +1083,17 @@ int Curl_nss_close_all(struct SessionHandle *data) return 0; } /* handle client certificate related errors if any; return false otherwise */ static bool handle_cc_error(PRInt32 err, struct SessionHandle *data) /* return true if the given error code is related to a client certificate */ static bool is_cc_error(PRInt32 err) { switch(err) { case SSL_ERROR_BAD_CERT_ALERT: failf(data, "SSL error: SSL_ERROR_BAD_CERT_ALERT"); return true; case SSL_ERROR_REVOKED_CERT_ALERT: failf(data, "SSL error: SSL_ERROR_REVOKED_CERT_ALERT"); return true; case SSL_ERROR_EXPIRED_CERT_ALERT: failf(data, "SSL error: SSL_ERROR_EXPIRED_CERT_ALERT"); return true; default: Loading Loading @@ -1460,11 +1432,15 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) data->state.ssl_connect_retry = FALSE; err = PR_GetError(); if(handle_cc_error(err, data)) if(is_cc_error(err)) curlerr = CURLE_SSL_CERTPROBLEM; else /* print the error number and error string */ infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err)); /* print a human-readable message describing the error if available */ nss_print_error_message(data, err); if(model) PR_Close(model); Loading Loading @@ -1496,12 +1472,17 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) *curlcode = CURLE_AGAIN; else if(handle_cc_error(err, conn->data)) *curlcode = CURLE_SSL_CERTPROBLEM; else { /* print the error number and error string */ const char *err_name = nss_error_to_name(err); failf(conn->data, "SSL write: error %d (%s)", err, err_name); *curlcode = CURLE_SEND_ERROR; infof(conn->data, "SSL write: error %d (%s)\n", err, err_name); /* print a human-readable message describing the error if available */ nss_print_error_message(conn->data, err); *curlcode = (is_cc_error(err)) ? CURLE_SSL_CERTPROBLEM : CURLE_SEND_ERROR; } return -1; } Loading @@ -1523,12 +1504,17 @@ static ssize_t nss_recv(struct connectdata * conn, /* connection data */ if(err == PR_WOULD_BLOCK_ERROR) *curlcode = CURLE_AGAIN; else if(handle_cc_error(err, conn->data)) *curlcode = CURLE_SSL_CERTPROBLEM; else { /* print the error number and error string */ const char *err_name = nss_error_to_name(err); failf(conn->data, "SSL read: errno %d (%s)", err, err_name); *curlcode = CURLE_RECV_ERROR; infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name); /* print a human-readable message describing the error if available */ nss_print_error_message(conn->data, err); *curlcode = (is_cc_error(err)) ? CURLE_SSL_CERTPROBLEM : CURLE_RECV_ERROR; } return -1; } Loading