diff --git a/src/mod_gnutls.c b/src/mod_gnutls.c index 8cf8cec2..16ad2766 100644 --- a/src/mod_gnutls.c +++ b/src/mod_gnutls.c @@ -2707,6 +2707,31 @@ https_add_ssl_client_subject (request_st * const r, gnutls_x509_dn_t dn) "gnutls_x509_dn_get_rdn_ava()"); } + +__attribute_cold__ +static void +https_add_ssl_client_verify_err (buffer * const b, unsigned int status) +{ + #if GNUTLS_VERSION_NUMBER >= 0x030104 + /* get failure string and translate newline to ':', removing last one */ + /* (preserving behavior from mod_openssl) */ + gnutls_datum_t msg = { NULL, 0 }; + if (gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, + &msg, 0) >= 0) { + size_t sz = msg.size-1; /* '\0'-terminated string */ + for (char *nl=(char *)msg.data; NULL != (nl=strchr(nl, '\n')); ++nl) + nl[0] = ('\0' == nl[1] ? (--sz, '\0') : ':'); + buffer_append_string_len(b, (char *)msg.data, sz); + } + if (msg.data) gnutls_free(msg.data); + #else + UNUSED(b); + UNUSED(status); + #endif +} + + +__attribute_noinline__ static void https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) { @@ -2724,20 +2749,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) } else if (0 != hctx->verify_status) { buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:")); - #if GNUTLS_VERSION_NUMBER >= 0x030104 - /* get failure string and translate newline to ':', removing last one */ - /* (preserving behavior from mod_openssl) */ - gnutls_datum_t msg = { NULL, 0 }; - if (gnutls_certificate_verification_status_print(hctx->verify_status, - GNUTLS_CRT_X509, - &msg, 0) >= 0) { - size_t sz = msg.size-1; /* '\0'-terminated string */ - for (char *nl=(char *)msg.data; NULL != (nl=strchr(nl, '\n')); ++nl) - nl[0] = ('\0' == nl[1] ? (--sz, '\0') : ':'); - buffer_append_string_len(vb, (char *)msg.data, sz); - } - if (msg.data) gnutls_free(msg.data); - #endif + https_add_ssl_client_verify_err(vb, hctx->verify_status); return; } else { diff --git a/src/mod_mbedtls.c b/src/mod_mbedtls.c index 240e92c8..577e5038 100644 --- a/src/mod_mbedtls.c +++ b/src/mod_mbedtls.c @@ -2362,6 +2362,22 @@ https_add_ssl_client_subject (request_st * const r, const mbedtls_x509_name *nam } +__attribute_cold__ +static void +https_add_ssl_client_verify_err (buffer * const b, uint32_t status) +{ + /* get failure string and translate newline to ':', removing last one */ + char buf[512]; + int n = mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", status); + if (n > 0) { + for (char *nl = buf; NULL != (nl = strchr(nl, '\n')); ++nl) + nl[0] = ('\0' == nl[1] ? (--n, '\0') : ':'); + buffer_append_string_len(b, buf, n); + } +} + + +__attribute_noinline__ static void https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) { @@ -2372,7 +2388,6 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) * the peer cert and check for NULL before using it. */ const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&hctx->ssl); buffer *vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_VERIFY")); - char buf[512]; int n; uint32_t rc = (NULL != crt) @@ -2383,20 +2398,15 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) return; } else if (0 != rc) { - /* get failure string and translate newline to ':', removing last one */ - n = mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", rc); buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:")); - if (n > 0) { - for (char *nl = buf; NULL != (nl = strchr(nl, '\n')); ++nl) - nl[0] = ('\0' == nl[1] ? (--n, '\0') : ':'); - buffer_append_string_len(vb, buf, n); - } + https_add_ssl_client_verify_err(vb, rc); return; } else { buffer_copy_string_len(vb, CONST_STR_LEN("SUCCESS")); } + char buf[512]; n = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject); if (n > 0 && n < (int)sizeof(buf)) { http_header_env_set(r, @@ -2406,12 +2416,14 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) https_add_ssl_client_subject(r, &crt->subject); - n = mbedtls_x509_serial_gets(buf, sizeof(buf), &crt->serial); - if (n > 0 && n < (int)sizeof(buf)) { - http_header_env_set(r, - CONST_STR_LEN("SSL_CLIENT_M_SERIAL"), - buf, n); - } + /* mbedtls_x509_serial_gets() (inefficiently) formats to hex separated by + * colons, but would differ from behavior of other lighttpd TLS modules */ + size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */ + while (i < crt->serial.len && crt->serial.p[i] == 0) ++i; + if (i == crt->serial.len) --i; + buffer_append_string_encoded_hex_uc( + http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_M_SERIAL")), + (char *)crt->serial.p+i, crt->serial.len-i); if (!buffer_string_is_empty(hctx->conf.ssl_verifyclient_username)) { /* pick one of the exported values as "REMOTE_USER", for example diff --git a/src/mod_nss.c b/src/mod_nss.c index e03980ef..c0c66f7f 100644 --- a/src/mod_nss.c +++ b/src/mod_nss.c @@ -2472,6 +2472,21 @@ https_add_ssl_client_subject (request_st * const r, CERTName * const subj) } } + +__attribute_cold__ +static void +https_add_ssl_client_verify_err (buffer * const b, unsigned int status) +{ + const char *s = PR_ErrorToName(status); + if (s) + buffer_append_string_len(b, s, strlen(s)); + buffer_append_string_len(b, CONST_STR_LEN(":")); + s = PR_ErrorToString(status, PR_LANGUAGE_I_DEFAULT); + buffer_append_string_len(b, s, strlen(s)); +} + + +__attribute_noinline__ static void https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) { @@ -2488,12 +2503,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) } else if (0 != hctx->verify_status) { buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:")); - const char *s = PR_ErrorToName(hctx->verify_status); - if (s) - buffer_append_string_len(vb, s, strlen(s)); - buffer_append_string_len(vb, CONST_STR_LEN(":")); - s = PR_ErrorToString(hctx->verify_status, PR_LANGUAGE_I_DEFAULT); - buffer_append_string_len(vb, s, strlen(s)); + https_add_ssl_client_verify_err(vb, hctx->verify_status); CERT_DestroyCertificate(crt); return; } @@ -2511,9 +2521,13 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) https_add_ssl_client_subject(r, &crt->subject); - buffer_append_uint_hex_lc( + s = (char *)crt->serialNumber.data; + size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */ + while (i < crt->serialNumber.len && s[i] == 0) ++i; + if (i == crt->serialNumber.len) --i; + buffer_append_string_encoded_hex_uc( http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_M_SERIAL")), - DER_GetInteger(&crt->serialNumber)); + s+i, crt->serialNumber.len-i); if (!buffer_string_is_empty(hctx->conf.ssl_verifyclient_username)) { /* pick one of the exported values as "REMOTE_USER", for example diff --git a/src/mod_openssl.c b/src/mod_openssl.c index 116fdb0b..bce10270 100644 --- a/src/mod_openssl.c +++ b/src/mod_openssl.c @@ -3374,6 +3374,17 @@ https_add_ssl_client_subject (request_st * const r, X509_NAME *xn) } +__attribute_cold__ +static void +https_add_ssl_client_verify_err (buffer * const b, long status) +{ + char errstr[256]; + ERR_error_string_n(status, errstr, sizeof(errstr)); + buffer_append_string(b, errstr); +} + + +__attribute_noinline__ static void https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) { @@ -3383,10 +3394,8 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) long vr = SSL_get_verify_result(hctx->ssl); if (vr != X509_V_OK) { - char errstr[256]; - ERR_error_string_n(vr, errstr, sizeof(errstr)); buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:")); - buffer_append_string(vb, errstr); + https_add_ssl_client_verify_err(vb, vr); return; } else if (!(xs = SSL_get_peer_certificate(hctx->ssl))) { buffer_copy_string_len(vb, CONST_STR_LEN("NONE")); diff --git a/src/mod_wolfssl.c b/src/mod_wolfssl.c index 8227d89d..9aed7047 100644 --- a/src/mod_wolfssl.c +++ b/src/mod_wolfssl.c @@ -3157,6 +3157,17 @@ https_add_ssl_client_subject (request_st * const r, X509_NAME *xn) } +__attribute_cold__ +static void +https_add_ssl_client_verify_err (buffer * const b, long status) +{ + char errstr[256]; + ERR_error_string_n(status, errstr, sizeof(errstr)); + buffer_append_string(b, errstr); +} + + +__attribute_noinline__ static void https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) { @@ -3166,10 +3177,8 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx) long vr = SSL_get_verify_result(hctx->ssl); if (vr != X509_V_OK) { - char errstr[256]; - ERR_error_string_n(vr, errstr, sizeof(errstr)); buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:")); - buffer_append_string(vb, errstr); + https_add_ssl_client_verify_err(vb, vr); return; } else if (!(xs = SSL_get_peer_certificate(hctx->ssl))) { buffer_copy_string_len(vb, CONST_STR_LEN("NONE"));