Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: webrtc/base/opensslidentity.cc

Issue 1189583002: Support generation of EC keys using P256 curve and support ECDSA certs. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase, glue to hbos's changes Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/opensslidentity.h ('k') | webrtc/base/opensslstreamadapter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/base/opensslidentity.h ('k') | webrtc/base/opensslstreamadapter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698