OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/ssl/ssl_platform_key_mac.h" | 5 #include "net/ssl/ssl_platform_key_mac.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <CoreFoundation/CoreFoundation.h> | 8 #include <CoreFoundation/CoreFoundation.h> |
9 #include <Security/cssm.h> | 9 #include <Security/cssm.h> |
10 #include <Security/SecBase.h> | 10 #include <Security/SecBase.h> |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "base/macros.h" | 24 #include "base/macros.h" |
25 #include "base/memory/ptr_util.h" | 25 #include "base/memory/ptr_util.h" |
26 #include "base/memory/scoped_policy.h" | 26 #include "base/memory/scoped_policy.h" |
27 #include "base/numerics/safe_conversions.h" | 27 #include "base/numerics/safe_conversions.h" |
28 #include "base/synchronization/lock.h" | 28 #include "base/synchronization/lock.h" |
29 #include "crypto/mac_security_services_lock.h" | 29 #include "crypto/mac_security_services_lock.h" |
30 #include "crypto/openssl_util.h" | 30 #include "crypto/openssl_util.h" |
31 #include "net/base/net_errors.h" | 31 #include "net/base/net_errors.h" |
32 #include "net/cert/x509_certificate.h" | 32 #include "net/cert/x509_certificate.h" |
33 #include "net/cert/x509_util_mac.h" | 33 #include "net/cert/x509_util_mac.h" |
34 #include "net/ssl/ssl_platform_key.h" | |
35 #include "net/ssl/ssl_platform_key_util.h" | 34 #include "net/ssl/ssl_platform_key_util.h" |
36 #include "net/ssl/ssl_private_key.h" | 35 #include "net/ssl/ssl_private_key.h" |
37 #include "net/ssl/threaded_ssl_private_key.h" | 36 #include "net/ssl/threaded_ssl_private_key.h" |
38 #include "third_party/boringssl/src/include/openssl/ecdsa.h" | 37 #include "third_party/boringssl/src/include/openssl/ecdsa.h" |
39 #include "third_party/boringssl/src/include/openssl/evp.h" | 38 #include "third_party/boringssl/src/include/openssl/evp.h" |
40 #include "third_party/boringssl/src/include/openssl/mem.h" | 39 #include "third_party/boringssl/src/include/openssl/mem.h" |
41 #include "third_party/boringssl/src/include/openssl/nid.h" | 40 #include "third_party/boringssl/src/include/openssl/nid.h" |
42 #include "third_party/boringssl/src/include/openssl/rsa.h" | 41 #include "third_party/boringssl/src/include/openssl/rsa.h" |
43 | 42 |
44 #if !defined(MAC_OS_X_VERSION_10_12) || \ | 43 #if !defined(MAC_OS_X_VERSION_10_12) || \ |
(...skipping 26 matching lines...) Expand all Loading... |
71 CSSM_DeleteContext(handle_); | 70 CSSM_DeleteContext(handle_); |
72 handle_ = 0; | 71 handle_ = 0; |
73 } | 72 } |
74 | 73 |
75 private: | 74 private: |
76 CSSM_CC_HANDLE handle_; | 75 CSSM_CC_HANDLE handle_; |
77 | 76 |
78 DISALLOW_COPY_AND_ASSIGN(ScopedCSSM_CC_HANDLE); | 77 DISALLOW_COPY_AND_ASSIGN(ScopedCSSM_CC_HANDLE); |
79 }; | 78 }; |
80 | 79 |
81 // Looks up the private key for |certificate| in |keychain| and returns | |
82 // a SecKeyRef or nullptr on failure. The caller takes ownership of the | |
83 // result. | |
84 SecKeyRef FetchSecKeyRefForCertificate(const X509Certificate* certificate, | |
85 SecKeychainRef keychain) { | |
86 OSStatus status; | |
87 base::ScopedCFTypeRef<SecIdentityRef> identity; | |
88 { | |
89 base::ScopedCFTypeRef<SecCertificateRef> os_cert( | |
90 x509_util::CreateSecCertificateFromX509Certificate(certificate)); | |
91 if (!os_cert) | |
92 return nullptr; | |
93 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | |
94 status = SecIdentityCreateWithCertificate(keychain, os_cert.get(), | |
95 identity.InitializeInto()); | |
96 } | |
97 if (status != noErr) { | |
98 OSSTATUS_LOG(WARNING, status); | |
99 return nullptr; | |
100 } | |
101 | |
102 base::ScopedCFTypeRef<SecKeyRef> private_key; | |
103 status = SecIdentityCopyPrivateKey(identity, private_key.InitializeInto()); | |
104 if (status != noErr) { | |
105 OSSTATUS_LOG(WARNING, status); | |
106 return nullptr; | |
107 } | |
108 | |
109 return private_key.release(); | |
110 } | |
111 | |
112 // These symbols were added in the 10.12 SDK, but we currently use an older SDK, | 80 // These symbols were added in the 10.12 SDK, but we currently use an older SDK, |
113 // so look them up with dlsym. | 81 // so look them up with dlsym. |
114 // | 82 // |
115 // TODO(davidben): After https://crbug.com/669240 is fixed, use the APIs | 83 // TODO(davidben): After https://crbug.com/669240 is fixed, use the APIs |
116 // directly. | 84 // directly. |
117 struct SecKeyAPIs { | 85 struct SecKeyAPIs { |
118 SecKeyAPIs() { Init(); } | 86 SecKeyAPIs() { Init(); } |
119 | 87 |
120 void Init() { | 88 void Init() { |
121 SecKeyCreateSignature = reinterpret_cast<SecKeyCreateSignatureFunc>( | 89 SecKeyCreateSignature = reinterpret_cast<SecKeyCreateSignatureFunc>( |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 return OK; | 337 return OK; |
370 } | 338 } |
371 | 339 |
372 private: | 340 private: |
373 int type_; | 341 int type_; |
374 base::ScopedCFTypeRef<SecKeyRef> key_; | 342 base::ScopedCFTypeRef<SecKeyRef> key_; |
375 | 343 |
376 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeySecKey); | 344 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeySecKey); |
377 }; | 345 }; |
378 | 346 |
379 } // namespace | 347 scoped_refptr<SSLPrivateKey> CreateSSLPrivateKeyForSecKey( |
380 | |
381 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKeyFromKeychain( | |
382 const X509Certificate* certificate, | 348 const X509Certificate* certificate, |
383 SecKeychainRef keychain) { | 349 SecKeyRef private_key) { |
384 // Look up the private key. | |
385 base::ScopedCFTypeRef<SecKeyRef> private_key( | |
386 FetchSecKeyRefForCertificate(certificate, keychain)); | |
387 if (!private_key) | |
388 return nullptr; | |
389 | |
390 int key_type; | 350 int key_type; |
391 size_t max_length; | 351 size_t max_length; |
392 if (!GetClientCertInfo(certificate, &key_type, &max_length)) | 352 if (!GetClientCertInfo(certificate, &key_type, &max_length)) |
393 return nullptr; | 353 return nullptr; |
394 | 354 |
395 if (base::mac::IsAtLeastOS10_12()) { | 355 if (base::mac::IsAtLeastOS10_12()) { |
396 return make_scoped_refptr( | 356 return make_scoped_refptr( |
397 new ThreadedSSLPrivateKey(base::MakeUnique<SSLPlatformKeySecKey>( | 357 new ThreadedSSLPrivateKey(base::MakeUnique<SSLPlatformKeySecKey>( |
398 key_type, max_length, private_key.get()), | 358 key_type, max_length, private_key), |
399 GetSSLPlatformKeyTaskRunner())); | 359 GetSSLPlatformKeyTaskRunner())); |
400 } | 360 } |
401 | 361 |
402 const CSSM_KEY* cssm_key; | 362 const CSSM_KEY* cssm_key; |
403 OSStatus status = SecKeyGetCSSMKey(private_key.get(), &cssm_key); | 363 OSStatus status = SecKeyGetCSSMKey(private_key, &cssm_key); |
404 if (status != noErr) { | 364 if (status != noErr) { |
405 OSSTATUS_LOG(WARNING, status); | 365 OSSTATUS_LOG(WARNING, status); |
406 return nullptr; | 366 return nullptr; |
407 } | 367 } |
408 | 368 |
409 return make_scoped_refptr(new ThreadedSSLPrivateKey( | 369 return make_scoped_refptr(new ThreadedSSLPrivateKey( |
410 base::MakeUnique<SSLPlatformKeyCSSM>(key_type, max_length, | 370 base::MakeUnique<SSLPlatformKeyCSSM>(key_type, max_length, private_key, |
411 private_key.get(), cssm_key), | 371 cssm_key), |
412 GetSSLPlatformKeyTaskRunner())); | 372 GetSSLPlatformKeyTaskRunner())); |
413 } | 373 } |
414 | 374 |
415 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( | 375 } // namespace |
416 const X509Certificate* certificate) { | 376 |
417 return FetchClientCertPrivateKeyFromKeychain(certificate, nullptr); | 377 scoped_refptr<SSLPrivateKey> CreateSSLPrivateKeyForSecIdentity( |
| 378 const X509Certificate* certificate, |
| 379 SecIdentityRef identity) { |
| 380 base::ScopedCFTypeRef<SecKeyRef> private_key; |
| 381 OSStatus status = |
| 382 SecIdentityCopyPrivateKey(identity, private_key.InitializeInto()); |
| 383 if (status != noErr) { |
| 384 OSSTATUS_LOG(WARNING, status); |
| 385 return nullptr; |
| 386 } |
| 387 |
| 388 return CreateSSLPrivateKeyForSecKey(certificate, private_key.get()); |
418 } | 389 } |
419 | 390 |
420 #pragma clang diagnostic pop // "-Wdeprecated-declarations" | 391 #pragma clang diagnostic pop // "-Wdeprecated-declarations" |
421 | 392 |
422 } // namespace net | 393 } // namespace net |
OLD | NEW |