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

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: Rebase 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
« no previous file with comments | « net/cert/x509_certificate_openssl.cc ('k') | net/cert/x509_util_openssl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free>::Type
25 ScopedASN1_INTEGER;
26 typedef crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free>::Type
27 ScopedASN1_OCTET_STRING;
28 typedef crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free>::Type
29 ScopedASN1_STRING;
30 typedef crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free>::Type ScopedASN1_TIME;
31 typedef crypto::ScopedOpenSSL<X509, X509_free>::Type ScopedX509;
32 typedef crypto::ScopedOpenSSL<X509_EXTENSION, X509_EXTENSION_free>::Type
33 ScopedX509_EXTENSION;
34 typedef crypto::ScopedOpenSSL<X509_NAME, X509_NAME_free>::Type ScopedX509_NAME;
35
23 const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) { 36 const EVP_MD* ToEVP(x509_util::DigestAlgorithm alg) {
24 switch (alg) { 37 switch (alg) {
25 case x509_util::DIGEST_SHA1: 38 case x509_util::DIGEST_SHA1:
26 return EVP_sha1(); 39 return EVP_sha1();
27 case x509_util::DIGEST_SHA256: 40 case x509_util::DIGEST_SHA256:
28 return EVP_sha256(); 41 return EVP_sha256();
29 } 42 }
30 return NULL; 43 return NULL;
31 } 44 }
32 45
33 } // namespace 46 } // namespace
34 47
35 namespace x509_util { 48 namespace x509_util {
36 49
37 namespace { 50 namespace {
38 51
39 X509* CreateCertificate(EVP_PKEY* key, 52 X509* CreateCertificate(EVP_PKEY* key,
40 DigestAlgorithm alg, 53 DigestAlgorithm alg,
41 const std::string& common_name, 54 const std::string& common_name,
42 uint32_t serial_number, 55 uint32_t serial_number,
43 base::Time not_valid_before, 56 base::Time not_valid_before,
44 base::Time not_valid_after) { 57 base::Time not_valid_after) {
45 // Put the serial number into an OpenSSL-friendly object. 58 // Put the serial number into an OpenSSL-friendly object.
46 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free> asn1_serial( 59 ScopedASN1_INTEGER asn1_serial(ASN1_INTEGER_new());
47 ASN1_INTEGER_new());
48 if (!asn1_serial.get() || 60 if (!asn1_serial.get() ||
49 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) { 61 !ASN1_INTEGER_set(asn1_serial.get(), static_cast<long>(serial_number))) {
50 LOG(ERROR) << "Invalid serial number " << serial_number; 62 LOG(ERROR) << "Invalid serial number " << serial_number;
51 return NULL; 63 return NULL;
52 } 64 }
53 65
54 // Do the same for the time stamps. 66 // Do the same for the time stamps.
55 crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free> asn1_not_before_time( 67 ScopedASN1_TIME asn1_not_before_time(
56 ASN1_TIME_set(NULL, not_valid_before.ToTimeT())); 68 ASN1_TIME_set(NULL, not_valid_before.ToTimeT()));
57 if (!asn1_not_before_time.get()) { 69 if (!asn1_not_before_time.get()) {
58 LOG(ERROR) << "Invalid not_valid_before time: " 70 LOG(ERROR) << "Invalid not_valid_before time: "
59 << not_valid_before.ToTimeT(); 71 << not_valid_before.ToTimeT();
60 return NULL; 72 return NULL;
61 } 73 }
62 74
63 crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free> asn1_not_after_time( 75 ScopedASN1_TIME asn1_not_after_time(
64 ASN1_TIME_set(NULL, not_valid_after.ToTimeT())); 76 ASN1_TIME_set(NULL, not_valid_after.ToTimeT()));
65 if (!asn1_not_after_time.get()) { 77 if (!asn1_not_after_time.get()) {
66 LOG(ERROR) << "Invalid not_valid_after time: " << not_valid_after.ToTimeT(); 78 LOG(ERROR) << "Invalid not_valid_after time: " << not_valid_after.ToTimeT();
67 return NULL; 79 return NULL;
68 } 80 }
69 81
70 // Because |common_name| only contains a common name and starts with 'CN=', 82 // 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 83 // there is no need for a full RFC 2253 parser here. Do some sanity checks
72 // though. 84 // though.
73 static const char kCommonNamePrefix[] = "CN="; 85 static const char kCommonNamePrefix[] = "CN=";
74 const size_t kCommonNamePrefixLen = sizeof(kCommonNamePrefix) - 1; 86 const size_t kCommonNamePrefixLen = sizeof(kCommonNamePrefix) - 1;
75 if (common_name.size() < kCommonNamePrefixLen || 87 if (common_name.size() < kCommonNamePrefixLen ||
76 strncmp(common_name.c_str(), kCommonNamePrefix, kCommonNamePrefixLen)) { 88 strncmp(common_name.c_str(), kCommonNamePrefix, kCommonNamePrefixLen)) {
77 LOG(ERROR) << "Common name must begin with " << kCommonNamePrefix; 89 LOG(ERROR) << "Common name must begin with " << kCommonNamePrefix;
78 return NULL; 90 return NULL;
79 } 91 }
80 if (common_name.size() > INT_MAX) { 92 if (common_name.size() > INT_MAX) {
81 LOG(ERROR) << "Common name too long"; 93 LOG(ERROR) << "Common name too long";
82 return NULL; 94 return NULL;
83 } 95 }
84 unsigned char* common_name_str = 96 unsigned char* common_name_str =
85 reinterpret_cast<unsigned char*>(const_cast<char*>(common_name.data())) + 97 reinterpret_cast<unsigned char*>(const_cast<char*>(common_name.data())) +
86 kCommonNamePrefixLen; 98 kCommonNamePrefixLen;
87 int common_name_len = 99 int common_name_len =
88 static_cast<int>(common_name.size() - kCommonNamePrefixLen); 100 static_cast<int>(common_name.size() - kCommonNamePrefixLen);
89 101
90 crypto::ScopedOpenSSL<X509_NAME, X509_NAME_free> name(X509_NAME_new()); 102 ScopedX509_NAME name(X509_NAME_new());
91 if (!name.get() || !X509_NAME_add_entry_by_NID(name.get(), 103 if (!name.get() || !X509_NAME_add_entry_by_NID(name.get(),
92 NID_commonName, 104 NID_commonName,
93 MBSTRING_ASC, 105 MBSTRING_ASC,
94 common_name_str, 106 common_name_str,
95 common_name_len, 107 common_name_len,
96 -1, 108 -1,
97 0)) { 109 0)) {
98 LOG(ERROR) << "Can't parse common name: " << common_name.c_str(); 110 LOG(ERROR) << "Can't parse common name: " << common_name.c_str();
99 return NULL; 111 return NULL;
100 } 112 }
101 113
102 // Now create certificate and populate it. 114 // Now create certificate and populate it.
103 crypto::ScopedOpenSSL<X509, X509_free> cert(X509_new()); 115 ScopedX509 cert(X509_new());
104 if (!cert.get() || !X509_set_version(cert.get(), 2L) /* i.e. version 3 */ || 116 if (!cert.get() || !X509_set_version(cert.get(), 2L) /* i.e. version 3 */ ||
105 !X509_set_pubkey(cert.get(), key) || 117 !X509_set_pubkey(cert.get(), key) ||
106 !X509_set_serialNumber(cert.get(), asn1_serial.get()) || 118 !X509_set_serialNumber(cert.get(), asn1_serial.get()) ||
107 !X509_set_notBefore(cert.get(), asn1_not_before_time.get()) || 119 !X509_set_notBefore(cert.get(), asn1_not_before_time.get()) ||
108 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) || 120 !X509_set_notAfter(cert.get(), asn1_not_after_time.get()) ||
109 !X509_set_subject_name(cert.get(), name.get()) || 121 !X509_set_subject_name(cert.get(), name.get()) ||
110 !X509_set_issuer_name(cert.get(), name.get())) { 122 !X509_set_issuer_name(cert.get(), name.get())) {
111 LOG(ERROR) << "Could not create certificate"; 123 LOG(ERROR) << "Could not create certificate";
112 return NULL; 124 return NULL;
113 } 125 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 bool CreateDomainBoundCertEC( 226 bool CreateDomainBoundCertEC(
215 crypto::ECPrivateKey* key, 227 crypto::ECPrivateKey* key,
216 DigestAlgorithm alg, 228 DigestAlgorithm alg,
217 const std::string& domain, 229 const std::string& domain,
218 uint32 serial_number, 230 uint32 serial_number,
219 base::Time not_valid_before, 231 base::Time not_valid_before,
220 base::Time not_valid_after, 232 base::Time not_valid_after,
221 std::string* der_cert) { 233 std::string* der_cert) {
222 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 234 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
223 // Create certificate. 235 // Create certificate.
224 crypto::ScopedOpenSSL<X509, X509_free> cert( 236 ScopedX509 cert(CreateCertificate(key->key(),
225 CreateCertificate(key->key(), 237 alg,
226 alg, 238 "CN=anonymous.invalid",
227 "CN=anonymous.invalid", 239 serial_number,
228 serial_number, 240 not_valid_before,
229 not_valid_before, 241 not_valid_after));
230 not_valid_after));
231 if (!cert.get()) 242 if (!cert.get())
232 return false; 243 return false;
233 244
234 // Add TLS-Channel-ID extension to the certificate before signing it. 245 // Add TLS-Channel-ID extension to the certificate before signing it.
235 // The value must be stored DER-encoded, as a ASN.1 IA5String. 246 // The value must be stored DER-encoded, as a ASN.1 IA5String.
236 crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free> domain_ia5( 247 ScopedASN1_STRING domain_ia5(ASN1_IA5STRING_new());
237 ASN1_IA5STRING_new());
238 if (!domain_ia5.get() || 248 if (!domain_ia5.get() ||
239 !ASN1_STRING_set(domain_ia5.get(), domain.data(), domain.size())) 249 !ASN1_STRING_set(domain_ia5.get(), domain.data(), domain.size()))
240 return false; 250 return false;
241 251
242 std::string domain_der; 252 std::string domain_der;
243 int domain_der_len = i2d_ASN1_IA5STRING(domain_ia5.get(), NULL); 253 int domain_der_len = i2d_ASN1_IA5STRING(domain_ia5.get(), NULL);
244 if (domain_der_len < 0) 254 if (domain_der_len < 0)
245 return false; 255 return false;
246 256
247 domain_der.resize(domain_der_len); 257 domain_der.resize(domain_der_len);
248 unsigned char* domain_der_data = 258 unsigned char* domain_der_data =
249 reinterpret_cast<unsigned char*>(&domain_der[0]); 259 reinterpret_cast<unsigned char*>(&domain_der[0]);
250 if (i2d_ASN1_IA5STRING(domain_ia5.get(), &domain_der_data) < 0) 260 if (i2d_ASN1_IA5STRING(domain_ia5.get(), &domain_der_data) < 0)
251 return false; 261 return false;
252 262
253 crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free> domain_str( 263 ScopedASN1_OCTET_STRING domain_str(ASN1_OCTET_STRING_new());
254 ASN1_OCTET_STRING_new());
255 if (!domain_str.get() || 264 if (!domain_str.get() ||
256 !ASN1_STRING_set(domain_str.get(), domain_der.data(), domain_der.size())) 265 !ASN1_STRING_set(domain_str.get(), domain_der.data(), domain_der.size()))
257 return false; 266 return false;
258 267
259 crypto::ScopedOpenSSL<X509_EXTENSION, X509_EXTENSION_free> ext( 268 ScopedX509_EXTENSION ext(X509_EXTENSION_create_by_OBJ(
260 X509_EXTENSION_create_by_OBJ( 269 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)) { 270 if (!ext.get() || !X509_add_ext(cert.get(), ext.get(), -1)) {
263 return false; 271 return false;
264 } 272 }
265 273
266 // Sign and encode it. 274 // Sign and encode it.
267 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_cert); 275 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_cert);
268 } 276 }
269 277
270 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, 278 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
271 DigestAlgorithm alg, 279 DigestAlgorithm alg,
272 const std::string& common_name, 280 const std::string& common_name,
273 uint32 serial_number, 281 uint32 serial_number,
274 base::Time not_valid_before, 282 base::Time not_valid_before,
275 base::Time not_valid_after, 283 base::Time not_valid_after,
276 std::string* der_encoded) { 284 std::string* der_encoded) {
277 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 285 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
278 crypto::ScopedOpenSSL<X509, X509_free> cert( 286 ScopedX509 cert(CreateCertificate(key->key(),
279 CreateCertificate(key->key(), 287 alg,
280 alg, 288 common_name,
281 common_name, 289 serial_number,
282 serial_number, 290 not_valid_before,
283 not_valid_before, 291 not_valid_after));
284 not_valid_after));
285 if (!cert.get()) 292 if (!cert.get())
286 return false; 293 return false;
287 294
288 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded); 295 return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_encoded);
289 } 296 }
290 297
291 bool ParsePrincipalKeyAndValue(X509_NAME_ENTRY* entry, 298 bool ParsePrincipalKeyAndValue(X509_NAME_ENTRY* entry,
292 std::string* key, 299 std::string* key,
293 std::string* value) { 300 std::string* value) {
294 if (key) { 301 if (key) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 x509_time->length); 352 x509_time->length);
346 353
347 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ? 354 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ?
348 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; 355 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME;
349 return ParseCertificateDate(str_date, format, time); 356 return ParseCertificateDate(str_date, format, time);
350 } 357 }
351 358
352 } // namespace x509_util 359 } // namespace x509_util
353 360
354 } // namespace net 361 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/x509_certificate_openssl.cc ('k') | net/cert/x509_util_openssl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698