Botan  2.6.0
Crypto and TLS for C++11
p11_ecc_key.cpp
Go to the documentation of this file.
1 /*
2 * PKCS#11 ECC
3 * (C) 2016 Daniel Neus, Sirrix AG
4 * (C) 2016 Philipp Weber, Sirrix AG
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/p11_ecc_key.h>
10 #include <botan/pk_keys.h>
11 
12 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
13 
14 #include <botan/workfactor.h>
15 #include <botan/ber_dec.h>
16 
17 namespace Botan {
18 namespace PKCS11 {
19 namespace {
20 /// Converts a DER-encoded ANSI X9.62 ECPoint to PointGFp
21 PointGFp decode_public_point(const secure_vector<uint8_t>& ec_point_data, const EC_Group& group)
22  {
23  secure_vector<uint8_t> ec_point;
24  BER_Decoder(ec_point_data).decode(ec_point, OCTET_STRING);
25  return group.OS2ECP(ec_point);
26  }
27 }
28 
29 EC_PublicKeyGenerationProperties::EC_PublicKeyGenerationProperties(const std::vector<uint8_t>& ec_params)
30  : PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params)
31  {
32  add_binary(AttributeType::EcParams, m_ec_params);
33  }
34 
35 EC_PublicKeyImportProperties::EC_PublicKeyImportProperties(const std::vector<uint8_t>& ec_params,
36  const std::vector<uint8_t>& ec_point)
37  : PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_ec_point(ec_point)
38  {
39  add_binary(AttributeType::EcParams, m_ec_params);
40  add_binary(AttributeType::EcPoint, m_ec_point);
41  }
42 
43 PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle)
44  : Object(session, handle)
45  {
46  secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
47  m_domain_params = EC_Group(unlock(ec_parameters));
48  m_public_key = decode_public_point(get_attribute_value(AttributeType::EcPoint), m_domain_params);
49  m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
50  }
51 
52 PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
53  : Object(session, props)
54  {
55  m_domain_params = EC_Group(props.ec_params());
56 
57  secure_vector<uint8_t> ec_point;
58  BER_Decoder(props.ec_point()).decode(ec_point, OCTET_STRING);
59  m_public_key = m_domain_params.OS2ECP(ec_point);
60  m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
61  }
62 
63 EC_PrivateKeyImportProperties::EC_PrivateKeyImportProperties(const std::vector<uint8_t>& ec_params, const BigInt& value)
64  : PrivateKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_value(value)
65  {
66  add_binary(AttributeType::EcParams, m_ec_params);
67  add_binary(AttributeType::Value, BigInt::encode(m_value));
68  }
69 
70 PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle)
71  : Object(session, handle), m_domain_params(), m_public_key()
72  {
73  secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
74  m_domain_params = EC_Group(unlock(ec_parameters));
75  }
76 
77 PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)
78  : Object(session, props)
79  {
80  m_domain_params = EC_Group(props.ec_params());
81  }
82 
83 PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const std::vector<uint8_t>& ec_params,
84  const EC_PrivateKeyGenerationProperties& props)
85  : Object(session)
86  {
87  m_domain_params = EC_Group(ec_params);
88 
89  EC_PublicKeyGenerationProperties pub_key_props(ec_params);
90  pub_key_props.set_verify(true);
91  pub_key_props.set_private(false);
92  pub_key_props.set_token(false); // don't create a persistent public key object
93 
94  ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
95  ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
96  Mechanism mechanism = { CKM_EC_KEY_PAIR_GEN, nullptr, 0 };
97  session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
98  pub_key_props.data(), pub_key_props.count(), props.data(), props.count(),
99  &pub_key_handle, &priv_key_handle);
100 
101  this->reset_handle(priv_key_handle);
102 
103  Object public_key(session, pub_key_handle);
104  m_public_key = decode_public_point(public_key.get_attribute_value(AttributeType::EcPoint), m_domain_params);
105  }
106 
107 size_t PKCS11_EC_PrivateKey::key_length() const
108  {
109  return m_domain_params.get_order().bits();
110  }
111 
112 std::vector<uint8_t> PKCS11_EC_PrivateKey::public_key_bits() const
113  {
114  return public_point().encode(PointGFp::COMPRESSED);
115  }
116 
117 size_t PKCS11_EC_PrivateKey::estimated_strength() const
118  {
119  return ecp_work_factor(key_length());
120  }
121 
122 bool PKCS11_EC_PrivateKey::check_key(RandomNumberGenerator&, bool) const
123  {
124  return m_public_key.on_the_curve();
125  }
126 
127 AlgorithmIdentifier PKCS11_EC_PrivateKey::algorithm_identifier() const
128  {
129  return AlgorithmIdentifier(get_oid(), domain().DER_encode(EC_DOMPAR_ENC_EXPLICIT));
130  }
131 }
132 
133 }
134 
135 #endif
#define CK_INVALID_HANDLE
Definition: pkcs11t.h:75
size_t ecp_work_factor(size_t bits)
Definition: workfactor.cpp:14
#define CKM_EC_KEY_PAIR_GEN
Definition: pkcs11t.h:889
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
Definition: alg_id.cpp:13
CK_OBJECT_HANDLE ObjectHandle
Definition: p11.h:846
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:95
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54