• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.41
/src/lib/ffi/ffi_pkey.cpp
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

9
#include <botan/data_src.h>
10
#include <botan/hash.h>
11
#include <botan/pk_algs.h>
12
#include <botan/pk_keys.h>
13
#include <botan/pkcs8.h>
14
#include <botan/x509_key.h>
15
#include <botan/internal/ffi_pkey.h>
16
#include <botan/internal/ffi_rng.h>
17
#include <botan/internal/ffi_util.h>
18

19
#if defined(BOTAN_HAS_HASH_ID)
20
   #include <botan/internal/hash_id.h>
21
#endif
22

23
extern "C" {
24

25
using namespace Botan_FFI;
26

27
int botan_privkey_create(botan_privkey_t* key_obj,
23✔
28
                         const char* algo_name,
29
                         const char* algo_params,
30
                         botan_rng_t rng_obj) {
31
   return ffi_guard_thunk(__func__, [=]() -> int {
23✔
32
      if(key_obj == nullptr)
46✔
33
         return BOTAN_FFI_ERROR_NULL_POINTER;
34

35
      *key_obj = nullptr;
23✔
36
      if(rng_obj == nullptr)
23✔
37
         return BOTAN_FFI_ERROR_NULL_POINTER;
38

39
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
23✔
40
      std::unique_ptr<Botan::Private_Key> key(
23✔
41
         Botan::create_private_key(algo_name ? algo_name : "RSA", rng, algo_params ? algo_params : ""));
69✔
42

43
      if(key) {
23✔
44
         *key_obj = new botan_privkey_struct(std::move(key));
23✔
45
         return BOTAN_FFI_SUCCESS;
23✔
46
      } else {
47
         return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
48
      }
49
   });
46✔
50
}
51

52
int botan_privkey_load(
51✔
53
   botan_privkey_t* key, botan_rng_t rng_obj, const uint8_t bits[], size_t len, const char* password) {
54
   BOTAN_UNUSED(rng_obj);
51✔
55

56
   *key = nullptr;
51✔
57

58
   return ffi_guard_thunk(__func__, [=]() -> int {
51✔
59
      Botan::DataSource_Memory src(bits, len);
51✔
60

61
      std::unique_ptr<Botan::Private_Key> pkcs8;
51✔
62

63
      if(password == nullptr) {
51✔
64
         pkcs8 = Botan::PKCS8::load_key(src);
22✔
65
      } else {
66
         pkcs8 = Botan::PKCS8::load_key(src, std::string(password));
35✔
67
      }
68

69
      if(pkcs8) {
51✔
70
         *key = new botan_privkey_struct(std::move(pkcs8));
51✔
71
         return BOTAN_FFI_SUCCESS;
51✔
72
      }
73
      return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
74
   });
153✔
75
}
76

77
int botan_privkey_destroy(botan_privkey_t key) { return BOTAN_FFI_CHECKED_DELETE(key); }
95✔
78

79
int botan_pubkey_load(botan_pubkey_t* key, const uint8_t bits[], size_t bits_len) {
12✔
80
   *key = nullptr;
12✔
81

82
   return ffi_guard_thunk(__func__, [=]() -> int {
12✔
83
      Botan::DataSource_Memory src(bits, bits_len);
12✔
84
      std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(src));
12✔
85

86
      if(pubkey == nullptr)
12✔
87
         return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
88

89
      *key = new botan_pubkey_struct(std::move(pubkey));
12✔
90
      return BOTAN_FFI_SUCCESS;
12✔
91
   });
36✔
92
}
93

94
int botan_pubkey_destroy(botan_pubkey_t key) { return BOTAN_FFI_CHECKED_DELETE(key); }
57✔
95

96
int botan_privkey_export_pubkey(botan_pubkey_t* pubout, botan_privkey_t key_obj) {
27✔
97
   return ffi_guard_thunk(__func__, [=]() -> int {
27✔
98
      auto public_key = safe_get(key_obj).public_key();
27✔
99
      *pubout = new botan_pubkey_struct(std::move(public_key));
27✔
100
      return BOTAN_FFI_SUCCESS;
27✔
101
   });
54✔
102
}
103

