| 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 |