]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/support.cc
Bug 4112: ssl_engine does not accept cryptodev
[thirdparty/squid.git] / src / ssl / support.cc
1 /*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /* DEBUG: section 83 SSL accelerator support */
10
11 #include "squid.h"
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 */
16 #if USE_OPENSSL
17
18 #include "acl/FilledChecklist.h"
19 #include "anyp/PortCfg.h"
20 #include "fatal.h"
21 #include "fd.h"
22 #include "fde.h"
23 #include "globals.h"
24 #include "ipc/MemMap.h"
25 #include "security/CertError.h"
26 #include "security/Session.h"
27 #include "SquidConfig.h"
28 #include "SquidTime.h"
29 #include "ssl/bio.h"
30 #include "ssl/Config.h"
31 #include "ssl/ErrorDetail.h"
32 #include "ssl/gadgets.h"
33 #include "ssl/support.h"
34 #include "URL.h"
35
36 #include <cerrno>
37
38 // TODO: Move ssl_ex_index_* global variables from global.cc here.
39 int ssl_ex_index_ssl_untrusted_chain = -1;
40
41 static Ssl::CertsIndexedList SquidUntrustedCerts;
42
43 const EVP_MD *Ssl::DefaultSignHash = NULL;
44
45 std::vector<const char *> Ssl::BumpModeStr = {
46 "none",
47 "client-first",
48 "server-first",
49 "peek",
50 "stare",
51 "bump",
52 "splice",
53 "terminate"
54 /*,"err"*/
55 };
56
57 /**
58 \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
59 \ingroup ServerProtocolSSLAPI
60 */
61
62 /// \ingroup ServerProtocolSSLInternal
63 static int
64 ssl_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'))
78 --len;
79
80 buf[len] = '\0';
81
82 pclose(in);
83
84 return len;
85 }
86
87 /// \ingroup ServerProtocolSSLInternal
88 static void
89 ssl_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
97 #if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
98 static RSA *
99 ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
100 {
101 static RSA *rsa_512 = NULL;
102 static RSA *rsa_1024 = NULL;
103 RSA *rsa = NULL;
104 int newkey = 0;
105
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:
129 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Unexpected key length " << keylen);
130 return NULL;
131 }
132
133 if (rsa == NULL) {
134 debugs(83, DBG_IMPORTANT, "ssl_temp_rsa_cb: Failed to generate key " << keylen);
135 return NULL;
136 }
137
138 if (newkey) {
139 if (Debug::Enabled(83, 5))
140 PEM_write_RSAPrivateKey(debug_log, rsa, NULL, NULL, 0, NULL, NULL);
141
142 debugs(83, DBG_IMPORTANT, "Generated ephemeral RSA key of length " << keylen);
143 }
144
145 return rsa;
146 }
147 #endif
148
149 static void
150 maybeSetupRsaCallback(Security::ContextPointer &ctx)
151 {
152 #if HAVE_LIBSSL_SSL_CTX_SET_TMP_RSA_CALLBACK
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 }
157
158 int 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) {
164 if (ASN1_TIME_print(bio, tm))
165 write = BIO_read(bio, buf, len-1);
166 BIO_free(bio);
167 }
168 buf[write]='\0';
169 return write;
170 }
171
172 int 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)) {
179
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);
191 for (int i = 0; i < numalts; ++i) {
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;
197
198 if ( (*check_func)(check_data, cn_data) == 0) {
199 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
200 return 1;
201 }
202 }
203 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
204 }
205 return 0;
206 }
207
208 static int check_domain( void *check_data, ASN1_STRING *cn_data)
209 {
210 char cn[1024];
211 const char *server = (const char *)check_data;
212
213 if (cn_data->length == 0)
214 return 1; // zero length cn, ignore
215
216 if (cn_data->length > (int)sizeof(cn) - 1)
217 return 1; //if does not fit our buffer just ignore
218
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 }
226 cn[cn_data->length] = '\0';
227 debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn);
228 return matchDomainName(server, (cn[0] == '*' ? cn + 1 : cn), mdnRejectSubsubDomains);
229 }
230
231 bool Ssl::checkX509ServerValidity(X509 *cert, const char *server)
232 {
233 return matchX509CommonNames(cert, (void *)server, check_domain);
234 }
235
236 #if !HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_CERT
237 static inline X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
238 {
239 return ctx->cert;
240 }
241 #endif
242
243 /// \ingroup ServerProtocolSSLInternal
244 static int
245 ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
246 {
247 // preserve original ctx->error before SSL_ calls can overwrite it
248 Security::ErrorCode error_no = ok ? SSL_ERROR_NONE : X509_STORE_CTX_get_error(ctx);
249
250 char buffer[256] = "";
251 SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
252 SSL_CTX *sslctx = SSL_get_SSL_CTX(ssl);
253 SBuf *server = (SBuf *)SSL_get_ex_data(ssl, ssl_ex_index_server);
254 void *dont_verify_domain = SSL_CTX_get_ex_data(sslctx, ssl_ctx_ex_index_dont_verify_domain);
255 ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
256 X509 *peeked_cert = (X509 *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_peeked_cert);
257 Security::CertPointer peer_cert;
258 peer_cert.resetAndLock(X509_STORE_CTX_get0_cert(ctx));
259
260 X509_NAME_oneline(X509_get_subject_name(peer_cert.get()), buffer, sizeof(buffer));
261
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
279 if (ok) {
280 debugs(83, 5, "SSL Certificate signature OK: " << buffer);
281
282 // Check for domain mismatch only if the current certificate is the peer certificate.
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())) {
285 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer << " does not match domainname " << server);
286 ok = 0;
287 error_no = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
288 }
289 }
290 }
291
292 if (ok && peeked_cert) {
293 // Check whether the already peeked certificate matches the new one.
294 if (X509_cmp(peer_cert.get(), peeked_cert) != 0) {
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
301 if (!ok) {
302 Security::CertPointer broken_cert;
303 broken_cert.resetAndLock(X509_STORE_CTX_get_current_cert(ctx));
304 if (!broken_cert)
305 broken_cert = peer_cert;
306
307 Security::CertErrors *errs = static_cast<Security::CertErrors *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_errors));
308 const int depth = X509_STORE_CTX_get_error_depth(ctx);
309 if (!errs) {
310 errs = new Security::CertErrors(Security::CertError(error_no, broken_cert, depth));
311 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_errors, (void *)errs)) {
312 debugs(83, 2, "Failed to set ssl error_no in ssl_verify_cb: Certificate " << buffer);
313 delete errs;
314 errs = NULL;
315 }
316 } else // remember another error number
317 errs->push_back_unique(Security::CertError(error_no, broken_cert, depth));
318
319 if (const char *err_descr = Ssl::GetErrorDescr(error_no))
320 debugs(83, 5, err_descr << ": " << buffer);
321 else
322 debugs(83, DBG_IMPORTANT, "SSL unknown certificate error " << error_no << " in " << buffer);
323
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);
330 filledCheck->sslErrors = new Security::CertErrors(Security::CertError(error_no, broken_cert));
331 filledCheck->serverCert = peer_cert;
332 if (check->fastCheck() == ACCESS_ALLOWED) {
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;
340 filledCheck->serverCert.reset();
341 }
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) {
345 ok = 1;
346 }
347 }
348 }
349
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
359 if (!ok && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) {
360
361 // Find the broken certificate. It may be intermediate.
362 Security::CertPointer broken_cert(peer_cert); // reasonable default if search fails
363 // Our SQUID_X509_V_ERR_DOMAIN_MISMATCH implies peer_cert is at fault.
364 if (error_no != SQUID_X509_V_ERR_DOMAIN_MISMATCH) {
365 if (auto *last_used_cert = X509_STORE_CTX_get_current_cert(ctx))
366 broken_cert.resetAndLock(last_used_cert);
367 }
368
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)) {
371 debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer);
372 delete errDetail;
373 }
374 }
375
376 return ok;
377 }
378
379 // "dup" function for SSL_get_ex_new_index("cert_err_check")
380 #if SQUID_USE_CONST_CRYPTO_EX_DATA_DUP
381 static int
382 ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void *,
383 int, long, void *)
384 #else
385 static int
386 ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
387 int, long, void *)
388 #endif
389 {
390 // We do not support duplication of ACLCheckLists.
391 // If duplication is needed, we can count copies with cbdata.
392 assert(false);
393 return 0;
394 }
395
396 // "free" function for SSL_get_ex_new_index("cert_err_check")
397 static void
398 ssl_freeAclChecklist(void *, void *ptr, CRYPTO_EX_DATA *,
399 int, long, void *)
400 {
401 delete static_cast<ACLChecklist *>(ptr); // may be NULL
402 }
403
404 // "free" function for SSL_get_ex_new_index("ssl_error_detail")
405 static void
406 ssl_free_ErrorDetail(void *, void *ptr, CRYPTO_EX_DATA *,
407 int, long, void *)
408 {
409 Ssl::ErrorDetail *errDetail = static_cast <Ssl::ErrorDetail *>(ptr);
410 delete errDetail;
411 }
412
413 static void
414 ssl_free_SslErrors(void *, void *ptr, CRYPTO_EX_DATA *,
415 int, long, void *)
416 {
417 Security::CertErrors *errs = static_cast <Security::CertErrors*>(ptr);
418 delete errs;
419 }
420
421 // "free" function for SSL_get_ex_new_index("ssl_ex_index_ssl_validation_counter")
422 static void
423 ssl_free_int(void *, void *ptr, CRYPTO_EX_DATA *,
424 int, long, void *)
425 {
426 uint32_t *counter = static_cast <uint32_t *>(ptr);
427 delete counter;
428 }
429
430 /// \ingroup ServerProtocolSSLInternal
431 /// Callback handler function to release STACK_OF(X509) "ex" data stored
432 /// in an SSL object.
433 static void
434 ssl_free_CertChain(void *, void *ptr, CRYPTO_EX_DATA *,
435 int, long, void *)
436 {
437 STACK_OF(X509) *certsChain = static_cast <STACK_OF(X509) *>(ptr);
438 sk_X509_pop_free(certsChain,X509_free);
439 }
440
441 // "free" function for X509 certificates
442 static void
443 ssl_free_X509(void *, void *ptr, CRYPTO_EX_DATA *,
444 int, long, void *)
445 {
446 X509 *cert = static_cast <X509 *>(ptr);
447 X509_free(cert);
448 }
449
450 // "free" function for SBuf
451 static void
452 ssl_free_SBuf(void *, void *ptr, CRYPTO_EX_DATA *,
453 int, long, void *)
454 {
455 SBuf *buf = static_cast <SBuf *>(ptr);
456 delete buf;
457 }
458
459 void
460 Ssl::Initialize(void)
461 {
462 static bool initialized = false;
463 if (initialized)
464 return;
465 initialized = true;
466
467 SSL_load_error_strings();
468 SSLeay_add_ssl_algorithms();
469
470 #if HAVE_OPENSSL_ENGINE_H
471 if (::Config.SSL.ssl_engine) {
472 ENGINE_load_builtin_engines();
473 ENGINE *e;
474 if (!(e = ENGINE_by_id(::Config.SSL.ssl_engine)))
475 fatalf("Unable to find SSL engine '%s'\n", ::Config.SSL.ssl_engine);
476
477 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
478 const int ssl_error = ERR_get_error();
479 fatalf("Failed to initialise SSL engine: %s\n", Security::ErrorString(ssl_error));
480 }
481 }
482 #else
483 if (::Config.SSL.ssl_engine)
484 fatalf("Your OpenSSL has no SSL engine support\n");
485 #endif
486
487 const char *defName = ::Config.SSL.certSignHash ? ::Config.SSL.certSignHash : SQUID_SSL_SIGN_HASH_IF_NONE;
488 Ssl::DefaultSignHash = EVP_get_digestbyname(defName);
489 if (!Ssl::DefaultSignHash)
490 fatalf("Sign hash '%s' is not supported\n", defName);
491
492 ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, ssl_free_SBuf);
493 ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
494 ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
495 ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
496 ssl_ex_index_ssl_peeked_cert = SSL_get_ex_new_index(0, (void *) "ssl_peeked_cert", NULL, NULL, &ssl_free_X509);
497 ssl_ex_index_ssl_errors = SSL_get_ex_new_index(0, (void *) "ssl_errors", NULL, NULL, &ssl_free_SslErrors);
498 ssl_ex_index_ssl_cert_chain = SSL_get_ex_new_index(0, (void *) "ssl_cert_chain", NULL, NULL, &ssl_free_CertChain);
499 ssl_ex_index_ssl_validation_counter = SSL_get_ex_new_index(0, (void *) "ssl_validation_counter", NULL, NULL, &ssl_free_int);
500 ssl_ex_index_ssl_untrusted_chain = SSL_get_ex_new_index(0, (void *) "ssl_untrusted_chain", NULL, NULL, &ssl_free_CertChain);
501 }
502
503 static bool
504 configureSslContext(Security::ContextPointer &ctx, AnyP::PortCfg &port)
505 {
506 int ssl_error;
507 SSL_CTX_set_options(ctx.get(), port.secure.parsedOptions);
508
509 if (port.sslContextSessionId)
510 SSL_CTX_set_session_id_context(ctx.get(), (const unsigned char *)port.sslContextSessionId, strlen(port.sslContextSessionId));
511
512 if (port.secure.parsedFlags & SSL_FLAG_NO_SESSION_REUSE) {
513 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_OFF);
514 }
515
516 if (Config.SSL.unclean_shutdown) {
517 debugs(83, 5, "Enabling quiet SSL shutdowns (RFC violation).");
518
519 SSL_CTX_set_quiet_shutdown(ctx.get(), 1);
520 }
521
522 if (!port.secure.sslCipher.isEmpty()) {
523 debugs(83, 5, "Using chiper suite " << port.secure.sslCipher << ".");
524
525 if (!SSL_CTX_set_cipher_list(ctx.get(), port.secure.sslCipher.c_str())) {
526 ssl_error = ERR_get_error();
527 debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << port.secure.sslCipher << "': " << Security::ErrorString(ssl_error));
528 return false;
529 }
530 }
531
532 maybeSetupRsaCallback(ctx);
533
534 port.secure.updateContextEecdh(ctx);
535 port.secure.updateContextCa(ctx);
536
537 if (port.clientCA.get()) {
538 ERR_clear_error();
539 if (STACK_OF(X509_NAME) *clientca = SSL_dup_CA_list(port.clientCA.get())) {
540 SSL_CTX_set_client_CA_list(ctx.get(), clientca);
541 } else {
542 ssl_error = ERR_get_error();
543 debugs(83, DBG_CRITICAL, "ERROR: Failed to dupe the client CA list: " << Security::ErrorString(ssl_error));
544 return false;
545 }
546
547 if (port.secure.parsedFlags & SSL_FLAG_DELAYED_AUTH) {
548 debugs(83, 9, "Not requesting client certificates until acl processing requires one");
549 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL);
550 } else {
551 debugs(83, 9, "Requiring client certificates.");
552 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
553 }
554
555 port.secure.updateContextCrl(ctx);
556
557 } else {
558 debugs(83, 9, "Not requiring any client certificates");
559 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL);
560 }
561
562 if (port.secure.parsedFlags & SSL_FLAG_DONT_VERIFY_DOMAIN)
563 SSL_CTX_set_ex_data(ctx.get(), ssl_ctx_ex_index_dont_verify_domain, (void *) -1);
564
565 Security::SetSessionCacheCallbacks(ctx);
566
567 return true;
568 }
569
570 bool
571 Ssl::InitServerContext(Security::ContextPointer &ctx, AnyP::PortCfg &port)
572 {
573 if (!ctx)
574 return false;
575
576 if (!SSL_CTX_use_certificate(ctx.get(), port.signingCert.get())) {
577 const int ssl_error = ERR_get_error();
578 const auto &keys = port.secure.certs.front();
579 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS certificate '" << keys.certFile << "': " << Security::ErrorString(ssl_error));
580 return false;
581 }
582
583 if (!SSL_CTX_use_PrivateKey(ctx.get(), port.signPkey.get())) {
584 const int ssl_error = ERR_get_error();
585 const auto &keys = port.secure.certs.front();
586 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS private key '" << keys.privateKeyFile << "': " << Security::ErrorString(ssl_error));
587 return false;
588 }
589
590 Ssl::addChainToSslContext(ctx, port.certsToChain.get());
591
592 /* Alternate code;
593 debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
594
595 if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) {
596 ssl_error = ERR_get_error();
597 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << certfile << "': " << Security::ErrorString(ssl_error));
598 return false;
599 }
600
601 debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
602 ssl_ask_password(ctx.get(), keyfile);
603
604 if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) {
605 ssl_error = ERR_get_error();
606 debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << keyfile << "': " << Security::ErrorString(ssl_error));
607 return false;
608 }
609
610 debugs(83, 5, "Comparing private and public SSL keys.");
611
612 if (!SSL_CTX_check_private_key(ctx.get())) {
613 ssl_error = ERR_get_error();
614 debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' does not match public key '" <<
615 keyfile << "': " << Security::ErrorString(ssl_error));
616 return false;
617 }
618 */
619
620 if (!configureSslContext(ctx, port)) {
621 debugs(83, DBG_CRITICAL, "ERROR: Configuring static SSL context");
622 return false;
623 }
624
625 return true;
626 }
627
628 bool
629 Ssl::InitClientContext(Security::ContextPointer &ctx, Security::PeerOptions &peer, long fl)
630 {
631 if (!ctx)
632 return false;
633
634 if (!peer.sslCipher.isEmpty()) {
635 debugs(83, 5, "Using chiper suite " << peer.sslCipher << ".");
636
637 const char *cipher = peer.sslCipher.c_str();
638 if (!SSL_CTX_set_cipher_list(ctx.get(), cipher)) {
639 const int ssl_error = ERR_get_error();
640 fatalf("Failed to set SSL cipher suite '%s': %s\n",
641 cipher, Security::ErrorString(ssl_error));
642 }
643 }
644
645 if (!peer.certs.empty()) {
646 // TODO: support loading multiple cert/key pairs
647 auto &keys = peer.certs.front();
648 if (!keys.certFile.isEmpty()) {
649 debugs(83, DBG_IMPORTANT, "Using certificate in " << keys.certFile);
650
651 const char *certfile = keys.certFile.c_str();
652 if (!SSL_CTX_use_certificate_chain_file(ctx.get(), certfile)) {
653 const int ssl_error = ERR_get_error();
654 fatalf("Failed to acquire SSL certificate '%s': %s\n",
655 certfile, Security::ErrorString(ssl_error));
656 }
657
658 debugs(83, DBG_IMPORTANT, "Using private key in " << keys.privateKeyFile);
659 const char *keyfile = keys.privateKeyFile.c_str();
660 ssl_ask_password(ctx.get(), keyfile);
661
662 if (!SSL_CTX_use_PrivateKey_file(ctx.get(), keyfile, SSL_FILETYPE_PEM)) {
663 const int ssl_error = ERR_get_error();
664 fatalf("Failed to acquire SSL private key '%s': %s\n",
665 keyfile, Security::ErrorString(ssl_error));
666 }
667
668 debugs(83, 5, "Comparing private and public SSL keys.");
669
670 if (!SSL_CTX_check_private_key(ctx.get())) {
671 const int ssl_error = ERR_get_error();
672 fatalf("SSL private key '%s' does not match public key '%s': %s\n",
673 certfile, keyfile, Security::ErrorString(ssl_error));
674 }
675 }
676 }
677
678 maybeSetupRsaCallback(ctx);
679
680 if (fl & SSL_FLAG_DONT_VERIFY_PEER) {
681 debugs(83, 2, "NOTICE: Peer certificates are not verified for validity!");
682 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_NONE, NULL);
683 } else {
684 debugs(83, 9, "Setting certificate verification callback.");
685 SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
686 }
687
688 return true;
689 }
690
691 /// \ingroup ServerProtocolSSLInternal
692 static const char *
693 ssl_get_attribute(X509_NAME * name, const char *attribute_name)
694 {
695 static char buffer[1024];
696 buffer[0] = '\0';
697
698 if (strcmp(attribute_name, "DN") == 0) {
699 X509_NAME_oneline(name, buffer, sizeof(buffer));
700 } else {
701 int nid = OBJ_txt2nid(const_cast<char *>(attribute_name));
702 if (nid == 0) {
703 debugs(83, DBG_IMPORTANT, "WARNING: Unknown SSL attribute name '" << attribute_name << "'");
704 return nullptr;
705 }
706 X509_NAME_get_text_by_NID(name, nid, buffer, sizeof(buffer));
707 }
708
709 return *buffer ? buffer : nullptr;
710 }
711
712 /// \ingroup ServerProtocolSSLInternal
713 const char *
714 Ssl::GetX509UserAttribute(X509 * cert, const char *attribute_name)
715 {
716 X509_NAME *name;
717 const char *ret;
718
719 if (!cert)
720 return NULL;
721
722 name = X509_get_subject_name(cert);
723
724 ret = ssl_get_attribute(name, attribute_name);
725
726 return ret;
727 }
728
729 const char *
730 Ssl::GetX509Fingerprint(X509 * cert, const char *)
731 {
732 static char buf[1024];
733 if (!cert)
734 return NULL;
735
736 unsigned int n;
737 unsigned char md[EVP_MAX_MD_SIZE];
738 if (!X509_digest(cert, EVP_sha1(), md, &n))
739 return NULL;
740
741 assert(3 * n + 1 < sizeof(buf));
742
743 char *s = buf;
744 for (unsigned int i=0; i < n; ++i, s += 3) {
745 const char term = (i + 1 < n) ? ':' : '\0';
746 snprintf(s, 4, "%02X%c", md[i], term);
747 }
748
749 return buf;
750 }
751
752 /// \ingroup ServerProtocolSSLInternal
753 const char *
754 Ssl::GetX509CAAttribute(X509 * cert, const char *attribute_name)
755 {
756
757 X509_NAME *name;
758 const char *ret;
759
760 if (!cert)
761 return NULL;
762
763 name = X509_get_issuer_name(cert);
764
765 ret = ssl_get_attribute(name, attribute_name);
766
767 return ret;
768 }
769
770 const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name)
771 {
772 if (!ssl)
773 return NULL;
774
775 X509 *cert = SSL_get_peer_certificate(ssl);
776
777 const char *attr = Ssl::GetX509UserAttribute(cert, attribute_name);
778
779 X509_free(cert);
780 return attr;
781 }
782
783 const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name)
784 {
785 if (!ssl)
786 return NULL;
787
788 X509 *cert = SSL_get_peer_certificate(ssl);
789
790 const char *attr = Ssl::GetX509CAAttribute(cert, attribute_name);
791
792 X509_free(cert);
793 return attr;
794 }
795
796 const char *
797 sslGetUserEmail(SSL * ssl)
798 {
799 return sslGetUserAttribute(ssl, "emailAddress");
800 }
801
802 const char *
803 sslGetUserCertificatePEM(SSL *ssl)
804 {
805 X509 *cert;
806 BIO *mem;
807 static char *str = NULL;
808 char *ptr;
809 long len;
810
811 safe_free(str);
812
813 if (!ssl)
814 return NULL;
815
816 cert = SSL_get_peer_certificate(ssl);
817
818 if (!cert)
819 return NULL;
820
821 mem = BIO_new(BIO_s_mem());
822
823 PEM_write_bio_X509(mem, cert);
824
825 len = BIO_get_mem_data(mem, &ptr);
826
827 str = (char *)xmalloc(len + 1);
828
829 memcpy(str, ptr, len);
830
831 str[len] = '\0';
832
833 X509_free(cert);
834
835 BIO_free(mem);
836
837 return str;
838 }
839
840 const char *
841 sslGetUserCertificateChainPEM(SSL *ssl)
842 {
843 STACK_OF(X509) *chain;
844 BIO *mem;
845 static char *str = NULL;
846 char *ptr;
847 long len;
848 int i;
849
850 safe_free(str);
851
852 if (!ssl)
853 return NULL;
854
855 chain = SSL_get_peer_cert_chain(ssl);
856
857 if (!chain)
858 return sslGetUserCertificatePEM(ssl);
859
860 mem = BIO_new(BIO_s_mem());
861
862 for (i = 0; i < sk_X509_num(chain); ++i) {
863 X509 *cert = sk_X509_value(chain, i);
864 PEM_write_bio_X509(mem, cert);
865 }
866
867 len = BIO_get_mem_data(mem, &ptr);
868
869 str = (char *)xmalloc(len + 1);
870 memcpy(str, ptr, len);
871 str[len] = '\0';
872
873 BIO_free(mem);
874
875 return str;
876 }
877
878 /// Create SSL context and apply ssl certificate and private key to it.
879 Security::ContextPointer
880 Ssl::createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port)
881 {
882 Security::ContextPointer ctx(port.secure.createBlankContext());
883
884 if (!SSL_CTX_use_certificate(ctx.get(), x509.get()))
885 return Security::ContextPointer();
886
887 if (!SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()))
888 return Security::ContextPointer();
889
890 if (!configureSslContext(ctx, port))
891 return Security::ContextPointer();
892
893 return ctx;
894 }
895
896 Security::ContextPointer
897 Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port)
898 {
899 Security::CertPointer cert;
900 Ssl::EVP_PKEY_Pointer pkey;
901 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data) || !cert || !pkey)
902 return Security::ContextPointer();
903
904 return createSSLContext(cert, pkey, port);
905 }
906
907 Security::ContextPointer
908 Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port)
909 {
910 Security::CertPointer cert;
911 Ssl::EVP_PKEY_Pointer pkey;
912 if (!generateSslCertificate(cert, pkey, properties) || !cert || !pkey)
913 return Security::ContextPointer();
914
915 return createSSLContext(cert, pkey, port);
916 }
917
918 void
919 Ssl::chainCertificatesToSSLContext(Security::ContextPointer &ctx, AnyP::PortCfg &port)
920 {
921 assert(ctx);
922 // Add signing certificate to the certificates chain
923 X509 *signingCert = port.signingCert.get();
924 if (SSL_CTX_add_extra_chain_cert(ctx.get(), signingCert)) {
925 // increase the certificate lock
926 X509_up_ref(signingCert);
927 } else {
928 const int ssl_error = ERR_get_error();
929 debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << Security::ErrorString(ssl_error));
930 }
931 Ssl::addChainToSslContext(ctx, port.certsToChain.get());
932 }
933
934 void
935 Ssl::configureUnconfiguredSslContext(Security::ContextPointer &ctx, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port)
936 {
937 if (ctx && signAlgorithm == Ssl::algSignTrusted)
938 Ssl::chainCertificatesToSSLContext(ctx, port);
939 }
940
941 bool
942 Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port)
943 {
944 Security::CertPointer cert;
945 Ssl::EVP_PKEY_Pointer pkey;
946 if (!generateSslCertificate(cert, pkey, properties))
947 return false;
948
949 if (!cert)
950 return false;
951
952 if (!pkey)
953 return false;
954
955 if (!SSL_use_certificate(ssl, cert.get()))
956 return false;
957
958 if (!SSL_use_PrivateKey(ssl, pkey.get()))
959 return false;
960
961 return true;
962 }
963
964 bool
965 Ssl::configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port)
966 {
967 Security::CertPointer cert;
968 Ssl::EVP_PKEY_Pointer pkey;
969 if (!readCertAndPrivateKeyFromMemory(cert, pkey, data))
970 return false;
971
972 if (!cert || !pkey)
973 return false;
974
975 if (!SSL_use_certificate(ssl, cert.get()))
976 return false;
977
978 if (!SSL_use_PrivateKey(ssl, pkey.get()))
979 return false;
980
981 return true;
982 }
983
984 bool
985 Ssl::verifySslCertificate(Security::ContextPointer &ctx, CertificateProperties const &properties)
986 {
987 #if HAVE_SSL_CTX_GET0_CERTIFICATE
988 X509 * cert = SSL_CTX_get0_certificate(ctx.get());
989 #elif SQUID_USE_SSLGETCERTIFICATE_HACK
990 // SSL_get_certificate is buggy in openssl versions 1.0.1d and 1.0.1e
991 // Try to retrieve certificate directly from Security::ContextPointer object
992 X509 ***pCert = (X509 ***)ctx->cert;
993 X509 * cert = pCert && *pCert ? **pCert : NULL;
994 #elif SQUID_SSLGETCERTIFICATE_BUGGY
995 X509 * cert = NULL;
996 assert(0);
997 #else
998 // Temporary ssl for getting X509 certificate from SSL_CTX.
999 Security::SessionPointer ssl(Security::NewSessionObject(ctx));
1000 X509 * cert = SSL_get_certificate(ssl.get());
1001 #endif
1002 if (!cert)
1003 return false;
1004 ASN1_TIME * time_notBefore = X509_get_notBefore(cert);
1005 ASN1_TIME * time_notAfter = X509_get_notAfter(cert);
1006 bool ret = (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
1007 if (!ret)
1008 return false;
1009
1010 return certificateMatchesProperties(cert, properties);
1011 }
1012
1013 bool
1014 Ssl::setClientSNI(SSL *ssl, const char *fqdn)
1015 {
1016 //The SSL_CTRL_SET_TLSEXT_HOSTNAME is a openssl macro which indicates
1017 // if the TLS servername extension (SNI) is enabled in openssl library.
1018 #if defined(SSL_CTRL_SET_TLSEXT_HOSTNAME)
1019 if (!SSL_set_tlsext_host_name(ssl, fqdn)) {
1020 const int ssl_error = ERR_get_error();
1021 debugs(83, 3, "WARNING: unable to set TLS servername extension (SNI): " <<
1022 Security::ErrorString(ssl_error) << "\n");
1023 return false;
1024 }
1025 return true;
1026 #else
1027 debugs(83, 7, "no support for TLS servername extension (SNI)\n");
1028 return false;
1029 #endif
1030 }
1031
1032 void
1033 Ssl::addChainToSslContext(Security::ContextPointer &ctx, STACK_OF(X509) *chain)
1034 {
1035 if (!chain)
1036 return;
1037
1038 for (int i = 0; i < sk_X509_num(chain); ++i) {
1039 X509 *cert = sk_X509_value(chain, i);
1040 if (SSL_CTX_add_extra_chain_cert(ctx.get(), cert)) {
1041 // increase the certificate lock
1042 X509_up_ref(cert);
1043 } else {
1044 const int ssl_error = ERR_get_error();
1045 debugs(83, DBG_IMPORTANT, "WARNING: can not add certificate to SSL context chain: " << Security::ErrorString(ssl_error));
1046 }
1047 }
1048 }
1049
1050 static const char *
1051 hasAuthorityInfoAccessCaIssuers(X509 *cert)
1052 {
1053 AUTHORITY_INFO_ACCESS *info;
1054 if (!cert)
1055 return nullptr;
1056 info = static_cast<AUTHORITY_INFO_ACCESS *>(X509_get_ext_d2i(cert, NID_info_access, NULL, NULL));
1057 if (!info)
1058 return nullptr;
1059
1060 static char uri[MAX_URL];
1061 uri[0] = '\0';
1062
1063 for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
1064 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
1065 if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers) {
1066 if (ad->location->type == GEN_URI) {
1067 xstrncpy(uri,
1068 reinterpret_cast<const char *>(
1069 #if HAVE_LIBCRYPTO_ASN1_STRING_GET0_DATA
1070 ASN1_STRING_get0_data(ad->location->d.uniformResourceIdentifier)
1071 #else
1072 ASN1_STRING_data(ad->location->d.uniformResourceIdentifier)
1073 #endif
1074 ),
1075 sizeof(uri));
1076 }
1077 break;
1078 }
1079 }
1080 AUTHORITY_INFO_ACCESS_free(info);
1081 return uri[0] != '\0' ? uri : nullptr;
1082 }
1083
1084 bool
1085 Ssl::loadCerts(const char *certsFile, Ssl::CertsIndexedList &list)
1086 {
1087 BIO *in = BIO_new_file(certsFile, "r");
1088 if (!in) {
1089 debugs(83, DBG_IMPORTANT, "Failed to open '" << certsFile << "' to load certificates");
1090 return false;
1091 }
1092
1093 X509 *aCert;
1094 while((aCert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1095 static char buffer[2048];
1096 X509_NAME_oneline(X509_get_subject_name(aCert), buffer, sizeof(buffer));
1097 list.insert(std::pair<SBuf, X509 *>(SBuf(buffer), aCert));
1098 }
1099 debugs(83, 4, "Loaded " << list.size() << " certificates from file: '" << certsFile << "'");
1100 BIO_free(in);
1101 return true;
1102 }
1103
1104 /// quickly find the issuer certificate of a certificate cert in the
1105 /// Ssl::CertsIndexedList list
1106 static X509 *
1107 findCertIssuerFast(Ssl::CertsIndexedList &list, X509 *cert)
1108 {
1109 static char buffer[2048];
1110
1111 if (X509_NAME *issuerName = X509_get_issuer_name(cert))
1112 X509_NAME_oneline(issuerName, buffer, sizeof(buffer));
1113 else
1114 return NULL;
1115
1116 const auto ret = list.equal_range(SBuf(buffer));
1117 for (Ssl::CertsIndexedList::iterator it = ret.first; it != ret.second; ++it) {
1118 X509 *issuer = it->second;
1119 if (X509_check_issued(issuer, cert) == X509_V_OK) {
1120 return issuer;
1121 }
1122 }
1123 return NULL;
1124 }
1125
1126 /// slowly find the issuer certificate of a given cert using linear search
1127 static bool
1128 findCertIssuer(Security::CertList const &list, X509 *cert)
1129 {
1130 for (Security::CertList::const_iterator it = list.begin(); it != list.end(); ++it) {
1131 if (X509_check_issued(it->get(), cert) == X509_V_OK)
1132 return true;
1133 }
1134 return false;
1135 }
1136
1137 const char *
1138 Ssl::uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates)
1139 {
1140 if (!cert || !serverCertificates.size())
1141 return nullptr;
1142
1143 if (!findCertIssuer(serverCertificates, cert)) {
1144 //if issuer is missing
1145 if (!findCertIssuerFast(SquidUntrustedCerts, cert)) {
1146 // and issuer not found in local untrusted certificates database
1147 if (const char *issuerUri = hasAuthorityInfoAccessCaIssuers(cert)) {
1148 // There is a URI where we can download a certificate.
1149 return issuerUri;
1150 }
1151 }
1152 }
1153 return nullptr;
1154 }
1155
1156 void
1157 Ssl::missingChainCertificatesUrls(std::queue<SBuf> &URIs, Security::CertList const &serverCertificates)
1158 {
1159 if (!serverCertificates.size())
1160 return;
1161
1162 for (const auto &i : serverCertificates) {
1163 if (const char *issuerUri = uriOfIssuerIfMissing(i.get(), serverCertificates))
1164 URIs.push(SBuf(issuerUri));
1165 }
1166 }
1167
1168 void
1169 Ssl::SSL_add_untrusted_cert(SSL *ssl, X509 *cert)
1170 {
1171 STACK_OF(X509) *untrustedStack = static_cast <STACK_OF(X509) *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain));
1172 if (!untrustedStack) {
1173 untrustedStack = sk_X509_new_null();
1174 if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain, untrustedStack)) {
1175 sk_X509_pop_free(untrustedStack, X509_free);
1176 throw TextException("Failed to attach untrusted certificates chain");
1177 }
1178 }
1179 sk_X509_push(untrustedStack, cert);
1180 }
1181
1182 /// Search for the issuer certificate of cert in sk list.
1183 static X509 *
1184 sk_x509_findIssuer(STACK_OF(X509) *sk, X509 *cert)
1185 {
1186 if (!sk)
1187 return NULL;
1188
1189 const int skItemsNum = sk_X509_num(sk);
1190 for (int i = 0; i < skItemsNum; ++i) {
1191 X509 *issuer = sk_X509_value(sk, i);
1192 if (X509_check_issued(issuer, cert) == X509_V_OK)
1193 return issuer;
1194 }
1195 return NULL;
1196 }
1197
1198 /// add missing issuer certificates to untrustedCerts
1199 static void
1200 completeIssuers(X509_STORE_CTX *ctx, STACK_OF(X509) *untrustedCerts)
1201 {
1202 debugs(83, 2, "completing " << sk_X509_num(untrustedCerts) << " OpenSSL untrusted certs using " << SquidUntrustedCerts.size() << " configured untrusted certificates");
1203
1204 #if HAVE_LIBCRYPTO_X509_VERIFY_PARAM_GET_DEPTH
1205 const X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
1206 int depth = X509_VERIFY_PARAM_get_depth(param);
1207 #else
1208 int depth = ctx->param->depth;
1209 #endif
1210 X509 *current = X509_STORE_CTX_get0_cert(ctx);
1211 int i = 0;
1212 for (i = 0; current && (i < depth); ++i) {
1213 if (X509_check_issued(current, current) == X509_V_OK) {
1214 // either ctx->cert is itself self-signed or untrustedCerts
1215 // aready contain the self-signed current certificate
1216 break;
1217 }
1218
1219 // untrustedCerts is short, not worth indexing
1220 X509 *issuer = sk_x509_findIssuer(untrustedCerts, current);
1221 if (!issuer) {
1222 if ((issuer = findCertIssuerFast(SquidUntrustedCerts, current)))
1223 sk_X509_push(untrustedCerts, issuer);
1224 }
1225 current = issuer;
1226 }
1227
1228 if (i >= depth)
1229 debugs(83, 2, "exceeded the maximum certificate chain length: " << depth);
1230 }
1231
1232 /// OpenSSL certificate validation callback.
1233 static int
1234 untrustedToStoreCtx_cb(X509_STORE_CTX *ctx,void *data)
1235 {
1236 debugs(83, 4, "Try to use pre-downloaded intermediate certificates\n");
1237
1238 SSL *ssl = static_cast<SSL *>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
1239 STACK_OF(X509) *sslUntrustedStack = static_cast <STACK_OF(X509) *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain));
1240
1241 // OpenSSL already maintains ctx->untrusted but we cannot modify
1242 // internal OpenSSL list directly. We have to give OpenSSL our own
1243 // list, but it must include certificates on the OpenSSL ctx->untrusted
1244 #if HAVE_LIBCRYPTO_X509_STORE_CTX_GET0_UNTRUSTED
1245 STACK_OF(X509) *oldUntrusted = X509_STORE_CTX_get0_untrusted(ctx);
1246 #else
1247 STACK_OF(X509) *oldUntrusted = ctx->untrusted;
1248 #endif
1249 STACK_OF(X509) *sk = sk_X509_dup(oldUntrusted); // oldUntrusted is always not NULL
1250
1251 for (int i = 0; i < sk_X509_num(sslUntrustedStack); ++i) {
1252 X509 *cert = sk_X509_value(sslUntrustedStack, i);
1253 sk_X509_push(sk, cert);
1254 }
1255
1256 // If the local untrusted certificates internal database is used
1257 // run completeIssuers to add missing certificates if possible.
1258 if (SquidUntrustedCerts.size() > 0)
1259 completeIssuers(ctx, sk);
1260
1261 X509_STORE_CTX_set_chain(ctx, sk); // No locking/unlocking, just sets ctx->untrusted
1262 int ret = X509_verify_cert(ctx);
1263 #if HAVE_LIBCRYPTO_X509_STORE_CTX_SET0_UNTRUSTED
1264 X509_STORE_CTX_set0_untrusted(ctx, oldUntrusted);
1265 #else
1266 X509_STORE_CTX_set_chain(ctx, oldUntrusted); // Set back the old untrusted list
1267 #endif
1268 sk_X509_free(sk); // Release sk list
1269 return ret;
1270 }
1271
1272 void
1273 Ssl::useSquidUntrusted(SSL_CTX *sslContext)
1274 {
1275 SSL_CTX_set_cert_verify_callback(sslContext, untrustedToStoreCtx_cb, NULL);
1276 }
1277
1278 bool
1279 Ssl::loadSquidUntrusted(const char *path)
1280 {
1281 return Ssl::loadCerts(path, SquidUntrustedCerts);
1282 }
1283
1284 void
1285 Ssl::unloadSquidUntrusted()
1286 {
1287 if (SquidUntrustedCerts.size()) {
1288 for (Ssl::CertsIndexedList::iterator it = SquidUntrustedCerts.begin(); it != SquidUntrustedCerts.end(); ++it) {
1289 X509_free(it->second);
1290 }
1291 SquidUntrustedCerts.clear();
1292 }
1293 }
1294
1295 /**
1296 \ingroup ServerProtocolSSLInternal
1297 * Read certificate from file.
1298 * See also: static readSslX509Certificate function, gadgets.cc file
1299 */
1300 static X509 * readSslX509CertificatesChain(char const * certFilename, STACK_OF(X509)* chain)
1301 {
1302 if (!certFilename)
1303 return NULL;
1304 Ssl::BIO_Pointer bio(BIO_new(BIO_s_file()));
1305 if (!bio)
1306 return NULL;
1307 if (!BIO_read_filename(bio.get(), certFilename))
1308 return NULL;
1309 X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL);
1310
1311 if (certificate && chain) {
1312
1313 if (X509_check_issued(certificate, certificate) == X509_V_OK)
1314 debugs(83, 5, "Certificate is self-signed, will not be chained");
1315 else {
1316 // and add to the chain any other certificate exist in the file
1317 while (X509 *ca = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)) {
1318 if (!sk_X509_push(chain, ca))
1319 debugs(83, DBG_IMPORTANT, "WARNING: unable to add CA certificate to cert chain");
1320 }
1321 }
1322 }
1323
1324 return certificate;
1325 }
1326
1327 void Ssl::readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename)
1328 {
1329 if (keyFilename == NULL)
1330 keyFilename = certFilename;
1331
1332 if (certFilename == NULL)
1333 certFilename = keyFilename;
1334
1335 debugs(83, DBG_IMPORTANT, "Using certificate in " << certFilename);
1336
1337 if (!chain)
1338 chain.reset(sk_X509_new_null());
1339 if (!chain)
1340 debugs(83, DBG_IMPORTANT, "WARNING: unable to allocate memory for cert chain");
1341 // XXX: ssl_ask_password_cb needs SSL_CTX_set_default_passwd_cb_userdata()
1342 // so this may not fully work iff Config.Program.ssl_password is set.
1343 pem_password_cb *cb = ::Config.Program.ssl_password ? &ssl_ask_password_cb : NULL;
1344 pkey.resetWithoutLocking(readSslPrivateKey(keyFilename, cb));
1345 cert.resetWithoutLocking(readSslX509CertificatesChain(certFilename, chain.get()));
1346 if (!cert) {
1347 debugs(83, DBG_IMPORTANT, "WARNING: missing cert in '" << certFilename << "'");
1348 } else if (!pkey) {
1349 debugs(83, DBG_IMPORTANT, "WARNING: missing private key in '" << keyFilename << "'");
1350 } else if (!X509_check_private_key(cert.get(), pkey.get())) {
1351 debugs(83, DBG_IMPORTANT, "WARNING: X509_check_private_key() failed to verify signing cert");
1352 } else
1353 return; // everything is okay
1354
1355 pkey.reset();
1356 cert.reset();
1357 }
1358
1359 bool Ssl::generateUntrustedCert(Security::CertPointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, Security::CertPointer const &cert, EVP_PKEY_Pointer const & pkey)
1360 {
1361 // Generate the self-signed certificate, using a hard-coded subject prefix
1362 Ssl::CertificateProperties certProperties;
1363 if (const char *cn = CommonHostName(cert.get())) {
1364 certProperties.commonName = "Not trusted by \"";
1365 certProperties.commonName += cn;
1366 certProperties.commonName += "\"";
1367 } else if (const char *org = getOrganization(cert.get())) {
1368 certProperties.commonName = "Not trusted by \"";
1369 certProperties.commonName += org;
1370 certProperties.commonName += "\"";
1371 } else
1372 certProperties.commonName = "Not trusted";
1373 certProperties.setCommonName = true;
1374 // O, OU, and other CA subject fields will be mimicked
1375 // Expiration date and other common properties will be mimicked
1376 certProperties.signAlgorithm = Ssl::algSignSelf;
1377 certProperties.signWithPkey.resetAndLock(pkey.get());
1378 certProperties.mimicCert.resetAndLock(cert.get());
1379 return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties);
1380 }
1381
1382 #endif /* USE_OPENSSL */
1383