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