| Index: net/base/dnssec_keyset.cc
|
| diff --git a/net/base/dnssec_keyset.cc b/net/base/dnssec_keyset.cc
|
| index 70aa217f9581df78e148cf3488977215898211ef..c7f8606f5e5c20190de1199b47b7ffb21b9ec075 100644
|
| --- a/net/base/dnssec_keyset.cc
|
| +++ b/net/base/dnssec_keyset.cc
|
| @@ -15,6 +15,19 @@
|
| #include "base/time.h"
|
| #include "net/base/dns_util.h"
|
|
|
| +namespace {
|
| +
|
| +// These are encoded AlgorithmIdentifiers for the given signature algorithm.
|
| +const unsigned char kRSAWithSHA1[] = {
|
| + 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x5, 5, 0
|
| +};
|
| +
|
| +const unsigned char kRSAWithSHA256[] = {
|
| + 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 5, 0
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| namespace net {
|
|
|
| DNSSECKeySet::DNSSECKeySet()
|
| @@ -35,33 +48,6 @@ bool DNSSECKeySet::AddKey(const base::StringPiece& dnskey) {
|
| return true;
|
| }
|
|
|
| -// static
|
| -uint16 DNSSECKeySet::DNSKEYToKeyID(const base::StringPiece& dnskey) {
|
| - const unsigned char* data =
|
| - reinterpret_cast<const unsigned char*>(dnskey.data());
|
| -
|
| - // RFC 4043: App B
|
| - uint32 ac = 0;
|
| - for (unsigned i = 0; i < dnskey.size(); i++) {
|
| - if (i & 1) {
|
| - ac += data[i];
|
| - } else {
|
| - ac += static_cast<uint32>(data[i]) << 8;
|
| - }
|
| - }
|
| - ac += (ac >> 16) & 0xffff;
|
| - return ac;
|
| -}
|
| -
|
| -// These are encoded AlgorithmIdentifiers for the given signature algorithm.
|
| -static const unsigned char kRSAWithSHA1[] = {
|
| - 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x5, 5, 0
|
| -};
|
| -
|
| -static const unsigned char kRSAWithSHA256[] = {
|
| - 0x30, 0xd, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 5, 0
|
| -};
|
| -
|
| bool DNSSECKeySet::CheckSignature(
|
| const base::StringPiece& name,
|
| const base::StringPiece& zone,
|
| @@ -180,10 +166,109 @@ bool DNSSECKeySet::CheckSignature(
|
| return false;
|
| }
|
|
|
| +// static
|
| +uint16 DNSSECKeySet::DNSKEYToKeyID(const base::StringPiece& dnskey) {
|
| + const unsigned char* data =
|
| + reinterpret_cast<const unsigned char*>(dnskey.data());
|
| +
|
| + // RFC 4043: App B
|
| + uint32 ac = 0;
|
| + for (unsigned i = 0; i < dnskey.size(); i++) {
|
| + if (i & 1) {
|
| + ac += data[i];
|
| + } else {
|
| + ac += static_cast<uint32>(data[i]) << 8;
|
| + }
|
| + }
|
| + ac += (ac >> 16) & 0xffff;
|
| + return ac;
|
| +}
|
| +
|
| void DNSSECKeySet::IgnoreTimestamps() {
|
| ignore_timestamps_ = true;
|
| }
|
|
|
| +bool DNSSECKeySet::VerifySignature(
|
| + base::StringPiece signature_algorithm,
|
| + base::StringPiece signature,
|
| + base::StringPiece public_key,
|
| + base::StringPiece signed_data) {
|
| + // This code is largely a copy-and-paste from
|
| + // base/crypto/signature_verifier_nss.cc. We can't change
|
| + // base::SignatureVerifier to always use NSS because we want the ability to
|
| + // be FIPS 140-2 compliant. However, we can't use base::SignatureVerifier
|
| + // here because some platforms don't support SHA256 signatures. Therefore, we
|
| + // use NSS directly.
|
| +
|
| + base::EnsureNSSInit();
|
| +
|
| + CERTSubjectPublicKeyInfo* spki = NULL;
|
| + SECItem spki_der;
|
| + spki_der.type = siBuffer;
|
| + spki_der.data = (uint8*) public_key.data();
|
| + spki_der.len = public_key.size();
|
| + spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der);
|
| + if (!spki)
|
| + return false;
|
| + SECKEYPublicKey* pub_key = SECKEY_ExtractPublicKey(spki);
|
| + SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki.
|
| + if (!pub_key)
|
| + return false;
|
| +
|
| + PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
| + if (!arena) {
|
| + SECKEY_DestroyPublicKey(pub_key);
|
| + return false;
|
| + }
|
| +
|
| + SECItem sig_alg_der;
|
| + sig_alg_der.type = siBuffer;
|
| + sig_alg_der.data = (uint8*) signature_algorithm.data();
|
| + sig_alg_der.len = signature_algorithm.size();
|
| + SECAlgorithmID sig_alg_id;
|
| + SECStatus rv;
|
| + rv = SEC_QuickDERDecodeItem(arena, &sig_alg_id, SECOID_AlgorithmIDTemplate,
|
| + &sig_alg_der);
|
| + if (rv != SECSuccess) {
|
| + SECKEY_DestroyPublicKey(pub_key);
|
| + PORT_FreeArena(arena, PR_TRUE);
|
| + return false;
|
| + }
|
| +
|
| + SECItem sig;
|
| + sig.type = siBuffer;
|
| + sig.data = (uint8*) signature.data();
|
| + sig.len = signature.size();
|
| + SECOidTag hash_alg_tag;
|
| + VFYContext* vfy_context =
|
| + VFY_CreateContextWithAlgorithmID(pub_key, &sig,
|
| + &sig_alg_id, &hash_alg_tag,
|
| + NULL);
|
| + SECKEY_DestroyPublicKey(pub_key);
|
| + PORT_FreeArena(arena, PR_TRUE); // Done with sig_alg_id.
|
| + if (!vfy_context) {
|
| + // A corrupted RSA signature could be detected without the data, so
|
| + // VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE
|
| + // (-8182).
|
| + return false;
|
| + }
|
| +
|
| + rv = VFY_Begin(vfy_context);
|
| + if (rv != SECSuccess) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| + rv = VFY_Update(vfy_context, (uint8*) signed_data.data(), signed_data.size());
|
| + if (rv != SECSuccess) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| + rv = VFY_End(vfy_context);
|
| + VFY_DestroyContext(vfy_context, PR_TRUE);
|
| +
|
| + return rv == SECSuccess;
|
| +}
|
| +
|
| // This is an ASN.1 encoded AlgorithmIdentifier for RSA
|
| static const unsigned char kASN1AlgorithmIdentifierRSA[] = {
|
| 0x30, // SEQUENCE
|
| @@ -373,85 +458,4 @@ std::string DNSSECKeySet::ASN1WrapDNSKEY(const base::StringPiece& dnskey) {
|
| return std::string(reinterpret_cast<char*>(out.get()), j);
|
| }
|
|
|
| -bool DNSSECKeySet::VerifySignature(
|
| - base::StringPiece signature_algorithm,
|
| - base::StringPiece signature,
|
| - base::StringPiece public_key,
|
| - base::StringPiece signed_data) {
|
| - // This code is largely a copy-and-paste from
|
| - // base/crypto/signature_verifier_nss.cc. We can't change
|
| - // base::SignatureVerifier to always use NSS because we want the ability to
|
| - // be FIPS 140-2 compliant. However, we can't use base::SignatureVerifier
|
| - // here because some platforms don't support SHA256 signatures. Therefore, we
|
| - // use NSS directly.
|
| -
|
| - base::EnsureNSSInit();
|
| -
|
| - CERTSubjectPublicKeyInfo* spki = NULL;
|
| - SECItem spki_der;
|
| - spki_der.type = siBuffer;
|
| - spki_der.data = (uint8*) public_key.data();
|
| - spki_der.len = public_key.size();
|
| - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der);
|
| - if (!spki)
|
| - return false;
|
| - SECKEYPublicKey* pub_key = SECKEY_ExtractPublicKey(spki);
|
| - SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki.
|
| - if (!pub_key)
|
| - return false;
|
| -
|
| - PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
| - if (!arena) {
|
| - SECKEY_DestroyPublicKey(pub_key);
|
| - return false;
|
| - }
|
| -
|
| - SECItem sig_alg_der;
|
| - sig_alg_der.type = siBuffer;
|
| - sig_alg_der.data = (uint8*) signature_algorithm.data();
|
| - sig_alg_der.len = signature_algorithm.size();
|
| - SECAlgorithmID sig_alg_id;
|
| - SECStatus rv;
|
| - rv = SEC_QuickDERDecodeItem(arena, &sig_alg_id, SECOID_AlgorithmIDTemplate,
|
| - &sig_alg_der);
|
| - if (rv != SECSuccess) {
|
| - SECKEY_DestroyPublicKey(pub_key);
|
| - PORT_FreeArena(arena, PR_TRUE);
|
| - return false;
|
| - }
|
| -
|
| - SECItem sig;
|
| - sig.type = siBuffer;
|
| - sig.data = (uint8*) signature.data();
|
| - sig.len = signature.size();
|
| - SECOidTag hash_alg_tag;
|
| - VFYContext* vfy_context =
|
| - VFY_CreateContextWithAlgorithmID(pub_key, &sig,
|
| - &sig_alg_id, &hash_alg_tag,
|
| - NULL);
|
| - SECKEY_DestroyPublicKey(pub_key);
|
| - PORT_FreeArena(arena, PR_TRUE); // Done with sig_alg_id.
|
| - if (!vfy_context) {
|
| - // A corrupted RSA signature could be detected without the data, so
|
| - // VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE
|
| - // (-8182).
|
| - return false;
|
| - }
|
| -
|
| - rv = VFY_Begin(vfy_context);
|
| - if (rv != SECSuccess) {
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| - rv = VFY_Update(vfy_context, (uint8*) signed_data.data(), signed_data.size());
|
| - if (rv != SECSuccess) {
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| - rv = VFY_End(vfy_context);
|
| - VFY_DestroyContext(vfy_context, PR_TRUE);
|
| -
|
| - return rv == SECSuccess;
|
| -}
|
| -
|
| } // namespace net
|
|
|