| Index: net/base/x509_certificate_nss.cc
|
| diff --git a/net/base/x509_certificate_nss.cc b/net/base/x509_certificate_nss.cc
|
| index 060f4f74602b464272a681c909a566df379e3267..54d2197e30ecd2db96f7d008a8c7442080e7a9fd 100644
|
| --- a/net/base/x509_certificate_nss.cc
|
| +++ b/net/base/x509_certificate_nss.cc
|
| @@ -19,110 +19,21 @@
|
| #include "base/time.h"
|
| #include "crypto/nss_util.h"
|
| #include "crypto/rsa_private_key.h"
|
| -#include "crypto/scoped_nss_types.h"
|
| #include "net/base/x509_util_nss.h"
|
|
|
| namespace net {
|
|
|
| -namespace {
|
| -
|
| -void ParsePrincipal(CERTName* name,
|
| - CertPrincipal* principal) {
|
| - typedef char* (*CERTGetNameFunc)(CERTName* name);
|
| -
|
| - // TODO(jcampan): add business_category and serial_number.
|
| - // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and
|
| - // CERT_GetDomainComponentName functions, but they return only the most
|
| - // general (the first) RDN. NSS doesn't have a function for the street
|
| - // address.
|
| - static const SECOidTag kOIDs[] = {
|
| - SEC_OID_AVA_STREET_ADDRESS,
|
| - SEC_OID_AVA_ORGANIZATION_NAME,
|
| - SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
|
| - SEC_OID_AVA_DC };
|
| -
|
| - std::vector<std::string>* values[] = {
|
| - &principal->street_addresses,
|
| - &principal->organization_names,
|
| - &principal->organization_unit_names,
|
| - &principal->domain_components };
|
| - DCHECK(arraysize(kOIDs) == arraysize(values));
|
| -
|
| - CERTRDN** rdns = name->rdns;
|
| - for (size_t rdn = 0; rdns[rdn]; ++rdn) {
|
| - CERTAVA** avas = rdns[rdn]->avas;
|
| - for (size_t pair = 0; avas[pair] != 0; ++pair) {
|
| - SECOidTag tag = CERT_GetAVATag(avas[pair]);
|
| - for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
|
| - if (kOIDs[oid] == tag) {
|
| - SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
|
| - if (!decode_item)
|
| - break;
|
| - // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
|
| - std::string value(reinterpret_cast<char*>(decode_item->data),
|
| - decode_item->len);
|
| - values[oid]->push_back(value);
|
| - SECITEM_FreeItem(decode_item, PR_TRUE);
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Get CN, L, S, and C.
|
| - CERTGetNameFunc get_name_funcs[4] = {
|
| - CERT_GetCommonName, CERT_GetLocalityName,
|
| - CERT_GetStateName, CERT_GetCountryName };
|
| - std::string* single_values[4] = {
|
| - &principal->common_name, &principal->locality_name,
|
| - &principal->state_or_province_name, &principal->country_name };
|
| - for (size_t i = 0; i < arraysize(get_name_funcs); ++i) {
|
| - char* value = get_name_funcs[i](name);
|
| - if (value) {
|
| - single_values[i]->assign(value);
|
| - PORT_Free(value);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ParseDate(SECItem* der_date, base::Time* result) {
|
| - PRTime prtime;
|
| - SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
|
| - DCHECK_EQ(SECSuccess, rv);
|
| - *result = crypto::PRTimeToBaseTime(prtime);
|
| -}
|
| -
|
| -SECStatus PR_CALLBACK
|
| -CollectCertsCallback(void* arg, SECItem** certs, int num_certs) {
|
| - X509Certificate::OSCertHandles* results =
|
| - reinterpret_cast<X509Certificate::OSCertHandles*>(arg);
|
| -
|
| - for (int i = 0; i < num_certs; ++i) {
|
| - X509Certificate::OSCertHandle handle =
|
| - X509Certificate::CreateOSCertHandleFromBytes(
|
| - reinterpret_cast<char*>(certs[i]->data), certs[i]->len);
|
| - if (handle)
|
| - results->push_back(handle);
|
| - }
|
| -
|
| - return SECSuccess;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| void X509Certificate::Initialize() {
|
| - ParsePrincipal(&cert_handle_->subject, &subject_);
|
| - ParsePrincipal(&cert_handle_->issuer, &issuer_);
|
| + x509_util::ParsePrincipal(&cert_handle_->subject, &subject_);
|
| + x509_util::ParsePrincipal(&cert_handle_->issuer, &issuer_);
|
|
|
| - ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
|
| - ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);
|
| + x509_util::ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
|
| + x509_util::ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);
|
|
|
| fingerprint_ = CalculateFingerprint(cert_handle_);
|
| ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
|
|
|
| - serial_number_ = std::string(
|
| - reinterpret_cast<char*>(cert_handle_->serialNumber.data),
|
| - cert_handle_->serialNumber.len);
|
| + serial_number_ = x509_util::ParseSerialNumber(cert_handle_);
|
| }
|
|
|
| // static
|
| @@ -216,7 +127,6 @@ X509Certificate* X509Certificate::CreateSelfSigned(
|
| uint32 serial_number,
|
| base::TimeDelta valid_duration) {
|
| DCHECK(key);
|
| -
|
| base::Time not_valid_before = base::Time::Now();
|
| base::Time not_valid_after = not_valid_before + valid_duration;
|
| CERTCertificate* cert = x509_util::CreateSelfSignedCert(key->public_key(),
|
| @@ -225,7 +135,6 @@ X509Certificate* X509Certificate::CreateSelfSigned(
|
| serial_number,
|
| not_valid_before,
|
| not_valid_after);
|
| -
|
| if (!cert)
|
| return NULL;
|
|
|
| @@ -238,44 +147,7 @@ X509Certificate* X509Certificate::CreateSelfSigned(
|
| void X509Certificate::GetSubjectAltName(
|
| std::vector<std::string>* dns_names,
|
| std::vector<std::string>* ip_addrs) const {
|
| - if (dns_names)
|
| - dns_names->clear();
|
| - if (ip_addrs)
|
| - ip_addrs->clear();
|
| -
|
| - SECItem alt_name;
|
| - SECStatus rv = CERT_FindCertExtension(cert_handle_,
|
| - SEC_OID_X509_SUBJECT_ALT_NAME,
|
| - &alt_name);
|
| - if (rv != SECSuccess)
|
| - return;
|
| -
|
| - PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
| - DCHECK(arena != NULL);
|
| -
|
| - CERTGeneralName* alt_name_list;
|
| - alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);
|
| - SECITEM_FreeItem(&alt_name, PR_FALSE);
|
| -
|
| - CERTGeneralName* name = alt_name_list;
|
| - while (name) {
|
| - // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs
|
| - // respectively, both of which can be byte copied from
|
| - // SECItemType::data into the appropriate output vector.
|
| - if (dns_names && name->type == certDNSName) {
|
| - dns_names->push_back(std::string(
|
| - reinterpret_cast<char*>(name->name.other.data),
|
| - name->name.other.len));
|
| - } else if (ip_addrs && name->type == certIPAddress) {
|
| - ip_addrs->push_back(std::string(
|
| - reinterpret_cast<char*>(name->name.other.data),
|
| - name->name.other.len));
|
| - }
|
| - name = CERT_GetNextGeneralName(name);
|
| - if (name == alt_name_list)
|
| - break;
|
| - }
|
| - PORT_FreeArena(arena, PR_FALSE);
|
| + x509_util::GetSubjectAltName(cert_handle_, dns_names, ip_addrs);
|
| }
|
|
|
| bool X509Certificate::VerifyNameMatch(const std::string& hostname) const {
|
| @@ -338,38 +210,7 @@ X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
|
| const char* data,
|
| int length,
|
| Format format) {
|
| - OSCertHandles results;
|
| - if (length < 0)
|
| - return results;
|
| -
|
| - crypto::EnsureNSSInit();
|
| -
|
| - if (!NSS_IsInitialized())
|
| - return results;
|
| -
|
| - switch (format) {
|
| - case FORMAT_SINGLE_CERTIFICATE: {
|
| - OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
|
| - if (handle)
|
| - results.push_back(handle);
|
| - break;
|
| - }
|
| - case FORMAT_PKCS7: {
|
| - // Make a copy since CERT_DecodeCertPackage may modify it
|
| - std::vector<char> data_copy(data, data + length);
|
| -
|
| - SECStatus result = CERT_DecodeCertPackage(&data_copy[0],
|
| - length, CollectCertsCallback, &results);
|
| - if (result != SECSuccess)
|
| - results.clear();
|
| - break;
|
| - }
|
| - default:
|
| - NOTREACHED() << "Certificate format " << format << " unimplemented";
|
| - break;
|
| - }
|
| -
|
| - return results;
|
| + return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
|
| }
|
|
|
| // static
|
| @@ -423,12 +264,7 @@ SHA1HashValue X509Certificate::CalculateCAFingerprint(
|
| // static
|
| X509Certificate::OSCertHandle
|
| X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) {
|
| - const char* data;
|
| - int length;
|
| - if (!pickle_iter->ReadData(&data, &length))
|
| - return NULL;
|
| -
|
| - return CreateOSCertHandleFromBytes(data, length);
|
| + return x509_util::ReadOSCertHandleFromPickle(pickle_iter);
|
| }
|
|
|
| // static
|
| @@ -443,34 +279,7 @@ bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
|
| void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
|
| size_t* size_bits,
|
| PublicKeyType* type) {
|
| - // Since we might fail, set the output parameters to default values first.
|
| - *type = kPublicKeyTypeUnknown;
|
| - *size_bits = 0;
|
| -
|
| - crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(cert_handle));
|
| - if (!key.get())
|
| - return;
|
| -
|
| - *size_bits = SECKEY_PublicKeyStrengthInBits(key.get());
|
| -
|
| - switch (key->keyType) {
|
| - case rsaKey:
|
| - *type = kPublicKeyTypeRSA;
|
| - break;
|
| - case dsaKey:
|
| - *type = kPublicKeyTypeDSA;
|
| - break;
|
| - case dhKey:
|
| - *type = kPublicKeyTypeDH;
|
| - break;
|
| - case ecKey:
|
| - *type = kPublicKeyTypeECDSA;
|
| - break;
|
| - default:
|
| - *type = kPublicKeyTypeUnknown;
|
| - *size_bits = 0;
|
| - break;
|
| - }
|
| + x509_util::GetPublicKeyInfo(cert_handle, size_bits, type);
|
| }
|
|
|
| } // namespace net
|
|
|