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