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