1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/net/x509_certificate_model.h"
7 #include <openssl/bio.h>
8 #include <openssl/obj_mac.h>
9 #include <openssl/sha.h>
10 #include <openssl/x509v3.h>
12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "crypto/openssl_bio_string.h"
15 #include "crypto/openssl_util.h"
16 #include "net/cert/x509_util_openssl.h"
18 namespace x509_util = net::x509_util;
22 std::string AlternativeWhenEmpty(const std::string& text,
23 const std::string& alternative) {
24 return text.empty() ? alternative : text;
27 std::string GetKeyValuesFromName(X509_NAME* name) {
29 int rdns = X509_NAME_entry_count(name) - 1;
30 for (int i = rdns; i >= 0; --i) {
33 if (!x509_util::ParsePrincipalKeyAndValueByIndex(name, i, &key, &value))
45 namespace x509_certificate_model {
47 using net::X509Certificate;
49 std::string GetCertNameOrNickname(X509Certificate::OSCertHandle cert_handle) {
51 ProcessIDN(GetSubjectCommonName(cert_handle, std::string()));
55 crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&name));
58 X509_NAME_print_ex(bio.get(),
59 X509_get_subject_name(cert_handle),
61 XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
65 std::string GetTokenName(X509Certificate::OSCertHandle cert_handle) {
66 // TODO(bulach): implement me.
70 std::string GetVersion(net::X509Certificate::OSCertHandle cert_handle) {
71 unsigned long version = X509_get_version(cert_handle);
72 if (version != ULONG_MAX)
73 return base::UintToString(version + 1);
77 net::CertType GetType(X509Certificate::OSCertHandle os_cert) {
78 // TODO(bulach): implement me.
79 return net::OTHER_CERT;
82 void GetUsageStrings(X509Certificate::OSCertHandle cert_handle,
83 std::vector<std::string>* usages) {
84 // TODO(bulach): implement me.
87 std::string GetSerialNumberHexified(
88 X509Certificate::OSCertHandle cert_handle,
89 const std::string& alternative_text) {
90 ASN1_INTEGER* num = X509_get_serialNumber(cert_handle);
91 const char kSerialNumberSeparator = ':';
92 std::string hex_string = ProcessRawBytesWithSeparators(
93 num->data, num->length, kSerialNumberSeparator, kSerialNumberSeparator);
94 return AlternativeWhenEmpty(hex_string, alternative_text);
97 std::string GetIssuerCommonName(
98 X509Certificate::OSCertHandle cert_handle,
99 const std::string& alternative_text) {
101 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle),
102 NID_commonName, &ret);
103 return AlternativeWhenEmpty(ret, alternative_text);
106 std::string GetIssuerOrgName(
107 X509Certificate::OSCertHandle cert_handle,
108 const std::string& alternative_text) {
110 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle),
111 NID_organizationName, &ret);
112 return AlternativeWhenEmpty(ret, alternative_text);
115 std::string GetIssuerOrgUnitName(
116 X509Certificate::OSCertHandle cert_handle,
117 const std::string& alternative_text) {
119 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle),
120 NID_organizationalUnitName, &ret);
121 return AlternativeWhenEmpty(ret, alternative_text);
124 std::string GetSubjectOrgName(
125 X509Certificate::OSCertHandle cert_handle,
126 const std::string& alternative_text) {
128 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle),
129 NID_organizationName, &ret);
130 return AlternativeWhenEmpty(ret, alternative_text);
133 std::string GetSubjectOrgUnitName(
134 X509Certificate::OSCertHandle cert_handle,
135 const std::string& alternative_text) {
137 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle),
138 NID_organizationalUnitName, &ret);
139 return AlternativeWhenEmpty(ret, alternative_text);
142 std::string GetSubjectCommonName(X509Certificate::OSCertHandle cert_handle,
143 const std::string& alternative_text) {
145 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle),
146 NID_commonName, &ret);
147 return AlternativeWhenEmpty(ret, alternative_text);
150 bool GetTimes(X509Certificate::OSCertHandle cert_handle,
151 base::Time* issued, base::Time* expires) {
152 return x509_util::ParseDate(X509_get_notBefore(cert_handle), issued) &&
153 x509_util::ParseDate(X509_get_notAfter(cert_handle), expires);
156 std::string GetTitle(net::X509Certificate::OSCertHandle cert_handle) {
157 // TODO(mattm): merge GetTitle and GetCertNameOrNickname?
158 // Is there any reason GetCertNameOrNickname calls ProcessIDN and this
161 GetSubjectCommonName(cert_handle, std::string());
165 crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&title));
168 X509_NAME_print_ex(bio.get(),
169 X509_get_subject_name(cert_handle),
171 XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
175 std::string GetIssuerName(net::X509Certificate::OSCertHandle cert_handle) {
176 return GetKeyValuesFromName(X509_get_issuer_name(cert_handle));
179 std::string GetSubjectName(net::X509Certificate::OSCertHandle cert_handle) {
180 return GetKeyValuesFromName(X509_get_subject_name(cert_handle));
184 const std::string& critical_label,
185 const std::string& non_critical_label,
186 net::X509Certificate::OSCertHandle cert_handle,
187 Extensions* extensions) {
188 // TODO(bulach): implement me.
191 std::string HashCertSHA256(net::X509Certificate::OSCertHandle cert_handle) {
192 unsigned char sha256_data[SHA256_DIGEST_LENGTH] = {0};
193 unsigned int sha256_size = sizeof(sha256_data);
194 int ret = X509_digest(cert_handle, EVP_sha256(), sha256_data, &sha256_size);
196 DCHECK_EQ(sha256_size, sizeof(sha256_data));
197 return ProcessRawBytes(sha256_data, sha256_size);
200 std::string HashCertSHA1(net::X509Certificate::OSCertHandle cert_handle) {
201 unsigned char sha1_data[SHA_DIGEST_LENGTH] = {0};
202 unsigned int sha1_size = sizeof(sha1_data);
203 int ret = X509_digest(cert_handle, EVP_sha1(), sha1_data, &sha1_size);
205 DCHECK_EQ(sha1_size, sizeof(sha1_data));
206 return ProcessRawBytes(sha1_data, sha1_size);
209 void GetCertChainFromCert(net::X509Certificate::OSCertHandle cert_handle,
210 net::X509Certificate::OSCertHandles* cert_handles) {
211 // TODO(bulach): how to get the chain out of a certificate?
212 cert_handles->push_back(net::X509Certificate::DupOSCertHandle(cert_handle));
215 void DestroyCertChain(net::X509Certificate::OSCertHandles* cert_handles) {
216 for (net::X509Certificate::OSCertHandles::iterator i = cert_handles->begin();
217 i != cert_handles->end(); ++i)
219 cert_handles->clear();
222 std::string GetDerString(net::X509Certificate::OSCertHandle cert_handle) {
223 // TODO(bulach): implement me.
227 std::string GetCMSString(const net::X509Certificate::OSCertHandles& cert_chain,
228 size_t start, size_t end) {
229 // TODO(bulach): implement me.
233 std::string ProcessSecAlgorithmSignature(
234 net::X509Certificate::OSCertHandle cert_handle) {
235 // TODO(bulach): implement me.
239 std::string ProcessSecAlgorithmSubjectPublicKey(
240 net::X509Certificate::OSCertHandle cert_handle) {
241 // TODO(bulach): implement me.
245 std::string ProcessSecAlgorithmSignatureWrap(
246 net::X509Certificate::OSCertHandle cert_handle) {
247 // TODO(bulach): implement me.
251 std::string ProcessSubjectPublicKeyInfo(
252 net::X509Certificate::OSCertHandle cert_handle) {
253 // TODO(bulach): implement me.
257 std::string ProcessRawBitsSignatureWrap(
258 net::X509Certificate::OSCertHandle cert_handle) {
259 // TODO(bulach): implement me.
263 } // namespace x509_certificate_model