Botan 3.0.0-alpha0
Crypto and TLS for C&
ffi_pkey.cpp
Go to the documentation of this file.
1/*
2* (C) 2015,2017 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/ffi.h>
8#include <botan/internal/ffi_util.h>
9#include <botan/internal/ffi_pkey.h>
10#include <botan/internal/ffi_rng.h>
11#include <botan/data_src.h>
12#include <botan/hash.h>
13#include <botan/pkcs8.h>
14#include <botan/pk_keys.h>
15#include <botan/x509_key.h>
16#include <botan/pk_algs.h>
17
18#if defined(BOTAN_HAS_HASH_ID)
19 #include <botan/internal/hash_id.h>
20#endif
21
22extern "C" {
23
24using namespace Botan_FFI;
25
27 const char* algo_name,
28 const char* algo_params,
29 botan_rng_t rng_obj)
30 {
31 return ffi_guard_thunk(__func__, [=]() -> int {
32 if(key_obj == nullptr)
34
35 *key_obj = nullptr;
36 if(rng_obj == nullptr)
38
40 std::unique_ptr<Botan::Private_Key> key(
41 Botan::create_private_key(algo_name ? algo_name : "RSA",
42 rng,
43 algo_params ? algo_params : ""));
44
45 if(key)
46 {
47 *key_obj = new botan_privkey_struct(std::move(key));
48 return BOTAN_FFI_SUCCESS;
49 }
50 else
51 {
53 }
54 });
55 }
56
58 const uint8_t bits[], size_t len,
59 const char* password)
60 {
61 BOTAN_UNUSED(rng_obj);
62
63 *key = nullptr;
64
65 return ffi_guard_thunk(__func__, [=]() -> int {
66 Botan::DataSource_Memory src(bits, len);
67
68 std::unique_ptr<Botan::Private_Key> pkcs8;
69
70 if(password == nullptr)
71 {
72 pkcs8 = Botan::PKCS8::load_key(src);
73 }
74 else
75 {
76 pkcs8 = Botan::PKCS8::load_key(src, std::string(password));
77 }
78
79 if(pkcs8)
80 {
81 *key = new botan_privkey_struct(std::move(pkcs8));
82 return BOTAN_FFI_SUCCESS;
83 }
85 });
86 }
87
89 {
90 return BOTAN_FFI_CHECKED_DELETE(key);
91 }
92
94 const uint8_t bits[], size_t bits_len)
95 {
96 *key = nullptr;
97
98 return ffi_guard_thunk(__func__, [=]() -> int {
99 Botan::DataSource_Memory src(bits, bits_len);
100 std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(src));
101
102 if(pubkey == nullptr)
104
105 *key = new botan_pubkey_struct(std::move(pubkey));
106 return BOTAN_FFI_SUCCESS;
107 });
108 }
109
111 {
112 return BOTAN_FFI_CHECKED_DELETE(key);
113 }
114
116 {
117 return ffi_guard_thunk(__func__, [=]() -> int {
118 std::unique_ptr<Botan::Public_Key>
120
121 *pubout = new botan_pubkey_struct(std::move(pubkey));
122 return BOTAN_FFI_SUCCESS;
123 });
124 }
125
126int botan_privkey_algo_name(botan_privkey_t key, char out[], size_t* out_len)
127 {
128 return BOTAN_FFI_DO(Botan::Private_Key, key, k, { return write_str_output(out, out_len, k.algo_name()); });
129 }
130
131int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len)
132 {
133 return BOTAN_FFI_DO(Botan::Public_Key, key, k, { return write_str_output(out, out_len, k.algo_name()); });
134 }
135
137 {
138 const bool strong = (flags & BOTAN_CHECK_KEY_EXPENSIVE_TESTS);
139
140 return BOTAN_FFI_RETURNING(Botan::Public_Key, key, k, {
141 return (k.check_key(safe_get(rng), strong) == true) ? 0 : BOTAN_FFI_ERROR_INVALID_INPUT;
142 });
143 }
144
146 {
147 const bool strong = (flags & BOTAN_CHECK_KEY_EXPENSIVE_TESTS);
149 return (k.check_key(safe_get(rng), strong) == true) ? 0 : BOTAN_FFI_ERROR_INVALID_INPUT;
150 });
151 }
152
153int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags)
154 {
155 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
157 return write_vec_output(out, out_len, Botan::X509::BER_encode(k));
159 return write_str_output(out, out_len, Botan::X509::PEM_encode(k));
160 else
162 });
163 }
164
165int botan_privkey_export(botan_privkey_t key, uint8_t out[], size_t* out_len, uint32_t flags)
166 {
167 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
169 return write_vec_output(out, out_len, Botan::PKCS8::BER_encode(k));
171 return write_str_output(out, out_len, Botan::PKCS8::PEM_encode(k));
172 else
174 });
175 }
176
178 uint8_t out[], size_t* out_len,
179 botan_rng_t rng_obj,
180 const char* pass,
181 const char* /*ignored - pbe*/,
182 uint32_t flags)
183 {
184 return botan_privkey_export_encrypted_pbkdf_iter(key, out, out_len, rng_obj, pass, 100000, nullptr, nullptr, flags);
185 }
186
188 uint8_t out[], size_t* out_len,
189 botan_rng_t rng_obj,
190 const char* pass,
191 uint32_t pbkdf_msec,
192 size_t* pbkdf_iters_out,
193 const char* maybe_cipher,
194 const char* maybe_pbkdf_hash,
195 uint32_t flags)
196 {
197 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
198 const std::chrono::milliseconds pbkdf_time(pbkdf_msec);
200
201 const std::string cipher = (maybe_cipher ? maybe_cipher : "");
202 const std::string pbkdf_hash = (maybe_pbkdf_hash ? maybe_pbkdf_hash : "");
203
205 {
206 return write_vec_output(out, out_len,
207 Botan::PKCS8::BER_encode_encrypted_pbkdf_msec(k, rng, pass, pbkdf_time, pbkdf_iters_out, cipher, pbkdf_hash));
208 }
210 {
211 return write_str_output(out, out_len,
212 Botan::PKCS8::PEM_encode_encrypted_pbkdf_msec(k, rng, pass, pbkdf_time, pbkdf_iters_out, cipher, pbkdf_hash));
213 }
214 else
215 {
216 return -2;
217 }
218 });
219 }
220
222 uint8_t out[], size_t* out_len,
223 botan_rng_t rng_obj,
224 const char* pass,
225 size_t pbkdf_iter,
226 const char* maybe_cipher,
227 const char* maybe_pbkdf_hash,
228 uint32_t flags)
229 {
230 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
232
233 const std::string cipher = (maybe_cipher ? maybe_cipher : "");
234 const std::string pbkdf_hash = (maybe_pbkdf_hash ? maybe_pbkdf_hash : "");
235
237 {
238 return write_vec_output(out, out_len,
239 Botan::PKCS8::BER_encode_encrypted_pbkdf_iter(k, rng, pass, pbkdf_iter, cipher, pbkdf_hash));
240 }
242 {
243 return write_str_output(out, out_len,
244 Botan::PKCS8::PEM_encode_encrypted_pbkdf_iter(k, rng, pass, pbkdf_iter, cipher, pbkdf_hash));
245 }
246 else
247 {
248 return -2;
249 }
250 });
251 }
252
254 {
255 return BOTAN_FFI_DO(Botan::Public_Key, key, k, { *estimate = k.estimated_strength(); });
256 }
257
258int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash_fn,
259 uint8_t out[], size_t* out_len)
260 {
261 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
262 std::unique_ptr<Botan::HashFunction> h(Botan::HashFunction::create(hash_fn));
263 return write_vec_output(out, out_len, h->process(k.public_key_bits()));
264 });
265 }
266
267int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len)
268 {
269#if defined(BOTAN_HAS_HASH_ID)
270 return ffi_guard_thunk(__func__, [=]() -> int {
271 const std::vector<uint8_t> hash_id = Botan::pkcs_hash_id(hash_name);
272 return write_output(pkcs_id, pkcs_id_len, hash_id.data(), hash_id.size());
273 });
274#else
276#endif
277 }
278
279}
#define BOTAN_UNUSED(...)
Definition: assert.h:141
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:98
virtual size_t estimated_strength() const =0
struct botan_pubkey_struct * botan_pubkey_t
Definition: ffi.h:1123
struct botan_privkey_struct * botan_privkey_t
Definition: ffi.h:976
#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM
Definition: ffi.h:1071
#define BOTAN_CHECK_KEY_EXPENSIVE_TESTS
Definition: ffi.h:991
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:200
#define BOTAN_PRIVKEY_EXPORT_FLAG_DER
Definition: ffi.h:1070
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition: ffi.h:83
@ BOTAN_FFI_ERROR_UNKNOWN_ERROR
Definition: ffi.h:90
@ BOTAN_FFI_ERROR_BAD_FLAG
Definition: ffi.h:76
@ BOTAN_FFI_ERROR_INVALID_INPUT
Definition: ffi.h:66
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition: ffi.h:77
@ BOTAN_FFI_SUCCESS
Definition: ffi.h:63
int botan_privkey_export_encrypted(botan_privkey_t key, uint8_t out[], size_t *out_len, botan_rng_t rng_obj, const char *pass, const char *, uint32_t flags)
Definition: ffi_pkey.cpp:177
int botan_privkey_check_key(botan_privkey_t key, botan_rng_t rng, uint32_t flags)
Definition: ffi_pkey.cpp:145
int botan_pubkey_fingerprint(botan_pubkey_t key, const char *hash_fn, uint8_t out[], size_t *out_len)
Definition: ffi_pkey.cpp:258
int botan_privkey_export_encrypted_pbkdf_iter(botan_privkey_t key, uint8_t out[], size_t *out_len, botan_rng_t rng_obj, const char *pass, size_t pbkdf_iter, const char *maybe_cipher, const char *maybe_pbkdf_hash, uint32_t flags)
Definition: ffi_pkey.cpp:221
int botan_privkey_load(botan_privkey_t *key, botan_rng_t rng_obj, const uint8_t bits[], size_t len, const char *password)
Definition: ffi_pkey.cpp:57
int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t *estimate)
Definition: ffi_pkey.cpp:253
int botan_pkcs_hash_id(const char *hash_name, uint8_t pkcs_id[], size_t *pkcs_id_len)
Definition: ffi_pkey.cpp:267
int botan_privkey_export_encrypted_pbkdf_msec(botan_privkey_t key, uint8_t out[], size_t *out_len, botan_rng_t rng_obj, const char *pass, uint32_t pbkdf_msec, size_t *pbkdf_iters_out, const char *maybe_cipher, const char *maybe_pbkdf_hash, uint32_t flags)
Definition: ffi_pkey.cpp:187
int botan_pubkey_load(botan_pubkey_t *key, const uint8_t bits[], size_t bits_len)
Definition: ffi_pkey.cpp:93
int botan_privkey_export(botan_privkey_t key, uint8_t out[], size_t *out_len, uint32_t flags)
Definition: ffi_pkey.cpp:165
int botan_privkey_destroy(botan_privkey_t key)
Definition: ffi_pkey.cpp:88
int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t *out_len)
Definition: ffi_pkey.cpp:131
int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t *out_len, uint32_t flags)
Definition: ffi_pkey.cpp:153
int botan_pubkey_destroy(botan_pubkey_t key)
Definition: ffi_pkey.cpp:110
int botan_privkey_algo_name(botan_privkey_t key, char out[], size_t *out_len)
Definition: ffi_pkey.cpp:126
int botan_privkey_create(botan_privkey_t *key_obj, const char *algo_name, const char *algo_params, botan_rng_t rng_obj)
Definition: ffi_pkey.cpp:26
int botan_privkey_export_pubkey(botan_pubkey_t *pubout, botan_privkey_t key_obj)
Definition: ffi_pkey.cpp:115
int botan_pubkey_check_key(botan_pubkey_t key, botan_rng_t rng, uint32_t flags)
Definition: ffi_pkey.cpp:136
#define BOTAN_FFI_DO(T, obj, param, block)
Definition: ffi_util.h:96
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition: ffi_util.h:126
#define BOTAN_FFI_RETURNING(T, obj, param, block)
Definition: ffi_util.h:105
Flags flags(Flag flags)
Definition: p11.h:860
std::vector< uint8_t > BER_encode_encrypted_pbkdf_iter(const Private_Key &key, RandomNumberGenerator &rng, const std::string &pass, size_t pbkdf_iterations, const std::string &cipher, const std::string &pbkdf_hash)
Definition: pkcs8.cpp:235
std::string PEM_encode(const Private_Key &key)
Definition: pkcs8.cpp:137
std::string PEM_encode_encrypted_pbkdf_msec(const Private_Key &key, RandomNumberGenerator &rng, const std::string &pass, std::chrono::milliseconds pbkdf_msec, size_t *pbkdf_iterations, const std::string &cipher, const std::string &pbkdf_hash)
Definition: pkcs8.cpp:316
std::vector< uint8_t > BER_encode(const Private_Key &key, RandomNumberGenerator &rng, const std::string &pass, std::chrono::milliseconds msec, const std::string &pbe_algo)
Definition: pkcs8.cpp:189
std::vector< uint8_t > BER_encode_encrypted_pbkdf_msec(const Private_Key &key, RandomNumberGenerator &rng, const std::string &pass, std::chrono::milliseconds pbkdf_msec, size_t *pbkdf_iterations, const std::string &cipher, const std::string &pbkdf_hash)
Definition: pkcs8.cpp:283
std::unique_ptr< Private_Key > load_key(DataSource &source, const std::function< std::string()> &get_pass)
Definition: pkcs8.cpp:355
std::string PEM_encode_encrypted_pbkdf_iter(const Private_Key &key, RandomNumberGenerator &rng, const std::string &pass, size_t pbkdf_iterations, const std::string &cipher, const std::string &pbkdf_hash)
Definition: pkcs8.cpp:268
std::vector< uint8_t > BER_encode(const Public_Key &key)
Definition: x509_key.h:28
Public_Key * load_key(DataSource &source)
Definition: x509_key.cpp:29
std::string PEM_encode(const Public_Key &key)
Definition: x509_key.cpp:20
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:65
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
Definition: ffi_util.h:157
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition: ffi.cpp:92
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
Definition: ffi_util.h:152
int write_output(uint8_t out[], size_t *out_len, const uint8_t buf[], size_t buf_len)
Definition: ffi_util.h:128
std::vector< uint8_t > pkcs_hash_id(const std::string &name)
Definition: hash_id.cpp:73
std::unique_ptr< Private_Key > create_private_key(const std::string &alg_name, RandomNumberGenerator &rng, const std::string &params, const std::string &provider)
Definition: pk_algs.cpp:299