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 // Random bits for certificate serial number | 39 // Random bits for certificate serial number |
40 static const int SERIAL_RAND_BITS = 64; | 40 static const int SERIAL_RAND_BITS = 64; |
41 | 41 |
42 // Certificate validity lifetime | 42 // Certificate validity lifetime |
43 static const int CERTIFICATE_LIFETIME = 60*60*24*30; // 30 days, arbitrarily | 43 static const int CERTIFICATE_LIFETIME = 60*60*24*30; // 30 days, arbitrarily |
44 // Certificate validity window. | 44 // Certificate validity window. |
45 // This is to compensate for slightly incorrect system clocks. | 45 // This is to compensate for slightly incorrect system clocks. |
46 static const int CERTIFICATE_WINDOW = -60*60*24; | 46 static const int CERTIFICATE_WINDOW = -60*60*24; |
47 | 47 |
48 // Generate a key pair. Caller is responsible for freeing the returned object. | 48 // Generate a key pair. Caller is responsible for freeing the returned object. |
49 static EVP_PKEY* MakeKey() { | 49 static EVP_PKEY* MakeKey(KeyType key_type) { |
50 LOG(LS_INFO) << "Making key pair"; | 50 LOG(LS_INFO) << "Making key pair"; |
51 EVP_PKEY* pkey = EVP_PKEY_new(); | 51 EVP_PKEY* pkey = EVP_PKEY_new(); |
52 // RSA_generate_key is deprecated. Use _ex version. | 52 if (key_type == KT_RSA) { |
53 BIGNUM* exponent = BN_new(); | 53 BIGNUM* exponent = BN_new(); |
54 RSA* rsa = RSA_new(); | 54 RSA* rsa = RSA_new(); |
55 if (!pkey || !exponent || !rsa || | 55 if (!pkey || !exponent || !rsa || |
56 !BN_set_word(exponent, 0x10001) || // 65537 RSA exponent | 56 !BN_set_word(exponent, 0x10001) || // 65537 RSA exponent |
57 !RSA_generate_key_ex(rsa, KEY_LENGTH, exponent, NULL) || | 57 !RSA_generate_key_ex(rsa, KEY_LENGTH, exponent, NULL) || |
58 !EVP_PKEY_assign_RSA(pkey, rsa)) { | 58 !EVP_PKEY_assign_RSA(pkey, rsa)) { |
| 59 EVP_PKEY_free(pkey); |
| 60 BN_free(exponent); |
| 61 RSA_free(rsa); |
| 62 LOG(LS_ERROR) << "Failed to make RSA key pair"; |
| 63 return NULL; |
| 64 } |
| 65 // ownership of rsa struct was assigned, don't free it. |
| 66 BN_free(exponent); |
| 67 } else if (key_type == KT_ECDSA) { |
| 68 EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); |
| 69 if (!pkey || !ec_key || !EC_KEY_generate_key(ec_key) || |
| 70 !EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { |
| 71 EVP_PKEY_free(pkey); |
| 72 EC_KEY_free(ec_key); |
| 73 LOG(LS_ERROR) << "Failed to make EC key pair"; |
| 74 return NULL; |
| 75 } |
| 76 // ownership of ec_key struct was assigned, don't free it. |
| 77 } else { |
59 EVP_PKEY_free(pkey); | 78 EVP_PKEY_free(pkey); |
60 BN_free(exponent); | 79 LOG(LS_ERROR) << "Key type requested not understood"; |
61 RSA_free(rsa); | |
62 return NULL; | 80 return NULL; |
63 } | 81 } |
64 // ownership of rsa struct was assigned, don't free it. | 82 |
65 BN_free(exponent); | |
66 LOG(LS_INFO) << "Returning key pair"; | 83 LOG(LS_INFO) << "Returning key pair"; |
67 return pkey; | 84 return pkey; |
68 } | 85 } |
69 | 86 |
70 // Generate a self-signed certificate, with the public key from the | 87 // Generate a self-signed certificate, with the public key from the |
71 // given key pair. Caller is responsible for freeing the returned object. | 88 // given key pair. Caller is responsible for freeing the returned object. |
72 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { | 89 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { |
73 LOG(LS_INFO) << "Making certificate for " << params.common_name; | 90 LOG(LS_INFO) << "Making certificate for " << params.common_name; |
74 X509* x509 = NULL; | 91 X509* x509 = NULL; |
75 BIGNUM* serial_number = NULL; | 92 BIGNUM* serial_number = NULL; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 static void LogSSLErrors(const std::string& prefix) { | 148 static void LogSSLErrors(const std::string& prefix) { |
132 char error_buf[200]; | 149 char error_buf[200]; |
133 unsigned long err; | 150 unsigned long err; |
134 | 151 |
135 while ((err = ERR_get_error()) != 0) { | 152 while ((err = ERR_get_error()) != 0) { |
136 ERR_error_string_n(err, error_buf, sizeof(error_buf)); | 153 ERR_error_string_n(err, error_buf, sizeof(error_buf)); |
137 LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; | 154 LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; |
138 } | 155 } |
139 } | 156 } |
140 | 157 |
141 OpenSSLKeyPair* OpenSSLKeyPair::Generate() { | 158 OpenSSLKeyPair* OpenSSLKeyPair::Generate(KeyType key_type) { |
142 EVP_PKEY* pkey = MakeKey(); | 159 EVP_PKEY* pkey = MakeKey(key_type); |
143 if (!pkey) { | 160 if (!pkey) { |
144 LogSSLErrors("Generating key pair"); | 161 LogSSLErrors("Generating key pair"); |
145 return NULL; | 162 return NULL; |
146 } | 163 } |
147 return new OpenSSLKeyPair(pkey); | 164 return new OpenSSLKeyPair(pkey); |
148 } | 165 } |
149 | 166 |
150 OpenSSLKeyPair::~OpenSSLKeyPair() { | 167 OpenSSLKeyPair::~OpenSSLKeyPair() { |
151 EVP_PKEY_free(pkey_); | 168 EVP_PKEY_free(pkey_); |
152 } | 169 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 X509_free(x509); | 217 X509_free(x509); |
201 return ret; | 218 return ret; |
202 } | 219 } |
203 | 220 |
204 OpenSSLCertificate* OpenSSLCertificate::FromPEMString( | 221 OpenSSLCertificate* OpenSSLCertificate::FromPEMString( |
205 const std::string& pem_string) { | 222 const std::string& pem_string) { |
206 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); | 223 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); |
207 if (!bio) | 224 if (!bio) |
208 return NULL; | 225 return NULL; |
209 BIO_set_mem_eof_return(bio, 0); | 226 BIO_set_mem_eof_return(bio, 0); |
210 X509 *x509 = PEM_read_bio_X509(bio, NULL, NULL, | 227 X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, const_cast<char*>("\0")); |
211 const_cast<char*>("\0")); | |
212 BIO_free(bio); // Frees the BIO, but not the pointed-to string. | 228 BIO_free(bio); // Frees the BIO, but not the pointed-to string. |
213 | 229 |
214 if (!x509) | 230 if (!x509) |
215 return NULL; | 231 return NULL; |
216 | 232 |
217 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); | 233 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); |
218 X509_free(x509); | 234 X509_free(x509); |
219 return ret; | 235 return ret; |
220 } | 236 } |
221 | 237 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 size_t size, | 292 size_t size, |
277 size_t* length) const { | 293 size_t* length) const { |
278 return ComputeDigest(x509_, algorithm, digest, size, length); | 294 return ComputeDigest(x509_, algorithm, digest, size, length); |
279 } | 295 } |
280 | 296 |
281 bool OpenSSLCertificate::ComputeDigest(const X509* x509, | 297 bool OpenSSLCertificate::ComputeDigest(const X509* x509, |
282 const std::string& algorithm, | 298 const std::string& algorithm, |
283 unsigned char* digest, | 299 unsigned char* digest, |
284 size_t size, | 300 size_t size, |
285 size_t* length) { | 301 size_t* length) { |
286 const EVP_MD *md; | 302 const EVP_MD* md; |
287 unsigned int n; | 303 unsigned int n; |
288 | 304 |
289 if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) | 305 if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) |
290 return false; | 306 return false; |
291 | 307 |
292 if (size < static_cast<size_t>(EVP_MD_size(md))) | 308 if (size < static_cast<size_t>(EVP_MD_size(md))) |
293 return false; | 309 return false; |
294 | 310 |
295 X509_digest(x509, md, digest, &n); | 311 X509_digest(x509, md, digest, &n); |
296 | 312 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 OpenSSLCertificate* certificate) | 372 OpenSSLCertificate* certificate) |
357 : key_pair_(key_pair), certificate_(certificate) { | 373 : key_pair_(key_pair), certificate_(certificate) { |
358 ASSERT(key_pair != NULL); | 374 ASSERT(key_pair != NULL); |
359 ASSERT(certificate != NULL); | 375 ASSERT(certificate != NULL); |
360 } | 376 } |
361 | 377 |
362 OpenSSLIdentity::~OpenSSLIdentity() = default; | 378 OpenSSLIdentity::~OpenSSLIdentity() = default; |
363 | 379 |
364 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( | 380 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( |
365 const SSLIdentityParams& params) { | 381 const SSLIdentityParams& params) { |
366 OpenSSLKeyPair *key_pair = OpenSSLKeyPair::Generate(); | 382 OpenSSLKeyPair* key_pair = OpenSSLKeyPair::Generate(params.key_type); |
367 if (key_pair) { | 383 if (key_pair) { |
368 OpenSSLCertificate *certificate = OpenSSLCertificate::Generate( | 384 OpenSSLCertificate* certificate = |
369 key_pair, params); | 385 OpenSSLCertificate::Generate(key_pair, params); |
370 if (certificate) | 386 if (certificate) |
371 return new OpenSSLIdentity(key_pair, certificate); | 387 return new OpenSSLIdentity(key_pair, certificate); |
372 delete key_pair; | 388 delete key_pair; |
373 } | 389 } |
374 LOG(LS_INFO) << "Identity generation failed"; | 390 LOG(LS_INFO) << "Identity generation failed"; |
375 return NULL; | 391 return NULL; |
376 } | 392 } |
377 | 393 |
378 OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name) { | 394 OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name, |
| 395 KeyType key_type) { |
379 SSLIdentityParams params; | 396 SSLIdentityParams params; |
380 params.common_name = common_name; | 397 params.common_name = common_name; |
381 params.not_before = CERTIFICATE_WINDOW; | 398 params.not_before = CERTIFICATE_WINDOW; |
382 params.not_after = CERTIFICATE_LIFETIME; | 399 params.not_after = CERTIFICATE_LIFETIME; |
| 400 params.key_type = key_type; |
383 return GenerateInternal(params); | 401 return GenerateInternal(params); |
384 } | 402 } |
385 | 403 |
386 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( | 404 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( |
387 const SSLIdentityParams& params) { | 405 const SSLIdentityParams& params) { |
388 return GenerateInternal(params); | 406 return GenerateInternal(params); |
389 } | 407 } |
390 | 408 |
391 SSLIdentity* OpenSSLIdentity::FromPEMStrings( | 409 SSLIdentity* OpenSSLIdentity::FromPEMStrings( |
392 const std::string& private_key, | 410 const std::string& private_key, |
393 const std::string& certificate) { | 411 const std::string& certificate) { |
394 scoped_ptr<OpenSSLCertificate> cert( | 412 scoped_ptr<OpenSSLCertificate> cert( |
395 OpenSSLCertificate::FromPEMString(certificate)); | 413 OpenSSLCertificate::FromPEMString(certificate)); |
396 if (!cert) { | 414 if (!cert) { |
397 LOG(LS_ERROR) << "Failed to create OpenSSLCertificate from PEM string."; | 415 LOG(LS_ERROR) << "Failed to create OpenSSLCertificate from PEM string."; |
398 return NULL; | 416 return NULL; |
399 } | 417 } |
400 | 418 |
401 BIO* bio = BIO_new_mem_buf(const_cast<char*>(private_key.c_str()), -1); | 419 BIO* bio = BIO_new_mem_buf(const_cast<char*>(private_key.c_str()), -1); |
402 if (!bio) { | 420 if (!bio) { |
403 LOG(LS_ERROR) << "Failed to create a new BIO buffer."; | 421 LOG(LS_ERROR) << "Failed to create a new BIO buffer."; |
404 return NULL; | 422 return NULL; |
405 } | 423 } |
406 BIO_set_mem_eof_return(bio, 0); | 424 BIO_set_mem_eof_return(bio, 0); |
407 EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, | 425 EVP_PKEY* pkey = |
408 const_cast<char*>("\0")); | 426 PEM_read_bio_PrivateKey(bio, NULL, NULL, const_cast<char*>("\0")); |
409 BIO_free(bio); // Frees the BIO, but not the pointed-to string. | 427 BIO_free(bio); // Frees the BIO, but not the pointed-to string. |
410 | 428 |
411 if (!pkey) { | 429 if (!pkey) { |
412 LOG(LS_ERROR) << "Failed to create the private key from PEM string."; | 430 LOG(LS_ERROR) << "Failed to create the private key from PEM string."; |
413 return NULL; | 431 return NULL; |
414 } | 432 } |
415 | 433 |
416 return new OpenSSLIdentity(new OpenSSLKeyPair(pkey), | 434 return new OpenSSLIdentity(new OpenSSLKeyPair(pkey), |
417 cert.release()); | 435 cert.release()); |
418 } | 436 } |
(...skipping 13 matching lines...) Expand all Loading... |
432 SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) { | 450 SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) { |
433 LogSSLErrors("Configuring key and certificate"); | 451 LogSSLErrors("Configuring key and certificate"); |
434 return false; | 452 return false; |
435 } | 453 } |
436 return true; | 454 return true; |
437 } | 455 } |
438 | 456 |
439 } // namespace rtc | 457 } // namespace rtc |
440 | 458 |
441 #endif // HAVE_OPENSSL_SSL_H | 459 #endif // HAVE_OPENSSL_SSL_H |
OLD | NEW |