Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / chrome / common / net / x509_certificate_model_openssl.cc
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
22 std::string AlternativeWhenEmpty(const std::string& text,
23                                  const std::string& alternative) {
24   return text.empty() ? alternative : text;
25 }
26
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
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
65 std::string GetTokenName(X509Certificate::OSCertHandle cert_handle) {
66   // TODO(bulach): implement me.
67   return "";
68 }
69
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
77 net::CertType GetType(X509Certificate::OSCertHandle os_cert) {
78   // TODO(bulach): implement me.
79   return net::OTHER_CERT;
80 }
81
82 void GetUsageStrings(X509Certificate::OSCertHandle cert_handle,
83                          std::vector<std::string>* usages) {
84   // TODO(bulach): implement me.
85 }
86
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
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
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
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
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
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
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
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
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
175 std::string GetIssuerName(net::X509Certificate::OSCertHandle cert_handle) {
176   return GetKeyValuesFromName(X509_get_issuer_name(cert_handle));
177 }
178
179 std::string GetSubjectName(net::X509Certificate::OSCertHandle cert_handle) {
180   return GetKeyValuesFromName(X509_get_subject_name(cert_handle));
181 }
182
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
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
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
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
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
222 std::string GetDerString(net::X509Certificate::OSCertHandle cert_handle) {
223   // TODO(bulach): implement me.
224   return "";
225 }
226
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
233 std::string ProcessSecAlgorithmSignature(
234     net::X509Certificate::OSCertHandle cert_handle) {
235   // TODO(bulach): implement me.
236   return "";
237 }
238
239 std::string ProcessSecAlgorithmSubjectPublicKey(
240     net::X509Certificate::OSCertHandle cert_handle) {
241   // TODO(bulach): implement me.
242   return "";
243 }
244
245 std::string ProcessSecAlgorithmSignatureWrap(
246     net::X509Certificate::OSCertHandle cert_handle) {
247   // TODO(bulach): implement me.
248   return "";
249 }
250
251 std::string ProcessSubjectPublicKeyInfo(
252     net::X509Certificate::OSCertHandle cert_handle) {
253   // TODO(bulach): implement me.
254   return "";
255 }
256
257 std::string ProcessRawBitsSignatureWrap(
258     net::X509Certificate::OSCertHandle cert_handle) {
259   // TODO(bulach): implement me.
260   return "";
261 }
262
263 }  // namespace x509_certificate_model