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 <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 |
OLD | NEW |