From f97700a0a4865bfae54962b477f2fb74a0ceff13 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Mon, 14 Sep 2015 09:25:05 -0700 Subject: [PATCH] Crypto-NG: replace Ssl::X509_Pointer with Security::CertPointer * shuffle LockingPointer to libsecurity.la along with supporting macros in security/forward.h * add GnuTLS and library agnostic definitions of Security::CertPointer --- src/AccessLogEntry.h | 2 +- src/acl/FilledChecklist.h | 2 +- src/anyp/PortCfg.h | 4 +- src/security/LockingPointer.h | 37 ++++++++++++++++++ src/security/Makefile.am | 1 + src/security/forward.h | 34 +++++++++++++++++ src/ssl/ErrorDetail.h | 9 ++--- src/ssl/PeerConnector.cc | 8 ++-- src/ssl/ServerBump.h | 3 +- src/ssl/cert_validate_message.cc | 2 +- src/ssl/cert_validate_message.h | 4 +- src/ssl/certificate_db.cc | 8 ++-- src/ssl/certificate_db.h | 6 +-- src/ssl/gadgets.cc | 30 +++++++-------- src/ssl/gadgets.h | 65 ++++++-------------------------- src/ssl/ssl_crtd.cc | 2 +- src/ssl/stub_libsslutil.cc | 16 ++++---- src/ssl/support.cc | 14 +++---- src/ssl/support.h | 12 +++--- src/tests/stub_libsslsquid.cc | 4 +- 20 files changed, 144 insertions(+), 119 deletions(-) create mode 100644 src/security/LockingPointer.h diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index f9dbd917cd..e44ee5717a 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -158,7 +158,7 @@ public: #if USE_OPENSSL const char *ssluser; - Ssl::X509_Pointer sslClientCert; ///< cert received from the client + Security::CertPointer sslClientCert; ///< cert received from the client #endif AnyP::PortCfgPointer port; diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 641272513e..8a3bbaf450 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -85,7 +85,7 @@ public: /// SSL [certificate validation] errors, in undefined order Ssl::CertErrors *sslErrors; /// The peer certificate - Ssl::X509_Pointer serverCert; + Security::CertPointer serverCert; #endif AccessLogEntry::Pointer al; ///< info for the future access.log entry diff --git a/src/anyp/PortCfg.h b/src/anyp/PortCfg.h index f1e195117e..e5040d9be2 100644 --- a/src/anyp/PortCfg.h +++ b/src/anyp/PortCfg.h @@ -81,10 +81,10 @@ public: size_t dynamicCertMemCacheSize; ///< max size of generated certificates memory cache Ssl::SSL_CTX_Pointer staticSslContext; ///< for HTTPS accelerator or static sslBump - Ssl::X509_Pointer signingCert; ///< x509 certificate for signing generated certificates + Security::CertPointer signingCert; ///< x509 certificate for signing generated certificates Ssl::EVP_PKEY_Pointer signPkey; ///< private key for sighing generated certificates Ssl::X509_STACK_Pointer certsToChain; ///< x509 certificates to send with the generated cert - Ssl::X509_Pointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates + Security::CertPointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates Ssl::EVP_PKEY_Pointer untrustedSignPkey; ///< private key for signing untrusted generated certificates Ssl::X509_CRL_STACK_Pointer clientVerifyCrls; ///< additional CRL lists to use when verifying the client certificate diff --git a/src/security/LockingPointer.h b/src/security/LockingPointer.h new file mode 100644 index 0000000000..5429f499d3 --- /dev/null +++ b/src/security/LockingPointer.h @@ -0,0 +1,37 @@ +#ifndef SQUID_SRC_SECURITY_LOCKINGPOINTER_H +#define SQUID_SRC_SECURITY_LOCKINGPOINTER_H + +#include "base/TidyPointer.h" + +namespace Security +{ + +/** + * Add SSL locking (a.k.a. reference counting) to TidyPointer + */ +template +class LockingPointer: public TidyPointer +{ +public: + typedef TidyPointer Parent; + + LockingPointer(T *t = nullptr): Parent(t) {} + + void resetAndLock(T *t) { + if (t != this->get()) { + this->reset(t); +#if USE_OPENSSL + if (t) + CRYPTO_add(&t->references, 1, lock); +#elif USE_GNUTLS + // XXX: GnuTLS does not provide locking ? +#else + assert(false); +#endif + } + } +}; + +} // namespace Security + +#endif /* SQUID_SRC_SECURITY_LOCKINGPOINTER_H */ diff --git a/src/security/Makefile.am b/src/security/Makefile.am index 475c094fd8..73865dce02 100644 --- a/src/security/Makefile.am +++ b/src/security/Makefile.am @@ -15,6 +15,7 @@ libsecurity_la_SOURCES= \ EncryptorAnswer.cc \ EncryptorAnswer.h \ forward.h \ + LockingPointer.h \ PeerOptions.cc \ PeerOptions.h \ Session.h diff --git a/src/security/forward.h b/src/security/forward.h index 96204331da..660eb1856a 100644 --- a/src/security/forward.h +++ b/src/security/forward.h @@ -11,6 +11,13 @@ #include "security/Context.h" #include "security/Session.h" +#include "security/LockingPointer.h" + +#if USE_GNUTLS +#if HAVE_GNUTLS_X509_H +#include +#endif +#endif /* flags a SSL connection can be configured with */ #define SSL_FLAG_NO_DEFAULT_CA (1<<0) @@ -21,6 +28,23 @@ #define SSL_FLAG_VERIFY_CRL (1<<5) #define SSL_FLAG_VERIFY_CRL_ALL (1<<6) +// Macro to be used to define the C++ equivalent function of an extern "C" +// function. The C++ function suffixed with the _cpp extension +#define CtoCpp1(function, argument) \ + extern "C++" inline void function ## _cpp(argument a) { \ + function(a); \ + } + +#if USE_OPENSSL +// Macro to be used to define the C++ wrapper function of a sk_*_pop_free +// openssl family functions. The C++ function suffixed with the _free_wrapper +// extension +#define sk_free_wrapper(sk_object, argument, freefunction) \ + extern "C++" inline void sk_object ## _free_wrapper(argument a) { \ + sk_object ## _pop_free(a, freefunction); \ + } +#endif + /// Network/connection security abstraction layer namespace Security { @@ -28,6 +52,16 @@ namespace Security class EncryptorAnswer; class PeerOptions; +#if USE_OPENSSL +CtoCpp1(X509_free, X509 *) +typedef Security::LockingPointer CertPointer; +#elif USE_GNUTLS +CtoCpp1(gnutls_x509_crt_deinit, gnutls_x509_crt_t) +typedef Security::LockingPointer CertPointer; +#else +typedef void * CertPointer; +#endif + } // namespace Security #endif /* SQUID_SRC_SECURITY_FORWARD_H */ diff --git a/src/ssl/ErrorDetail.h b/src/ssl/ErrorDetail.h index 8c4bf8d4d8..d7cfac11e4 100644 --- a/src/ssl/ErrorDetail.h +++ b/src/ssl/ErrorDetail.h @@ -12,10 +12,7 @@ #include "err_detail_type.h" #include "ErrorDetailManager.h" #include "HttpRequest.h" - -#if HAVE_OPENSSL_SSL_H -#include -#endif +#include "security/forward.h" namespace Ssl { @@ -105,8 +102,8 @@ private: mutable String errDetailStr; ///< Caches the error detail message ssl_error_t error_no; ///< The error code unsigned long lib_error_no; ///< low-level error returned by OpenSSL ERR_get_error(3SSL) - X509_Pointer peer_cert; ///< A pointer to the peer certificate - X509_Pointer broken_cert; ///< A pointer to the broken certificate (peer or intermediate) + Security::CertPointer peer_cert; ///< A pointer to the peer certificate + Security::CertPointer broken_cert; ///< A pointer to the broken certificate (peer or intermediate) String errReason; ///< A custom reason for error, else retrieved from OpenSSL. mutable ErrorDetailEntry detailEntry; HttpRequest::Pointer request; diff --git a/src/ssl/PeerConnector.cc b/src/ssl/PeerConnector.cc index 4466805c1d..53774cb6da 100644 --- a/src/ssl/PeerConnector.cc +++ b/src/ssl/PeerConnector.cc @@ -366,7 +366,7 @@ Ssl::PeerConnector::sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &re } else { debugs(83, 5, "confirming SSL error " << i->error_no); X509 *brokenCert = i->cert.get(); - Ssl::X509_Pointer peerCert(SSL_get_peer_certificate(ssl)); + Security::CertPointer peerCert(SSL_get_peer_certificate(ssl)); const char *aReason = i->error_reason.empty() ? NULL : i->error_reason.c_str(); errDetails = new Ssl::ErrorDetail(i->error_no, peerCert.get(), brokenCert, aReason); } @@ -805,7 +805,7 @@ Ssl::PeekingPeerConnector::noteSslNegotiationError(const int result, const int s // unsupported server Hello message (TODO: make configurable). if (!SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) && (srvBio->bumpMode() == Ssl::bumpPeek || srvBio->bumpMode() == Ssl::bumpStare) && srvBio->holdWrite()) { - Ssl::X509_Pointer serverCert(SSL_get_peer_certificate(ssl)); + Security::CertPointer serverCert(SSL_get_peer_certificate(ssl)); if (serverCert.get()) { debugs(81, 3, "Error (" << ERR_error_string(ssl_lib_error, NULL) << ") but, hold write on SSL connection on FD " << fd); checkForPeekAndSplice(); @@ -826,7 +826,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() if (ConnStateData *csd = request->clientConnectionManager.valid()) { const int fd = serverConnection()->fd; SSL *ssl = fd_table[fd].ssl; - Ssl::X509_Pointer serverCert(SSL_get_peer_certificate(ssl)); + Security::CertPointer serverCert(SSL_get_peer_certificate(ssl)); if (!serverCert.get()) return; @@ -843,7 +843,7 @@ void Ssl::PeekingPeerConnector::serverCertificateVerified() { if (ConnStateData *csd = request->clientConnectionManager.valid()) { - Ssl::X509_Pointer serverCert; + Security::CertPointer serverCert; if(Ssl::ServerBump *serverBump = csd->serverBump()) serverCert.resetAndLock(serverBump->serverCert.get()); else { diff --git a/src/ssl/ServerBump.h b/src/ssl/ServerBump.h index 01d58b90af..ba6999f452 100644 --- a/src/ssl/ServerBump.h +++ b/src/ssl/ServerBump.h @@ -14,6 +14,7 @@ #include "comm/forward.h" #include "HttpRequest.h" #include "ip/Address.h" +#include "security/forward.h" class ConnStateData; class store_client; @@ -35,7 +36,7 @@ public: /// faked, minimal request; required by Client API HttpRequest::Pointer request; StoreEntry *entry; ///< for receiving Squid-generated error messages - Ssl::X509_Pointer serverCert; ///< HTTPS server certificate + Security::CertPointer serverCert; ///< HTTPS server certificate Ssl::CertErrors *sslErrors; ///< SSL [certificate validation] errors struct { Ssl::BumpMode step1; ///< The SSL bump mode at step1 diff --git a/src/ssl/cert_validate_message.cc b/src/ssl/cert_validate_message.cc index ca45e5b5a7..071795d28a 100644 --- a/src/ssl/cert_validate_message.cc +++ b/src/ssl/cert_validate_message.cc @@ -95,7 +95,7 @@ Ssl::CertValidationMsg::parseResponse(CertValidationResponse &resp, STACK_OF(X50 strncmp(param, param_cert.c_str(), param_cert.length()) == 0) { CertItem ci; ci.name.assign(param, param_len); - X509_Pointer x509; + Security::CertPointer x509; readCertFromMemory(x509, value); ci.setCert(x509.get()); certs.push_back(ci); diff --git a/src/ssl/cert_validate_message.h b/src/ssl/cert_validate_message.h index 79edea4ab5..3fcd6b7df2 100644 --- a/src/ssl/cert_validate_message.h +++ b/src/ssl/cert_validate_message.h @@ -52,7 +52,7 @@ public: int id; ///< The id of the error ssl_error_t error_no; ///< The OpenSSL error code std::string error_reason; ///< A string describing the error - X509_Pointer cert; ///< The broken certificate + Security::CertPointer cert; ///< The broken certificate }; typedef std::vector RecvdErrors; @@ -81,7 +81,7 @@ private: { public: std::string name; ///< The certificate Id to use - X509_Pointer cert; ///< A pointer to certificate + Security::CertPointer cert; ///< A pointer to certificate CertItem(): cert(NULL) {} CertItem(const CertItem &); CertItem & operator =(const CertItem &); diff --git a/src/ssl/certificate_db.cc b/src/ssl/certificate_db.cc index fc2cf6197b..601b6fd018 100644 --- a/src/ssl/certificate_db.cc +++ b/src/ssl/certificate_db.cc @@ -263,7 +263,7 @@ Ssl::CertificateDb::CertificateDb(std::string const & aDb_path, size_t aMax_db_s throw std::runtime_error("ssl_crtd is missing the required parameter. There should be -s and -M parameters together."); } -bool Ssl::CertificateDb::find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey) { +bool Ssl::CertificateDb::find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey) { const Locker locker(dbLock, Here); load(); return pure_find(host_name, cert, pkey); @@ -282,7 +282,7 @@ bool Ssl::CertificateDb::purgeCert(std::string const & key) { return true; } -bool Ssl::CertificateDb::addCertAndPrivateKey(Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey, std::string const & useName) { +bool Ssl::CertificateDb::addCertAndPrivateKey(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, std::string const & useName) { const Locker locker(dbLock, Here); load(); if (!db || !cert || !pkey) @@ -306,7 +306,7 @@ bool Ssl::CertificateDb::addCertAndPrivateKey(Ssl::X509_Pointer & cert, Ssl::EVP { TidyPointer subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), NULL, 0)); - Ssl::X509_Pointer findCert; + Security::CertPointer findCert; Ssl::EVP_PKEY_Pointer findPkey; if (pure_find(useName.empty() ? subject.get() : useName, findCert, findPkey)) { // Replace with database certificate @@ -427,7 +427,7 @@ size_t Ssl::CertificateDb::rebuildSize() return dbSize; } -bool Ssl::CertificateDb::pure_find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey) { +bool Ssl::CertificateDb::pure_find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey) { if (!db) return false; diff --git a/src/ssl/certificate_db.h b/src/ssl/certificate_db.h index 96e8e8bec9..c61699a34f 100644 --- a/src/ssl/certificate_db.h +++ b/src/ssl/certificate_db.h @@ -98,11 +98,11 @@ public: CertificateDb(std::string const & db_path, size_t aMax_db_size, size_t aFs_block_size); /// Find certificate and private key for host name - bool find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey); + bool find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey); /// Delete a certificate from database bool purgeCert(std::string const & key); /// Save certificate to disk. - bool addCertAndPrivateKey(Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey, std::string const & useName); + bool addCertAndPrivateKey(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, std::string const & useName); /// Create and initialize a database under the db_path static void create(std::string const & db_path); /// Check the database stored under the db_path. @@ -121,7 +121,7 @@ private: size_t getFileSize(std::string const & filename); ///< get file size on disk. size_t rebuildSize(); ///< Rebuild size_file /// Only find certificate in current db and return it. - bool pure_find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey); + bool pure_find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey); void deleteRow(const char **row, int rowIndex); ///< Delete a row from TXT_DB bool deleteInvalidCertificate(); ///< Delete invalid certificate. diff --git a/src/ssl/gadgets.cc b/src/ssl/gadgets.cc index 5729ad323f..9b552d7e3a 100644 --- a/src/ssl/gadgets.cc +++ b/src/ssl/gadgets.cc @@ -56,7 +56,7 @@ static bool setSerialNumber(ASN1_INTEGER *ai, BIGNUM const* serial) return true; } -bool Ssl::writeCertAndPrivateKeyToMemory(Ssl::X509_Pointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite) +bool Ssl::writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite) { bufferToWrite.clear(); if (!pkey || !cert) @@ -80,7 +80,7 @@ bool Ssl::writeCertAndPrivateKeyToMemory(Ssl::X509_Pointer const & cert, Ssl::EV return true; } -bool Ssl::appendCertToMemory(Ssl::X509_Pointer const & cert, std::string & bufferToWrite) +bool Ssl::appendCertToMemory(Security::CertPointer const & cert, std::string & bufferToWrite) { if (!cert) return false; @@ -104,7 +104,7 @@ bool Ssl::appendCertToMemory(Ssl::X509_Pointer const & cert, std::string & buffe return true; } -bool Ssl::writeCertAndPrivateKeyToFile(Ssl::X509_Pointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, char const * filename) +bool Ssl::writeCertAndPrivateKeyToFile(Security::CertPointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, char const * filename) { if (!pkey || !cert) return false; @@ -124,7 +124,7 @@ bool Ssl::writeCertAndPrivateKeyToFile(Ssl::X509_Pointer const & cert, Ssl::EVP_ return true; } -bool Ssl::readCertAndPrivateKeyFromMemory(Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey, char const * bufferToRead) +bool Ssl::readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, char const * bufferToRead) { Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem())); BIO_puts(bio.get(), bufferToRead); @@ -142,7 +142,7 @@ bool Ssl::readCertAndPrivateKeyFromMemory(Ssl::X509_Pointer & cert, Ssl::EVP_PKE return true; } -bool Ssl::readCertFromMemory(X509_Pointer & cert, char const * bufferToRead) +bool Ssl::readCertFromMemory(Security::CertPointer & cert, char const * bufferToRead) { Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem())); BIO_puts(bio.get(), bufferToRead); @@ -160,7 +160,7 @@ bool Ssl::readCertFromMemory(X509_Pointer & cert, char const * bufferToRead) static const size_t MaxCnLen = 64; // Replace certs common name with the given -static bool replaceCommonName(Ssl::X509_Pointer & cert, std::string const &rawCn) +static bool replaceCommonName(Security::CertPointer & cert, std::string const &rawCn) { std::string cn = rawCn; @@ -270,7 +270,7 @@ std::string & Ssl::CertificateProperties::dbKey() const // mimicked. More safe to mimic extensions would be added here if users request // them. static int -mimicExtensions(Ssl::X509_Pointer & cert, Ssl::X509_Pointer const & mimicCert) +mimicExtensions(Security::CertPointer & cert, Security::CertPointer const & mimicCert) { static int extensions[]= { NID_key_usage, @@ -339,7 +339,7 @@ mimicExtensions(Ssl::X509_Pointer & cert, Ssl::X509_Pointer const & mimicCert) return added; } -static bool buildCertificate(Ssl::X509_Pointer & cert, Ssl::CertificateProperties const &properties) +static bool buildCertificate(Security::CertPointer & cert, Ssl::CertificateProperties const &properties) { // not an Ssl::X509_NAME_Pointer because X509_REQ_get_subject_name() // returns a pointer to the existing subject name. Nothing to clean here. @@ -419,7 +419,7 @@ static bool buildCertificate(Ssl::X509_Pointer & cert, Ssl::CertificatePropertie return true; } -static bool generateFakeSslCertificate(Ssl::X509_Pointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties, Ssl::BIGNUM_Pointer const &serial) +static bool generateFakeSslCertificate(Security::CertPointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties, Ssl::BIGNUM_Pointer const &serial) { Ssl::EVP_PKEY_Pointer pkey; // Use signing certificates private key as generated certificate private key @@ -431,7 +431,7 @@ static bool generateFakeSslCertificate(Ssl::X509_Pointer & certToStore, Ssl::EVP if (!pkey) return false; - Ssl::X509_Pointer cert(X509_new()); + Security::CertPointer cert(X509_new()); if (!cert) return false; @@ -499,7 +499,7 @@ static BIGNUM *createCertSerial(unsigned char *md, unsigned int n) /// Return the SHA1 digest of the DER encoded version of the certificate /// stored in a BIGNUM -static BIGNUM *x509Digest(Ssl::X509_Pointer const & cert) +static BIGNUM *x509Digest(Security::CertPointer const & cert) { unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; @@ -510,7 +510,7 @@ static BIGNUM *x509Digest(Ssl::X509_Pointer const & cert) return createCertSerial(md, n); } -static BIGNUM *x509Pubkeydigest(Ssl::X509_Pointer const & cert) +static BIGNUM *x509Pubkeydigest(Security::CertPointer const & cert) { unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; @@ -526,7 +526,7 @@ static BIGNUM *x509Pubkeydigest(Ssl::X509_Pointer const & cert) static bool createSerial(Ssl::BIGNUM_Pointer &serial, Ssl::CertificateProperties const &properties) { Ssl::EVP_PKEY_Pointer fakePkey; - Ssl::X509_Pointer fakeCert; + Security::CertPointer fakeCert; serial.reset(x509Pubkeydigest(properties.signWithX509)); if (!serial.get()) { @@ -547,7 +547,7 @@ static bool createSerial(Ssl::BIGNUM_Pointer &serial, Ssl::CertificateProperties return true; } -bool Ssl::generateSslCertificate(Ssl::X509_Pointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties) +bool Ssl::generateSslCertificate(Security::CertPointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties) { Ssl::BIGNUM_Pointer serial; @@ -587,7 +587,7 @@ EVP_PKEY * Ssl::readSslPrivateKey(char const * keyFilename, pem_password_cb *pas return pkey; } -void Ssl::readCertAndPrivateKeyFromFiles(Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename) +void Ssl::readCertAndPrivateKeyFromFiles(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename) { if (keyFilename == NULL) keyFilename = certFilename; diff --git a/src/ssl/gadgets.h b/src/ssl/gadgets.h index e3bd0b4fa5..7d9e1d2990 100644 --- a/src/ssl/gadgets.h +++ b/src/ssl/gadgets.h @@ -9,12 +9,9 @@ #ifndef SQUID_SSL_GADGETS_H #define SQUID_SSL_GADGETS_H -#include "base/TidyPointer.h" +#include "security/forward.h" #include "ssl/crtd_message.h" -#if HAVE_OPENSSL_SSL_H -#include -#endif #if HAVE_OPENSSL_TXT_DB_H #include #endif @@ -38,55 +35,15 @@ typedef SSL_METHOD * ContextMethod; #define SQUID_SSL_SIGN_HASH_IF_NONE "sha256" #endif -/** - \ingroup SslCrtdSslAPI - * Add SSL locking (a.k.a. reference counting) to TidyPointer - */ -template -class LockingPointer: public TidyPointer -{ -public: - typedef TidyPointer Parent; - - LockingPointer(T *t = NULL): Parent(t) { - } - - void resetAndLock(T *t) { - if (t != this->get()) { - this->reset(t); - if (t) - CRYPTO_add(&t->references, 1, lock); - } - } -}; - -// Macro to be used to define the C++ equivalent function of an extern "C" -// function. The C++ function suffixed with the _cpp extension -#define CtoCpp1(function, argument) \ - extern "C++" inline void function ## _cpp(argument a) { \ - function(a); \ - } - -// Macro to be used to define the C++ wrapper function of a sk_*_pop_free -// openssl family functions. The C++ function suffixed with the _free_wrapper -// extension -#define sk_free_wrapper(sk_object, argument, freefunction) \ - extern "C++" inline void sk_object ## _free_wrapper(argument a) { \ - sk_object ## _pop_free(a, freefunction); \ - } - /** \ingroup SslCrtdSslAPI * TidyPointer typedefs for common SSL objects */ -CtoCpp1(X509_free, X509 *) -typedef LockingPointer X509_Pointer; - sk_free_wrapper(sk_X509, STACK_OF(X509) *, X509_free) typedef TidyPointer X509_STACK_Pointer; CtoCpp1(EVP_PKEY_free, EVP_PKEY *) -typedef LockingPointer EVP_PKEY_Pointer; +typedef Security::LockingPointer EVP_PKEY_Pointer; CtoCpp1(BN_free, BIGNUM *) typedef TidyPointer BIGNUM_Pointer; @@ -134,31 +91,31 @@ EVP_PKEY * createSslPrivateKey(); \ingroup SslCrtdSslAPI * Write private key and SSL certificate to memory. */ -bool writeCertAndPrivateKeyToMemory(X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite); +bool writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite); /** \ingroup SslCrtdSslAPI * Append SSL certificate to bufferToWrite. */ -bool appendCertToMemory(X509_Pointer const & cert, std::string & bufferToWrite); +bool appendCertToMemory(Security::CertPointer const & cert, std::string & bufferToWrite); /** \ingroup SslCrtdSslAPI * Write private key and SSL certificate to file. */ -bool writeCertAndPrivateKeyToFile(X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey, char const * filename); +bool writeCertAndPrivateKeyToFile(Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey, char const * filename); /** \ingroup SslCrtdSslAPI * Write private key and SSL certificate to memory. */ -bool readCertAndPrivateKeyFromMemory(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, char const * bufferToRead); +bool readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, char const * bufferToRead); /** \ingroup SslCrtdSslAPI * Read SSL certificate from memory. */ -bool readCertFromMemory(X509_Pointer & cert, char const * bufferToRead); +bool readCertFromMemory(Security::CertPointer & cert, char const * bufferToRead); /** \ingroup SslCrtdSslAPI @@ -230,8 +187,8 @@ class CertificateProperties { public: CertificateProperties(); - X509_Pointer mimicCert; ///< Certificate to mimic - X509_Pointer signWithX509; ///< Certificate to sign the generated request + Security::CertPointer mimicCert; ///< Certificate to mimic + Security::CertPointer signWithX509; ///< Certificate to sign the generated request EVP_PKEY_Pointer signWithPkey; ///< The key of the signing certificate bool setValidAfter; ///< Do not mimic "Not Valid After" field bool setValidBefore; ///< Do not mimic "Not Valid Before" field @@ -254,7 +211,7 @@ private: * Return generated certificate and private key in resultX509 and resultPkey * variables. */ -bool generateSslCertificate(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, CertificateProperties const &properties); +bool generateSslCertificate(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, CertificateProperties const &properties); /** \ingroup SslCrtdSslAPI @@ -268,7 +225,7 @@ EVP_PKEY * readSslPrivateKey(char const * keyFilename, pem_password_cb *passwd_c * \param certFilename name of file with certificate. * \param keyFilename name of file with private key. */ -void readCertAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename); +void readCertAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename); /** \ingroup SslCrtdSslAPI diff --git a/src/ssl/ssl_crtd.cc b/src/ssl/ssl_crtd.cc index 41042ebdbc..622f0594e6 100644 --- a/src/ssl/ssl_crtd.cc +++ b/src/ssl/ssl_crtd.cc @@ -201,7 +201,7 @@ static bool proccessNewRequest(Ssl::CrtdMessage & request_message, std::string c Ssl::CertificateDb db(db_path, max_db_size, fs_block_size); - Ssl::X509_Pointer cert; + Security::CertPointer cert; Ssl::EVP_PKEY_Pointer pkey; std::string &cert_subject = certProperties.dbKey(); diff --git a/src/ssl/stub_libsslutil.cc b/src/ssl/stub_libsslutil.cc index c036adcee4..76fee86074 100644 --- a/src/ssl/stub_libsslutil.cc +++ b/src/ssl/stub_libsslutil.cc @@ -31,14 +31,14 @@ void Ssl::CrtdMessage::parseBody(BodyParams & map, std::string & other_part) con void Ssl::CrtdMessage::composeBody(BodyParams const & map, std::string const & other_part) STUB #include "ssl/gadgets.h" -X509_REQ * Ssl::createNewX509Request(EVP_PKEY_Pointer const & pkey, const char * hostname) STUB_RETVAL(NULL) -bool Ssl::writeCertAndPrivateKeyToMemory(X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite) STUB_RETVAL(false) -bool Ssl::writeCertAndPrivateKeyToFile(X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey, char const * filename) STUB_RETVAL(false) -bool Ssl::readCertAndPrivateKeyFromMemory(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, char const * bufferToRead) STUB_RETVAL(false) -X509 * Ssl::signRequest(X509_REQ_Pointer const & request, X509_Pointer const & x509, EVP_PKEY_Pointer const & pkey, ASN1_TIME * timeNotAfter, BIGNUM const * serial) STUB_RETVAL(NULL) -bool Ssl::generateSslCertificateAndPrivateKey(char const *host, X509_Pointer const & signedX509, EVP_PKEY_Pointer const & signedPkey, X509_Pointer & cert, EVP_PKEY_Pointer & pkey, BIGNUM const* serial) STUB_RETVAL(false) -void Ssl::readCertAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, char const * certFilename, char const * keyFilename) STUB -bool Ssl::sslDateIsInTheFuture(char const * date) STUB_RETVAL(false) +X509_REQ * Ssl::createNewX509Request(EVP_PKEY_Pointer const &, const char *) STUB_RETVAL(NULL) +bool Ssl::writeCertAndPrivateKeyToMemory(Security::CertPointer const &, EVP_PKEY_Pointer const &, std::string &) STUB_RETVAL(false) +bool Ssl::writeCertAndPrivateKeyToFile(Security::CertPointer const &, EVP_PKEY_Pointer const &, char const *) STUB_RETVAL(false) +bool Ssl::readCertAndPrivateKeyFromMemory(Security::CertPointer &, EVP_PKEY_Pointer &, char const *) STUB_RETVAL(false) +X509 * Ssl::signRequest(X509_REQ_Pointer const &, Security::CertPointer const &, EVP_PKEY_Pointer const &, ASN1_TIME *, BIGNUM const *) STUB_RETVAL(NULL) +bool Ssl::generateSslCertificateAndPrivateKey(char const *, Security::CertPointer const &, EVP_PKEY_Pointer const &, Security::CertPointer &, EVP_PKEY_Pointer &, BIGNUM const *) STUB_RETVAL(false) +void Ssl::readCertAndPrivateKeyFromFiles(Security::CertPointer &, EVP_PKEY_Pointer &, char const *, char const *) STUB +bool Ssl::sslDateIsInTheFuture(char const *) STUB_RETVAL(false) #include "ssl/helper.h" Ssl::Helper * Ssl::Helper::GetInstance() STUB_RETVAL(NULL) diff --git a/src/ssl/support.cc b/src/ssl/support.cc index dce31c9d9d..52afe8a0cd 100644 --- a/src/ssl/support.cc +++ b/src/ssl/support.cc @@ -1132,7 +1132,7 @@ sslGetUserCertificateChainPEM(SSL *ssl) /// \ingroup ServerProtocolSSLInternal /// Create SSL context and apply ssl certificate and private key to it. SSL_CTX * -Ssl::createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port) +Ssl::createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port) { #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) Ssl::SSL_CTX_Pointer sslContext(SSL_CTX_new(TLS_server_method())); @@ -1155,7 +1155,7 @@ Ssl::createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & pkey, An SSL_CTX * Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port) { - Ssl::X509_Pointer cert; + Security::CertPointer cert; Ssl::EVP_PKEY_Pointer pkey; if (!readCertAndPrivateKeyFromMemory(cert, pkey, data)) return NULL; @@ -1169,7 +1169,7 @@ Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortC SSL_CTX * Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port) { - Ssl::X509_Pointer cert; + Security::CertPointer cert; Ssl::EVP_PKEY_Pointer pkey; if (!generateSslCertificate(cert, pkey, properties)) return NULL; @@ -1186,7 +1186,7 @@ Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg & bool Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port) { - Ssl::X509_Pointer cert; + Security::CertPointer cert; Ssl::EVP_PKEY_Pointer pkey; if (!generateSslCertificate(cert, pkey, properties)) return false; @@ -1209,7 +1209,7 @@ Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortC bool Ssl::configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port) { - Ssl::X509_Pointer cert; + Security::CertPointer cert; Ssl::EVP_PKEY_Pointer pkey; if (!readCertAndPrivateKeyFromMemory(cert, pkey, data)) return false; @@ -1320,7 +1320,7 @@ static X509 * readSslX509CertificatesChain(char const * certFilename, STACK_OF( return certificate; } -void Ssl::readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename) +void Ssl::readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename) { if (keyFilename == NULL) keyFilename = certFilename; @@ -1345,7 +1345,7 @@ void Ssl::readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Poin } } -bool Ssl::generateUntrustedCert(X509_Pointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, X509_Pointer const &cert, EVP_PKEY_Pointer const & pkey) +bool Ssl::generateUntrustedCert(Security::CertPointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, Security::CertPointer const &cert, EVP_PKEY_Pointer const & pkey) { // Generate the self-signed certificate, using a hard-coded subject prefix Ssl::CertificateProperties certProperties; diff --git a/src/ssl/support.h b/src/ssl/support.h index 1d754c8361..8a9c80feb9 100644 --- a/src/ssl/support.h +++ b/src/ssl/support.h @@ -12,11 +12,9 @@ #define SQUID_SSL_SUPPORT_H #include "base/CbDataList.h" +#include "security/forward.h" #include "ssl/gadgets.h" -#if HAVE_OPENSSL_SSL_H -#include -#endif #if HAVE_OPENSSL_X509V3_H #include #endif @@ -75,7 +73,7 @@ class CertError { public: ssl_error_t code; ///< certificate error code - X509_Pointer cert; ///< certificate with the above error code + Security::CertPointer cert; ///< certificate with the above error code CertError(ssl_error_t anErr, X509 *aCert); CertError(CertError const &err); CertError & operator = (const CertError &old); @@ -173,7 +171,7 @@ DH *readDHParams(const char *dhfile); \ingroup ServerProtocolSSLAPI * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA */ -bool generateUntrustedCert(X509_Pointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey); +bool generateUntrustedCert(Security::CertPointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey); /** \ingroup ServerProtocolSSLAPI @@ -201,7 +199,7 @@ SSL_CTX * generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP:: \ingroup ServerProtocolSSLAPI * Create an SSL context using the provided certificate and key */ -SSL_CTX * createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port); +SSL_CTX * createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port); /** \ingroup ServerProtocolSSLAPI @@ -230,7 +228,7 @@ void addChainToSslContext(SSL_CTX *sslContext, STACK_OF(X509) *certList); * \param certFilename name of file with certificate and certificates which must be chainned. * \param keyFilename name of file with private key. */ -void readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename); +void readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename); /** \ingroup ServerProtocolSSLAPI diff --git a/src/tests/stub_libsslsquid.cc b/src/tests/stub_libsslsquid.cc index a805db513a..34225e06f6 100644 --- a/src/tests/stub_libsslsquid.cc +++ b/src/tests/stub_libsslsquid.cc @@ -74,12 +74,12 @@ namespace Ssl const char *BumpModeStr[] = {""}; STACK_OF(X509_CRL) *loadCrl(const char *CRLFile, long &flags) STUB_RETVAL(NULL) DH *readDHParams(const char *dhfile) STUB_RETVAL(NULL) -bool generateUntrustedCert(X509_Pointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey) STUB_RETVAL(false) +bool generateUntrustedCert(Security::CertPointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey) STUB_RETVAL(false) SSL_CTX * generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port) STUB_RETVAL(NULL) bool verifySslCertificate(SSL_CTX * sslContext, CertificateProperties const &properties) STUB_RETVAL(false) SSL_CTX * generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port) STUB_RETVAL(NULL) void addChainToSslContext(SSL_CTX *sslContext, STACK_OF(X509) *certList) STUB -void readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename) STUB +void readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename) STUB int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data)) STUB_RETVAL(0) bool checkX509ServerValidity(X509 *cert, const char *server) STUB_RETVAL(false) int asn1timeToString(ASN1_TIME *tm, char *buf, int len) STUB_RETVAL(0) -- 2.47.3