| 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 |