Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1411)

Side by Side Diff: net/cert/x509_certificate_ios.cc

Issue 1882433002: Removing NSS files and USE_OPENSSL flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/cert/test_root_certs_unittest.cc ('k') | net/cert/x509_certificate_openssl_ios.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <CommonCrypto/CommonDigest.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <Security/Security.h> 8 #include <Security/Security.h>
9 #include <cert.h>
10 #include <cryptohi.h>
11 #include <keyhi.h>
12 #include <nss.h>
13 #include <pk11pub.h>
14 #include <prerror.h>
15 #include <prtime.h>
16 #include <prtypes.h>
17 #include <secder.h>
18 #include <secerr.h>
19 #include <sslerr.h>
20 9
21 #include <memory> 10 #include <openssl/x509.h>
22 #include <vector> 11 #include <openssl/x509v3.h>
23 12
24 #include "base/logging.h"
25 #include "base/mac/scoped_cftyperef.h" 13 #include "base/mac/scoped_cftyperef.h"
26 #include "base/numerics/safe_conversions.h"
27 #include "base/pickle.h" 14 #include "base/pickle.h"
28 #include "base/time/time.h" 15 #include "base/strings/string_piece.h"
29 #include "crypto/nss_util.h" 16 #include "base/strings/string_util.h"
30 #include "crypto/scoped_nss_types.h" 17 #include "crypto/openssl_util.h"
31 #include "net/base/net_errors.h" 18 #include "crypto/scoped_openssl_types.h"
32 #include "net/cert/asn1_util.h" 19 #include "net/base/ip_address_number.h"
33 #include "net/cert/cert_status_flags.h" 20 #include "net/cert/x509_util_openssl.h"
34 #include "net/cert/cert_verify_result.h" 21 #include "net/ssl/openssl_ssl_util.h"
35 #include "net/cert/ev_root_ca_metadata.h"
36 #include "net/cert/x509_util_ios.h"
37 #include "net/cert/x509_util_nss.h"
38 22
39 using base::ScopedCFTypeRef; 23 using base::ScopedCFTypeRef;
40 24
41 namespace net { 25 namespace net {
26
42 namespace { 27 namespace {
28
29 using ScopedGENERAL_NAMES =
30 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
31
43 // Returns true if a given |cert_handle| is actually a valid X.509 certificate 32 // Returns true if a given |cert_handle| is actually a valid X.509 certificate
44 // handle. 33 // handle.
45 // 34 //
46 // SecCertificateCreateFromData() does not always force the immediate parsing of 35 // SecCertificateCreateFromData() does not always force the immediate parsing of
47 // the certificate, and as such, may return a SecCertificateRef for an 36 // the certificate, and as such, may return a SecCertificateRef for an
48 // invalid/unparsable certificate. Force parsing to occur to ensure that the 37 // invalid/unparsable certificate. Force parsing to occur to ensure that the
49 // SecCertificateRef is correct. On later versions where 38 // SecCertificateRef is correct. On later versions where
50 // SecCertificateCreateFromData() immediately parses, rather than lazily, this 39 // SecCertificateCreateFromData() immediately parses, rather than lazily, this
51 // call is cheap, as the subject is cached. 40 // call is cheap, as the subject is cached.
52 bool IsValidOSCertHandle(SecCertificateRef cert_handle) { 41 bool IsValidOSCertHandle(SecCertificateRef cert_handle) {
53 ScopedCFTypeRef<CFStringRef> sanity_check( 42 ScopedCFTypeRef<CFStringRef> sanity_check(
54 SecCertificateCopySubjectSummary(cert_handle)); 43 SecCertificateCopySubjectSummary(cert_handle));
55 return sanity_check != NULL; 44 return sanity_check != nullptr;
56 }
57 } // namespace
58
59 void X509Certificate::Initialize() {
60 x509_util_ios::NSSCertificate nss_cert(cert_handle_);
61 CERTCertificate* cert_handle = nss_cert.cert_handle();
62 if (cert_handle) {
63 x509_util::ParsePrincipal(&cert_handle->subject, &subject_);
64 x509_util::ParsePrincipal(&cert_handle->issuer, &issuer_);
65 x509_util::ParseDate(&cert_handle->validity.notBefore, &valid_start_);
66 x509_util::ParseDate(&cert_handle->validity.notAfter, &valid_expiry_);
67 serial_number_ = x509_util::ParseSerialNumber(cert_handle);
68 }
69 fingerprint_ = CalculateFingerprint(cert_handle_);
70 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
71 } 45 }
72 46
73 bool X509Certificate::IsIssuedByEncoded( 47 void CreateOSCertHandlesFromPKCS7Bytes(
74 const std::vector<std::string>& valid_issuers) { 48 const char* data,
75 x509_util_ios::NSSCertChain nss_chain(this); 49 size_t length,
76 // Convert to scoped CERTName* list. 50 X509Certificate::OSCertHandles* handles) {
77 std::vector<CERTName*> issuers; 51 crypto::EnsureOpenSSLInit();
78 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); 52 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
79 if (!x509_util::GetIssuersFromEncodedList(valid_issuers, 53
80 arena.get(), 54 CBS der_data;
81 &issuers)) { 55 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length);
82 return false; 56 STACK_OF(X509)* certs = sk_X509_new_null();
57
58 if (PKCS7_get_certificates(certs, &der_data)) {
59 for (size_t i = 0; i < sk_X509_num(certs); ++i) {
60 X509* x509_cert = sk_X509_value(certs, i);
61 base::StringPiece der;
62 if (!x509_util::GetDER(x509_cert, &der))
63 return;
64 handles->push_back(X509Certificate::CreateOSCertHandleFromBytes(
65 der.data(), der.length()));
66 }
83 } 67 }
84 return x509_util::IsCertificateIssuedBy( 68 sk_X509_pop_free(certs, X509_free);
85 nss_chain.cert_chain(), issuers);
86 } 69 }
87 70
88 void X509Certificate::GetSubjectAltName( 71 void ParsePrincipalValues(X509_NAME* name,
89 std::vector<std::string>* dns_names, 72 int nid,
90 std::vector<std::string>* ip_addrs) const { 73 std::vector<std::string>* fields) {
91 x509_util_ios::NSSCertificate nss_cert(cert_handle_); 74 for (int index = -1;
92 CERTCertificate* cert_handle = nss_cert.cert_handle(); 75 (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) {
93 if (!cert_handle) { 76 std::string field;
94 if (dns_names) 77 if (!x509_util::ParsePrincipalValueByIndex(name, index, &field))
95 dns_names->clear(); 78 break;
96 if (ip_addrs) 79 fields->push_back(field);
97 ip_addrs->clear();
98 return;
99 } 80 }
100 x509_util::GetSubjectAltName(cert_handle, dns_names, ip_addrs);
101 } 81 }
102 82
103 // static 83 void ParsePrincipal(X509Certificate::OSCertHandle os_cert,
104 bool X509Certificate::GetDEREncoded(OSCertHandle cert_handle, 84 X509_NAME* x509_name,
105 std::string* encoded) { 85 CertPrincipal* principal) {
106 if (!cert_handle) 86 if (!x509_name)
107 return false; 87 return;
108 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle)); 88
109 if (!der_data) 89 ParsePrincipalValues(x509_name, NID_streetAddress,
110 return false; 90 &principal->street_addresses);
111 encoded->assign(reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)), 91 ParsePrincipalValues(x509_name, NID_organizationName,
112 CFDataGetLength(der_data)); 92 &principal->organization_names);
113 return true; 93 ParsePrincipalValues(x509_name, NID_organizationalUnitName,
94 &principal->organization_unit_names);
95 ParsePrincipalValues(x509_name, NID_domainComponent,
96 &principal->domain_components);
97
98 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName,
99 &principal->common_name);
100 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName,
101 &principal->locality_name);
102 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName,
103 &principal->state_or_province_name);
104 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName,
105 &principal->country_name);
114 } 106 }
115 107
116 // static 108 void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
117 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, 109 std::vector<std::string>* dns_names,
118 X509Certificate::OSCertHandle b) { 110 std::vector<std::string>* ip_addresses) {
119 DCHECK(a && b); 111 DCHECK(dns_names || ip_addresses);
120 if (a == b) 112 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
121 return true; 113 if (!cert.get())
122 if (CFEqual(a, b)) 114 return;
123 return true; 115 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
124 ScopedCFTypeRef<CFDataRef> a_data(SecCertificateCopyData(a)); 116 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index);
125 ScopedCFTypeRef<CFDataRef> b_data(SecCertificateCopyData(b)); 117 if (!alt_name_ext)
126 return a_data && b_data && 118 return;
127 CFDataGetLength(a_data) == CFDataGetLength(b_data) && 119
128 memcmp(CFDataGetBytePtr(a_data), CFDataGetBytePtr(b_data), 120 ScopedGENERAL_NAMES alt_names(
129 CFDataGetLength(a_data)) == 0; 121 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
122 if (!alt_names.get())
123 return;
124
125 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
126 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
127 if (name->type == GEN_DNS && dns_names) {
128 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
129 if (!dns_name)
130 continue;
131 int dns_name_len = ASN1_STRING_length(name->d.dNSName);
132 dns_names->push_back(
133 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len));
134 } else if (name->type == GEN_IPADD && ip_addresses) {
135 const unsigned char* ip_addr = name->d.iPAddress->data;
136 if (!ip_addr)
137 continue;
138 int ip_addr_len = name->d.iPAddress->length;
139 if (ip_addr_len != static_cast<int>(kIPv4AddressSize) &&
140 ip_addr_len != static_cast<int>(kIPv6AddressSize)) {
141 // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress
142 // to have 4 or 16 bytes, whereas in a name constraint it includes a
143 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup.
144 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
145 continue;
146 }
147 ip_addresses->push_back(
148 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len));
149 }
150 }
130 } 151 }
131 152
132 // static 153 // Used to free a list of X509_NAMEs and the objects it points to.
133 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 154 void sk_X509_NAME_free_all(STACK_OF(X509_NAME) * sk) {
134 const char* data, 155 sk_X509_NAME_pop_free(sk, X509_NAME_free);
135 size_t length) {
136 ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy(
137 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
138 base::checked_cast<CFIndex>(length), kCFAllocatorNull));
139 if (!cert_data)
140 return nullptr;
141 OSCertHandle cert_handle = SecCertificateCreateWithData(NULL, cert_data);
142 if (!cert_handle)
143 return nullptr;
144 if (!IsValidOSCertHandle(cert_handle)) {
145 CFRelease(cert_handle);
146 return nullptr;
147 }
148 return cert_handle;
149 } 156 }
150 157
151 // static 158 } // namespace
152 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
153 const char* data,
154 size_t length,
155 Format format) {
156 return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
157 }
158 159
159 // static 160 // static
160 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 161 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
161 OSCertHandle handle) { 162 OSCertHandle handle) {
162 if (!handle) 163 if (!handle)
163 return NULL; 164 return nullptr;
164 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); 165 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
165 } 166 }
166 167
167 // static 168 // static
168 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 169 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
169 if (cert_handle) 170 if (cert_handle)
170 CFRelease(cert_handle); 171 CFRelease(cert_handle);
171 } 172 }
172 173
174 void X509Certificate::Initialize() {
175 crypto::EnsureOpenSSLInit();
176 fingerprint_ = CalculateFingerprint(cert_handle_);
177 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
178 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_);
179 if (!x509_cert)
180 return;
181 ASN1_INTEGER* serial_num = X509_get_serialNumber(x509_cert.get());
182 if (serial_num) {
183 // ASN1_INTEGERS represent the decoded number, in a format internal to
184 // OpenSSL. Most notably, this may have leading zeroes stripped off for
185 // numbers whose first byte is >= 0x80. Thus, it is necessary to
186 // re-encoded the integer back into DER, which is what the interface
187 // of X509Certificate exposes, to ensure callers get the proper (DER)
188 // value.
189 int bytes_required = i2c_ASN1_INTEGER(serial_num, nullptr);
190 unsigned char* buffer = reinterpret_cast<unsigned char*>(
191 base::WriteInto(&serial_number_, bytes_required + 1));
192 int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer);
193 DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size());
194 }
195
196 ParsePrincipal(cert_handle_, X509_get_subject_name(x509_cert.get()),
197 &subject_);
198 ParsePrincipal(cert_handle_, X509_get_issuer_name(x509_cert.get()), &issuer_);
199 x509_util::ParseDate(X509_get_notBefore(x509_cert.get()), &valid_start_);
200 x509_util::ParseDate(X509_get_notAfter(x509_cert.get()), &valid_expiry_);
201 }
202
173 // static 203 // static
174 SHA1HashValue X509Certificate::CalculateFingerprint( 204 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) {
175 OSCertHandle cert) {
176 SHA1HashValue sha1; 205 SHA1HashValue sha1;
177 memset(sha1.data, 0, sizeof(sha1.data)); 206 memset(sha1.data, 0, sizeof(sha1.data));
178 207
179 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert)); 208 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
180 if (!cert_data) 209 if (!cert_data)
181 return sha1; 210 return sha1;
182 DCHECK(CFDataGetBytePtr(cert_data)); 211 DCHECK(CFDataGetBytePtr(cert_data));
183 DCHECK_NE(0, CFDataGetLength(cert_data)); 212 DCHECK_NE(0, CFDataGetLength(cert_data));
184 CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data); 213 CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data);
185 214
186 return sha1; 215 return sha1;
187 } 216 }
188 217
189 // static 218 // static
190 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { 219 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
191 SHA256HashValue sha256; 220 SHA256HashValue sha256;
192 memset(sha256.data, 0, sizeof(sha256.data)); 221 memset(sha256.data, 0, sizeof(sha256.data));
193 222
194 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert)); 223 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
195 if (!cert_data) 224 if (!cert_data)
196 return sha256; 225 return sha256;
197 DCHECK(CFDataGetBytePtr(cert_data)); 226 DCHECK(CFDataGetBytePtr(cert_data));
198 DCHECK_NE(0, CFDataGetLength(cert_data)); 227 DCHECK_NE(0, CFDataGetLength(cert_data));
199 CC_SHA256( 228 CC_SHA256(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data),
200 CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha256.data); 229 sha256.data);
201 230
202 return sha256; 231 return sha256;
203 } 232 }
204 233
205 // static 234 // static
206 SHA1HashValue X509Certificate::CalculateCAFingerprint( 235 SHA1HashValue X509Certificate::CalculateCAFingerprint(
207 const OSCertHandles& intermediates) { 236 const OSCertHandles& intermediates) {
208 SHA1HashValue sha1; 237 SHA1HashValue sha1;
209 memset(sha1.data, 0, sizeof(sha1.data)); 238 memset(sha1.data, 0, sizeof(sha1.data));
210 239
211 // The CC_SHA(3cc) man page says all CC_SHA1_xxx routines return 1, so
212 // we don't check their return values.
213 CC_SHA1_CTX sha1_ctx; 240 CC_SHA1_CTX sha1_ctx;
214 CC_SHA1_Init(&sha1_ctx); 241 CC_SHA1_Init(&sha1_ctx);
215 for (size_t i = 0; i < intermediates.size(); ++i) { 242 for (size_t i = 0; i < intermediates.size(); ++i) {
216 ScopedCFTypeRef<CFDataRef> 243 ScopedCFTypeRef<CFDataRef> cert_data(
217 cert_data(SecCertificateCopyData(intermediates[i])); 244 SecCertificateCopyData(intermediates[i]));
218 if (!cert_data) 245 if (!cert_data)
219 return sha1; 246 return sha1;
220 CC_SHA1_Update(&sha1_ctx, 247 CC_SHA1_Update(&sha1_ctx, CFDataGetBytePtr(cert_data),
221 CFDataGetBytePtr(cert_data),
222 CFDataGetLength(cert_data)); 248 CFDataGetLength(cert_data));
223 } 249 }
224 CC_SHA1_Final(sha1.data, &sha1_ctx); 250 CC_SHA1_Final(sha1.data, &sha1_ctx);
225 return sha1; 251 return sha1;
226 } 252 }
227 253
228 // static 254 // static
255 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
256 const char* data,
257 size_t length) {
258 ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy(
259 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
260 base::checked_cast<CFIndex>(length), kCFAllocatorNull));
261 if (!cert_data)
262 return nullptr;
263 OSCertHandle cert_handle = SecCertificateCreateWithData(nullptr, cert_data);
264 if (!cert_handle)
265 return nullptr;
266 if (!IsValidOSCertHandle(cert_handle)) {
267 CFRelease(cert_handle);
268 return nullptr;
269 }
270 return cert_handle;
271 }
272
273 // static
274 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
275 const char* data,
276 size_t length,
277 Format format) {
278 OSCertHandles results;
279
280 switch (format) {
281 case FORMAT_SINGLE_CERTIFICATE: {
282 OSCertHandle handle =
283 X509Certificate::CreateOSCertHandleFromBytes(data, length);
284 if (handle)
285 results.push_back(handle);
286 break;
287 }
288 case FORMAT_PKCS7: {
289 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results);
290 break;
291 }
292 default: {
293 NOTREACHED() << "Certificate format " << format << " unimplemented";
294 break;
295 }
296 }
297
298 return results;
299 }
300
301 void X509Certificate::GetSubjectAltName(
302 std::vector<std::string>* dns_names,
303 std::vector<std::string>* ip_addrs) const {
304 if (dns_names)
305 dns_names->clear();
306 if (ip_addrs)
307 ip_addrs->clear();
308
309 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs);
310 }
311
312 // static
313 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
314 std::string* encoded) {
315 base::StringPiece der;
316 if (!cert_handle)
317 return false;
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));
323 return true;
324 }
325
326 // static
327 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
328 X509Certificate::OSCertHandle b) {
329 DCHECK(a && b);
330 return CFEqual(a, b);
331 }
332
333 // static
229 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle( 334 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle(
230 base::PickleIterator* pickle_iter) { 335 base::PickleIterator* pickle_iter) {
231 return x509_util::ReadOSCertHandleFromPickle(pickle_iter); 336 const char* data;
337 int length;
338 if (!pickle_iter->ReadData(&data, &length))
339 return nullptr;
340
341 return X509Certificate::CreateOSCertHandleFromBytes(data, length);
232 } 342 }
233 343
234 // static 344 // static
235 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, 345 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
236 base::Pickle* pickle) { 346 base::Pickle* pickle) {
237 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle)); 347 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle));
238 if (!cert_data) 348 if (!cert_data)
239 return false; 349 return false;
240 350
241 return pickle->WriteData( 351 return pickle->WriteData(
242 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)), 352 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)),
243 CFDataGetLength(cert_data)); 353 CFDataGetLength(cert_data));
244 } 354 }
245 355
246 // static 356 // static
247 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, 357 void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert,
248 size_t* size_bits, 358 size_t* size_bits,
249 PublicKeyType* type) { 359 PublicKeyType* type) {
250 x509_util_ios::NSSCertificate nss_cert(cert_handle); 360 *type = kPublicKeyTypeUnknown;
251 x509_util::GetPublicKeyInfo(nss_cert.cert_handle(), size_bits, type); 361 *size_bits = 0;
362 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
363 if (!cert)
364 return;
365 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
366 if (!scoped_key)
367 return;
368
369 EVP_PKEY* key = scoped_key.get();
370
371 switch (key->type) {
372 case EVP_PKEY_RSA:
373 *type = kPublicKeyTypeRSA;
374 break;
375 case EVP_PKEY_DSA:
376 *type = kPublicKeyTypeDSA;
377 break;
378 case EVP_PKEY_EC:
379 *type = kPublicKeyTypeECDSA;
380 break;
381 case EVP_PKEY_DH:
382 *type = kPublicKeyTypeDH;
383 break;
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;
403 }
404
405 bool X509Certificate::IsIssuedByEncoded(
406 const std::vector<std::string>& valid_issuers) {
407 if (valid_issuers.empty())
408 return false;
409
410 // Convert to a temporary list of X509_NAME objects.
411 // It will own the objects it points to.
412 crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all>
413 issuer_names(sk_X509_NAME_new_null());
414 if (!issuer_names)
415 return false;
416
417 for (std::vector<std::string>::const_iterator it = valid_issuers.begin();
418 it != valid_issuers.end(); ++it) {
419 const unsigned char* p = reinterpret_cast<const unsigned char*>(it->data());
420 long len = static_cast<long>(it->length());
421 X509_NAME* ca_name = d2i_X509_NAME(nullptr, &p, len);
422 if (ca_name == nullptr)
423 return false;
424 sk_X509_NAME_push(issuer_names.get(), ca_name);
425 }
426
427 ScopedX509 x509_cert = OSCertHandleToOpenSSL(cert_handle_);
428 if (!x509_cert)
429 return false;
430 X509_NAME* cert_issuer = X509_get_issuer_name(x509_cert.get());
431 if (cert_issuer == nullptr)
432 return false;
433
434 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) {
435 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m);
436 if (X509_NAME_cmp(issuer, cert_issuer) == 0) {
437 return true;
438 }
439 }
440
441 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin();
442 it != intermediate_ca_certs_.end(); ++it) {
443 ScopedX509 intermediate_cert = OSCertHandleToOpenSSL(*it);
444 if (!intermediate_cert)
445 return false;
446 cert_issuer = X509_get_issuer_name(intermediate_cert.get());
447 if (cert_issuer == nullptr)
448 return false;
449
450 for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) {
451 X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m);
452 if (X509_NAME_cmp(issuer, cert_issuer) == 0) {
453 return true;
454 }
455 }
456 }
457
458 return false;
252 } 459 }
253 460
254 // static 461 // static
255 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { 462 bool X509Certificate::IsSelfSigned(OSCertHandle os_cert) {
256 x509_util_ios::NSSCertificate nss_cert(cert_handle); 463 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
257 crypto::ScopedSECKEYPublicKey public_key( 464 if (!cert)
258 CERT_ExtractPublicKey(nss_cert.cert_handle()));
259 if (!public_key.get())
260 return false; 465 return false;
261 return SECSuccess == CERT_VerifySignedDataWithPublicKey( 466 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
262 &nss_cert.cert_handle()->signatureWrap, public_key.get(), NULL); 467 if (!scoped_key)
468 return false;
469
470 // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error.
471 return X509_verify(cert.get(), scoped_key.get()) == 1;
263 } 472 }
264 473
265 } // namespace net 474 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/test_root_certs_unittest.cc ('k') | net/cert/x509_certificate_openssl_ios.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698