15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/openssl_platform_key.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <openssl/err.h> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <openssl/evp.h> 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <openssl/rsa.h> 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <Security/cssm.h> 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <Security/SecBase.h> 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <Security/SecCertificate.h> 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <Security/SecIdentity.h> 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <Security/SecKey.h> 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/lazy_instance.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/location.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/logging.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/mac/mac_logging.h" 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/mac/scoped_cftyperef.h" 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_policy.h" 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/synchronization/lock.h" 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "crypto/mac_security_services_lock.h" 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/net_errors.h" 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/cert/x509_certificate.h" 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/ssl/openssl_ssl_util.h" 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace net { 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace { 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ScopedCSSM_CC_HANDLE { 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedCSSM_CC_HANDLE() : handle_(0) { 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ~ScopedCSSM_CC_HANDLE() { 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reset(); 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_CC_HANDLE get() const { 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return handle_; 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void reset() { 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (handle_) 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_DeleteContext(handle_); 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) handle_ = 0; 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_CC_HANDLE* InitializeInto() { 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reset(); 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return &handle_; 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_CC_HANDLE handle_; 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedCSSM_CC_HANDLE); 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Looks up the private key for |certificate| in KeyChain and returns 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// a SecKeyRef or NULL on failure. The caller takes ownership of the 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// result. 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SecKeyRef FetchSecKeyRefForCertificate(const X509Certificate* certificate) { 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OSStatus status; 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ScopedCFTypeRef<SecIdentityRef> identity; 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::AutoLock lock(crypto::GetMacSecurityServicesLock()); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status = SecIdentityCreateWithCertificate( 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL, certificate->os_cert_handle(), identity.InitializeInto()); 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (status != noErr) { 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OSSTATUS_LOG(WARNING, status); 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ScopedCFTypeRef<SecKeyRef> private_key; 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status = SecIdentityCopyPrivateKey(identity, private_key.InitializeInto()); 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (status != noErr) { 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OSSTATUS_LOG(WARNING, status); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return private_key.release(); 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern const RSA_METHOD mac_rsa_method; 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern const ECDSA_METHOD mac_ecdsa_method; 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// KeyExData contains the data that is contained in the EX_DATA of the 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// RSA and ECDSA objects that are created to wrap Mac system keys. 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct KeyExData { 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) KeyExData(SecKeyRef key, const CSSM_KEY* cssm_key) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : key(key, base::scoped_policy::RETAIN), cssm_key(cssm_key) {} 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ScopedCFTypeRef<SecKeyRef> key; 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CSSM_KEY* cssm_key; 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// ExDataDup is called when one of the RSA or EC_KEY objects is 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// duplicated. This is not supported and should never happen. 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int ExDataDup(CRYPTO_EX_DATA* to, 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CRYPTO_EX_DATA* from, 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void** from_d, 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int idx, 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) long argl, 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void* argp) { 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK_EQ((void*)NULL, *from_d); 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// ExDataFree is called when one of the RSA or EC_KEY objects is freed. 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ExDataFree(void* parent, 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void* ptr, 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CRYPTO_EX_DATA* ex_data, 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int idx, 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) long argl, void* argp) { 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) KeyExData* data = reinterpret_cast<KeyExData*>(ptr); 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delete data; 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// BoringSSLEngine is a BoringSSL ENGINE that implements RSA and ECDSA 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// by forwarding the requested operations to Apple's CSSM 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// implementation. 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class BoringSSLEngine { 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BoringSSLEngine() 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : rsa_index_(RSA_get_ex_new_index(0 /* argl */, 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* argp */, 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* new_func */, 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExDataDup, 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExDataFree)), 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */, 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* argp */, 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* new_func */, 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExDataDup, 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExDataFree)), 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) engine_(ENGINE_new()) { 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ENGINE_set_RSA_method( 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) engine_, &mac_rsa_method, sizeof(mac_rsa_method)); 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ENGINE_set_ECDSA_method( 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) engine_, &mac_ecdsa_method, sizeof(mac_ecdsa_method)); 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int rsa_ex_index() const { return rsa_index_; } 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int ec_key_ex_index() const { return ec_key_index_; } 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const ENGINE* engine() const { return engine_; } 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int rsa_index_; 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int ec_key_index_; 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ENGINE* const engine_; 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::LazyInstance<BoringSSLEngine>::Leaky global_boringssl_engine = 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Helper function for making a signature. 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// MakeCSSMSignature uses the key information in |ex_data| to sign the 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |in_len| bytes pointed by |in|. It writes up to |max_out| bytes 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// into the buffer pointed to by |out|, setting |*out_len| to the 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// number of bytes written. It returns 1 on success and 0 on failure. 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int MakeCSSMSignature(const KeyExData* ex_data, 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* out_len, 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint8_t* out, 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t max_out, 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const uint8_t* in, 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t in_len) { 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_CSP_HANDLE csp_handle; 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OSStatus status = SecKeyGetCSPHandle(ex_data->key.get(), &csp_handle); 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (status != noErr) { 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OSSTATUS_LOG(WARNING, status); 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_INTERNAL_ERROR); 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CSSM_ACCESS_CREDENTIALS* cssm_creds = NULL; 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) status = SecKeyGetCredentials(ex_data->key.get(), CSSM_ACL_AUTHORIZATION_SIGN, 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kSecCredentialTypeDefault, &cssm_creds); 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (status != noErr) { 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OSSTATUS_LOG(WARNING, status); 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED); 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedCSSM_CC_HANDLE cssm_signature; 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (CSSM_CSP_CreateSignatureContext( 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) csp_handle, ex_data->cssm_key->KeyHeader.AlgorithmId, cssm_creds, 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ex_data->cssm_key, cssm_signature.InitializeInto()) != CSSM_OK) { 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED); 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ex_data->cssm_key->KeyHeader.AlgorithmId == CSSM_ALGID_RSA) { 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Set RSA blinding. 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_CONTEXT_ATTRIBUTE blinding_attr; 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blinding_attr.AttributeType = CSSM_ATTRIBUTE_RSA_BLINDING; 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blinding_attr.AttributeLength = sizeof(uint32); 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blinding_attr.Attribute.Uint32 = 1; 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (CSSM_UpdateContextAttributes( 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cssm_signature.get(), 1, &blinding_attr) != CSSM_OK) { 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED); 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_DATA hash_data; 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hash_data.Length = in_len; 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hash_data.Data = const_cast<uint8*>(in); 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_DATA signature_data; 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) signature_data.Length = max_out; 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) signature_data.Data = out; 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (CSSM_SignData(cssm_signature.get(), &hash_data, 1, 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CSSM_ALGID_NONE, &signature_data) != CSSM_OK) { 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED); 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *out_len = signature_data.Length; 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 1; 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Custom RSA_METHOD that uses the platform APIs for signing. 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const KeyExData* RsaGetExData(const RSA* rsa) { 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return reinterpret_cast<const KeyExData*>( 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RSA_get_ex_data(rsa, global_boringssl_engine.Get().rsa_ex_index())); 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)size_t RsaMethodSize(const RSA *rsa) { 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const KeyExData *ex_data = RsaGetExData(rsa); 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return (ex_data->cssm_key->KeyHeader.LogicalKeySizeInBits + 7) / 8; 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int RsaMethodEncrypt(RSA* rsa, 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* out_len, 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint8_t* out, 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t max_out, 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const uint8_t* in, 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t in_len, 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int padding) { 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTIMPLEMENTED(); 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_UNKNOWN_ALGORITHM_TYPE); 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int RsaMethodSignRaw(RSA* rsa, 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* out_len, 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint8_t* out, 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t max_out, 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const uint8_t* in, 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t in_len, 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int padding) { 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Only support PKCS#1 padding. 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(RSA_PKCS1_PADDING, padding); 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (padding != RSA_PKCS1_PADDING) { 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_UNKNOWN_PADDING_TYPE); 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const KeyExData *ex_data = RsaGetExData(rsa); 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ex_data) { 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_INTERNAL_ERROR); 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(CSSM_ALGID_RSA, ex_data->cssm_key->KeyHeader.AlgorithmId); 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return MakeCSSMSignature(ex_data, out_len, out, max_out, in, in_len); 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int RsaMethodDecrypt(RSA* rsa, 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* out_len, 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint8_t* out, 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t max_out, 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const uint8_t* in, 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t in_len, 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int padding) { 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTIMPLEMENTED(); 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_UNKNOWN_ALGORITHM_TYPE); 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int RsaMethodVerifyRaw(RSA* rsa, 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* out_len, 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint8_t* out, 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t max_out, 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const uint8_t* in, 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t in_len, 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int padding) { 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTIMPLEMENTED(); 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_UNKNOWN_ALGORITHM_TYPE); 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const RSA_METHOD mac_rsa_method = { 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0 /* references */, 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1 /* is_static */ 3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } /* common */, 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* app_data */, 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* init */, 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* finish */, 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RsaMethodSize, 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* sign */, 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* verify */, 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RsaMethodEncrypt, 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RsaMethodSignRaw, 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RsaMethodDecrypt, 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RsaMethodVerifyRaw, 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NULL /* private_transform */, 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* mod_exp */, 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* bn_mod_exp */, 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RSA_FLAG_OPAQUE, 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* keygen */, 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)crypto::ScopedEVP_PKEY CreateRSAWrapper(SecKeyRef key, 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CSSM_KEY* cssm_key) { 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crypto::ScopedRSA rsa( 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RSA_new_method(global_boringssl_engine.Get().engine())); 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!rsa) 3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RSA_set_ex_data( 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rsa.get(), global_boringssl_engine.Get().rsa_ex_index(), 3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new KeyExData(key, cssm_key)); 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); 3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!pkey) 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) 3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pkey.Pass(); 3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Custom ECDSA_METHOD that uses the platform APIs. 3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Note that for now, only signing through ECDSA_sign() is really supported. 3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// all other method pointers are either stubs returning errors, or no-ops. 3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const KeyExData* EcKeyGetExData(const EC_KEY* ec_key) { 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return reinterpret_cast<const KeyExData*>(EC_KEY_get_ex_data( 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ec_key, global_boringssl_engine.Get().ec_key_ex_index())); 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)size_t EcdsaMethodGroupOrderSize(const EC_KEY* ec_key) { 3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const KeyExData* ex_data = EcKeyGetExData(ec_key); 3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // LogicalKeySizeInBits is the size of an EC public key. But an 3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // ECDSA signature length depends on the size of the base point's 3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // order. For P-256, P-384, and P-521, these two sizes are the same. 3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return (ex_data->cssm_key->KeyHeader.LogicalKeySizeInBits + 7) / 8; 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int EcdsaMethodSign(const uint8_t* digest, 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t digest_len, 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint8_t* sig, 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned int* sig_len, 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EC_KEY* ec_key) { 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const KeyExData *ex_data = EcKeyGetExData(ec_key); 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ex_data) { 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_INTERNAL_ERROR); 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(CSSM_ALGID_ECDSA, ex_data->cssm_key->KeyHeader.AlgorithmId); 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(davidben): Fix BoringSSL to make sig_len a size_t*. 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t out_len; 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int ret = MakeCSSMSignature( 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ex_data, &out_len, sig, ECDSA_size(ec_key), digest, digest_len); 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ret) 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *sig_len = out_len; 3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 1; 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int EcdsaMethodVerify(const uint8_t* digest, 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t digest_len, 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const uint8_t* sig, 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t sig_len, 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EC_KEY* eckey) { 3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTIMPLEMENTED(); 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_NOT_IMPLEMENTED); 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const ECDSA_METHOD mac_ecdsa_method = { 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0 /* references */, 3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1 /* is_static */ 3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } /* common */, 3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* app_data */, 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* init */, 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL /* finish */, 4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EcdsaMethodGroupOrderSize, 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EcdsaMethodSign, 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EcdsaMethodVerify, 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ECDSA_FLAG_OPAQUE, 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)crypto::ScopedEVP_PKEY CreateECDSAWrapper(SecKeyRef key, 4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CSSM_KEY* cssm_key) { 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crypto::ScopedEC_KEY ec_key( 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EC_KEY_new_method(global_boringssl_engine.Get().engine())); 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ec_key) 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EC_KEY_set_ex_data( 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ec_key.get(), global_boringssl_engine.Get().ec_key_ex_index(), 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new KeyExData(key, cssm_key)); 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!pkey) 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get())) 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pkey.Pass(); 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)crypto::ScopedEVP_PKEY CreatePkeyWrapper(SecKeyRef key) { 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const CSSM_KEY* cssm_key; 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OSStatus status = SecKeyGetCSSMKey(key, &cssm_key); 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (status != noErr) 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (cssm_key->KeyHeader.AlgorithmId) { 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case CSSM_ALGID_RSA: 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return CreateRSAWrapper(key, cssm_key); 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case CSSM_ALGID_ECDSA: 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return CreateECDSAWrapper(key, cssm_key); 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(davidben): Filter out anything other than ECDSA and RSA 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // elsewhere. We don't support other key types. 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Unknown key type"; 4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)crypto::ScopedEVP_PKEY FetchClientCertPrivateKey( 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const X509Certificate* certificate) { 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Look up the private key. 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ScopedCFTypeRef<SecKeyRef> private_key( 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FetchSecKeyRefForCertificate(certificate)); 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!private_key) 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return crypto::ScopedEVP_PKEY(); 4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Create an EVP_PKEY wrapper. 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return CreatePkeyWrapper(private_key.get()); 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace net 465