diff options
author | Alessandro Ghedini <alessandro@ghedini.me> | 2015-05-04 10:41:25 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2015-05-04 13:42:45 +0200 |
commit | a5e09e9eea3cf4607b66a5d4fb8b5b43c0ed95c3 (patch) | |
tree | 6515e8e7a8d32a5b376c45f2cdf836e6cb99fa17 | |
parent | 86bc654532e24bdc3a76324fc976fe3be399985b (diff) |
gtls: properly retrieve certificate status
Also print the revocation reason if appropriate.
-rw-r--r-- | lib/vtls/gtls.c | 96 |
1 files changed, 92 insertions, 4 deletions
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index 3ad0f82ff..3c473cb7c 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -897,10 +897,98 @@ gtls_connect_step3(struct connectdata *conn, #ifdef HAS_OCSP if(data->set.ssl.verifystatus) { if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) { - if(verify_status & GNUTLS_CERT_REVOKED) - infof(data, "\t server certificate was REVOKED\n"); - else - infof(data, "\t server certificate status verification FAILED\n"); + gnutls_datum_t status_request; + gnutls_ocsp_resp_t ocsp_resp; + + gnutls_ocsp_cert_status_t status; + gnutls_x509_crl_reason_t reason; + + rc = gnutls_ocsp_status_request_get(session, &status_request); + + infof(data, "\t server certificate status verification FAILED\n"); + + if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { + failf(data, "No OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + if(rc < 0) { + failf(data, "Invalid OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + gnutls_ocsp_resp_init(&ocsp_resp); + + rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); + if(rc < 0) { + failf(data, "Invalid OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, + &status, NULL, NULL, NULL, &reason); + + switch(status) { + case GNUTLS_OCSP_CERT_GOOD: + break; + + case GNUTLS_OCSP_CERT_REVOKED: { + const char *crl_reason; + + switch(reason) { + default: + case GNUTLS_X509_CRLREASON_UNSPECIFIED: + crl_reason = "unspecified reason"; + break; + + case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: + crl_reason = "private key compromised"; + break; + + case GNUTLS_X509_CRLREASON_CACOMPROMISE: + crl_reason = "CA compromised"; + break; + + case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: + crl_reason = "affiliation has changed"; + break; + + case GNUTLS_X509_CRLREASON_SUPERSEDED: + crl_reason = "certificate superseded"; + break; + + case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: + crl_reason = "operation has ceased"; + break; + + case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: + crl_reason = "certificate is on hold"; + break; + + case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: + crl_reason = "will be removed from delta CRL"; + break; + + case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: + crl_reason = "privilege withdrawn"; + break; + + case GNUTLS_X509_CRLREASON_AACOMPROMISE: + crl_reason = "AA compromised"; + break; + } + + failf(data, "Server certificate was revoked: %s", crl_reason); + break; + } + + default: + case GNUTLS_OCSP_CERT_UNKNOWN: + failf(data, "Server certificate status is unknown"); + break; + } + + gnutls_ocsp_resp_deinit(ocsp_resp); return CURLE_SSL_INVALIDCERTSTATUS; } |