Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: net/cert/x509_util_openssl.cc

Issue 361193003: Eliminate ScopedOpenSSL in favour of scoped_ptr<> specializations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Android fixes Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "crypto/scoped_openssl_types.h"
16 #include "net/cert/x509_cert_types.h" 17 #include "net/cert/x509_cert_types.h"
17 #include "net/cert/x509_util.h" 18 #include "net/cert/x509_util.h"
18 19
19 namespace net { 20 namespace net {
20 21
21 namespace { 22 namespace {
22 23
24 typedef scoped_ptr<ASN1_INTEGER,
25 crypto::OpenSSLDestroyer<ASN1_INTEGER, ASN1_INTEGER_free> >
26 ScopedASN1_INTEGER;
27 typedef scoped_ptr<ASN1_OCTET_STRING,
28 crypto::OpenSSLDestroyer<ASN1_OCTET_STRING,
29 ASN1_OCTET_STRING_free> >
30 ScopedASN1_OCTET_STRING;
31 typedef scoped_ptr<ASN1_STRING,
32 crypto::OpenSSLDestroyer<ASN1_STRING, ASN1_STRING_free> >
33 ScopedASN1_STRING;
34 typedef scoped_ptr<ASN1_TIME,
35 crypto::OpenSSLDestroyer<ASN1_TIME, ASN1_TIME_free> >
36 ScopedASN1_TIME;
37 typedef scoped_ptr<X509, crypto::OpenSSLDestroyer<X509, X509_free> > ScopedX509;
38 typedef scoped_ptr<X509_EXTENSION,
39 crypto::OpenSSLDestroyer<X509_EXTENSION,
40 X509_EXTENSION_free> >
41 ScopedX509_EXTENSION;
42 typedef scoped_ptr<X509_NAME,
43 crypto::OpenSSLDestroyer<X509_NAME,
44 X509_NAME_free> >
45 ScopedX509_NAME;
46
23 const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) { 47 const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) {
24 switch (alg) { 48 switch (alg) {
25 case x509_util::DIGEST_SHA1: 49 case x509_util::DIGEST_SHA1:
26 return EVP_sha1(); 50 return EVP_sha1();
27 case x509_util::DIGEST_SHA256: 51 case x509_util::DIGEST_SHA256:
28 return EVP_sha256(); 52 return EVP_sha256();
29 } 53 }
30 return NULL; 54 return NULL;
31 } 55 }
32 56
33 } // namespace 57 } // namespace
34 58
35 namespace x509_util { 59 namespace x509_util {
36 60
37 namespace { 61 namespace {
38 62
39 X509* CreateCertificate(EVP_PKEY* key, 63 X509* CreateCertificate(EVP_PKEY* key,
40 DigestAlgorithm alg, 64 DigestAlgorithm alg,
41 const std::string& common_name, 65 const std::string& common_name,
42 uint32_t serial_number, 66 uint32_t serial_number,
43 base::Time not_valid_before, 67 base::Time not_valid_before,
44 base::Time not_valid_after) { 68 base::Time not_valid_after) {
45 // Put the serial number into an OpenSSL-friendly object. 69 // Put the serial number into an OpenSSL-friendly object.
46 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free> asn1_serial( 70 ScopedASN1_INTEGER asn1_serial(ASN1_INTEGER_new());
47 ASN1_INTEGER_new());
48 if (!asn1_serial.get() || 71 if (!asn1_serial.get() ||
49 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) { 72 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) {
50 LOG(ERROR) << "Invalid serial number " << serial_number; 73 LOG(ERROR) << "Invalid serial number " << serial_number;
51 return NULL; 74 return NULL;
52 } 75 }
53 76
54 // Do the same for the time stamps. 77 // Do the same for the time stamps.
55 crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free> asn1_not_before_time( 78 ScopedASN1_TIME asn1_not_before_time(
56 ASN1_TIME_set(NULL, not_valid_before.ToTimeT())); 79 ASN1_TIME_set(NULL, not_valid_before.ToTimeT()));
57 if (!asn1_not_before_time.get()) { 80 if (!asn1_not_before_time.get()) {
58 LOG(ERROR) << "Invalid not_valid_before time: " 81 LOG(ERROR) << "Invalid not_valid_before time: "
59 << not_valid_before.ToTimeT(); 82 << not_valid_before.ToTimeT();
60 return NULL; 83 return NULL;
61 } 84 }
62 85
63 crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free> asn1_not_after_time( 86 ScopedASN1_TIME asn1_not_after_time(
64 ASN1_TIME_set(NULL, not_valid_after.ToTimeT())); 87 ASN1_TIME_set(NULL, not_valid_after.ToTimeT()));
65 if (!asn1_not_after_time.get()) { 88 if (!asn1_not_after_time.get()) {
66 LOG(ERROR) << "Invalid not_valid_after time: " << not_valid_after.ToTimeT(); 89 LOG(ERROR) << "Invalid not_valid_after time: " << not_valid_after.ToTimeT();
67 return NULL; 90 return NULL;
68 } 91 }
69 92
70 // Because |common_name| only contains a common name and starts with 'CN=', 93 // Because |common_name| only contains a common name and starts with 'CN=',
71 // there is no need for a full RFC 2253 parser here. Do some sanity checks 94 // there is no need for a full RFC 2253 parser here. Do some sanity checks
72 // though. 95 // though.
73 static const char kCommonNamePrefix[] = "CN="; 96 static const char kCommonNamePrefix[] = "CN=";
74 const size_t kCommonNamePrefixLen = sizeof(kCommonNamePrefix) - 1; 97 const size_t kCommonNamePrefixLen = sizeof(kCommonNamePrefix) - 1;
75 if (common_name.size() < kCommonNamePrefixLen || 98 if (common_name.size() < kCommonNamePrefixLen ||
76 strncmp(common_name.c_str(), kCommonNamePrefix, kCommonNamePrefixLen)) { 99 strncmp(common_name.c_str(), kCommonNamePrefix, kCommonNamePrefixLen)) {
77 LOG(ERROR) << "Common name must begin with " << kCommonNamePrefix; 100 LOG(ERROR) << "Common name must begin with " << kCommonNamePrefix;
78 return NULL; 101 return NULL;
79 } 102 }
80 if (common_name.size() > INT_MAX) { 103 if (common_name.size() > INT_MAX) {
81 LOG(ERROR) << "Common name too long"; 104 LOG(ERROR) << "Common name too long";
82 return NULL; 105 return NULL;
83 } 106 }
84 unsigned char* common_name_str = 107 unsigned char* common_name_str =
85 reinterpret_cast<unsigned char*>(const_cast<char*>(common_name.data())) + 108 reinterpret_cast<unsigned char*>(const_cast<char*>(common_name.data())) +
86 kCommonNamePrefixLen; 109 kCommonNamePrefixLen;
87 int common_name_len = 110 int common_name_len =
88 static_cast<int>(common_name.size() - kCommonNamePrefixLen); 111 static_cast<int>(common_name.size() - kCommonNamePrefixLen);
89 112
90 crypto::ScopedOpenSSL<X509_NAME, X509_NAME_free> name(X509_NAME_new()); 113 ScopedX509_NAME name(X509_NAME_new());
91 if (!name.get() || !X509_NAME_add_entry_by_NID(name.get(), 114 if (!name.get() || !X509_NAME_add_entry_by_NID(name.get(),
92 NID_commonName, 115 NID_commonName,
93 MBSTRING_ASC, 116 MBSTRING_ASC,
94 common_name_str, 117 common_name_str,
95 common_name_len, 118 common_name_len,
96 -1, 119 -1,
97 0)) { 120 0)) {
98 LOG(ERROR) << "Can't parse common name: " << common_name.c_str(); 121 LOG(ERROR) << "Can't parse common name: " << common_name.c_str();
99 return NULL; 122 return NULL;
100 } 123 }
101 124
102 // Now create certificate and populate it. 125 // Now create certificate and populate it.
103 crypto::ScopedOpenSSL<X509, X509_free> cert(X509_new()); 126 ScopedX509 cert(X509_new());
104 if (!cert.get() || !X509_set_version(cert.get(), 2L) /* i.e. version 3 */ || 127 if (!cert.get() || !X509_set_version(cert.get(), 2L) /* i.e. version 3 */ ||
105 !X509_set_pubkey(cert.get(), key) || 128 !X509_set_pubkey(cert.get(), key) ||
106 !X509_set_serialNumber(cert.get(), asn1_serial.get()) || 129 !X509_set_serialNumber(cert.get(), asn1_serial.get()) ||
107 !X509_set_notBefore(cert.get(), asn1_not_before_time.get()) || 130 !X509_set_notBefore(cert.get(), asn1_not_before_time.get()) ||
108 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) || 131 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) ||
109 !X509_set_subject_name(cert.get(), name.get()) || 132 !X509_set_subject_name(cert.get(), name.get()) ||
110 !X509_set_issuer_name(cert.get(), name.get())) { 133 !X509_set_issuer_name(cert.get(), name.get())) {
111 LOG(ERROR) << "Could not create certificate"; 134 LOG(ERROR) << "Could not create certificate";
112 return NULL; 135 return NULL;
113 } 136 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 bool CreateDomainBoundCertEC( 237 bool CreateDomainBoundCertEC(
215 crypto::ECPrivateKey* key, 238 crypto::ECPrivateKey* key,
216 DigestAlgorithm alg, 239 DigestAlgorithm alg,
217 const std::string& domain, 240 const std::string& domain,
218 uint32 serial_number, 241 uint32 serial_number,
219 base::Time not_valid_before, 242 base::Time not_valid_before,
220 base::Time not_valid_after, 243 base::Time not_valid_after,
221 std::string* der_cert) { 244 std::string* der_cert) {
222 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 245 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
223 // Create certificate. 246 // Create certificate.
224 crypto::ScopedOpenSSL<X509, X509_free> cert( 247 ScopedX509 cert(CreateCertificate(key->key(),
225 CreateCertificate(key->key(), 248 alg,
226 alg, 249 "CN=anonymous.invalid",
227 "CN=anonymous.invalid", 250 serial_number,
228 serial_number, 251 not_valid_before,
229 not_valid_before, 252 not_valid_after));
230 not_valid_after));
231 if (!cert.get()) 253 if (!cert.get())
232 return false; 254 return false;
233 255
234 // Add TLS-Channel-ID extension to the certificate before signing it. 256 // Add TLS-Channel-ID extension to the certificate before signing it.
235 // The value must be stored DER-encoded, as a ASN.1 IA5String. 257 // The value must be stored DER-encoded, as a ASN.1 IA5String.
236 crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free> domain_ia5( 258 ScopedASN1_STRING domain_ia5(ASN1_IA5STRING_new());
237 ASN1_IA5STRING_new());
238 if (!domain_ia5.get() || 259 if (!domain_ia5.get() ||
239 !ASN1_STRING_set(domain_ia5.get(), domain.data(), domain.size())) 260 !ASN1_STRING_set(domain_ia5.get(), domain.data(), domain.size()))
240 return false; 261 return false;
241 262
242 std::string domain_der; 263 std::string domain_der;
243 int domain_der_len = i2d_ASN1_IA5STRING(domain_ia5.get(), NULL); 264 int domain_der_len = i2d_ASN1_IA5STRING(domain_ia5.get(), NULL);
244 if (domain_der_len < 0) 265 if (domain_der_len < 0)
245 return false; 266 return false;
246 267
247 domain_der.resize(domain_der_len); 268 domain_der.resize(domain_der_len);
248 unsigned char* domain_der_data = 269 unsigned char* domain_der_data =
249 reinterpret_cast<unsigned char*>(&domain_der[0]); 270 reinterpret_cast<unsigned char*>(&domain_der[0]);
250 if (i2d_ASN1_IA5STRING(domain_ia5.get(), &domain_der_data) < 0) 271 if (i2d_ASN1_IA5STRING(domain_ia5.get(), &domain_der_data) < 0)
251 return false; 272 return false;
252 273
253 crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free> domain_str( 274 ScopedASN1_OCTET_STRING domain_str(ASN1_OCTET_STRING_new());
254 ASN1_OCTET_STRING_new());
255 if (!domain_str.get() || 275 if (!domain_str.get() ||
256 !ASN1_STRING_set(domain_str.get(), domain_der.data(), domain_der.size())) 276 !ASN1_STRING_set(domain_str.get(), domain_der.data(), domain_der.size()))
257 return false; 277 return false;
258 278
259 crypto::ScopedOpenSSL<X509_EXTENSION, X509_EXTENSION_free> ext( 279 ScopedX509_EXTENSION ext(X509_EXTENSION_create_by_OBJ(
260 X509_EXTENSION_create_by_OBJ( 280 NULL, GetDomainBoundOid(), 1 /* critical */, domain_str.get()));
261 NULL, GetDomainBoundOid(), 1 /* critical */, domain_str.get()));
262 if (!ext.get() || !X509_add_ext(cert.get(), ext.get(), -1)) { 281 if (!ext.get() || !X509_add_ext(cert.get(), ext.get(), -1)) {
263 return false; 282 return false;
264 } 283 }
265 284
266 // Sign and encode it. 285 // Sign and encode it.
267 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_cert); 286 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_cert);
268 } 287 }
269 288
270 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, 289 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
271 DigestAlgorithm alg, 290 DigestAlgorithm alg,
272 const std::string& common_name, 291 const std::string& common_name,
273 uint32 serial_number, 292 uint32 serial_number,
274 base::Time not_valid_before, 293 base::Time not_valid_before,
275 base::Time not_valid_after, 294 base::Time not_valid_after,
276 std::string* der_encoded) { 295 std::string* der_encoded) {
277 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 296 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
278 crypto::ScopedOpenSSL<X509, X509_free> cert( 297 ScopedX509 cert(CreateCertificate(key->key(),
279 CreateCertificate(key->key(), 298 alg,
280 alg, 299 common_name,
281 common_name, 300 serial_number,
282 serial_number, 301 not_valid_before,
283 not_valid_before, 302 not_valid_after));
284 not_valid_after));
285 if (!cert.get()) 303 if (!cert.get())
286 return false; 304 return false;
287 305
288 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded); 306 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded);
289 } 307 }
290 308
291 bool ParsePrincipalKeyAndValue(X509_NAME_ENTRY* entry, 309 bool ParsePrincipalKeyAndValue(X509_NAME_ENTRY* entry,
292 std::string* key, 310 std::string* key,
293 std::string* value) { 311 std::string* value) {
294 if (key) { 312 if (key) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 x509_time->length); 363 x509_time->length);
346 364
347 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ? 365 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ?
348 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; 366 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME;
349 return ParseCertificateDate(str_date, format, time); 367 return ParseCertificateDate(str_date, format, time);
350 } 368 }
351 369
352 } // namespace x509_util 370 } // namespace x509_util
353 371
354 } // namespace net 372 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698