104
int botan_privkey_algo_name(botan_privkey_t key, char out[], size_t* out_len) {
2✔
105
   return BOTAN_FFI_VISIT(key, [=](const auto& k) { return write_str_output(out, out_len, k.algo_name()); });
4✔
106
}
107

108
int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len) {
7✔
109
   return BOTAN_FFI_VISIT(key, [=](const auto& k) { return write_str_output(out, out_len, k.algo_name()); });
14✔
110
}
111

112
int botan_pubkey_check_key(botan_pubkey_t key, botan_rng_t rng, uint32_t flags) {
25✔
113
   const bool strong = (flags & BOTAN_CHECK_KEY_EXPENSIVE_TESTS);
25✔
114

115
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
50✔
116
      return (k.check_key(safe_get(rng), strong) == true) ? 0 : BOTAN_FFI_ERROR_INVALID_INPUT;
117
   });
118
}
119

120
int botan_privkey_check_key(botan_privkey_t key, botan_rng_t rng, uint32_t flags) {
14✔
121
   const bool strong = (flags & BOTAN_CHECK_KEY_EXPENSIVE_TESTS);
14✔
122
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
28✔
123
      return (k.check_key(safe_get(rng), strong) == true) ? 0 : BOTAN_FFI_ERROR_INVALID_INPUT;
124
   });
125
}
126

127
int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags) {
44✔
128
   if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER)
44✔
129
      return copy_view_bin(out, out_len, botan_pubkey_view_der, key);
22✔
130
   else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
22✔
131
      return copy_view_str(out, out_len, botan_pubkey_view_pem, key);
22✔
132
   else
133
      return BOTAN_FFI_ERROR_BAD_FLAG;
134
}
135

136
int botan_pubkey_view_der(botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) {
23✔
137
   return BOTAN_FFI_VISIT(
69✔
138
      key, [=](const auto& k) -> int { return invoke_view_callback(view, ctx, Botan::X509::BER_encode(k)); });
139
}
140

141
int botan_pubkey_view_pem(botan_pubkey_t key, botan_view_ctx ctx, botan_view_str_fn view) {
26✔
142
   return BOTAN_FFI_VISIT(
78✔
143
      key, [=](const auto& k) -> int { return invoke_view_callback(view, ctx, Botan::X509::PEM_encode(k)); });
144
}
145

146
int botan_privkey_export(botan_privkey_t key, uint8_t out[], size_t* out_len, uint32_t flags) {
44✔
147
   if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER)
44✔
148
      return copy_view_bin(out, out_len, botan_privkey_view_der, key);
22✔
149
   else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
22✔
150
      return copy_view_str(out, out_len, botan_privkey_view_pem, key);
22✔
151
   else
152
      return BOTAN_FFI_ERROR_BAD_FLAG;
153
}
154

155
int botan_privkey_view_der(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) {
27✔
156
   return BOTAN_FFI_VISIT(
81✔
157
      key, [=](const auto& k) -> int { return invoke_view_callback(view, ctx, Botan::PKCS8::BER_encode(k)); });
158
}
159

160
int botan_privkey_view_pem(botan_privkey_t key, botan_view_ctx ctx, botan_view_str_fn view) {
34✔
161
   return BOTAN_FFI_VISIT(
102✔
162
      key, [=](const auto& k) -> int { return invoke_view_callback(view, ctx, Botan::PKCS8::PEM_encode(k)); });
163
}
164

165
int botan_privkey_export_encrypted(botan_privkey_t key,
×
166
                                   uint8_t out[],
167
                                   size_t* out_len,
168
                                   botan_rng_t rng_obj,
169
                                   const char* pass,
170
                                   const char* /*ignored - pbe*/,
171
                                   uint32_t flags) {
172
   return botan_privkey_export_encrypted_pbkdf_iter(key, out, out_len, rng_obj, pass, 100000, nullptr, nullptr, flags);
×
173
}
174

