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;
512 debugs(83,
DBG_PARSE_NOTE(3),
"not requesting client certificates until ACL processing requires one");
513 mode = SSL_VERIFY_NONE;
517 mode = SSL_VERIFY_PEER;
521 mode = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
524 SSL_CTX_set_verify(ctx.get(), mode, (mode != SSL_VERIFY_NONE) ?
ssl_verify_cb :
nullptr);
531 SSL_CTX_set_verify(ctx.get(),SSL_VERIFY_NONE,
nullptr);
539 const auto peerCertificatesChain = SSL_get_peer_cert_chain(&sconn);
549 if (!peerCertificatesChain || sk_X509_num(peerCertificatesChain) == 0) {
550 debugs(83, 2,
"no server certificates");
554 const auto verificationStore = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(&sconn));
555 if (!verificationStore) {
556 debugs(83, 2,
"no certificate store");
562 debugs(83, 2,
"cannot create X509_STORE_CTX; likely OOM");
566 const auto peerCert = sk_X509_value(peerCertificatesChain, 0);
567 if (!X509_STORE_CTX_init(storeCtx.get(), verificationStore, peerCert, peerCertificatesChain)) {
568 debugs(83, 2,
"cannot initialize X509_STORE_CTX");
572#if defined(SSL_CERT_FLAG_SUITEB_128_LOS)
576 const unsigned long certFlags = SSL_set_cert_flags(&sconn, 0);
577 if (
const auto suiteBflags = certFlags & SSL_CERT_FLAG_SUITEB_128_LOS)
578 X509_STORE_CTX_set_flags(storeCtx.get(), suiteBflags);
581 if (!X509_STORE_CTX_set_ex_data(storeCtx.get(), SSL_get_ex_data_X509_STORE_CTX_idx(), &sconn)) {
582 debugs(83, 2,
"cannot attach SSL object to X509_STORE_CTX");
590 if (!X509_STORE_CTX_set_default(storeCtx.get(),
"ssl_server")) {
591 debugs(83, 2,
"cannot set default verification method to ssl_server");
596 const auto param = X509_STORE_CTX_get0_param(storeCtx.get());
598 debugs(83, 2,
"no context verification parameters");
601#if defined(HAVE_X509_VERIFY_PARAM_SET_AUTH_LEVEL)
602 X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(&sconn));
605 debugs(83, 2,
"cannot overwrite context verification parameters");
611 if (
const auto cb = SSL_get_verify_callback(&sconn))
612 X509_STORE_CTX_set_verify_cb(storeCtx.get(), cb);
617 const auto verifyResult = X509_STORE_CTX_get_error(storeCtx.get());
618 debugs(83, 3,
"verification failure: " << verifyResult <<
' ' << X509_verify_cert_error_string(verifyResult));
649 const auto parameters = Find(sconn);
655#if OPENSSL_VERSION_MAJOR >= 3
659#elif SQUID_USE_CONST_CRYPTO_EX_DATA_DUP
705 uint32_t *counter =
static_cast <uint32_t *
>(ptr);
717 sk_X509_pop_free(certsChain,X509_free);
725 X509 *cert =
static_cast <X509 *
>(ptr);
734 SBuf *buf =
static_cast <SBuf *
>(ptr);
749 static bool initialized =
false;
757#if OPENSSL_VERSION_MAJOR < 3
759 "in Squids built with OpenSSL 1.x (like this Squid). " <<
760 "It is removed in Squids built with OpenSSL 3.0 or newer.");
761#if !defined(OPENSSL_NO_ENGINE)
762 ENGINE_load_builtin_engines();
767 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
768 const auto ssl_error = ERR_get_error();
772 throw TextException(
"Cannot use ssl_engine in Squid built with OpenSSL configured to disable SSL engine support",
Here());
776 throw TextException(
"Cannot use ssl_engine in Squid built with OpenSSL 3.0 or newer",
Here());
783 fatalf(
"Sign hash '%s' is not supported\n", defName);
815 if (!SSL_CTX_set_cipher_list(ctx.get(), cipher)) {
816 const auto ssl_error = ERR_get_error();
817 fatalf(
"Failed to set SSL cipher suite '%s': %s\n",
822 if (!peer.
certs.empty()) {
825 if (!
keys.certFile.isEmpty()) {
826 debugs(83, 2,
"loading client certificate from " <<
keys.certFile);
828 const char *certfile =
keys.certFile.c_str();
829 if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) {
830 const auto ssl_error = ERR_get_error();
831 fatalf(
"Failed to acquire SSL certificate '%s': %s\n",
835 debugs(83, 2,
"loading private key from " <<
keys.privateKeyFile);
836 const char *keyfile =
keys.privateKeyFile.c_str();
839 if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) {
840 const auto ssl_error = ERR_get_error();
841 fatalf(
"Failed to acquire SSL private key '%s': %s\n",
845 debugs(83, 5,
"Comparing private and public SSL keys.");
847 if (!SSL_CTX_check_private_key(ctx.get())) {
848 const auto ssl_error = ERR_get_error();
849 fatalf(
"SSL private key '%s' does not match public key '%s': %s\n",
866 static char buffer[1024];
869 if (strcmp(attribute_name,
"DN") == 0) {
870 X509_NAME_oneline(name, buffer,
sizeof(buffer));
872 int nid = OBJ_txt2nid(
const_cast<char *
>(attribute_name));
874 debugs(83,
DBG_IMPORTANT,
"WARNING: Unknown SSL attribute name '" << attribute_name <<
"'");
877 X509_NAME_get_text_by_NID(name, nid, buffer,
sizeof(buffer));
880 return *buffer ? buffer :
nullptr;
893 name = X509_get_subject_name(cert);
903 static char buf[1024];
908 unsigned char md[EVP_MAX_MD_SIZE];
909 if (!X509_digest(cert, EVP_sha1(), md, &n))
912 assert(3 * n + 1 <
sizeof(buf));
915 for (
unsigned int i=0; i < n; ++i, s += 3) {
916 const char term = (i + 1 < n) ?
':' :
'\0';
917 snprintf(s, 4,
"%02X%c", md[i], term);
929 PEM_write_bio_X509(bio.get(), cert);
932 const auto len = BIO_get_mem_data(bio.get(), &ptr);
933 return SBuf(ptr, len);
947 name = X509_get_issuer_name(cert);
959 X509 *cert = SSL_get_peer_certificate(ssl);
972 X509 *cert = SSL_get_peer_certificate(ssl);
991 if (
const auto cert = SSL_get_peer_certificate(ssl))
1002 auto chain = SSL_get_peer_cert_chain(ssl);
1009 for (
int i = 0; i < sk_X509_num(chain); ++i) {
1010 X509 *cert = sk_X509_value(chain, i);
1011 PEM_write_bio_X509(bio.get(), cert);
1015 const auto len = BIO_get_mem_data(bio.get(), &ptr);
1016 return SBuf(ptr, len);
1025 if (!SSL_CTX_use_certificate(ctx.get(), x509.
get()))
1028 if (!SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()))
1041 Security::PrivateKeyPointer pkey;
1055 Security::PrivateKeyPointer pkey;
1071 if (SSL_CTX_add_extra_chain_cert(ctx.get(), signingCert)) {
1073 X509_up_ref(signingCert);
1075 const auto ssl_error = ERR_get_error();
1080 if (SSL_CTX_add_extra_chain_cert(ctx.get(), cert.get())) {
1082 X509_up_ref(cert.get());
1084 const auto error = ERR_get_error();
1101 Security::PrivateKeyPointer pkey;
1111 if (!SSL_use_certificate(ssl, cert.
get()))
1114 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1124 Security::PrivateKeyPointer pkey;
1131 if (!SSL_use_certificate(ssl, cert.
get()))
1134 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1143#if HAVE_SSL_CTX_GET0_CERTIFICATE
1144 X509 * cert = SSL_CTX_get0_certificate(ctx.get());
1145#elif SQUID_USE_SSLGETCERTIFICATE_HACK
1148 X509 ***pCert = (X509 ***)ctx->cert;
1149 X509 * cert = pCert && *pCert ? **pCert :
NULL;
1150#elif SQUID_SSLGETCERTIFICATE_BUGGY
1151 X509 * cert =
nullptr;
1156 X509 * cert = SSL_get_certificate(ssl.get());
1162 return (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
1174#if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
1175 if (!SSL_set_tlsext_host_name(ssl, fqdn)) {
1176 const auto ssl_error = ERR_get_error();
1177 debugs(83, 3,
"WARNING: unable to set TLS servername extension (SNI): " <<
1181 debugs(83, 7,
"no support for TLS servername extension (SNI)");
1188 AUTHORITY_INFO_ACCESS *info;
1191 info =
static_cast<AUTHORITY_INFO_ACCESS *
>(X509_get_ext_d2i(cert, NID_info_access,
nullptr,
nullptr));
1198 for (
int i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
1199 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
1200 if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers) {
1201 if (ad->location->type == GEN_URI) {
1203 reinterpret_cast<const char *
>(
1211 AUTHORITY_INFO_ACCESS_free(info);
1212 return uri[0] !=
'\0' ? uri :
nullptr;
1218 const BIO_Pointer in(BIO_new_file(certsFile,
"r"));
1220 debugs(83,
DBG_IMPORTANT,
"ERROR: Failed to open '" << certsFile <<
"' to load certificates");
1226 list.insert(std::pair<SBuf, X509 *>(name, aCert.release()));
1228 debugs(83, 4,
"Loaded " << list.size() <<
" certificates from file: '" << certsFile <<
"'");
1241 const auto ret = list.equal_range(name);
1242 for (Ssl::CertsIndexedList::iterator it = ret.first; it != ret.second; ++it) {
1243 X509 *issuer = it->second;
1258 const auto certCount = sk_X509_num(sk);
1259 for (
int i = 0; i < certCount; ++i) {
1260 const auto issuer = sk_X509_value(sk, i);
1275 X509_STORE_CTX *storeCtx = X509_STORE_CTX_new();
1281 X509 *issuer =
nullptr;
1282 X509_STORE *store = SSL_CTX_get_cert_store(connContext.get());
1283 if (X509_STORE_CTX_init(storeCtx, store,
nullptr,
nullptr)) {
1284 const auto ret = X509_STORE_CTX_get1_issuer(&issuer, storeCtx, cert);
1287 debugs(83, 5,
"found " << *issuer);
1289 debugs(83, ret < 0 ? 2 : 3,
"not found or failure: " << ret);
1293 const auto ssl_error = ERR_get_error();
1297 X509_STORE_CTX_free(storeCtx);
1308 if (
const auto issuer = serverCertificates ?
sk_x509_findIssuer(serverCertificates, cert) :
nullptr) {
1309 X509_up_ref(issuer);
1315 X509_up_ref(issuer);
1331 for (
int i = 0; i < sk_X509_num(&serverCertificates); ++i) {
1332 const auto cert = sk_X509_value(&serverCertificates, i);
1338 URIs.push(
SBuf(issuerUri));
1340 debugs(83, 3,
"Issuer certificate for " <<
1342 " is missing and its URI is not provided");
1346 debugs(83, (URIs.empty() ? 3 : 5),
"found: " << URIs.size());
1347 return !URIs.empty();
1354 debugs(83, 2,
"completing " << sk_X509_num(&untrustedCerts) <<
1356 " configured untrusted certificates");
1358 const X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
1363 for (i = 0; current && (i < depth); ++i) {
1375 sk_X509_push(&untrustedCerts, issuer.release());
1379 debugs(83, 2,
"exceeded the maximum certificate chain length: " << depth);
1391 STACK_OF(X509) *oldUntrusted = X509_STORE_CTX_get0_untrusted(ctx);
1396 for (
int i = 0; i < sk_X509_num(extraCerts); ++i) {
1397 const auto cert = sk_X509_value(extraCerts, i);
1399 sk_X509_push(untrustedCerts.get(), cert);
1409 int ret = X509_verify_cert(ctx);
1436 debugs(83, 4,
"Try to use pre-downloaded intermediate certificates");
1457 X509_free(i.second);
1468 certProperties.
commonName =
"Not trusted by \"";
1472 certProperties.
commonName =
"Not trusted by \"";
1488 bool origSignatureAsKey =
false;
1491 origSignatureAsKey =
true;
1492 key.
append((
const char *)sig->data, sig->length);
1508 ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bio.get(), (ASN1_VALUE *)certProperties.
mimicCert.
get());
1542 size_t oldLen = buf->
length();
1544 return buf->
length() - oldLen;
1552 case BIO_CTRL_RESET:
1556 case BIO_CTRL_FLUSH:
1565#if HAVE_LIBCRYPTO_BIO_METH_NEW
1566 static BIO_METHOD *BioSBufMethods =
nullptr;
1567 if (!BioSBufMethods) {
1568 BioSBufMethods = BIO_meth_new(BIO_TYPE_MEM,
"Squid-SBuf");
1570 BIO_meth_set_read(BioSBufMethods,
nullptr);
1572 BIO_meth_set_gets(BioSBufMethods,
nullptr);
1578 static BIO_METHOD *BioSBufMethods =
new BIO_METHOD({
1591 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 SSL_FLAG_DELAYED_AUTH
#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)