15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CRYPTO_EC_PRIVATE_KEY_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CRYPTO_EC_PRIVATE_KEY_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/crypto_export.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_OPENSSL)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Forward declaration for openssl/*.h
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct evp_pkey_st EVP_PKEY;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Forward declaration.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct CERTSubjectPublicKeyInfoStr CERTSubjectPublicKeyInfo;
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)typedef struct PK11SlotInfoStr PK11SlotInfo;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct SECKEYPublicKeyStr SECKEYPublicKey;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Encapsulates an elliptic curve (EC) private key. Can be used to generate new
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// keys, export keys to other formats, or to extract a public key.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(mattm): make this and RSAPrivateKey implement some PrivateKey interface.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (The difference in types of key() and public_key() make this a little
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tricky.)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CRYPTO_EXPORT ECPrivateKey {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ECPrivateKey();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns whether the system supports elliptic curve cryptography.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsSupported();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a new random instance. Can return NULL if initialization fails.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The created key will use the NIST P-256 curve.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mattm): Add a curve parameter.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ECPrivateKey* Create();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(USE_NSS)
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates a new random instance in |slot|. Can return NULL if initialization
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // fails.  The created key is permanent and is not exportable in plaintext
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // form.
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static ECPrivateKey* CreateSensitive(PK11SlotInfo* slot);
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a new instance by importing an existing key pair.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key pair is given as an ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // block and an X.509 SubjectPublicKeyInfo block.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns NULL if initialization fails.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ECPrivateKey* CreateFromEncryptedPrivateKeyInfo(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& password,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<uint8>& encrypted_private_key_info,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<uint8>& subject_public_key_info);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(USE_NSS)
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creates a new instance in |slot| by importing an existing key pair.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The key pair is given as an ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // block and an X.509 SubjectPublicKeyInfo block.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This can return NULL if initialization fails.  The created key is permanent
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and is not exportable in plaintext form.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ECPrivateKey* CreateSensitiveFromEncryptedPrivateKeyInfo(
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PK11SlotInfo* slot,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& password,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<uint8>& encrypted_private_key_info,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<uint8>& subject_public_key_info);
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_OPENSSL)
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Imports the key pair into |slot| and returns in |public_key| and |key|.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shortcut for code that needs to keep a reference directly to NSS types
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // without having to create a ECPrivateKey object and make a copy of them.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mattm): move this function to some NSS util file.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ImportFromEncryptedPrivateKeyInfo(
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PK11SlotInfo* slot,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& password,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const uint8* encrypted_private_key_info,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t encrypted_private_key_info_len,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CERTSubjectPublicKeyInfo* decoded_spki,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool permanent,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool sensitive,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SECKEYPrivateKey** key,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SECKEYPublicKey** public_key);
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns a copy of the object.
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ECPrivateKey* Copy() const;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_OPENSSL)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EVP_PKEY* key() { return key_; }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SECKEYPrivateKey* key() { return key_; }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SECKEYPublicKey* public_key() { return public_key_; }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exports the private key as an ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // block and the public key as an X.509 SubjectPublicKeyInfo block.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |password| and |iterations| are used as inputs to the key derivation
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // function for generating the encryption key.  PKCS #5 recommends a minimum
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of 1000 iterations, on modern systems a larger value may be preferrable.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ExportEncryptedPrivateKey(const std::string& password,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 int iterations,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::vector<uint8>* output);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exports the public key to an X.509 SubjectPublicKeyInfo block.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ExportPublicKey(std::vector<uint8>* output);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Exports the public key as an EC point in the uncompressed point format.
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool ExportRawPublicKey(std::string* output);
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exports private key data for testing. The format of data stored into output
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // doesn't matter other than that it is consistent for the same key.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ExportValue(std::vector<uint8>* output);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ExportECParams(std::vector<uint8>* output);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructor is private. Use one of the Create*() methods above instead.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ECPrivateKey();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(USE_OPENSSL)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shared helper for Create() and CreateSensitive().
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(cmasone): consider replacing |permanent| and |sensitive| with a
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                flags arg created by ORing together some enumerated values.
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static ECPrivateKey* CreateWithParams(PK11SlotInfo* slot,
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        bool permanent,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool sensitive);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shared helper for CreateFromEncryptedPrivateKeyInfo() and
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CreateSensitiveFromEncryptedPrivateKeyInfo().
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ECPrivateKey* CreateFromEncryptedPrivateKeyInfoWithParams(
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PK11SlotInfo* slot,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& password,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<uint8>& encrypted_private_key_info,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<uint8>& subject_public_key_info,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool permanent,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool sensitive);
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_OPENSSL)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EVP_PKEY* key_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SECKEYPrivateKey* key_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SECKEYPublicKey* public_key_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ECPrivateKey);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace crypto
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CRYPTO_EC_PRIVATE_KEY_H_
158