• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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