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

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

Issue 2400033005: Use BoringSSL scopers in //net. (Closed)
Patch Set: eroman comments Created 4 years, 2 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
« no previous file with comments | « net/cert/x509_certificate_openssl.cc ('k') | net/quic/chromium/crypto/proof_source_chromium.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 <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
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
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
OLDNEW
« no previous file with comments | « net/cert/x509_certificate_openssl.cc ('k') | net/quic/chromium/crypto/proof_source_chromium.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698