| 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.h" | 5 #include "net/ssl/ssl_platform_key.h" |
| 6 | 6 |
| 7 #include <Security/SecBase.h> | 7 #include <Security/SecBase.h> |
| 8 #include <Security/SecCertificate.h> | 8 #include <Security/SecCertificate.h> |
| 9 #include <Security/SecIdentity.h> | 9 #include <Security/SecIdentity.h> |
| 10 #include <Security/SecKey.h> | 10 #include <Security/SecKey.h> |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "base/mac/scoped_cftyperef.h" | 22 #include "base/mac/scoped_cftyperef.h" |
| 23 #include "base/macros.h" | 23 #include "base/macros.h" |
| 24 #include "base/memory/ptr_util.h" | 24 #include "base/memory/ptr_util.h" |
| 25 #include "base/memory/scoped_policy.h" | 25 #include "base/memory/scoped_policy.h" |
| 26 #include "base/sequenced_task_runner.h" | 26 #include "base/sequenced_task_runner.h" |
| 27 #include "base/synchronization/lock.h" | 27 #include "base/synchronization/lock.h" |
| 28 #include "crypto/mac_security_services_lock.h" | 28 #include "crypto/mac_security_services_lock.h" |
| 29 #include "crypto/openssl_util.h" | 29 #include "crypto/openssl_util.h" |
| 30 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
| 31 #include "net/cert/x509_certificate.h" | 31 #include "net/cert/x509_certificate.h" |
| 32 #include "net/ssl/ssl_platform_key_task_runner.h" | 32 #include "net/ssl/ssl_platform_key_util.h" |
| 33 #include "net/ssl/ssl_private_key.h" | 33 #include "net/ssl/ssl_private_key.h" |
| 34 #include "net/ssl/threaded_ssl_private_key.h" | 34 #include "net/ssl/threaded_ssl_private_key.h" |
| 35 | 35 |
| 36 namespace net { | 36 namespace net { |
| 37 | 37 |
| 38 // CSSM functions are deprecated as of OSX 10.7, but have no replacement. | 38 // CSSM functions are deprecated as of OSX 10.7, but have no replacement. |
| 39 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 | 39 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 |
| 40 #pragma clang diagnostic push | 40 #pragma clang diagnostic push |
| 41 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | 41 #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| 42 | 42 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 if (status != noErr) { | 84 if (status != noErr) { |
| 85 OSSTATUS_LOG(WARNING, status); | 85 OSSTATUS_LOG(WARNING, status); |
| 86 return nullptr; | 86 return nullptr; |
| 87 } | 87 } |
| 88 | 88 |
| 89 return private_key.release(); | 89 return private_key.release(); |
| 90 } | 90 } |
| 91 | 91 |
| 92 class SSLPlatformKeyMac : public ThreadedSSLPrivateKey::Delegate { | 92 class SSLPlatformKeyMac : public ThreadedSSLPrivateKey::Delegate { |
| 93 public: | 93 public: |
| 94 SSLPlatformKeyMac(SecKeyRef key, const CSSM_KEY* cssm_key) | 94 SSLPlatformKeyMac(SSLPrivateKey::Type type, |
| 95 : key_(key, base::scoped_policy::RETAIN), cssm_key_(cssm_key) { | 95 size_t max_length, |
| 96 DCHECK(cssm_key_->KeyHeader.AlgorithmId == CSSM_ALGID_RSA || | 96 SecKeyRef key, |
| 97 cssm_key_->KeyHeader.AlgorithmId == CSSM_ALGID_ECDSA); | 97 const CSSM_KEY* cssm_key) |
| 98 } | 98 : type_(type), |
| 99 max_length_(max_length), |
| 100 key_(key, base::scoped_policy::RETAIN), |
| 101 cssm_key_(cssm_key) {} |
| 99 | 102 |
| 100 ~SSLPlatformKeyMac() override {} | 103 ~SSLPlatformKeyMac() override {} |
| 101 | 104 |
| 102 SSLPrivateKey::Type GetType() override { | 105 SSLPrivateKey::Type GetType() override { return type_; } |
| 103 if (cssm_key_->KeyHeader.AlgorithmId == CSSM_ALGID_RSA) { | |
| 104 return SSLPrivateKey::Type::RSA; | |
| 105 } else { | |
| 106 DCHECK_EQ(CSSM_ALGID_ECDSA, cssm_key_->KeyHeader.AlgorithmId); | |
| 107 return SSLPrivateKey::Type::ECDSA; | |
| 108 } | |
| 109 } | |
| 110 | 106 |
| 111 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override { | 107 std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override { |
| 112 static const SSLPrivateKey::Hash kHashes[] = { | 108 static const SSLPrivateKey::Hash kHashes[] = { |
| 113 SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384, | 109 SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384, |
| 114 SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1}; | 110 SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1}; |
| 115 return std::vector<SSLPrivateKey::Hash>(kHashes, | 111 return std::vector<SSLPrivateKey::Hash>(kHashes, |
| 116 kHashes + arraysize(kHashes)); | 112 kHashes + arraysize(kHashes)); |
| 117 } | 113 } |
| 118 | 114 |
| 119 size_t GetMaxSignatureLengthInBytes() override { | 115 size_t GetMaxSignatureLengthInBytes() override { return max_length_; } |
| 120 if (cssm_key_->KeyHeader.AlgorithmId == CSSM_ALGID_RSA) { | |
| 121 return (cssm_key_->KeyHeader.LogicalKeySizeInBits + 7) / 8; | |
| 122 } else { | |
| 123 // LogicalKeySizeInBits is the size of an EC public key. But an | |
| 124 // ECDSA signature length depends on the size of the base point's | |
| 125 // order. For P-256, P-384, and P-521, these two sizes are the same. | |
| 126 return ECDSA_SIG_max_len((cssm_key_->KeyHeader.LogicalKeySizeInBits + 7) / | |
| 127 8); | |
| 128 } | |
| 129 } | |
| 130 | 116 |
| 131 Error SignDigest(SSLPrivateKey::Hash hash, | 117 Error SignDigest(SSLPrivateKey::Hash hash, |
| 132 const base::StringPiece& input, | 118 const base::StringPiece& input, |
| 133 std::vector<uint8_t>* signature) override { | 119 std::vector<uint8_t>* signature) override { |
| 134 crypto::OpenSSLErrStackTracer tracer(FROM_HERE); | 120 crypto::OpenSSLErrStackTracer tracer(FROM_HERE); |
| 135 | 121 |
| 136 CSSM_CSP_HANDLE csp_handle; | 122 CSSM_CSP_HANDLE csp_handle; |
| 137 OSStatus status = SecKeyGetCSPHandle(key_.get(), &csp_handle); | 123 OSStatus status = SecKeyGetCSPHandle(key_.get(), &csp_handle); |
| 138 if (status != noErr) { | 124 if (status != noErr) { |
| 139 OSSTATUS_LOG(WARNING, status); | 125 OSSTATUS_LOG(WARNING, status); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 CSSM_CONTEXT_ATTRIBUTE blinding_attr; | 181 CSSM_CONTEXT_ATTRIBUTE blinding_attr; |
| 196 blinding_attr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING; | 182 blinding_attr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING; |
| 197 blinding_attr.AttributeLength = sizeof(uint32_t); | 183 blinding_attr.AttributeLength = sizeof(uint32_t); |
| 198 blinding_attr.Attribute.Uint32 = 1; | 184 blinding_attr.Attribute.Uint32 = 1; |
| 199 if (CSSM_UpdateContextAttributes(cssm_signature.get(), 1, | 185 if (CSSM_UpdateContextAttributes(cssm_signature.get(), 1, |
| 200 &blinding_attr) != CSSM_OK) { | 186 &blinding_attr) != CSSM_OK) { |
| 201 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; | 187 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; |
| 202 } | 188 } |
| 203 } | 189 } |
| 204 | 190 |
| 205 signature->resize(GetMaxSignatureLengthInBytes()); | 191 signature->resize(max_length_); |
| 206 CSSM_DATA signature_data; | 192 CSSM_DATA signature_data; |
| 207 signature_data.Length = signature->size(); | 193 signature_data.Length = signature->size(); |
| 208 signature_data.Data = signature->data(); | 194 signature_data.Data = signature->data(); |
| 209 | 195 |
| 210 if (CSSM_SignData(cssm_signature.get(), &hash_data, 1, CSSM_ALGID_NONE, | 196 if (CSSM_SignData(cssm_signature.get(), &hash_data, 1, CSSM_ALGID_NONE, |
| 211 &signature_data) != CSSM_OK) { | 197 &signature_data) != CSSM_OK) { |
| 212 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; | 198 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; |
| 213 } | 199 } |
| 214 signature->resize(signature_data.Length); | 200 signature->resize(signature_data.Length); |
| 215 return OK; | 201 return OK; |
| 216 } | 202 } |
| 217 | 203 |
| 218 private: | 204 private: |
| 205 SSLPrivateKey::Type type_; |
| 206 size_t max_length_; |
| 219 base::ScopedCFTypeRef<SecKeyRef> key_; | 207 base::ScopedCFTypeRef<SecKeyRef> key_; |
| 220 const CSSM_KEY* cssm_key_; | 208 const CSSM_KEY* cssm_key_; |
| 221 | 209 |
| 222 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyMac); | 210 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyMac); |
| 223 }; | 211 }; |
| 224 | 212 |
| 225 } // namespace | 213 } // namespace |
| 226 | 214 |
| 227 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( | 215 scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( |
| 228 X509Certificate* certificate) { | 216 X509Certificate* certificate) { |
| 229 // Look up the private key. | 217 // Look up the private key. |
| 230 base::ScopedCFTypeRef<SecKeyRef> private_key( | 218 base::ScopedCFTypeRef<SecKeyRef> private_key( |
| 231 FetchSecKeyRefForCertificate(certificate)); | 219 FetchSecKeyRefForCertificate(certificate)); |
| 232 if (!private_key) | 220 if (!private_key) |
| 233 return nullptr; | 221 return nullptr; |
| 234 | 222 |
| 235 const CSSM_KEY* cssm_key; | 223 const CSSM_KEY* cssm_key; |
| 236 OSStatus status = SecKeyGetCSSMKey(private_key.get(), &cssm_key); | 224 OSStatus status = SecKeyGetCSSMKey(private_key.get(), &cssm_key); |
| 237 if (status != noErr) | 225 if (status != noErr) |
| 238 return nullptr; | 226 return nullptr; |
| 239 | 227 |
| 240 if (cssm_key->KeyHeader.AlgorithmId != CSSM_ALGID_RSA && | 228 SSLPrivateKey::Type key_type; |
| 241 cssm_key->KeyHeader.AlgorithmId != CSSM_ALGID_ECDSA) { | 229 size_t max_length; |
| 242 LOG(ERROR) << "Unknown key type: " << cssm_key->KeyHeader.AlgorithmId; | 230 if (!GetClientCertInfo(certificate, &key_type, &max_length)) |
| 243 return nullptr; | 231 return nullptr; |
| 244 } | 232 |
| 245 return make_scoped_refptr(new ThreadedSSLPrivateKey( | 233 return make_scoped_refptr(new ThreadedSSLPrivateKey( |
| 246 base::MakeUnique<SSLPlatformKeyMac>(private_key.get(), cssm_key), | 234 base::MakeUnique<SSLPlatformKeyMac>(key_type, max_length, |
| 235 private_key.get(), cssm_key), |
| 247 GetSSLPlatformKeyTaskRunner())); | 236 GetSSLPlatformKeyTaskRunner())); |
| 248 } | 237 } |
| 249 | 238 |
| 250 #pragma clang diagnostic pop // "-Wdeprecated-declarations" | 239 #pragma clang diagnostic pop // "-Wdeprecated-declarations" |
| 251 | 240 |
| 252 } // namespace net | 241 } // namespace net |
| OLD | NEW |