diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-25 12:59:54 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-25 12:59:54 +0000 |
commit | 5c51876fc45efafe4b9d918553c7b32a854ed8ed (patch) | |
tree | 2acc3b2ef0b1f76005b3e081553e01c9e149fc30 /net | |
parent | 4da06efd6d467e07ac311a59e5f79bd0cc6145d4 (diff) | |
download | chromium_src-5c51876fc45efafe4b9d918553c7b32a854ed8ed.zip chromium_src-5c51876fc45efafe4b9d918553c7b32a854ed8ed.tar.gz chromium_src-5c51876fc45efafe4b9d918553c7b32a854ed8ed.tar.bz2 |
More UI-related OpenSSL support.
Refactors a few functions from nsNSSCertHelper into common.
(no functional change when using NSS).
Implements some of the x509_certificate_model functions for OpenSSL.
BUG=none
TEST=Compile w/ use_openssl=1, check that the fields in certificate viewer are displayed.
Review URL: http://codereview.chromium.org/3815012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63723 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/x509_certificate_openssl.cc | 101 | ||||
-rw-r--r-- | net/base/x509_openssl_util.cc | 104 | ||||
-rw-r--r-- | net/base/x509_openssl_util.h | 39 | ||||
-rw-r--r-- | net/net.gyp | 4 |
4 files changed, 166 insertions, 82 deletions
diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc index 444b5d4..4a7beaa 100644 --- a/net/base/x509_certificate_openssl.cc +++ b/net/base/x509_certificate_openssl.cc @@ -20,9 +20,12 @@ #include "net/base/cert_verify_result.h" #include "net/base/net_errors.h" #include "net/base/openssl_util.h" +#include "net/base/x509_openssl_util.h" namespace net { +namespace nxou = net::x509_openssl_util; + namespace { void CreateOSCertHandlesFromPKCS7Bytes( @@ -51,39 +54,13 @@ void CreateOSCertHandlesFromPKCS7Bytes( } } -bool ParsePrincipalFieldInternal(X509_NAME* name, - int index, - std::string* field) { - ASN1_STRING* data = - X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, index)); - if (!data) - return false; - - unsigned char* buf = NULL; - int len = ASN1_STRING_to_UTF8(&buf, data); - if (len <= 0) - return false; - - field->assign(reinterpret_cast<const char*>(buf), len); - OPENSSL_free(buf); - return true; -} - -void ParsePrincipalField(X509_NAME* name, int nid, std::string* field) { - int index = X509_NAME_get_index_by_NID(name, nid, -1); - if (index < 0) - return; - - ParsePrincipalFieldInternal(name, index, field); -} - -void ParsePrincipalFields(X509_NAME* name, +void ParsePrincipalValues(X509_NAME* name, int nid, std::vector<std::string>* fields) { for (int index = -1; (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) { std::string field; - if (!ParsePrincipalFieldInternal(name, index, &field)) + if (!nxou::ParsePrincipalValueByIndex(name, index, &field)) break; fields->push_back(field); } @@ -95,64 +72,24 @@ void ParsePrincipal(X509Certificate::OSCertHandle cert, if (!x509_name) return; - ParsePrincipalFields(x509_name, NID_streetAddress, + ParsePrincipalValues(x509_name, NID_streetAddress, &principal->street_addresses); - ParsePrincipalFields(x509_name, NID_organizationName, + ParsePrincipalValues(x509_name, NID_organizationName, &principal->organization_names); - ParsePrincipalFields(x509_name, NID_organizationalUnitName, + ParsePrincipalValues(x509_name, NID_organizationalUnitName, &principal->organization_unit_names); - ParsePrincipalFields(x509_name, NID_domainComponent, + ParsePrincipalValues(x509_name, NID_domainComponent, &principal->domain_components); - ParsePrincipalField(x509_name, NID_commonName, &principal->common_name); - ParsePrincipalField(x509_name, NID_localityName, &principal->locality_name); - ParsePrincipalField(x509_name, NID_stateOrProvinceName, - &principal->state_or_province_name); - ParsePrincipalField(x509_name, NID_countryName, &principal->country_name); -} - -void ParseDate(ASN1_TIME* x509_time, base::Time* time) { - if (!x509_time || - (x509_time->type != V_ASN1_UTCTIME && - x509_time->type != V_ASN1_GENERALIZEDTIME)) - return; - - std::string str_date(reinterpret_cast<char*>(x509_time->data), - x509_time->length); - // UTCTime: YYMMDDHHMMSSZ - // GeneralizedTime: YYYYMMDDHHMMSSZ - size_t year_length = x509_time->type == V_ASN1_UTCTIME ? 2 : 4; - size_t fields_offset = x509_time->type == V_ASN1_UTCTIME ? 0 : 2; - - if (str_date.length() < 11 + year_length) - return; + nxou::ParsePrincipalValueByNID(x509_name, NID_commonName, + &principal->common_name); + nxou::ParsePrincipalValueByNID(x509_name, NID_localityName, + &principal->locality_name); + nxou::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, + &principal->state_or_province_name); + nxou::ParsePrincipalValueByNID(x509_name, NID_countryName, + &principal->country_name); - base::Time::Exploded exploded = {0}; - bool valid = base::StringToInt(str_date.begin(), - str_date.begin() + year_length, - &exploded.year); - if (valid && year_length == 2) - exploded.year += exploded.year < 50 ? 2000 : 1900; - - valid &= base::StringToInt(str_date.begin() + fields_offset + 2, - str_date.begin() + fields_offset + 4, - &exploded.month); - valid &= base::StringToInt(str_date.begin() + fields_offset + 4, - str_date.begin() + fields_offset + 6), - &exploded.day_of_month); - valid &= base::StringToInt(str_date.begin() + fields_offset + 6, - str_date.begin() + fields_offset + 8), - &exploded.hour); - valid &= base::StringToInt(str_date.begin() + fields_offset + 8, - str_date.begin() + fields_offset + 10), - &exploded.minute); - valid &= base::StringToInt(str_date.begin() + fields_offset + 10, - str_date.begin() + fields_offset + 12, - &exploded.second); - - DCHECK(valid); - - *time = base::Time::FromUTCExploded(exploded); } void ParseSubjectAltNames(X509Certificate::OSCertHandle cert, @@ -357,8 +294,8 @@ void X509Certificate::Initialize() { fingerprint_ = CalculateFingerprint(cert_handle_); ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_); ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_); - ParseDate(X509_get_notBefore(cert_handle_), &valid_start_); - ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_); + nxou::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_); + nxou::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_); } SHA1Fingerprint X509Certificate::CalculateFingerprint(OSCertHandle cert) { diff --git a/net/base/x509_openssl_util.cc b/net/base/x509_openssl_util.cc new file mode 100644 index 0000000..5eb4e3f --- /dev/null +++ b/net/base/x509_openssl_util.cc @@ -0,0 +1,104 @@ +// Copyright (c) 2006-2008 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/base/x509_openssl_util.h" + +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "base/time.h" + +namespace net { + +namespace x509_openssl_util { + +bool ParsePrincipalKeyAndValueByIndex(X509_NAME* name, + int index, + std::string* key, + std::string* value) { + X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, index); + if (!entry) + return false; + + if (key) { + ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(entry); + key->assign(OBJ_nid2sn(OBJ_obj2nid(object))); + } + + ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry); + if (!data) + return false; + + unsigned char* buf = NULL; + int len = ASN1_STRING_to_UTF8(&buf, data); + if (len <= 0) + return false; + + value->assign(reinterpret_cast<const char*>(buf), len); + OPENSSL_free(buf); + return true; +} + +bool ParsePrincipalValueByIndex(X509_NAME* name, + int index, + std::string* value) { + return ParsePrincipalKeyAndValueByIndex(name, index, NULL, value); +} + +bool ParsePrincipalValueByNID(X509_NAME* name, int nid, std::string* value) { + int index = X509_NAME_get_index_by_NID(name, nid, -1); + if (index < 0) + return false; + + return ParsePrincipalValueByIndex(name, index, value); +} + +bool ParseDate(ASN1_TIME* x509_time, base::Time* time) { + if (!x509_time || + (x509_time->type != V_ASN1_UTCTIME && + x509_time->type != V_ASN1_GENERALIZEDTIME)) + return false; + + std::string str_date(reinterpret_cast<char*>(x509_time->data), + x509_time->length); + // UTCTime: YYMMDDHHMMSSZ + // GeneralizedTime: YYYYMMDDHHMMSSZ + size_t year_length = x509_time->type == V_ASN1_UTCTIME ? 2 : 4; + size_t fields_offset = x509_time->type == V_ASN1_UTCTIME ? 0 : 2; + + if (str_date.length() < 11 + year_length) + return false; + + base::Time::Exploded exploded = {0}; + bool valid = base::StringToInt(str_date.begin(), + str_date.begin() + year_length, + &exploded.year); + if (valid && year_length == 2) + exploded.year += exploded.year < 50 ? 2000 : 1900; + + valid &= base::StringToInt(str_date.begin() + fields_offset + 2, + str_date.begin() + fields_offset + 4, + &exploded.month); + valid &= base::StringToInt(str_date.begin() + fields_offset + 4, + str_date.begin() + fields_offset + 6, + &exploded.day_of_month); + valid &= base::StringToInt(str_date.begin() + fields_offset + 6, + str_date.begin() + fields_offset + 8, + &exploded.hour); + valid &= base::StringToInt(str_date.begin() + fields_offset + 8, + str_date.begin() + fields_offset + 10, + &exploded.minute); + valid &= base::StringToInt(str_date.begin() + fields_offset + 10, + str_date.begin() + fields_offset + 12, + &exploded.second); + + if (!valid) + return false; + + *time = base::Time::FromUTCExploded(exploded); + return valid; +} + +} // namespace x509_openssl_util + +} // namespace net diff --git a/net/base/x509_openssl_util.h b/net/base/x509_openssl_util.h new file mode 100644 index 0000000..5ac511b --- /dev/null +++ b/net/base/x509_openssl_util.h @@ -0,0 +1,39 @@ +// Copyright (c) 2006-2008 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. + +#ifndef NET_BASE_X509_OPENSSL_UTIL_H_ +#define NET_BASE_X509_OPENSSL_UTIL_H_ +#pragma once + +#include <openssl/asn1.h> +#include <openssl/x509v3.h> + +#include <string> + +namespace base { +class Time; +} // namespace base + +namespace net { + +// A collection of helper functions to fetch data from OpenSSL X509 certificates +// into more convenient std / base datatypes. +namespace x509_openssl_util { + +bool ParsePrincipalKeyAndValueByIndex(X509_NAME* name, + int index, + std::string* key, + std::string* value); + +bool ParsePrincipalValueByIndex(X509_NAME* name, int index, std::string* value); + +bool ParsePrincipalValueByNID(X509_NAME* name, int nid, std::string* value); + +bool ParseDate(ASN1_TIME* x509_time, base::Time* time); + +} // namespace x509_openssl_util + +} // namespace net + +#endif // NET_BASE_X509_OPENSSL_UTIL_H_ diff --git a/net/net.gyp b/net/net.gyp index 8e01f57..4a2db1b 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -196,6 +196,8 @@ 'base/x509_cert_types.cc', 'base/x509_cert_types.h', 'base/x509_cert_types_mac.cc', + 'base/x509_openssl_util.cc', + 'base/x509_openssl_util.h', 'third_party/mozilla_security_manager/nsKeygenHandler.cpp', 'third_party/mozilla_security_manager/nsKeygenHandler.h', 'third_party/mozilla_security_manager/nsNSSCertificateDB.cpp', @@ -288,6 +290,8 @@ 'base/openssl_util.cc', 'base/openssl_util.h', 'base/x509_certificate_openssl.cc', + 'base/x509_openssl_util.cc', + 'base/x509_openssl_util.h', ], }, ], |