]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl/support.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / ssl / support.cc
CommitLineData
f484cdf5 1/*
f70aedc4 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
f484cdf5 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
f484cdf5 7 */
8
bbc27441
AJ
9/* DEBUG: section 83 SSL accelerator support */
10
582c2af2 11#include "squid.h"
454e8283 12
13/* MS Visual Studio Projects are monolithic, so we need the following
14 * #if to exclude the SSL code from compile process when not needed.
15 */
cb4f4424 16#if USE_OPENSSL
454e8283 17
c0941a6a 18#include "acl/FilledChecklist.h"
86660d64 19#include "anyp/PortCfg.h"
c8ab5ec6 20#include "anyp/Uri.h"
ed6e9fb9 21#include "fatal.h"
b3a8ae1b 22#include "fd.h"
582c2af2
FC
23#include "fde.h"
24#include "globals.h"
86c63190 25#include "ipc/MemMap.h"
92e3827b 26#include "security/CertError.h"
83b053a0 27#include "security/ErrorDetail.h"
8d15a0c1 28#include "security/Session.h"
4d5904f7 29#include "SquidConfig.h"
10a69fc0 30#include "SquidTime.h"
b3a8ae1b 31#include "ssl/bio.h"
2cef0ca6 32#include "ssl/Config.h"
4d16918e 33#include "ssl/ErrorDetail.h"
95d2589c 34#include "ssl/gadgets.h"
602d9612 35#include "ssl/support.h"
f484cdf5 36
1a30fdf5 37#include <cerrno>
21d845b1 38
55369ae6 39// TODO: Move ssl_ex_index_* global variables from global.cc here.
800967af 40static int ssl_ex_index_verify_callback_parameters = -1;
55369ae6 41
55369ae6
AR
42static Ssl::CertsIndexedList SquidUntrustedCerts;
43
3c26b00a
CT
44const EVP_MD *Ssl::DefaultSignHash = NULL;
45
ba6fffba 46std::vector<const char *> Ssl::BumpModeStr = {
caf3666d
AR
47 "none",
48 "client-first",
49 "server-first",
5d65362c
CT
50 "peek",
51 "stare",
52 "bump",
7f4e9b73 53 "splice",
ba6fffba
EB
54 "terminate"
55 /*,"err"*/
caf3666d
AR
56};
57
63be0a78 58/**
59 \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
60 \ingroup ServerProtocolSSLAPI
61 */
62
51e09c08
AJ
63int
64Ssl::AskPasswordCb(char *buf, int size, int rwflag, void *userdata)
307b83b7 65{
66 FILE *in;
67 int len = 0;
68 char cmdline[1024];
69
51e09c08 70 snprintf(cmdline, sizeof(cmdline), "\"%s\" \"%s\"", ::Config.Program.ssl_password, (const char *)userdata);
307b83b7 71 in = popen(cmdline, "r");
72
73 if (fgets(buf, size, in))
74
75 len = strlen(buf);
76
77 while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r'))
5e263176 78 --len;
307b83b7 79
80 buf[len] = '\0';
81
82 pclose(in);
83
84 return len;
85}
86
63be0a78 87/// \ingroup ServerProtocolSSLInternal
307b83b7 88static void
89ssl_ask_password(SSL_CTX * context, const char * prompt)
90{
91 if (Config.Program.ssl_password) {
51e09c08 92 SSL_CTX_set_default_passwd_cb(context, Ssl::AskPasswordCb);
307b83b7 93 SSL_CTX_set_default_passwd_cb_userdata(context, (void *)prompt);
94 }
95}
96
17e98f24 97#if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
f484cdf5 98static RSA *
e6ccf245 99ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
f484cdf5 100{
24b30fdc
EQ
101 static RSA *rsa_512 = nullptr;
102 static RSA *rsa_1024 = nullptr;
103 static BIGNUM *e = nullptr;
104 RSA *rsa = nullptr;
e01f02ed 105 int newkey = 0;
f484cdf5 106
24b30fdc
EQ
107 if (!e) {
108 e = BN_new();
109 if (!e || !BN_set_word(e, RSA_F4)) {
110 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Failed to set exponent for key " << keylen);
111 BN_free(e);
112 e = nullptr;
113 return nullptr;
114 }
115 }
116
e01f02ed 117 switch (keylen) {
118
119 case 512:
120
121 if (!rsa_512) {
24b30fdc
EQ
122 rsa_512 = RSA_new();
123 if (rsa_512 && RSA_generate_key_ex(rsa_512, 512, e, nullptr)) {
124 newkey = 1;
125 } else {
126 RSA_free(rsa_512);
127 rsa_512 = nullptr;
128 }
e01f02ed 129 }
130
131 rsa = rsa_512;
132 break;
133
134 case 1024:
135
136 if (!rsa_1024) {
24b30fdc
EQ
137 rsa_1024 = RSA_new();
138 if (rsa_1024 && RSA_generate_key_ex(rsa_1024, 1024, e, nullptr)) {
139 newkey = 1;
140 } else {
141 RSA_free(rsa_1024);
142 rsa_1024 = nullptr;
143 }
e01f02ed 144 }
145
146 rsa = rsa_1024;
147 break;
148
149 default:
e0236918 150 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Unexpected key length " << keylen);
e01f02ed 151 return NULL;
152 }
153
154 if (rsa == NULL) {
e0236918 155 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Failed to generate key " << keylen);
e01f02ed 156 return NULL;
157 }
158
159 if (newkey) {
014adac1 160 if (Debug::Enabled(83, 5))
e01f02ed 161 PEM_write_RSAPrivateKey(debug_log, rsa, NULL, NULL, 0, NULL, NULL);
162
e0236918 163 debugs(83, DBG_IMPORTANT, "Generated ephemeral RSA key of length " << keylen);
e01f02ed 164 }
62e76326 165
f484cdf5 166 return rsa;
167}
b7afb10f
CT
168#endif
169
cf487124
AJ
170void
171Ssl::MaybeSetupRsaCallback(Security::ContextPointer &ctx)
b7afb10f 172{
17e98f24 173#if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
b7afb10f
CT
174 debugs(83, 9, "Setting RSA key generation callback.");
175 SSL_CTX_set_tmp_rsa_callback(ctx.get(), ssl_temp_rsa_cb);
176#endif
177}
f484cdf5 178
4d16918e
CT
179int Ssl::asn1timeToString(ASN1_TIME *tm, char *buf, int len)
180{
181 BIO *bio;
182 int write = 0;
183 bio = BIO_new(BIO_s_mem());
184 if (bio) {
e34763f4
A
185 if (ASN1_TIME_print(bio, tm))
186 write = BIO_read(bio, buf, len-1);
187 BIO_free(bio);
4d16918e
CT
188 }
189 buf[write]='\0';
190 return write;
191}
192
193int Ssl::matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data))
194{
195 assert(peer_cert);
196
197 X509_NAME *name = X509_get_subject_name(peer_cert);
198
199 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)) {
e34763f4 200
4d16918e
CT
201 ASN1_STRING *cn_data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
202
203 if ( (*check_func)(check_data, cn_data) == 0)
204 return 1;
205 }
206
207 STACK_OF(GENERAL_NAME) * altnames;
208 altnames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(peer_cert, NID_subject_alt_name, NULL, NULL);
209
210 if (altnames) {
211 int numalts = sk_GENERAL_NAME_num(altnames);
d7ae3534 212 for (int i = 0; i < numalts; ++i) {
4d16918e
CT
213 const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
214 if (check->type != GEN_DNS) {
215 continue;
216 }
217 ASN1_STRING *cn_data = check->d.dNSName;
e34763f4 218
40dd2b59
CT
219 if ( (*check_func)(check_data, cn_data) == 0) {
220 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
4d16918e 221 return 1;
40dd2b59 222 }
4d16918e
CT
223 }
224 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
225 }
226 return 0;
227}
228
229static int check_domain( void *check_data, ASN1_STRING *cn_data)
230{
231 char cn[1024];
232 const char *server = (const char *)check_data;
233
abbd7825
CT
234 if (cn_data->length == 0)
235 return 1; // zero length cn, ignore
236
237 if (cn_data->length > (int)sizeof(cn) - 1)
4d16918e 238 return 1; //if does not fit our buffer just ignore
abbd7825 239
0f7f4cfc
AJ
240 char *s = reinterpret_cast<char*>(cn_data->data);
241 char *d = cn;
242 for (int i = 0; i < cn_data->length; ++i, ++d, ++s) {
243 if (*s == '\0')
244 return 1; // always a domain mismatch. contains 0x00
245 *d = *s;
246 }
4d16918e
CT
247 cn[cn_data->length] = '\0';
248 debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn);
abbd7825 249 return matchDomainName(server, (cn[0] == '*' ? cn + 1 : cn), mdnRejectSubsubDomains);
4d16918e
CT
250}
251
8eb0a7ee
CT
252bool Ssl::checkX509ServerValidity(X509 *cert, const char *server)
253{
254 return matchX509CommonNames(cert, (void *)server, check_domain);
255}
256
800967af
CT
257/// adjusts OpenSSL validation results for each verified certificate in ctx
258/// OpenSSL "verify_callback function" (\ref OpenSSL_vcb_disambiguation)
f484cdf5 259static int
260ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
261{
7698a79c 262 // preserve original ctx->error before SSL_ calls can overwrite it
2a268a06 263 Security::ErrorCode error_no = ok ? SSL_ERROR_NONE : X509_STORE_CTX_get_error(ctx);
7698a79c
CT
264
265 char buffer[256] = "";
a7ad6e4e 266 SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
0476ec45 267 SSL_CTX *sslctx = SSL_get_SSL_CTX(ssl);
68920ad8 268 SBuf *server = (SBuf *)SSL_get_ex_data(ssl, ssl_ex_index_server);
a7ad6e4e 269 void *dont_verify_domain = SSL_CTX_get_ex_data(sslctx, ssl_ctx_ex_index_dont_verify_domain);
815eaa44 270 ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
e7bcc25f 271 X509 *peeked_cert = (X509 *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_peeked_cert);
92e3827b 272 Security::CertPointer peer_cert;
2a268a06 273 peer_cert.resetAndLock(X509_STORE_CTX_get0_cert(ctx));
f484cdf5 274
92e3827b 275 X509_NAME_oneline(X509_get_subject_name(peer_cert.get()), buffer, sizeof(buffer));
a7ad6e4e 276
0ad3ff51
CT
277 // detect infinite loops
278 uint32_t *validationCounter = static_cast<uint32_t *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_validation_counter));
279 if (!validationCounter) {
280 validationCounter = new uint32_t(1);
281 SSL_set_ex_data(ssl, ssl_ex_index_ssl_validation_counter, validationCounter);
282 } else {
283 // overflows allowed if SQUID_CERT_VALIDATION_ITERATION_MAX >= UINT32_MAX
284 (*validationCounter)++;
285 }
286
287 if ((*validationCounter) >= SQUID_CERT_VALIDATION_ITERATION_MAX) {
288 ok = 0; // or the validation loop will never stop
289 error_no = SQUID_X509_V_ERR_INFINITE_VALIDATION;
290 debugs(83, 2, "SQUID_X509_V_ERR_INFINITE_VALIDATION: " <<
291 *validationCounter << " iterations while checking " << buffer);
292 }
293
a7ad6e4e 294 if (ok) {
bf8fe701 295 debugs(83, 5, "SSL Certificate signature OK: " << buffer);
62e76326 296
4747ea4c 297 // Check for domain mismatch only if the current certificate is the peer certificate.
92e3827b
AJ
298 if (!dont_verify_domain && server && peer_cert.get() == X509_STORE_CTX_get_current_cert(ctx)) {
299 if (!Ssl::checkX509ServerValidity(peer_cert.get(), server->c_str())) {
815eaa44 300 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer << " does not match domainname " << server);
62e76326 301 ok = 0;
4d16918e 302 error_no = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
62e76326 303 }
304 }
7698a79c 305 }
0db46e4f 306
e7bcc25f 307 if (ok && peeked_cert) {
7a957a93 308 // Check whether the already peeked certificate matches the new one.
92e3827b 309 if (X509_cmp(peer_cert.get(), peeked_cert) != 0) {
e7bcc25f
CT
310 debugs(83, 2, "SQUID_X509_V_ERR_CERT_CHANGE: Certificate " << buffer << " does not match peeked certificate");
311 ok = 0;
312 error_no = SQUID_X509_V_ERR_CERT_CHANGE;
313 }
314 }
315
800967af
CT
316 if (!ok && error_no == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
317 if (const auto params = Ssl::VerifyCallbackParameters::Find(*ssl)) {
318 if (params->callerHandlesMissingCertificates) {
319 debugs(83, 3, "hiding X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY");
320 params->hidMissingIssuer = true;
321 ok = 1;
322 }
323 }
324 }
325
7698a79c 326 if (!ok) {
92e3827b
AJ
327 Security::CertPointer broken_cert;
328 broken_cert.resetAndLock(X509_STORE_CTX_get_current_cert(ctx));
62a7607e
CT
329 if (!broken_cert)
330 broken_cert = peer_cert;
331
92e3827b 332 Security::CertErrors *errs = static_cast<Security::CertErrors *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_errors));
e36bc333 333 const int depth = X509_STORE_CTX_get_error_depth(ctx);
7a957a93 334 if (!errs) {
92e3827b 335 errs = new Security::CertErrors(Security::CertError(error_no, broken_cert, depth));
7a957a93 336 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_errors, (void *)errs)) {
fb2178bb 337 debugs(83, 2, "Failed to set ssl error_no in ssl_verify_cb: Certificate " << buffer);
7a957a93
AR
338 delete errs;
339 errs = NULL;
fb2178bb 340 }
87f237a9 341 } else // remember another error number
92e3827b 342 errs->push_back_unique(Security::CertError(error_no, broken_cert, depth));
fb2178bb 343
7698a79c 344 if (const char *err_descr = Ssl::GetErrorDescr(error_no))
cf09bec7
CT
345 debugs(83, 5, err_descr << ": " << buffer);
346 else
7698a79c
CT
347 debugs(83, DBG_IMPORTANT, "SSL unknown certificate error " << error_no << " in " << buffer);
348
0ad3ff51
CT
349 // Check if the certificate error can be bypassed.
350 // Infinity validation loop errors can not bypassed.
351 if (error_no != SQUID_X509_V_ERR_INFINITE_VALIDATION) {
352 if (check) {
353 ACLFilledChecklist *filledCheck = Filled(check);
354 assert(!filledCheck->sslErrors);
92e3827b
AJ
355 filledCheck->sslErrors = new Security::CertErrors(Security::CertError(error_no, broken_cert));
356 filledCheck->serverCert = peer_cert;
06bf5384 357 if (check->fastCheck().allowed()) {
0ad3ff51
CT
358 debugs(83, 3, "bypassing SSL error " << error_no << " in " << buffer);
359 ok = 1;
360 } else {
361 debugs(83, 5, "confirming SSL error " << error_no);
362 }
363 delete filledCheck->sslErrors;
364 filledCheck->sslErrors = NULL;
58a5291c 365 filledCheck->serverCert.reset();
7698a79c 366 }
0ad3ff51 367 // If the certificate validator is used then we need to allow all errors and
2f8abb64 368 // pass them to certificate validator for more processing
0ad3ff51 369 else if (Ssl::TheConfig.ssl_crt_validator) {
7698a79c 370 ok = 1;
7698a79c 371 }
815eaa44 372 }
a7ad6e4e 373 }
62e76326 374
081be7eb
CT
375 if (Ssl::TheConfig.ssl_crt_validator) {
376 // Check if we have stored certificates chain. Store if not.
377 if (!SSL_get_ex_data(ssl, ssl_ex_index_ssl_cert_chain)) {
378 STACK_OF(X509) *certStack = X509_STORE_CTX_get1_chain(ctx);
379 if (certStack && !SSL_set_ex_data(ssl, ssl_ex_index_ssl_cert_chain, certStack))
380 sk_X509_pop_free(certStack, X509_free);
381 }
382 }
383
7698a79c 384 if (!ok && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) {
f622c461
MF
385
386 // Find the broken certificate. It may be intermediate.
92e3827b 387 Security::CertPointer broken_cert(peer_cert); // reasonable default if search fails
f622c461
MF
388 // Our SQUID_X509_V_ERR_DOMAIN_MISMATCH implies peer_cert is at fault.
389 if (error_no != SQUID_X509_V_ERR_DOMAIN_MISMATCH) {
92e3827b
AJ
390 if (auto *last_used_cert = X509_STORE_CTX_get_current_cert(ctx))
391 broken_cert.resetAndLock(last_used_cert);
f622c461
MF
392 }
393
83b053a0
CT
394 std::unique_ptr<Security::ErrorDetail::Pointer> edp(new Security::ErrorDetail::Pointer(
395 new Security::ErrorDetail(error_no, peer_cert, broken_cert)));
396 if (SSL_set_ex_data(ssl, ssl_ex_index_ssl_error_detail, edp.get()))
397 edp.release();
398 else
399 debugs(83, 2, "failed to store a " << buffer << " error detail: " << *edp);
4d16918e
CT
400 }
401
f484cdf5 402 return ok;
403}
404
621f4299 405void
983fab6e 406Ssl::ConfigurePeerVerification(Security::ContextPointer &ctx, const Security::ParsedPortFlags flags)
621f4299 407{
983fab6e 408 int mode;
409
410 // assume each flag is exclusive; flags creator must check this assumption
411 if (flags & SSL_FLAG_DONT_VERIFY_PEER) {
412 debugs(83, DBG_IMPORTANT, "SECURITY WARNING: Peer certificates are not verified for validity!");
413 debugs(83, DBG_IMPORTANT, "UPGRADE NOTICE: The DONT_VERIFY_PEER flag is deprecated. Remove the clientca= option to disable client certificates.");
414 mode = SSL_VERIFY_NONE;
415 }
416 else if (flags & SSL_FLAG_DELAYED_AUTH) {
417 debugs(83, DBG_PARSE_NOTE(3), "not requesting client certificates until ACL processing requires one");
418 mode = SSL_VERIFY_NONE;
419 }
420 else if (flags & SSL_FLAG_CONDITIONAL_AUTH) {
7c25db36 421 debugs(83, DBG_PARSE_NOTE(3), "will request the client certificate but ignore its absence");
983fab6e 422 mode = SSL_VERIFY_PEER;
423 }
424 else {
425 debugs(83, DBG_PARSE_NOTE(3), "Requiring client certificates.");
426 mode = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
427 }
428
429 SSL_CTX_set_verify(ctx.get(), mode, (mode != SSL_VERIFY_NONE) ? ssl_verify_cb : nullptr);
430}
431
432void
433Ssl::DisablePeerVerification(Security::ContextPointer &ctx)
434{
435 debugs(83, DBG_PARSE_NOTE(3), "Not requiring any client certificates");
436 SSL_CTX_set_verify(ctx.get(),SSL_VERIFY_NONE,nullptr);
621f4299
AJ
437}
438
800967af
CT
439static int VerifyCtxCertificates(X509_STORE_CTX *ctx, STACK_OF(X509) *extraCerts);
440
441bool
442Ssl::VerifyConnCertificates(Security::Connection &sconn, const Ssl::X509_STACK_Pointer &extraCerts)
443{
444 const auto peerCertificatesChain = SSL_get_peer_cert_chain(&sconn);
445
446 // TODO: Replace debugs/return false with returning ErrorDetail::Pointer.
447 // Using Security::ErrorDetail terminology, errors in _this_ function are
448 // "non-validation errors", but VerifyCtxCertificates() errors may be
449 // "certificate validation errors". Callers detail SQUID_TLS_ERR_CONNECT.
450 // Some details should be created right here. Others extracted from OpenSSL.
451 // Why not throw? Most of the reasons detailed in the following commit apply
452 // here as well: https://github.com/measurement-factory/squid/commit/e862d33
453
454 if (!peerCertificatesChain || sk_X509_num(peerCertificatesChain) == 0) {
455 debugs(83, 2, "no server certificates");
456 return false;
457 }
458
459 const auto verificationStore = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(&sconn));
460 if (!verificationStore) {
461 debugs(83, 2, "no certificate store");
462 return false;
463 }
464
465 const X509_STORE_CTX_Pointer storeCtx(X509_STORE_CTX_new());
466 if (!storeCtx) {
467 debugs(83, 2, "cannot create X509_STORE_CTX; likely OOM");
468 return false;
469 }
470
471 const auto peerCert = sk_X509_value(peerCertificatesChain, 0);
472 if (!X509_STORE_CTX_init(storeCtx.get(), verificationStore, peerCert, peerCertificatesChain)) {
473 debugs(83, 2, "cannot initialize X509_STORE_CTX");
474 return false;
475 }
476
477#if defined(SSL_CERT_FLAG_SUITEB_128_LOS)
478 // overwrite context Suite B (RFC 5759) flags with connection non-defaults
479 // SSL_set_cert_flags() return type is long, but its implementation actually
480 // returns an unsigned long flags value expected by X509_STORE_CTX_set_flags
481 const unsigned long certFlags = SSL_set_cert_flags(&sconn, 0);
482 if (const auto suiteBflags = certFlags & SSL_CERT_FLAG_SUITEB_128_LOS)
483 X509_STORE_CTX_set_flags(storeCtx.get(), suiteBflags);
484#endif
485
486 if (!X509_STORE_CTX_set_ex_data(storeCtx.get(), SSL_get_ex_data_X509_STORE_CTX_idx(), &sconn)) {
487 debugs(83, 2, "cannot attach SSL object to X509_STORE_CTX");
488 return false;
489 }
490
491 // If we ever add DANE support to Squid, we will supply DANE details here:
492 // X509_STORE_CTX_set0_dane(storeCtx.get(), SSL_get0_dane(&sconn));
493
494 // tell OpenSSL we are verifying a server certificate
495 if (!X509_STORE_CTX_set_default(storeCtx.get(), "ssl_server")) {
496 debugs(83, 2, "cannot set default verification method to ssl_server");
497 return false;
498 }
499
500 // overwrite context "verification parameters" with connection non-defaults
501 const auto param = X509_STORE_CTX_get0_param(storeCtx.get());
502 if (!param) {
503 debugs(83, 2, "no context verification parameters");
504 return false;
505 }
506#if defined(HAVE_X509_VERIFY_PARAM_SET_AUTH_LEVEL)
507 X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(&sconn));
508#endif
509 if (!X509_VERIFY_PARAM_set1(param, SSL_get0_param(&sconn))) {
510 debugs(83, 2, "cannot overwrite context verification parameters");
511 return false;
512 }
513
514 // copy any connection "verify_callback function" to the validation context
515 // (\ref OpenSSL_vcb_disambiguation)
516 if (const auto cb = SSL_get_verify_callback(&sconn))
517 X509_STORE_CTX_set_verify_cb(storeCtx.get(), cb);
518
519 // verify the server certificate chain in the prepared validation context
520 if (VerifyCtxCertificates(storeCtx.get(), extraCerts.get()) <= 0) {
521 // see also: ssl_verify_cb() details errors via ssl_ex_index_ssl_errors
522 const auto verifyResult = X509_STORE_CTX_get_error(storeCtx.get());
523 debugs(83, 3, "verification failure: " << verifyResult << ' ' << X509_verify_cert_error_string(verifyResult));
524 return false;
525 }
526
527 debugs(83, 7, "success");
528 return true;
529}
530
531/* Ssl::VerifyCallbackParameters */
532
533Ssl::VerifyCallbackParameters *
534Ssl::VerifyCallbackParameters::Find(Security::Connection &sconn)
535{
536 return static_cast<VerifyCallbackParameters*>(SSL_get_ex_data(&sconn, ssl_ex_index_verify_callback_parameters));
537}
538
539Ssl::VerifyCallbackParameters *
540Ssl::VerifyCallbackParameters::New(Security::Connection &sconn)
541{
542 Must(!Find(sconn));
543 const auto parameters = new VerifyCallbackParameters();
544 if (!SSL_set_ex_data(&sconn, ssl_ex_index_verify_callback_parameters, parameters)) {
545 delete parameters;
546 throw TextException("SSL_set_ex_data() failed; likely OOM", Here());
547 }
548 return parameters;
549}
550
551Ssl::VerifyCallbackParameters &
552Ssl::VerifyCallbackParameters::At(Security::Connection &sconn)
553{
554 const auto parameters = Find(sconn);
555 Must(parameters);
556 return *parameters;
557}
558
815eaa44 559// "dup" function for SSL_get_ex_new_index("cert_err_check")
7d841344 560#if SQUID_USE_CONST_CRYPTO_EX_DATA_DUP
2a268a06
CT
561static int
562ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void *,
563 int, long, void *)
564#else
815eaa44 565static int
566ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
26ac0430 567 int, long, void *)
2a268a06 568#endif
26ac0430 569{
815eaa44 570 // We do not support duplication of ACLCheckLists.
571 // If duplication is needed, we can count copies with cbdata.
572 assert(false);
573 return 0;
574}
575
576// "free" function for SSL_get_ex_new_index("cert_err_check")
577static void
578ssl_freeAclChecklist(void *, void *ptr, CRYPTO_EX_DATA *,
26ac0430
AJ
579 int, long, void *)
580{
815eaa44 581 delete static_cast<ACLChecklist *>(ptr); // may be NULL
582}
a7ad6e4e 583
4d16918e
CT
584// "free" function for SSL_get_ex_new_index("ssl_error_detail")
585static void
586ssl_free_ErrorDetail(void *, void *ptr, CRYPTO_EX_DATA *,
587 int, long, void *)
588{
83b053a0 589 const auto errDetail = static_cast<Security::ErrorDetail::Pointer*>(ptr);
4d16918e
CT
590 delete errDetail;
591}
592
fb2178bb 593static void
7a957a93 594ssl_free_SslErrors(void *, void *ptr, CRYPTO_EX_DATA *,
87f237a9 595 int, long, void *)
fb2178bb 596{
92e3827b 597 Security::CertErrors *errs = static_cast <Security::CertErrors*>(ptr);
7a957a93 598 delete errs;
fb2178bb
CT
599}
600
0ad3ff51
CT
601// "free" function for SSL_get_ex_new_index("ssl_ex_index_ssl_validation_counter")
602static void
603ssl_free_int(void *, void *ptr, CRYPTO_EX_DATA *,
3cc296c4 604 int, long, void *)
0ad3ff51
CT
605{
606 uint32_t *counter = static_cast <uint32_t *>(ptr);
607 delete counter;
608}
609
4747ea4c
CT
610/// \ingroup ServerProtocolSSLInternal
611/// Callback handler function to release STACK_OF(X509) "ex" data stored
612/// in an SSL object.
613static void
614ssl_free_CertChain(void *, void *ptr, CRYPTO_EX_DATA *,
615 int, long, void *)
616{
617 STACK_OF(X509) *certsChain = static_cast <STACK_OF(X509) *>(ptr);
618 sk_X509_pop_free(certsChain,X509_free);
619}
620
e7bcc25f
CT
621// "free" function for X509 certificates
622static void
623ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *,
87f237a9 624 int, long, void *)
e7bcc25f
CT
625{
626 X509 *cert = static_cast <X509 *>(ptr);
627 X509_free(cert);
628}
629
c1d50c01 630// "free" function for SBuf
68920ad8
CT
631static void
632ssl_free_SBuf(void *, void *ptr, CRYPTO_EX_DATA *,
633 int, long, void *)
634{
635 SBuf *buf = static_cast <SBuf *>(ptr);
636 delete buf;
637}
638
800967af
CT
639/// "free" function for the ssl_ex_index_verify_callback_parameters entry
640static void
641ssl_free_VerifyCallbackParameters(void *, void *ptr, CRYPTO_EX_DATA *,
642 int, long, void *)
643{
644 delete static_cast<Ssl::VerifyCallbackParameters*>(ptr);
645}
646
0a28c16a
AJ
647void
648Ssl::Initialize(void)
f484cdf5 649{
56a35ad1
AR
650 static bool initialized = false;
651 if (initialized)
652 return;
653 initialized = true;
62e76326 654
24b30fdc 655 SQUID_OPENSSL_init_ssl();
62e76326 656
a7dc0869 657#if !defined(OPENSSL_NO_ENGINE)
0a28c16a 658 if (::Config.SSL.ssl_engine) {
95c85af7 659 ENGINE_load_builtin_engines();
56a35ad1 660 ENGINE *e;
0a28c16a
AJ
661 if (!(e = ENGINE_by_id(::Config.SSL.ssl_engine)))
662 fatalf("Unable to find SSL engine '%s'\n", ::Config.SSL.ssl_engine);
56a35ad1
AR
663
664 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
83b053a0 665 const auto ssl_error = ERR_get_error();
ea574635 666 fatalf("Failed to initialise SSL engine: %s\n", Security::ErrorString(ssl_error));
62e76326 667 }
56a35ad1 668 }
a7ad6e4e 669#else
0a28c16a 670 if (::Config.SSL.ssl_engine)
56a35ad1 671 fatalf("Your OpenSSL has no SSL engine support\n");
a7ad6e4e 672#endif
62e76326 673
0a28c16a 674 const char *defName = ::Config.SSL.certSignHash ? ::Config.SSL.certSignHash : SQUID_SSL_SIGN_HASH_IF_NONE;
3c26b00a
CT
675 Ssl::DefaultSignHash = EVP_get_digestbyname(defName);
676 if (!Ssl::DefaultSignHash)
677 fatalf("Sign hash '%s' is not supported\n", defName);
678
fa1cf51e 679 ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, ssl_free_SBuf);
a7ad6e4e 680 ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
815eaa44 681 ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
4d16918e 682 ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
e7bcc25f 683 ssl_ex_index_ssl_peeked_cert = SSL_get_ex_new_index(0, (void *) "ssl_peeked_cert", NULL, NULL, &ssl_free_X509);
7a957a93 684 ssl_ex_index_ssl_errors = SSL_get_ex_new_index(0, (void *) "ssl_errors", NULL, NULL, &ssl_free_SslErrors);
4747ea4c 685 ssl_ex_index_ssl_cert_chain = SSL_get_ex_new_index(0, (void *) "ssl_cert_chain", NULL, NULL, &ssl_free_CertChain);
0ad3ff51 686 ssl_ex_index_ssl_validation_counter = SSL_get_ex_new_index(0, (void *) "ssl_validation_counter", NULL, NULL, &ssl_free_int);
800967af 687 ssl_ex_index_verify_callback_parameters = SSL_get_ex_new_index(0, (void *) "verify_callback_parameters", nullptr, nullptr, &ssl_free_VerifyCallbackParameters);
55369ae6
AR
688}
689
c75aba02 690bool
b23f5f9c 691Ssl::InitServerContext(Security::ContextPointer &ctx, AnyP::PortCfg &port)
86660d64 692{
9ad528b8 693 if (!ctx)
c75aba02 694 return false;
86660d64 695
c75aba02 696 return true;
a7ad6e4e 697}
698
c75aba02 699bool
983fab6e 700Ssl::InitClientContext(Security::ContextPointer &ctx, Security::PeerOptions &peer, Security::ParsedPortFlags fl)
d620ae0e 701{
64769c79 702 if (!ctx)
c75aba02 703 return false;
62e76326 704
d1d72d43
AJ
705 if (!peer.sslCipher.isEmpty()) {
706 debugs(83, 5, "Using chiper suite " << peer.sslCipher << ".");
62e76326 707
d1d72d43 708 const char *cipher = peer.sslCipher.c_str();
64769c79 709 if (!SSL_CTX_set_cipher_list(ctx.get(), cipher)) {
83b053a0 710 const auto ssl_error = ERR_get_error();
62e76326 711 fatalf("Failed to set SSL cipher suite '%s': %s\n",
ea574635 712 cipher, Security::ErrorString(ssl_error));
62e76326 713 }
a7ad6e4e 714 }
62e76326 715
332c979d
AJ
716 if (!peer.certs.empty()) {
717 // TODO: support loading multiple cert/key pairs
718 auto &keys = peer.certs.front();
719 if (!keys.certFile.isEmpty()) {
720 debugs(83, DBG_IMPORTANT, "Using certificate in " << keys.certFile);
721
722 const char *certfile = keys.certFile.c_str();
64769c79 723 if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) {
83b053a0 724 const auto ssl_error = ERR_get_error();
332c979d 725 fatalf("Failed to acquire SSL certificate '%s': %s\n",
ea574635 726 certfile, Security::ErrorString(ssl_error));
332c979d 727 }
62e76326 728
332c979d
AJ
729 debugs(83, DBG_IMPORTANT, "Using private key in " << keys.privateKeyFile);
730 const char *keyfile = keys.privateKeyFile.c_str();
64769c79 731 ssl_ask_password(ctx.get(), keyfile);
62e76326 732
64769c79 733 if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) {
83b053a0 734 const auto ssl_error = ERR_get_error();
332c979d 735 fatalf("Failed to acquire SSL private key '%s': %s\n",
ea574635 736 keyfile, Security::ErrorString(ssl_error));
332c979d 737 }
62e76326 738
332c979d 739 debugs(83, 5, "Comparing private and public SSL keys.");
62e76326 740
64769c79 741 if (!SSL_CTX_check_private_key(ctx.get())) {
83b053a0 742 const auto ssl_error = ERR_get_error();
332c979d 743 fatalf("SSL private key '%s' does not match public key '%s': %s\n",
ea574635 744 certfile, keyfile, Security::ErrorString(ssl_error));
332c979d 745 }
62e76326 746 }
a7ad6e4e 747 }
62e76326 748
cf487124 749 MaybeSetupRsaCallback(ctx);
f484cdf5 750
983fab6e 751 Ssl::ConfigurePeerVerification(ctx, fl);
f484cdf5 752
c75aba02 753 return true;
f484cdf5 754}
755
63be0a78 756/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 757static const char *
758ssl_get_attribute(X509_NAME * name, const char *attribute_name)
759{
760 static char buffer[1024];
a7ad6e4e 761 buffer[0] = '\0';
762
763 if (strcmp(attribute_name, "DN") == 0) {
62e76326 764 X509_NAME_oneline(name, buffer, sizeof(buffer));
627059a5
AJ
765 } else {
766 int nid = OBJ_txt2nid(const_cast<char *>(attribute_name));
767 if (nid == 0) {
768 debugs(83, DBG_IMPORTANT, "WARNING: Unknown SSL attribute name '" << attribute_name << "'");
769 return nullptr;
770 }
771 X509_NAME_get_text_by_NID(name, nid, buffer, sizeof(buffer));
a7ad6e4e 772 }
62e76326 773
627059a5 774 return *buffer ? buffer : nullptr;
a7ad6e4e 775}
776
63be0a78 777/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 778const char *
00352183 779Ssl::GetX509UserAttribute(X509 * cert, const char *attribute_name)
a7ad6e4e 780{
a7ad6e4e 781 X509_NAME *name;
23e6c4ae 782 const char *ret;
a7ad6e4e 783
a7ad6e4e 784 if (!cert)
62e76326 785 return NULL;
a7ad6e4e 786
5a4684b6 787 name = X509_get_subject_name(cert);
a7ad6e4e 788
23e6c4ae 789 ret = ssl_get_attribute(name, attribute_name);
790
23e6c4ae 791 return ret;
a7ad6e4e 792}
793
00352183
AR
794const char *
795Ssl::GetX509Fingerprint(X509 * cert, const char *)
796{
797 static char buf[1024];
798 if (!cert)
799 return NULL;
960e100b 800
00352183
AR
801 unsigned int n;
802 unsigned char md[EVP_MAX_MD_SIZE];
803 if (!X509_digest(cert, EVP_sha1(), md, &n))
804 return NULL;
805
806 assert(3 * n + 1 < sizeof(buf));
807
808 char *s = buf;
809 for (unsigned int i=0; i < n; ++i, s += 3) {
810 const char term = (i + 1 < n) ? ':' : '\0';
811 snprintf(s, 4, "%02X%c", md[i], term);
812 }
813
814 return buf;
815}
816
12b5040f
DN
817SBuf
818Ssl::GetX509PEM(X509 * cert)
819{
820 assert(cert);
821
822 Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem()));
823 PEM_write_bio_X509(bio.get(), cert);
824
825 char *ptr;
826 const auto len = BIO_get_mem_data(bio.get(), &ptr);
827 return SBuf(ptr, len);
828}
829
63be0a78 830/// \ingroup ServerProtocolSSLInternal
a7ad6e4e 831const char *
00352183 832Ssl::GetX509CAAttribute(X509 * cert, const char *attribute_name)
a7ad6e4e 833{
00352183 834
a7ad6e4e 835 X509_NAME *name;
23e6c4ae 836 const char *ret;
a7ad6e4e 837
a7ad6e4e 838 if (!cert)
62e76326 839 return NULL;
a7ad6e4e 840
5a4684b6 841 name = X509_get_issuer_name(cert);
a7ad6e4e 842
23e6c4ae 843 ret = ssl_get_attribute(name, attribute_name);
844
00352183
AR
845 return ret;
846}
847
848const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name)
849{
850 if (!ssl)
851 return NULL;
852
853 X509 *cert = SSL_get_peer_certificate(ssl);
854
855 const char *attr = Ssl::GetX509UserAttribute(cert, attribute_name);
856
23e6c4ae 857 X509_free(cert);
00352183
AR
858 return attr;
859}
23e6c4ae 860
00352183
AR
861const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name)
862{
863 if (!ssl)
864 return NULL;
865
866 X509 *cert = SSL_get_peer_certificate(ssl);
867
868 const char *attr = Ssl::GetX509CAAttribute(cert, attribute_name);
869
870 X509_free(cert);
871 return attr;
a7ad6e4e 872}
873
a7ad6e4e 874const char *
875sslGetUserEmail(SSL * ssl)
876{
e6ceef10 877 return sslGetUserAttribute(ssl, "emailAddress");
a7ad6e4e 878}
4ac9968f 879
12b5040f 880SBuf
4ac9968f 881sslGetUserCertificatePEM(SSL *ssl)
882{
12b5040f 883 assert(ssl);
4ac9968f 884
12b5040f
DN
885 if (const auto cert = SSL_get_peer_certificate(ssl))
886 return Ssl::GetX509PEM(cert);
4ac9968f 887
12b5040f 888 return SBuf();
4ac9968f 889}
3d61c476 890
12b5040f 891SBuf
3d61c476 892sslGetUserCertificateChainPEM(SSL *ssl)
893{
12b5040f 894 assert(ssl);
3d61c476 895
12b5040f 896 auto chain = SSL_get_peer_cert_chain(ssl);
3d61c476 897
898 if (!chain)
899 return sslGetUserCertificatePEM(ssl);
900
12b5040f 901 Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem()));
3d61c476 902
12b5040f 903 for (int i = 0; i < sk_X509_num(chain); ++i) {
3d61c476 904 X509 *cert = sk_X509_value(chain, i);
12b5040f 905 PEM_write_bio_X509(bio.get(), cert);
3d61c476 906 }
907
12b5040f
DN
908 char *ptr;
909 const auto len = BIO_get_mem_data(bio.get(), &ptr);
910 return SBuf(ptr, len);
3d61c476 911}
454e8283 912
95d2589c 913/// Create SSL context and apply ssl certificate and private key to it.
0476ec45 914Security::ContextPointer
cf487124 915Ssl::createSSLContext(Security::CertPointer & x509, Security::PrivateKeyPointer & pkey, Security::ServerOptions &options)
95d2589c 916{
cf487124 917 Security::ContextPointer ctx(options.createBlankContext());
95d2589c 918
0476ec45
AJ
919 if (!SSL_CTX_use_certificate(ctx.get(), x509.get()))
920 return Security::ContextPointer();
95d2589c 921
0476ec45
AJ
922 if (!SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()))
923 return Security::ContextPointer();
86660d64 924
cf487124 925 if (!options.updateContextConfig(ctx))
0476ec45 926 return Security::ContextPointer();
86660d64 927
0476ec45 928 return ctx;
95d2589c
CT
929}
930
0476ec45 931Security::ContextPointer
cf487124 932Ssl::GenerateSslContextUsingPkeyAndCertFromMemory(const char * data, Security::ServerOptions &options, bool trusted)
95d2589c 933{
f97700a0 934 Security::CertPointer cert;
cf487124 935 Security::PrivateKeyPointer pkey;
96993ee0 936 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data) || !cert || !pkey)
0476ec45 937 return Security::ContextPointer();
95d2589c 938
cf487124 939 Security::ContextPointer ctx(createSSLContext(cert, pkey, options));
5107d2c4 940 if (ctx && trusted)
cf487124 941 Ssl::chainCertificatesToSSLContext(ctx, options);
5107d2c4 942 return ctx;
95d2589c
CT
943}
944
0476ec45 945Security::ContextPointer
cf487124 946Ssl::GenerateSslContext(CertificateProperties const &properties, Security::ServerOptions &options, bool trusted)
95d2589c 947{
f97700a0 948 Security::CertPointer cert;
cf487124 949 Security::PrivateKeyPointer pkey;
96993ee0 950 if (!generateSslCertificate(cert, pkey, properties) || !cert || !pkey)
0476ec45 951 return Security::ContextPointer();
95d2589c 952
cf487124 953 Security::ContextPointer ctx(createSSLContext(cert, pkey, options));
5107d2c4 954 if (ctx && trusted)
cf487124 955 Ssl::chainCertificatesToSSLContext(ctx, options);
5107d2c4 956 return ctx;
95d2589c
CT
957}
958
d8f0ceab 959void
cf487124 960Ssl::chainCertificatesToSSLContext(Security::ContextPointer &ctx, Security::ServerOptions &options)
d8f0ceab 961{
b23f5f9c 962 assert(ctx);
d8f0ceab 963 // Add signing certificate to the certificates chain
51e09c08 964 X509 *signingCert = options.signingCa.cert.get();
b23f5f9c 965 if (SSL_CTX_add_extra_chain_cert(ctx.get(), signingCert)) {
d8f0ceab 966 // increase the certificate lock
6f2b8700 967 X509_up_ref(signingCert);
d8f0ceab 968 } else {
83b053a0 969 const auto ssl_error = ERR_get_error();
ea574635 970 debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << Security::ErrorString(ssl_error));
d8f0ceab 971 }
51e09c08
AJ
972
973 for (auto cert : options.signingCa.chain) {
974 if (SSL_CTX_add_extra_chain_cert(ctx.get(), cert.get())) {
975 // increase the certificate lock
976 X509_up_ref(cert.get());
977 } else {
978 const auto error = ERR_get_error();
979 debugs(83, DBG_IMPORTANT, "WARNING: can not add certificate to SSL dynamic context chain: " << Security::ErrorString(error));
980 }
981 }
d8f0ceab
CT
982}
983
984void
b23f5f9c 985Ssl::configureUnconfiguredSslContext(Security::ContextPointer &ctx, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port)
d8f0ceab 986{
b23f5f9c 987 if (ctx && signAlgorithm == Ssl::algSignTrusted)
cf487124 988 Ssl::chainCertificatesToSSLContext(ctx, port.secure);
d8f0ceab
CT
989}
990
d620ae0e
CT
991bool
992Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port)
993{
f97700a0 994 Security::CertPointer cert;
cf487124 995 Security::PrivateKeyPointer pkey;
d620ae0e
CT
996 if (!generateSslCertificate(cert, pkey, properties))
997 return false;
998
999 if (!cert)
1000 return false;
1001
1002 if (!pkey)
1003 return false;
1004
1005 if (!SSL_use_certificate(ssl, cert.get()))
1006 return false;
1007
1008 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1009 return false;
1010
1011 return true;
1012}
1013
1014bool
1015Ssl::configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port)
1016{
f97700a0 1017 Security::CertPointer cert;
cf487124 1018 Security::PrivateKeyPointer pkey;
d620ae0e
CT
1019 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data))
1020 return false;
1021
1022 if (!cert || !pkey)
1023 return false;
1024
1025 if (!SSL_use_certificate(ssl, cert.get()))
1026 return false;
1027
1028 if (!SSL_use_PrivateKey(ssl, pkey.get()))
1029 return false;
1030
1031 return true;
1032}
1033
b23f5f9c 1034bool
72247610 1035Ssl::verifySslCertificate(const Security::ContextPointer &ctx, CertificateProperties const &properties)
95d2589c 1036{
b8649ee4
CT
1037#if HAVE_SSL_CTX_GET0_CERTIFICATE
1038 X509 * cert = SSL_CTX_get0_certificate(ctx.get());
1039#elif SQUID_USE_SSLGETCERTIFICATE_HACK
b8658552 1040 // SSL_get_certificate is buggy in openssl versions 1.0.1d and 1.0.1e
b23f5f9c 1041 // Try to retrieve certificate directly from Security::ContextPointer object
b23f5f9c 1042 X509 ***pCert = (X509 ***)ctx->cert;
b8658552 1043 X509 * cert = pCert && *pCert ? **pCert : NULL;
fc321c30
CT
1044#elif SQUID_SSLGETCERTIFICATE_BUGGY
1045 X509 * cert = NULL;
1046 assert(0);
b8658552 1047#else
95d2589c 1048 // Temporary ssl for getting X509 certificate from SSL_CTX.
c96b5508 1049 Security::SessionPointer ssl(Security::NewSessionObject(ctx));
95d2589c 1050 X509 * cert = SSL_get_certificate(ssl.get());
b8658552
CT
1051#endif
1052 if (!cert)
1053 return false;
24b30fdc
EQ
1054 const auto time_notBefore = X509_getm_notBefore(cert);
1055 const auto time_notAfter = X509_getm_notAfter(cert);
5107d2c4 1056 return (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
95d2589c
CT
1057}
1058
428819f3 1059void
253749a8
CT
1060Ssl::setClientSNI(SSL *ssl, const char *fqdn)
1061{
428819f3
RB
1062 const Ip::Address test(fqdn);
1063 if (!test.isAnyAddr())
1064 return; // raw IP is inappropriate for SNI
1065
253749a8
CT
1066 //The SSL_CTRL_SET_TLSEXT_HOSTNAME is a openssl macro which indicates
1067 // if the TLS servername extension (SNI) is enabled in openssl library.
1068#if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
1069 if (!SSL_set_tlsext_host_name(ssl, fqdn)) {
83b053a0 1070 const auto ssl_error = ERR_get_error();
253749a8 1071 debugs(83, 3, "WARNING: unable to set TLS servername extension (SNI): " <<
ea574635 1072 Security::ErrorString(ssl_error) << "\n");
253749a8 1073 }
253749a8 1074#else
34492237 1075 debugs(83, 7, "no support for TLS servername extension (SNI)");
253749a8
CT
1076#endif
1077}
1078
800967af
CT
1079const char *
1080Ssl::findIssuerUri(X509 *cert)
55369ae6
AR
1081{
1082 AUTHORITY_INFO_ACCESS *info;
1083 if (!cert)
168d2b30 1084 return nullptr;
4b5ea8a6 1085 info = static_cast<AUTHORITY_INFO_ACCESS *>(X509_get_ext_d2i(cert, NID_info_access, NULL, NULL));
55369ae6 1086 if (!info)
168d2b30 1087 return nullptr;
55369ae6
AR
1088
1089 static char uri[MAX_URL];
1090 uri[0] = '\0';
1091
1092 for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
1093 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
1094 if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers) {
1095 if (ad->location->type == GEN_URI) {
2a268a06
CT
1096 xstrncpy(uri,
1097 reinterpret_cast<const char *>(
2a268a06 1098 ASN1_STRING_get0_data(ad->location->d.uniformResourceIdentifier)
ac756c8c 1099 ),
2a268a06 1100 sizeof(uri));
55369ae6
AR
1101 }
1102 break;
1103 }
1104 }
1105 AUTHORITY_INFO_ACCESS_free(info);
168d2b30 1106 return uri[0] != '\0' ? uri : nullptr;
55369ae6
AR
1107}
1108
866be11c
CT
1109bool
1110Ssl::loadCerts(const char *certsFile, Ssl::CertsIndexedList &list)
1111{
1112 BIO *in = BIO_new_file(certsFile, "r");
1113 if (!in) {
1114 debugs(83, DBG_IMPORTANT, "Failed to open '" << certsFile << "' to load certificates");
1115 return false;
1116 }
1117
1118 X509 *aCert;
1119 while((aCert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1120 static char buffer[2048];
1121 X509_NAME_oneline(X509_get_subject_name(aCert), buffer, sizeof(buffer));
1122 list.insert(std::pair<SBuf, X509 *>(SBuf(buffer), aCert));
1123 }
1124 debugs(83, 4, "Loaded " << list.size() << " certificates from file: '" << certsFile << "'");
1125 BIO_free(in);
1126 return true;
1127}
1128
6c4905ef
CT
1129/// quickly find the issuer certificate of a certificate cert in the
1130/// Ssl::CertsIndexedList list
55369ae6 1131static X509 *
6c4905ef 1132findCertIssuerFast(Ssl::CertsIndexedList &list, X509 *cert)
55369ae6
AR
1133{
1134 static char buffer[2048];
1135
1136 if (X509_NAME *issuerName = X509_get_issuer_name(cert))
1137 X509_NAME_oneline(issuerName, buffer, sizeof(buffer));
1138 else
1139 return NULL;
1140
1141 const auto ret = list.equal_range(SBuf(buffer));
1142 for (Ssl::CertsIndexedList::iterator it = ret.first; it != ret.second; ++it) {
1143 X509 *issuer = it->second;
2f774469 1144 if (X509_check_issued(issuer, cert) == X509_V_OK) {
55369ae6
AR
1145 return issuer;
1146 }
1147 }
1148 return NULL;
1149}
1150
6c4905ef 1151/// slowly find the issuer certificate of a given cert using linear search
800967af
CT
1152static X509 *
1153sk_x509_findIssuer(const STACK_OF(X509) *sk, X509 *cert)
55369ae6 1154{
800967af
CT
1155 if (!sk)
1156 return nullptr;
1157
1158 const auto certCount = sk_X509_num(sk);
1159 for (int i = 0; i < certCount; ++i) {
1160 const auto issuer = sk_X509_value(sk, i);
1161 if (X509_check_issued(issuer, cert) == X509_V_OK)
1162 return issuer;
55369ae6 1163 }
800967af 1164 return nullptr;
55369ae6
AR
1165}
1166
800967af
CT
1167/// finds issuer of a given certificate in CA store of the given connContext
1168/// \returns the cert issuer (after increasing its reference count) or nil
1169static X509 *
1170findIssuerInCaDb(X509 *cert, const Security::ContextPointer &connContext)
9fdbe165
CT
1171{
1172 if (!connContext)
800967af 1173 return nullptr;
9fdbe165
CT
1174
1175 X509_STORE_CTX *storeCtx = X509_STORE_CTX_new();
1176 if (!storeCtx) {
1177 debugs(83, DBG_IMPORTANT, "Failed to allocate STORE_CTX object");
800967af 1178 return nullptr;
9fdbe165
CT
1179 }
1180
800967af 1181 X509 *issuer = nullptr;
9fdbe165
CT
1182 X509_STORE *store = SSL_CTX_get_cert_store(connContext.get());
1183 if (X509_STORE_CTX_init(storeCtx, store, nullptr, nullptr)) {
800967af
CT
1184 const auto ret = X509_STORE_CTX_get1_issuer(&issuer, storeCtx, cert);
1185 if (ret > 0) {
1186 assert(issuer);
1187 char buffer[256];
1188 debugs(83, 5, "found " << X509_NAME_oneline(X509_get_subject_name(issuer), buffer, sizeof(buffer)));
1189 } else {
1190 debugs(83, ret < 0 ? 2 : 3, "not found or failure: " << ret);
1191 assert(!issuer);
1192 }
9fdbe165 1193 } else {
83b053a0 1194 const auto ssl_error = ERR_get_error();
9fdbe165
CT
1195 debugs(83, DBG_IMPORTANT, "Failed to initialize STORE_CTX object: " << Security::ErrorString(ssl_error));
1196 }
800967af 1197
9fdbe165
CT
1198 X509_STORE_CTX_free(storeCtx);
1199
800967af 1200 return issuer;
9fdbe165
CT
1201}
1202
800967af
CT
1203Security::CertPointer
1204Ssl::findIssuerCertificate(X509 *cert, const STACK_OF(X509) *serverCertificates, const Security::ContextPointer &context)
55369ae6 1205{
800967af 1206 Must(cert);
55369ae6 1207
800967af
CT
1208 // check certificate chain, if any
1209 if (const auto issuer = serverCertificates ? sk_x509_findIssuer(serverCertificates, cert) : nullptr) {
1210 X509_up_ref(issuer);
1211 return Security::CertPointer(issuer);
55369ae6 1212 }
55369ae6 1213
800967af
CT
1214 // check untrusted certificates
1215 if (const auto issuer = findCertIssuerFast(SquidUntrustedCerts, cert)) {
1216 X509_up_ref(issuer);
1217 return Security::CertPointer(issuer);
55369ae6 1218 }
55369ae6 1219
800967af
CT
1220 // check trusted CA certificates
1221 if (const auto issuer = findIssuerInCaDb(cert, context)) {
1222 // no X509_up_ref(issuer) because findIssuerInCaDb() ups reference count
1223 return Security::CertPointer(issuer);
55369ae6 1224 }
800967af
CT
1225
1226 return Security::CertPointer(nullptr);
55369ae6
AR
1227}
1228
800967af
CT
1229bool
1230Ssl::missingChainCertificatesUrls(std::queue<SBuf> &URIs, const STACK_OF(X509) &serverCertificates, const Security::ContextPointer &context)
a34d1d2d 1231{
800967af
CT
1232 for (int i = 0; i < sk_X509_num(&serverCertificates); ++i) {
1233 const auto cert = sk_X509_value(&serverCertificates, i);
a34d1d2d 1234
800967af
CT
1235 if (findIssuerCertificate(cert, &serverCertificates, context))
1236 continue;
1237
1238 if (const auto issuerUri = findIssuerUri(cert)) {
1239 URIs.push(SBuf(issuerUri));
1240 } else {
1241 static char name[2048];
1242 debugs(83, 3, "Issuer certificate for " <<
1243 X509_NAME_oneline(X509_get_subject_name(cert), name, sizeof(name)) <<
1244 " is missing and its URI is not provided");
1245 }
a34d1d2d 1246 }
800967af
CT
1247
1248 debugs(83, (URIs.empty() ? 3 : 5), "found: " << URIs.size());
1249 return !URIs.empty();
a34d1d2d
CT
1250}
1251
55369ae6
AR
1252/// add missing issuer certificates to untrustedCerts
1253static void
800967af 1254completeIssuers(X509_STORE_CTX *ctx, STACK_OF(X509) &untrustedCerts)
55369ae6 1255{
800967af
CT
1256 debugs(83, 2, "completing " << sk_X509_num(&untrustedCerts) <<
1257 " OpenSSL untrusted certs using " << SquidUntrustedCerts.size() <<
1258 " configured untrusted certificates");
55369ae6 1259
2a268a06
CT
1260 const X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
1261 int depth = X509_VERIFY_PARAM_get_depth(param);
800967af
CT
1262 Security::CertPointer current;
1263 current.resetAndLock(X509_STORE_CTX_get0_cert(ctx));
55369ae6
AR
1264 int i = 0;
1265 for (i = 0; current && (i < depth); ++i) {
800967af 1266 if (X509_check_issued(current.get(), current.get()) == X509_V_OK) {
55369ae6 1267 // either ctx->cert is itself self-signed or untrustedCerts
2f8abb64 1268 // already contain the self-signed current certificate
55369ae6
AR
1269 break;
1270 }
1271
1272 // untrustedCerts is short, not worth indexing
800967af
CT
1273 const Security::ContextPointer nullCtx;
1274 auto issuer = Ssl::findIssuerCertificate(current.get(), &untrustedCerts, nullCtx);
55369ae6 1275 current = issuer;
800967af
CT
1276 if (issuer)
1277 sk_X509_push(&untrustedCerts, issuer.release());
55369ae6
AR
1278 }
1279
1280 if (i >= depth)
1281 debugs(83, 2, "exceeded the maximum certificate chain length: " << depth);
1282}
1283
800967af
CT
1284/// Validates certificates while consulting sslproxy_foreign_intermediate_certs
1285/// and, optionally, the given extra certificates.
1286/// \returns whatever OpenSSL X509_verify_cert() returns
55369ae6 1287static int
800967af 1288VerifyCtxCertificates(X509_STORE_CTX *ctx, STACK_OF(X509) *extraCerts)
55369ae6 1289{
55369ae6
AR
1290 // OpenSSL already maintains ctx->untrusted but we cannot modify
1291 // internal OpenSSL list directly. We have to give OpenSSL our own
1292 // list, but it must include certificates on the OpenSSL ctx->untrusted
2a268a06 1293 STACK_OF(X509) *oldUntrusted = X509_STORE_CTX_get0_untrusted(ctx);
800967af
CT
1294 // X509_chain_up_ref() increments cert references _and_ dupes the stack
1295 Ssl::X509_STACK_Pointer untrustedCerts(oldUntrusted ? X509_chain_up_ref(oldUntrusted) : sk_X509_new_null());
1296
1297 if (extraCerts) {
1298 for (int i = 0; i < sk_X509_num(extraCerts); ++i) {
1299 const auto cert = sk_X509_value(extraCerts, i);
1300 X509_up_ref(cert);
1301 sk_X509_push(untrustedCerts.get(), cert);
1302 }
55369ae6
AR
1303 }
1304
1305 // If the local untrusted certificates internal database is used
1306 // run completeIssuers to add missing certificates if possible.
1307 if (SquidUntrustedCerts.size() > 0)
800967af 1308 completeIssuers(ctx, *untrustedCerts);
55369ae6 1309
800967af 1310 X509_STORE_CTX_set0_untrusted(ctx, untrustedCerts.get()); // No locking/unlocking, just sets ctx->untrusted
55369ae6 1311 int ret = X509_verify_cert(ctx);
24b30fdc 1312 X509_STORE_CTX_set0_untrusted(ctx, oldUntrusted); // Set back the old untrusted list
55369ae6
AR
1313 return ret;
1314}
1315
800967af
CT
1316/// \interface OpenSSL_vcb_disambiguation
1317///
1318/// OpenSSL has two very different concepts with nearly identical names:
1319///
1320/// a) A (replaceable) certificate verification function -- X509_verify_cert():
1321/// This function drives the entire certificate verification algorithm.
1322/// It can be called directly, but is usually called during SSL_connect().
1323/// OpenSSL calls this function a "verification callback function".
1324/// SSL_CTX_set_cert_verify_callback(3) replaces X509_verify_cert() default.
1325///
1326/// b) An (optional) certificate verification adjustment callback:
1327/// This function, if set, is called at the end of (a) to adjust (a) results.
1328/// It is never called directly, only from (a).
1329/// OpenSSL calls this function a "verify_callback function".
1330/// The SSL_CTX_set_verify(3) family of functions sets this function.
1331
1332/// Validates certificates while consulting sslproxy_foreign_intermediate_certs
1333/// but without using any dynamically downloaded intermediate certificates.
1334/// OpenSSL "verification callback function" (\ref OpenSSL_vcb_disambiguation)
1335static int
1336untrustedToStoreCtx_cb(X509_STORE_CTX *ctx, void *)
1337{
1338 debugs(83, 4, "Try to use pre-downloaded intermediate certificates");
1339 return VerifyCtxCertificates(ctx, nullptr);
1340}
1341
55369ae6
AR
1342void
1343Ssl::useSquidUntrusted(SSL_CTX *sslContext)
1344{
1345 SSL_CTX_set_cert_verify_callback(sslContext, untrustedToStoreCtx_cb, NULL);
1346}
1347
1348bool
1349Ssl::loadSquidUntrusted(const char *path)
1350{
1351 return Ssl::loadCerts(path, SquidUntrustedCerts);
1352}
1353
1354void
1355Ssl::unloadSquidUntrusted()
1356{
1357 if (SquidUntrustedCerts.size()) {
1358 for (Ssl::CertsIndexedList::iterator it = SquidUntrustedCerts.begin(); it != SquidUntrustedCerts.end(); ++it) {
1359 X509_free(it->second);
1360 }
1361 SquidUntrustedCerts.clear();
1362 }
1363}
1364
cf487124 1365bool Ssl::generateUntrustedCert(Security::CertPointer &untrustedCert, Security::PrivateKeyPointer &untrustedPkey, Security::CertPointer const &cert, Security::PrivateKeyPointer const & pkey)
95588170
CT
1366{
1367 // Generate the self-signed certificate, using a hard-coded subject prefix
1368 Ssl::CertificateProperties certProperties;
1369 if (const char *cn = CommonHostName(cert.get())) {
1370 certProperties.commonName = "Not trusted by \"";
1371 certProperties.commonName += cn;
1372 certProperties.commonName += "\"";
87f237a9 1373 } else if (const char *org = getOrganization(cert.get())) {
95588170
CT
1374 certProperties.commonName = "Not trusted by \"";
1375 certProperties.commonName += org;
1376 certProperties.commonName += "\"";
87f237a9 1377 } else
95588170
CT
1378 certProperties.commonName = "Not trusted";
1379 certProperties.setCommonName = true;
1380 // O, OU, and other CA subject fields will be mimicked
1381 // Expiration date and other common properties will be mimicked
1382 certProperties.signAlgorithm = Ssl::algSignSelf;
1383 certProperties.signWithPkey.resetAndLock(pkey.get());
1384 certProperties.mimicCert.resetAndLock(cert.get());
1385 return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties);
1386}
1387
5107d2c4
CT
1388void Ssl::InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBuf &key)
1389{
1390 bool origSignatureAsKey = false;
70cfe22f
AJ
1391 if (certProperties.mimicCert) {
1392 if (auto *sig = Ssl::X509_get_signature(certProperties.mimicCert)) {
5107d2c4
CT
1393 origSignatureAsKey = true;
1394 key.append((const char *)sig->data, sig->length);
1395 }
1396 }
1397
1398 if (!origSignatureAsKey || certProperties.setCommonName) {
1399 // Use common name instead
1400 key.append(certProperties.commonName.c_str());
1401 }
1402 key.append(certProperties.setCommonName ? '1' : '0');
1403 key.append(certProperties.setValidAfter ? '1' : '0');
1404 key.append(certProperties.setValidBefore ? '1' : '0');
1405 key.append(certProperties.signAlgorithm != Ssl:: algSignEnd ? certSignAlgorithm(certProperties.signAlgorithm) : "-");
1406 key.append(certProperties.signHash ? EVP_MD_name(certProperties.signHash) : "-");
1407
1408 if (certProperties.mimicCert) {
64e64225
AR
1409 Ssl::BIO_Pointer bio(BIO_new_SBuf(&key));
1410 ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bio.get(), (ASN1_VALUE *)certProperties.mimicCert.get());
5107d2c4
CT
1411 }
1412}
1413
1414static int
1415bio_sbuf_create(BIO* bio)
1416{
1417 BIO_set_init(bio, 0);
1418 BIO_set_data(bio, NULL);
1419 return 1;
1420}
1421
1422static int
1423bio_sbuf_destroy(BIO* bio)
1424{
1425 if (!bio)
1426 return 0;
1427 return 1;
1428}
1429
1430int
1431bio_sbuf_write(BIO* bio, const char* data, int len)
1432{
1433 SBuf *buf = static_cast<SBuf *>(BIO_get_data(bio));
64e64225 1434 // TODO: Convert exceptions into BIO errors
5107d2c4
CT
1435 buf->append(data, len);
1436 return len;
1437}
1438
1439int
1440bio_sbuf_puts(BIO* bio, const char* data)
1441{
64e64225 1442 // TODO: use bio_sbuf_write() instead
5107d2c4
CT
1443 SBuf *buf = static_cast<SBuf *>(BIO_get_data(bio));
1444 size_t oldLen = buf->length();
1445 buf->append(data);
1446 return buf->length() - oldLen;
1447}
1448
1449long
1450bio_sbuf_ctrl(BIO* bio, int cmd, long num, void* ptr) {
1451 SBuf *buf = static_cast<SBuf *>(BIO_get_data(bio));
1452 switch (cmd) {
1453 case BIO_CTRL_RESET:
64e64225 1454 // TODO: Convert exceptions into BIO errors
5107d2c4
CT
1455 buf->clear();
1456 return 1;
1457 case BIO_CTRL_FLUSH:
1458 return 1;
1459 default:
1460 return 0;
1461 }
1462}
1463
5107d2c4
CT
1464BIO *Ssl::BIO_new_SBuf(SBuf *buf)
1465{
1466#if HAVE_LIBCRYPTO_BIO_METH_NEW
64e64225 1467 static BIO_METHOD *BioSBufMethods = nullptr;
5107d2c4
CT
1468 if (!BioSBufMethods) {
1469 BioSBufMethods = BIO_meth_new(BIO_TYPE_MEM, "Squid-SBuf");
1470 BIO_meth_set_write(BioSBufMethods, bio_sbuf_write);
1471 BIO_meth_set_read(BioSBufMethods, nullptr);
1472 BIO_meth_set_puts(BioSBufMethods, bio_sbuf_puts);
1473 BIO_meth_set_gets(BioSBufMethods, nullptr);
1474 BIO_meth_set_ctrl(BioSBufMethods, bio_sbuf_ctrl);
1475 BIO_meth_set_create(BioSBufMethods, bio_sbuf_create);
1476 BIO_meth_set_destroy(BioSBufMethods, bio_sbuf_destroy);
1477 }
1478#else
64e64225
AR
1479 static BIO_METHOD *BioSBufMethods = new BIO_METHOD({
1480 BIO_TYPE_MEM,
1481 "Squid SBuf",
1482 bio_sbuf_write,
1483 nullptr,
1484 bio_sbuf_puts,
1485 nullptr,
1486 bio_sbuf_ctrl,
1487 bio_sbuf_create,
1488 bio_sbuf_destroy,
1489 NULL
1490 });
5107d2c4 1491#endif
64e64225
AR
1492 BIO *bio = BIO_new(BioSBufMethods);
1493 Must(bio);
5107d2c4
CT
1494 BIO_set_data(bio, buf);
1495 BIO_set_init(bio, 1);
1496 return bio;
1497}
1498
cb4f4424 1499#endif /* USE_OPENSSL */
f53969cc 1500