Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      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
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #if HAVE_OPENSSL_SSL_H
     12 
     13 #include "webrtc/base/opensslidentity.h"
     14 
     15 // Must be included first before openssl headers.
     16 #include "webrtc/base/win32.h"  // NOLINT
     17 
     18 #include <openssl/bio.h>
     19 #include <openssl/err.h>
     20 #include <openssl/pem.h>
     21 #include <openssl/bn.h>
     22 #include <openssl/rsa.h>
     23 #include <openssl/crypto.h>
     24 
     25 #include "webrtc/base/checks.h"
     26 #include "webrtc/base/helpers.h"
     27 #include "webrtc/base/logging.h"
     28 #include "webrtc/base/openssl.h"
     29 #include "webrtc/base/openssldigest.h"
     30 
     31 namespace rtc {
     32 
     33 // We could have exposed a myriad of parameters for the crypto stuff,
     34 // but keeping it simple seems best.
     35 
     36 // Random bits for certificate serial number
     37 static const int SERIAL_RAND_BITS = 64;
     38 
     39 // Certificate validity lifetime
     40 static const int CERTIFICATE_LIFETIME = 60*60*24*30;  // 30 days, arbitrarily
     41 // Certificate validity window.
     42 // This is to compensate for slightly incorrect system clocks.
     43 static const int CERTIFICATE_WINDOW = -60*60*24;
     44 
     45 // Generate a key pair. Caller is responsible for freeing the returned object.
     46 static EVP_PKEY* MakeKey(const KeyParams& key_params) {
     47   LOG(LS_INFO) << "Making key pair";
     48   EVP_PKEY* pkey = EVP_PKEY_new();
     49   if (key_params.type() == KT_RSA) {
     50     int key_length = key_params.rsa_params().mod_size;
     51     BIGNUM* exponent = BN_new();
     52     RSA* rsa = RSA_new();
     53     if (!pkey || !exponent || !rsa ||
     54         !BN_set_word(exponent, key_params.rsa_params().pub_exp) ||
     55         !RSA_generate_key_ex(rsa, key_length, exponent, NULL) ||
     56         !EVP_PKEY_assign_RSA(pkey, rsa)) {
     57       EVP_PKEY_free(pkey);
     58       BN_free(exponent);
     59       RSA_free(rsa);
     60       LOG(LS_ERROR) << "Failed to make RSA key pair";
     61       return NULL;
     62     }
     63     // ownership of rsa struct was assigned, don't free it.
     64     BN_free(exponent);
     65   } else if (key_params.type() == KT_ECDSA) {
     66     if (key_params.ec_curve() == EC_NIST_P256) {
     67       EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
     68       if (!pkey || !ec_key || !EC_KEY_generate_key(ec_key) ||
     69           !EVP_PKEY_assign_EC_KEY(pkey, ec_key)) {
     70         EVP_PKEY_free(pkey);
     71         EC_KEY_free(ec_key);
     72         LOG(LS_ERROR) << "Failed to make EC key pair";
     73         return NULL;
     74       }
     75       // ownership of ec_key struct was assigned, don't free it.
     76     } else {
     77       // Add generation of any other curves here.
     78       EVP_PKEY_free(pkey);
     79       LOG(LS_ERROR) << "ECDSA key requested for unknown curve";
     80       return NULL;
     81     }
     82   } else {
     83     EVP_PKEY_free(pkey);
     84     LOG(LS_ERROR) << "Key type requested not understood";
     85     return NULL;
     86   }
     87 
     88   LOG(LS_INFO) << "Returning key pair";
     89   return pkey;
     90 }
     91 
     92 // Generate a self-signed certificate, with the public key from the
     93 // given key pair. Caller is responsible for freeing the returned object.
     94 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) {
     95   LOG(LS_INFO) << "Making certificate for " << params.common_name;
     96   X509* x509 = NULL;
     97   BIGNUM* serial_number = NULL;
     98   X509_NAME* name = NULL;
     99   time_t epoch_off = 0;  // Time offset since epoch.
    100 
    101   if ((x509=X509_new()) == NULL)
    102     goto error;
    103 
    104   if (!X509_set_pubkey(x509, pkey))
    105     goto error;
    106 
    107   // serial number
    108   // temporary reference to serial number inside x509 struct
    109   ASN1_INTEGER* asn1_serial_number;
    110   if ((serial_number = BN_new()) == NULL ||
    111       !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) ||
    112       (asn1_serial_number = X509_get_serialNumber(x509)) == NULL ||
    113       !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number))
    114     goto error;
    115 
    116   if (!X509_set_version(x509, 0L))  // version 1
    117     goto error;
    118 
    119   // There are a lot of possible components for the name entries. In
    120   // our P2P SSL mode however, the certificates are pre-exchanged
    121   // (through the secure XMPP channel), and so the certificate
    122   // identification is arbitrary. It can't be empty, so we set some
    123   // arbitrary common_name. Note that this certificate goes out in
    124   // clear during SSL negotiation, so there may be a privacy issue in
    125   // putting anything recognizable here.
    126   if ((name = X509_NAME_new()) == NULL ||
    127       !X509_NAME_add_entry_by_NID(
    128           name, NID_commonName, MBSTRING_UTF8,
    129           (unsigned char*)params.common_name.c_str(), -1, -1, 0) ||
    130       !X509_set_subject_name(x509, name) ||
    131       !X509_set_issuer_name(x509, name))
    132     goto error;
    133 
    134   if (!X509_time_adj(X509_get_notBefore(x509), params.not_before, &epoch_off) ||
    135       !X509_time_adj(X509_get_notAfter(x509), params.not_after, &epoch_off))
    136     goto error;
    137 
    138   if (!X509_sign(x509, pkey, EVP_sha256()))
    139     goto error;
    140 
    141   BN_free(serial_number);
    142   X509_NAME_free(name);
    143   LOG(LS_INFO) << "Returning certificate";
    144   return x509;
    145 
    146  error:
    147   BN_free(serial_number);
    148   X509_NAME_free(name);
    149   X509_free(x509);
    150   return NULL;
    151 }
    152 
    153 // This dumps the SSL error stack to the log.
    154 static void LogSSLErrors(const std::string& prefix) {
    155   char error_buf[200];
    156   unsigned long err;
    157 
    158   while ((err = ERR_get_error()) != 0) {
    159     ERR_error_string_n(err, error_buf, sizeof(error_buf));
    160     LOG(LS_ERROR) << prefix << ": " << error_buf << "\n";
    161   }
    162 }
    163 
    164 OpenSSLKeyPair* OpenSSLKeyPair::Generate(const KeyParams& key_params) {
    165   EVP_PKEY* pkey = MakeKey(key_params);
    166   if (!pkey) {
    167     LogSSLErrors("Generating key pair");
    168     return NULL;
    169   }
    170   return new OpenSSLKeyPair(pkey);
    171 }
    172 
    173 OpenSSLKeyPair::~OpenSSLKeyPair() {
    174   EVP_PKEY_free(pkey_);
    175 }
    176 
    177 OpenSSLKeyPair* OpenSSLKeyPair::GetReference() {
    178   AddReference();
    179   return new OpenSSLKeyPair(pkey_);
    180 }
    181 
    182 void OpenSSLKeyPair::AddReference() {
    183 #if defined(OPENSSL_IS_BORINGSSL)
    184   EVP_PKEY_up_ref(pkey_);
    185 #else
    186   CRYPTO_add(&pkey_->references, 1, CRYPTO_LOCK_EVP_PKEY);
    187 #endif
    188 }
    189 
    190 #if !defined(NDEBUG)
    191 // Print a certificate to the log, for debugging.
    192 static void PrintCert(X509* x509) {
    193   BIO* temp_memory_bio = BIO_new(BIO_s_mem());
    194   if (!temp_memory_bio) {
    195     LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio";
    196     return;
    197   }
    198   X509_print_ex(temp_memory_bio, x509, XN_FLAG_SEP_CPLUS_SPC, 0);
    199   BIO_write(temp_memory_bio, "\0", 1);
    200   char* buffer;
    201   BIO_get_mem_data(temp_memory_bio, &buffer);
    202   LOG(LS_VERBOSE) << buffer;
    203   BIO_free(temp_memory_bio);
    204 }
    205 #endif
    206 
    207 OpenSSLCertificate* OpenSSLCertificate::Generate(
    208     OpenSSLKeyPair* key_pair, const SSLIdentityParams& params) {
    209   SSLIdentityParams actual_params(params);
    210   if (actual_params.common_name.empty()) {
    211     // Use a random string, arbitrarily 8chars long.
    212     actual_params.common_name = CreateRandomString(8);
    213   }
    214   X509* x509 = MakeCertificate(key_pair->pkey(), actual_params);
    215   if (!x509) {
    216     LogSSLErrors("Generating certificate");
    217     return NULL;
    218   }
    219 #if !defined(NDEBUG)
    220   PrintCert(x509);
    221 #endif
    222   OpenSSLCertificate* ret = new OpenSSLCertificate(x509);
    223   X509_free(x509);
    224   return ret;
    225 }
    226 
    227 OpenSSLCertificate* OpenSSLCertificate::FromPEMString(
    228     const std::string& pem_string) {
    229   BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1);
    230   if (!bio)
    231     return NULL;
    232   BIO_set_mem_eof_return(bio, 0);
    233   X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, const_cast<char*>("\0"));
    234   BIO_free(bio);  // Frees the BIO, but not the pointed-to string.
    235 
    236   if (!x509)
    237     return NULL;
    238 
    239   OpenSSLCertificate* ret = new OpenSSLCertificate(x509);
    240   X509_free(x509);
    241   return ret;
    242 }
    243 
    244 // NOTE: This implementation only functions correctly after InitializeSSL
    245 // and before CleanupSSL.
    246 bool OpenSSLCertificate::GetSignatureDigestAlgorithm(
    247     std::string* algorithm) const {
    248   int nid = OBJ_obj2nid(x509_->sig_alg->algorithm);
    249   switch (nid) {
    250     case NID_md5WithRSA:
    251     case NID_md5WithRSAEncryption:
    252       *algorithm = DIGEST_MD5;
    253       break;
    254     case NID_ecdsa_with_SHA1:
    255     case NID_dsaWithSHA1:
    256     case NID_dsaWithSHA1_2:
    257     case NID_sha1WithRSA:
    258     case NID_sha1WithRSAEncryption:
    259       *algorithm = DIGEST_SHA_1;
    260       break;
    261     case NID_ecdsa_with_SHA224:
    262     case NID_sha224WithRSAEncryption:
    263     case NID_dsa_with_SHA224:
    264       *algorithm = DIGEST_SHA_224;
    265       break;
    266     case NID_ecdsa_with_SHA256:
    267     case NID_sha256WithRSAEncryption:
    268     case NID_dsa_with_SHA256:
    269       *algorithm = DIGEST_SHA_256;
    270       break;
    271     case NID_ecdsa_with_SHA384:
    272     case NID_sha384WithRSAEncryption:
    273       *algorithm = DIGEST_SHA_384;
    274       break;
    275     case NID_ecdsa_with_SHA512:
    276     case NID_sha512WithRSAEncryption:
    277       *algorithm = DIGEST_SHA_512;
    278       break;
    279     default:
    280       // Unknown algorithm.  There are several unhandled options that are less
    281       // common and more complex.
    282       LOG(LS_ERROR) << "Unknown signature algorithm NID: " << nid;
    283       algorithm->clear();
    284       return false;
    285   }
    286   return true;
    287 }
    288 
    289 bool OpenSSLCertificate::GetChain(SSLCertChain** chain) const {
    290   // Chains are not yet supported when using OpenSSL.
    291   // OpenSSLStreamAdapter::SSLVerifyCallback currently requires the remote
    292   // certificate to be self-signed.
    293   return false;
    294 }
    295 
    296 bool OpenSSLCertificate::ComputeDigest(const std::string& algorithm,
    297                                        unsigned char* digest,
    298                                        size_t size,
    299                                        size_t* length) const {
    300   return ComputeDigest(x509_, algorithm, digest, size, length);
    301 }
    302 
    303 bool OpenSSLCertificate::ComputeDigest(const X509* x509,
    304                                        const std::string& algorithm,
    305                                        unsigned char* digest,
    306                                        size_t size,
    307                                        size_t* length) {
    308   const EVP_MD* md;
    309   unsigned int n;
    310 
    311   if (!OpenSSLDigest::GetDigestEVP(algorithm, &md))
    312     return false;
    313 
    314   if (size < static_cast<size_t>(EVP_MD_size(md)))
    315     return false;
    316 
    317   X509_digest(x509, md, digest, &n);
    318 
    319   *length = n;
    320 
    321   return true;
    322 }
    323 
    324 OpenSSLCertificate::~OpenSSLCertificate() {
    325   X509_free(x509_);
    326 }
    327 
    328 OpenSSLCertificate* OpenSSLCertificate::GetReference() const {
    329   return new OpenSSLCertificate(x509_);
    330 }
    331 
    332 std::string OpenSSLCertificate::ToPEMString() const {
    333   BIO* bio = BIO_new(BIO_s_mem());
    334   if (!bio) {
    335     FATAL() << "unreachable code";
    336   }
    337   if (!PEM_write_bio_X509(bio, x509_)) {
    338     BIO_free(bio);
    339     FATAL() << "unreachable code";
    340   }
    341   BIO_write(bio, "\0", 1);
    342   char* buffer;
    343   BIO_get_mem_data(bio, &buffer);
    344   std::string ret(buffer);
    345   BIO_free(bio);
    346   return ret;
    347 }
    348 
    349 void OpenSSLCertificate::ToDER(Buffer* der_buffer) const {
    350   // In case of failure, make sure to leave the buffer empty.
    351   der_buffer->SetSize(0);
    352 
    353   // Calculates the DER representation of the certificate, from scratch.
    354   BIO* bio = BIO_new(BIO_s_mem());
    355   if (!bio) {
    356     FATAL() << "unreachable code";
    357   }
    358   if (!i2d_X509_bio(bio, x509_)) {
    359     BIO_free(bio);
    360     FATAL() << "unreachable code";
    361   }
    362   char* data;
    363   size_t length = BIO_get_mem_data(bio, &data);
    364   der_buffer->SetData(data, length);
    365   BIO_free(bio);
    366 }
    367 
    368 void OpenSSLCertificate::AddReference() const {
    369   ASSERT(x509_ != NULL);
    370 #if defined(OPENSSL_IS_BORINGSSL)
    371   X509_up_ref(x509_);
    372 #else
    373   CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509);
    374 #endif
    375 }
    376 
    377 // Documented in sslidentity.h.
    378 int64_t OpenSSLCertificate::CertificateExpirationTime() const {
    379   ASN1_TIME* expire_time = X509_get_notAfter(x509_);
    380   bool long_format;
    381 
    382   if (expire_time->type == V_ASN1_UTCTIME) {
    383     long_format = false;
    384   } else if (expire_time->type == V_ASN1_GENERALIZEDTIME) {
    385     long_format = true;
    386   } else {
    387     return -1;
    388   }
    389 
    390   return ASN1TimeToSec(expire_time->data, expire_time->length, long_format);
    391 }
    392 
    393 OpenSSLIdentity::OpenSSLIdentity(OpenSSLKeyPair* key_pair,
    394                                  OpenSSLCertificate* certificate)
    395     : key_pair_(key_pair), certificate_(certificate) {
    396   ASSERT(key_pair != NULL);
    397   ASSERT(certificate != NULL);
    398 }
    399 
    400 OpenSSLIdentity::~OpenSSLIdentity() = default;
    401 
    402 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal(
    403     const SSLIdentityParams& params) {
    404   OpenSSLKeyPair* key_pair = OpenSSLKeyPair::Generate(params.key_params);
    405   if (key_pair) {
    406     OpenSSLCertificate* certificate =
    407         OpenSSLCertificate::Generate(key_pair, params);
    408     if (certificate)
    409       return new OpenSSLIdentity(key_pair, certificate);
    410     delete key_pair;
    411   }
    412   LOG(LS_INFO) << "Identity generation failed";
    413   return NULL;
    414 }
    415 
    416 OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name,
    417                                            const KeyParams& key_params) {
    418   SSLIdentityParams params;
    419   params.key_params = key_params;
    420   params.common_name = common_name;
    421   time_t now = time(NULL);
    422   params.not_before = now + CERTIFICATE_WINDOW;
    423   params.not_after = now + CERTIFICATE_LIFETIME;
    424   return GenerateInternal(params);
    425 }
    426 
    427 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest(
    428     const SSLIdentityParams& params) {
    429   return GenerateInternal(params);
    430 }
    431 
    432 SSLIdentity* OpenSSLIdentity::FromPEMStrings(
    433     const std::string& private_key,
    434     const std::string& certificate) {
    435   scoped_ptr<OpenSSLCertificate> cert(
    436       OpenSSLCertificate::FromPEMString(certificate));
    437   if (!cert) {
    438     LOG(LS_ERROR) << "Failed to create OpenSSLCertificate from PEM string.";
    439     return NULL;
    440   }
    441 
    442   BIO* bio = BIO_new_mem_buf(const_cast<char*>(private_key.c_str()), -1);
    443   if (!bio) {
    444     LOG(LS_ERROR) << "Failed to create a new BIO buffer.";
    445     return NULL;
    446   }
    447   BIO_set_mem_eof_return(bio, 0);
    448   EVP_PKEY* pkey =
    449       PEM_read_bio_PrivateKey(bio, NULL, NULL, const_cast<char*>("\0"));
    450   BIO_free(bio);  // Frees the BIO, but not the pointed-to string.
    451 
    452   if (!pkey) {
    453     LOG(LS_ERROR) << "Failed to create the private key from PEM string.";
    454     return NULL;
    455   }
    456 
    457   return new OpenSSLIdentity(new OpenSSLKeyPair(pkey),
    458                              cert.release());
    459 }
    460 
    461 const OpenSSLCertificate& OpenSSLIdentity::certificate() const {
    462   return *certificate_;
    463 }
    464 
    465 OpenSSLIdentity* OpenSSLIdentity::GetReference() const {
    466   return new OpenSSLIdentity(key_pair_->GetReference(),
    467                              certificate_->GetReference());
    468 }
    469 
    470 bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) {
    471   // 1 is the documented success return code.
    472   if (SSL_CTX_use_certificate(ctx, certificate_->x509()) != 1 ||
    473      SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) {
    474     LogSSLErrors("Configuring key and certificate");
    475     return false;
    476   }
    477   return true;
    478 }
    479 
    480 }  // namespace rtc
    481 
    482 #endif  // HAVE_OPENSSL_SSL_H
    483