175
int botan_privkey_export_encrypted_pbkdf_msec(botan_privkey_t key,
11✔
176
                                              uint8_t out[],
177
                                              size_t* out_len,
178
                                              botan_rng_t rng,
179
                                              const char* passphrase,
180
                                              uint32_t pbkdf_msec,
181
                                              size_t* pbkdf_iters_out,
182
                                              const char* cipher,
183
                                              const char* pbkdf_hash,
184
                                              uint32_t flags) {
185
   if(pbkdf_iters_out)
11✔
186
      *pbkdf_iters_out = 0;
11✔
187

188
   if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER) {
11✔
189
      return copy_view_bin(
11✔
190
         out, out_len, botan_privkey_view_encrypted_der_timed, key, rng, passphrase, cipher, pbkdf_hash, pbkdf_msec);
11✔
191
   } else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM) {
×
192
      return copy_view_str(
×
193
         out, out_len, botan_privkey_view_encrypted_pem_timed, key, rng, passphrase, cipher, pbkdf_hash, pbkdf_msec);
×
194
   } else {
195
      return BOTAN_FFI_ERROR_BAD_FLAG;
196
   }
197
}
198

199
int botan_privkey_view_encrypted_der_timed(botan_privkey_t key,
14✔
200
                                           botan_rng_t rng_obj,
201
                                           const char* passphrase,
202
                                           const char* maybe_cipher,
203
                                           const char* maybe_pbkdf_algo,
204
                                           size_t pbkdf_runtime_msec,
205
                                           botan_view_ctx ctx,
206
                                           botan_view_bin_fn view) {
207
   if(passphrase == nullptr)
14✔
208
      return BOTAN_FFI_ERROR_NULL_POINTER;
209

210
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
67✔
211
      const std::chrono::milliseconds pbkdf_time(pbkdf_runtime_msec);
212
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
213

214
      const std::string cipher = (maybe_cipher ? maybe_cipher : "");
215
      const std::string pbkdf_algo = (maybe_pbkdf_algo ? maybe_pbkdf_algo : "");
216

217
      auto pkcs8 =
218
         Botan::PKCS8::BER_encode_encrypted_pbkdf_msec(k, rng, passphrase, pbkdf_time, nullptr, cipher, pbkdf_algo);
219

220
      return invoke_view_callback(view, ctx, pkcs8);
221
   });
222
}
223

224
int botan_privkey_view_encrypted_pem_timed(botan_privkey_t key,
3✔
225
                                           botan_rng_t rng_obj,
226
                                           const char* passphrase,
227
                                           const char* maybe_cipher,
228
                                           const char* maybe_pbkdf_algo,
229
                                           size_t pbkdf_runtime_msec,
230
                                           botan_view_ctx ctx,
231
                                           botan_view_str_fn view) {
232
   if(passphrase == nullptr)
3✔
233
      return BOTAN_FFI_ERROR_NULL_POINTER;
234

235
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
12✔
236
      const std::chrono::milliseconds pbkdf_time(pbkdf_runtime_msec);
237
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
238

239
      const std::string cipher = (maybe_cipher ? maybe_cipher : "");
240
      const std::string pbkdf_algo = (maybe_pbkdf_algo ? maybe_pbkdf_algo : "");
241

242
      auto pkcs8 =
243
         Botan::PKCS8::PEM_encode_encrypted_pbkdf_msec(k, rng, passphrase, pbkdf_time, nullptr, cipher, pbkdf_algo);
244

245
      return invoke_view_callback(view, ctx, pkcs8);
246
   });
247
}
248

