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