OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 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/base/x509_certificate.h" | 5 #include "net/base/x509_certificate.h" |
6 | 6 |
7 #include <CommonCrypto/CommonDigest.h> | 7 #include <CommonCrypto/CommonDigest.h> |
8 #include <CoreServices/CoreServices.h> | 8 #include <CoreServices/CoreServices.h> |
9 #include <Security/Security.h> | 9 #include <Security/Security.h> |
10 #include <time.h> | 10 #include <time.h> |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 OSStatus CreateTrustPolicies(const std::string& hostname, int flags, | 312 OSStatus CreateTrustPolicies(const std::string& hostname, int flags, |
313 ScopedCFTypeRef<CFArrayRef>* policies) { | 313 ScopedCFTypeRef<CFArrayRef>* policies) { |
314 ScopedCFTypeRef<CFMutableArrayRef> local_policies( | 314 ScopedCFTypeRef<CFMutableArrayRef> local_policies( |
315 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); | 315 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); |
316 if (!local_policies) | 316 if (!local_policies) |
317 return memFullErr; | 317 return memFullErr; |
318 | 318 |
319 // Create an SSL SecPolicyRef, and configure it to perform hostname | 319 // Create an SSL SecPolicyRef, and configure it to perform hostname |
320 // validation. The hostname check does 99% of what we want, with the | 320 // validation. The hostname check does 99% of what we want, with the |
321 // exception of dotted IPv4 addreses, which we handle ourselves below. | 321 // exception of dotted IPv4 addreses, which we handle ourselves below. |
322 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = { | |
323 CSSM_APPLE_TP_SSL_OPTS_VERSION, | |
324 hostname.size(), | |
325 hostname.data(), | |
326 0 | |
327 }; | |
328 SecPolicyRef ssl_policy; | 322 SecPolicyRef ssl_policy; |
329 OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, | 323 OSStatus status = X509Certificate::CreateSSLServerPolicy(hostname, |
330 sizeof(tp_ssl_options), &ssl_policy); | 324 &ssl_policy); |
331 if (status) | 325 if (status) |
332 return status; | 326 return status; |
333 CFArrayAppendValue(local_policies, ssl_policy); | 327 CFArrayAppendValue(local_policies, ssl_policy); |
334 CFRelease(ssl_policy); | 328 CFRelease(ssl_policy); |
335 | 329 |
336 // Manually add revocation policies. In order to actually disable revocation | 330 // Explicitly add revocation policies, in order to override system |
337 // checking, the SecTrustRef must have at least one revocation policy | 331 // revocation checking policies and instead respect the application-level |
338 // associated with it. If none are present, the Apple TP will add policies | 332 // revocation preference. |
339 // according to the system preferences, which will enable revocation | 333 status = X509Certificate::CreateRevocationPolicies( |
340 // checking even if the caller explicitly disabled it. An OCSP policy is | 334 (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED), |
341 // used, rather than a CRL policy, because the Apple TP will force an OCSP | 335 local_policies); |
342 // policy to be present and enabled if it believes the certificate may chain | |
343 // to an EV root. By explicitly disabling network and OCSP cache access, | |
344 // then even if the Apple TP enables OCSP checking, no revocation checking | |
345 // will actually succeed. | |
346 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; | |
347 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); | |
348 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; | |
349 | |
350 if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) { | |
351 // The default for the OCSP policy is to fetch responses via the network, | |
352 // unlike the CRL policy default. The policy is further modified to | |
353 // prefer OCSP over CRLs, if both are specified on the certificate. This | |
354 // is because an OCSP response is both sufficient and typically | |
355 // significantly smaller than the CRL counterpart. | |
356 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; | |
357 } else { | |
358 // Effectively disable OCSP checking by making it impossible to get an | |
359 // OCSP response. Even if the Apple TP forces OCSP, no checking will | |
360 // be able to succeed. If this happens, the Apple TP will report an error | |
361 // that OCSP was unavailable, but this will be handled and suppressed in | |
362 // X509Certificate::Verify(). | |
363 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | | |
364 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; | |
365 } | |
366 | |
367 SecPolicyRef ocsp_policy; | |
368 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options, | |
369 sizeof(tp_ocsp_options), &ocsp_policy); | |
370 if (status) | 336 if (status) |
371 return status; | 337 return status; |
372 CFArrayAppendValue(local_policies, ocsp_policy); | |
373 CFRelease(ocsp_policy); | |
374 | |
375 if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) { | |
376 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; | |
377 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); | |
378 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; | |
379 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; | |
380 | |
381 SecPolicyRef crl_policy; | |
382 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, | |
383 sizeof(tp_crl_options), &crl_policy); | |
384 if (status) | |
385 return status; | |
386 CFArrayAppendValue(local_policies, crl_policy); | |
387 CFRelease(crl_policy); | |
388 } | |
389 | 338 |
390 policies->reset(local_policies.release()); | 339 policies->reset(local_policies.release()); |
391 return noErr; | 340 return noErr; |
392 } | 341 } |
393 | 342 |
394 // Gets the issuer for a given cert, starting with the cert itself and | 343 // Gets the issuer for a given cert, starting with the cert itself and |
395 // including the intermediate and finally root certificates (if any). | 344 // including the intermediate and finally root certificates (if any). |
396 // This function calls SecTrust but doesn't actually pay attention to the trust | 345 // This function calls SecTrust but doesn't actually pay attention to the trust |
397 // result: it shouldn't be used to determine trust, just to traverse the chain. | 346 // result: it shouldn't be used to determine trust, just to traverse the chain. |
398 // Caller is responsible for releasing the value stored into *out_cert_chain. | 347 // Caller is responsible for releasing the value stored into *out_cert_chain. |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 X509Certificate::OSCertHandles())); | 1153 X509Certificate::OSCertHandles())); |
1205 for (unsigned j = 0; j < valid_issuers.size(); j++) { | 1154 for (unsigned j = 0; j < valid_issuers.size(); j++) { |
1206 if (cert->issuer().Matches(valid_issuers[j])) | 1155 if (cert->issuer().Matches(valid_issuers[j])) |
1207 return true; | 1156 return true; |
1208 } | 1157 } |
1209 } | 1158 } |
1210 return false; | 1159 return false; |
1211 } | 1160 } |
1212 | 1161 |
1213 // static | 1162 // static |
1214 OSStatus X509Certificate::CreateSSLClientPolicy(SecPolicyRef* out_policy) { | 1163 OSStatus X509Certificate::CreateSSLClientPolicy(SecPolicyRef* policy) { |
1215 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = { | 1164 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; |
1216 CSSM_APPLE_TP_SSL_OPTS_VERSION, | 1165 memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); |
1217 0, | 1166 tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; |
1218 NULL, | 1167 tp_ssl_options.Flags |= CSSM_APPLE_TP_SSL_CLIENT; |
1219 CSSM_APPLE_TP_SSL_CLIENT | 1168 |
1220 }; | 1169 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, |
1221 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, | 1170 sizeof(tp_ssl_options), policy); |
1222 &tp_ssl_options, | |
1223 sizeof(tp_ssl_options), | |
1224 out_policy); | |
1225 } | 1171 } |
1226 | 1172 |
1227 // static | 1173 // static |
| 1174 OSStatus X509Certificate::CreateSSLServerPolicy(const std::string& hostname, |
| 1175 SecPolicyRef* policy) { |
| 1176 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; |
| 1177 memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); |
| 1178 tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; |
| 1179 if (!hostname.empty()) { |
| 1180 tp_ssl_options.ServerName = hostname.data(); |
| 1181 tp_ssl_options.ServerNameLen = hostname.size(); |
| 1182 } |
| 1183 |
| 1184 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, |
| 1185 sizeof(tp_ssl_options), policy); |
| 1186 } |
| 1187 |
| 1188 // static |
| 1189 OSStatus X509Certificate::CreateBasicX509Policy(SecPolicyRef* policy) { |
| 1190 return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy); |
| 1191 } |
| 1192 |
| 1193 // static |
| 1194 OSStatus X509Certificate::CreateRevocationPolicies( |
| 1195 bool enable_revocation_checking, |
| 1196 CFMutableArrayRef policies) { |
| 1197 // In order to actually disable revocation checking, the SecTrustRef must |
| 1198 // have at least one revocation policy associated with it. If none are |
| 1199 // present, the Apple TP will add policies according to the system |
| 1200 // preferences, which will enable revocation checking even if the caller |
| 1201 // explicitly disabled it. An OCSP policy is used, rather than a CRL policy, |
| 1202 // because the Apple TP will force an OCSP policy to be present and enabled |
| 1203 // if it believes the certificate may chain to an EV root. By explicitly |
| 1204 // disabling network and OCSP cache access, then even if the Apple TP |
| 1205 // enables OCSP checking, no revocation checking will actually succeed. |
| 1206 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; |
| 1207 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); |
| 1208 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; |
| 1209 |
| 1210 if (enable_revocation_checking) { |
| 1211 // The default for the OCSP policy is to fetch responses via the network, |
| 1212 // unlike the CRL policy default. The policy is further modified to |
| 1213 // prefer OCSP over CRLs, if both are specified on the certificate. This |
| 1214 // is because an OCSP response is both sufficient and typically |
| 1215 // significantly smaller than the CRL counterpart. |
| 1216 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; |
| 1217 } else { |
| 1218 // Effectively disable OCSP checking by making it impossible to get an |
| 1219 // OCSP response. Even if the Apple TP forces OCSP, no checking will |
| 1220 // be able to succeed. If this happens, the Apple TP will report an error |
| 1221 // that OCSP was unavailable, but this will be handled and suppressed in |
| 1222 // X509Certificate::Verify(). |
| 1223 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | |
| 1224 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; |
| 1225 } |
| 1226 |
| 1227 SecPolicyRef ocsp_policy; |
| 1228 OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, |
| 1229 &tp_ocsp_options, sizeof(tp_ocsp_options), |
| 1230 &ocsp_policy); |
| 1231 if (status) |
| 1232 return status; |
| 1233 CFArrayAppendValue(policies, ocsp_policy); |
| 1234 CFRelease(ocsp_policy); |
| 1235 |
| 1236 if (enable_revocation_checking) { |
| 1237 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; |
| 1238 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); |
| 1239 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; |
| 1240 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; |
| 1241 |
| 1242 SecPolicyRef crl_policy; |
| 1243 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, |
| 1244 sizeof(tp_crl_options), &crl_policy); |
| 1245 if (status) |
| 1246 return status; |
| 1247 CFArrayAppendValue(policies, crl_policy); |
| 1248 CFRelease(crl_policy); |
| 1249 } |
| 1250 |
| 1251 return status; |
| 1252 } |
| 1253 |
| 1254 |
| 1255 // static |
1228 bool X509Certificate::GetSSLClientCertificates( | 1256 bool X509Certificate::GetSSLClientCertificates( |
1229 const std::string& server_domain, | 1257 const std::string& server_domain, |
1230 const std::vector<CertPrincipal>& valid_issuers, | 1258 const std::vector<CertPrincipal>& valid_issuers, |
1231 CertificateList* certs) { | 1259 CertificateList* certs) { |
1232 ScopedCFTypeRef<SecIdentityRef> preferred_identity; | 1260 ScopedCFTypeRef<SecIdentityRef> preferred_identity; |
1233 if (!server_domain.empty()) { | 1261 if (!server_domain.empty()) { |
1234 // See if there's an identity preference for this domain: | 1262 // See if there's an identity preference for this domain: |
1235 ScopedCFTypeRef<CFStringRef> domain_str( | 1263 ScopedCFTypeRef<CFStringRef> domain_str( |
1236 base::SysUTF8ToCFStringRef("https://" + server_domain)); | 1264 base::SysUTF8ToCFStringRef("https://" + server_domain)); |
1237 SecIdentityRef identity = NULL; | 1265 SecIdentityRef identity = NULL; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 CSSM_DATA cert_data; | 1383 CSSM_DATA cert_data; |
1356 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); | 1384 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); |
1357 if (status) | 1385 if (status) |
1358 return false; | 1386 return false; |
1359 | 1387 |
1360 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), | 1388 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), |
1361 cert_data.Length); | 1389 cert_data.Length); |
1362 } | 1390 } |
1363 | 1391 |
1364 } // namespace net | 1392 } // namespace net |
OLD | NEW |