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.h" | 5 #include "net/cert/x509_util.h" |
6 #include "net/cert/x509_util_nss.h" | 6 #include "net/cert/x509_util_nss.h" |
7 | 7 |
8 #include <cert.h> // Must be included before certdb.h | 8 #include <cert.h> // Must be included before certdb.h |
9 #include <certdb.h> | 9 #include <certdb.h> |
10 #include <cryptohi.h> | 10 #include <cryptohi.h> |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 } | 127 } |
128 | 128 |
129 // Cleanup for resources used to generate the cert. | 129 // Cleanup for resources used to generate the cert. |
130 CERT_DestroyName(subject_name); | 130 CERT_DestroyName(subject_name); |
131 CERT_DestroyValidity(validity); | 131 CERT_DestroyValidity(validity); |
132 CERT_DestroyCertificateRequest(cert_request); | 132 CERT_DestroyCertificateRequest(cert_request); |
133 | 133 |
134 return cert; | 134 return cert; |
135 } | 135 } |
136 | 136 |
| 137 SECOidTag HashAlgorithmToIdTag(crypto::HMAC::HashAlgorithm alg) { |
| 138 SECOidTag id_tag = SEC_OID_UNKNOWN; |
| 139 switch (alg) { |
| 140 case crypto::HMAC::SHA1: |
| 141 id_tag = SEC_OID_SHA1; |
| 142 break; |
| 143 case crypto::HMAC::SHA256: |
| 144 id_tag = SEC_OID_SHA256; |
| 145 break; |
| 146 } |
| 147 return id_tag; |
| 148 } |
| 149 |
137 // Signs a certificate object, with |key| generating a new X509Certificate | 150 // Signs a certificate object, with |key| generating a new X509Certificate |
138 // and destroying the passed certificate object (even when NULL is returned). | 151 // and destroying the passed certificate object (even when NULL is returned). |
139 // The logic of this method references SignCert() in NSS utility certutil: | 152 // The logic of this method references SignCert() in NSS utility certutil: |
140 // http://mxr.mozilla.org/security/ident?i=SignCert. | 153 // http://mxr.mozilla.org/security/ident?i=SignCert. |
141 // Returns true on success or false if an error is encountered in the | 154 // Returns true on success or false if an error is encountered in the |
142 // certificate signing process. | 155 // certificate signing process. |
143 bool SignCertificate( | 156 bool SignCertificate( |
144 CERTCertificate* cert, | 157 CERTCertificate* cert, |
145 SECKEYPrivateKey* key) { | 158 SECKEYPrivateKey* key, |
| 159 SECOidTag alg_id_tag) { |
146 // |arena| is used to encode the cert. | 160 // |arena| is used to encode the cert. |
147 PLArenaPool* arena = cert->arena; | 161 PLArenaPool* arena = cert->arena; |
148 SECOidTag algo_id = SEC_GetSignatureAlgorithmOidTag(key->keyType, | 162 SECOidTag algo_id = SEC_GetSignatureAlgorithmOidTag(key->keyType, alg_id_tag); |
149 SEC_OID_SHA1); | |
150 if (algo_id == SEC_OID_UNKNOWN) | 163 if (algo_id == SEC_OID_UNKNOWN) |
151 return false; | 164 return false; |
152 | 165 |
153 SECStatus rv = SECOID_SetAlgorithmID(arena, &cert->signature, algo_id, 0); | 166 SECStatus rv = SECOID_SetAlgorithmID(arena, &cert->signature, algo_id, 0); |
154 if (rv != SECSuccess) | 167 if (rv != SECSuccess) |
155 return false; | 168 return false; |
156 | 169 |
157 // Generate a cert of version 3. | 170 // Generate a cert of version 3. |
158 *(cert->version.data) = 2; | 171 *(cert->version.data) = 2; |
159 cert->version.len = 1; | 172 cert->version.len = 1; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 245 |
233 return name.release(); | 246 return name.release(); |
234 } | 247 } |
235 | 248 |
236 #endif // defined(USE_NSS) || defined(OS_IOS) | 249 #endif // defined(USE_NSS) || defined(OS_IOS) |
237 | 250 |
238 } // namespace | 251 } // namespace |
239 | 252 |
240 namespace x509_util { | 253 namespace x509_util { |
241 | 254 |
242 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, | 255 bool CreateSelfSignedCertInternal(crypto::RSAPrivateKey* key, |
243 const std::string& subject, | 256 crypto::HMAC::HashAlgorithm alg, |
244 uint32 serial_number, | 257 const std::string& subject, |
245 base::Time not_valid_before, | 258 uint32 serial_number, |
246 base::Time not_valid_after, | 259 base::Time not_valid_before, |
247 std::string* der_cert) { | 260 base::Time not_valid_after, |
| 261 std::string* der_cert) { |
248 DCHECK(key); | 262 DCHECK(key); |
249 CERTCertificate* cert = CreateCertificate(key->public_key(), | 263 CERTCertificate* cert = CreateCertificate(key->public_key(), |
250 subject, | 264 subject, |
251 serial_number, | 265 serial_number, |
252 not_valid_before, | 266 not_valid_before, |
253 not_valid_after); | 267 not_valid_after); |
254 if (!cert) | 268 if (!cert) |
255 return false; | 269 return false; |
256 | 270 |
257 if (!SignCertificate(cert, key->key())) { | 271 if (!SignCertificate(cert, key->key(), HashAlgorithmToIdTag(alg))) { |
258 CERT_DestroyCertificate(cert); | 272 CERT_DestroyCertificate(cert); |
259 return false; | 273 return false; |
260 } | 274 } |
261 | 275 |
262 der_cert->assign(reinterpret_cast<char*>(cert->derCert.data), | 276 der_cert->assign(reinterpret_cast<char*>(cert->derCert.data), |
263 cert->derCert.len); | 277 cert->derCert.len); |
264 CERT_DestroyCertificate(cert); | 278 CERT_DestroyCertificate(cert); |
265 return true; | 279 return true; |
266 } | 280 } |
267 | 281 |
268 bool IsSupportedValidityRange(base::Time not_valid_before, | 282 bool IsSupportedValidityRange(base::Time not_valid_before, |
269 base::Time not_valid_after) { | 283 base::Time not_valid_after) { |
270 CERTValidity* validity = CERT_CreateValidity( | 284 CERTValidity* validity = CERT_CreateValidity( |
271 crypto::BaseTimeToPRTime(not_valid_before), | 285 crypto::BaseTimeToPRTime(not_valid_before), |
272 crypto::BaseTimeToPRTime(not_valid_after)); | 286 crypto::BaseTimeToPRTime(not_valid_after)); |
273 | 287 |
274 if (!validity) | 288 if (!validity) |
275 return false; | 289 return false; |
276 | 290 |
277 CERT_DestroyValidity(validity); | 291 CERT_DestroyValidity(validity); |
278 return true; | 292 return true; |
279 } | 293 } |
280 | 294 |
281 bool CreateDomainBoundCertEC(crypto::ECPrivateKey* key, | 295 bool CreateDomainBoundCertECInternal(crypto::ECPrivateKey* key, |
282 const std::string& domain, | 296 crypto::HMAC::HashAlgorithm alg, |
283 uint32 serial_number, | 297 const std::string& domain, |
284 base::Time not_valid_before, | 298 uint32 serial_number, |
285 base::Time not_valid_after, | 299 base::Time not_valid_before, |
286 std::string* der_cert) { | 300 base::Time not_valid_after, |
| 301 std::string* der_cert) { |
287 DCHECK(key); | 302 DCHECK(key); |
288 | 303 |
289 CERTCertificate* cert = CreateCertificate(key->public_key(), | 304 CERTCertificate* cert = CreateCertificate(key->public_key(), |
290 "CN=anonymous.invalid", | 305 "CN=anonymous.invalid", |
291 serial_number, | 306 serial_number, |
292 not_valid_before, | 307 not_valid_before, |
293 not_valid_after); | 308 not_valid_after); |
294 | 309 |
295 if (!cert) | 310 if (!cert) |
296 return false; | 311 return false; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 return false; | 348 return false; |
334 } | 349 } |
335 | 350 |
336 // Copy extension into x509 cert | 351 // Copy extension into x509 cert |
337 if (CERT_FinishExtensions(cert_handle) != SECSuccess){ | 352 if (CERT_FinishExtensions(cert_handle) != SECSuccess){ |
338 LOG(ERROR) << "Unable to copy extension to X509 cert"; | 353 LOG(ERROR) << "Unable to copy extension to X509 cert"; |
339 CERT_DestroyCertificate(cert); | 354 CERT_DestroyCertificate(cert); |
340 return false; | 355 return false; |
341 } | 356 } |
342 | 357 |
343 if (!SignCertificate(cert, key->key())) { | 358 if (!SignCertificate(cert, key->key(), HashAlgorithmToIdTag(alg))) { |
344 CERT_DestroyCertificate(cert); | 359 CERT_DestroyCertificate(cert); |
345 return false; | 360 return false; |
346 } | 361 } |
347 | 362 |
348 DCHECK(cert->derCert.len); | 363 DCHECK(cert->derCert.len); |
349 // XXX copied from X509Certificate::GetDEREncoded | 364 // XXX copied from X509Certificate::GetDEREncoded |
350 der_cert->clear(); | 365 der_cert->clear(); |
351 der_cert->append(reinterpret_cast<char*>(cert->derCert.data), | 366 der_cert->append(reinterpret_cast<char*>(cert->derCert.data), |
352 cert->derCert.len); | 367 cert->derCert.len); |
353 CERT_DestroyCertificate(cert); | 368 CERT_DestroyCertificate(cert); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 } | 630 } |
616 | 631 |
617 return new_name; | 632 return new_name; |
618 } | 633 } |
619 | 634 |
620 #endif // defined(USE_NSS) || defined(OS_IOS) | 635 #endif // defined(USE_NSS) || defined(OS_IOS) |
621 | 636 |
622 } // namespace x509_util | 637 } // namespace x509_util |
623 | 638 |
624 } // namespace net | 639 } // namespace net |
OLD | NEW |