]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/gadgets.cc
SourceFormat Enforcement (#68)
[thirdparty/squid.git] / src / ssl / gadgets.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 #include "squid.h"
10 #include "ssl/gadgets.h"
11
12 #include <openssl/asn1.h>
13 #if HAVE_OPENSSL_X509V3_H
14 #include <openssl/x509v3.h>
15 #endif
16
17 EVP_PKEY * Ssl::createSslPrivateKey()
18 {
19 Ssl::EVP_PKEY_Pointer pkey(EVP_PKEY_new());
20
21 if (!pkey)
22 return NULL;
23
24 BIGNUM_Pointer bn(BN_new());
25 if (!bn)
26 return NULL;
27
28 if (!BN_set_word(bn.get(), RSA_F4))
29 return NULL;
30
31 Ssl::RSA_Pointer rsa(RSA_new());
32 if (!rsa)
33 return NULL;
34
35 int num = 2048; // Maybe use 4096 RSA keys, or better make it configurable?
36 if (!RSA_generate_key_ex(rsa.get(), num, bn.get(), NULL))
37 return NULL;
38
39 if (!rsa)
40 return NULL;
41
42 if (!EVP_PKEY_assign_RSA(pkey.get(), (rsa.get())))
43 return NULL;
44
45 rsa.release();
46 return pkey.release();
47 }
48
49 /**
50 \ingroup ServerProtocolSSLInternal
51 * Set serial random serial number or set random serial number.
52 */
53 static bool setSerialNumber(ASN1_INTEGER *ai, BIGNUM const* serial)
54 {
55 if (!ai)
56 return false;
57 Ssl::BIGNUM_Pointer bn(BN_new());
58 if (serial) {
59 bn.reset(BN_dup(serial));
60 } else {
61 if (!bn)
62 return false;
63
64 if (!BN_pseudo_rand(bn.get(), 64, 0, 0))
65 return false;
66 }
67
68 if (ai && !BN_to_ASN1_INTEGER(bn.get(), ai))
69 return false;
70 return true;
71 }
72
73 bool Ssl::writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite)
74 {
75 bufferToWrite.clear();
76 if (!pkey || !cert)
77 return false;
78 BIO_Pointer bio(BIO_new(BIO_s_mem()));
79 if (!bio)
80 return false;
81
82 if (!PEM_write_bio_X509 (bio.get(), cert.get()))
83 return false;
84
85 if (!PEM_write_bio_PrivateKey(bio.get(), pkey.get(), NULL, NULL, 0, NULL, NULL))
86 return false;
87
88 char *ptr = NULL;
89 long len = BIO_get_mem_data(bio.get(), &ptr);
90 if (!ptr)
91 return false;
92
93 bufferToWrite = std::string(ptr, len);
94 return true;
95 }
96
97 bool Ssl::appendCertToMemory(Security::CertPointer const & cert, std::string & bufferToWrite)
98 {
99 if (!cert)
100 return false;
101
102 BIO_Pointer bio(BIO_new(BIO_s_mem()));
103 if (!bio)
104 return false;
105
106 if (!PEM_write_bio_X509 (bio.get(), cert.get()))
107 return false;
108
109 char *ptr = NULL;
110 long len = BIO_get_mem_data(bio.get(), &ptr);
111 if (!ptr)
112 return false;
113
114 if (!bufferToWrite.empty())
115 bufferToWrite.append(" "); // add a space...
116
117 bufferToWrite.append(ptr, len);
118 return true;
119 }
120
121 bool Ssl::readCertAndPrivateKeyFromMemory(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, char const * bufferToRead)
122 {
123 Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem()));
124 BIO_puts(bio.get(), bufferToRead);
125
126 X509 * certPtr = NULL;
127 cert.resetWithoutLocking(PEM_read_bio_X509(bio.get(), &certPtr, 0, 0));
128 if (!cert)
129 return false;
130
131 EVP_PKEY * pkeyPtr = NULL;
132 pkey.resetWithoutLocking(PEM_read_bio_PrivateKey(bio.get(), &pkeyPtr, 0, 0));
133 if (!pkey)
134 return false;
135
136 return true;
137 }
138
139 bool Ssl::readCertFromMemory(Security::CertPointer & cert, char const * bufferToRead)
140 {
141 Ssl::BIO_Pointer bio(BIO_new(BIO_s_mem()));
142 BIO_puts(bio.get(), bufferToRead);
143
144 X509 * certPtr = NULL;
145 cert.resetWithoutLocking(PEM_read_bio_X509(bio.get(), &certPtr, 0, 0));
146 if (!cert)
147 return false;
148
149 return true;
150 }
151
152 // According to RFC 5280 (Section A.1), the common name length in a certificate
153 // can be at most 64 characters
154 static const size_t MaxCnLen = 64;
155
156 // Replace certs common name with the given
157 static bool replaceCommonName(Security::CertPointer & cert, std::string const &rawCn)
158 {
159 std::string cn = rawCn;
160
161 if (cn.length() > MaxCnLen) {
162 // In the case the length od CN is more than the maximum supported size
163 // try to use the first upper level domain.
164 size_t pos = 0;
165 do {
166 pos = cn.find('.', pos + 1);
167 } while (pos != std::string::npos && (cn.length() - pos + 2) > MaxCnLen);
168
169 // If no short domain found or this domain is a toplevel domain
170 // we failed to find a good cn name.
171 if (pos == std::string::npos || cn.find('.', pos + 1) == std::string::npos)
172 return false;
173
174 std::string fixedCn(1, '*');
175 fixedCn.append(cn.c_str() + pos);
176 cn = fixedCn;
177 }
178
179 // Assume [] surround an IPv6 address and strip them because browsers such
180 // as Firefox, Chromium, and Safari prefer bare IPv6 addresses in CNs.
181 if (cn.length() > 2 && *cn.begin() == '[' && *cn.rbegin() == ']')
182 cn = cn.substr(1, cn.size()-2);
183
184 X509_NAME *name = X509_get_subject_name(cert.get());
185 if (!name)
186 return false;
187 // Remove the CN part:
188 int loc = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
189 if (loc >=0) {
190 X509_NAME_ENTRY *tmp = X509_NAME_get_entry(name, loc);
191 X509_NAME_delete_entry(name, loc);
192 X509_NAME_ENTRY_free(tmp);
193 }
194
195 // Add a new CN
196 return X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC,
197 (unsigned char *)(cn.c_str()), -1, -1, 0);
198 }
199
200 const char *Ssl::CertSignAlgorithmStr[] = {
201 "signTrusted",
202 "signUntrusted",
203 "signSelf",
204 NULL
205 };
206
207 const char *Ssl::CertAdaptAlgorithmStr[] = {
208 "setValidAfter",
209 "setValidBefore",
210 "setCommonName",
211 NULL
212 };
213
214 Ssl::CertificateProperties::CertificateProperties():
215 setValidAfter(false),
216 setValidBefore(false),
217 setCommonName(false),
218 signAlgorithm(Ssl::algSignEnd),
219 signHash(NULL)
220 {}
221
222 static void
223 printX509Signature(const Security::CertPointer &cert, std::string &out)
224 {
225 const ASN1_BIT_STRING *sig = Ssl::X509_get_signature(cert);
226 if (sig && sig->data) {
227 const unsigned char *s = sig->data;
228 for (int i = 0; i < sig->length; ++i) {
229 char hex[3];
230 snprintf(hex, sizeof(hex), "%02x", s[i]);
231 out.append(hex);
232 }
233 }
234 }
235
236 std::string &
237 Ssl::OnDiskCertificateDbKey(const Ssl::CertificateProperties &properties)
238 {
239 static std::string certKey;
240 certKey.clear();
241 certKey.reserve(4096);
242 if (properties.mimicCert.get())
243 printX509Signature(properties.mimicCert, certKey);
244
245 if (certKey.empty()) {
246 certKey.append("/CN=", 4);
247 certKey.append(properties.commonName);
248 }
249
250 if (properties.setValidAfter)
251 certKey.append("+SetValidAfter=on", 17);
252
253 if (properties.setValidBefore)
254 certKey.append("+SetValidBefore=on", 18);
255
256 if (properties.setCommonName) {
257 certKey.append("+SetCommonName=", 15);
258 certKey.append(properties.commonName);
259 }
260
261 if (properties.signAlgorithm != Ssl::algSignEnd) {
262 certKey.append("+Sign=", 6);
263 certKey.append(certSignAlgorithm(properties.signAlgorithm));
264 }
265
266 if (properties.signHash != NULL) {
267 certKey.append("+SignHash=", 10);
268 certKey.append(EVP_MD_name(properties.signHash));
269 }
270
271 return certKey;
272 }
273
274 /// Check if mimicCert certificate has the Authority Key Identifier extension
275 /// and if yes add the extension to cert certificate with the same fields if
276 /// possible. If the issuerCert certificate does not have the Subject Key
277 /// Identifier extension (required to build the keyIdentifier field of
278 /// AuthorityKeyIdentifier) then the authorityCertIssuer and
279 /// authorityCertSerialNumber fields added.
280 static bool
281 mimicAuthorityKeyId(Security::CertPointer &cert, Security::CertPointer const &mimicCert, Security::CertPointer const &issuerCert)
282 {
283 if (!mimicCert.get() || !issuerCert.get())
284 return false;
285
286 Ssl::AUTHORITY_KEYID_Pointer akid((AUTHORITY_KEYID *)X509_get_ext_d2i(mimicCert.get(), NID_authority_key_identifier, nullptr, nullptr));
287
288 bool addKeyId = false, addIssuer = false;
289 if (akid.get()) {
290 addKeyId = (akid.get()->keyid != nullptr);
291 addIssuer = (akid.get()->issuer && akid.get()->serial);
292 }
293
294 if (!addKeyId && !addIssuer)
295 return false; // No need to add AuthorityKeyIdentifier
296
297 Ssl::ASN1_OCTET_STRING_Pointer issuerKeyId;
298 if (addKeyId) {
299 X509_EXTENSION *ext;
300 // Check if the issuer has the Subject Key Identifier extension
301 const int indx = X509_get_ext_by_NID(issuerCert.get(), NID_subject_key_identifier, -1);
302 if (indx >= 0 && (ext = X509_get_ext(issuerCert.get(), indx))) {
303 issuerKeyId.reset((ASN1_OCTET_STRING *)X509V3_EXT_d2i(ext));
304 }
305 }
306
307 Ssl::X509_NAME_Pointer issuerName;
308 Ssl::ASN1_INT_Pointer issuerSerial;
309 if (issuerKeyId.get() == nullptr || addIssuer) {
310 issuerName.reset(X509_NAME_dup(X509_get_issuer_name(issuerCert.get())));
311 issuerSerial.reset(ASN1_INTEGER_dup(X509_get_serialNumber(issuerCert.get())));
312 }
313
314 Ssl::AUTHORITY_KEYID_Pointer theAuthKeyId(AUTHORITY_KEYID_new());
315 if (!theAuthKeyId.get())
316 return false;
317 theAuthKeyId.get()->keyid = issuerKeyId.release();
318 if (issuerName && issuerSerial) {
319 Ssl::GENERAL_NAME_STACK_Pointer genNames(sk_GENERAL_NAME_new_null());
320 if (genNames.get()) {
321 if (GENERAL_NAME *aname = GENERAL_NAME_new()) {
322 sk_GENERAL_NAME_push(genNames.get(), aname);
323 aname->type = GEN_DIRNAME;
324 aname->d.dirn = issuerName.release();
325 theAuthKeyId.get()->issuer = genNames.release();
326 theAuthKeyId.get()->serial = issuerSerial.release();
327 }
328 }
329 }
330
331 // The Authority Key Identifier extension should include KeyId or/and both
332 /// issuer name and issuer serial
333 if (!theAuthKeyId.get()->keyid && (!theAuthKeyId.get()->issuer || !theAuthKeyId.get()->serial))
334 return false;
335
336 const X509V3_EXT_METHOD *method = X509V3_EXT_get_nid(NID_authority_key_identifier);
337 if (!method)
338 return false;
339
340 unsigned char *ext_der = NULL;
341 int ext_len = ASN1_item_i2d((ASN1_VALUE *)theAuthKeyId.get(), &ext_der, ASN1_ITEM_ptr(method->it));
342 Ssl::ASN1_OCTET_STRING_Pointer extOct(ASN1_OCTET_STRING_new());
343 extOct.get()->data = ext_der;
344 extOct.get()->length = ext_len;
345 Ssl::X509_EXTENSION_Pointer extAuthKeyId(X509_EXTENSION_create_by_NID(NULL, NID_authority_key_identifier, 0, extOct.get()));
346 if (!extAuthKeyId.get())
347 return false;
348
349 extOct.release();
350 if (!X509_add_ext(cert.get(), extAuthKeyId.get(), -1))
351 return false;
352
353 return true;
354 }
355
356 /// Copy certificate extensions from cert to mimicCert.
357 /// Returns the number of extensions copied.
358 // Currently only extensions which are reported by the users that required are
359 // mimicked. More safe to mimic extensions would be added here if users request
360 // them.
361 static int
362 mimicExtensions(Security::CertPointer & cert, Security::CertPointer const &mimicCert, Security::CertPointer const &issuerCert)
363 {
364 static int extensions[]= {
365 NID_key_usage,
366 NID_ext_key_usage,
367 NID_basic_constraints,
368 0
369 };
370
371 // key usage bit names
372 enum {
373 DigitalSignature,
374 NonRepudiation,
375 KeyEncipherment, // NSS requires for RSA but not EC
376 DataEncipherment,
377 KeyAgreement,
378 KeyCertificateSign,
379 CRLSign,
380 EncipherOnly,
381 DecipherOnly
382 };
383
384 #if HAVE_LIBCRYPTO_EVP_PKEY_GET0_RSA
385 EVP_PKEY *certKey = X509_get_pubkey(mimicCert.get());
386 const bool rsaPkey = (EVP_PKEY_get0_RSA(certKey) != nullptr);
387 #else
388 const int mimicAlgo = OBJ_obj2nid(mimicCert.get()->cert_info->key->algor->algorithm);
389 const bool rsaPkey = (mimicAlgo == NID_rsaEncryption);
390 #endif
391
392 int added = 0;
393 int nid;
394 for (int i = 0; (nid = extensions[i]) != 0; ++i) {
395 const int pos = X509_get_ext_by_NID(mimicCert.get(), nid, -1);
396 if (X509_EXTENSION *ext = X509_get_ext(mimicCert.get(), pos)) {
397 // Mimic extension exactly.
398 if (X509_add_ext(cert.get(), ext, -1))
399 ++added;
400 if (nid == NID_key_usage && !rsaPkey) {
401 // NSS does not requre the KeyEncipherment flag on EC keys
402 // but it does require it for RSA keys. Since ssl-bump
403 // substitutes RSA keys for EC ones, we need to ensure that
404 // that the more stringent requirements are met.
405
406 const int p = X509_get_ext_by_NID(cert.get(), NID_key_usage, -1);
407 if ((ext = X509_get_ext(cert.get(), p)) != NULL) {
408 ASN1_BIT_STRING *keyusage = (ASN1_BIT_STRING *)X509V3_EXT_d2i(ext);
409 ASN1_BIT_STRING_set_bit(keyusage, KeyEncipherment, 1);
410
411 //Build the ASN1_OCTET_STRING
412 const X509V3_EXT_METHOD *method = X509V3_EXT_get(ext);
413 assert(method && method->it);
414 unsigned char *ext_der = NULL;
415 int ext_len = ASN1_item_i2d((ASN1_VALUE *)keyusage,
416 &ext_der,
417 (const ASN1_ITEM *)ASN1_ITEM_ptr(method->it));
418
419 ASN1_OCTET_STRING *ext_oct = ASN1_OCTET_STRING_new();
420 ext_oct->data = ext_der;
421 ext_oct->length = ext_len;
422 X509_EXTENSION_set_data(ext, ext_oct);
423
424 ASN1_OCTET_STRING_free(ext_oct);
425 ASN1_BIT_STRING_free(keyusage);
426 }
427 }
428 }
429 }
430
431 if (mimicAuthorityKeyId(cert, mimicCert, issuerCert))
432 ++added;
433
434 // We could also restrict mimicking of the CA extension to CA:FALSE
435 // because Squid does not generate valid fake CA certificates.
436
437 return added;
438 }
439
440 /// Adds a new subjectAltName extension contining Subject CN or returns false
441 /// expects the caller to check for the existing subjectAltName extension
442 static bool
443 addAltNameWithSubjectCn(Security::CertPointer &cert)
444 {
445 X509_NAME *name = X509_get_subject_name(cert.get());
446 if (!name)
447 return false;
448
449 const int loc = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
450 if (loc < 0)
451 return false;
452
453 ASN1_STRING *cn_data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, loc));
454 if (!cn_data)
455 return false;
456
457 char dnsName[1024]; // DNS names are limited to 256 characters
458 const int res = snprintf(dnsName, sizeof(dnsName), "DNS:%*s", cn_data->length, cn_data->data);
459 if (res <= 0 || res >= static_cast<int>(sizeof(dnsName)))
460 return false;
461
462 X509_EXTENSION *ext = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name, dnsName);
463 if (!ext)
464 return false;
465
466 const bool result = X509_add_ext(cert.get(), ext, -1);
467
468 X509_EXTENSION_free(ext);
469 return result;
470 }
471
472 static bool buildCertificate(Security::CertPointer & cert, Ssl::CertificateProperties const &properties)
473 {
474 // not an Ssl::X509_NAME_Pointer because X509_REQ_get_subject_name()
475 // returns a pointer to the existing subject name. Nothing to clean here.
476 if (properties.mimicCert.get()) {
477 // Leave subject empty if we cannot extract it from true cert.
478 if (X509_NAME *name = X509_get_subject_name(properties.mimicCert.get())) {
479 // X509_set_subject_name will call X509_dup for name
480 X509_set_subject_name(cert.get(), name);
481 }
482 }
483
484 if (properties.setCommonName || !properties.mimicCert.get()) {
485 // In this case the CN of the certificate given by the user
486 // Ignore errors: it is better to make a certificate with no CN
487 // than to quit ssl-crtd helper because we cannot make a certificate.
488 // Most errors are caused by user input such as huge domain names.
489 (void)replaceCommonName(cert, properties.commonName);
490 }
491
492 // We should get caCert notBefore and notAfter fields and do not allow
493 // notBefore/notAfter values from certToMimic before/after notBefore/notAfter
494 // fields from caCert.
495 // Currently there is not any way in openssl tollkit to compare two ASN1_TIME
496 // objects.
497 ASN1_TIME *aTime = NULL;
498 if (!properties.setValidBefore && properties.mimicCert.get())
499 aTime = X509_get_notBefore(properties.mimicCert.get());
500 if (!aTime && properties.signWithX509.get())
501 aTime = X509_get_notBefore(properties.signWithX509.get());
502
503 if (aTime) {
504 if (!X509_set_notBefore(cert.get(), aTime))
505 return false;
506 } else if (!X509_gmtime_adj(X509_get_notBefore(cert.get()), (-2)*24*60*60))
507 return false;
508
509 aTime = NULL;
510 if (!properties.setValidAfter && properties.mimicCert.get())
511 aTime = X509_get_notAfter(properties.mimicCert.get());
512 if (!aTime && properties.signWithX509.get())
513 aTime = X509_get_notAfter(properties.signWithX509.get());
514 if (aTime) {
515 if (!X509_set_notAfter(cert.get(), aTime))
516 return false;
517 } else if (!X509_gmtime_adj(X509_get_notAfter(cert.get()), 60*60*24*356*3))
518 return false;
519
520 int addedExtensions = 0;
521 bool useCommonNameAsAltName = true;
522 // mimic the alias and possibly subjectAltName
523 if (properties.mimicCert.get()) {
524 unsigned char *alStr;
525 int alLen;
526 alStr = X509_alias_get0(properties.mimicCert.get(), &alLen);
527 if (alStr) {
528 X509_alias_set1(cert.get(), alStr, alLen);
529 }
530
531 // Mimic subjectAltName unless we used a configured CN: browsers reject
532 // certificates with CN unrelated to subjectAltNames.
533 if (!properties.setCommonName) {
534 int pos = X509_get_ext_by_NID(properties.mimicCert.get(), NID_subject_alt_name, -1);
535 X509_EXTENSION *ext=X509_get_ext(properties.mimicCert.get(), pos);
536 if (ext) {
537 if (X509_add_ext(cert.get(), ext, -1))
538 ++addedExtensions;
539 }
540 // We want to mimic the server-sent subjectAltName, not enhance it.
541 useCommonNameAsAltName = false;
542 }
543
544 addedExtensions += mimicExtensions(cert, properties.mimicCert, properties.signWithX509);
545 }
546
547 if (useCommonNameAsAltName && addAltNameWithSubjectCn(cert))
548 ++addedExtensions;
549
550 // According to RFC 5280, using extensions requires v3 certificate.
551 if (addedExtensions)
552 X509_set_version(cert.get(), 2); // value 2 means v3
553
554 return true;
555 }
556
557 static bool generateFakeSslCertificate(Security::CertPointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties, Ssl::BIGNUM_Pointer const &serial)
558 {
559 Ssl::EVP_PKEY_Pointer pkey;
560 // Use signing certificates private key as generated certificate private key
561 if (properties.signWithPkey.get())
562 pkey.resetAndLock(properties.signWithPkey.get());
563 else // if not exist generate one
564 pkey.resetWithoutLocking(Ssl::createSslPrivateKey());
565
566 if (!pkey)
567 return false;
568
569 Security::CertPointer cert(X509_new());
570 if (!cert)
571 return false;
572
573 // Set pub key and serial given by the caller
574 if (!X509_set_pubkey(cert.get(), pkey.get()))
575 return false;
576 if (!setSerialNumber(X509_get_serialNumber(cert.get()), serial.get()))
577 return false;
578
579 // Fill the certificate with the required properties
580 if (!buildCertificate(cert, properties))
581 return false;
582
583 int ret = 0;
584 // Set issuer name, from CA or our subject name for self signed cert
585 if (properties.signAlgorithm != Ssl::algSignSelf && properties.signWithX509.get())
586 ret = X509_set_issuer_name(cert.get(), X509_get_subject_name(properties.signWithX509.get()));
587 else // Self signed certificate, set issuer to self
588 ret = X509_set_issuer_name(cert.get(), X509_get_subject_name(cert.get()));
589 if (!ret)
590 return false;
591
592 const EVP_MD *hash = properties.signHash ? properties.signHash : EVP_get_digestbyname(SQUID_SSL_SIGN_HASH_IF_NONE);
593 assert(hash);
594 /*Now sign the request */
595 if (properties.signAlgorithm != Ssl::algSignSelf && properties.signWithPkey.get())
596 ret = X509_sign(cert.get(), properties.signWithPkey.get(), hash);
597 else //else sign with self key (self signed request)
598 ret = X509_sign(cert.get(), pkey.get(), hash);
599
600 if (!ret)
601 return false;
602
603 certToStore = std::move(cert);
604 pkeyToStore = std::move(pkey);
605 return true;
606 }
607
608 static BIGNUM *createCertSerial(unsigned char *md, unsigned int n)
609 {
610
611 assert(n == 20); //for sha1 n is 20 (for md5 n is 16)
612
613 BIGNUM *serial = NULL;
614 serial = BN_bin2bn(md, n, NULL);
615
616 // if the serial is "0" set it to '1'
617 if (BN_is_zero(serial) == true)
618 BN_one(serial);
619
620 // serial size does not exceed 20 bytes
621 assert(BN_num_bits(serial) <= 160);
622
623 // According the RFC 5280, serial is an 20 bytes ASN.1 INTEGER (a signed big integer)
624 // and the maximum value for X.509 certificate serial number is 2^159-1 and
625 // the minimum 0. If the first bit of the serial is '1' ( eg 2^160-1),
626 // will result to a negative integer.
627 // To handle this, if the produced serial is greater than 2^159-1
628 // truncate the last bit
629 if (BN_is_bit_set(serial, 159))
630 BN_clear_bit(serial, 159);
631
632 return serial;
633 }
634
635 /// Return the SHA1 digest of the DER encoded version of the certificate
636 /// stored in a BIGNUM
637 static BIGNUM *x509Digest(Security::CertPointer const & cert)
638 {
639 unsigned int n;
640 unsigned char md[EVP_MAX_MD_SIZE];
641
642 if (!X509_digest(cert.get(),EVP_sha1(),md,&n))
643 return NULL;
644
645 return createCertSerial(md, n);
646 }
647
648 static BIGNUM *x509Pubkeydigest(Security::CertPointer const & cert)
649 {
650 unsigned int n;
651 unsigned char md[EVP_MAX_MD_SIZE];
652
653 if (!X509_pubkey_digest(cert.get(),EVP_sha1(),md,&n))
654 return NULL;
655
656 return createCertSerial(md, n);
657 }
658
659 /// Generate a unique serial number based on a Ssl::CertificateProperties object
660 /// for a new generated certificate
661 static bool createSerial(Ssl::BIGNUM_Pointer &serial, Ssl::CertificateProperties const &properties)
662 {
663 Ssl::EVP_PKEY_Pointer fakePkey;
664 Security::CertPointer fakeCert;
665
666 serial.reset(x509Pubkeydigest(properties.signWithX509));
667 if (!serial.get()) {
668 serial.reset(BN_new());
669 BN_zero(serial.get());
670 }
671
672 if (!generateFakeSslCertificate(fakeCert, fakePkey, properties, serial))
673 return false;
674
675 // The x509Fingerprint return an SHA1 hash.
676 // both SHA1 hash and maximum serial number size are 20 bytes.
677 BIGNUM *r = x509Digest(fakeCert);
678 if (!r)
679 return false;
680
681 serial.reset(r);
682 return true;
683 }
684
685 bool Ssl::generateSslCertificate(Security::CertPointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties)
686 {
687 Ssl::BIGNUM_Pointer serial;
688
689 if (!createSerial(serial, properties))
690 return false;
691
692 return generateFakeSslCertificate(certToStore, pkeyToStore, properties, serial);
693 }
694
695 bool
696 Ssl::OpenCertsFileForReading(Ssl::BIO_Pointer &bio, const char *filename)
697 {
698 bio.reset(BIO_new(BIO_s_file()));
699 if (!bio)
700 return false;
701 if (!BIO_read_filename(bio.get(), filename))
702 return false;
703 return true;
704 }
705
706 bool
707 Ssl::ReadX509Certificate(Ssl::BIO_Pointer &bio, Security::CertPointer & cert)
708 {
709 assert(bio);
710 if (X509 *certificate = PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)) {
711 cert.resetWithoutLocking(certificate);
712 return true;
713 }
714 return false;
715 }
716
717 bool
718 Ssl::ReadPrivateKey(Ssl::BIO_Pointer &bio, Ssl::EVP_PKEY_Pointer &pkey, pem_password_cb *passwd_callback)
719 {
720 assert(bio);
721 if (EVP_PKEY *akey = PEM_read_bio_PrivateKey(bio.get(), NULL, passwd_callback, NULL)) {
722 pkey.resetWithoutLocking(akey);
723 return true;
724 }
725 return false;
726 }
727
728 void
729 Ssl::ReadPrivateKeyFromFile(char const * keyFilename, Ssl::EVP_PKEY_Pointer &pkey, pem_password_cb *passwd_callback)
730 {
731 if (!keyFilename)
732 return;
733 Ssl::BIO_Pointer bio;
734 if (!OpenCertsFileForReading(bio, keyFilename))
735 return;
736 ReadPrivateKey(bio, pkey, passwd_callback);
737 }
738
739 bool
740 Ssl::OpenCertsFileForWriting(Ssl::BIO_Pointer &bio, const char *filename)
741 {
742 bio.reset(BIO_new(BIO_s_file()));
743 if (!bio)
744 return false;
745 if (!BIO_write_filename(bio.get(), const_cast<char *>(filename)))
746 return false;
747 return true;
748 }
749
750 bool
751 Ssl::WriteX509Certificate(Ssl::BIO_Pointer &bio, const Security::CertPointer & cert)
752 {
753 if (!cert || !bio)
754 return false;
755 if (!PEM_write_bio_X509(bio.get(), cert.get()))
756 return false;
757 return true;
758 }
759
760 bool
761 Ssl::WritePrivateKey(Ssl::BIO_Pointer &bio, const Ssl::EVP_PKEY_Pointer &pkey)
762 {
763 if (!pkey || !bio)
764 return false;
765 if (!PEM_write_bio_PrivateKey(bio.get(), pkey.get(), NULL, NULL, 0, NULL, NULL))
766 return false;
767 return true;
768 }
769
770 bool Ssl::sslDateIsInTheFuture(char const * date)
771 {
772 ASN1_UTCTIME tm;
773 tm.flags = 0;
774 tm.type = 23;
775 tm.data = (unsigned char *)date;
776 tm.length = strlen(date);
777
778 return (X509_cmp_current_time(&tm) > 0);
779 }
780
781 /// Print the time represented by a ASN1_TIME struct to a string using GeneralizedTime format
782 static bool asn1timeToGeneralizedTimeStr(ASN1_TIME *aTime, char *buf, int bufLen)
783 {
784 // ASN1_Time holds time to UTCTime or GeneralizedTime form.
785 // UTCTime has the form YYMMDDHHMMSS[Z | [+|-]offset]
786 // GeneralizedTime has the form YYYYMMDDHHMMSS[Z | [+|-] offset]
787
788 // length should have space for data plus 2 extra bytes for the two extra year fields
789 // plus the '\0' char.
790 if ((aTime->length + 3) > bufLen)
791 return false;
792
793 char *str;
794 if (aTime->type == V_ASN1_UTCTIME) {
795 if (aTime->data[0] > '5') { // RFC 2459, section 4.1.2.5.1
796 buf[0] = '1';
797 buf[1] = '9';
798 } else {
799 buf[0] = '2';
800 buf[1] = '0';
801 }
802 str = buf +2;
803 } else // if (aTime->type == V_ASN1_GENERALIZEDTIME)
804 str = buf;
805
806 memcpy(str, aTime->data, aTime->length);
807 str[aTime->length] = '\0';
808 return true;
809 }
810
811 static int asn1time_cmp(ASN1_TIME *asnTime1, ASN1_TIME *asnTime2)
812 {
813 char strTime1[64], strTime2[64];
814 if (!asn1timeToGeneralizedTimeStr(asnTime1, strTime1, sizeof(strTime1)))
815 return -1;
816 if (!asn1timeToGeneralizedTimeStr(asnTime2, strTime2, sizeof(strTime2)))
817 return -1;
818
819 return strcmp(strTime1, strTime2);
820 }
821
822 bool Ssl::certificateMatchesProperties(X509 *cert, CertificateProperties const &properties)
823 {
824 assert(cert);
825
826 // For non self-signed certificates we have to check if the signing certificate changed
827 if (properties.signAlgorithm != Ssl::algSignSelf) {
828 assert(properties.signWithX509.get());
829 if (X509_check_issued(properties.signWithX509.get(), cert) != X509_V_OK)
830 return false;
831 }
832
833 X509 *cert2 = properties.mimicCert.get();
834 // If there is not certificate to mimic stop here
835 if (!cert2)
836 return true;
837
838 if (!properties.setCommonName) {
839 X509_NAME *cert1_name = X509_get_subject_name(cert);
840 X509_NAME *cert2_name = X509_get_subject_name(cert2);
841 if (X509_NAME_cmp(cert1_name, cert2_name) != 0)
842 return false;
843 } else if (properties.commonName != CommonHostName(cert))
844 return false;
845
846 if (!properties.setValidBefore) {
847 ASN1_TIME *aTime = X509_get_notBefore(cert);
848 ASN1_TIME *bTime = X509_get_notBefore(cert2);
849 if (asn1time_cmp(aTime, bTime) != 0)
850 return false;
851 } else if (X509_cmp_current_time(X509_get_notBefore(cert)) >= 0) {
852 // notBefore does not exist (=0) or it is in the future (>0)
853 return false;
854 }
855
856 if (!properties.setValidAfter) {
857 ASN1_TIME *aTime = X509_get_notAfter(cert);
858 ASN1_TIME *bTime = X509_get_notAfter(cert2);
859 if (asn1time_cmp(aTime, bTime) != 0)
860 return false;
861 } else if (X509_cmp_current_time(X509_get_notAfter(cert)) <= 0) {
862 // notAfter does not exist (0) or it is in the past (<0)
863 return false;
864 }
865
866 char *alStr1;
867 int alLen;
868 alStr1 = (char *)X509_alias_get0(cert, &alLen);
869 char *alStr2 = (char *)X509_alias_get0(cert2, &alLen);
870 if ((!alStr1 && alStr2) || (alStr1 && !alStr2) ||
871 (alStr1 && alStr2 && strcmp(alStr1, alStr2)) != 0)
872 return false;
873
874 // Compare subjectAltName extension
875 STACK_OF(GENERAL_NAME) * cert1_altnames;
876 cert1_altnames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
877 STACK_OF(GENERAL_NAME) * cert2_altnames;
878 cert2_altnames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(cert2, NID_subject_alt_name, NULL, NULL);
879 bool match = true;
880 if (cert1_altnames) {
881 int numalts = sk_GENERAL_NAME_num(cert1_altnames);
882 for (int i = 0; match && i < numalts; ++i) {
883 GENERAL_NAME *aName = sk_GENERAL_NAME_value(cert1_altnames, i);
884 match = sk_GENERAL_NAME_find(cert2_altnames, aName);
885 }
886 } else if (cert2_altnames)
887 match = false;
888
889 sk_GENERAL_NAME_pop_free(cert1_altnames, GENERAL_NAME_free);
890 sk_GENERAL_NAME_pop_free(cert2_altnames, GENERAL_NAME_free);
891
892 return match;
893 }
894
895 static const char *getSubjectEntry(X509 *x509, int nid)
896 {
897 static char name[1024] = ""; // stores common name (CN)
898
899 if (!x509)
900 return NULL;
901
902 // TODO: What if the entry is a UTF8String? See X509_NAME_get_index_by_NID(3ssl).
903 const int nameLen = X509_NAME_get_text_by_NID(
904 X509_get_subject_name(x509),
905 nid, name, sizeof(name));
906
907 if (nameLen > 0)
908 return name;
909
910 return NULL;
911 }
912
913 const char *Ssl::CommonHostName(X509 *x509)
914 {
915 return getSubjectEntry(x509, NID_commonName);
916 }
917
918 const char *Ssl::getOrganization(X509 *x509)
919 {
920 return getSubjectEntry(x509, NID_organizationName);
921 }
922
923 bool
924 Ssl::CertificatesCmp(const Security::CertPointer &cert1, const Security::CertPointer &cert2)
925 {
926 if (!cert1 || ! cert2)
927 return false;
928
929 int cert1Len;
930 unsigned char *cert1Asn = NULL;
931 cert1Len = ASN1_item_i2d((ASN1_VALUE *)cert1.get(), &cert1Asn, ASN1_ITEM_rptr(X509));
932
933 int cert2Len;
934 unsigned char *cert2Asn = NULL;
935 cert2Len = ASN1_item_i2d((ASN1_VALUE *)cert2.get(), &cert2Asn, ASN1_ITEM_rptr(X509));
936
937 if (cert1Len != cert2Len)
938 return false;
939
940 bool ret = (memcmp(cert1Asn, cert2Asn, cert1Len) == 0);
941
942 OPENSSL_free(cert1Asn);
943 OPENSSL_free(cert2Asn);
944
945 return ret;
946 }
947
948 const ASN1_BIT_STRING *
949 Ssl::X509_get_signature(const Security::CertPointer &cert)
950 {
951 #if HAVE_LIBCRYPTO_X509_GET0_SIGNATURE
952 #if SQUID_USE_CONST_X509_GET0_SIGNATURE_ARGS
953 const ASN1_BIT_STRING *sig = nullptr;
954 const X509_ALGOR *sig_alg = nullptr;
955 #else
956 ASN1_BIT_STRING *sig = nullptr;
957 X509_ALGOR *sig_alg = nullptr;
958 #endif
959 X509_get0_signature(&sig, &sig_alg, cert.get());
960 return sig;
961 #else
962 return cert->signature;
963 #endif
964 }
965