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.
4
5 #include "chrome/common/net/x509_certificate_model.h"
6
7 #include <openssl/bio.h>
8 #include <openssl/obj_mac.h>
9 #include <openssl/sha.h>
10 #include <openssl/x509v3.h>
11
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"
17
18 namespace x509_util = net::x509_util;
19
20 namespace {
21
AlternativeWhenEmpty(const std::string & text,const std::string & alternative)22 std::string AlternativeWhenEmpty(const std::string& text,
23 const std::string& alternative) {
24 return text.empty() ? alternative : text;
25 }
26
GetKeyValuesFromName(X509_NAME * name)27 std::string GetKeyValuesFromName(X509_NAME* name) {
28 std::string ret;
29 int rdns = X509_NAME_entry_count(name) - 1;
30 for (int i = rdns; i >= 0; --i) {
31 std::string key;
32 std::string value;
33 if (!x509_util::ParsePrincipalKeyAndValueByIndex(name, i, &key, &value))
34 break;
35 ret += key;
36 ret += " = ";
37 ret += value;
38 ret += '\n';
39 }
40 return ret;
41 }
42
43 } // namespace
44
45 namespace x509_certificate_model {
46
47 using net::X509Certificate;
48
GetCertNameOrNickname(X509Certificate::OSCertHandle cert_handle)49 std::string GetCertNameOrNickname(X509Certificate::OSCertHandle cert_handle) {
50 std::string name =
51 ProcessIDN(GetSubjectCommonName(cert_handle, std::string()));
52 if (!name.empty())
53 return name;
54
55 crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&name));
56 if (!bio.get())
57 return name;
58 X509_NAME_print_ex(bio.get(),
59 X509_get_subject_name(cert_handle),
60 0 /* indent */,
61 XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
62 return name;
63 }
64
GetTokenName(X509Certificate::OSCertHandle cert_handle)65 std::string GetTokenName(X509Certificate::OSCertHandle cert_handle) {
66 // TODO(bulach): implement me.
67 return "";
68 }
69
GetVersion(net::X509Certificate::OSCertHandle cert_handle)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);
74 return "";
75 }
76
GetType(X509Certificate::OSCertHandle os_cert)77 net::CertType GetType(X509Certificate::OSCertHandle os_cert) {
78 // TODO(bulach): implement me.
79 return net::OTHER_CERT;
80 }
81
GetUsageStrings(X509Certificate::OSCertHandle cert_handle,std::vector<std::string> * usages)82 void GetUsageStrings(X509Certificate::OSCertHandle cert_handle,
83 std::vector<std::string>* usages) {
84 // TODO(bulach): implement me.
85 }
86
GetSerialNumberHexified(X509Certificate::OSCertHandle cert_handle,const std::string & alternative_text)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);
95 }
96
GetIssuerCommonName(X509Certificate::OSCertHandle cert_handle,const std::string & alternative_text)97 std::string GetIssuerCommonName(
98 X509Certificate::OSCertHandle cert_handle,
99 const std::string& alternative_text) {
100 std::string ret;
101 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle),
102 NID_commonName, &ret);
103 return AlternativeWhenEmpty(ret, alternative_text);
104 }
105
GetIssuerOrgName(X509Certificate::OSCertHandle cert_handle,const std::string & alternative_text)106 std::string GetIssuerOrgName(
107 X509Certificate::OSCertHandle cert_handle,
108 const std::string& alternative_text) {
109 std::string ret;
110 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle),
111 NID_organizationName, &ret);
112 return AlternativeWhenEmpty(ret, alternative_text);
113 }
114
GetIssuerOrgUnitName(X509Certificate::OSCertHandle cert_handle,const std::string & alternative_text)115 std::string GetIssuerOrgUnitName(
116 X509Certificate::OSCertHandle cert_handle,
117 const std::string& alternative_text) {
118 std::string ret;
119 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle),
120 NID_organizationalUnitName, &ret);
121 return AlternativeWhenEmpty(ret, alternative_text);
122 }
123
GetSubjectOrgName(X509Certificate::OSCertHandle cert_handle,const std::string & alternative_text)124 std::string GetSubjectOrgName(
125 X509Certificate::OSCertHandle cert_handle,
126 const std::string& alternative_text) {
127 std::string ret;
128 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle),
129 NID_organizationName, &ret);
130 return AlternativeWhenEmpty(ret, alternative_text);
131 }
132
GetSubjectOrgUnitName(X509Certificate::OSCertHandle cert_handle,const std::string & alternative_text)133 std::string GetSubjectOrgUnitName(
134 X509Certificate::OSCertHandle cert_handle,
135 const std::string& alternative_text) {
136 std::string ret;
137 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle),
138 NID_organizationalUnitName, &ret);
139 return AlternativeWhenEmpty(ret, alternative_text);
140 }
141
GetSubjectCommonName(X509Certificate::OSCertHandle cert_handle,const std::string & alternative_text)142 std::string GetSubjectCommonName(X509Certificate::OSCertHandle cert_handle,
143 const std::string& alternative_text) {
144 std::string ret;
145 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle),
146 NID_commonName, &ret);
147 return AlternativeWhenEmpty(ret, alternative_text);
148 }
149
GetTimes(X509Certificate::OSCertHandle cert_handle,base::Time * issued,base::Time * expires)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);
154 }
155
GetTitle(net::X509Certificate::OSCertHandle cert_handle)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
159 // doesn't?
160 std::string title =
161 GetSubjectCommonName(cert_handle, std::string());
162 if (!title.empty())
163 return title;
164
165 crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&title));
166 if (!bio.get())
167 return title;
168 X509_NAME_print_ex(bio.get(),
169 X509_get_subject_name(cert_handle),
170 0 /* indent */,
171 XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
172 return title;
173 }
174
GetIssuerName(net::X509Certificate::OSCertHandle cert_handle)175 std::string GetIssuerName(net::X509Certificate::OSCertHandle cert_handle) {
176 return GetKeyValuesFromName(X509_get_issuer_name(cert_handle));
177 }
178
GetSubjectName(net::X509Certificate::OSCertHandle cert_handle)179 std::string GetSubjectName(net::X509Certificate::OSCertHandle cert_handle) {
180 return GetKeyValuesFromName(X509_get_subject_name(cert_handle));
181 }
182
GetExtensions(const std::string & critical_label,const std::string & non_critical_label,net::X509Certificate::OSCertHandle cert_handle,Extensions * extensions)183 void GetExtensions(
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.
189 }
190
HashCertSHA256(net::X509Certificate::OSCertHandle cert_handle)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);
195 DCHECK(ret);
196 DCHECK_EQ(sha256_size, sizeof(sha256_data));
197 return ProcessRawBytes(sha256_data, sha256_size);
198 }
199
HashCertSHA1(net::X509Certificate::OSCertHandle cert_handle)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);
204 DCHECK(ret);
205 DCHECK_EQ(sha1_size, sizeof(sha1_data));
206 return ProcessRawBytes(sha1_data, sha1_size);
207 }
208
GetCertChainFromCert(net::X509Certificate::OSCertHandle cert_handle,net::X509Certificate::OSCertHandles * cert_handles)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));
213 }
214
DestroyCertChain(net::X509Certificate::OSCertHandles * cert_handles)215 void DestroyCertChain(net::X509Certificate::OSCertHandles* cert_handles) {
216 for (net::X509Certificate::OSCertHandles::iterator i = cert_handles->begin();
217 i != cert_handles->end(); ++i)
218 X509_free(*i);
219 cert_handles->clear();
220 }
221
GetDerString(net::X509Certificate::OSCertHandle cert_handle)222 std::string GetDerString(net::X509Certificate::OSCertHandle cert_handle) {
223 // TODO(bulach): implement me.
224 return "";
225 }
226
GetCMSString(const net::X509Certificate::OSCertHandles & cert_chain,size_t start,size_t end)227 std::string GetCMSString(const net::X509Certificate::OSCertHandles& cert_chain,
228 size_t start, size_t end) {
229 // TODO(bulach): implement me.
230 return "";
231 }
232
ProcessSecAlgorithmSignature(net::X509Certificate::OSCertHandle cert_handle)233 std::string ProcessSecAlgorithmSignature(
234 net::X509Certificate::OSCertHandle cert_handle) {
235 // TODO(bulach): implement me.
236 return "";
237 }
238
ProcessSecAlgorithmSubjectPublicKey(net::X509Certificate::OSCertHandle cert_handle)239 std::string ProcessSecAlgorithmSubjectPublicKey(
240 net::X509Certificate::OSCertHandle cert_handle) {
241 // TODO(bulach): implement me.
242 return "";
243 }
244
ProcessSecAlgorithmSignatureWrap(net::X509Certificate::OSCertHandle cert_handle)245 std::string ProcessSecAlgorithmSignatureWrap(
246 net::X509Certificate::OSCertHandle cert_handle) {
247 // TODO(bulach): implement me.
248 return "";
249 }
250
ProcessSubjectPublicKeyInfo(net::X509Certificate::OSCertHandle cert_handle)251 std::string ProcessSubjectPublicKeyInfo(
252 net::X509Certificate::OSCertHandle cert_handle) {
253 // TODO(bulach): implement me.
254 return "";
255 }
256
ProcessRawBitsSignatureWrap(net::X509Certificate::OSCertHandle cert_handle)257 std::string ProcessRawBitsSignatureWrap(
258 net::X509Certificate::OSCertHandle cert_handle) {
259 // TODO(bulach): implement me.
260 return "";
261 }
262
263 } // namespace x509_certificate_model
264