78 return *untrustedCerts;
88 if (
const auto ip = name.
ip())
90 Assure(!
"unreachable code: the above `if` statements must cover all name variants");
99 debugs(83, 5,
"needle=" << needle_ <<
" domain=" << rawName);
102 debugs(83, 7,
"needle is an IP; mismatch");
106 Assure(needle_.domainName());
107 auto domainNeedle = *needle_.domainName();
110 if (name.length() > 0 && name[0] ==
'*')
118 debugs(83, 5,
"needle=" << needle_ <<
" ip=" << ip);
119 if (
const auto needleIp = needle_.ip())
120 return (*needleIp == ip);
121 debugs(83, 7,
"needle is not an IP; mismatch");
137 snprintf(cmdline,
sizeof(cmdline),
"\"%s\" \"%s\"", ::Config.Program.ssl_password, (
const char *)userdata);
138 in = popen(cmdline,
"r");
140 if (fgets(buf,
size, in))
144 while (len > 0 && (buf[len - 1] ==
'\n' || buf[len - 1] ==
'\r'))
160 SSL_CTX_set_default_passwd_cb_userdata(context, (
void *)prompt);
164#if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
166ssl_temp_rsa_cb(SSL *,
int,
int keylen)
168 static RSA *rsa_512 =
nullptr;
169 static RSA *rsa_1024 =
nullptr;
170 static BIGNUM *e =
nullptr;
176 if (!e || !BN_set_word(e, RSA_F4)) {
177 debugs(83,
DBG_IMPORTANT,
"ERROR: ssl_temp_rsa_cb: Failed to set exponent for key " << keylen);
190 if (rsa_512 && RSA_generate_key_ex(rsa_512, 512, e,
nullptr)) {
204 rsa_1024 = RSA_new();
205 if (rsa_1024 && RSA_generate_key_ex(rsa_1024, 1024, e,
nullptr)) {
228 PEM_write_RSAPrivateKey(
DebugStream(), rsa,
nullptr,
nullptr, 0,
nullptr,
nullptr);
240#if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
241 debugs(83, 9,
"Setting RSA key generation callback.");
242 SSL_CTX_set_tmp_rsa_callback(ctx.get(), ssl_temp_rsa_cb);
252 bio = BIO_new(BIO_s_mem());
254 if (ASN1_TIME_print(bio, tm))
255 write = BIO_read(bio, buf, len-1);
262static std::optional<AnyP::Host>
280 if (san.d.iPAddress->length == 4) {
282 static_assert(
sizeof(addr.s_addr) == 4);
283 memcpy(&addr.s_addr, san.d.iPAddress->data,
sizeof(addr.s_addr));
288 if (san.d.iPAddress->length == 16) {
289 struct in6_addr addr;
290 static_assert(
sizeof(addr.s6_addr) == 16);
291 memcpy(&addr.s6_addr, san.d.iPAddress->data,
sizeof(addr.s6_addr));
296 debugs(83, 3,
"unexpected length of an IP address SAN: " << san.d.iPAddress->length);
301 debugs(83, 3,
"unsupported SAN kind: " << san.type);
309 const auto name = X509_get_subject_name(&cert);
310 for (
int i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); i >= 0; i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) {
311 debugs(83, 7,
"checking CN at " << i);
313 if (matcher.
match(*cn))
319 X509_get_ext_d2i(&cert, NID_subject_alt_name,
nullptr,
nullptr)));
321 const auto sanCount = sk_GENERAL_NAME_num(sans.get());
322 for (
int i = 0; i < sanCount; ++i) {
323 debugs(83, 7,
"checking SAN at " << i);
324 const auto rawSan = sk_GENERAL_NAME_value(sans.get(), i);
327 if (matcher.
match(*san))
333 debugs(83, 7,
"no matches");
351 SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
352 SSL_CTX *sslctx = SSL_get_SSL_CTX(ssl);
362 if (!validationCounter) {
363 validationCounter =
new uint32_t(1);
367 (*validationCounter)++;
373 debugs(83, 2,
"SQUID_X509_V_ERR_INFINITE_VALIDATION: " <<
374 *validationCounter <<
" iterations while checking " << *peer_cert);
378 debugs(83, 5,
"SSL Certificate signature OK: " << *peer_cert);
381 if (!dont_verify_domain &&
server && peer_cert.
get() == X509_STORE_CTX_get_current_cert(ctx)) {
388 debugs(83, 5,
"certificate subject matches " << *host);
390 debugs(83, 2,
"SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << *peer_cert <<
" does not match domainname " << *host);
395 debugs(83, 2,
"SQUID_X509_V_ERR_DOMAIN_MISMATCH: Cannot check whether certificate " << *peer_cert <<
" subject matches malformed domainname " << *
server);
402 if (ok && peeked_cert) {
404 if (X509_cmp(peer_cert.
get(), peeked_cert) != 0) {
405 debugs(83, 2,
"SQUID_X509_V_ERR_CERT_CHANGE: Certificate " << *peer_cert <<
" does not match peeked certificate");
411 if (!ok && error_no == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
413 if (params->callerHandlesMissingCertificates) {
414 debugs(83, 3,
"hiding X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY");
415 params->hidMissingIssuer =
true;
423 broken_cert.
resetAndLock(X509_STORE_CTX_get_current_cert(ctx));
425 broken_cert = peer_cert;
428 const int depth = X509_STORE_CTX_get_error_depth(ctx);
432 debugs(83, 2,
"Failed to set ssl error_no in ssl_verify_cb: Certificate " << *peer_cert);
440 debugs(83, 5, *description <<
": " << *peer_cert);
442 debugs(83,
DBG_IMPORTANT,
"ERROR: SSL unknown certificate error " << error_no <<
" in " << *peer_cert);
449 const auto savedErrors = filledCheck->
sslErrors;
450 const auto sslErrors = std::make_unique<Security::CertErrors>(
Security::CertError(error_no, broken_cert));
451 filledCheck->
sslErrors = sslErrors.get();
454 debugs(83, 3,
"bypassing SSL error " << error_no <<
" in " << *peer_cert);
457 debugs(83, 5,
"confirming SSL error " << error_no);
473 STACK_OF(X509) *certStack = X509_STORE_CTX_get1_chain(ctx);
475 sk_X509_pop_free(certStack, X509_free);
485 if (
auto *last_used_cert = X509_STORE_CTX_get_current_cert(ctx))
494 debugs(83, 2,
"failed to store a " << *peer_cert <<
" error detail: " << *edp);
507 debugs(83,
DBG_IMPORTANT,
"SECURITY WARNING: Peer certificates are not verified for validity!");
508 debugs(83,
DBG_IMPORTANT,
"WARNING: UPGRADE: The DONT_VERIFY_PEER flag is deprecated. Remove the clientca= option to disable client certificates.");
509 mode = SSL_VERIFY_NONE;
513 mode = SSL_VERIFY_PEER;
517 mode = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
520 SSL_CTX_set_verify(ctx.get(), mode, (mode != SSL_VERIFY_NONE) ?
ssl_verify_cb :
nullptr);
527 SSL_CTX_set_verify(ctx.get(),SSL_VERIFY_NONE,
nullptr);
535 const auto peerCertificatesChain = SSL_get_peer_cert_chain(&sconn);
545 if (!peerCertificatesChain || sk_X509_num(peerCertificatesChain) == 0) {
546 debugs(83, 2,
"no server certificates");
550 const auto verificationStore = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(&sconn));
551 if (!verificationStore) {
552 debugs(83, 2,
"no certificate store");
558 debugs(83, 2,
"cannot create X509_STORE_CTX; likely OOM");
562 const auto peerCert = sk_X509_value(peerCertificatesChain, 0);
563 if (!X509_STORE_CTX_init(storeCtx.get(), verificationStore, peerCert, peerCertificatesChain)) {
564 debugs(83, 2,
"cannot initialize X509_STORE_CTX");
568#if defined(SSL_CERT_FLAG_SUITEB_128_LOS)
572 const unsigned long certFlags = SSL_set_cert_flags(&sconn, 0);
573 if (
const auto suiteBflags = certFlags & SSL_CERT_FLAG_SUITEB_128_LOS)
574 X509_STORE_CTX_set_flags(storeCtx.get(), suiteBflags);
577 if (!X509_STORE_CTX_set_ex_data(storeCtx.get(), SSL_get_ex_data_X509_STORE_CTX_idx(), &sconn)) {
578 debugs(83, 2,
"cannot attach SSL object to X509_STORE_CTX");
586 if (!X509_STORE_CTX_set_default(storeCtx.get(),
"ssl_server")) {
587 debugs(83, 2,
"cannot set default verification method to ssl_server");
592 const auto param = X509_STORE_CTX_get0_param(storeCtx.get());
594 debugs(83, 2,
"no context verification parameters");
597#if defined(HAVE_X509_VERIFY_PARAM_SET_AUTH_LEVEL)
598 X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(&sconn));
601 debugs(83, 2,
"cannot overwrite context verification parameters");
607 if (
const auto cb = SSL_get_verify_callback(&sconn))
608 X509_STORE_CTX_set_verify_cb(storeCtx.get(), cb);
613 const auto verifyResult = X509_STORE_CTX_get_error(storeCtx.get());
614 debugs(83, 3,
"verification failure: " << verifyResult <<
' ' << X509_verify_cert_error_string(verifyResult));
645 const auto parameters = Find(sconn);
651#if OPENSSL_VERSION_MAJOR >= 3
655#elif SQUID_USE_CONST_CRYPTO_EX_DATA_DUP
701 uint32_t *counter =
static_cast <uint32_t *
>(ptr);
713 sk_X509_pop_free(certsChain,X509_free);
721 X509 *cert =
static_cast <X509 *
>(ptr);
730 SBuf *buf =
static_cast <SBuf *
>(ptr);
745 static bool initialized =
false;
753#if OPENSSL_VERSION_MAJOR < 3
755 "in Squids built with OpenSSL 1.x (like this Squid). " <<
756 "It is removed in Squids built with OpenSSL 3.0 or newer.");
757#if !defined(OPENSSL_NO_ENGINE)
758 ENGINE_load_builtin_engines();
763 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
764 const auto ssl_error = ERR_get_error();
768 throw TextException(
"Cannot use ssl_engine in Squid built with OpenSSL configured to disable SSL engine support",
Here());
772 throw TextException(
"Cannot use ssl_engine in Squid built with OpenSSL 3.0 or newer",
Here());
779 fatalf(
"Sign hash '%s' is not supported\n", defName);
811 if (!SSL_CTX_set_cipher_list(ctx.get(), cipher)) {
812 const auto ssl_error = ERR_get_error();
813 fatalf(
"Failed to set SSL cipher suite '%s': %s\n",
818 if (!peer.
certs.empty()) {
821 if (!
keys.certFile.isEmpty()) {
822 debugs(83, 2,
"loading client certificate from " <<
keys.certFile);
824 const char *certfile =
keys.certFile.c_str();
825 if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) {
826 const auto ssl_error = ERR_get_error();
827 fatalf(
"Failed to acquire SSL certificate '%s': %s\n",
831 debugs(83, 2,
"loading private key from " <<
keys.privateKeyFile);
832 const char *keyfile =
keys.privateKeyFile.c_str();
835 if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) {
836 const auto ssl_error = ERR_get_error();
837 fatalf(
"Failed to acquire SSL private key '%s': %s\n",
841 debugs(83, 5,
"Comparing private and public SSL keys.");
843 if (!SSL_CTX_check_private_key(ctx.get())) {
844 const auto ssl_error = ERR_get_error();
845 fatalf(
"SSL private key '%s' does not match public key '%s': %s\n",
862 static char buffer[1024];
865 if (strcmp(attribute_name,
"DN") == 0) {
866 X509_NAME_oneline(name, buffer,
sizeof(buffer));
868 int nid = OBJ_txt2nid(
const_cast<char *
>(attribute_name));
870 debugs(83,
DBG_IMPORTANT,
"WARNING: Unknown SSL attribute name '" << attribute_name <<
"'");
873 X509_NAME_get_text_by_NID(name, nid, buffer,
sizeof(buffer));
876 return *buffer ? buffer :
nullptr;
889 name = X509_get_subject_name(cert);
899 static char buf[1024];
904 unsigned char md[EVP_MAX_MD_SIZE];
905 if (!X509_digest(cert, EVP_sha1(), md, &n))
908 assert(3 * n + 1 <
sizeof(buf));
911 for (
unsigned int i=0; i < n; ++i, s += 3) {
912 const char term = (i + 1 < n) ?
':' :
'\0';
913 snprintf(s, 4,
"%02X%c", md[i], term);
925 PEM_write_bio_X509(bio.get(), cert);
928 const auto len = BIO_get_mem_data(bio.get(), &ptr);
929 return SBuf(ptr, len);
943 name = X509_get_issuer_name(cert);
955 X509 *cert = SSL_get_peer_certificate(ssl);
968 X509 *cert = SSL_get_peer_certificate(ssl);
987 if (
const auto cert = SSL_get_peer_certificate(ssl))
998 auto chain = SSL_get_peer_cert_chain(ssl);
1005 for (
int i = 0; i < sk_X509_num(chain); ++i) {
1006 X509 *cert = sk_X509_value(chain, i);
1007 PEM_write_bio_X509(bio.get(), cert);
1011 const auto len = BIO_get_mem_data(bio.get(), &ptr);
1012 return SBuf(ptr, len);
1021 if (!SSL_CTX_use_certificate(ctx.get(), x509.
get()))
1024 if (!SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()))
1037 Security::PrivateKeyPointer pkey;
1051 Security::PrivateKeyPointer pkey;
1067 if (SSL_CTX_add_extra_chain_cert(ctx.get(), signingCert)) {
1069 X509_up_ref(signingCert);
1071 const auto ssl_error = ERR_get_error();
1076 if (SSL_CTX_add_extra_chain_cert(ctx.get(), cert.get())) {
1078 X509_up_ref(cert.get());
1080 const auto error = ERR_get_error();
1097 Security::PrivateKeyPointer pkey;
1107 if (!SSL_use_certificate(ssl, cert.
get()))
1110 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1120 Security::PrivateKeyPointer pkey;
1127 if (!SSL_use_certificate(ssl, cert.
get()))
1130 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1139#if HAVE_SSL_CTX_GET0_CERTIFICATE
1140 X509 * cert = SSL_CTX_get0_certificate(ctx.get());
1141#elif SQUID_USE_SSLGETCERTIFICATE_HACK
1144 X509 ***pCert = (X509 ***)ctx->cert;
1145 X509 * cert = pCert && *pCert ? **pCert :
NULL;
1146#elif SQUID_SSLGETCERTIFICATE_BUGGY
1147 X509 * cert =
nullptr;
1152 X509 * cert = SSL_get_certificate(ssl.get());
1158 return (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
1170#if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
1171 if (!SSL_set_tlsext_host_name(ssl, fqdn)) {
1172 const auto ssl_error = ERR_get_error();
1173 debugs(83, 3,
"WARNING: unable to set TLS servername extension (SNI): " <<
1177 debugs(83, 7,
"no support for TLS servername extension (SNI)");
1184 AUTHORITY_INFO_ACCESS *info;
1187 info =
static_cast<AUTHORITY_INFO_ACCESS *
>(X509_get_ext_d2i(cert, NID_info_access,
nullptr,
nullptr));
1194 for (
int i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
1195 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
1196 if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers) {
1197 if (ad->location->type == GEN_URI) {
1199 reinterpret_cast<const char *
>(
1207 AUTHORITY_INFO_ACCESS_free(info);
1208 return uri[0] !=
'\0' ? uri :
nullptr;
1214 const BIO_Pointer in(BIO_new_file(certsFile,
"r"));
1216 debugs(83,
DBG_IMPORTANT,
"ERROR: Failed to open '" << certsFile <<
"' to load certificates");
1222 list.insert(std::pair<SBuf, X509 *>(name, aCert.release()));
1224 debugs(83, 4,
"Loaded " << list.size() <<
" certificates from file: '" << certsFile <<
"'");
1237 const auto ret = list.equal_range(name);
1238 for (Ssl::CertsIndexedList::iterator it = ret.first; it != ret.second; ++it) {
1239 X509 *issuer = it->second;
1254 const auto certCount = sk_X509_num(sk);
1255 for (
int i = 0; i < certCount; ++i) {
1256 const auto issuer = sk_X509_value(sk, i);
1271 X509_STORE_CTX *storeCtx = X509_STORE_CTX_new();
1277 X509 *issuer =
nullptr;
1278 X509_STORE *store = SSL_CTX_get_cert_store(connContext.get());
1279 if (X509_STORE_CTX_init(storeCtx, store,
nullptr,
nullptr)) {
1280 const auto ret = X509_STORE_CTX_get1_issuer(&issuer, storeCtx, cert);
1283 debugs(83, 5,
"found " << *issuer);
1285 debugs(83, ret < 0 ? 2 : 3,
"not found or failure: " << ret);
1289 const auto ssl_error = ERR_get_error();
1293 X509_STORE_CTX_free(storeCtx);
1304 if (
const auto issuer = serverCertificates ?
sk_x509_findIssuer(serverCertificates, cert) :
nullptr) {
1305 X509_up_ref(issuer);
1311 X509_up_ref(issuer);
1327 for (
int i = 0; i < sk_X509_num(&serverCertificates); ++i) {
1328 const auto cert = sk_X509_value(&serverCertificates, i);
1334 URIs.push(
SBuf(issuerUri));
1336 debugs(83, 3,
"Issuer certificate for " <<
1338 " is missing and its URI is not provided");
1342 debugs(83, (URIs.empty() ? 3 : 5),
"found: " << URIs.size());
1343 return !URIs.empty();
1350 debugs(83, 2,
"completing " << sk_X509_num(&untrustedCerts) <<
1352 " configured untrusted certificates");
1354 const X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
1359 for (i = 0; current && (i < depth); ++i) {
1371 sk_X509_push(&untrustedCerts, issuer.release());
1375 debugs(83, 2,
"exceeded the maximum certificate chain length: " << depth);
1387 STACK_OF(X509) *oldUntrusted = X509_STORE_CTX_get0_untrusted(ctx);
1392 for (
int i = 0; i < sk_X509_num(extraCerts); ++i) {
1393 const auto cert = sk_X509_value(extraCerts, i);
1395 sk_X509_push(untrustedCerts.get(), cert);
1405 int ret = X509_verify_cert(ctx);
1432 debugs(83, 4,
"Try to use pre-downloaded intermediate certificates");
1453 X509_free(i.second);
1464 certProperties.
commonName =
"Not trusted by \"";
1468 certProperties.
commonName =
"Not trusted by \"";
1484 bool origSignatureAsKey =
false;
1487 origSignatureAsKey =
true;
1488 key.
append((
const char *)sig->data, sig->length);
1504 ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bio.get(), (ASN1_VALUE *)certProperties.
mimicCert.
get());
1538 size_t oldLen = buf->
length();
1540 return buf->
length() - oldLen;
1548 case BIO_CTRL_RESET:
1552 case BIO_CTRL_FLUSH:
1561#if HAVE_LIBCRYPTO_BIO_METH_NEW
1562 static BIO_METHOD *BioSBufMethods =
nullptr;
1563 if (!BioSBufMethods) {
1564 BioSBufMethods = BIO_meth_new(BIO_TYPE_MEM,
"Squid-SBuf");
1566 BIO_meth_set_read(BioSBufMethods,
nullptr);
1568 BIO_meth_set_gets(BioSBufMethods,
nullptr);
1574 static BIO_METHOD *BioSBufMethods =
new BIO_METHOD({
1587 BIO *bio = BIO_new(BioSBufMethods);
#define Assure(condition)
ACLFilledChecklist * Filled(ACLChecklist *checklist)
convenience and safety wrapper for dynamic_cast<ACLFilledChecklist*>
#define Here()
source code location of the caller
void error(char *format,...)
static char server[MAXLINE]
Acl::Answer const & fastCheck()
Security::CertPointer serverCert
CbcPointer< Security::CertErrors > sslErrors
either a domain name (as defined in DNS RFC 1034) or an IP address
static std::optional< Host > ParseIp(const Ip::Address &)
converts an already parsed IP address to a Host object
auto domainName() const
stored domain name (if any)
static std::optional< Host > ParseWildDomainName(const SBuf &)
bool push_back_unique(C const &element)
static bool Enabled(const int section, const int level)
whether debugging the given section and the given level produces output
SBuf consume(size_type n=npos)
size_type length() const
Returns the number of bytes stored in SBuf.
SBuf & append(const SBuf &S)
Security::CertPointer cert
public X.509 certificate from certFile
Security::CertList chain
any certificates which must be chained from cert
void reset()
Forget the raw pointer - unlock if any value was set. Become a nil pointer.
T * get() const
Returns raw and possibly nullptr pointer.
TLS squid.conf settings for a remote server peer.
std::list< Security::KeyData > certs
details from the cert= and file= config parameters
TLS squid.conf settings for a listening port.
Security::ContextPointer createBlankContext() const override
generate an unset security context object
bool updateContextConfig(Security::ContextPointer &)
update the given TLS security context using squid.conf settings
Security::KeyData signingCa
x509 certificate and key for signing generated certificates
struct SquidConfig::@83 Program
struct SquidConfig::@97 SSL
Security::PrivateKeyPointer signWithPkey
The key of the signing certificate.
bool setCommonName
Replace the CN field of the mimicking subject with the given.
bool setValidAfter
Do not mimic "Not Valid After" field.
CertSignAlgorithm signAlgorithm
The signing algorithm to use.
bool setValidBefore
Do not mimic "Not Valid Before" field.
Security::CertPointer mimicCert
Certificate to mimic.
const EVP_MD * signHash
The signing hash to use.
std::string commonName
A CN to use for the generated certificate.
an algorithm for checking/testing/comparing X.509 certificate names
bool match(const Ssl::GeneralName &) const
whether the given name satisfies algorithm conditions
virtual bool matchIp(const Ip::Address &) const =0
virtual bool matchDomainName(const Dns::DomainName &) const =0
GeneralNameMatcher for matching a single AnyP::Host given at construction time.
AnyP::Host needle_
a name we are looking for
OneNameMatcher(const AnyP::Host &needle)
bool matchIp(const Ip::Address &) const override
bool matchDomainName(const Dns::DomainName &) const override
static VerifyCallbackParameters & At(Security::Connection &)
static VerifyCallbackParameters * New(Security::Connection &)
static VerifyCallbackParameters * Find(Security::Connection &)
an std::runtime_error with thrower location info
#define DBG_PARSE_NOTE(x)
#define debugs(SECTION, LEVEL, CONTENT)
void fatalf(const char *fmt,...)
int ssl_ex_index_ssl_peeked_cert
int ssl_ex_index_ssl_error_detail
int ssl_ctx_ex_index_dont_verify_domain
int ssl_ex_index_ssl_errors
int ssl_ex_index_ssl_validation_counter
int ssl_ex_index_ssl_cert_chain
int ssl_ex_index_cert_error_check
void useSquidUntrusted(SSL_CTX *sslContext)
Security::ContextPointer GenerateSslContext(CertificateProperties const &, Security::ServerOptions &, bool trusted)
std::vector< const char * > BumpModeStr
SBuf sslGetUserCertificatePEM(SSL *ssl)
bool configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port)
bool generateUntrustedCert(Security::CertPointer &untrustedCert, Security::PrivateKeyPointer &untrustedPkey, Security::CertPointer const &cert, Security::PrivateKeyPointer const &pkey)
void chainCertificatesToSSLContext(Security::ContextPointer &, Security::ServerOptions &)
void InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBuf &key)
const char * sslGetUserAttribute(SSL *ssl, const char *attribute_name)
BIO * BIO_new_SBuf(SBuf *buf)
Security::ContextPointer createSSLContext(Security::CertPointer &x509, Security::PrivateKeyPointer &pkey, Security::ServerOptions &)
Create SSL context and apply ssl certificate and private key to it.
bool verifySslCertificate(const Security::ContextPointer &, CertificateProperties const &)
bool configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port)
bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list)
int asn1timeToString(ASN1_TIME *tm, char *buf, int len)
const char * sslGetCAAttribute(SSL *ssl, const char *attribute_name)
Security::ContextPointer GenerateSslContextUsingPkeyAndCertFromMemory(const char *data, Security::ServerOptions &, bool trusted)
GETX509ATTRIBUTE GetX509Fingerprint
SBuf sslGetUserCertificateChainPEM(SSL *ssl)
void configureUnconfiguredSslContext(Security::ContextPointer &, Ssl::CertSignAlgorithm signAlgorithm, AnyP::PortCfg &)
void setClientSNI(SSL *ssl, const char *fqdn)
const char * getOrganization(X509 *x509)
bool loadSquidUntrusted(const char *path)
const char * CommonHostName(X509 *x509)
const char * sslGetUserEmail(SSL *ssl)
GETX509ATTRIBUTE GetX509UserAttribute
void unloadSquidUntrusted()
GETX509ATTRIBUTE GetX509CAAttribute
static void ssl_free_CertChain(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
static void ssl_ask_password(SSL_CTX *context, const char *prompt)
static const char * ssl_get_attribute(X509_NAME *name, const char *attribute_name)
bool generateSslCertificate(Security::CertPointer &cert, Security::PrivateKeyPointer &pkey, CertificateProperties const &properties)
bool readCertAndPrivateKeyFromMemory(Security::CertPointer &cert, Security::PrivateKeyPointer &pkey, char const *bufferToRead)
const char * certSignAlgorithm(int sg)
SBuf IssuerName(Certificate &)
The Issuer field of the given certificate (if found) or an empty SBuf.
std::shared_ptr< SSL_CTX > ContextPointer
int ErrorCode
Squid-defined error code (<0), an error code returned by X.509 API, or zero.
Security::SessionPointer NewSessionObject(const Security::ContextPointer &)
std::shared_ptr< SSL > SessionPointer
CbDataList< Security::CertError > CertErrors
Holds a list of X.509 certificate errors.
Security::LockingPointer< X509, X509_free_cpp, HardFun< int, X509 *, X509_up_ref > > CertPointer
bool SelfSigned(Certificate &c)
Whether the given certificate is self-signed.
SBuf SubjectName(Certificate &)
The SubjectName field of the given certificate (if found) or an empty SBuf.
bool IssuedBy(Certificate &cert, Certificate &issuer)
const char * ErrorString(const LibErrorCode code)
converts numeric LibErrorCode into a human-friendlier string
bool HasMatchingSubjectName(X509 &, const GeneralNameMatcher &)
bool HasSubjectName(X509 &, const AnyP::Host &)
whether at least one common or alternate subject name matches the given one
void DisablePeerVerification(Security::ContextPointer &)
bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, Security::ParsedPortFlags)
initialize a TLS client context with OpenSSL specific settings
std::optional< AnyP::Host > ParseAsSimpleDomainNameOrIp(const SBuf &)
std::unique_ptr< BIO, HardFun< void, BIO *, &BIO_vfree > > BIO_Pointer
static CertsIndexedList & SquidUntrustedCerts()
bool VerifyConnCertificates(Security::Connection &, const Ssl::X509_STACK_Pointer &extraCerts)
std::unique_ptr< X509_STORE_CTX, HardFun< void, X509_STORE_CTX *, &X509_STORE_CTX_free > > X509_STORE_CTX_Pointer
Security::CertPointer findIssuerCertificate(X509 *cert, const STACK_OF(X509) *serverCertificates, const Security::ContextPointer &context)
bool missingChainCertificatesUrls(std::queue< SBuf > &URIs, const STACK_OF(X509) &serverCertificates, const Security::ContextPointer &context)
std::optional< AnyP::Host > ParseCommonNameAt(X509_NAME &, int)
interprets X.509 Subject or Issuer name entry (at the given position) as CN
Security::CertPointer ReadOptionalCertificate(const BIO_Pointer &)
const ASN1_BIT_STRING * X509_get_signature(const Security::CertPointer &)
std::optional< SBuf > GetErrorDescr(Security::ErrorCode)
const EVP_MD * DefaultSignHash
std::unique_ptr< STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_free_wrapper > GENERAL_NAME_STACK_Pointer
int AskPasswordCb(char *buf, int size, int rwflag, void *userdata)
SBuf AsnToSBuf(const ASN1_STRING &)
converts ASN1_STRING to SBuf
void MaybeSetupRsaCallback(Security::ContextPointer &)
if required, setup callback for generating ephemeral RSA keys
const char * findIssuerUri(X509 *cert)
finds certificate issuer URI in the Authority Info Access extension
std::unique_ptr< STACK_OF(X509), sk_X509_free_wrapper > X509_STACK_Pointer
std::multimap< SBuf, X509 * > CertsIndexedList
certificates indexed by issuer name
void ConfigurePeerVerification(Security::ContextPointer &, const Security::ParsedPortFlags)
set the certificate verify callback for a context
bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &)
initialize a TLS server context with OpenSSL specific settings
int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
void * BIO_get_data(BIO *table)
#define X509_getm_notAfter
void SQUID_OPENSSL_init_ssl(void)
#define X509_getm_notBefore
X509_VERIFY_PARAM * SSL_get0_param(SSL *ssl)
#define X509_STORE_CTX_set0_untrusted
void BIO_set_init(BIO *table, int init)
STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
X509 * X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
void BIO_set_data(BIO *table, void *data)
#define SSL_FLAG_CONDITIONAL_AUTH
#define SSL_FLAG_DONT_VERIFY_PEER
@ SQUID_X509_V_ERR_INFINITE_VALIDATION
@ SQUID_X509_V_ERR_DOMAIN_MISMATCH
@ SQUID_X509_V_ERR_CERT_CHANGE
#define SQUID_SSL_SIGN_HASH_IF_NONE
#define SQUID_CERT_VALIDATION_ITERATION_MAX
static void ssl_free_ErrorDetail(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
static void ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
static int bio_sbuf_puts(BIO *bio, const char *data)
static void ssl_free_SBuf(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
static int bio_sbuf_destroy(BIO *bio)
static void completeIssuers(X509_STORE_CTX *ctx, STACK_OF(X509) &untrustedCerts)
add missing issuer certificates to untrustedCerts
static void ssl_free_int(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
static X509 * findIssuerInCaDb(X509 *cert, const Security::ContextPointer &connContext)
static int ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *, int, long, void *)
static int ssl_verify_cb(int ok, X509_STORE_CTX *ctx)
static int ssl_ex_index_verify_callback_parameters
static int untrustedToStoreCtx_cb(X509_STORE_CTX *ctx, void *)
static void ssl_freeAclChecklist(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
static std::optional< AnyP::Host > ParseSubjectAltName(const GENERAL_NAME &san)
static int bio_sbuf_write(BIO *bio, const char *data, int len)
static void ssl_free_SslErrors(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
static X509 * findCertIssuerFast(Ssl::CertsIndexedList &list, X509 *cert)
static int VerifyCtxCertificates(X509_STORE_CTX *ctx, STACK_OF(X509) *extraCerts)
static int bio_sbuf_create(BIO *bio)
static long bio_sbuf_ctrl(BIO *bio, int cmd, long, void *)
static X509 * sk_x509_findIssuer(const STACK_OF(X509) *sk, X509 *cert)
slowly find the issuer certificate of a given cert using linear search
static void ssl_free_VerifyCallbackParameters(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
"free" function for the ssl_ex_index_verify_callback_parameters entry
char * xstrncpy(char *dst, const char *src, size_t n)