1 /* 2 * libjingle 3 * Copyright 2004--2008, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #if HAVE_OPENSSL_SSL_H 29 30 #include "talk/base/opensslidentity.h" 31 32 // Must be included first before openssl headers. 33 #include "talk/base/win32.h" // NOLINT 34 35 #include <openssl/bio.h> 36 #include <openssl/err.h> 37 #include <openssl/pem.h> 38 #include <openssl/bn.h> 39 #include <openssl/rsa.h> 40 #include <openssl/crypto.h> 41 42 #include "talk/base/checks.h" 43 #include "talk/base/helpers.h" 44 #include "talk/base/logging.h" 45 #include "talk/base/openssl.h" 46 #include "talk/base/openssldigest.h" 47 48 namespace talk_base { 49 50 // We could have exposed a myriad of parameters for the crypto stuff, 51 // but keeping it simple seems best. 52 53 // Strength of generated keys. Those are RSA. 54 static const int KEY_LENGTH = 1024; 55 56 // Random bits for certificate serial number 57 static const int SERIAL_RAND_BITS = 64; 58 59 // Certificate validity lifetime 60 static const int CERTIFICATE_LIFETIME = 60*60*24*30; // 30 days, arbitrarily 61 // Certificate validity window. 62 // This is to compensate for slightly incorrect system clocks. 63 static const int CERTIFICATE_WINDOW = -60*60*24; 64 65 // Generate a key pair. Caller is responsible for freeing the returned object. 66 static EVP_PKEY* MakeKey() { 67 LOG(LS_INFO) << "Making key pair"; 68 EVP_PKEY* pkey = EVP_PKEY_new(); 69 // RSA_generate_key is deprecated. Use _ex version. 70 BIGNUM* exponent = BN_new(); 71 RSA* rsa = RSA_new(); 72 if (!pkey || !exponent || !rsa || 73 !BN_set_word(exponent, 0x10001) || // 65537 RSA exponent 74 !RSA_generate_key_ex(rsa, KEY_LENGTH, exponent, NULL) || 75 !EVP_PKEY_assign_RSA(pkey, rsa)) { 76 EVP_PKEY_free(pkey); 77 BN_free(exponent); 78 RSA_free(rsa); 79 return NULL; 80 } 81 // ownership of rsa struct was assigned, don't free it. 82 BN_free(exponent); 83 LOG(LS_INFO) << "Returning key pair"; 84 return pkey; 85 } 86 87 // Generate a self-signed certificate, with the public key from the 88 // given key pair. Caller is responsible for freeing the returned object. 89 static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { 90 LOG(LS_INFO) << "Making certificate for " << params.common_name; 91 X509* x509 = NULL; 92 BIGNUM* serial_number = NULL; 93 X509_NAME* name = NULL; 94 95 if ((x509=X509_new()) == NULL) 96 goto error; 97 98 if (!X509_set_pubkey(x509, pkey)) 99 goto error; 100 101 // serial number 102 // temporary reference to serial number inside x509 struct 103 ASN1_INTEGER* asn1_serial_number; 104 if ((serial_number = BN_new()) == NULL || 105 !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) || 106 (asn1_serial_number = X509_get_serialNumber(x509)) == NULL || 107 !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number)) 108 goto error; 109 110 if (!X509_set_version(x509, 0L)) // version 1 111 goto error; 112 113 // There are a lot of possible components for the name entries. In 114 // our P2P SSL mode however, the certificates are pre-exchanged 115 // (through the secure XMPP channel), and so the certificate 116 // identification is arbitrary. It can't be empty, so we set some 117 // arbitrary common_name. Note that this certificate goes out in 118 // clear during SSL negotiation, so there may be a privacy issue in 119 // putting anything recognizable here. 120 if ((name = X509_NAME_new()) == NULL || 121 !X509_NAME_add_entry_by_NID( 122 name, NID_commonName, MBSTRING_UTF8, 123 (unsigned char*)params.common_name.c_str(), -1, -1, 0) || 124 !X509_set_subject_name(x509, name) || 125 !X509_set_issuer_name(x509, name)) 126 goto error; 127 128 if (!X509_gmtime_adj(X509_get_notBefore(x509), params.not_before) || 129 !X509_gmtime_adj(X509_get_notAfter(x509), params.not_after)) 130 goto error; 131 132 if (!X509_sign(x509, pkey, EVP_sha1())) 133 goto error; 134 135 BN_free(serial_number); 136 X509_NAME_free(name); 137 LOG(LS_INFO) << "Returning certificate"; 138 return x509; 139 140 error: 141 BN_free(serial_number); 142 X509_NAME_free(name); 143 X509_free(x509); 144 return NULL; 145 } 146 147 // This dumps the SSL error stack to the log. 148 static void LogSSLErrors(const std::string& prefix) { 149 char error_buf[200]; 150 unsigned long err; 151 152 while ((err = ERR_get_error()) != 0) { 153 ERR_error_string_n(err, error_buf, sizeof(error_buf)); 154 LOG(LS_ERROR) << prefix << ": " << error_buf << "\n"; 155 } 156 } 157 158 OpenSSLKeyPair* OpenSSLKeyPair::Generate() { 159 EVP_PKEY* pkey = MakeKey(); 160 if (!pkey) { 161 LogSSLErrors("Generating key pair"); 162 return NULL; 163 } 164 return new OpenSSLKeyPair(pkey); 165 } 166 167 OpenSSLKeyPair::~OpenSSLKeyPair() { 168 EVP_PKEY_free(pkey_); 169 } 170 171 void OpenSSLKeyPair::AddReference() { 172 CRYPTO_add(&pkey_->references, 1, CRYPTO_LOCK_EVP_PKEY); 173 } 174 175 #ifdef _DEBUG 176 // Print a certificate to the log, for debugging. 177 static void PrintCert(X509* x509) { 178 BIO* temp_memory_bio = BIO_new(BIO_s_mem()); 179 if (!temp_memory_bio) { 180 LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio"; 181 return; 182 } 183 X509_print_ex(temp_memory_bio, x509, XN_FLAG_SEP_CPLUS_SPC, 0); 184 BIO_write(temp_memory_bio, "\0", 1); 185 char* buffer; 186 BIO_get_mem_data(temp_memory_bio, &buffer); 187 LOG(LS_VERBOSE) << buffer; 188 BIO_free(temp_memory_bio); 189 } 190 #endif 191 192 OpenSSLCertificate* OpenSSLCertificate::Generate( 193 OpenSSLKeyPair* key_pair, const SSLIdentityParams& params) { 194 SSLIdentityParams actual_params(params); 195 if (actual_params.common_name.empty()) { 196 // Use a random string, arbitrarily 8chars long. 197 actual_params.common_name = CreateRandomString(8); 198 } 199 X509* x509 = MakeCertificate(key_pair->pkey(), actual_params); 200 if (!x509) { 201 LogSSLErrors("Generating certificate"); 202 return NULL; 203 } 204 #ifdef _DEBUG 205 PrintCert(x509); 206 #endif 207 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); 208 X509_free(x509); 209 return ret; 210 } 211 212 OpenSSLCertificate* OpenSSLCertificate::FromPEMString( 213 const std::string& pem_string) { 214 BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1); 215 if (!bio) 216 return NULL; 217 BIO_set_mem_eof_return(bio, 0); 218 X509 *x509 = PEM_read_bio_X509(bio, NULL, NULL, 219 const_cast<char*>("\0")); 220 BIO_free(bio); // Frees the BIO, but not the pointed-to string. 221 222 if (!x509) 223 return NULL; 224 225 OpenSSLCertificate* ret = new OpenSSLCertificate(x509); 226 X509_free(x509); 227 return ret; 228 } 229 230 // NOTE: This implementation only functions correctly after InitializeSSL 231 // and before CleanupSSL. 232 bool OpenSSLCertificate::GetSignatureDigestAlgorithm( 233 std::string* algorithm) const { 234 return OpenSSLDigest::GetDigestName( 235 EVP_get_digestbyobj(x509_->sig_alg->algorithm), algorithm); 236 } 237 238 bool OpenSSLCertificate::ComputeDigest(const std::string& algorithm, 239 unsigned char* digest, 240 size_t size, 241 size_t* length) const { 242 return ComputeDigest(x509_, algorithm, digest, size, length); 243 } 244 245 bool OpenSSLCertificate::ComputeDigest(const X509* x509, 246 const std::string& algorithm, 247 unsigned char* digest, 248 size_t size, 249 size_t* length) { 250 const EVP_MD *md; 251 unsigned int n; 252 253 if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) 254 return false; 255 256 if (size < static_cast<size_t>(EVP_MD_size(md))) 257 return false; 258 259 X509_digest(x509, md, digest, &n); 260 261 *length = n; 262 263 return true; 264 } 265 266 OpenSSLCertificate::~OpenSSLCertificate() { 267 X509_free(x509_); 268 } 269 270 std::string OpenSSLCertificate::ToPEMString() const { 271 BIO* bio = BIO_new(BIO_s_mem()); 272 if (!bio) { 273 UNREACHABLE(); 274 return std::string(); 275 } 276 if (!PEM_write_bio_X509(bio, x509_)) { 277 BIO_free(bio); 278 UNREACHABLE(); 279 return std::string(); 280 } 281 BIO_write(bio, "\0", 1); 282 char* buffer; 283 BIO_get_mem_data(bio, &buffer); 284 std::string ret(buffer); 285 BIO_free(bio); 286 return ret; 287 } 288 289 void OpenSSLCertificate::ToDER(Buffer* der_buffer) const { 290 // In case of failure, make sure to leave the buffer empty. 291 der_buffer->SetData(NULL, 0); 292 293 // Calculates the DER representation of the certificate, from scratch. 294 BIO* bio = BIO_new(BIO_s_mem()); 295 if (!bio) { 296 UNREACHABLE(); 297 return; 298 } 299 if (!i2d_X509_bio(bio, x509_)) { 300 BIO_free(bio); 301 UNREACHABLE(); 302 return; 303 } 304 char* data; 305 size_t length = BIO_get_mem_data(bio, &data); 306 der_buffer->SetData(data, length); 307 BIO_free(bio); 308 } 309 310 void OpenSSLCertificate::AddReference() const { 311 ASSERT(x509_ != NULL); 312 CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509); 313 } 314 315 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( 316 const SSLIdentityParams& params) { 317 OpenSSLKeyPair *key_pair = OpenSSLKeyPair::Generate(); 318 if (key_pair) { 319 OpenSSLCertificate *certificate = OpenSSLCertificate::Generate( 320 key_pair, params); 321 if (certificate) 322 return new OpenSSLIdentity(key_pair, certificate); 323 delete key_pair; 324 } 325 LOG(LS_INFO) << "Identity generation failed"; 326 return NULL; 327 } 328 329 OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name) { 330 SSLIdentityParams params; 331 params.common_name = common_name; 332 params.not_before = CERTIFICATE_WINDOW; 333 params.not_after = CERTIFICATE_LIFETIME; 334 return GenerateInternal(params); 335 } 336 337 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( 338 const SSLIdentityParams& params) { 339 return GenerateInternal(params); 340 } 341 342 SSLIdentity* OpenSSLIdentity::FromPEMStrings( 343 const std::string& private_key, 344 const std::string& certificate) { 345 scoped_ptr<OpenSSLCertificate> cert( 346 OpenSSLCertificate::FromPEMString(certificate)); 347 if (!cert) { 348 LOG(LS_ERROR) << "Failed to create OpenSSLCertificate from PEM string."; 349 return NULL; 350 } 351 352 BIO* bio = BIO_new_mem_buf(const_cast<char*>(private_key.c_str()), -1); 353 if (!bio) { 354 LOG(LS_ERROR) << "Failed to create a new BIO buffer."; 355 return NULL; 356 } 357 BIO_set_mem_eof_return(bio, 0); 358 EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, 359 const_cast<char*>("\0")); 360 BIO_free(bio); // Frees the BIO, but not the pointed-to string. 361 362 if (!pkey) { 363 LOG(LS_ERROR) << "Failed to create the private key from PEM string."; 364 return NULL; 365 } 366 367 return new OpenSSLIdentity(new OpenSSLKeyPair(pkey), 368 cert.release()); 369 } 370 371 bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) { 372 // 1 is the documented success return code. 373 if (SSL_CTX_use_certificate(ctx, certificate_->x509()) != 1 || 374 SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) { 375 LogSSLErrors("Configuring key and certificate"); 376 return false; 377 } 378 return true; 379 } 380 381 } // namespace talk_base 382 383 #endif // HAVE_OPENSSL_SSL_H 384