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

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: Created 5 years, 6 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
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 } 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
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
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
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
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
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

Powered by Google App Engine
This is Rietveld 408576698