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

Unified Diff: net/cert/ct_objects_extractor_nss.cc

Issue 1882433002: Removing NSS files and USE_OPENSSL flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/cert/ct_log_verifier_nss.cc ('k') | net/cert/ev_root_ca_metadata.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/ct_objects_extractor_nss.cc
diff --git a/net/cert/ct_objects_extractor_nss.cc b/net/cert/ct_objects_extractor_nss.cc
deleted file mode 100644
index 76a3be51d2ef4b5c467ec6521634b8f08ad89857..0000000000000000000000000000000000000000
--- a/net/cert/ct_objects_extractor_nss.cc
+++ /dev/null
@@ -1,619 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/cert/ct_objects_extractor.h"
-
-#include <cert.h>
-#include <secasn1.h>
-#include <secitem.h>
-#include <secoid.h>
-
-#include "base/lazy_instance.h"
-#include "base/macros.h"
-#include "base/sha1.h"
-#include "crypto/scoped_nss_types.h"
-#include "crypto/sha2.h"
-#include "net/cert/asn1_util.h"
-#include "net/cert/scoped_nss_types.h"
-#include "net/cert/signed_certificate_timestamp.h"
-#include "net/der/input.h"
-#include "net/der/parser.h"
-
-namespace net {
-
-namespace ct {
-
-namespace {
-
-// NSS black magic to get the address of externally defined template at runtime.
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
-SEC_ASN1_MKSUB(CERT_SequenceOfCertExtensionTemplate)
-
-// Wrapper class to convert a X509Certificate::OSCertHandle directly
-// into a CERTCertificate* usable with other NSS functions. This is used for
-// platforms where X509Certificate::OSCertHandle refers to a different type
-// than a CERTCertificate*.
-struct NSSCertWrapper {
- explicit NSSCertWrapper(X509Certificate::OSCertHandle cert_handle);
- ~NSSCertWrapper() {}
-
- ScopedCERTCertificate cert;
-};
-
-NSSCertWrapper::NSSCertWrapper(X509Certificate::OSCertHandle cert_handle) {
-#if defined(USE_NSS_CERTS)
- cert.reset(CERT_DupCertificate(cert_handle));
-#else
- SECItem der_cert;
- std::string der_data;
- if (!X509Certificate::GetDEREncoded(cert_handle, &der_data))
- return;
- der_cert.data =
- reinterpret_cast<unsigned char*>(const_cast<char*>(der_data.data()));
- der_cert.len = der_data.size();
-
- // Note: CERT_NewTempCertificate may return NULL if the certificate
- // shares a serial number with another cert issued by the same CA,
- // which is not supposed to happen.
- cert.reset(CERT_NewTempCertificate(
- CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE));
-#endif
- DCHECK(cert.get() != NULL);
-}
-
-// The wire form of the OID 1.3.6.1.4.1.11129.2.4.2. See Section 3.3 of
-// RFC6962.
-const unsigned char kEmbeddedSCTOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01,
- 0xD6, 0x79, 0x02, 0x04, 0x02};
-const char kEmbeddedSCTDescription[] =
- "X.509v3 Certificate Transparency Embedded Signed Certificate Timestamp "
- "List";
-
-// The wire form of the OID 1.3.6.1.4.1.11129.2.4.5 - OCSP SingleExtension for
-// X.509v3 Certificate Transparency Signed Certificate Timestamp List, see
-// Section 3.3 of RFC6962.
-const unsigned char kOCSPExtensionOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01,
- 0xD6, 0x79, 0x02, 0x04, 0x05};
-
-const SECItem kOCSPExtensionOidItem = {
- siBuffer, const_cast<unsigned char*>(kOCSPExtensionOid),
- sizeof(kOCSPExtensionOid)
-};
-
-// id-ad-ocsp: 1.3.6.1.5.5.7.48.1.1
-const unsigned char kBasicOCSPResponseOid[] = {0x2B, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x30, 0x01, 0x01};
-
-const SECItem kBasicOCSPResponseOidItem = {
- siBuffer, const_cast<unsigned char*>(kBasicOCSPResponseOid),
- sizeof(kBasicOCSPResponseOid)
-};
-
-
-// Initializes the necessary NSS internals for use with Certificate
-// Transparency.
-class CTInitSingleton {
- public:
- SECOidTag embedded_oid() const { return embedded_oid_; }
-
- private:
- friend struct base::DefaultLazyInstanceTraits<CTInitSingleton>;
-
- CTInitSingleton() : embedded_oid_(SEC_OID_UNKNOWN) {
- embedded_oid_ = RegisterOid(
- kEmbeddedSCTOid, sizeof(kEmbeddedSCTOid), kEmbeddedSCTDescription);
- }
-
- ~CTInitSingleton() {}
-
- SECOidTag RegisterOid(const unsigned char* oid,
- unsigned int oid_len,
- const char* description) {
- SECOidData oid_data;
- oid_data.oid.len = oid_len;
- oid_data.oid.data = const_cast<unsigned char*>(oid);
- oid_data.offset = SEC_OID_UNKNOWN;
- oid_data.desc = description;
- oid_data.mechanism = CKM_INVALID_MECHANISM;
- // Setting this to SUPPORTED_CERT_EXTENSION ensures that if a certificate
- // contains this extension with the critical bit set, NSS will not reject
- // it. However, because verification of this extension happens after NSS,
- // it is currently left as INVALID_CERT_EXTENSION.
- oid_data.supportedExtension = INVALID_CERT_EXTENSION;
-
- SECOidTag result = SECOID_AddEntry(&oid_data);
- CHECK_NE(SEC_OID_UNKNOWN, result);
-
- return result;
- }
-
- SECOidTag embedded_oid_;
-
- DISALLOW_COPY_AND_ASSIGN(CTInitSingleton);
-};
-
-base::LazyInstance<CTInitSingleton>::Leaky g_ct_singleton =
- LAZY_INSTANCE_INITIALIZER;
-
-// Obtains the data for an X.509v3 certificate extension identified by |oid|
-// and encoded as an OCTET STRING. Returns true if the extension was found in
-// the certificate, updating |ext_data| to be the extension data after removing
-// the DER encoding of OCTET STRING.
-bool GetCertOctetStringExtension(CERTCertificate* cert,
- SECOidTag oid,
- std::string* extension_data) {
- SECItem extension;
- SECStatus rv = CERT_FindCertExtension(cert, oid, &extension);
- if (rv != SECSuccess)
- return false;
-
- der::Parser parser(der::Input(extension.data, extension.len));
- der::Input parsed_extension;
- if (!parser.ReadTag(der::kOctetString, &parsed_extension) ||
- parser.HasMore()) { // Decoding failure or raw data left
- rv = SECFailure;
- } else {
- *extension_data = parsed_extension.AsString();
- }
-
- SECITEM_FreeItem(&extension, PR_FALSE);
- return rv == SECSuccess;
-}
-
-// NSS offers CERT_FindCertExtension for certificates, but that only accepts
-// CERTCertificate* inputs, so the method below extracts the SCT extension
-// directly from the CERTCertExtension** of an OCSP response.
-//
-// Obtains the data for an OCSP extension identified by kOCSPExtensionOidItem
-// and encoded as an OCTET STRING. Returns true if the extension was found in
-// |extensions|, updating |extension_data| to be the extension data after
-// removing the DER encoding of OCTET STRING.
-bool GetSCTListFromOCSPExtension(PLArenaPool* arena,
- const CERTCertExtension* const* extensions,
- std::string* extension_data) {
- if (!extensions)
- return false;
-
- const CERTCertExtension* match = NULL;
-
- for (const CERTCertExtension* const* exts = extensions; *exts; ++exts) {
- const CERTCertExtension* ext = *exts;
- if (SECITEM_ItemsAreEqual(&kOCSPExtensionOidItem, &ext->id)) {
- match = ext;
- break;
- }
- }
-
- if (!match)
- return false;
-
- SECItem contents;
- // SEC_QuickDERDecodeItem sets |contents| to point to |match|, so it is not
- // necessary to free the contents of |contents|.
- SECStatus rv = SEC_QuickDERDecodeItem(arena, &contents,
- SEC_ASN1_GET(SEC_OctetStringTemplate),
- &match->value);
- if (rv != SECSuccess)
- return false;
-
- base::StringPiece parsed_data(reinterpret_cast<char*>(contents.data),
- contents.len);
- parsed_data.CopyToString(extension_data);
- return true;
-}
-
-// Given a |cert|, extract the TBSCertificate from this certificate, also
-// removing the X.509 extension with OID 1.3.6.1.4.1.11129.2.4.2 (that is,
-// the embedded SCT)
-bool ExtractTBSCertWithoutSCTs(CERTCertificate* cert,
- std::string* to_be_signed) {
- SECOidData* oid = SECOID_FindOIDByTag(g_ct_singleton.Get().embedded_oid());
- if (!oid)
- return false;
-
- // This is a giant hack, due to the fact that NSS does not expose a good API
- // for simply removing certificate fields from existing certificates.
- CERTCertificate temp_cert;
- temp_cert = *cert;
- temp_cert.extensions = NULL;
-
- // Strip out the embedded SCT OID from the new certificate by directly
- // mutating the extensions in place.
- std::vector<CERTCertExtension*> new_extensions;
- if (cert->extensions) {
- for (CERTCertExtension** exts = cert->extensions; *exts; ++exts) {
- CERTCertExtension* ext = *exts;
- SECComparison result = SECITEM_CompareItem(&oid->oid, &ext->id);
- if (result != SECEqual)
- new_extensions.push_back(ext);
- }
- }
- if (!new_extensions.empty()) {
- new_extensions.push_back(NULL);
- temp_cert.extensions = &new_extensions[0];
- }
-
- crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
-
- SECItem tbs_data;
- tbs_data.len = 0;
- tbs_data.data = NULL;
- void* result = SEC_ASN1EncodeItem(arena.get(),
- &tbs_data,
- &temp_cert,
- SEC_ASN1_GET(CERT_CertificateTemplate));
- if (!result)
- return false;
-
- to_be_signed->assign(reinterpret_cast<char*>(tbs_data.data), tbs_data.len);
- return true;
-}
-
-// The following code is adapted from the NSS OCSP module, in order to expose
-// the internal structure of an OCSP response.
-
-// ResponseBytes ::= SEQUENCE {
-// responseType OBJECT IDENTIFIER,
-// response OCTET STRING }
-struct ResponseBytes {
- SECItem response_type;
- SECItem der_response;
-};
-
-const SEC_ASN1Template kResponseBytesTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ResponseBytes) },
- { SEC_ASN1_OBJECT_ID, offsetof(ResponseBytes, response_type) },
- { SEC_ASN1_OCTET_STRING, offsetof(ResponseBytes, der_response) },
- { 0 }
-};
-
-// OCSPResponse ::= SEQUENCE {
-// responseStatus OCSPResponseStatus,
-// responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
-struct OCSPResponse {
- SECItem response_status;
- // This indirection is needed because |response_bytes| is an optional
- // component and we need a way to determine if it is missing.
- ResponseBytes* response_bytes;
-};
-
-const SEC_ASN1Template kPointerToResponseBytesTemplate[] = {
- { SEC_ASN1_POINTER, 0, kResponseBytesTemplate }
-};
-
-const SEC_ASN1Template kOCSPResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OCSPResponse) },
- { SEC_ASN1_ENUMERATED, offsetof(OCSPResponse, response_status) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(OCSPResponse, response_bytes),
- kPointerToResponseBytesTemplate },
- { 0 }
-};
-
-// CertID ::= SEQUENCE {
-// hashAlgorithm AlgorithmIdentifier,
-// issuerNameHash OCTET STRING, -- Hash of Issuer's DN
-// issuerKeyHash OCTET STRING, -- Hash of Issuers public key
-// serialNumber CertificateSerialNumber }
-struct CertID {
- SECAlgorithmID hash_algorithm;
- SECItem issuer_name_hash;
- SECItem issuer_key_hash;
- SECItem serial_number;
-};
-
-const SEC_ASN1Template kCertIDTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CertID) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CertID, hash_algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING, offsetof(CertID, issuer_name_hash) },
- { SEC_ASN1_OCTET_STRING, offsetof(CertID, issuer_key_hash) },
- { SEC_ASN1_INTEGER, offsetof(CertID, serial_number) },
- { 0 }
-};
-
-// SingleResponse ::= SEQUENCE {
-// certID CertID,
-// certStatus CertStatus,
-// thisUpdate GeneralizedTime,
-// nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
-// singleExtensions [1] EXPLICIT Extensions OPTIONAL }
-struct SingleResponse {
- CertID cert_id;
- // The following three fields are not used.
- SECItem der_cert_status;
- SECItem this_update;
- SECItem next_update;
- CERTCertExtension** single_extensions;
-};
-
-const SEC_ASN1Template kSingleResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SingleResponse) },
- { SEC_ASN1_INLINE, offsetof(SingleResponse, cert_id), kCertIDTemplate },
- // Really a CHOICE but we make it an ANY because we don't care about the
- // contents of this field.
- // TODO(ekasper): use SEC_ASN1_CHOICE.
- { SEC_ASN1_ANY, offsetof(SingleResponse, der_cert_status) },
- { SEC_ASN1_GENERALIZED_TIME, offsetof(SingleResponse, this_update) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(SingleResponse, next_update),
- SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(SingleResponse, single_extensions),
- SEC_ASN1_SUB(CERT_SequenceOfCertExtensionTemplate) },
- { 0 }
-};
-
-// ResponseData ::= SEQUENCE {
-// version [0] EXPLICIT Version DEFAULT v1,
-// responderID ResponderID,
-// producedAt GeneralizedTime,
-// responses SEQUENCE OF SingleResponse,
-// responseExtensions [1] EXPLICIT Extensions OPTIONAL }
-struct ResponseData {
- // The first three fields are not used.
- SECItem version;
- SECItem der_responder_id;
- SECItem produced_at;
- SingleResponse** single_responses;
- // Skip extensions.
-};
-
-const SEC_ASN1Template kResponseDataTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ResponseData) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(ResponseData, version), SEC_ASN1_SUB(SEC_IntegerTemplate) },
- // Really a CHOICE but we make it an ANY because we don't care about the
- // contents of this field.
- // TODO(ekasper): use SEC_ASN1_CHOICE.
- { SEC_ASN1_ANY, offsetof(ResponseData, der_responder_id) },
- { SEC_ASN1_GENERALIZED_TIME, offsetof(ResponseData, produced_at) },
- { SEC_ASN1_SEQUENCE_OF, offsetof(ResponseData, single_responses),
- kSingleResponseTemplate },
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-
-// BasicOCSPResponse ::= SEQUENCE {
-// tbsResponseData ResponseData,
-// signatureAlgorithm AlgorithmIdentifier,
-// signature BIT STRING,
-// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
-struct BasicOCSPResponse {
- ResponseData tbs_response_data;
- // We do not care about the rest.
-};
-
-const SEC_ASN1Template kBasicOCSPResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(BasicOCSPResponse) },
- { SEC_ASN1_INLINE, offsetof(BasicOCSPResponse, tbs_response_data),
- kResponseDataTemplate },
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-
-bool StringEqualToSECItem(const std::string& value1, const SECItem& value2) {
- if (value1.size() != value2.len)
- return false;
- return memcmp(value1.data(), value2.data, value2.len) == 0;
-}
-
-// TODO(ekasper): also use the issuer name hash in matching.
-bool CertIDMatches(const CertID& cert_id,
- const std::string& serial_number,
- const std::string& issuer_key_sha1_hash,
- const std::string& issuer_key_sha256_hash) {
- if (!StringEqualToSECItem(serial_number, cert_id.serial_number))
- return false;
-
- SECOidTag hash_alg = SECOID_FindOIDTag(&cert_id.hash_algorithm.algorithm);
- switch (hash_alg) {
- case SEC_OID_SHA1:
- return StringEqualToSECItem(issuer_key_sha1_hash,
- cert_id.issuer_key_hash);
- case SEC_OID_SHA256:
- return StringEqualToSECItem(issuer_key_sha256_hash,
- cert_id.issuer_key_hash);
- default:
- return false;
- }
-}
-
-} // namespace
-
-bool ExtractEmbeddedSCTList(X509Certificate::OSCertHandle cert,
- std::string* sct_list) {
- DCHECK(cert);
-
- NSSCertWrapper leaf_cert(cert);
- if (!leaf_cert.cert)
- return false;
-
- return GetCertOctetStringExtension(leaf_cert.cert.get(),
- g_ct_singleton.Get().embedded_oid(),
- sct_list);
-}
-
-bool GetPrecertLogEntry(X509Certificate::OSCertHandle leaf,
- X509Certificate::OSCertHandle issuer,
- LogEntry* result) {
- DCHECK(leaf);
- DCHECK(issuer);
-
- NSSCertWrapper leaf_cert(leaf);
- NSSCertWrapper issuer_cert(issuer);
-
- result->Reset();
- // XXX(rsleevi): This check may be overkill, since we should be able to
- // generate precerts for certs without the extension. For now, just a sanity
- // check to match the reference implementation.
- SECItem extension;
- SECStatus rv = CERT_FindCertExtension(
- leaf_cert.cert.get(), g_ct_singleton.Get().embedded_oid(), &extension);
- if (rv != SECSuccess)
- return false;
- SECITEM_FreeItem(&extension, PR_FALSE);
-
- std::string to_be_signed;
- if (!ExtractTBSCertWithoutSCTs(leaf_cert.cert.get(), &to_be_signed))
- return false;
-
- if (!issuer_cert.cert) {
- // This can happen when the issuer and leaf certs share the same serial
- // number and are from the same CA, which should never be the case
- // (but happened with bad test certs).
- VLOG(1) << "Issuer cert is null, cannot generate Precert entry.";
- return false;
- }
-
- SECKEYPublicKey* issuer_pub_key =
- SECKEY_ExtractPublicKey(&(issuer_cert.cert->subjectPublicKeyInfo));
- if (!issuer_pub_key) {
- VLOG(1) << "Could not extract issuer public key, "
- << "cannot generate Precert entry.";
- return false;
- }
-
- SECItem* encoded_issuer_pubKey =
- SECKEY_EncodeDERSubjectPublicKeyInfo(issuer_pub_key);
- if (!encoded_issuer_pubKey) {
- SECKEY_DestroyPublicKey(issuer_pub_key);
- return false;
- }
-
- result->type = ct::LogEntry::LOG_ENTRY_TYPE_PRECERT;
- result->tbs_certificate.swap(to_be_signed);
-
- crypto::SHA256HashString(
- base::StringPiece(reinterpret_cast<char*>(encoded_issuer_pubKey->data),
- encoded_issuer_pubKey->len),
- result->issuer_key_hash.data,
- sizeof(result->issuer_key_hash.data));
-
- SECITEM_FreeItem(encoded_issuer_pubKey, PR_TRUE);
- SECKEY_DestroyPublicKey(issuer_pub_key);
-
- return true;
-}
-
-bool GetX509LogEntry(X509Certificate::OSCertHandle leaf, LogEntry* result) {
- DCHECK(leaf);
-
- std::string encoded;
- if (!X509Certificate::GetDEREncoded(leaf, &encoded))
- return false;
-
- result->Reset();
- result->type = ct::LogEntry::LOG_ENTRY_TYPE_X509;
- result->leaf_certificate.swap(encoded);
- return true;
-}
-
-bool ExtractSCTListFromOCSPResponse(X509Certificate::OSCertHandle issuer,
- const std::string& cert_serial_number,
- const std::string& ocsp_response,
- std::string* sct_list) {
- DCHECK(issuer);
-
- // Any OCSP response is unlikely to be even close to 2^24 bytes; further, CT
- // only uses stapled OCSP responses which have this limit imposed by the TLS
- // protocol.
- if (ocsp_response.size() > 0xffffff)
- return false;
-
- crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
-
- OCSPResponse response;
- memset(&response, 0, sizeof(response));
-
- SECItem src = { siBuffer,
- reinterpret_cast<unsigned char*>(const_cast<char*>(
- ocsp_response.data())),
- static_cast<unsigned int>(ocsp_response.size()) };
-
- // |response| will point directly into |src|, so it's not necessary to
- // free the |response| contents, but they may only be used while |src|
- // is valid (i.e., in this method).
- SECStatus rv = SEC_QuickDERDecodeItem(arena.get(), &response,
- kOCSPResponseTemplate, &src);
- if (rv != SECSuccess)
- return false;
-
- if (!response.response_bytes)
- return false;
-
- if (!SECITEM_ItemsAreEqual(&kBasicOCSPResponseOidItem,
- &response.response_bytes->response_type)) {
- return false;
- }
-
- BasicOCSPResponse basic_response;
- memset(&basic_response, 0, sizeof(basic_response));
-
- rv = SEC_QuickDERDecodeItem(arena.get(), &basic_response,
- kBasicOCSPResponseTemplate,
- &response.response_bytes->der_response);
- if (rv != SECSuccess)
- return false;
-
- SingleResponse** responses =
- basic_response.tbs_response_data.single_responses;
- if (!responses)
- return false;
-
- std::string issuer_der;
- if (!X509Certificate::GetDEREncoded(issuer, &issuer_der))
- return false;
-
- base::StringPiece issuer_spki;
- if (!asn1::ExtractSPKIFromDERCert(issuer_der, &issuer_spki))
- return false;
-
- // In OCSP, only the key itself is under hash.
- base::StringPiece issuer_spk;
- if (!asn1::ExtractSubjectPublicKeyFromSPKI(issuer_spki, &issuer_spk))
- return false;
-
- // ExtractSubjectPublicKey... does not remove the initial octet encoding the
- // number of unused bits in the ASN.1 BIT STRING so we do it here. For public
- // keys, the bitstring is in practice always byte-aligned.
- if (issuer_spk.empty() || issuer_spk[0] != 0)
- return false;
- issuer_spk.remove_prefix(1);
-
- // NSS OCSP lib recognizes SHA1, MD5 and MD2; MD5 and MD2 are dead but
- // https://bugzilla.mozilla.org/show_bug.cgi?id=663315 will add SHA-256
- // and SHA-384.
- // TODO(ekasper): add SHA-384 to crypto/sha2.h and here if it proves
- // necessary.
- // TODO(ekasper): only compute the hashes on demand.
- std::string issuer_key_sha256_hash = crypto::SHA256HashString(issuer_spk);
- std::string issuer_key_sha1_hash = base::SHA1HashString(
- issuer_spk.as_string());
-
- const SingleResponse* match = NULL;
- for (const SingleResponse* const* resps = responses; *resps; ++resps) {
- const SingleResponse* resp = *resps;
- if (CertIDMatches(resp->cert_id, cert_serial_number,
- issuer_key_sha1_hash, issuer_key_sha256_hash)) {
- match = resp;
- break;
- }
- }
-
- if (!match)
- return false;
-
- return GetSCTListFromOCSPExtension(arena.get(), match->single_extensions,
- sct_list);
-}
-
-} // namespace ct
-
-} // namespace net
« no previous file with comments | « net/cert/ct_log_verifier_nss.cc ('k') | net/cert/ev_root_ca_metadata.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698