Chromium Code Reviews| 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) { | |
|
Ryan Sleevi
2013/10/18 22:45:23
ToSECOid
bemasc
2013/10/19 00:47:45
Done.
| |
| 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) { | |
|
Ryan Sleevi
2013/10/18 22:45:23
s/alg_id_tag/hash_algorithm/
bemasc
2013/10/19 00:47:45
Done.
| |
| 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 DCHECK(!strncmp(subject.c_str(), "CN=", 3U)); | 263 DCHECK(!strncmp(subject.c_str(), "CN=", 3U)); |
| 250 CERTCertificate* cert = CreateCertificate(key->public_key(), | 264 CERTCertificate* cert = CreateCertificate(key->public_key(), |
| 251 subject, | 265 subject, |
| 252 serial_number, | 266 serial_number, |
| 253 not_valid_before, | 267 not_valid_before, |
| 254 not_valid_after); | 268 not_valid_after); |
| 255 if (!cert) | 269 if (!cert) |
| 256 return false; | 270 return false; |
| 257 | 271 |
| 258 if (!SignCertificate(cert, key->key())) { | 272 if (!SignCertificate(cert, key->key(), HashAlgorithmToIdTag(alg))) { |
| 259 CERT_DestroyCertificate(cert); | 273 CERT_DestroyCertificate(cert); |
| 260 return false; | 274 return false; |
| 261 } | 275 } |
| 262 | 276 |
| 263 der_cert->assign(reinterpret_cast<char*>(cert->derCert.data), | 277 der_cert->assign(reinterpret_cast<char*>(cert->derCert.data), |
| 264 cert->derCert.len); | 278 cert->derCert.len); |
| 265 CERT_DestroyCertificate(cert); | 279 CERT_DestroyCertificate(cert); |
| 266 return true; | 280 return true; |
| 267 } | 281 } |
| 268 | 282 |
| 269 bool IsSupportedValidityRange(base::Time not_valid_before, | 283 bool IsSupportedValidityRange(base::Time not_valid_before, |
| 270 base::Time not_valid_after) { | 284 base::Time not_valid_after) { |
| 271 CERTValidity* validity = CERT_CreateValidity( | 285 CERTValidity* validity = CERT_CreateValidity( |
| 272 crypto::BaseTimeToPRTime(not_valid_before), | 286 crypto::BaseTimeToPRTime(not_valid_before), |
| 273 crypto::BaseTimeToPRTime(not_valid_after)); | 287 crypto::BaseTimeToPRTime(not_valid_after)); |
| 274 | 288 |
| 275 if (!validity) | 289 if (!validity) |
| 276 return false; | 290 return false; |
| 277 | 291 |
| 278 CERT_DestroyValidity(validity); | 292 CERT_DestroyValidity(validity); |
| 279 return true; | 293 return true; |
| 280 } | 294 } |
| 281 | 295 |
| 282 bool CreateDomainBoundCertEC(crypto::ECPrivateKey* key, | 296 bool CreateDomainBoundCertECInternal(crypto::ECPrivateKey* key, |
| 283 const std::string& domain, | 297 crypto::HMAC::HashAlgorithm alg, |
| 284 uint32 serial_number, | 298 const std::string& domain, |
| 285 base::Time not_valid_before, | 299 uint32 serial_number, |
| 286 base::Time not_valid_after, | 300 base::Time not_valid_before, |
| 287 std::string* der_cert) { | 301 base::Time not_valid_after, |
| 302 std::string* der_cert) { | |
| 288 DCHECK(key); | 303 DCHECK(key); |
| 289 | 304 |
| 290 CERTCertificate* cert = CreateCertificate(key->public_key(), | 305 CERTCertificate* cert = CreateCertificate(key->public_key(), |
| 291 "CN=anonymous.invalid", | 306 "CN=anonymous.invalid", |
| 292 serial_number, | 307 serial_number, |
| 293 not_valid_before, | 308 not_valid_before, |
| 294 not_valid_after); | 309 not_valid_after); |
| 295 | 310 |
| 296 if (!cert) | 311 if (!cert) |
| 297 return false; | 312 return false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 334 return false; | 349 return false; |
| 335 } | 350 } |
| 336 | 351 |
| 337 // Copy extension into x509 cert | 352 // Copy extension into x509 cert |
| 338 if (CERT_FinishExtensions(cert_handle) != SECSuccess){ | 353 if (CERT_FinishExtensions(cert_handle) != SECSuccess){ |
| 339 LOG(ERROR) << "Unable to copy extension to X509 cert"; | 354 LOG(ERROR) << "Unable to copy extension to X509 cert"; |
| 340 CERT_DestroyCertificate(cert); | 355 CERT_DestroyCertificate(cert); |
| 341 return false; | 356 return false; |
| 342 } | 357 } |
| 343 | 358 |
| 344 if (!SignCertificate(cert, key->key())) { | 359 if (!SignCertificate(cert, key->key(), HashAlgorithmToIdTag(alg))) { |
| 345 CERT_DestroyCertificate(cert); | 360 CERT_DestroyCertificate(cert); |
| 346 return false; | 361 return false; |
| 347 } | 362 } |
| 348 | 363 |
| 349 DCHECK(cert->derCert.len); | 364 DCHECK(cert->derCert.len); |
| 350 // XXX copied from X509Certificate::GetDEREncoded | 365 // XXX copied from X509Certificate::GetDEREncoded |
| 351 der_cert->clear(); | 366 der_cert->clear(); |
| 352 der_cert->append(reinterpret_cast<char*>(cert->derCert.data), | 367 der_cert->append(reinterpret_cast<char*>(cert->derCert.data), |
| 353 cert->derCert.len); | 368 cert->derCert.len); |
| 354 CERT_DestroyCertificate(cert); | 369 CERT_DestroyCertificate(cert); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 } | 631 } |
| 617 | 632 |
| 618 return new_name; | 633 return new_name; |
| 619 } | 634 } |
| 620 | 635 |
| 621 #endif // defined(USE_NSS) || defined(OS_IOS) | 636 #endif // defined(USE_NSS) || defined(OS_IOS) |
| 622 | 637 |
| 623 } // namespace x509_util | 638 } // namespace x509_util |
| 624 | 639 |
| 625 } // namespace net | 640 } // namespace net |
| OLD | NEW |