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

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: Fixing header ordering. 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
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 9
10 #include <cert.h> 10 #include <openssl/x509.h>
11 #include <cryptohi.h> 11 #include <openssl/x509v3.h>
12 #include <keyhi.h>
13 #include <nss.h>
14 #include <pk11pub.h>
15 #include <prerror.h>
16 #include <prtime.h>
17 #include <prtypes.h>
18 #include <secder.h>
19 #include <secerr.h>
20 #include <sslerr.h>
21 12
22 #include <vector>
23
24 #include "base/logging.h"
25 #include "base/mac/scoped_cftyperef.h" 13 #include "base/mac/scoped_cftyperef.h"
26 #include "base/memory/scoped_ptr.h"
27 #include "base/numerics/safe_conversions.h"
28 #include "base/pickle.h" 14 #include "base/pickle.h"
29 #include "base/time/time.h" 15 #include "base/strings/string_piece.h"
30 #include "crypto/nss_util.h" 16 #include "base/strings/string_util.h"
31 #include "crypto/scoped_nss_types.h" 17 #include "crypto/openssl_util.h"
32 #include "net/base/net_errors.h" 18 #include "crypto/scoped_openssl_types.h"
33 #include "net/cert/asn1_util.h" 19 #include "net/base/ip_address_number.h"
34 #include "net/cert/cert_status_flags.h" 20 #include "net/cert/x509_util_openssl.h"
35 #include "net/cert/cert_verify_result.h" 21 #include "net/ssl/openssl_ssl_util.h"
36 #include "net/cert/ev_root_ca_metadata.h"
37 #include "net/cert/x509_util_ios.h"
38 #include "net/cert/x509_util_nss.h"
39 22
40 using base::ScopedCFTypeRef; 23 using base::ScopedCFTypeRef;
41 24
42 namespace net { 25 namespace net {
26
43 namespace { 27 namespace {
28
29 using ScopedGENERAL_NAMES =
30 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>;
31
44 // 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
45 // handle. 33 // handle.
46 // 34 //
47 // SecCertificateCreateFromData() does not always force the immediate parsing of 35 // SecCertificateCreateFromData() does not always force the immediate parsing of
48 // the certificate, and as such, may return a SecCertificateRef for an 36 // the certificate, and as such, may return a SecCertificateRef for an
49 // invalid/unparsable certificate. Force parsing to occur to ensure that the 37 // invalid/unparsable certificate. Force parsing to occur to ensure that the
50 // SecCertificateRef is correct. On later versions where 38 // SecCertificateRef is correct. On later versions where
51 // SecCertificateCreateFromData() immediately parses, rather than lazily, this 39 // SecCertificateCreateFromData() immediately parses, rather than lazily, this
52 // call is cheap, as the subject is cached. 40 // call is cheap, as the subject is cached.
53 bool IsValidOSCertHandle(SecCertificateRef cert_handle) { 41 bool IsValidOSCertHandle(SecCertificateRef cert_handle) {
54 ScopedCFTypeRef<CFStringRef> sanity_check( 42 ScopedCFTypeRef<CFStringRef> sanity_check(
55 SecCertificateCopySubjectSummary(cert_handle)); 43 SecCertificateCopySubjectSummary(cert_handle));
56 return sanity_check != NULL; 44 return sanity_check != nullptr;
57 }
58 } // namespace
59
60 void X509Certificate::Initialize() {
61 x509_util_ios::NSSCertificate nss_cert(cert_handle_);
62 CERTCertificate* cert_handle = nss_cert.cert_handle();
63 if (cert_handle) {
64 x509_util::ParsePrincipal(&cert_handle->subject, &subject_);
65 x509_util::ParsePrincipal(&cert_handle->issuer, &issuer_);
66 x509_util::ParseDate(&cert_handle->validity.notBefore, &valid_start_);
67 x509_util::ParseDate(&cert_handle->validity.notAfter, &valid_expiry_);
68 serial_number_ = x509_util::ParseSerialNumber(cert_handle);
69 }
70 fingerprint_ = CalculateFingerprint(cert_handle_);
71 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
72 } 45 }
73 46
74 bool X509Certificate::IsIssuedByEncoded( 47 void CreateOSCertHandlesFromPKCS7Bytes(
75 const std::vector<std::string>& valid_issuers) { 48 const char* data,
76 x509_util_ios::NSSCertChain nss_chain(this); 49 size_t length,
77 // Convert to scoped CERTName* list. 50 X509Certificate::OSCertHandles* handles) {
78 std::vector<CERTName*> issuers; 51 crypto::EnsureOpenSSLInit();
79 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); 52 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
80 if (!x509_util::GetIssuersFromEncodedList(valid_issuers, 53
81 arena.get(), 54 CBS der_data;
82 &issuers)) { 55 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length);
83 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 }
84 } 67 }
85 return x509_util::IsCertificateIssuedBy( 68 sk_X509_pop_free(certs, X509_free);
86 nss_chain.cert_chain(), issuers);
87 } 69 }
88 70
89 void X509Certificate::GetSubjectAltName( 71 void ParsePrincipalValues(X509_NAME* name,
90 std::vector<std::string>* dns_names, 72 int nid,
91 std::vector<std::string>* ip_addrs) const { 73 std::vector<std::string>* fields) {
92 x509_util_ios::NSSCertificate nss_cert(cert_handle_); 74 for (int index = -1;
93 CERTCertificate* cert_handle = nss_cert.cert_handle(); 75 (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) {
94 if (!cert_handle) { 76 std::string field;
95 if (dns_names) 77 if (!x509_util::ParsePrincipalValueByIndex(name, index, &field))
96 dns_names->clear(); 78 break;
97 if (ip_addrs) 79 fields->push_back(field);
98 ip_addrs->clear();
99 return;
100 } 80 }
101 x509_util::GetSubjectAltName(cert_handle, dns_names, ip_addrs);
102 } 81 }
103 82
104 // static 83 void ParsePrincipal(X509Certificate::OSCertHandle os_cert,
105 bool X509Certificate::GetDEREncoded(OSCertHandle cert_handle, 84 X509_NAME* x509_name,
106 std::string* encoded) { 85 CertPrincipal* principal) {
107 if (!cert_handle) 86 if (!x509_name)
108 return false; 87 return;
109 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle)); 88
110 if (!der_data) 89 ParsePrincipalValues(x509_name, NID_streetAddress,
111 return false; 90 &principal->street_addresses);
112 encoded->assign(reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)), 91 ParsePrincipalValues(x509_name, NID_organizationName,
113 CFDataGetLength(der_data)); 92 &principal->organization_names);
114 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);
115 } 106 }
116 107
117 // static 108 void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
118 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, 109 std::vector<std::string>* dns_names,
119 X509Certificate::OSCertHandle b) { 110 std::vector<std::string>* ip_addresses) {
120 DCHECK(a && b); 111 DCHECK(dns_names || ip_addresses);
121 if (a == b) 112 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
122 return true; 113 if (!cert.get())
123 if (CFEqual(a, b)) 114 return;
124 return true; 115 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
125 ScopedCFTypeRef<CFDataRef> a_data(SecCertificateCopyData(a)); 116 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index);
126 ScopedCFTypeRef<CFDataRef> b_data(SecCertificateCopyData(b)); 117 if (!alt_name_ext)
127 return a_data && b_data && 118 return;
128 CFDataGetLength(a_data) == CFDataGetLength(b_data) && 119
129 memcmp(CFDataGetBytePtr(a_data), CFDataGetBytePtr(b_data), 120 ScopedGENERAL_NAMES alt_names(
130 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 }
131 } 151 }
132 152
133 // static 153 // Used to free a list of X509_NAMEs and the objects it points to.
134 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 154 void sk_X509_NAME_free_all(STACK_OF(X509_NAME) * sk) {
135 const char* data, 155 sk_X509_NAME_pop_free(sk, X509_NAME_free);
136 size_t length) {
137 ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy(
138 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
139 base::checked_cast<CFIndex>(length), kCFAllocatorNull));
140 if (!cert_data)
141 return nullptr;
142 OSCertHandle cert_handle = SecCertificateCreateWithData(NULL, cert_data);
143 if (!cert_handle)
144 return nullptr;
145 if (!IsValidOSCertHandle(cert_handle)) {
146 CFRelease(cert_handle);
147 return nullptr;
148 }
149 return cert_handle;
150 } 156 }
151 157
152 // static 158 } // namespace
153 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
154 const char* data,
155 size_t length,
156 Format format) {
157 return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
158 }
159 159
160 // static 160 // static
161 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 161 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
162 OSCertHandle handle) { 162 OSCertHandle handle) {
163 if (!handle) 163 if (!handle)
164 return NULL; 164 return nullptr;
165 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); 165 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
166 } 166 }
167 167
168 // static 168 // static
169 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 169 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
170 if (cert_handle) 170 if (cert_handle)
171 CFRelease(cert_handle); 171 CFRelease(cert_handle);
172 } 172 }
173 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
174 // static 203 // static
175 SHA1HashValue X509Certificate::CalculateFingerprint( 204 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) {
176 OSCertHandle cert) {
177 SHA1HashValue sha1; 205 SHA1HashValue sha1;
178 memset(sha1.data, 0, sizeof(sha1.data)); 206 memset(sha1.data, 0, sizeof(sha1.data));
179 207
180 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert)); 208 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
181 if (!cert_data) 209 if (!cert_data)
182 return sha1; 210 return sha1;
183 DCHECK(CFDataGetBytePtr(cert_data)); 211 DCHECK(CFDataGetBytePtr(cert_data));
184 DCHECK_NE(0, CFDataGetLength(cert_data)); 212 DCHECK_NE(0, CFDataGetLength(cert_data));
185 CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data); 213 CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data);
186 214
187 return sha1; 215 return sha1;
188 } 216 }
189 217
190 // static 218 // static
191 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { 219 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
192 SHA256HashValue sha256; 220 SHA256HashValue sha256;
193 memset(sha256.data, 0, sizeof(sha256.data)); 221 memset(sha256.data, 0, sizeof(sha256.data));
194 222
195 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert)); 223 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
196 if (!cert_data) 224 if (!cert_data)
197 return sha256; 225 return sha256;
198 DCHECK(CFDataGetBytePtr(cert_data)); 226 DCHECK(CFDataGetBytePtr(cert_data));
199 DCHECK_NE(0, CFDataGetLength(cert_data)); 227 DCHECK_NE(0, CFDataGetLength(cert_data));
200 CC_SHA256( 228 CC_SHA256(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data),
201 CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha256.data); 229 sha256.data);
202 230
203 return sha256; 231 return sha256;
204 } 232 }
205 233
206 // static 234 // static
207 SHA1HashValue X509Certificate::CalculateCAFingerprint( 235 SHA1HashValue X509Certificate::CalculateCAFingerprint(
208 const OSCertHandles& intermediates) { 236 const OSCertHandles& intermediates) {
209 SHA1HashValue sha1; 237 SHA1HashValue sha1;
210 memset(sha1.data, 0, sizeof(sha1.data)); 238 memset(sha1.data, 0, sizeof(sha1.data));
211 239
212 // The CC_SHA(3cc) man page says all CC_SHA1_xxx routines return 1, so
213 // we don't check their return values.
214 CC_SHA1_CTX sha1_ctx; 240 CC_SHA1_CTX sha1_ctx;
215 CC_SHA1_Init(&sha1_ctx); 241 CC_SHA1_Init(&sha1_ctx);
216 for (size_t i = 0; i < intermediates.size(); ++i) { 242 for (size_t i = 0; i < intermediates.size(); ++i) {
217 ScopedCFTypeRef<CFDataRef> 243 ScopedCFTypeRef<CFDataRef> cert_data(
218 cert_data(SecCertificateCopyData(intermediates[i])); 244 SecCertificateCopyData(intermediates[i]));
219 if (!cert_data) 245 if (!cert_data)
220 return sha1; 246 return sha1;
221 CC_SHA1_Update(&sha1_ctx, 247 CC_SHA1_Update(&sha1_ctx, CFDataGetBytePtr(cert_data),
222 CFDataGetBytePtr(cert_data),
223 CFDataGetLength(cert_data)); 248 CFDataGetLength(cert_data));
224 } 249 }
225 CC_SHA1_Final(sha1.data, &sha1_ctx); 250 CC_SHA1_Final(sha1.data, &sha1_ctx);
226 return sha1; 251 return sha1;
227 } 252 }
228 253
229 // 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
230 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle( 334 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle(
231 base::PickleIterator* pickle_iter) { 335 base::PickleIterator* pickle_iter) {
232 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);
233 } 342 }
234 343
235 // static 344 // static
236 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, 345 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
237 base::Pickle* pickle) { 346 base::Pickle* pickle) {
238 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle)); 347 ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle));
239 if (!cert_data) 348 if (!cert_data)
240 return false; 349 return false;
241 350
242 return pickle->WriteData( 351 return pickle->WriteData(
243 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)), 352 reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)),
244 CFDataGetLength(cert_data)); 353 CFDataGetLength(cert_data));
245 } 354 }
246 355
247 // static 356 // static
248 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, 357 void X509Certificate::GetPublicKeyInfo(OSCertHandle os_cert,
249 size_t* size_bits, 358 size_t* size_bits,
250 PublicKeyType* type) { 359 PublicKeyType* type) {
251 x509_util_ios::NSSCertificate nss_cert(cert_handle); 360 *type = kPublicKeyTypeUnknown;
252 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;
253 } 459 }
254 460
255 // static 461 // static
256 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { 462 bool X509Certificate::IsSelfSigned(OSCertHandle os_cert) {
257 x509_util_ios::NSSCertificate nss_cert(cert_handle); 463 ScopedX509 cert = OSCertHandleToOpenSSL(os_cert);
258 crypto::ScopedSECKEYPublicKey public_key( 464 if (!cert)
259 CERT_ExtractPublicKey(nss_cert.cert_handle()));
260 if (!public_key.get())
261 return false; 465 return false;
262 return SECSuccess == CERT_VerifySignedDataWithPublicKey( 466 crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
263 &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;
264 } 472 }
265 473
266 } // namespace net 474 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698