12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef NET_SSL_OPENSSL_CLIENT_KEY_STORE_H_
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define NET_SSL_OPENSSL_CLIENT_KEY_STORE_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <openssl/evp.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/singleton.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "crypto/openssl_util.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "crypto/scoped_openssl_types.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_export.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class X509Certificate;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OpenSSLClientKeyStore implements an in-memory store for client
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// certificate private keys, because the platforms where OpenSSL is
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used do not provide a way to retrieve the private key of a known
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// certificate.
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class is not thread-safe and should only be used from the network
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// thread.
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class NET_EXPORT OpenSSLClientKeyStore {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Platforms must define this factory function as appropriate.
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static OpenSSLClientKeyStore* GetInstance();
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Record the association between a certificate and its
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // private key. This method should be called _before_
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FetchClientCertPrivateKey to ensure that the private key is returned
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // when it is called later. The association is recorded in memory
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // exclusively.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |cert| is a handle to a certificate object.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |private_key| is an OpenSSL EVP_PKEY that corresponds to the
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // certificate's private key.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns false if an error occured.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This function does not take ownership of the private_key, but may
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // increment its internal reference count.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NET_EXPORT bool RecordClientCertPrivateKey(const X509Certificate* cert,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             EVP_PKEY* private_key);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Given a certificate's |public_key|, return the corresponding private
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // key that has been recorded previously by RecordClientCertPrivateKey().
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |cert| is a client certificate.
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns its matching private key on success, NULL otherwise.
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  crypto::ScopedEVP_PKEY FetchClientCertPrivateKey(const X509Certificate* cert);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Flush all recorded keys.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Flush();
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenSSLClientKeyStore();
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~OpenSSLClientKeyStore();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Adds a given public/private key pair.
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |pub_key| and |private_key| can point to the same object.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This increments the reference count on both objects, caller
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // must still call EVP_PKEY_free on them.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddKeyPair(EVP_PKEY* pub_key, EVP_PKEY* private_key);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // KeyPair is an internal class used to hold a pair of private / public
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // EVP_PKEY objects, with appropriate ownership.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class KeyPair {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    explicit KeyPair(EVP_PKEY* pub_key, EVP_PKEY* priv_key);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    KeyPair(const KeyPair& other);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void operator=(const KeyPair& other);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~KeyPair();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    crypto::ScopedEVP_PKEY public_key;
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    crypto::ScopedEVP_PKEY private_key;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    KeyPair();  // intentionally not implemented.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the index of the keypair for |public_key|. or -1 if not found.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int FindKeyPairIndex(EVP_PKEY* public_key);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<KeyPair> pairs_;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend struct DefaultSingletonTraits<OpenSSLClientKeyStore>;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OpenSSLClientKeyStore);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // NET_SSL_OPENSSL_CLIENT_KEY_STORE_H_
99