From: Daris A Nevil Date: Mon, 17 Dec 2018 17:38:01 +0000 (+0000) Subject: Add %ssl::request) { ConnStateData *conn = al->request->clientConnectionManager.get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { - if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) - out = sslGetUserCertificatePEM(ssl); + if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) { + sb = sslGetUserCertificatePEM(ssl); + out = sb.c_str(); + } } } break; @@ -1188,8 +1190,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS if (al->request) { ConnStateData *conn = al->request->clientConnectionManager.get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { - if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) - out = sslGetUserCertificatePEM(ssl); + if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) { + sb = sslGetUserCertificatePEM(ssl); + out = sb.c_str(); + } } } break; @@ -1265,13 +1269,20 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_ISSUER: case LFT_SSL_SERVER_CERT_SUBJECT: + case LFT_SSL_SERVER_CERT_WHOLE: if (al->request && al->request->clientConnectionManager.valid()) { if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) { if (X509 *serverCert = srvBump->serverCert.get()) { if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT) out = Ssl::GetX509UserAttribute(serverCert, "DN"); - else + else if (fmt->type == LFT_SSL_SERVER_CERT_ISSUER) out = Ssl::GetX509CAAttribute(serverCert, "DN"); + else { + assert(fmt->type == LFT_SSL_SERVER_CERT_WHOLE); + sb = Ssl::GetX509PEM(serverCert); + out = sb.c_str(); + quote = 1; + } } } } diff --git a/src/format/Token.cc b/src/format/Token.cc index 4802a5be09..daf4bf9d3c 100644 --- a/src/format/Token.cc +++ b/src/format/Token.cc @@ -221,6 +221,7 @@ static TokenTableEntry TokenTableSsl[] = { TokenTableEntry("negotiated_version", LFT_TLS_CLIENT_NEGOTIATED_VERSION), TokenTableEntry("negotiated_cipher", LFT_TLS_CLIENT_NEGOTIATED_CIPHER), diff --git a/src/ssl/support.cc b/src/ssl/support.cc index f6d4ce7aaf..8f3c54ab27 100644 --- a/src/ssl/support.cc +++ b/src/ssl/support.cc @@ -651,6 +651,19 @@ Ssl::GetX509Fingerprint(X509 * cert, const char *) return buf; } +SBuf +Ssl::GetX509PEM(X509 * cert) +{ + assert(cert); + + Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem())); + PEM_write_bio_X509(bio.get(), cert); + + char *ptr; + const auto len = BIO_get_mem_data(bio.get(), &ptr); + return SBuf(ptr, len); +} + /// \ingroup ServerProtocolSSLInternal const char * Ssl::GetX509CAAttribute(X509 * cert, const char *attribute_name) @@ -701,80 +714,37 @@ sslGetUserEmail(SSL * ssl) return sslGetUserAttribute(ssl, "emailAddress"); } -const char * +SBuf sslGetUserCertificatePEM(SSL *ssl) { - X509 *cert; - BIO *mem; - static char *str = NULL; - char *ptr; - long len; - - safe_free(str); - - if (!ssl) - return NULL; - - cert = SSL_get_peer_certificate(ssl); - - if (!cert) - return NULL; - - mem = BIO_new(BIO_s_mem()); + assert(ssl); - PEM_write_bio_X509(mem, cert); + if (const auto cert = SSL_get_peer_certificate(ssl)) + return Ssl::GetX509PEM(cert); - len = BIO_get_mem_data(mem, &ptr); - - str = (char *)xmalloc(len + 1); - - memcpy(str, ptr, len); - - str[len] = '\0'; - - X509_free(cert); - - BIO_free(mem); - - return str; + return SBuf(); } -const char * +SBuf sslGetUserCertificateChainPEM(SSL *ssl) { - STACK_OF(X509) *chain; - BIO *mem; - static char *str = NULL; - char *ptr; - long len; - int i; + assert(ssl); - safe_free(str); - - if (!ssl) - return NULL; - - chain = SSL_get_peer_cert_chain(ssl); + auto chain = SSL_get_peer_cert_chain(ssl); if (!chain) return sslGetUserCertificatePEM(ssl); - mem = BIO_new(BIO_s_mem()); + Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem())); - for (i = 0; i < sk_X509_num(chain); ++i) { + for (int i = 0; i < sk_X509_num(chain); ++i) { X509 *cert = sk_X509_value(chain, i); - PEM_write_bio_X509(mem, cert); + PEM_write_bio_X509(bio.get(), cert); } - len = BIO_get_mem_data(mem, &ptr); - - str = (char *)xmalloc(len + 1); - memcpy(str, ptr, len); - str[len] = '\0'; - - BIO_free(mem); - - return str; + char *ptr; + const auto len = BIO_get_mem_data(bio.get(), &ptr); + return SBuf(ptr, len); } /// Create SSL context and apply ssl certificate and private key to it. diff --git a/src/ssl/support.h b/src/ssl/support.h index 40dc2903af..118d309fdf 100644 --- a/src/ssl/support.h +++ b/src/ssl/support.h @@ -103,15 +103,16 @@ const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name); const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name); /// \ingroup ServerProtocolSSLAPI -const char *sslGetUserCertificatePEM(SSL *ssl); +SBuf sslGetUserCertificatePEM(SSL *ssl); /// \ingroup ServerProtocolSSLAPI -const char *sslGetUserCertificateChainPEM(SSL *ssl); +SBuf sslGetUserCertificateChainPEM(SSL *ssl); namespace Ssl { /// \ingroup ServerProtocolSSLAPI typedef char const *GETX509ATTRIBUTE(X509 *, const char *); +typedef SBuf GETX509PEM(X509 *); /// \ingroup ServerProtocolSSLAPI GETX509ATTRIBUTE GetX509UserAttribute; @@ -119,6 +120,9 @@ GETX509ATTRIBUTE GetX509UserAttribute; /// \ingroup ServerProtocolSSLAPI GETX509ATTRIBUTE GetX509CAAttribute; +/// \ingroup ServerProtocolSSLAPI +GETX509PEM GetX509PEM; + /// \ingroup ServerProtocolSSLAPI GETX509ATTRIBUTE GetX509Fingerprint; diff --git a/src/tests/stub_libsslsquid.cc b/src/tests/stub_libsslsquid.cc index fb47a924c7..35ed7c864c 100644 --- a/src/tests/stub_libsslsquid.cc +++ b/src/tests/stub_libsslsquid.cc @@ -11,6 +11,7 @@ #if USE_OPENSSL #include "fatal.h" +#include "sbuf/SBuf.h" /* Stub File for the ssl/libsslsquid.la convenience library */ @@ -59,8 +60,8 @@ void MaybeSetupRsaCallback(Security::ContextPointer &) STUB const char *sslGetUserEmail(SSL *ssl) STUB_RETVAL(NULL) const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name) STUB_RETVAL(NULL) const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name) STUB_RETVAL(NULL) -const char *sslGetUserCertificatePEM(SSL *ssl) STUB_RETVAL(NULL) -const char *sslGetUserCertificateChainPEM(SSL *ssl) STUB_RETVAL(NULL) +SBuf sslGetUserCertificatePEM(SSL *ssl) STUB_RETVAL(SBuf()) +SBuf sslGetUserCertificateChainPEM(SSL *ssl) STUB_RETVAL(SBuf()) namespace Ssl { //GETX509ATTRIBUTE GetX509UserAttribute; @@ -75,6 +76,7 @@ int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(vo bool checkX509ServerValidity(X509 *cert, const char *server) STUB_RETVAL(false) int asn1timeToString(ASN1_TIME *tm, char *buf, int len) STUB_RETVAL(0) void setClientSNI(SSL *ssl, const char *fqdn) STUB +SBuf GetX509PEM(SSL *ssl) STUB_RETVAL(SBuf()) } //namespace Ssl #endif diff --git a/test-suite/squidconf/external_acl_type b/test-suite/squidconf/external_acl_type index 1fef7ff686..5274108b97 100644 --- a/test-suite/squidconf/external_acl_type +++ b/test-suite/squidconf/external_acl_type @@ -44,3 +44,4 @@ external_acl_type foo \ # %ssl::>sni # %ssl::