1// Copyright (c) 2012 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.
4
5#include "net/base/openssl_private_key_store.h"
6
7#include <openssl/evp.h>
8#include <openssl/x509.h>
9
10#include "base/logging.h"
11#include "base/memory/singleton.h"
12#include "crypto/openssl_util.h"
13#include "crypto/scoped_openssl_types.h"
14#include "net/android/network_library.h"
15
16namespace net {
17
18bool OpenSSLPrivateKeyStore::StoreKeyPair(const GURL& url,
19                                          EVP_PKEY* pkey) {
20  // Always clear openssl errors on exit.
21  crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
22
23  // Important: Do not use i2d_PublicKey() here, which returns data in
24  // PKCS#1 format, use i2d_PUBKEY() which returns it as DER-encoded
25  // SubjectPublicKeyInfo (X.509), as expected by the platform.
26  unsigned char* public_key = NULL;
27  int public_len = i2d_PUBKEY(pkey, &public_key);
28
29  // Important: Do not use i2d_PrivateKey() here, it returns data
30  // in a format that is incompatible with what the platform expects.
31  unsigned char* private_key = NULL;
32  int private_len = 0;
33  crypto::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type
34      pkcs8(EVP_PKEY2PKCS8(pkey));
35  if (pkcs8.get() != NULL) {
36    private_len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &private_key);
37  }
38  bool ret = false;
39  if (public_len > 0 && private_len > 0) {
40    ret = net::android::StoreKeyPair(
41        static_cast<const uint8*>(public_key), public_len,
42        static_cast<const uint8*>(private_key), private_len);
43  }
44  LOG_IF(ERROR, !ret) << "StoreKeyPair failed. pub len = " << public_len
45                      << " priv len = " << private_len;
46  OPENSSL_free(public_key);
47  OPENSSL_free(private_key);
48  return ret;
49}
50
51}  // namespace net
52