249
int botan_privkey_export_encrypted_pbkdf_iter(botan_privkey_t key,
44✔
250
                                              uint8_t out[],
251
                                              size_t* out_len,
252
                                              botan_rng_t rng,
253
                                              const char* passphrase,
254
                                              size_t pbkdf_iter,
255
                                              const char* cipher,
256
                                              const char* pbkdf_algo,
257
                                              uint32_t flags) {
258
   if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER) {
44✔
259
      return copy_view_bin(
22✔
260
         out, out_len, botan_privkey_view_encrypted_der, key, rng, passphrase, cipher, pbkdf_algo, pbkdf_iter);
22✔
261
   } else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM) {
22✔
262
      return copy_view_str(
22✔
263
         out, out_len, botan_privkey_view_encrypted_pem, key, rng, passphrase, cipher, pbkdf_algo, pbkdf_iter);
22✔
264
   } else {
265
      return BOTAN_FFI_ERROR_BAD_FLAG;
266
   }
267
}
268

269
int botan_privkey_view_encrypted_der(botan_privkey_t key,
22✔
270
                                     botan_rng_t rng_obj,
271
                                     const char* passphrase,
272
                                     const char* maybe_cipher,
273
                                     const char* maybe_pbkdf_algo,
274
                                     size_t maybe_pbkdf_iterations,
275
                                     botan_view_ctx ctx,
276
                                     botan_view_bin_fn view) {
277
   if(passphrase == nullptr)
22✔
278
      return BOTAN_FFI_ERROR_NULL_POINTER;
279

280
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
132✔
281
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
282

283
      const std::string cipher = (maybe_cipher ? maybe_cipher : "");
284
      const std::string pbkdf_algo = (maybe_pbkdf_algo ? maybe_pbkdf_algo : "");
285
      const size_t pbkdf_iter = (maybe_pbkdf_iterations ? maybe_pbkdf_iterations : 100000);
286

287
      auto pkcs8 = Botan::PKCS8::BER_encode_encrypted_pbkdf_iter(k, rng, passphrase, pbkdf_iter, cipher, pbkdf_algo);
288

289
      return invoke_view_callback(view, ctx, pkcs8);
290
   });
291
}
292

293
int botan_privkey_view_encrypted_pem(botan_privkey_t key,
22✔
294
                                     botan_rng_t rng_obj,
295
                                     const char* passphrase,
296
                                     const char* maybe_cipher,
297
                                     const char* maybe_pbkdf_algo,
298
                                     size_t maybe_pbkdf_iterations,
299
                                     botan_view_ctx ctx,
300
                                     botan_view_str_fn view) {
301
   if(passphrase == nullptr)
22✔
302
      return BOTAN_FFI_ERROR_NULL_POINTER;
303

304
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
132✔
305
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
306

307
      const std::string cipher = (maybe_cipher ? maybe_cipher : "");
308
      const std::string pbkdf_algo = (maybe_pbkdf_algo ? maybe_pbkdf_algo : "");
309
      const size_t pbkdf_iter = (maybe_pbkdf_iterations ? maybe_pbkdf_iterations : 100000);
310

311
      auto pkcs8 = Botan::PKCS8::PEM_encode_encrypted_pbkdf_iter(k, rng, passphrase, pbkdf_iter, cipher, pbkdf_algo);
312

313
      return invoke_view_callback(view, ctx, pkcs8);
314
   });
315
}
316

317
int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estimate) {
14✔
318
   return BOTAN_FFI_VISIT(key, [=](const auto& k) { *estimate = k.estimated_strength(); });
28✔
319
}
320

321
int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash_fn, uint8_t out[], size_t* out_len) {
22✔
322
   return BOTAN_FFI_VISIT(key, [=](const auto& k) {
132✔
323
      auto h = Botan::HashFunction::create_or_throw(hash_fn);
324
      return write_vec_output(out, out_len, h->process(k.public_key_bits()));
325
   });
326
}
327

328
int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len) {
2✔
329
#if defined(BOTAN_HAS_HASH_ID)
330
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
331
      const std::vector<uint8_t> hash_id = Botan::pkcs_hash_id(hash_name);
2✔
332
      return write_output(pkcs_id, pkcs_id_len, hash_id.data(), hash_id.size());
2✔
333
   });
4✔
334
#else
335
   BOTAN_UNUSED(hash_name, pkcs_id, pkcs_id_len);
336
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
337
#endif
338
}
339
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc