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 } else { | |
59 EVP_PKEY_free(pkey); | 77 EVP_PKEY_free(pkey); |
60 BN_free(exponent); | 78 LOG(LS_ERROR) << "Key type requested not understood"; |
tommi
2015/06/15 21:02:42
[D]CHECK instead?
torbjorng (webrtc)
2015/06/16 14:11:51
Caller needs handle this, making no change.
| |
61 RSA_free(rsa); | |
62 return NULL; | 79 return NULL; |
63 } | 80 } |
64 // ownership of rsa struct was assigned, don't free it. | 81 |
65 BN_free(exponent); | |
66 LOG(LS_INFO) << "Returning key pair"; | 82 LOG(LS_INFO) << "Returning key pair"; |
67 return pkey; | 83 return pkey; |
68 } | 84 } |
69 | 85 |
70 // Generate a self-signed certificate, with the public key from the | 86 // Generate a self-signed certificate, with the public key from the |
71 // given key pair. Caller is responsible for freeing the returned object. | 87 // given key pair. Caller is responsible for freeing the returned object. |
72 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { | 88 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { |
73 LOG(LS_INFO) << "Making certificate for " << params.common_name; | 89 LOG(LS_INFO) << "Making certificate for " << params.common_name; |
74 X509* x509 = NULL; | 90 X509* x509 = NULL; |
75 BIGNUM* serial_number = NULL; | 91 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) { | 147 static void LogSSLErrors(const std::string& prefix) { |
132 char error_buf[200]; | 148 char error_buf[200]; |
133 unsigned long err; | 149 unsigned long err; |
134 | 150 |
135 while ((err = ERR_get_error()) != 0) { | 151 while ((err = ERR_get_error()) != 0) { |
136 ERR_error_string_n(err, error_buf, sizeof(error_buf)); | 152 ERR_error_string_n(err, error_buf, sizeof(error_buf)); |
137 LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; | 153 LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; |
138 } | 154 } |
139 } | 155 } |
140 | 156 |
141 OpenSSLKeyPair* OpenSSLKeyPair::Generate() { | 157 OpenSSLKeyPair* OpenSSLKeyPair::Generate(KeyType key_type) { |
142 EVP_PKEY* pkey = MakeKey(); | 158 EVP_PKEY* pkey = MakeKey(key_type); |
143 if (!pkey) { | 159 if (!pkey) { |
144 LogSSLErrors("Generating key pair"); | 160 LogSSLErrors("Generating key pair"); |
145 return NULL; | 161 return NULL; |
146 } | 162 } |
147 return new OpenSSLKeyPair(pkey); | 163 return new OpenSSLKeyPair(pkey); |
148 } | 164 } |
149 | 165 |
150 OpenSSLKeyPair::~OpenSSLKeyPair() { | 166 OpenSSLKeyPair::~OpenSSLKeyPair() { |
151 EVP_PKEY_free(pkey_); | 167 EVP_PKEY_free(pkey_); |
152 } | 168 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
200 X509_free(x509); | 216 X509_free(x509); |
201 return ret; | 217 return ret; |
202 } | 218 } |
203 | 219 |
204 OpenSSLCertificate* OpenSSLCertificate::FromPEMString( | 220 OpenSSLCertificate* OpenSSLCertificate::FromPEMString( |
205 const std::string& pem_string) { | 221 const std::string& pem_string) { |
206 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); | 222 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); |
207 if (!bio) | 223 if (!bio) |
208 return NULL; | 224 return NULL; |
209 BIO_set_mem_eof_return(bio, 0); | 225 BIO_set_mem_eof_return(bio, 0); |
210 X509 *x509 = PEM_read_bio_X509(bio, NULL, NULL, | 226 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. | 227 BIO_free(bio); // Frees the BIO, but not the pointed-to string. |
213 | 228 |
214 if (!x509) | 229 if (!x509) |
215 return NULL; | 230 return NULL; |
216 | 231 |
217 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); | 232 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); |
218 X509_free(x509); | 233 X509_free(x509); |
219 return ret; | 234 return ret; |
220 } | 235 } |
221 | 236 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 size_t size, | 291 size_t size, |
277 size_t* length) const { | 292 size_t* length) const { |
278 return ComputeDigest(x509_, algorithm, digest, size, length); | 293 return ComputeDigest(x509_, algorithm, digest, size, length); |
279 } | 294 } |
280 | 295 |
281 bool OpenSSLCertificate::ComputeDigest(const X509* x509, | 296 bool OpenSSLCertificate::ComputeDigest(const X509* x509, |
282 const std::string& algorithm, | 297 const std::string& algorithm, |
283 unsigned char* digest, | 298 unsigned char* digest, |
284 size_t size, | 299 size_t size, |
285 size_t* length) { | 300 size_t* length) { |
286 const EVP_MD *md; | 301 const EVP_MD* md; |
287 unsigned int n; | 302 unsigned int n; |
288 | 303 |
289 if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) | 304 if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) |
290 return false; | 305 return false; |
291 | 306 |
292 if (size < static_cast<size_t>(EVP_MD_size(md))) | 307 if (size < static_cast<size_t>(EVP_MD_size(md))) |
293 return false; | 308 return false; |
294 | 309 |
295 X509_digest(x509, md, digest, &n); | 310 X509_digest(x509, md, digest, &n); |
296 | 311 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 OpenSSLIdentity::OpenSSLIdentity(OpenSSLKeyPair* key_pair, | 370 OpenSSLIdentity::OpenSSLIdentity(OpenSSLKeyPair* key_pair, |
356 OpenSSLCertificate* certificate) | 371 OpenSSLCertificate* certificate) |
357 : key_pair_(key_pair), certificate_(certificate) { | 372 : key_pair_(key_pair), certificate_(certificate) { |
358 ASSERT(key_pair != NULL); | 373 ASSERT(key_pair != NULL); |
359 ASSERT(certificate != NULL); | 374 ASSERT(certificate != NULL); |
360 } | 375 } |
361 | 376 |
362 OpenSSLIdentity::~OpenSSLIdentity() = default; | 377 OpenSSLIdentity::~OpenSSLIdentity() = default; |
363 | 378 |
364 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( | 379 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( |
365 const SSLIdentityParams& params) { | 380 const SSLIdentityParams& params, |
366 OpenSSLKeyPair *key_pair = OpenSSLKeyPair::Generate(); | 381 KeyType key_type) { |
382 OpenSSLKeyPair* key_pair = OpenSSLKeyPair::Generate(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; |
383 return GenerateInternal(params); | 400 return GenerateInternal(params, key_type); |
384 } | 401 } |
385 | 402 |
386 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( | 403 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( |
387 const SSLIdentityParams& params) { | 404 const SSLIdentityParams& params, |
388 return GenerateInternal(params); | 405 KeyType key_type) { |
406 return GenerateInternal(params, key_type); | |
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 |