OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... |
39 // Generate a key pair. Caller is responsible for freeing the returned object. | 39 // Generate a key pair. Caller is responsible for freeing the returned object. |
40 static EVP_PKEY* MakeKey(const KeyParams& key_params) { | 40 static EVP_PKEY* MakeKey(const KeyParams& key_params) { |
41 LOG(LS_INFO) << "Making key pair"; | 41 LOG(LS_INFO) << "Making key pair"; |
42 EVP_PKEY* pkey = EVP_PKEY_new(); | 42 EVP_PKEY* pkey = EVP_PKEY_new(); |
43 if (key_params.type() == KT_RSA) { | 43 if (key_params.type() == KT_RSA) { |
44 int key_length = key_params.rsa_params().mod_size; | 44 int key_length = key_params.rsa_params().mod_size; |
45 BIGNUM* exponent = BN_new(); | 45 BIGNUM* exponent = BN_new(); |
46 RSA* rsa = RSA_new(); | 46 RSA* rsa = RSA_new(); |
47 if (!pkey || !exponent || !rsa || | 47 if (!pkey || !exponent || !rsa || |
48 !BN_set_word(exponent, key_params.rsa_params().pub_exp) || | 48 !BN_set_word(exponent, key_params.rsa_params().pub_exp) || |
49 !RSA_generate_key_ex(rsa, key_length, exponent, NULL) || | 49 !RSA_generate_key_ex(rsa, key_length, exponent, nullptr) || |
50 !EVP_PKEY_assign_RSA(pkey, rsa)) { | 50 !EVP_PKEY_assign_RSA(pkey, rsa)) { |
51 EVP_PKEY_free(pkey); | 51 EVP_PKEY_free(pkey); |
52 BN_free(exponent); | 52 BN_free(exponent); |
53 RSA_free(rsa); | 53 RSA_free(rsa); |
54 LOG(LS_ERROR) << "Failed to make RSA key pair"; | 54 LOG(LS_ERROR) << "Failed to make RSA key pair"; |
55 return NULL; | 55 return nullptr; |
56 } | 56 } |
57 // ownership of rsa struct was assigned, don't free it. | 57 // ownership of rsa struct was assigned, don't free it. |
58 BN_free(exponent); | 58 BN_free(exponent); |
59 } else if (key_params.type() == KT_ECDSA) { | 59 } else if (key_params.type() == KT_ECDSA) { |
60 if (key_params.ec_curve() == EC_NIST_P256) { | 60 if (key_params.ec_curve() == EC_NIST_P256) { |
61 EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); | 61 EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); |
62 | 62 |
63 // Ensure curve name is included when EC key is serialized. | 63 // Ensure curve name is included when EC key is serialized. |
64 // Without this call, OpenSSL versions before 1.1.0 will create | 64 // Without this call, OpenSSL versions before 1.1.0 will create |
65 // certificates that don't work for TLS. | 65 // certificates that don't work for TLS. |
66 // This is a no-op for BoringSSL and OpenSSL 1.1.0+ | 66 // This is a no-op for BoringSSL and OpenSSL 1.1.0+ |
67 EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE); | 67 EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE); |
68 | 68 |
69 if (!pkey || !ec_key || !EC_KEY_generate_key(ec_key) || | 69 if (!pkey || !ec_key || !EC_KEY_generate_key(ec_key) || |
70 !EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { | 70 !EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { |
71 EVP_PKEY_free(pkey); | 71 EVP_PKEY_free(pkey); |
72 EC_KEY_free(ec_key); | 72 EC_KEY_free(ec_key); |
73 LOG(LS_ERROR) << "Failed to make EC key pair"; | 73 LOG(LS_ERROR) << "Failed to make EC key pair"; |
74 return NULL; | 74 return nullptr; |
75 } | 75 } |
76 // ownership of ec_key struct was assigned, don't free it. | 76 // ownership of ec_key struct was assigned, don't free it. |
77 } else { | 77 } else { |
78 // Add generation of any other curves here. | 78 // Add generation of any other curves here. |
79 EVP_PKEY_free(pkey); | 79 EVP_PKEY_free(pkey); |
80 LOG(LS_ERROR) << "ECDSA key requested for unknown curve"; | 80 LOG(LS_ERROR) << "ECDSA key requested for unknown curve"; |
81 return NULL; | 81 return nullptr; |
82 } | 82 } |
83 } else { | 83 } else { |
84 EVP_PKEY_free(pkey); | 84 EVP_PKEY_free(pkey); |
85 LOG(LS_ERROR) << "Key type requested not understood"; | 85 LOG(LS_ERROR) << "Key type requested not understood"; |
86 return NULL; | 86 return nullptr; |
87 } | 87 } |
88 | 88 |
89 LOG(LS_INFO) << "Returning key pair"; | 89 LOG(LS_INFO) << "Returning key pair"; |
90 return pkey; | 90 return pkey; |
91 } | 91 } |
92 | 92 |
93 // Generate a self-signed certificate, with the public key from the | 93 // Generate a self-signed certificate, with the public key from the |
94 // given key pair. Caller is responsible for freeing the returned object. | 94 // given key pair. Caller is responsible for freeing the returned object. |
95 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { | 95 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { |
96 LOG(LS_INFO) << "Making certificate for " << params.common_name; | 96 LOG(LS_INFO) << "Making certificate for " << params.common_name; |
97 X509* x509 = NULL; | 97 X509* x509 = nullptr; |
98 BIGNUM* serial_number = NULL; | 98 BIGNUM* serial_number = nullptr; |
99 X509_NAME* name = NULL; | 99 X509_NAME* name = nullptr; |
100 time_t epoch_off = 0; // Time offset since epoch. | 100 time_t epoch_off = 0; // Time offset since epoch. |
101 | 101 |
102 if ((x509=X509_new()) == NULL) | 102 if ((x509 = X509_new()) == nullptr) |
103 goto error; | 103 goto error; |
104 | 104 |
105 if (!X509_set_pubkey(x509, pkey)) | 105 if (!X509_set_pubkey(x509, pkey)) |
106 goto error; | 106 goto error; |
107 | 107 |
108 // serial number | 108 // serial number |
109 // temporary reference to serial number inside x509 struct | 109 // temporary reference to serial number inside x509 struct |
110 ASN1_INTEGER* asn1_serial_number; | 110 ASN1_INTEGER* asn1_serial_number; |
111 if ((serial_number = BN_new()) == NULL || | 111 if ((serial_number = BN_new()) == nullptr || |
112 !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) || | 112 !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) || |
113 (asn1_serial_number = X509_get_serialNumber(x509)) == NULL || | 113 (asn1_serial_number = X509_get_serialNumber(x509)) == nullptr || |
114 !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) | 114 !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) |
115 goto error; | 115 goto error; |
116 | 116 |
117 if (!X509_set_version(x509, 2L)) // version 3 | 117 if (!X509_set_version(x509, 2L)) // version 3 |
118 goto error; | 118 goto error; |
119 | 119 |
120 // There are a lot of possible components for the name entries. In | 120 // There are a lot of possible components for the name entries. In |
121 // our P2P SSL mode however, the certificates are pre-exchanged | 121 // our P2P SSL mode however, the certificates are pre-exchanged |
122 // (through the secure XMPP channel), and so the certificate | 122 // (through the secure XMPP channel), and so the certificate |
123 // identification is arbitrary. It can't be empty, so we set some | 123 // identification is arbitrary. It can't be empty, so we set some |
124 // arbitrary common_name. Note that this certificate goes out in | 124 // arbitrary common_name. Note that this certificate goes out in |
125 // clear during SSL negotiation, so there may be a privacy issue in | 125 // clear during SSL negotiation, so there may be a privacy issue in |
126 // putting anything recognizable here. | 126 // putting anything recognizable here. |
127 if ((name = X509_NAME_new()) == NULL || | 127 if ((name = X509_NAME_new()) == nullptr || |
128 !X509_NAME_add_entry_by_NID( | 128 !X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8, |
129 name, NID_commonName, MBSTRING_UTF8, | 129 (unsigned char*)params.common_name.c_str(), |
130 (unsigned char*)params.common_name.c_str(), -1, -1, 0) || | 130 -1, -1, 0) || |
131 !X509_set_subject_name(x509, name) || | 131 !X509_set_subject_name(x509, name) || !X509_set_issuer_name(x509, name)) |
132 !X509_set_issuer_name(x509, name)) | |
133 goto error; | 132 goto error; |
134 | 133 |
135 if (!X509_time_adj(X509_get_notBefore(x509), params.not_before, &epoch_off) || | 134 if (!X509_time_adj(X509_get_notBefore(x509), params.not_before, &epoch_off) || |
136 !X509_time_adj(X509_get_notAfter(x509), params.not_after, &epoch_off)) | 135 !X509_time_adj(X509_get_notAfter(x509), params.not_after, &epoch_off)) |
137 goto error; | 136 goto error; |
138 | 137 |
139 if (!X509_sign(x509, pkey, EVP_sha256())) | 138 if (!X509_sign(x509, pkey, EVP_sha256())) |
140 goto error; | 139 goto error; |
141 | 140 |
142 BN_free(serial_number); | 141 BN_free(serial_number); |
143 X509_NAME_free(name); | 142 X509_NAME_free(name); |
144 LOG(LS_INFO) << "Returning certificate"; | 143 LOG(LS_INFO) << "Returning certificate"; |
145 return x509; | 144 return x509; |
146 | 145 |
147 error: | 146 error: |
148 BN_free(serial_number); | 147 BN_free(serial_number); |
149 X509_NAME_free(name); | 148 X509_NAME_free(name); |
150 X509_free(x509); | 149 X509_free(x509); |
151 return NULL; | 150 return nullptr; |
152 } | 151 } |
153 | 152 |
154 // This dumps the SSL error stack to the log. | 153 // This dumps the SSL error stack to the log. |
155 static void LogSSLErrors(const std::string& prefix) { | 154 static void LogSSLErrors(const std::string& prefix) { |
156 char error_buf[200]; | 155 char error_buf[200]; |
157 unsigned long err; | 156 unsigned long err; |
158 | 157 |
159 while ((err = ERR_get_error()) != 0) { | 158 while ((err = ERR_get_error()) != 0) { |
160 ERR_error_string_n(err, error_buf, sizeof(error_buf)); | 159 ERR_error_string_n(err, error_buf, sizeof(error_buf)); |
161 LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; | 160 LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; |
162 } | 161 } |
163 } | 162 } |
164 | 163 |
165 OpenSSLKeyPair* OpenSSLKeyPair::Generate(const KeyParams& key_params) { | 164 OpenSSLKeyPair* OpenSSLKeyPair::Generate(const KeyParams& key_params) { |
166 EVP_PKEY* pkey = MakeKey(key_params); | 165 EVP_PKEY* pkey = MakeKey(key_params); |
167 if (!pkey) { | 166 if (!pkey) { |
168 LogSSLErrors("Generating key pair"); | 167 LogSSLErrors("Generating key pair"); |
169 return NULL; | 168 return nullptr; |
170 } | 169 } |
171 return new OpenSSLKeyPair(pkey); | 170 return new OpenSSLKeyPair(pkey); |
172 } | 171 } |
173 | 172 |
174 OpenSSLKeyPair* OpenSSLKeyPair::FromPrivateKeyPEMString( | 173 OpenSSLKeyPair* OpenSSLKeyPair::FromPrivateKeyPEMString( |
175 const std::string& pem_string) { | 174 const std::string& pem_string) { |
176 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); | 175 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); |
177 if (!bio) { | 176 if (!bio) { |
178 LOG(LS_ERROR) << "Failed to create a new BIO buffer."; | 177 LOG(LS_ERROR) << "Failed to create a new BIO buffer."; |
179 return nullptr; | 178 return nullptr; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 OpenSSLCertificate* OpenSSLCertificate::Generate( | 281 OpenSSLCertificate* OpenSSLCertificate::Generate( |
283 OpenSSLKeyPair* key_pair, const SSLIdentityParams& params) { | 282 OpenSSLKeyPair* key_pair, const SSLIdentityParams& params) { |
284 SSLIdentityParams actual_params(params); | 283 SSLIdentityParams actual_params(params); |
285 if (actual_params.common_name.empty()) { | 284 if (actual_params.common_name.empty()) { |
286 // Use a random string, arbitrarily 8chars long. | 285 // Use a random string, arbitrarily 8chars long. |
287 actual_params.common_name = CreateRandomString(8); | 286 actual_params.common_name = CreateRandomString(8); |
288 } | 287 } |
289 X509* x509 = MakeCertificate(key_pair->pkey(), actual_params); | 288 X509* x509 = MakeCertificate(key_pair->pkey(), actual_params); |
290 if (!x509) { | 289 if (!x509) { |
291 LogSSLErrors("Generating certificate"); | 290 LogSSLErrors("Generating certificate"); |
292 return NULL; | 291 return nullptr; |
293 } | 292 } |
294 #if !defined(NDEBUG) | 293 #if !defined(NDEBUG) |
295 PrintCert(x509); | 294 PrintCert(x509); |
296 #endif | 295 #endif |
297 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); | 296 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); |
298 X509_free(x509); | 297 X509_free(x509); |
299 return ret; | 298 return ret; |
300 } | 299 } |
301 | 300 |
302 OpenSSLCertificate* OpenSSLCertificate::FromPEMString( | 301 OpenSSLCertificate* OpenSSLCertificate::FromPEMString( |
303 const std::string& pem_string) { | 302 const std::string& pem_string) { |
304 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); | 303 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); |
305 if (!bio) | 304 if (!bio) |
306 return NULL; | 305 return nullptr; |
307 BIO_set_mem_eof_return(bio, 0); | 306 BIO_set_mem_eof_return(bio, 0); |
308 X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, const_cast<char*>("\0")); | 307 X509* x509 = |
| 308 PEM_read_bio_X509(bio, nullptr, nullptr, const_cast<char*>("\0")); |
309 BIO_free(bio); // Frees the BIO, but not the pointed-to string. | 309 BIO_free(bio); // Frees the BIO, but not the pointed-to string. |
310 | 310 |
311 if (!x509) | 311 if (!x509) |
312 return NULL; | 312 return nullptr; |
313 | 313 |
314 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); | 314 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); |
315 X509_free(x509); | 315 X509_free(x509); |
316 return ret; | 316 return ret; |
317 } | 317 } |
318 | 318 |
319 // NOTE: This implementation only functions correctly after InitializeSSL | 319 // NOTE: This implementation only functions correctly after InitializeSSL |
320 // and before CleanupSSL. | 320 // and before CleanupSSL. |
321 bool OpenSSLCertificate::GetSignatureDigestAlgorithm( | 321 bool OpenSSLCertificate::GetSignatureDigestAlgorithm( |
322 std::string* algorithm) const { | 322 std::string* algorithm) const { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 BIO_free(bio); | 434 BIO_free(bio); |
435 FATAL() << "unreachable code"; | 435 FATAL() << "unreachable code"; |
436 } | 436 } |
437 char* data; | 437 char* data; |
438 size_t length = BIO_get_mem_data(bio, &data); | 438 size_t length = BIO_get_mem_data(bio, &data); |
439 der_buffer->SetData(data, length); | 439 der_buffer->SetData(data, length); |
440 BIO_free(bio); | 440 BIO_free(bio); |
441 } | 441 } |
442 | 442 |
443 void OpenSSLCertificate::AddReference() const { | 443 void OpenSSLCertificate::AddReference() const { |
444 RTC_DCHECK(x509_ != NULL); | 444 RTC_DCHECK(x509_ != nullptr); |
445 #if defined(OPENSSL_IS_BORINGSSL) | 445 #if defined(OPENSSL_IS_BORINGSSL) |
446 X509_up_ref(x509_); | 446 X509_up_ref(x509_); |
447 #else | 447 #else |
448 CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509); | 448 CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509); |
449 #endif | 449 #endif |
450 } | 450 } |
451 | 451 |
452 bool OpenSSLCertificate::operator==(const OpenSSLCertificate& other) const { | 452 bool OpenSSLCertificate::operator==(const OpenSSLCertificate& other) const { |
453 return X509_cmp(this->x509_, other.x509_) == 0; | 453 return X509_cmp(this->x509_, other.x509_) == 0; |
454 } | 454 } |
(...skipping 14 matching lines...) Expand all Loading... |
469 } else { | 469 } else { |
470 return -1; | 470 return -1; |
471 } | 471 } |
472 | 472 |
473 return ASN1TimeToSec(expire_time->data, expire_time->length, long_format); | 473 return ASN1TimeToSec(expire_time->data, expire_time->length, long_format); |
474 } | 474 } |
475 | 475 |
476 OpenSSLIdentity::OpenSSLIdentity(OpenSSLKeyPair* key_pair, | 476 OpenSSLIdentity::OpenSSLIdentity(OpenSSLKeyPair* key_pair, |
477 OpenSSLCertificate* certificate) | 477 OpenSSLCertificate* certificate) |
478 : key_pair_(key_pair), certificate_(certificate) { | 478 : key_pair_(key_pair), certificate_(certificate) { |
479 RTC_DCHECK(key_pair != NULL); | 479 RTC_DCHECK(key_pair != nullptr); |
480 RTC_DCHECK(certificate != NULL); | 480 RTC_DCHECK(certificate != nullptr); |
481 } | 481 } |
482 | 482 |
483 OpenSSLIdentity::~OpenSSLIdentity() = default; | 483 OpenSSLIdentity::~OpenSSLIdentity() = default; |
484 | 484 |
485 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( | 485 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( |
486 const SSLIdentityParams& params) { | 486 const SSLIdentityParams& params) { |
487 OpenSSLKeyPair* key_pair = OpenSSLKeyPair::Generate(params.key_params); | 487 OpenSSLKeyPair* key_pair = OpenSSLKeyPair::Generate(params.key_params); |
488 if (key_pair) { | 488 if (key_pair) { |
489 OpenSSLCertificate* certificate = | 489 OpenSSLCertificate* certificate = |
490 OpenSSLCertificate::Generate(key_pair, params); | 490 OpenSSLCertificate::Generate(key_pair, params); |
491 if (certificate) | 491 if (certificate) |
492 return new OpenSSLIdentity(key_pair, certificate); | 492 return new OpenSSLIdentity(key_pair, certificate); |
493 delete key_pair; | 493 delete key_pair; |
494 } | 494 } |
495 LOG(LS_INFO) << "Identity generation failed"; | 495 LOG(LS_INFO) << "Identity generation failed"; |
496 return NULL; | 496 return nullptr; |
497 } | 497 } |
498 | 498 |
499 OpenSSLIdentity* OpenSSLIdentity::GenerateWithExpiration( | 499 OpenSSLIdentity* OpenSSLIdentity::GenerateWithExpiration( |
500 const std::string& common_name, | 500 const std::string& common_name, |
501 const KeyParams& key_params, | 501 const KeyParams& key_params, |
502 time_t certificate_lifetime) { | 502 time_t certificate_lifetime) { |
503 SSLIdentityParams params; | 503 SSLIdentityParams params; |
504 params.key_params = key_params; | 504 params.key_params = key_params; |
505 params.common_name = common_name; | 505 params.common_name = common_name; |
506 time_t now = time(NULL); | 506 time_t now = time(nullptr); |
507 params.not_before = now + kCertificateWindowInSeconds; | 507 params.not_before = now + kCertificateWindowInSeconds; |
508 params.not_after = now + certificate_lifetime; | 508 params.not_after = now + certificate_lifetime; |
509 if (params.not_before > params.not_after) | 509 if (params.not_before > params.not_after) |
510 return nullptr; | 510 return nullptr; |
511 return GenerateInternal(params); | 511 return GenerateInternal(params); |
512 } | 512 } |
513 | 513 |
514 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( | 514 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( |
515 const SSLIdentityParams& params) { | 515 const SSLIdentityParams& params) { |
516 return GenerateInternal(params); | 516 return GenerateInternal(params); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 bool OpenSSLIdentity::operator==(const OpenSSLIdentity& other) const { | 567 bool OpenSSLIdentity::operator==(const OpenSSLIdentity& other) const { |
568 return *this->key_pair_ == *other.key_pair_ && | 568 return *this->key_pair_ == *other.key_pair_ && |
569 *this->certificate_ == *other.certificate_; | 569 *this->certificate_ == *other.certificate_; |
570 } | 570 } |
571 | 571 |
572 bool OpenSSLIdentity::operator!=(const OpenSSLIdentity& other) const { | 572 bool OpenSSLIdentity::operator!=(const OpenSSLIdentity& other) const { |
573 return !(*this == other); | 573 return !(*this == other); |
574 } | 574 } |
575 | 575 |
576 } // namespace rtc | 576 } // namespace rtc |
OLD | NEW |