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

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

Issue 27832002: Sign self-signed certs with SHA256. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 1 month 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
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 "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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698