| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <openssl/asn1.h> | 8 #include <openssl/asn1.h> |
| 9 | 9 |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" |
| 13 #include "crypto/ec_private_key.h" | 13 #include "crypto/ec_private_key.h" |
| 14 #include "crypto/openssl_util.h" | 14 #include "crypto/openssl_util.h" |
| 15 #include "crypto/rsa_private_key.h" | 15 #include "crypto/rsa_private_key.h" |
| 16 #include "net/cert/x509_cert_types.h" | 16 #include "net/cert/x509_cert_types.h" |
| 17 #include "net/cert/x509_util.h" | 17 #include "net/cert/x509_util.h" |
| 18 | 18 |
| 19 namespace net { | 19 namespace net { |
| 20 | 20 |
| 21 namespace { |
| 22 |
| 23 const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) { |
| 24 switch (alg) { |
| 25 case x509_util::DIGEST_SHA1: |
| 26 return EVP_sha1(); |
| 27 case x509_util::DIGEST_SHA256: |
| 28 return EVP_sha256(); |
| 29 } |
| 30 return NULL; |
| 31 } |
| 32 |
| 33 } // namespace |
| 34 |
| 21 namespace x509_util { | 35 namespace x509_util { |
| 22 | 36 |
| 23 namespace { | 37 namespace { |
| 24 | 38 |
| 25 X509* CreateCertificate(EVP_PKEY* key, | 39 X509* CreateCertificate(EVP_PKEY* key, |
| 40 DigestAlgorithm alg, |
| 26 const std::string& common_name, | 41 const std::string& common_name, |
| 27 uint32_t serial_number, | 42 uint32_t serial_number, |
| 28 base::Time not_valid_before, | 43 base::Time not_valid_before, |
| 29 base::Time not_valid_after) { | 44 base::Time not_valid_after) { |
| 30 // Put the serial number into an OpenSSL-friendly object. | 45 // Put the serial number into an OpenSSL-friendly object. |
| 31 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free> asn1_serial( | 46 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free> asn1_serial( |
| 32 ASN1_INTEGER_new()); | 47 ASN1_INTEGER_new()); |
| 33 if (!asn1_serial.get() || | 48 if (!asn1_serial.get() || |
| 34 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) { | 49 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) { |
| 35 LOG(ERROR) << "Invalid serial number " << serial_number; | 50 LOG(ERROR) << "Invalid serial number " << serial_number; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) || | 108 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) || |
| 94 !X509_set_subject_name(cert.get(), name.get()) || | 109 !X509_set_subject_name(cert.get(), name.get()) || |
| 95 !X509_set_issuer_name(cert.get(), name.get())) { | 110 !X509_set_issuer_name(cert.get(), name.get())) { |
| 96 LOG(ERROR) << "Could not create certificate"; | 111 LOG(ERROR) << "Could not create certificate"; |
| 97 return NULL; | 112 return NULL; |
| 98 } | 113 } |
| 99 | 114 |
| 100 return cert.release(); | 115 return cert.release(); |
| 101 } | 116 } |
| 102 | 117 |
| 103 bool SignAndDerEncodeCert(X509* cert, EVP_PKEY* key, std::string* der_encoded) { | 118 bool SignAndDerEncodeCert(X509* cert, |
| 119 EVP_PKEY* key, |
| 120 DigestAlgorithm alg, |
| 121 std::string* der_encoded) { |
| 122 // Get the message digest algorithm |
| 123 const EVP_MD* md = ToEVP(alg); |
| 124 if (!md) { |
| 125 LOG(ERROR) << "Unrecognized hash algorithm."; |
| 126 return false; |
| 127 } |
| 128 |
| 104 // Sign it with the private key. | 129 // Sign it with the private key. |
| 105 if (!X509_sign(cert, key, EVP_sha1())) { | 130 if (!X509_sign(cert, key, md)) { |
| 106 LOG(ERROR) << "Could not sign certificate with key."; | 131 LOG(ERROR) << "Could not sign certificate with key."; |
| 107 return false; | 132 return false; |
| 108 } | 133 } |
| 109 | 134 |
| 110 // Convert it into a DER-encoded string copied to |der_encoded|. | 135 // Convert it into a DER-encoded string copied to |der_encoded|. |
| 111 int der_data_length = i2d_X509(cert, NULL); | 136 int der_data_length = i2d_X509(cert, NULL); |
| 112 if (der_data_length < 0) | 137 if (der_data_length < 0) |
| 113 return false; | 138 return false; |
| 114 | 139 |
| 115 der_encoded->resize(der_data_length); | 140 der_encoded->resize(der_data_length); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 | 206 |
| 182 if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 || | 207 if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 || |
| 183 not_valid_after < kYear0001 || not_valid_after >= kYear10000) | 208 not_valid_after < kYear0001 || not_valid_after >= kYear10000) |
| 184 return false; | 209 return false; |
| 185 | 210 |
| 186 return true; | 211 return true; |
| 187 } | 212 } |
| 188 | 213 |
| 189 bool CreateDomainBoundCertEC( | 214 bool CreateDomainBoundCertEC( |
| 190 crypto::ECPrivateKey* key, | 215 crypto::ECPrivateKey* key, |
| 216 DigestAlgorithm alg, |
| 191 const std::string& domain, | 217 const std::string& domain, |
| 192 uint32 serial_number, | 218 uint32 serial_number, |
| 193 base::Time not_valid_before, | 219 base::Time not_valid_before, |
| 194 base::Time not_valid_after, | 220 base::Time not_valid_after, |
| 195 std::string* der_cert) { | 221 std::string* der_cert) { |
| 196 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 222 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 197 // Create certificate. | 223 // Create certificate. |
| 198 crypto::ScopedOpenSSL<X509, X509_free> cert( | 224 crypto::ScopedOpenSSL<X509, X509_free> cert( |
| 199 CreateCertificate(key->key(), | 225 CreateCertificate(key->key(), |
| 226 alg, |
| 200 "CN=anonymous.invalid", | 227 "CN=anonymous.invalid", |
| 201 serial_number, | 228 serial_number, |
| 202 not_valid_before, | 229 not_valid_before, |
| 203 not_valid_after)); | 230 not_valid_after)); |
| 204 if (!cert.get()) | 231 if (!cert.get()) |
| 205 return false; | 232 return false; |
| 206 | 233 |
| 207 // Add TLS-Channel-ID extension to the certificate before signing it. | 234 // Add TLS-Channel-ID extension to the certificate before signing it. |
| 208 // The value must be stored DER-encoded, as a ASN.1 IA5String. | 235 // The value must be stored DER-encoded, as a ASN.1 IA5String. |
| 209 crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free> domain_ia5( | 236 crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free> domain_ia5( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 230 return false; | 257 return false; |
| 231 | 258 |
| 232 crypto::ScopedOpenSSL<X509_EXTENSION, X509_EXTENSION_free> ext( | 259 crypto::ScopedOpenSSL<X509_EXTENSION, X509_EXTENSION_free> ext( |
| 233 X509_EXTENSION_create_by_OBJ( | 260 X509_EXTENSION_create_by_OBJ( |
| 234 NULL, GetDomainBoundOid(), 1 /* critical */, domain_str.get())); | 261 NULL, GetDomainBoundOid(), 1 /* critical */, domain_str.get())); |
| 235 if (!ext.get() || !X509_add_ext(cert.get(), ext.get(), -1)) { | 262 if (!ext.get() || !X509_add_ext(cert.get(), ext.get(), -1)) { |
| 236 return false; | 263 return false; |
| 237 } | 264 } |
| 238 | 265 |
| 239 // Sign and encode it. | 266 // Sign and encode it. |
| 240 return SignAndDerEncodeCert(cert.get(), key->key(), der_cert); | 267 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_cert); |
| 241 } | 268 } |
| 242 | 269 |
| 243 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, | 270 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, |
| 271 DigestAlgorithm alg, |
| 244 const std::string& common_name, | 272 const std::string& common_name, |
| 245 uint32 serial_number, | 273 uint32 serial_number, |
| 246 base::Time not_valid_before, | 274 base::Time not_valid_before, |
| 247 base::Time not_valid_after, | 275 base::Time not_valid_after, |
| 248 std::string* der_encoded) { | 276 std::string* der_encoded) { |
| 249 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 277 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 250 crypto::ScopedOpenSSL<X509, X509_free> cert( | 278 crypto::ScopedOpenSSL<X509, X509_free> cert( |
| 251 CreateCertificate(key->key(), | 279 CreateCertificate(key->key(), |
| 280 alg, |
| 252 common_name, | 281 common_name, |
| 253 serial_number, | 282 serial_number, |
| 254 not_valid_before, | 283 not_valid_before, |
| 255 not_valid_after)); | 284 not_valid_after)); |
| 256 if (!cert.get()) | 285 if (!cert.get()) |
| 257 return false; | 286 return false; |
| 258 | 287 |
| 259 return SignAndDerEncodeCert(cert.get(), key->key(), der_encoded); | 288 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded); |
| 260 } | 289 } |
| 261 | 290 |
| 262 bool ParsePrincipalKeyAndValueByIndex(X509_NAME* name, | 291 bool ParsePrincipalKeyAndValueByIndex(X509_NAME* name, |
| 263 int index, | 292 int index, |
| 264 std::string* key, | 293 std::string* key, |
| 265 std::string* value) { | 294 std::string* value) { |
| 266 X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, index); | 295 X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, index); |
| 267 if (!entry) | 296 if (!entry) |
| 268 return false; | 297 return false; |
| 269 | 298 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 x509_time->length); | 339 x509_time->length); |
| 311 | 340 |
| 312 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ? | 341 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ? |
| 313 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; | 342 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; |
| 314 return ParseCertificateDate(str_date, format, time); | 343 return ParseCertificateDate(str_date, format, time); |
| 315 } | 344 } |
| 316 | 345 |
| 317 } // namespace x509_util | 346 } // namespace x509_util |
| 318 | 347 |
| 319 } // namespace net | 348 } // namespace net |
| OLD | NEW |