| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert/x509_util_openssl.h" | 5 #include "net/cert/x509_util_openssl.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <openssl/asn1.h> | 8 #include <openssl/asn1.h> |
| 9 #include <openssl/digest.h> | 9 #include <openssl/digest.h> |
| 10 #include <openssl/mem.h> | 10 #include <openssl/mem.h> |
| 11 | 11 |
| 12 #include <algorithm> | 12 #include <algorithm> |
| 13 #include <memory> | 13 #include <memory> |
| 14 | 14 |
| 15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/macros.h" | 17 #include "base/macros.h" |
| 18 #include "base/strings/string_piece.h" | 18 #include "base/strings/string_piece.h" |
| 19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 20 #include "crypto/ec_private_key.h" | 20 #include "crypto/ec_private_key.h" |
| 21 #include "crypto/openssl_util.h" | 21 #include "crypto/openssl_util.h" |
| 22 #include "crypto/rsa_private_key.h" | 22 #include "crypto/rsa_private_key.h" |
| 23 #include "crypto/scoped_openssl_types.h" | |
| 24 #include "net/cert/internal/parse_certificate.h" | 23 #include "net/cert/internal/parse_certificate.h" |
| 25 #include "net/cert/internal/signature_algorithm.h" | 24 #include "net/cert/internal/signature_algorithm.h" |
| 26 #include "net/cert/x509_cert_types.h" | 25 #include "net/cert/x509_cert_types.h" |
| 27 #include "net/cert/x509_certificate.h" | 26 #include "net/cert/x509_certificate.h" |
| 28 #include "net/cert/x509_util.h" | 27 #include "net/cert/x509_util.h" |
| 29 #include "net/ssl/scoped_openssl_types.h" | |
| 30 | 28 |
| 31 namespace net { | 29 namespace net { |
| 32 | 30 |
| 33 namespace { | 31 namespace { |
| 34 | 32 |
| 35 using ScopedASN1_INTEGER = | |
| 36 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free>; | |
| 37 using ScopedASN1_OCTET_STRING = | |
| 38 crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free>; | |
| 39 using ScopedASN1_STRING = crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free>; | |
| 40 using ScopedASN1_TIME = crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free>; | |
| 41 using ScopedX509_EXTENSION = | |
| 42 crypto::ScopedOpenSSL<X509_EXTENSION, X509_EXTENSION_free>; | |
| 43 | |
| 44 const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) { | 33 const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) { |
| 45 switch (alg) { | 34 switch (alg) { |
| 46 case x509_util::DIGEST_SHA1: | 35 case x509_util::DIGEST_SHA1: |
| 47 return EVP_sha1(); | 36 return EVP_sha1(); |
| 48 case x509_util::DIGEST_SHA256: | 37 case x509_util::DIGEST_SHA256: |
| 49 return EVP_sha256(); | 38 return EVP_sha256(); |
| 50 } | 39 } |
| 51 return NULL; | 40 return NULL; |
| 52 } | 41 } |
| 53 | 42 |
| 54 } // namespace | 43 } // namespace |
| 55 | 44 |
| 56 namespace x509_util { | 45 namespace x509_util { |
| 57 | 46 |
| 58 namespace { | 47 namespace { |
| 59 | 48 |
| 60 X509* CreateCertificate(EVP_PKEY* key, | 49 bssl::UniquePtr<X509> CreateCertificate(EVP_PKEY* key, |
| 61 DigestAlgorithm alg, | 50 DigestAlgorithm alg, |
| 62 const std::string& common_name, | 51 const std::string& common_name, |
| 63 uint32_t serial_number, | 52 uint32_t serial_number, |
| 64 base::Time not_valid_before, | 53 base::Time not_valid_before, |
| 65 base::Time not_valid_after) { | 54 base::Time not_valid_after) { |
| 66 // Put the serial number into an OpenSSL-friendly object. | 55 // Put the serial number into an OpenSSL-friendly object. |
| 67 ScopedASN1_INTEGER asn1_serial(ASN1_INTEGER_new()); | 56 bssl::UniquePtr<ASN1_INTEGER> asn1_serial(ASN1_INTEGER_new()); |
| 68 if (!asn1_serial.get() || | 57 if (!asn1_serial.get() || |
| 69 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) { | 58 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) { |
| 70 LOG(ERROR) << "Invalid serial number " << serial_number; | 59 LOG(ERROR) << "Invalid serial number " << serial_number; |
| 71 return NULL; | 60 return nullptr; |
| 72 } | 61 } |
| 73 | 62 |
| 74 // Do the same for the time stamps. | 63 // Do the same for the time stamps. |
| 75 ScopedASN1_TIME asn1_not_before_time( | 64 bssl::UniquePtr<ASN1_TIME> asn1_not_before_time( |
| 76 ASN1_TIME_set(NULL, not_valid_before.ToTimeT())); | 65 ASN1_TIME_set(nullptr, not_valid_before.ToTimeT())); |
| 77 if (!asn1_not_before_time.get()) { | 66 if (!asn1_not_before_time.get()) { |
| 78 LOG(ERROR) << "Invalid not_valid_before time: " | 67 LOG(ERROR) << "Invalid not_valid_before time: " |
| 79 << not_valid_before.ToTimeT(); | 68 << not_valid_before.ToTimeT(); |
| 80 return NULL; | 69 return nullptr; |
| 81 } | 70 } |
| 82 | 71 |
| 83 ScopedASN1_TIME asn1_not_after_time( | 72 bssl::UniquePtr<ASN1_TIME> asn1_not_after_time( |
| 84 ASN1_TIME_set(NULL, not_valid_after.ToTimeT())); | 73 ASN1_TIME_set(nullptr, not_valid_after.ToTimeT())); |
| 85 if (!asn1_not_after_time.get()) { | 74 if (!asn1_not_after_time.get()) { |
| 86 LOG(ERROR) << "Invalid not_valid_after time: " << not_valid_after.ToTimeT(); | 75 LOG(ERROR) << "Invalid not_valid_after time: " << not_valid_after.ToTimeT(); |
| 87 return NULL; | 76 return nullptr; |
| 88 } | 77 } |
| 89 | 78 |
| 90 // Because |common_name| only contains a common name and starts with 'CN=', | 79 // Because |common_name| only contains a common name and starts with 'CN=', |
| 91 // there is no need for a full RFC 2253 parser here. Do some sanity checks | 80 // there is no need for a full RFC 2253 parser here. Do some sanity checks |
| 92 // though. | 81 // though. |
| 93 static const char kCommonNamePrefix[] = "CN="; | 82 static const char kCommonNamePrefix[] = "CN="; |
| 94 const size_t kCommonNamePrefixLen = sizeof(kCommonNamePrefix) - 1; | 83 const size_t kCommonNamePrefixLen = sizeof(kCommonNamePrefix) - 1; |
| 95 if (common_name.size() < kCommonNamePrefixLen || | 84 if (common_name.size() < kCommonNamePrefixLen || |
| 96 strncmp(common_name.c_str(), kCommonNamePrefix, kCommonNamePrefixLen)) { | 85 strncmp(common_name.c_str(), kCommonNamePrefix, kCommonNamePrefixLen)) { |
| 97 LOG(ERROR) << "Common name must begin with " << kCommonNamePrefix; | 86 LOG(ERROR) << "Common name must begin with " << kCommonNamePrefix; |
| 98 return NULL; | 87 return nullptr; |
| 99 } | 88 } |
| 100 if (common_name.size() > INT_MAX) { | 89 if (common_name.size() > INT_MAX) { |
| 101 LOG(ERROR) << "Common name too long"; | 90 LOG(ERROR) << "Common name too long"; |
| 102 return NULL; | 91 return nullptr; |
| 103 } | 92 } |
| 104 unsigned char* common_name_str = | 93 unsigned char* common_name_str = |
| 105 reinterpret_cast<unsigned char*>(const_cast<char*>(common_name.data())) + | 94 reinterpret_cast<unsigned char*>(const_cast<char*>(common_name.data())) + |
| 106 kCommonNamePrefixLen; | 95 kCommonNamePrefixLen; |
| 107 int common_name_len = | 96 int common_name_len = |
| 108 static_cast<int>(common_name.size() - kCommonNamePrefixLen); | 97 static_cast<int>(common_name.size() - kCommonNamePrefixLen); |
| 109 | 98 |
| 110 ScopedX509_NAME name(X509_NAME_new()); | 99 bssl::UniquePtr<X509_NAME> name(X509_NAME_new()); |
| 111 if (!name.get() || !X509_NAME_add_entry_by_NID(name.get(), | 100 if (!name.get() || !X509_NAME_add_entry_by_NID(name.get(), |
| 112 NID_commonName, | 101 NID_commonName, |
| 113 MBSTRING_ASC, | 102 MBSTRING_ASC, |
| 114 common_name_str, | 103 common_name_str, |
| 115 common_name_len, | 104 common_name_len, |
| 116 -1, | 105 -1, |
| 117 0)) { | 106 0)) { |
| 118 LOG(ERROR) << "Can't parse common name: " << common_name.c_str(); | 107 LOG(ERROR) << "Can't parse common name: " << common_name.c_str(); |
| 119 return NULL; | 108 return nullptr; |
| 120 } | 109 } |
| 121 | 110 |
| 122 // Now create certificate and populate it. | 111 // Now create certificate and populate it. |
| 123 ScopedX509 cert(X509_new()); | 112 bssl::UniquePtr<X509> cert(X509_new()); |
| 124 if (!cert.get() || !X509_set_version(cert.get(), 2L) /* i.e. version 3 */ || | 113 if (!cert.get() || !X509_set_version(cert.get(), 2L) /* i.e. version 3 */ || |
| 125 !X509_set_pubkey(cert.get(), key) || | 114 !X509_set_pubkey(cert.get(), key) || |
| 126 !X509_set_serialNumber(cert.get(), asn1_serial.get()) || | 115 !X509_set_serialNumber(cert.get(), asn1_serial.get()) || |
| 127 !X509_set_notBefore(cert.get(), asn1_not_before_time.get()) || | 116 !X509_set_notBefore(cert.get(), asn1_not_before_time.get()) || |
| 128 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) || | 117 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) || |
| 129 !X509_set_subject_name(cert.get(), name.get()) || | 118 !X509_set_subject_name(cert.get(), name.get()) || |
| 130 !X509_set_issuer_name(cert.get(), name.get())) { | 119 !X509_set_issuer_name(cert.get(), name.get())) { |
| 131 LOG(ERROR) << "Could not create certificate"; | 120 LOG(ERROR) << "Could not create certificate"; |
| 132 return NULL; | 121 return nullptr; |
| 133 } | 122 } |
| 134 | 123 |
| 135 return cert.release(); | 124 return cert; |
| 136 } | 125 } |
| 137 | 126 |
| 138 // DER-encodes |x509|. On success, returns true and writes the | 127 // DER-encodes |x509|. On success, returns true and writes the |
| 139 // encoding to |*out_der|. | 128 // encoding to |*out_der|. |
| 140 bool DerEncodeCert(X509* x509, std::string* out_der) { | 129 bool DerEncodeCert(X509* x509, std::string* out_der) { |
| 141 int len = i2d_X509(x509, NULL); | 130 int len = i2d_X509(x509, NULL); |
| 142 if (len < 0) | 131 if (len < 0) |
| 143 return false; | 132 return false; |
| 144 | 133 |
| 145 uint8_t* ptr = reinterpret_cast<uint8_t*>(base::WriteInto(out_der, len + 1)); | 134 uint8_t* ptr = reinterpret_cast<uint8_t*>(base::WriteInto(out_der, len + 1)); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 } // namespace | 193 } // namespace |
| 205 | 194 |
| 206 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, | 195 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, |
| 207 DigestAlgorithm alg, | 196 DigestAlgorithm alg, |
| 208 const std::string& common_name, | 197 const std::string& common_name, |
| 209 uint32_t serial_number, | 198 uint32_t serial_number, |
| 210 base::Time not_valid_before, | 199 base::Time not_valid_before, |
| 211 base::Time not_valid_after, | 200 base::Time not_valid_after, |
| 212 std::string* der_encoded) { | 201 std::string* der_encoded) { |
| 213 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 202 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 214 ScopedX509 cert(CreateCertificate(key->key(), | 203 bssl::UniquePtr<X509> cert = |
| 215 alg, | 204 CreateCertificate(key->key(), alg, common_name, serial_number, |
| 216 common_name, | 205 not_valid_before, not_valid_after); |
| 217 serial_number, | 206 if (!cert) |
| 218 not_valid_before, | |
| 219 not_valid_after)); | |
| 220 if (!cert.get()) | |
| 221 return false; | 207 return false; |
| 222 | 208 |
| 223 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded); | 209 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded); |
| 224 } | 210 } |
| 225 | 211 |
| 226 bool ParsePrincipalKeyAndValue(X509_NAME_ENTRY* entry, | 212 bool ParsePrincipalKeyAndValue(X509_NAME_ENTRY* entry, |
| 227 std::string* key, | 213 std::string* key, |
| 228 std::string* value) { | 214 std::string* value) { |
| 229 if (key) { | 215 if (key) { |
| 230 ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(entry); | 216 ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(entry); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 | 343 |
| 358 digest.resize(out_size); | 344 digest.resize(out_size); |
| 359 token->assign(kChannelBindingPrefix); | 345 token->assign(kChannelBindingPrefix); |
| 360 token->append(digest.begin(), digest.end()); | 346 token->append(digest.begin(), digest.end()); |
| 361 return true; | 347 return true; |
| 362 } | 348 } |
| 363 | 349 |
| 364 } // namespace x509_util | 350 } // namespace x509_util |
| 365 | 351 |
| 366 } // namespace net | 352 } // namespace net |
| OLD | NEW |