Chromium Code Reviews| Index: net/base/x509_certificate_nss.cc |
| diff --git a/net/base/x509_certificate_nss.cc b/net/base/x509_certificate_nss.cc |
| index 7224020cb44e528318c204f10f3d6e70ff0dced2..095974afc03a63a3fb89ca9562ffc171e8aee8ca 100644 |
| --- a/net/base/x509_certificate_nss.cc |
| +++ b/net/base/x509_certificate_nss.cc |
| @@ -18,6 +18,7 @@ |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/memory/singleton.h" |
| #include "base/pickle.h" |
| #include "base/time.h" |
| #include "crypto/nss_util.h" |
| @@ -31,6 +32,46 @@ namespace net { |
| namespace { |
| +class ObCertOIDWrapper { |
| + private: |
| + ObCertOIDWrapper(); |
| + |
| + public: |
| + static SECOidTag ObCertOIDTag; |
| + |
| + static ObCertOIDWrapper* GetInstance() { |
| + return Singleton<ObCertOIDWrapper>::get(); |
| + } |
| + |
| + friend struct DefaultSingletonTraits<ObCertOIDWrapper>; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ObCertOIDWrapper); |
| +}; |
|
wtc
2011/08/19 18:18:08
The public: section should precede the private: se
mdietz
2011/08/22 20:09:00
Done.
|
| + |
| +SECOidTag ObCertOIDWrapper::ObCertOIDTag; |
| + |
| +ObCertOIDWrapper::ObCertOIDWrapper() { |
| + // It's harmless if multiple threads enter this block concurrently. |
|
wtc
2011/08/19 18:18:08
Delete this line.
mdietz
2011/08/22 20:09:00
Done.
|
| + // 1.3.6.1.4.1.11129.2.1.6 |
| + // (iso.org.dod.internet.private.enterprises.google.googleSecurity. |
| + // certificateExtensions.originBoundCertificate) |
| + static const uint8 kObCertOID[] = { |
| + 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x06 |
| + }; |
| + SECOidData oid_data; |
| + memset(&oid_data, 0, sizeof(oid_data)); |
| + oid_data.oid.data = const_cast<uint8*>(kObCertOID); |
| + oid_data.oid.len = sizeof(kObCertOID); |
| + oid_data.offset = SEC_OID_UNKNOWN; |
| + oid_data.desc = "Origin Bound Certificate"; |
| + oid_data.mechanism = CKM_INVALID_MECHANISM; |
| + oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION; |
| + ObCertOIDWrapper::ObCertOIDTag = SECOID_AddEntry(&oid_data); |
| + if(ObCertOIDWrapper::ObCertOIDTag == SEC_OID_UNKNOWN) { |
| + LOG(ERROR) << "OB_CERT OID tag creation failed"; |
| + } |
|
wtc
2011/08/19 18:18:08
Remove the curly braces for one-liner if bodies.
mdietz
2011/08/22 20:09:00
Done, also added space to fit "if (" coding style.
|
| +} |
| + |
| class ScopedCERTCertificatePolicies { |
| public: |
| explicit ScopedCERTCertificatePolicies(CERTCertificatePolicies* policies) |
| @@ -624,13 +665,11 @@ void X509Certificate::Initialize() { |
| } |
| // static |
| -X509Certificate* X509Certificate::CreateSelfSigned( |
| +CERTCertificate* CreateCertificate( |
|
wtc
2011/08/19 18:18:08
Remove the
// static
comments for CreateCertific
mdietz
2011/08/22 20:09:00
Done.
|
| crypto::RSAPrivateKey* key, |
| const std::string& subject, |
| uint32 serial_number, |
| base::TimeDelta valid_duration) { |
| - DCHECK(key); |
| - |
| // Create info about public key. |
| CERTSubjectPublicKeyInfo* spki = |
| SECKEY_CreateSubjectPublicKeyInfo(key->public_key()); |
| @@ -668,12 +707,13 @@ X509Certificate* X509Certificate::CreateSelfSigned( |
| CERT_DestroyValidity(validity); |
| CERT_DestroyCertificateRequest(cert_request); |
| - if (!cert) |
| - return NULL; |
| - |
| - // Sign the cert here. The logic of this method references SignCert() in NSS |
| - // utility certutil: http://mxr.mozilla.org/security/ident?i=SignCert. |
| + return cert; |
| +} |
| +// static |
| +X509Certificate* SignCertificate( |
|
wtc
2011/08/19 18:18:08
The comment for this function should point out the
mdietz
2011/08/22 20:09:00
Added the TODO for now. If I get a chance, I'll d
|
| + CERTCertificate* cert, |
| + crypto::RSAPrivateKey* key) { |
| // |arena| is used to encode the cert. |
| PRArenaPool* arena = cert->arena; |
| SECOidTag algo_id = SEC_GetSignatureAlgorithmOidTag(key->key()->keyType, |
| @@ -722,11 +762,39 @@ X509Certificate* X509Certificate::CreateSelfSigned( |
| // Save the signed result to the cert. |
| cert->derCert = *result; |
| - X509Certificate* x509_cert = CreateFromHandle(cert, OSCertHandles()); |
| + X509Certificate* x509_cert = |
| + X509Certificate::CreateFromHandle(cert, X509Certificate::OSCertHandles()); |
| CERT_DestroyCertificate(cert); |
| return x509_cert; |
| } |
| +// static |
| +X509Certificate* X509Certificate::CreateSelfSigned( |
| + crypto::RSAPrivateKey* key, |
| + const std::string& subject, |
| + uint32 serial_number, |
| + base::TimeDelta valid_duration) { |
| + DCHECK(key); |
| + |
| + CERTCertificate* cert = CreateCertificate(key, |
| + subject, |
| + serial_number, |
| + valid_duration); |
| + |
| + if(!cert) |
| + return NULL; |
| + |
| + // Sign the cert here. The logic of this method references SignCert() in NSS |
| + // utility certutil: http://mxr.mozilla.org/security/ident?i=SignCert. |
|
wtc
2011/08/19 18:18:08
Move this comment before the SignCertificate() fun
mdietz
2011/08/22 20:09:00
Done.
|
| + |
| + X509Certificate* x509_cert = SignCertificate(cert, key); |
| + |
| + if(!x509_cert) |
| + return NULL; |
|
wtc
2011/08/19 18:18:08
Remove this, because this is handled by the
retu
mdietz
2011/08/22 20:09:00
Done.
|
| + |
| + return x509_cert; |
| +} |
| + |
| void X509Certificate::GetSubjectAltName( |
| std::vector<std::string>* dns_names, |
| std::vector<std::string>* ip_addrs) const { |
| @@ -770,6 +838,79 @@ void X509Certificate::GetSubjectAltName( |
| PORT_FreeArena(arena, PR_FALSE); |
| } |
| +// static |
| +X509Certificate* X509Certificate::CreateOriginBound( |
|
wtc
2011/08/19 18:18:08
Move this function up to follow CreateSelfSigned()
mdietz
2011/08/22 20:09:00
Done.
|
| + crypto::RSAPrivateKey* key, |
| + const std::string& subject, |
| + const std::string& origin, |
| + uint32 serial_number, |
| + base::TimeDelta valid_duration) { |
| + DCHECK(key); |
| + |
| + CERTCertificate* cert = CreateCertificate(key, |
| + subject, |
|
wtc
2011/08/19 18:18:08
Change
subject
to
"CN=anonymous.invalid"
|
| + serial_number, |
| + valid_duration); |
| + |
| + if(!cert) |
| + return NULL; |
| + |
| + SECStatus ok; |
| + |
| + // Create opaque handle used to add extensions later. |
| + void* cert_handle; |
| + if ((cert_handle = CERT_StartCertExtensions(cert)) == NULL) { |
| + LOG(ERROR) << "Unable to get opaque handle for adding extensions"; |
| + return NULL; |
| + } |
| + |
| + // Create stack allocated SECItem for IA5String encoding |
|
wtc
2011/08/19 18:18:08
Nit: remove "stack allocated". Add a period.
mdietz
2011/08/22 20:09:00
Done.
|
| + SECItem origin_string_item = { |
| + siAsciiString, |
| + (unsigned char*)origin.data(), |
| + origin.size() |
| + }; |
| + |
| + // IA5Encode and arena allocate SECItem |
| + SECItem* asn1_origin_string; |
| + if ((asn1_origin_string = SEC_ASN1EncodeItem(cert->arena, |
| + NULL, |
| + &origin_string_item, |
| + SEC_ASN1_GET( |
| + SEC_IA5StringTemplate |
| + ))) |
| + == NULL){ |
|
wtc
2011/08/19 18:18:08
I would format this as follows:
SECItem* asn1_or
mdietz
2011/08/22 20:09:00
Much cleaner, thanks.
On 2011/08/19 18:18:08, wtc
|
| + LOG(ERROR) << "Unable to get ASN1 encoding for origin in ob_cert extension"; |
| + return NULL; |
| + } |
| + |
| + // Add the extension to the opaque handle |
| + if((ok = CERT_AddExtension(cert_handle, |
|
rkn
2011/08/18 22:59:41
Can you replace all instances of "if(" with "if ("
wtc
2011/08/19 18:18:08
No need to save the function return value in the '
mdietz
2011/08/22 20:09:00
Done.
|
| + ObCertOIDWrapper::GetInstance()->ObCertOIDTag, |
| + asn1_origin_string, |
| + PR_TRUE, PR_TRUE)) |
| + != SECSuccess){ |
| + LOG(ERROR) << "Unable to add origin bound cert extension to opaque handle"; |
| + return NULL; |
| + } |
| + |
| + // Copy extension into x509 cert |
| + if((ok = CERT_FinishExtensions(cert_handle)) != SECSuccess){ |
| + LOG(ERROR) << "Unable to copy extension to X509 cert"; |
| + return NULL; |
| + } |
| + |
| + // Sign the cert here. The logic of this method references SignCert() in NSS |
| + // utility certutil: http://mxr.mozilla.org/security/ident?i=SignCert. |
| + |
| + X509Certificate* x509_cert = SignCertificate(cert, key); |
| + |
| + if(!x509_cert) |
| + return NULL; |
| + |
| + return x509_cert; |
| +} |
| + |
| int X509Certificate::VerifyInternal(const std::string& hostname, |
| int flags, |
| CertVerifyResult* verify_result) const { |