OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/x509_certificate.h" | 5 #include "net/cert/x509_certificate.h" |
6 | 6 |
7 #include <openssl/asn1.h> | 7 #include <CommonCrypto/CommonDigest.h> |
8 #include <openssl/bytestring.h> | 8 #include <Security/Security.h> |
9 #include <openssl/crypto.h> | 9 |
10 #include <openssl/obj_mac.h> | 10 #include <openssl/x509.h> |
11 #include <openssl/pem.h> | |
12 #include <openssl/sha.h> | |
13 #include <openssl/ssl.h> | |
14 #include <openssl/x509v3.h> | 11 #include <openssl/x509v3.h> |
15 | 12 |
16 #include "base/macros.h" | 13 #include "base/mac/scoped_cftyperef.h" |
17 #include "base/memory/singleton.h" | |
18 #include "base/numerics/safe_conversions.h" | |
19 #include "base/pickle.h" | 14 #include "base/pickle.h" |
20 #include "base/sha1.h" | |
21 #include "base/strings/string_number_conversions.h" | |
22 #include "base/strings/string_piece.h" | 15 #include "base/strings/string_piece.h" |
23 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
24 #include "crypto/openssl_util.h" | 17 #include "crypto/openssl_util.h" |
25 #include "crypto/scoped_openssl_types.h" | 18 #include "crypto/scoped_openssl_types.h" |
26 #include "net/base/ip_address_number.h" | 19 #include "net/base/ip_address_number.h" |
27 #include "net/base/net_errors.h" | |
28 #include "net/cert/x509_util_openssl.h" | 20 #include "net/cert/x509_util_openssl.h" |
| 21 #include "net/ssl/openssl_ssl_util.h" |
29 | 22 |
30 #if defined(OS_ANDROID) | 23 using base::ScopedCFTypeRef; |
31 #include "base/logging.h" | |
32 #include "net/android/network_library.h" | |
33 #endif | |
34 | 24 |
35 namespace net { | 25 namespace net { |
36 | 26 |
37 namespace { | 27 namespace { |
38 | 28 |
39 using ScopedGENERAL_NAMES = | 29 using ScopedGENERAL_NAMES = |
40 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>; | 30 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>; |
41 | 31 |
| 32 // Returns true if a given |cert_handle| is actually a valid X.509 certificate |
| 33 // handle. |
| 34 // |
| 35 // SecCertificateCreateFromData() does not always force the immediate parsing of |
| 36 // the certificate, and as such, may return a SecCertificateRef for an |
| 37 // invalid/unparsable certificate. Force parsing to occur to ensure that the |
| 38 // SecCertificateRef is correct. On later versions where |
| 39 // SecCertificateCreateFromData() immediately parses, rather than lazily, this |
| 40 // call is cheap, as the subject is cached. |
| 41 bool IsValidOSCertHandle(SecCertificateRef cert_handle) { |
| 42 ScopedCFTypeRef<CFStringRef> sanity_check( |
| 43 SecCertificateCopySubjectSummary(cert_handle)); |
| 44 return sanity_check != nullptr; |
| 45 } |
| 46 |
42 void CreateOSCertHandlesFromPKCS7Bytes( | 47 void CreateOSCertHandlesFromPKCS7Bytes( |
43 const char* data, | 48 const char* data, |
44 size_t length, | 49 size_t length, |
45 X509Certificate::OSCertHandles* handles) { | 50 X509Certificate::OSCertHandles* handles) { |
46 crypto::EnsureOpenSSLInit(); | 51 crypto::EnsureOpenSSLInit(); |
47 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE); | 52 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE); |
48 | 53 |
49 CBS der_data; | 54 CBS der_data; |
50 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length); | 55 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length); |
51 STACK_OF(X509)* certs = sk_X509_new_null(); | 56 STACK_OF(X509)* certs = sk_X509_new_null(); |
52 | 57 |
53 if (PKCS7_get_certificates(certs, &der_data)) { | 58 if (PKCS7_get_certificates(certs, &der_data)) { |
54 for (size_t i = 0; i < sk_X509_num(certs); ++i) { | 59 for (size_t i = 0; i < sk_X509_num(certs); ++i) { |
55 X509* x509_cert = | 60 X509* x509_cert = sk_X509_value(certs, i); |
56 X509Certificate::DupOSCertHandle(sk_X509_value(certs, i)); | 61 base::StringPiece der; |
57 handles->push_back(x509_cert); | 62 if (!x509_util::GetDER(x509_cert, &der)) |
| 63 return; |
| 64 handles->push_back(X509Certificate::CreateOSCertHandleFromBytes( |
| 65 der.data(), der.length())); |
58 } | 66 } |
59 } | 67 } |
60 sk_X509_pop_free(certs, X509_free); | 68 sk_X509_pop_free(certs, X509_free); |
61 } | 69 } |
62 | 70 |
63 void ParsePrincipalValues(X509_NAME* name, | 71 void ParsePrincipalValues(X509_NAME* name, |
64 int nid, | 72 int nid, |
65 std::vector<std::string>* fields) { | 73 std::vector<std::string>* fields) { |
66 for (int index = -1; | 74 for (int index = -1; |
67 (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) { | 75 (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) { |
68 std::string field; | 76 std::string field; |
69 if (!x509_util::ParsePrincipalValueByIndex(name, index, &field)) | 77 if (!x509_util::ParsePrincipalValueByIndex(name, index, &field)) |
70 break; | 78 break; |
71 fields->push_back(field); | 79 fields->push_back(field); |
72 } | 80 } |
73 } | 81 } |
74 | 82 |
75 void ParsePrincipal(X509Certificate::OSCertHandle cert, | 83 void ParsePrincipal(X509Certificate::OSCertHandle os_cert, |
76 X509_NAME* x509_name, | 84 X509_NAME* x509_name, |
77 CertPrincipal* principal) { | 85 CertPrincipal* principal) { |
78 if (!x509_name) | 86 if (!x509_name) |
79 return; | 87 return; |
80 | 88 |
81 ParsePrincipalValues(x509_name, NID_streetAddress, | 89 ParsePrincipalValues(x509_name, NID_streetAddress, |
82 &principal->street_addresses); | 90 &principal->street_addresses); |
83 ParsePrincipalValues(x509_name, NID_organizationName, | 91 ParsePrincipalValues(x509_name, NID_organizationName, |
84 &principal->organization_names); | 92 &principal->organization_names); |
85 ParsePrincipalValues(x509_name, NID_organizationalUnitName, | 93 ParsePrincipalValues(x509_name, NID_organizationalUnitName, |
86 &principal->organization_unit_names); | 94 &principal->organization_unit_names); |
87 ParsePrincipalValues(x509_name, NID_domainComponent, | 95 ParsePrincipalValues(x509_name, NID_domainComponent, |
88 &principal->domain_components); | 96 &principal->domain_components); |
89 | 97 |
90 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, | 98 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, |
91 &principal->common_name); | 99 &principal->common_name); |
92 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, | 100 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, |
93 &principal->locality_name); | 101 &principal->locality_name); |
94 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, | 102 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, |
95 &principal->state_or_province_name); | 103 &principal->state_or_province_name); |
96 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, | 104 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, |
97 &principal->country_name); | 105 &principal->country_name); |
98 } | 106 } |
99 | 107 |
100 void ParseSubjectAltName(X509Certificate::OSCertHandle cert, | 108 void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert, |
101 std::vector<std::string>* dns_names, | 109 std::vector<std::string>* dns_names, |
102 std::vector<std::string>* ip_addresses) { | 110 std::vector<std::string>* ip_addresses) { |
103 DCHECK(dns_names || ip_addresses); | 111 DCHECK(dns_names || ip_addresses); |
104 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); | 112 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert); |
105 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); | 113 if (!cert.get()) |
| 114 return; |
| 115 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1); |
| 116 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index); |
106 if (!alt_name_ext) | 117 if (!alt_name_ext) |
107 return; | 118 return; |
108 | 119 |
109 ScopedGENERAL_NAMES alt_names( | 120 ScopedGENERAL_NAMES alt_names( |
110 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); | 121 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); |
111 if (!alt_names.get()) | 122 if (!alt_names.get()) |
112 return; | 123 return; |
113 | 124 |
114 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { | 125 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { |
115 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); | 126 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); |
(...skipping 16 matching lines...) Expand all Loading... |
132 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. | 143 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. |
133 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; | 144 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; |
134 continue; | 145 continue; |
135 } | 146 } |
136 ip_addresses->push_back( | 147 ip_addresses->push_back( |
137 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); | 148 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); |
138 } | 149 } |
139 } | 150 } |
140 } | 151 } |
141 | 152 |
142 class X509InitSingleton { | |
143 public: | |
144 static X509InitSingleton* GetInstance() { | |
145 // We allow the X509 store to leak, because it is used from a non-joinable | |
146 // worker that is not stopped on shutdown, hence may still be using | |
147 // OpenSSL library after the AtExit runner has completed. | |
148 return base::Singleton<X509InitSingleton, base::LeakySingletonTraits< | |
149 X509InitSingleton>>::get(); | |
150 } | |
151 X509_STORE* store() const { return store_.get(); } | |
152 | |
153 void ResetCertStore() { | |
154 store_.reset(X509_STORE_new()); | |
155 DCHECK(store_.get()); | |
156 X509_STORE_set_default_paths(store_.get()); | |
157 // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)). | |
158 } | |
159 | |
160 private: | |
161 friend struct base::DefaultSingletonTraits<X509InitSingleton>; | |
162 X509InitSingleton() { | |
163 crypto::EnsureOpenSSLInit(); | |
164 ResetCertStore(); | |
165 } | |
166 | |
167 crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_; | |
168 | |
169 DISALLOW_COPY_AND_ASSIGN(X509InitSingleton); | |
170 }; | |
171 | |
172 // Used to free a list of X509_NAMEs and the objects it points to. | 153 // Used to free a list of X509_NAMEs and the objects it points to. |
173 void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) { | 154 void sk_X509_NAME_free_all(STACK_OF(X509_NAME) * sk) { |
174 sk_X509_NAME_pop_free(sk, X509_NAME_free); | 155 sk_X509_NAME_pop_free(sk, X509_NAME_free); |
175 } | 156 } |
176 | 157 |
177 } // namespace | 158 } // namespace |
178 | 159 |
179 // static | 160 // static |
180 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 161 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
181 OSCertHandle cert_handle) { | 162 OSCertHandle handle) { |
182 DCHECK(cert_handle); | 163 if (!handle) |
183 return X509_up_ref(cert_handle); | 164 return nullptr; |
| 165 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); |
184 } | 166 } |
185 | 167 |
186 // static | 168 // static |
187 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { | 169 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
188 // Decrement the ref-count for the cert and, if all references are gone, | 170 if (cert_handle) |
189 // free the memory and any application-specific data associated with the | 171 CFRelease(cert_handle); |
190 // certificate. | |
191 X509_free(cert_handle); | |
192 } | 172 } |
193 | 173 |
194 void X509Certificate::Initialize() { | 174 void X509Certificate::Initialize() { |
195 crypto::EnsureOpenSSLInit(); | 175 crypto::EnsureOpenSSLInit(); |
196 fingerprint_ = CalculateFingerprint(cert_handle_); | 176 fingerprint_ = CalculateFingerprint(cert_handle_); |
197 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); | 177 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); |
198 | 178 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_); |
199 ASN1_INTEGER* serial_num = X509_get_serialNumber(cert_handle_); | 179 if (!x509_cert) |
| 180 return; |
| 181 ASN1_INTEGER* serial_num = X509_get_serialNumber(x509_cert.get()); |
200 if (serial_num) { | 182 if (serial_num) { |
201 // ASN1_INTEGERS represent the decoded number, in a format internal to | 183 // ASN1_INTEGERS represent the decoded number, in a format internal to |
202 // OpenSSL. Most notably, this may have leading zeroes stripped off for | 184 // OpenSSL. Most notably, this may have leading zeroes stripped off for |
203 // numbers whose first byte is >= 0x80. Thus, it is necessary to | 185 // numbers whose first byte is >= 0x80. Thus, it is necessary to |
204 // re-encoded the integer back into DER, which is what the interface | 186 // re-encoded the integer back into DER, which is what the interface |
205 // of X509Certificate exposes, to ensure callers get the proper (DER) | 187 // of X509Certificate exposes, to ensure callers get the proper (DER) |
206 // value. | 188 // value. |
207 int bytes_required = i2c_ASN1_INTEGER(serial_num, NULL); | 189 int bytes_required = i2c_ASN1_INTEGER(serial_num, nullptr); |
208 unsigned char* buffer = reinterpret_cast<unsigned char*>( | 190 unsigned char* buffer = reinterpret_cast<unsigned char*>( |
209 base::WriteInto(&serial_number_, bytes_required + 1)); | 191 base::WriteInto(&serial_number_, bytes_required + 1)); |
210 int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer); | 192 int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer); |
211 DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size()); | 193 DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size()); |
212 } | 194 } |
213 | 195 |
214 ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_); | 196 ParsePrincipal(cert_handle_, X509_get_subject_name(x509_cert.get()), |
215 ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_); | 197 &subject_); |
216 x509_util::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_); | 198 ParsePrincipal(cert_handle_, X509_get_issuer_name(x509_cert.get()), &issuer_); |
217 x509_util::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_); | 199 x509_util::ParseDate(X509_get_notBefore(x509_cert.get()), &valid_start_); |
218 } | 200 x509_util::ParseDate(X509_get_notAfter(x509_cert.get()), &valid_expiry_); |
219 | |
220 // static | |
221 void X509Certificate::ResetCertStore() { | |
222 X509InitSingleton::GetInstance()->ResetCertStore(); | |
223 } | 201 } |
224 | 202 |
225 // static | 203 // static |
226 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) { | 204 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) { |
227 SHA1HashValue sha1; | 205 SHA1HashValue sha1; |
228 unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data)); | 206 memset(sha1.data, 0, sizeof(sha1.data)); |
229 int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size); | 207 |
230 CHECK(ret); | 208 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert)); |
231 CHECK_EQ(sha1_size, sizeof(sha1.data)); | 209 if (!cert_data) |
| 210 return sha1; |
| 211 DCHECK(CFDataGetBytePtr(cert_data)); |
| 212 DCHECK_NE(0, CFDataGetLength(cert_data)); |
| 213 CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data); |
| 214 |
232 return sha1; | 215 return sha1; |
233 } | 216 } |
234 | 217 |
235 // static | 218 // static |
236 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { | 219 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { |
237 SHA256HashValue sha256; | 220 SHA256HashValue sha256; |
238 unsigned int sha256_size = static_cast<unsigned int>(sizeof(sha256.data)); | 221 memset(sha256.data, 0, sizeof(sha256.data)); |
239 int ret = X509_digest(cert, EVP_sha256(), sha256.data, &sha256_size); | 222 |
240 CHECK(ret); | 223 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert)); |
241 CHECK_EQ(sha256_size, sizeof(sha256.data)); | 224 if (!cert_data) |
| 225 return sha256; |
| 226 DCHECK(CFDataGetBytePtr(cert_data)); |
| 227 DCHECK_NE(0, CFDataGetLength(cert_data)); |
| 228 CC_SHA256(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), |
| 229 sha256.data); |
| 230 |
242 return sha256; | 231 return sha256; |
243 } | 232 } |
244 | 233 |
245 // static | 234 // static |
246 SHA1HashValue X509Certificate::CalculateCAFingerprint( | 235 SHA1HashValue X509Certificate::CalculateCAFingerprint( |
247 const OSCertHandles& intermediates) { | 236 const OSCertHandles& intermediates) { |
248 SHA1HashValue sha1; | 237 SHA1HashValue sha1; |
249 memset(sha1.data, 0, sizeof(sha1.data)); | 238 memset(sha1.data, 0, sizeof(sha1.data)); |
250 | 239 |
251 SHA_CTX sha1_ctx; | 240 CC_SHA1_CTX sha1_ctx; |
252 SHA1_Init(&sha1_ctx); | 241 CC_SHA1_Init(&sha1_ctx); |
253 base::StringPiece der; | |
254 for (size_t i = 0; i < intermediates.size(); ++i) { | 242 for (size_t i = 0; i < intermediates.size(); ++i) { |
255 if (!x509_util::GetDER(intermediates[i], &der)) | 243 ScopedCFTypeRef<CFDataRef> cert_data( |
| 244 SecCertificateCopyData(intermediates[i])); |
| 245 if (!cert_data) |
256 return sha1; | 246 return sha1; |
257 SHA1_Update(&sha1_ctx, der.data(), der.length()); | 247 CC_SHA1_Update(&sha1_ctx, CFDataGetBytePtr(cert_data), |
| 248 CFDataGetLength(cert_data)); |
258 } | 249 } |
259 SHA1_Final(sha1.data, &sha1_ctx); | 250 CC_SHA1_Final(sha1.data, &sha1_ctx); |
260 | |
261 return sha1; | 251 return sha1; |
262 } | 252 } |
263 | 253 |
264 // static | 254 // static |
265 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( | 255 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( |
266 const char* data, | 256 const char* data, |
267 size_t length) { | 257 size_t length) { |
268 crypto::EnsureOpenSSLInit(); | 258 ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy( |
269 const unsigned char* d2i_data = | 259 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), |
270 reinterpret_cast<const unsigned char*>(data); | 260 base::checked_cast<CFIndex>(length), kCFAllocatorNull)); |
271 // Don't cache this data for x509_util::GetDER as this wire format | 261 if (!cert_data) |
272 // may be not be identical from the i2d_X509 roundtrip. | 262 return nullptr; |
273 X509* cert = d2i_X509(NULL, &d2i_data, base::checked_cast<long>(length)); | 263 OSCertHandle cert_handle = SecCertificateCreateWithData(nullptr, cert_data); |
274 return cert; | 264 if (!cert_handle) |
| 265 return nullptr; |
| 266 if (!IsValidOSCertHandle(cert_handle)) { |
| 267 CFRelease(cert_handle); |
| 268 return nullptr; |
| 269 } |
| 270 return cert_handle; |
275 } | 271 } |
276 | 272 |
277 // static | 273 // static |
278 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( | 274 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( |
279 const char* data, | 275 const char* data, |
280 size_t length, | 276 size_t length, |
281 Format format) { | 277 Format format) { |
282 OSCertHandles results; | 278 OSCertHandles results; |
283 | 279 |
284 switch (format) { | 280 switch (format) { |
285 case FORMAT_SINGLE_CERTIFICATE: { | 281 case FORMAT_SINGLE_CERTIFICATE: { |
286 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); | 282 OSCertHandle handle = |
| 283 X509Certificate::CreateOSCertHandleFromBytes(data, length); |
287 if (handle) | 284 if (handle) |
288 results.push_back(handle); | 285 results.push_back(handle); |
289 break; | 286 break; |
290 } | 287 } |
291 case FORMAT_PKCS7: { | 288 case FORMAT_PKCS7: { |
292 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results); | 289 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results); |
293 break; | 290 break; |
294 } | 291 } |
295 default: { | 292 default: { |
296 NOTREACHED() << "Certificate format " << format << " unimplemented"; | 293 NOTREACHED() << "Certificate format " << format << " unimplemented"; |
297 break; | 294 break; |
298 } | 295 } |
299 } | 296 } |
300 | 297 |
301 return results; | 298 return results; |
302 } | 299 } |
303 | 300 |
304 void X509Certificate::GetSubjectAltName( | 301 void X509Certificate::GetSubjectAltName( |
305 std::vector<std::string>* dns_names, | 302 std::vector<std::string>* dns_names, |
306 std::vector<std::string>* ip_addrs) const { | 303 std::vector<std::string>* ip_addrs) const { |
307 if (dns_names) | 304 if (dns_names) |
308 dns_names->clear(); | 305 dns_names->clear(); |
309 if (ip_addrs) | 306 if (ip_addrs) |
310 ip_addrs->clear(); | 307 ip_addrs->clear(); |
311 | 308 |
312 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); | 309 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); |
313 } | 310 } |
314 | 311 |
315 // static | 312 // static |
316 X509_STORE* X509Certificate::cert_store() { | |
317 return X509InitSingleton::GetInstance()->store(); | |
318 } | |
319 | |
320 // static | |
321 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, | 313 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, |
322 std::string* encoded) { | 314 std::string* encoded) { |
323 base::StringPiece der; | 315 base::StringPiece der; |
324 if (!cert_handle || !x509_util::GetDER(cert_handle, &der)) | 316 if (!cert_handle) |
325 return false; | 317 return false; |
326 encoded->assign(der.data(), der.length()); | 318 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle)); |
| 319 if (!der_data) |
| 320 return false; |
| 321 encoded->assign(reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)), |
| 322 CFDataGetLength(der_data)); |
327 return true; | 323 return true; |
328 } | 324 } |
329 | 325 |
330 // static | 326 // static |
331 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, | 327 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, |
332 X509Certificate::OSCertHandle b) { | 328 X509Certificate::OSCertHandle b) { |
333 DCHECK(a && b); | 329 DCHECK(a && b); |
334 if (a == b) | 330 return CFEqual(a, b); |
335 return true; | |
336 | |
337 // X509_cmp only checks the fingerprint, but we want to compare the whole | |
338 // DER data. Encoding it from OSCertHandle is an expensive operation, so we | |
339 // cache the DER (if not already cached via X509_set_ex_data). | |
340 base::StringPiece der_a, der_b; | |
341 | |
342 return x509_util::GetDER(a, &der_a) && | |
343 x509_util::GetDER(b, &der_b) && | |
344 der_a == der_b; | |
345 } | 331 } |
346 | 332 |
347 // static | 333 // static |
348 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle( | 334 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle( |
349 base::PickleIterator* pickle_iter) { | 335 base::PickleIterator* pickle_iter) { |
350 const char* data; | 336 const char* data; |
351 int length; | 337 int length; |
352 if (!pickle_iter->ReadData(&data, &length)) | 338 if (!pickle_iter->ReadData(&data, &length)) |
353 return NULL; | 339 return nullptr; |
354 | 340 |
355 return CreateOSCertHandleFromBytes(data, length); | 341 return X509Certificate::CreateOSCertHandleFromBytes(data, length); |
356 } | 342 } |
357 | 343 |
358 // static | 344 // static |
359 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, | 345 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, |
360 base::Pickle* pickle) { | 346 base::Pickle* pickle) { |
361 base::StringPiece der; | 347 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle)); |
362 if (!x509_util::GetDER(cert_handle, &der)) | 348 if (!cert_data) |
363 return false; | 349 return false; |
364 | 350 |
365 return pickle->WriteData(der.data(), der.length()); | 351 return pickle->WriteData( |
| 352 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)), |
| 353 CFDataGetLength(cert_data)); |
366 } | 354 } |
367 | 355 |
368 // static | 356 // static |
369 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, | 357 void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert, |
370 size_t* size_bits, | 358 size_t* size_bits, |
371 PublicKeyType* type) { | 359 PublicKeyType* type) { |
372 *type = kPublicKeyTypeUnknown; | 360 *type = kPublicKeyTypeUnknown; |
373 *size_bits = 0; | 361 *size_bits = 0; |
374 | 362 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert); |
375 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle)); | 363 if (!cert) |
376 if (!scoped_key.get()) | 364 return; |
| 365 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get())); |
| 366 if (!scoped_key) |
377 return; | 367 return; |
378 | 368 |
379 CHECK(scoped_key.get()); | |
380 EVP_PKEY* key = scoped_key.get(); | 369 EVP_PKEY* key = scoped_key.get(); |
381 | 370 |
382 switch (key->type) { | 371 switch (key->type) { |
383 case EVP_PKEY_RSA: | 372 case EVP_PKEY_RSA: |
384 *type = kPublicKeyTypeRSA; | 373 *type = kPublicKeyTypeRSA; |
385 *size_bits = EVP_PKEY_size(key) * 8; | |
386 break; | 374 break; |
387 case EVP_PKEY_DSA: | 375 case EVP_PKEY_DSA: |
388 *type = kPublicKeyTypeDSA; | 376 *type = kPublicKeyTypeDSA; |
389 *size_bits = EVP_PKEY_size(key) * 8; | |
390 break; | 377 break; |
391 case EVP_PKEY_EC: | 378 case EVP_PKEY_EC: |
392 *type = kPublicKeyTypeECDSA; | 379 *type = kPublicKeyTypeECDSA; |
393 *size_bits = EVP_PKEY_bits(key); | |
394 break; | 380 break; |
395 case EVP_PKEY_DH: | 381 case EVP_PKEY_DH: |
396 *type = kPublicKeyTypeDH; | 382 *type = kPublicKeyTypeDH; |
397 *size_bits = EVP_PKEY_size(key) * 8; | |
398 break; | 383 break; |
399 } | 384 } |
| 385 *size_bits = EVP_PKEY_bits(key); |
| 386 } |
| 387 |
| 388 bool X509Certificate::SupportsSSLClientAuth() const { |
| 389 return false; |
| 390 } |
| 391 |
| 392 CFMutableArrayRef X509Certificate::CreateOSCertChainForCert() const { |
| 393 CFMutableArrayRef cert_list = |
| 394 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); |
| 395 if (!cert_list) |
| 396 return nullptr; |
| 397 |
| 398 CFArrayAppendValue(cert_list, os_cert_handle()); |
| 399 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) |
| 400 CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]); |
| 401 |
| 402 return cert_list; |
400 } | 403 } |
401 | 404 |
402 bool X509Certificate::IsIssuedByEncoded( | 405 bool X509Certificate::IsIssuedByEncoded( |
403 const std::vector<std::string>& valid_issuers) { | 406 const std::vector<std::string>& valid_issuers) { |
404 if (valid_issuers.empty()) | 407 if (valid_issuers.empty()) |
405 return false; | 408 return false; |
406 | 409 |
407 // Convert to a temporary list of X509_NAME objects. | 410 // Convert to a temporary list of X509_NAME objects. |
408 // It will own the objects it points to. | 411 // It will own the objects it points to. |
409 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all> | 412 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all> |
410 issuer_names(sk_X509_NAME_new_null()); | 413 issuer_names(sk_X509_NAME_new_null()); |
411 if (!issuer_names.get()) | 414 if (!issuer_names) |
412 return false; | 415 return false; |
413 | 416 |
414 for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); | 417 for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); |
415 it != valid_issuers.end(); ++it) { | 418 it != valid_issuers.end(); ++it) { |
416 const unsigned char* p = | 419 const unsigned char* p = reinterpret_cast<const unsigned char*>(it->data()); |
417 reinterpret_cast<const unsigned char*>(it->data()); | |
418 long len = static_cast<long>(it->length()); | 420 long len = static_cast<long>(it->length()); |
419 X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len); | 421 X509_NAME* ca_name = d2i_X509_NAME(nullptr, &p, len); |
420 if (ca_name == NULL) | 422 if (ca_name == nullptr) |
421 return false; | 423 return false; |
422 sk_X509_NAME_push(issuer_names.get(), ca_name); | 424 sk_X509_NAME_push(issuer_names.get(), ca_name); |
423 } | 425 } |
424 | 426 |
425 // Create a temporary list of X509_NAME objects corresponding | 427 // Create a temporary list of X509_NAME objects corresponding |
426 // to the certificate chain. It doesn't own the object it points to. | 428 // to the certificate chain. It doesn't own the object it points to. |
427 std::vector<X509_NAME*> cert_names; | 429 std::vector<X509_NAME*> cert_names; |
428 X509_NAME* issuer = X509_get_issuer_name(cert_handle_); | 430 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_); |
429 if (issuer == NULL) | 431 if (!x509_cert) |
| 432 return false; |
| 433 X509_NAME* issuer = X509_get_issuer_name(x509_cert.get()); |
| 434 if (issuer == nullptr) |
430 return false; | 435 return false; |
431 | 436 |
432 cert_names.push_back(issuer); | 437 cert_names.push_back(issuer); |
433 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); | 438 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); |
434 it != intermediate_ca_certs_.end(); ++it) { | 439 it != intermediate_ca_certs_.end(); ++it) { |
435 issuer = X509_get_issuer_name(*it); | 440 ScopedX509 intermediate_cert = OSCertHandleToOpenSSL(*it); |
436 if (issuer == NULL) | 441 if (!intermediate_cert) |
| 442 return false; |
| 443 issuer = X509_get_issuer_name(intermediate_cert.get()); |
| 444 if (issuer == nullptr) |
437 return false; | 445 return false; |
438 cert_names.push_back(issuer); | 446 cert_names.push_back(issuer); |
439 } | 447 } |
440 | 448 |
441 // and 'cert_names'. | 449 // and 'cert_names'. |
442 for (size_t n = 0; n < cert_names.size(); ++n) { | 450 for (size_t n = 0; n < cert_names.size(); ++n) { |
443 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { | 451 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { |
444 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); | 452 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); |
445 if (X509_NAME_cmp(issuer, cert_names[n]) == 0) { | 453 if (X509_NAME_cmp(issuer, cert_names[n]) == 0) { |
446 return true; | 454 return true; |
447 } | 455 } |
448 } | 456 } |
449 } | 457 } |
450 | 458 |
451 return false; | 459 return false; |
452 } | 460 } |
453 | 461 |
454 // static | 462 // static |
455 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { | 463 bool X509Certificate::IsSelfSigned(OSCertHandle os_cert) { |
456 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle)); | 464 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert); |
| 465 if (!cert) |
| 466 return false; |
| 467 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get())); |
457 if (!scoped_key) | 468 if (!scoped_key) |
458 return false; | 469 return false; |
459 | 470 |
460 // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error. | 471 // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error. |
461 return X509_verify(cert_handle, scoped_key.get()) == 1; | 472 return X509_verify(cert.get(), scoped_key.get()) == 1; |
462 } | 473 } |
463 | 474 |
464 } // namespace net | 475 } // namespace net |
OLD | NEW |