Index: net/cert/x509_util.cc |
diff --git a/net/cert/x509_util.cc b/net/cert/x509_util.cc |
index 51e7b6ac1766b3ea301690cd0eb553ac6df61d1d..6517b4e6000de4bb9efd333dc850e6af4846f0a6 100644 |
--- a/net/cert/x509_util.cc |
+++ b/net/cert/x509_util.cc |
@@ -10,12 +10,44 @@ |
#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" |
namespace net { |
+namespace { |
+ |
+bool GetCommonName(const net::der::Input& tlv, std::string* common_name) { |
davidben
2016/09/06 17:21:45
No need for net:: prefix since we're already in ne
jam
2016/09/06 17:43:24
Done.
|
+ net::RDNSequence rdn_sequence; |
+ if (!net::ParseName(tlv, &rdn_sequence)) |
+ return false; |
+ |
+ for (const net::RelativeDistinguishedName& rdn : rdn_sequence) { |
davidben
2016/09/06 17:21:45
Any reason to use auto some of the time and the ty
jam
2016/09/06 17:43:24
no reason, switched to auto
|
+ for (const auto& atv : rdn) { |
+ if (atv.type == net::TypeCommonNameOid()) { |
+ return atv.ValueAsStringUnsafe(common_name); |
+ } |
+ } |
+ } |
+ return true; |
+} |
+ |
+bool DecodeTime(const net::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); |
+} |
davidben
2016/09/06 17:21:45
Nit: newline
jam
2016/09/06 17:43:24
Done.
|
+} |
davidben
2016/09/06 17:21:45
Nit: // namespace
jam
2016/09/06 17:43:24
Done.
|
+ |
namespace x509_util { |
// RSA keys created by CreateKeyAndSelfSignedCert will be of this length. |
@@ -82,6 +114,61 @@ 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) { |
+ net::der::Input cert_data(certificate); |
davidben
2016/09/06 17:21:46
#include "net/der/input.h"
jam
2016/09/06 17:43:24
Done.
|
+ net::der::Input tbs_cert, signature_alg; |
+ net::der::BitString signature_value; |
davidben
2016/09/06 17:21:46
#include "net/der/parse_values.h"
jam
2016/09/06 17:43:24
Done.
|
+ bool rv = net::ParseCertificate(cert_data, &tbs_cert, &signature_alg, |
+ &signature_value); |
+ if (!rv) |
davidben
2016/09/06 17:21:45
Nit: Rather than bool rv, could just write
if (!P
jam
2016/09/06 17:43:24
Done.
|
+ return false; |
+ |
+ net::ParsedTbsCertificate parsed_tbs_cert; |
+ rv = net::ParseTbsCertificate(tbs_cert, net::ParseCertificateOptions(), |
+ &parsed_tbs_cert); |
+ if (!rv) |
+ 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<net::der::Input, net::ParsedExtension> extensions; |
+ if (!net::ParseExtensions(parsed_tbs_cert.extensions_tlv, &extensions)) |
+ return false; |
+ |
+ std::vector<std::string> san; |
+ if (extensions.find(net::SubjectAltNameOid()) != extensions.end()) { |
davidben
2016/09/06 17:21:45
Not that it matters, but may as well save a lookup
jam
2016/09/06 17:43:24
Done.
|
+ std::unique_ptr<net::GeneralNames> subject_alt_names = |
+ net::GeneralNames::CreateFromDer( |
+ extensions[net::SubjectAltNameOid()].value); |
+ if (subject_alt_names) { |
+ *dns_names = subject_alt_names->dns_names; |
+ for (const net::IPAddress& ip : subject_alt_names->ip_addresses) |
+ ip_addresses->push_back(ip.ToString()); |
+ } |
+ } |
+ |
+ return true; |
+} |
+ |
} // namespace x509_util |
} // namespace net |