| Index: net/cert/x509_util.cc
|
| diff --git a/net/cert/x509_util.cc b/net/cert/x509_util.cc
|
| index 51e7b6ac1766b3ea301690cd0eb553ac6df61d1d..8729e560c64aecefb4befcdf59389a99429e5b6d 100644
|
| --- a/net/cert/x509_util.cc
|
| +++ b/net/cert/x509_util.cc
|
| @@ -10,12 +10,47 @@
|
| #include "crypto/ec_private_key.h"
|
| #include "crypto/rsa_private_key.h"
|
| #include "net/base/hash_value.h"
|
| +#include "net/cert/internal/name_constraints.h"
|
| #include "net/cert/internal/parse_certificate.h"
|
| +#include "net/cert/internal/parse_name.h"
|
| #include "net/cert/internal/signature_algorithm.h"
|
| #include "net/cert/x509_certificate.h"
|
| +#include "net/der/input.h"
|
| +#include "net/der/parse_values.h"
|
|
|
| namespace net {
|
|
|
| +namespace {
|
| +
|
| +bool GetCommonName(const der::Input& tlv, std::string* common_name) {
|
| + RDNSequence rdn_sequence;
|
| + if (!ParseName(tlv, &rdn_sequence))
|
| + return false;
|
| +
|
| + for (const auto& rdn : rdn_sequence) {
|
| + for (const auto& atv : rdn) {
|
| + if (atv.type == TypeCommonNameOid()) {
|
| + return atv.ValueAsStringUnsafe(common_name);
|
| + }
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool DecodeTime(const der::GeneralizedTime& generalized_time,
|
| + base::Time* time) {
|
| + base::Time::Exploded exploded = {0};
|
| + exploded.year = generalized_time.year;
|
| + exploded.month = generalized_time.month;
|
| + exploded.day_of_month = generalized_time.day;
|
| + exploded.hour = generalized_time.hours;
|
| + exploded.minute = generalized_time.minutes;
|
| + exploded.second = generalized_time.seconds;
|
| + return base::Time::FromUTCExploded(exploded, time);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| namespace x509_util {
|
|
|
| // RSA keys created by CreateKeyAndSelfSignedCert will be of this length.
|
| @@ -82,6 +117,58 @@ bool CreateKeyAndSelfSignedCert(const std::string& subject,
|
| return success;
|
| }
|
|
|
| +bool ParseCertificateSandboxed(const base::StringPiece& certificate,
|
| + std::string* subject,
|
| + std::string* issuer,
|
| + base::Time* not_before,
|
| + base::Time* not_after,
|
| + std::vector<std::string>* dns_names,
|
| + std::vector<std::string>* ip_addresses) {
|
| + der::Input cert_data(certificate);
|
| + der::Input tbs_cert, signature_alg;
|
| + der::BitString signature_value;
|
| + if (!ParseCertificate(cert_data, &tbs_cert, &signature_alg, &signature_value))
|
| + return false;
|
| +
|
| + ParsedTbsCertificate parsed_tbs_cert;
|
| + if (!ParseTbsCertificate(tbs_cert, ParseCertificateOptions(),
|
| + &parsed_tbs_cert))
|
| + return false;
|
| +
|
| + if (!GetCommonName(parsed_tbs_cert.subject_tlv, subject))
|
| + return false;
|
| +
|
| + if (!GetCommonName(parsed_tbs_cert.issuer_tlv, issuer))
|
| + return false;
|
| +
|
| + if (!DecodeTime(parsed_tbs_cert.validity_not_before, not_before))
|
| + return false;
|
| +
|
| + if (!DecodeTime(parsed_tbs_cert.validity_not_after, not_after))
|
| + return false;
|
| +
|
| + if (!parsed_tbs_cert.has_extensions)
|
| + return true;
|
| +
|
| + std::map<der::Input, ParsedExtension> extensions;
|
| + if (!ParseExtensions(parsed_tbs_cert.extensions_tlv, &extensions))
|
| + return false;
|
| +
|
| + std::vector<std::string> san;
|
| + auto iter = extensions.find(SubjectAltNameOid());
|
| + if (iter != extensions.end()) {
|
| + std::unique_ptr<GeneralNames> subject_alt_names =
|
| + GeneralNames::CreateFromDer(iter->second.value);
|
| + if (subject_alt_names) {
|
| + *dns_names = subject_alt_names->dns_names;
|
| + for (const auto& ip : subject_alt_names->ip_addresses)
|
| + ip_addresses->push_back(ip.ToString());
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace x509_util
|
|
|
| } // namespace net
|
|
|