1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
/*
* PKCS#11 ECC
* (C) 2016 Daniel Neus, Sirrix AG
* (C) 2016 Philipp Weber, Sirrix AG
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_P11_ECC_H_
#define BOTAN_P11_ECC_H_
#include <botan/p11_object.h>
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
#include <botan/pk_keys.h>
#include <botan/ecc_key.h>
#include <botan/ec_group.h>
#include <botan/rng.h>
#include <botan/alg_id.h>
#include <vector>
namespace Botan {
namespace PKCS11 {
class Session;
/// Properties for generating a PKCS#11 EC public key
class BOTAN_PUBLIC_API(2,0) EC_PublicKeyGenerationProperties final : public PublicKeyProperties
{
public:
/// @param ec_params DER-encoding of an ANSI X9.62 Parameters value
EC_PublicKeyGenerationProperties(const std::vector<uint8_t>& ec_params);
/// @return the DER-encoding of the ec parameters according to ANSI X9.62
inline const std::vector<uint8_t>& ec_params() const
{
return m_ec_params;
}
private:
const std::vector<uint8_t> m_ec_params;
};
/// Properties for importing a PKCS#11 EC public key
class BOTAN_PUBLIC_API(2,0) EC_PublicKeyImportProperties final : public PublicKeyProperties
{
public:
/**
* @param ec_params DER-encoding of an ANSI X9.62 Parameters value
* @param ec_point DER-encoding of ANSI X9.62 ECPoint value Q
*/
EC_PublicKeyImportProperties(const std::vector<uint8_t>& ec_params, const std::vector<uint8_t>& ec_point);
/// @return the DER-encoding of the ec parameters according to ANSI X9.62
inline const std::vector<uint8_t>& ec_params() const
{
return m_ec_params;
}
/// @return the DER-encoding of the ec public point according to ANSI X9.62
inline const std::vector<uint8_t>& ec_point() const
{
return m_ec_point;
}
private:
const std::vector<uint8_t> m_ec_params;
const std::vector<uint8_t> m_ec_point;
};
/// Represents a PKCS#11 EC public key
class BOTAN_PUBLIC_API(2,0) PKCS11_EC_PublicKey : public virtual EC_PublicKey,
public Object
{
public:
static const ObjectClass Class = ObjectClass::PublicKey;
/**
* Creates a PKCS11_EC_PublicKey object from an existing PKCS#11 EC public key
* @param session the session to use
* @param handle the handle of the ecc public key
*/
PKCS11_EC_PublicKey(Session& session, ObjectHandle handle);
/**
* Imports an EC public key
* @param session the session to use
* @param props the attributes of the public key
*/
PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props);
};
/// Properties for generating a PKCS#11 EC private key
class BOTAN_PUBLIC_API(2,0) EC_PrivateKeyGenerationProperties final : public PrivateKeyProperties
{
public:
EC_PrivateKeyGenerationProperties()
: PrivateKeyProperties(KeyType::Ec)
{}
};
/// Properties for importing a PKCS#11 EC private key
class BOTAN_PUBLIC_API(2,0) EC_PrivateKeyImportProperties final : public PrivateKeyProperties
{
public:
/**
* @param ec_params DER-encoding of an ANSI X9.62 Parameters value
* @param value ANSI X9.62 private value d
*/
EC_PrivateKeyImportProperties(const std::vector<uint8_t>& ec_params, const BigInt& value);
/// @return the DER-encoding of the ec parameters according to ANSI X9.62
inline const std::vector<uint8_t>& ec_params() const
{
return m_ec_params;
}
/// @return the value of the ec private key
inline const BigInt& value() const
{
return m_value;
}
private:
const std::vector<uint8_t> m_ec_params;
const BigInt m_value;
};
// note: don't inherit from PKCS11_EC_PublicKey: a private key object IS NOT A public key object on a smartcard (-> two different objects)
// note: don't inherit from EC_PublicKey: the public key can not be extracted from a PKCS11-EC-PrivateKey (its only attributes are CKA_EC_PARAMS and CKA_VALUE)
/// Represents a PKCS#11 EC private key
class BOTAN_PUBLIC_API(2,0) PKCS11_EC_PrivateKey : public virtual Private_Key,
public Object
{
public:
static const ObjectClass Class = ObjectClass::PrivateKey;
/**
* Creates a PKCS11_EC_PrivateKey object from an existing PKCS#11 EC private key
* @param session the session to use
* @param handle the handle of the EC private key
*/
PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle);
/**
* Imports an EC private key
* @param session the session to use
* @param props the attributes of the private key
*/
PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props);
/**
* Generates a PKCS#11 EC private key
* @param session the session to use
* @param ec_params DER-encoding of an ANSI X9.62 Parameters value
* @param props the attributes of the private key
* @note no persistent public key object will be created
*/
PKCS11_EC_PrivateKey(Session& session, const std::vector<uint8_t>& ec_params,
const EC_PrivateKeyGenerationProperties& props);
/// @returns the domain of the EC private key
inline const EC_Group& domain() const
{
return m_domain_params;
}
/**
* Sets the associated public point of this private key
* @param point the public point
* @param point_encoding encoding of the point (default DER-encoded)
*/
void set_public_point(const PointGFp& point, PublicPointEncoding point_encoding = PublicPointEncoding::Der)
{
m_public_key = point;
m_point_encoding = point_encoding;
}
/**
* Gets the public_point
* @note the public key must be set using `set_public_point`
* because it is not possible to infer the public key from a PKCS#11 EC private key
* @return the public point of the private key
* @throws Exception if the public point was not set using set_public_point()
*/
const PointGFp& public_point() const
{
if(m_public_key.is_zero())
{
throw Exception("Public point not set. Inferring the public key from a PKCS#11 ec private key is not possible.");
}
return m_public_key;
}
/// @return the encoding format for the public point when it is passed to cryptoki functions as an argument
PublicPointEncoding point_encoding() const
{
return m_point_encoding;
}
// Private_Key methods
std::vector<uint8_t> public_key_bits() const override;
std::size_t key_length() const override;
std::size_t estimated_strength() const override;
bool check_key(RandomNumberGenerator&, bool) const override;
AlgorithmIdentifier algorithm_identifier() const override;
private:
EC_Group m_domain_params;
PointGFp m_public_key;
PublicPointEncoding m_point_encoding = PublicPointEncoding::Der;
};
}
}
#endif
#endif
|