diff --git a/CHANGES b/CHANGES index cd84cf358..eadf532ca 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,9 @@ Kamil Dudka (4 Apr 2010) - Refactorized interface of Curl_ssl_recv()/Curl_ssl_send(). +- libcurl-NSS now provides more accurate messages and error codes in case of + client certificate problem. Either during connection, or transfer phase. + Daniel Stenberg (1 Apr 2010) - Matt Wixson found and fixed a bug in the SCP/SFTP area where the code treated a 0 return code from libssh2 to be the same as EAGAIN while in diff --git a/lib/nss.c b/lib/nss.c index 560154dd1..0f8ebd527 100644 --- a/lib/nss.c +++ b/lib/nss.c @@ -989,6 +989,27 @@ 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) +{ + 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: + return false; + } +} + CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) { PRInt32 err; @@ -1326,7 +1347,11 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) data->state.ssl_connect_retry = FALSE; err = PR_GetError(); - infof(data, "NSS error %d\n", err); + if(handle_cc_error(err, data)) + curlerr = CURLE_SSL_CERTPROBLEM; + else + infof(data, "NSS error %d\n", err); + if(model) PR_Close(model); @@ -1355,6 +1380,8 @@ int Curl_nss_send(struct connectdata *conn, /* connection data */ PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) *curlcode = -1; /* EWOULDBLOCK */ + else if(handle_cc_error(err, conn->data)) + *curlcode = CURLE_SSL_CERTPROBLEM; else { failf(conn->data, "SSL write: error %d", err); *curlcode = CURLE_SEND_ERROR; @@ -1380,6 +1407,8 @@ ssize_t Curl_nss_recv(struct connectdata * conn, /* connection data */ if(err == PR_WOULD_BLOCK_ERROR) *curlcode = -1; /* EWOULDBLOCK */ + else if(handle_cc_error(err, conn->data)) + *curlcode = CURLE_SSL_CERTPROBLEM; else { failf(conn->data, "SSL read: errno %d", err); *curlcode = CURLE_RECV_ERROR;