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
3 // found in the LICENSE file.
5 #include "net/ssl/ssl_platform_key.h"
7 #include <openssl/digest.h>
8 #include <openssl/evp.h>
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "base/stl_util.h"
13 #include "crypto/scoped_openssl_types.h"
14 #include "net/base/net_errors.h"
15 #include "net/ssl/openssl_client_key_store.h"
16 #include "net/ssl/ssl_private_key.h"
17 #include "net/ssl/threaded_ssl_private_key.h"
23 class SSLPlatformKeyAndroid
: public ThreadedSSLPrivateKey::Delegate
{
25 SSLPlatformKeyAndroid(crypto::ScopedEVP_PKEY key
, SSLPrivateKey::Type type
)
26 : key_(key
.Pass()), type_(type
) {}
28 ~SSLPlatformKeyAndroid() override
{}
30 SSLPrivateKey::Type
GetType() override
{ return type_
; }
32 bool SupportsHash(SSLPrivateKey::Hash hash
) override
{ return true; }
34 size_t GetMaxSignatureLengthInBytes() override
{
35 return EVP_PKEY_size(key_
.get());
38 Error
SignDigest(SSLPrivateKey::Hash hash
,
39 const base::StringPiece
& input
,
40 std::vector
<uint8_t>* signature
) override
{
41 crypto::ScopedEVP_PKEY_CTX ctx
=
42 crypto::ScopedEVP_PKEY_CTX(EVP_PKEY_CTX_new(key_
.get(), NULL
));
44 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
45 if (!EVP_PKEY_sign_init(ctx
.get()))
46 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
48 if (type_
== SSLPrivateKey::Type::RSA
) {
49 const EVP_MD
* digest
= nullptr;
51 case SSLPrivateKey::Hash::MD5_SHA1
:
52 digest
= EVP_md5_sha1();
54 case SSLPrivateKey::Hash::SHA1
:
57 case SSLPrivateKey::Hash::SHA256
:
58 digest
= EVP_sha256();
60 case SSLPrivateKey::Hash::SHA384
:
61 digest
= EVP_sha384();
63 case SSLPrivateKey::Hash::SHA512
:
64 digest
= EVP_sha512();
67 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
70 if (!EVP_PKEY_CTX_set_rsa_padding(ctx
.get(), RSA_PKCS1_PADDING
))
71 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
72 if (!EVP_PKEY_CTX_set_signature_md(ctx
.get(), digest
))
73 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
77 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(input
.data()));
78 size_t input_len
= input
.size();
80 if (!EVP_PKEY_sign(ctx
.get(), NULL
, &sig_len
, input_ptr
, input_len
))
81 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
82 signature
->resize(sig_len
);
83 uint8_t* sig
= const_cast<uint8_t*>(
84 reinterpret_cast<const uint8_t*>(vector_as_array(signature
)));
86 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
87 if (!EVP_PKEY_sign(ctx
.get(), sig
, &sig_len
, input_ptr
, input_len
))
88 return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED
;
90 signature
->resize(sig_len
);
96 crypto::ScopedEVP_PKEY key_
;
97 SSLPrivateKey::Type type_
;
99 DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyAndroid
);
104 scoped_ptr
<SSLPrivateKey
> FetchClientCertPrivateKey(
105 X509Certificate
* certificate
,
106 scoped_refptr
<base::SequencedTaskRunner
> task_runner
) {
107 crypto::ScopedEVP_PKEY key
=
108 OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey(
113 SSLPrivateKey::Type type
;
114 switch (EVP_PKEY_id(key
.get())) {
116 type
= SSLPrivateKey::Type::RSA
;
119 type
= SSLPrivateKey::Type::ECDSA
;
122 LOG(ERROR
) << "Unknown key type: " << EVP_PKEY_id(key
.get());
125 return make_scoped_ptr(new ThreadedSSLPrivateKey(
126 make_scoped_ptr(new SSLPlatformKeyAndroid(key
.Pass(), type
)),
127 task_runner
.Pass()));