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"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_export.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class X509Certificate;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OpenSSLClientKeyStore implements an in-memory store for client
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// certificate private keys, because the platforms where OpenSSL is
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used do not provide a way to retrieve the private key of a known
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// certificate.
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class is not thread-safe and should only be used from the network
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// thread.
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class NET_EXPORT OpenSSLClientKeyStore {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Platforms must define this factory function as appropriate.
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static OpenSSLClientKeyStore* GetInstance();
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct EVP_PKEY_Deleter {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inline void operator()(EVP_PKEY* ptr) const {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EVP_PKEY_free(ptr);
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef scoped_ptr<EVP_PKEY, EVP_PKEY_Deleter> ScopedEVP_PKEY;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Record the association between a certificate and its
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // private key. This method should be called _before_
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FetchClientCertPrivateKey to ensure that the private key is returned
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // when it is called later. The association is recorded in memory
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // exclusively.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |cert| is a handle to a certificate object.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |private_key| is an OpenSSL EVP_PKEY that corresponds to the
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // certificate's private key.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns false if an error occured.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This function does not take ownership of the private_key, but may
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // increment its internal reference count.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NET_EXPORT bool RecordClientCertPrivateKey(const X509Certificate* cert,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             EVP_PKEY* private_key);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Given a certificate's |public_key|, return the corresponding private
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // key that has been recorded previously by RecordClientCertPrivateKey().
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |cert| is a client certificate.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |*private_key| will be reset to its matching private key on success.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true on success, false otherwise. This increments the reference
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // count of the private key on success.
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool FetchClientCertPrivateKey(const X509Certificate* cert,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 ScopedEVP_PKEY* private_key);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Flush all recorded keys. Used only during testing.
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Flush();
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenSSLClientKeyStore();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~OpenSSLClientKeyStore();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Adds a given public/private key pair.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |pub_key| and |private_key| can point to the same object.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This increments the reference count on both objects, caller
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // must still call EVP_PKEY_free on them.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddKeyPair(EVP_PKEY* pub_key, EVP_PKEY* private_key);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // KeyPair is an internal class used to hold a pair of private / public
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // EVP_PKEY objects, with appropriate ownership.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class KeyPair {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    explicit KeyPair(EVP_PKEY* pub_key, EVP_PKEY* priv_key);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    KeyPair(const KeyPair& other);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void operator=(const KeyPair& other);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~KeyPair();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EVP_PKEY* public_key;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EVP_PKEY* private_key;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    KeyPair();  // intentionally not implemented.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the index of the keypair for |public_key|. or -1 if not found.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int FindKeyPairIndex(EVP_PKEY* public_key);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<KeyPair> pairs_;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend struct DefaultSingletonTraits<OpenSSLClientKeyStore>;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OpenSSLClientKeyStore);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // NET_SSL_OPENSSL_CLIENT_KEY_STORE_H_
109