Botan 3.13.0
Crypto and TLS for C&
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
11#include <botan/pk_keys.h>
12
13#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
14
15 #include <botan/ber_dec.h>
16 #include <botan/internal/ec_key_data.h>
17 #include <botan/internal/scoped_cleanup.h>
18 #include <botan/internal/workfactor.h>
19
20namespace Botan::PKCS11 {
21
22namespace {
23
24/// Converts a DER-encoded ANSI X9.62 ECPoint to EC_Point
25EC_AffinePoint decode_public_point(const EC_Group& group, std::span<const uint8_t> ec_point_data) {
26 std::vector<uint8_t> ec_point;
27 BER_Decoder(ec_point_data, BER_Decoder::Limits::DER()).decode(ec_point, ASN1_Type::OctetString).verify_end();
28 // Throws if invalid
29 return EC_AffinePoint(group, ec_point);
30}
31
32} // namespace
33
34EC_PublicKeyGenerationProperties::EC_PublicKeyGenerationProperties(const std::vector<uint8_t>& ec_params) :
35 PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params) {
36 add_binary(AttributeType::EcParams, m_ec_params);
37}
38
39EC_PublicKeyImportProperties::EC_PublicKeyImportProperties(const std::vector<uint8_t>& ec_params,
40 const std::vector<uint8_t>& ec_point) :
41 PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_ec_point(ec_point) {
42 add_binary(AttributeType::EcParams, m_ec_params);
43 add_binary(AttributeType::EcPoint, m_ec_point);
44}
45
46PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle) : Object(session, handle) {
47 auto ec_parameters = get_attribute_value(AttributeType::EcParams);
48 auto pt_bytes = get_attribute_value(AttributeType::EcPoint);
49
50 EC_Group group(ec_parameters);
51 auto pt = decode_public_point(group, pt_bytes);
52 m_public_key = std::make_shared<EC_PublicKey_Data>(std::move(group), std::move(pt));
53}
54
55PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props) :
56 Object(session, props) {
57 EC_Group group(props.ec_params());
58 auto pt = decode_public_point(group, props.ec_point());
59 m_public_key = std::make_shared<EC_PublicKey_Data>(std::move(group), std::move(pt));
60}
61
62EC_PrivateKeyImportProperties::EC_PrivateKeyImportProperties(const std::vector<uint8_t>& ec_params,
63 const BigInt& value) :
64 PrivateKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_value(value) {
65 add_binary(AttributeType::EcParams, m_ec_params);
66 add_binary(AttributeType::Value, m_value.serialize());
67}
68
69PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle) :
70 Object(session, handle), m_domain_params(get_attribute_value(AttributeType::EcParams)) {}
71
72PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props) :
73 Object(session, props), m_domain_params(EC_Group(props.ec_params())) {}
74
75PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session,
76 const std::vector<uint8_t>& ec_params,
77 const EC_PrivateKeyGenerationProperties& props) :
78 Object(session), m_domain_params(ec_params) {
79 EC_PublicKeyGenerationProperties pub_key_props(ec_params);
80 pub_key_props.set_verify(true);
81 pub_key_props.set_private(false);
82 pub_key_props.set_token(false); // don't create a persistent public key object
83
84 ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
85 ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
86 const Mechanism mechanism = {CKM_EC_KEY_PAIR_GEN, nullptr, 0};
87 session.module()->C_GenerateKeyPair(session.handle(),
88 &mechanism,
89 pub_key_props.data(),
90 checked_ulong_cast(pub_key_props.count()),
91 props.data(),
92 checked_ulong_cast(props.count()),
93 &pub_key_handle,
94 &priv_key_handle);
95
96 this->reset_handle(priv_key_handle);
97 const Object public_key(session, pub_key_handle);
98 auto destroy_public = scoped_cleanup([&]() noexcept {
99 try {
100 public_key.destroy();
101 } catch(...) { // NOLINT(*-empty-catch)
102 }
103 });
104
105 auto pt_bytes = public_key.get_attribute_value(AttributeType::EcPoint);
106 m_public_key = decode_public_point(m_domain_params, pt_bytes);
107}
108
109size_t PKCS11_EC_PrivateKey::key_length() const {
110 return m_domain_params.get_order_bits();
111}
112
113std::vector<uint8_t> PKCS11_EC_PrivateKey::raw_public_key_bits() const {
114 // It seems odd that this serializes compressed without ability to control
115 return public_ec_point().serialize_compressed();
116}
117
118std::vector<uint8_t> PKCS11_EC_PrivateKey::public_key_bits() const {
119 return raw_public_key_bits();
120}
121
122size_t PKCS11_EC_PrivateKey::estimated_strength() const {
123 return ecp_work_factor(key_length());
124}
125
126bool PKCS11_EC_PrivateKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/) const {
127 return true;
128}
129
130AlgorithmIdentifier PKCS11_EC_PrivateKey::algorithm_identifier() const {
131 return AlgorithmIdentifier(object_identifier(), domain().DER_encode());
132}
133} // namespace Botan::PKCS11
134
135#endif
static Limits DER()
Definition ber_dec.h:42
Common attributes of all public key objects.
Definition p11_object.h:298
Ulong checked_ulong_cast(size_t v)
Definition p11.h:1228
AttributeType
Definition p11.h:50
CK_MECHANISM Mechanism
Definition p11.h:1207
CK_OBJECT_HANDLE ObjectHandle
Definition p11.h:1214
size_t ecp_work_factor(size_t bits)
#define CK_INVALID_HANDLE
Definition pkcs11.h:35
#define CKM_EC_KEY_PAIR_GEN
Definition pkcs11.h:861