Botan 3.11.0
Crypto and TLS for C&
ffi_cert.cpp
Go to the documentation of this file.
1/*
2* (C) 2015,2017,2018 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/assert.h>
10#include <botan/internal/ffi_cert.h>
11#include <botan/internal/ffi_pkey.h>
12#include <botan/internal/ffi_rng.h>
13#include <botan/internal/ffi_util.h>
14#include <memory>
15
16#if defined(BOTAN_HAS_X509_CERTIFICATES)
17 #include <botan/data_src.h>
18 #include <botan/x509_crl.h>
19 #include <botan/x509_ext.h>
20 #include <botan/x509cert.h>
21 #include <botan/x509path.h>
22 #include <botan/internal/ffi_mp.h>
23 #include <botan/internal/ffi_oid.h>
24 #include <botan/internal/loadstor.h>
25 #include <botan/internal/stl_util.h>
26#endif
27
28#if defined(BOTAN_HAS_X509_CERTIFICATES)
29
30namespace Botan_FFI {
31
32namespace {
33
34/**
35 * As specified in RFC 5280 Section 4.2.1.6. alternative names essentially are a
36 * collection of GeneralNames. This allows mapping a single entry of @p altnames
37 * to a GeneralName by its @p index. If the index is out of range, std::nullopt
38 * is returned.
39 *
40 * NOTE: if the set of alternative name types handled here is extended,
41 * count_general_names_in() must be updated accordingly!
42 */
43std::optional<Botan::GeneralName> extract_general_name_at(const Botan::AlternativeName& altnames, size_t index) {
44 if(index < altnames.email().size()) {
45 auto itr = altnames.email().begin();
46 std::advance(itr, index);
47 return Botan::GeneralName::email(*itr);
48 }
49 index -= altnames.email().size();
50
51 if(index < altnames.dns().size()) {
52 auto itr = altnames.dns().begin();
53 std::advance(itr, index);
54 return Botan::GeneralName::dns(*itr);
55 }
56 index -= altnames.dns().size();
57
58 if(index < altnames.directory_names().size()) {
59 auto itr = altnames.directory_names().begin();
60 std::advance(itr, index);
62 }
63 index -= altnames.directory_names().size();
64
65 if(index < altnames.uris().size()) {
66 auto itr = altnames.uris().begin();
67 std::advance(itr, index);
68 return Botan::GeneralName::uri(*itr);
69 }
70 index -= altnames.uris().size();
71
72 if(index < altnames.ipv4_address().size()) {
73 auto itr = altnames.ipv4_address().begin();
74 std::advance(itr, index);
76 }
77
78 return std::nullopt;
79}
80
81/**
82 * Counts the total number of GeneralNames contained in the given
83 * AlternativeName @p alt_names.
84 *
85 * NOTE: if the set of alternative name types handled here is extended,
86 * extract_general_name_at() must be updated accordingly!
87 */
88size_t count_general_names_in(const Botan::AlternativeName& alt_names) {
89 return alt_names.email().size() + alt_names.dns().size() + alt_names.directory_names().size() +
90 alt_names.uris().size() + alt_names.ipv4_address().size();
91}
92
93std::optional<botan_x509_general_name_types> to_botan_x509_general_name_types(Botan::GeneralName::NameType gn_type) {
95 switch(gn_type) {
96 case Type::Unknown:
97 return std::nullopt;
98 case Type::RFC822:
100 case Type::DNS:
101 return BOTAN_X509_DNS_NAME;
102 case Type::URI:
103 return BOTAN_X509_URI;
104 case Type::DN:
106 case Type::IPv4:
108 case Type::Other:
110 }
111
113}
114
115/**
116 * Given some enumerator-style function @p fn, count how many values it can
117 * produce before returning BOTAN_FFI_ERROR_OUT_OF_RANGE. If the first call to
118 * @p fn returns BOTAN_FFI_ERROR_NO_VALUE, zero is written to @p count.
119 *
120 * If this function returns BOTAN_FFI_SUCCESS, @p count contains the number of
121 * values that can be enumerated. Otherwise, the value of @p count is undefined.
122 */
123template <std::invocable<size_t> EnumeratorT>
124int enumerator_count_values(size_t* count, EnumeratorT fn) {
125 if(Botan::any_null_pointers(count)) {
127 }
128
129 *count = 0;
130 for(;; ++(*count)) {
131 const auto rc = fn(*count);
132 switch(rc) {
135 // hit the end of the enumeration
136 return BOTAN_FFI_SUCCESS;
138 // got a value, continue counting
139 break;
140 default:
141 // unexpected error from enumerator function
142 return rc;
143 }
144 }
145}
146
147std::chrono::system_clock::time_point timepoint_from_timestamp(uint64_t time_since_epoch) {
148 return std::chrono::system_clock::time_point(std::chrono::seconds(time_since_epoch));
149}
150
151std::string default_from_ptr(const char* value) {
152 std::string ret;
153 if(value != nullptr) {
154 ret = value;
155 }
156 return ret;
157}
158
159} // namespace
160
161} // namespace Botan_FFI
162
163#endif
164
165extern "C" {
166
167using namespace Botan_FFI;
168
169int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* cert_path) {
170 if(cert_obj == nullptr || cert_path == nullptr) {
172 }
173
174#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
175
176 return ffi_guard_thunk(__func__, [=]() -> int {
177 auto c = std::make_unique<Botan::X509_Certificate>(cert_path);
178 return ffi_new_object(cert_obj, std::move(c));
179 });
180
181#else
183#endif
184}
185
187 if(cert_obj == nullptr) {
189 }
190
191#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
192
193 return ffi_guard_thunk(__func__, [=]() -> int {
194 auto c = std::make_unique<Botan::X509_Certificate>(safe_get(cert));
195 return ffi_new_object(cert_obj, std::move(c));
196 });
197
198#else
199 BOTAN_UNUSED(cert);
201#endif
202}
203
204int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert_bits[], size_t cert_bits_len) {
205 if(cert_obj == nullptr || cert_bits == nullptr) {
207 }
208
209#if defined(BOTAN_HAS_X509_CERTIFICATES)
210 return ffi_guard_thunk(__func__, [=]() -> int {
211 Botan::DataSource_Memory bits(cert_bits, cert_bits_len);
212 auto c = std::make_unique<Botan::X509_Certificate>(bits);
213 return ffi_new_object(cert_obj, std::move(c));
214 });
215#else
216 BOTAN_UNUSED(cert_bits_len);
218#endif
219}
220}
221
222namespace {
223
224#if defined(BOTAN_HAS_X509_CERTIFICATES)
225
226int botan_x509_object_view_value(const Botan::X509_Object& object,
227 botan_x509_value_type value_type,
228 size_t index,
229 botan_view_ctx ctx,
230 botan_view_str_fn view_fn) {
231 if(index != 0) {
232 // As of now there are no multi-value generic string entries.
234 }
235
236 auto view = [=](const std::string& value) { return invoke_view_callback(view_fn, ctx, value); };
237
238 switch(value_type) {
240 return view(object.PEM_encode());
241 default:
242 BOTAN_ASSERT_UNREACHABLE(); /* called with unexpected (non-generic) value_type */
243 }
244}
245
246int botan_x509_object_view_value(const Botan::X509_Object& object,
247 botan_x509_value_type value_type,
248 size_t index,
249 botan_view_ctx ctx,
250 botan_view_bin_fn view_fn) {
251 if(index != 0) {
252 // As of now there are no multi-value generic binary entries.
254 }
255
256 auto view = [=](std::span<const uint8_t> value) { return invoke_view_callback(view_fn, ctx, value); };
257
258 switch(value_type) {
260 return view(object.tbs_data());
262 return view(object.signature_algorithm().BER_encode());
264 return view(object.signature());
266 return view(object.BER_encode());
267 default:
268 BOTAN_ASSERT_UNREACHABLE(); /* called with unexpected (non-generic) value_type */
269 }
270}
271
272#endif
273
274} // namespace
275
276extern "C" {
277
279 botan_x509_value_type value_type,
280 size_t index,
281 botan_view_ctx ctx,
282 botan_view_bin_fn view_fn) {
283#if defined(BOTAN_HAS_X509_CERTIFICATES)
284 if(index != 0) {
285 // As of now there are no multi-value binary entries.
287 }
288
289 auto view = [=](std::span<const uint8_t> value) -> int {
290 if(value.empty()) {
292 } else {
293 return invoke_view_callback(view_fn, ctx, value);
294 }
295 };
296
297 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) -> int {
298 switch(value_type) {
300 return view(c.serial_number());
302 return view(c.raw_subject_dn());
304 return view(c.raw_issuer_dn());
306 return view(c.subject_key_id());
308 return view(c.authority_key_id());
310 return view(c.subject_public_key_info());
311
316 return botan_x509_object_view_value(c, value_type, index, ctx, view_fn);
317
323 }
324
326 });
327#else
328 BOTAN_UNUSED(cert, value_type, index, ctx, view_fn);
330#endif
331}
332
334#if defined(BOTAN_HAS_X509_CERTIFICATES)
335 return enumerator_count_values(count, [=](size_t index) {
337 cert, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
338 });
339#else
340 BOTAN_UNUSED(cert, value_type, count);
342#endif
343}
344
346 botan_x509_value_type value_type,
347 size_t index,
348 botan_view_ctx ctx,
349 botan_view_str_fn view_fn) {
350#if defined(BOTAN_HAS_X509_CERTIFICATES)
351 auto enumerate = [view_fn, ctx](auto values, size_t idx) -> int {
352 if(idx >= values.size()) {
354 } else {
355 return invoke_view_callback(view_fn, ctx, values[idx]);
356 }
357 };
358
359 auto enumerate_crl_distribution_points = [view_fn, ctx](const Botan::X509_Certificate& c, size_t idx) -> int {
360 const auto* crl_dp_ext =
361 c.v3_extensions().get_extension_object_as<Botan::Cert_Extension::CRL_Distribution_Points>();
362 if(crl_dp_ext == nullptr) {
363 return BOTAN_FFI_ERROR_OUT_OF_RANGE; // essentially an empty list
364 }
365
366 const auto& dps = crl_dp_ext->distribution_points();
367 for(size_t i = idx; const auto& dp : dps) {
368 const auto& uris = dp.point().uris();
369 if(i >= uris.size()) {
370 i -= uris.size();
371 continue;
372 }
373
374 auto itr = uris.begin();
375 std::advance(itr, i);
376 return invoke_view_callback(view_fn, ctx, *itr);
377 }
378
380 };
381
382 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) -> int {
383 switch(value_type) {
385 return enumerate_crl_distribution_points(c, index);
387 return enumerate(c.ocsp_responders(), index);
389 return enumerate(c.ca_issuers(), index);
391 return botan_x509_object_view_value(c, value_type, index, ctx, view_fn);
392
404 }
405
407 });
408#else
409 BOTAN_UNUSED(cert, value_type, index, ctx, view_fn);
411#endif
412}
413
415#if defined(BOTAN_HAS_X509_CERTIFICATES)
416 return enumerator_count_values(count, [=](size_t index) {
418 cert, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
419 });
420#else
421 BOTAN_UNUSED(cert, value_type, count);
423#endif
424}
425
427#if defined(BOTAN_HAS_X509_CERTIFICATES)
428 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return c.is_CA_cert() ? 1 : 0; });
429#else
430 BOTAN_UNUSED(cert);
432#endif
433}
434
436#if defined(BOTAN_HAS_X509_CERTIFICATES)
437 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
438 if(Botan::any_null_pointers(path_limit)) {
440 }
441
442 if(const auto path_len = c.path_length_constraint()) {
443 *path_limit = path_len.value();
444 return BOTAN_FFI_SUCCESS;
445 } else {
447 }
448 });
449#else
450 BOTAN_UNUSED(cert, path_limit);
452#endif
453}
454
456 if(key == nullptr) {
458 }
459
460 *key = nullptr;
461
462#if defined(BOTAN_HAS_X509_CERTIFICATES)
463 return ffi_guard_thunk(__func__, [=]() -> int {
464 auto public_key = safe_get(cert).subject_public_key();
465 return ffi_new_object(key, std::move(public_key));
466 });
467#else
468 BOTAN_UNUSED(cert);
470#endif
471}
472
474 botan_x509_cert_t cert, const char* key, size_t index, uint8_t out[], size_t* out_len) {
475#if defined(BOTAN_HAS_X509_CERTIFICATES)
476 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
477 auto issuer_info = c.issuer_info(key);
478 if(index < issuer_info.size()) {
479 // TODO(Botan4) change the type of out and remove this cast
480 return write_str_output(reinterpret_cast<char*>(out), out_len, c.issuer_info(key).at(index));
481 } else {
482 return BOTAN_FFI_ERROR_BAD_PARAMETER; // TODO(Botan4): use BOTAN_FFI_ERROR_OUT_OF_RANGE
483 }
484 });
485#else
486 BOTAN_UNUSED(cert, key, index, out, out_len);
488#endif
489}
490
491int botan_x509_cert_get_issuer_dn_count(botan_x509_cert_t cert, const char* key, size_t* count) {
492#if defined(BOTAN_HAS_X509_CERTIFICATES)
493 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
494 if(Botan::any_null_pointers(count)) {
496 }
497
498 *count = c.issuer_info(key).size();
499 return BOTAN_FFI_SUCCESS;
500 });
501#else
502 BOTAN_UNUSED(cert, key, count);
504#endif
505}
506
508 botan_x509_cert_t cert, const char* key, size_t index, uint8_t out[], size_t* out_len) {
509#if defined(BOTAN_HAS_X509_CERTIFICATES)
510 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
511 auto subject_info = c.subject_info(key);
512 if(index < subject_info.size()) {
513 // TODO(Botan4) change the type of out and remove this cast
514 return write_str_output(reinterpret_cast<char*>(out), out_len, c.subject_info(key).at(index));
515 } else {
516 return BOTAN_FFI_ERROR_BAD_PARAMETER; // TODO(Botan4): use BOTAN_FFI_ERROR_OUT_OF_RANGE
517 }
518 });
519#else
520 BOTAN_UNUSED(cert, key, index, out, out_len);
522#endif
523}
524
525int botan_x509_cert_get_subject_dn_count(botan_x509_cert_t cert, const char* key, size_t* count) {
526#if defined(BOTAN_HAS_X509_CERTIFICATES)
527 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
528 if(Botan::any_null_pointers(count)) {
530 }
531
532 *count = c.subject_info(key).size();
533 return BOTAN_FFI_SUCCESS;
534 });
535#else
536 BOTAN_UNUSED(cert, key, count);
538#endif
539}
540
541int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len) {
542 return copy_view_str(reinterpret_cast<uint8_t*>(out), out_len, botan_x509_cert_view_as_string, cert);
543}
544
546#if defined(BOTAN_HAS_X509_CERTIFICATES)
547 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return invoke_view_callback(view, ctx, c.to_string()); });
548#else
549 BOTAN_UNUSED(cert, ctx, view);
551#endif
552}
553
554int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage) {
555#if defined(BOTAN_HAS_X509_CERTIFICATES)
556 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
557 const Botan::Key_Constraints k = static_cast<Botan::Key_Constraints>(key_usage);
558 if(c.allowed_usage(k)) {
559 return BOTAN_FFI_SUCCESS;
560 }
561 return 1;
562 });
563#else
564 BOTAN_UNUSED(cert, key_usage);
566#endif
567}
568
570#if defined(BOTAN_HAS_X509_CERTIFICATES)
571 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
572 if(Botan::any_null_pointers(oid)) {
574 }
575
576 return c.has_ex_constraint(oid) ? 1 : 0;
577 });
578#else
579 BOTAN_UNUSED(cert, oid);
581#endif
582}
583
585#if defined(BOTAN_HAS_X509_CERTIFICATES)
586 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int { return c.has_ex_constraint(safe_get(oid)) ? 1 : 0; });
587#else
588 BOTAN_UNUSED(cert, oid);
590#endif
591}
592
594#if defined(BOTAN_HAS_X509_CERTIFICATES)
595 return BOTAN_FFI_CHECKED_DELETE(cert);
596#else
597 BOTAN_UNUSED(cert);
599#endif
600}
601
602int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len) {
603#if defined(BOTAN_HAS_X509_CERTIFICATES)
604 return BOTAN_FFI_VISIT(cert,
605 [=](const auto& c) { return write_str_output(out, out_len, c.not_before().to_string()); });
606#else
607 BOTAN_UNUSED(cert, out, out_len);
609#endif
610}
611
612int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len) {
613#if defined(BOTAN_HAS_X509_CERTIFICATES)
614 return BOTAN_FFI_VISIT(cert,
615 [=](const auto& c) { return write_str_output(out, out_len, c.not_after().to_string()); });
616#else
617 BOTAN_UNUSED(cert, out, out_len);
619#endif
620}
621
622int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t* time_since_epoch) {
623#if defined(BOTAN_HAS_X509_CERTIFICATES)
624 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *time_since_epoch = c.not_before().time_since_epoch(); });
625#else
626 BOTAN_UNUSED(cert, time_since_epoch);
628#endif
629}
630
631int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t* time_since_epoch) {
632#if defined(BOTAN_HAS_X509_CERTIFICATES)
633 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *time_since_epoch = c.not_after().time_since_epoch(); });
634#else
635 BOTAN_UNUSED(cert, time_since_epoch);
637#endif
638}
639
640int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
641#if defined(BOTAN_HAS_X509_CERTIFICATES)
642 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.serial_number()); });
643#else
644 BOTAN_UNUSED(cert, out, out_len);
646#endif
647}
648
650#if defined(BOTAN_HAS_X509_CERTIFICATES)
651 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
652 if(Botan::any_null_pointers(serial_number)) {
654 }
655
656 auto serial_bn = Botan::BigInt::from_bytes(c.serial_number());
657 return ffi_new_object(serial_number, std::make_unique<Botan::BigInt>(std::move(serial_bn)));
658 });
659#else
660 BOTAN_UNUSED(cert, serial_number);
662#endif
663}
664
665int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len) {
666#if defined(BOTAN_HAS_X509_CERTIFICATES)
667 // TODO(Botan4) change the type of out and remove this cast
668
669 return BOTAN_FFI_VISIT(cert, [=](const auto& c) {
670 return write_str_output(reinterpret_cast<char*>(out), out_len, c.fingerprint(hash));
671 });
672#else
673 BOTAN_UNUSED(cert, hash, out, out_len);
675#endif
676}
677
678int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
679#if defined(BOTAN_HAS_X509_CERTIFICATES)
680 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.authority_key_id()); });
681#else
682 BOTAN_UNUSED(cert, out, out_len);
684#endif
685}
686
687int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
688#if defined(BOTAN_HAS_X509_CERTIFICATES)
689 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.subject_key_id()); });
690#else
691 BOTAN_UNUSED(cert, out, out_len);
693#endif
694}
695
696int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
697 return copy_view_bin(out, out_len, botan_x509_cert_view_public_key_bits, cert);
698}
699
701#if defined(BOTAN_HAS_X509_CERTIFICATES)
702 return BOTAN_FFI_VISIT(cert,
703 [=](const auto& c) { return invoke_view_callback(view, ctx, c.subject_public_key_bits()); });
704#else
705 BOTAN_UNUSED(cert, ctx, view);
707#endif
708}
709
711#if defined(BOTAN_HAS_X509_CERTIFICATES)
712 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) {
713 if(Botan::any_null_pointers(type)) {
715 }
716
717 const auto mapped_type = to_botan_x509_general_name_types(n.type_code());
718 if(!mapped_type.has_value()) {
720 }
721
722 *type = mapped_type.value();
723 if(*type == BOTAN_X509_OTHER_NAME /* ... viewing of other-names not supported */) {
725 }
726
727 return BOTAN_FFI_SUCCESS;
728 });
729#else
730 BOTAN_UNUSED(name, type);
732#endif
733}
734
736 botan_view_ctx ctx,
737 botan_view_str_fn view) {
738#if defined(BOTAN_HAS_X509_CERTIFICATES)
739 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) -> int {
740 const auto type = to_botan_x509_general_name_types(n.type_code());
741 if(!type) {
743 }
744
745 if(type != BOTAN_X509_EMAIL_ADDRESS && type != BOTAN_X509_DNS_NAME && type != BOTAN_X509_URI &&
746 type != BOTAN_X509_IP_ADDRESS) {
748 }
749
750 return invoke_view_callback(view, ctx, n.name());
751 });
752#else
753 BOTAN_UNUSED(name, ctx, view);
755#endif
756}
757
759 botan_view_ctx ctx,
760 botan_view_bin_fn view) {
761#if defined(BOTAN_HAS_X509_CERTIFICATES)
762 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) -> int {
763 const auto type = to_botan_x509_general_name_types(n.type_code());
764 if(!type) {
766 }
767
768 if(type != BOTAN_X509_DIRECTORY_NAME && type != BOTAN_X509_IP_ADDRESS) {
770 }
771
772 return invoke_view_callback(view, ctx, n.binary_name());
773 });
774#else
775 BOTAN_UNUSED(name, ctx, view);
777#endif
778}
779
781#if defined(BOTAN_HAS_X509_CERTIFICATES)
782 return BOTAN_FFI_CHECKED_DELETE(name);
783#else
784 BOTAN_UNUSED(name);
786#endif
787}
788
790 size_t index,
791 botan_x509_general_name_t* constraint) {
792#if defined(BOTAN_HAS_X509_CERTIFICATES)
793 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
794 if(Botan::any_null_pointers(constraint)) {
796 }
797
798 const auto& constraints = c.name_constraints().permitted();
799 if(index >= constraints.size()) {
801 }
802
803 return ffi_new_object(constraint, std::make_unique<Botan::GeneralName>(constraints[index].base()));
804 });
805#else
806 BOTAN_UNUSED(cert, index, constraint);
808#endif
809}
810
812#if defined(BOTAN_HAS_X509_CERTIFICATES)
813 if(Botan::any_null_pointers(count)) {
815 }
816
817 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *count = c.name_constraints().permitted().size(); });
818#else
819 BOTAN_UNUSED(cert, count);
821#endif
822}
823
825 size_t index,
826 botan_x509_general_name_t* constraint) {
827#if defined(BOTAN_HAS_X509_CERTIFICATES)
828 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
829 if(Botan::any_null_pointers(constraint)) {
831 }
832
833 const auto& constraints = c.name_constraints().excluded();
834 if(index >= constraints.size()) {
836 }
837
838 return ffi_new_object(constraint, std::make_unique<Botan::GeneralName>(constraints[index].base()));
839 });
840#else
841 BOTAN_UNUSED(cert, index, constraint);
843#endif
844}
845
847#if defined(BOTAN_HAS_X509_CERTIFICATES)
848 if(Botan::any_null_pointers(count)) {
850 }
851
852 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *count = c.name_constraints().excluded().size(); });
853#else
854 BOTAN_UNUSED(cert, count);
856#endif
857}
858
860 size_t index,
861 botan_x509_general_name_t* alt_name) {
862#if defined(BOTAN_HAS_X509_CERTIFICATES)
863 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
864 if(Botan::any_null_pointers(alt_name)) {
866 }
867
868 if(!c.v3_extensions().extension_set(Botan::OID::from_string("X509v3.SubjectAlternativeName"))) {
870 }
871
872 if(auto name = extract_general_name_at(c.subject_alt_name(), index)) {
873 return ffi_new_object(alt_name, std::make_unique<Botan::GeneralName>(std::move(name).value()));
874 }
875
877 });
878#else
879 BOTAN_UNUSED(cert, index, alt_name);
881#endif
882}
883
885#if defined(BOTAN_HAS_X509_CERTIFICATES)
886 if(Botan::any_null_pointers(count)) {
888 }
889
890 return BOTAN_FFI_VISIT(
891 cert, [=](const Botan::X509_Certificate& c) { *count = count_general_names_in(c.subject_alt_name()); });
892#else
893 BOTAN_UNUSED(cert, count);
895#endif
896}
897
899 size_t index,
900 botan_x509_general_name_t* alt_name) {
901#if defined(BOTAN_HAS_X509_CERTIFICATES)
902 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
903 if(Botan::any_null_pointers(alt_name)) {
905 }
906
907 if(!c.v3_extensions().extension_set(Botan::OID::from_string("X509v3.IssuerAlternativeName"))) {
909 }
910
911 if(auto name = extract_general_name_at(c.issuer_alt_name(), index)) {
912 return ffi_new_object(alt_name, std::make_unique<Botan::GeneralName>(std::move(name).value()));
913 }
914
916 });
917#else
918 BOTAN_UNUSED(cert, index, alt_name);
920#endif
921}
922
924#if defined(BOTAN_HAS_X509_CERTIFICATES)
925 if(Botan::any_null_pointers(count)) {
927 }
928
929 return BOTAN_FFI_VISIT(
930 cert, [=](const Botan::X509_Certificate& c) { *count = count_general_names_in(c.issuer_alt_name()); });
931#else
932 BOTAN_UNUSED(cert, count);
934#endif
935}
936
937int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char* hostname) {
938 if(hostname == nullptr) {
940 }
941
942#if defined(BOTAN_HAS_X509_CERTIFICATES)
943 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return c.matches_dns_name(hostname) ? 0 : -1; });
944#else
945 BOTAN_UNUSED(cert);
947#endif
948}
949
950int botan_x509_cert_verify(int* result_code,
952 const botan_x509_cert_t* intermediates,
953 size_t intermediates_len,
954 const botan_x509_cert_t* trusted,
955 size_t trusted_len,
956 const char* trusted_path,
957 size_t required_strength,
958 const char* hostname_cstr,
959 uint64_t reference_time) {
960 if(required_strength == 0) {
961 required_strength = 110;
962 }
963
964#if defined(BOTAN_HAS_X509_CERTIFICATES)
965 return ffi_guard_thunk(__func__, [=]() -> int {
966 const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);
968 const auto validation_time = reference_time == 0
969 ? std::chrono::system_clock::now()
970 : std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));
971
972 std::vector<Botan::X509_Certificate> end_certs;
973 end_certs.push_back(safe_get(cert));
974 for(size_t i = 0; i != intermediates_len; ++i) {
975 end_certs.push_back(safe_get(intermediates[i]));
976 }
977
978 std::unique_ptr<Botan::Certificate_Store> trusted_from_path;
979 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra;
980 std::vector<Botan::Certificate_Store*> trusted_roots;
981
982 if(trusted_path != nullptr && *trusted_path != 0) {
983 trusted_from_path = std::make_unique<Botan::Certificate_Store_In_Memory>(trusted_path);
984 trusted_roots.push_back(trusted_from_path.get());
985 }
986
987 if(trusted_len > 0) {
988 trusted_extra = std::make_unique<Botan::Certificate_Store_In_Memory>();
989 for(size_t i = 0; i != trusted_len; ++i) {
990 trusted_extra->add_certificate(safe_get(trusted[i]));
991 }
992 trusted_roots.push_back(trusted_extra.get());
993 }
994
995 const Botan::Path_Validation_Restrictions restrictions(false, required_strength);
996
997 auto validation_result =
998 Botan::x509_path_validate(end_certs, restrictions, trusted_roots, hostname, usage, validation_time);
999
1000 if(result_code != nullptr) {
1001 *result_code = static_cast<int>(validation_result.result());
1002 }
1003
1004 if(validation_result.successful_validation()) {
1005 return 0;
1006 } else {
1007 return 1;
1008 }
1009 });
1010#else
1011 BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);
1012 BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time);
1014#endif
1015}
1016
1018 if(code < 0) {
1019 return nullptr;
1020 }
1021
1022#if defined(BOTAN_HAS_X509_CERTIFICATES)
1024 return Botan::to_string(sc);
1025#else
1026 return nullptr;
1027#endif
1028}
1029
1030int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path) {
1031 if(crl_obj == nullptr || crl_path == nullptr) {
1033 }
1034
1035#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
1036
1037 return ffi_guard_thunk(__func__, [=]() -> int {
1038 auto c = std::make_unique<Botan::X509_CRL>(crl_path);
1039 return ffi_new_object(crl_obj, std::move(c));
1040 });
1041
1042#else
1044#endif
1045}
1046
1047int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len) {
1048 if(crl_obj == nullptr || crl_bits == nullptr) {
1050 }
1051
1052#if defined(BOTAN_HAS_X509_CERTIFICATES)
1053 return ffi_guard_thunk(__func__, [=]() -> int {
1054 Botan::DataSource_Memory bits(crl_bits, crl_bits_len);
1055 auto c = std::make_unique<Botan::X509_CRL>(bits);
1056 return ffi_new_object(crl_obj, std::move(c));
1057 });
1058#else
1059 BOTAN_UNUSED(crl_bits_len);
1061#endif
1062}
1063
1064int botan_x509_crl_this_update(botan_x509_crl_t crl, uint64_t* time_since_epoch) {
1065#if defined(BOTAN_HAS_X509_CERTIFICATES)
1066 return BOTAN_FFI_VISIT(crl, [=](const auto& c) {
1067 if(Botan::any_null_pointers(time_since_epoch)) {
1069 }
1070 *time_since_epoch = c.this_update().time_since_epoch();
1071 return BOTAN_FFI_SUCCESS;
1072 });
1073#else
1074 BOTAN_UNUSED(crl, time_since_epoch);
1076#endif
1077}
1078
1079int botan_x509_crl_next_update(botan_x509_crl_t crl, uint64_t* time_since_epoch) {
1080#if defined(BOTAN_HAS_X509_CERTIFICATES)
1081 return BOTAN_FFI_VISIT(crl, [=](const auto& c) {
1082 const auto& time = c.next_update();
1083 if(!time.time_is_set()) {
1085 }
1086
1087 if(Botan::any_null_pointers(time_since_epoch)) {
1089 }
1090
1091 *time_since_epoch = c.next_update().time_since_epoch();
1092 return BOTAN_FFI_SUCCESS;
1093 });
1094#else
1095 BOTAN_UNUSED(crl, time_since_epoch);
1097#endif
1098}
1099
1101 botan_rng_t rng,
1102 botan_x509_cert_t ca_cert,
1103 botan_privkey_t ca_key,
1104 uint64_t issue_time,
1105 uint32_t next_update,
1106 const char* hash_fn,
1107 const char* padding) {
1108 if(Botan::any_null_pointers(crl_obj)) {
1110 }
1111#if defined(BOTAN_HAS_X509_CERTIFICATES)
1112 return ffi_guard_thunk(__func__, [=]() -> int {
1113 auto& rng_ = safe_get(rng);
1114 auto ca = Botan::X509_CA(
1115 safe_get(ca_cert), safe_get(ca_key), default_from_ptr(hash_fn), default_from_ptr(padding), rng_);
1116 auto crl = std::make_unique<Botan::X509_CRL>(
1117 ca.new_crl(rng_, timepoint_from_timestamp(issue_time), std::chrono::seconds(next_update)));
1118 return ffi_new_object(crl_obj, std::move(crl));
1119 });
1120#else
1121 BOTAN_UNUSED(rng, ca_cert, ca_key, hash_fn, padding, issue_time, next_update);
1123#endif
1124}
1125
1127 if(Botan::any_null_pointers(entry)) {
1129 }
1130#if defined(BOTAN_HAS_X509_CERTIFICATES)
1131 return ffi_guard_thunk(__func__, [=]() -> int {
1132 return ffi_new_object(
1133 entry, std::make_unique<Botan::CRL_Entry>(safe_get(cert), static_cast<Botan::CRL_Code>(reason_code)));
1134 });
1135#else
1136 BOTAN_UNUSED(cert, reason_code);
1138#endif
1139}
1140
1142 botan_x509_crl_t last_crl,
1143 botan_rng_t rng,
1144 botan_x509_cert_t ca_cert,
1145 botan_privkey_t ca_key,
1146 uint64_t issue_time,
1147 uint32_t next_update,
1148 const botan_x509_crl_entry_t* new_entries,
1149 size_t new_entries_len,
1150 const char* hash_fn,
1151 const char* padding) {
1152 if(Botan::any_null_pointers(crl_obj)) {
1154 }
1155 if(new_entries_len > 0 && Botan::any_null_pointers(new_entries)) {
1157 }
1158#if defined(BOTAN_HAS_X509_CERTIFICATES)
1159 return ffi_guard_thunk(__func__, [=]() -> int {
1160 auto& rng_ = safe_get(rng);
1161 auto ca = Botan::X509_CA(
1162 safe_get(ca_cert), safe_get(ca_key), default_from_ptr(hash_fn), default_from_ptr(padding), rng_);
1163
1164 std::vector<Botan::CRL_Entry> entries;
1165 entries.reserve(new_entries_len);
1166 for(size_t i = 0; i < new_entries_len; i++) {
1167 entries.push_back(safe_get(new_entries[i]));
1168 }
1169
1170 auto crl = std::make_unique<Botan::X509_CRL>(ca.update_crl(
1171 safe_get(last_crl), entries, rng_, timepoint_from_timestamp(issue_time), std::chrono::seconds(next_update)));
1172 return ffi_new_object(crl_obj, std::move(crl));
1173 });
1174#else
1176 last_crl, rng, ca_cert, ca_key, hash_fn, padding, issue_time, next_update, new_entries, new_entries_len);
1178#endif
1179}
1180
1182#if defined(BOTAN_HAS_X509_CERTIFICATES)
1183 return BOTAN_FFI_VISIT(crl, [=](const auto& c) -> int { return c.check_signature(safe_get(key)) ? 1 : 0; });
1184#else
1185 BOTAN_UNUSED(crl, key);
1187#endif
1188}
1189
1191#if defined(BOTAN_HAS_X509_CERTIFICATES)
1192 return BOTAN_FFI_CHECKED_DELETE(crl);
1193#else
1194 BOTAN_UNUSED(crl);
1196#endif
1197}
1198
1200 botan_x509_value_type value_type,
1201 size_t index,
1202 botan_view_ctx ctx,
1203 botan_view_bin_fn view_fn) {
1204#if defined(BOTAN_HAS_X509_CERTIFICATES)
1205 if(index != 0) {
1206 // As of now there are no multi-value binary entries.
1208 }
1209
1210 auto view = [=](std::span<const uint8_t> value) -> int {
1211 if(value.empty()) {
1213 } else {
1214 return invoke_view_callback(view_fn, ctx, value);
1215 }
1216 };
1217
1218 return BOTAN_FFI_VISIT(crl_obj, [=](const Botan::X509_CRL& crl) -> int {
1219 switch(value_type) {
1221 return view(Botan::store_be(crl.crl_number()));
1223 return view(Botan::ASN1::put_in_sequence(crl.issuer_dn().get_bits()));
1225 return view(crl.authority_key_id());
1226
1231 return botan_x509_object_view_value(crl, value_type, index, ctx, view_fn);
1232
1241 }
1242
1244 });
1245#else
1246 BOTAN_UNUSED(crl_obj, value_type, index, ctx, view_fn);
1248#endif
1249}
1250
1252#if defined(BOTAN_HAS_X509_CERTIFICATES)
1253 return enumerator_count_values(count, [=](size_t index) {
1255 crl_obj, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
1256 });
1257#else
1258 BOTAN_UNUSED(crl_obj, value_type, count);
1260#endif
1261}
1262
1264 botan_x509_value_type value_type,
1265 size_t index,
1266 botan_view_ctx ctx,
1267 botan_view_str_fn view) {
1268#if defined(BOTAN_HAS_X509_CERTIFICATES)
1269 return BOTAN_FFI_VISIT(crl_obj, [=](const Botan::X509_CRL& crl) -> int {
1270 switch(value_type) {
1272 return botan_x509_object_view_value(crl, value_type, index, ctx, view);
1273
1288 }
1289
1291 });
1292#else
1293 BOTAN_UNUSED(crl_obj, value_type, index, ctx, view);
1295#endif
1296}
1297
1299#if defined(BOTAN_HAS_X509_CERTIFICATES)
1300 return enumerator_count_values(count, [=](size_t index) {
1302 crl_obj, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
1303 });
1304#else
1305 BOTAN_UNUSED(crl_obj, value_type, count);
1307#endif
1308}
1309
1311#if defined(BOTAN_HAS_X509_CERTIFICATES)
1312 return BOTAN_FFI_VISIT(crl, [=](const auto& c) { return c.is_revoked(safe_get(cert)) ? 0 : -1; });
1313#else
1314 BOTAN_UNUSED(cert);
1315 BOTAN_UNUSED(crl);
1317#endif
1318}
1319
1321#if defined(BOTAN_HAS_X509_CERTIFICATES)
1322 return BOTAN_FFI_VISIT(crl, [=](const Botan::X509_CRL& c) -> int {
1323 const auto& entries = c.get_revoked();
1324 if(index >= entries.size()) {
1326 }
1327
1328 if(Botan::any_null_pointers(entry)) {
1330 }
1331
1332 return ffi_new_object(entry, std::make_unique<Botan::CRL_Entry>(entries[index]));
1333 });
1334#else
1335 BOTAN_UNUSED(crl, index, entry);
1337#endif
1338}
1339
1341#if defined(BOTAN_HAS_X509_CERTIFICATES)
1342 if(Botan::any_null_pointers(count)) {
1344 }
1345
1346 return BOTAN_FFI_VISIT(crl, [=](const Botan::X509_CRL& c) { *count = c.get_revoked().size(); });
1347#else
1348 BOTAN_UNUSED(crl, count);
1350#endif
1351}
1352
1354#if defined(BOTAN_HAS_X509_CERTIFICATES)
1355 return BOTAN_FFI_CHECKED_DELETE(entry);
1356#else
1357 BOTAN_UNUSED(entry);
1359#endif
1360}
1361
1363#if defined(BOTAN_HAS_X509_CERTIFICATES)
1364 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1365 if(Botan::any_null_pointers(reason_code)) {
1367 }
1368
1369 *reason_code = static_cast<int>(e.reason_code());
1370 return BOTAN_FFI_SUCCESS;
1371 });
1372#else
1373 BOTAN_UNUSED(entry, reason_code);
1375#endif
1376}
1377
1379#if defined(BOTAN_HAS_X509_CERTIFICATES)
1380 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1381 if(Botan::any_null_pointers(serial_number)) {
1383 }
1384
1385 auto serial_bn = Botan::BigInt::from_bytes(e.serial_number());
1386 return ffi_new_object(serial_number, std::make_unique<Botan::BigInt>(std::move(serial_bn)));
1387 });
1388#else
1389 BOTAN_UNUSED(entry, serial_number);
1391#endif
1392}
1393
1395#if defined(BOTAN_HAS_X509_CERTIFICATES)
1396 return BOTAN_FFI_VISIT(
1397 entry, [=](const Botan::CRL_Entry& e) { return invoke_view_callback(view, ctx, e.serial_number()); });
1398#else
1399 BOTAN_UNUSED(entry, ctx, view);
1401#endif
1402}
1403
1404int botan_x509_crl_entry_revocation_date(botan_x509_crl_entry_t entry, uint64_t* time_since_epoch) {
1405#if defined(BOTAN_HAS_X509_CERTIFICATES)
1406 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1407 if(Botan::any_null_pointers(time_since_epoch)) {
1409 }
1410
1411 *time_since_epoch = e.expire_time().time_since_epoch();
1412 return BOTAN_FFI_SUCCESS;
1413 });
1414#else
1415 BOTAN_UNUSED(entry, time_since_epoch);
1417#endif
1418}
1419
1421 botan_x509_cert_t cert,
1422 const botan_x509_cert_t* intermediates,
1423 size_t intermediates_len,
1424 const botan_x509_cert_t* trusted,
1425 size_t trusted_len,
1426 const botan_x509_crl_t* crls,
1427 size_t crls_len,
1428 const char* trusted_path,
1429 size_t required_strength,
1430 const char* hostname_cstr,
1431 uint64_t reference_time) {
1432 if(required_strength == 0) {
1433 required_strength = 110;
1434 }
1435
1436#if defined(BOTAN_HAS_X509_CERTIFICATES)
1437 return ffi_guard_thunk(__func__, [=]() -> int {
1438 const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);
1440 const auto validation_time = reference_time == 0
1441 ? std::chrono::system_clock::now()
1442 : std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));
1443
1444 std::vector<Botan::X509_Certificate> end_certs;
1445 end_certs.push_back(safe_get(cert));
1446 for(size_t i = 0; i != intermediates_len; ++i) {
1447 end_certs.push_back(safe_get(intermediates[i]));
1448 }
1449
1450 std::unique_ptr<Botan::Certificate_Store> trusted_from_path;
1451 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra;
1452 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_crls;
1453 std::vector<Botan::Certificate_Store*> trusted_roots;
1454
1455 if(trusted_path != nullptr && *trusted_path != 0) {
1456 trusted_from_path = std::make_unique<Botan::Certificate_Store_In_Memory>(trusted_path);
1457 trusted_roots.push_back(trusted_from_path.get());
1458 }
1459
1460 if(trusted_len > 0) {
1461 trusted_extra = std::make_unique<Botan::Certificate_Store_In_Memory>();
1462 for(size_t i = 0; i != trusted_len; ++i) {
1463 trusted_extra->add_certificate(safe_get(trusted[i]));
1464 }
1465 trusted_roots.push_back(trusted_extra.get());
1466 }
1467
1468 if(crls_len > 0) {
1469 trusted_crls = std::make_unique<Botan::Certificate_Store_In_Memory>();
1470 for(size_t i = 0; i != crls_len; ++i) {
1471 trusted_crls->add_crl(safe_get(crls[i]));
1472 }
1473 trusted_roots.push_back(trusted_crls.get());
1474 }
1475
1476 const Botan::Path_Validation_Restrictions restrictions(false, required_strength);
1477
1478 auto validation_result =
1479 Botan::x509_path_validate(end_certs, restrictions, trusted_roots, hostname, usage, validation_time);
1480
1481 if(result_code != nullptr) {
1482 *result_code = static_cast<int>(validation_result.result());
1483 }
1484
1485 if(validation_result.successful_validation()) {
1486 return 0;
1487 } else {
1488 return 1;
1489 }
1490 });
1491#else
1492 BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);
1493 BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time, crls, crls_len);
1495#endif
1496}
1497}
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:163
uint64_t time_since_epoch() const
Return time since epoch.
const std::set< X509_DN > & directory_names() const
Return the set of directory names included in this alternative name.
Definition pkix_types.h:187
const std::set< uint32_t > & ipv4_address() const
Return the set of IPv4 addresses included in this alternative name.
Definition pkix_types.h:178
const std::set< std::string > & uris() const
Return the set of URIs included in this alternative name.
Definition pkix_types.h:169
const std::set< std::string > & dns() const
Return the set of DNS names included in this alternative name.
Definition pkix_types.h:175
const std::set< std::string > & email() const
Return the set of email addresses included in this alternative name.
Definition pkix_types.h:172
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
Definition x509_crl.h:29
CRL_Code reason_code() const
Definition crl_ent.cpp:147
const X509_Time & expire_time() const
Definition crl_ent.cpp:143
const std::vector< uint8_t > & serial_number() const
Definition crl_ent.cpp:139
const std::vector< Distribution_Point > & distribution_points() const
Definition x509_ext.h:450
bool extension_set(const OID &oid) const
Definition x509_ext.cpp:188
X.509 GeneralName Type.
Definition pkix_types.h:274
static GeneralName email(std::string_view email)
static GeneralName ipv4_address(uint32_t ipv4)
static GeneralName uri(std::string_view uri)
std::vector< uint8_t > binary_name() const
std::string name() const
NameType type_code() const
Definition pkix_types.h:311
static GeneralName dns(std::string_view dns)
static GeneralName directory_name(Botan::X509_DN dn)
const std::vector< GeneralSubtree > & permitted() const
Definition pkix_types.h:426
const std::vector< GeneralSubtree > & excluded() const
Definition pkix_types.h:433
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:86
const std::vector< CRL_Entry > & get_revoked() const
Definition x509_crl.cpp:203
const std::vector< uint8_t > & authority_key_id() const
Definition x509_crl.cpp:221
uint32_t crl_number() const
Definition x509_crl.cpp:228
const X509_DN & issuer_dn() const
Definition x509_crl.cpp:214
const NameConstraints & name_constraints() const
Definition x509cert.cpp:458
const std::vector< uint8_t > & serial_number() const
Definition x509cert.cpp:402
const std::vector< uint8_t > & authority_key_id() const
Definition x509cert.cpp:394
const AlternativeName & issuer_alt_name() const
Definition x509cert.cpp:575
const std::vector< uint8_t > & raw_subject_dn() const
Definition x509cert.cpp:422
const std::vector< uint8_t > & subject_key_id() const
Definition x509cert.cpp:398
const Extensions & v3_extensions() const
Definition x509cert.cpp:462
const std::vector< uint8_t > & raw_issuer_dn() const
Definition x509cert.cpp:418
const AlternativeName & subject_alt_name() const
Definition x509cert.cpp:571
const std::vector< uint8_t > & subject_public_key_info() const
Definition x509cert.cpp:378
const std::vector< uint8_t > & get_bits() const
Definition pkix_types.h:82
struct botan_pubkey_struct * botan_pubkey_t
Definition ffi.h:1650
struct botan_asn1_oid_struct * botan_asn1_oid_t
Definition ffi.h:1224
struct botan_privkey_struct * botan_privkey_t
Definition ffi.h:1417
struct botan_x509_crl_entry_struct * botan_x509_crl_entry_t
Definition ffi.h:2546
struct botan_x509_crl_struct * botan_x509_crl_t
Definition ffi.h:2545
struct botan_x509_general_name_struct * botan_x509_general_name_t
Definition ffi.h:2414
int botan_x509_cert_view_as_string(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_str_fn view)
Definition ffi_cert.cpp:545
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
Definition ffi.h:163
struct botan_x509_cert_struct * botan_x509_cert_t
Definition ffi.h:2231
@ BOTAN_X509_DNS_NAME
Definition ffi.h:2424
@ BOTAN_X509_DIRECTORY_NAME
Definition ffi.h:2425
@ BOTAN_X509_OTHER_NAME
Definition ffi.h:2422
@ BOTAN_X509_EMAIL_ADDRESS
Definition ffi.h:2423
@ BOTAN_X509_IP_ADDRESS
Definition ffi.h:2427
@ BOTAN_X509_URI
Definition ffi.h:2426
struct botan_mp_struct * botan_mp_t
Definition ffi.h:1003
void * botan_view_ctx
Definition ffi.h:154
struct botan_rng_struct * botan_rng_t
Definition ffi.h:291
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:140
@ BOTAN_FFI_ERROR_OUT_OF_RANGE
Definition ffi.h:138
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:133
@ BOTAN_FFI_SUCCESS
Definition ffi.h:116
@ BOTAN_FFI_ERROR_NO_VALUE
Definition ffi.h:122
@ BOTAN_FFI_ERROR_INVALID_OBJECT_STATE
Definition ffi.h:137
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:134
int botan_x509_cert_view_public_key_bits(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_bin_fn view)
Definition ffi_cert.cpp:700
int(* botan_view_str_fn)(botan_view_ctx view_ctx, const char *str, size_t len)
Definition ffi.h:172
botan_x509_value_type
Definition ffi.h:2246
@ BOTAN_X509_AUTHORITY_KEY_IDENTIFIER
Definition ffi.h:2251
@ BOTAN_X509_SUBJECT_KEY_IDENTIFIER
Definition ffi.h:2250
@ BOTAN_X509_TBS_DATA_BITS
Definition ffi.h:2254
@ BOTAN_X509_SIGNATURE_BITS
Definition ffi.h:2256
@ BOTAN_X509_PUBLIC_KEY_PKCS8_BITS
Definition ffi.h:2253
@ BOTAN_X509_DER_ENCODING
Definition ffi.h:2258
@ BOTAN_X509_PEM_ENCODING
Definition ffi.h:2259
@ BOTAN_X509_OCSP_RESPONDER_URLS
Definition ffi.h:2262
@ BOTAN_X509_SIGNATURE_SCHEME_BITS
Definition ffi.h:2255
@ BOTAN_X509_SUBJECT_DN_BITS
Definition ffi.h:2248
@ BOTAN_X509_CRL_DISTRIBUTION_URLS
Definition ffi.h:2261
@ BOTAN_X509_SERIAL_NUMBER
Definition ffi.h:2247
@ BOTAN_X509_ISSUER_DN_BITS
Definition ffi.h:2249
@ BOTAN_X509_CA_ISSUERS_URLS
Definition ffi.h:2263
int botan_x509_cert_get_subject_dn_count(botan_x509_cert_t cert, const char *key, size_t *count)
Definition ffi_cert.cpp:525
int botan_x509_is_revoked(botan_x509_crl_t crl, botan_x509_cert_t cert)
int botan_x509_crl_destroy(botan_x509_crl_t crl)
int botan_x509_cert_destroy(botan_x509_cert_t cert)
Definition ffi_cert.cpp:593
int botan_x509_cert_load_file(botan_x509_cert_t *cert_obj, const char *cert_path)
Definition ffi_cert.cpp:169
int botan_x509_crl_entry_serial_number(botan_x509_crl_entry_t entry, botan_mp_t *serial_number)
int botan_x509_general_name_destroy(botan_x509_general_name_t name)
Definition ffi_cert.cpp:780
int botan_x509_cert_dup(botan_x509_cert_t *cert_obj, botan_x509_cert_t cert)
Definition ffi_cert.cpp:186
int botan_x509_crl_next_update(botan_x509_crl_t crl, uint64_t *time_since_epoch)
int botan_x509_cert_get_issuer_dn_count(botan_x509_cert_t cert, const char *key, size_t *count)
Definition ffi_cert.cpp:491
int botan_x509_crl_entry_destroy(botan_x509_crl_entry_t entry)
int botan_x509_cert_issuer_alternative_names_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:923
int botan_x509_cert_verify_with_crl(int *result_code, botan_x509_cert_t cert, const botan_x509_cert_t *intermediates, size_t intermediates_len, const botan_x509_cert_t *trusted, size_t trusted_len, const botan_x509_crl_t *crls, size_t crls_len, const char *trusted_path, size_t required_strength, const char *hostname_cstr, uint64_t reference_time)
int botan_x509_crl_view_binary_values_count(botan_x509_crl_t crl_obj, botan_x509_value_type value_type, size_t *count)
int botan_x509_general_name_view_binary_value(botan_x509_general_name_t name, botan_view_ctx ctx, botan_view_bin_fn view)
Definition ffi_cert.cpp:758
int botan_x509_crl_this_update(botan_x509_crl_t crl, uint64_t *time_since_epoch)
int botan_x509_cert_view_binary_values_count(botan_x509_cert_t cert, botan_x509_value_type value_type, size_t *count)
Definition ffi_cert.cpp:333
int botan_x509_crl_view_binary_values(botan_x509_crl_t crl_obj, botan_x509_value_type value_type, size_t index, botan_view_ctx ctx, botan_view_bin_fn view_fn)
int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t *key)
Definition ffi_cert.cpp:455
int botan_x509_cert_allowed_extended_usage_oid(botan_x509_cert_t cert, botan_asn1_oid_t oid)
Definition ffi_cert.cpp:584
int botan_x509_cert_view_binary_values(botan_x509_cert_t cert, botan_x509_value_type value_type, size_t index, botan_view_ctx ctx, botan_view_bin_fn view_fn)
Definition ffi_cert.cpp:278
const char * botan_x509_cert_validation_status(int code)
int botan_x509_crl_update(botan_x509_crl_t *crl_obj, botan_x509_crl_t last_crl, botan_rng_t rng, botan_x509_cert_t ca_cert, botan_privkey_t ca_key, uint64_t issue_time, uint32_t next_update, const botan_x509_crl_entry_t *new_entries, size_t new_entries_len, const char *hash_fn, const char *padding)
int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:678
int botan_x509_cert_get_issuer_dn(botan_x509_cert_t cert, const char *key, size_t index, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:473
int botan_x509_cert_subject_alternative_names_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:884
int botan_x509_cert_excluded_name_constraints(botan_x509_cert_t cert, size_t index, botan_x509_general_name_t *constraint)
Definition ffi_cert.cpp:824
int botan_x509_crl_entries_count(botan_x509_crl_t crl, size_t *count)
int botan_x509_crl_entries(botan_x509_crl_t crl, size_t index, botan_x509_crl_entry_t *entry)
int botan_x509_cert_subject_alternative_names(botan_x509_cert_t cert, size_t index, botan_x509_general_name_t *alt_name)
Definition ffi_cert.cpp:859
int botan_x509_crl_entry_revocation_date(botan_x509_crl_entry_t entry, uint64_t *time_since_epoch)
int botan_x509_cert_issuer_alternative_names(botan_x509_cert_t cert, size_t index, botan_x509_general_name_t *alt_name)
Definition ffi_cert.cpp:898
int botan_x509_cert_serial_number(botan_x509_cert_t cert, botan_mp_t *serial_number)
Definition ffi_cert.cpp:649
int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:612
int botan_x509_cert_permitted_name_constraints(botan_x509_cert_t cert, size_t index, botan_x509_general_name_t *constraint)
Definition ffi_cert.cpp:789
int botan_x509_cert_view_as_string(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_str_fn view)
Definition ffi_cert.cpp:545
int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:602
int botan_x509_cert_load(botan_x509_cert_t *cert_obj, const uint8_t cert_bits[], size_t cert_bits_len)
Definition ffi_cert.cpp:204
int botan_x509_crl_load(botan_x509_crl_t *crl_obj, const uint8_t crl_bits[], size_t crl_bits_len)
int botan_x509_cert_get_subject_dn(botan_x509_cert_t cert, const char *key, size_t index, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:507
int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t *time_since_epoch)
Definition ffi_cert.cpp:622
int botan_x509_crl_entry_view_serial_number(botan_x509_crl_entry_t entry, botan_view_ctx ctx, botan_view_bin_fn view)
int botan_x509_cert_verify(int *result_code, botan_x509_cert_t cert, const botan_x509_cert_t *intermediates, size_t intermediates_len, const botan_x509_cert_t *trusted, size_t trusted_len, const char *trusted_path, size_t required_strength, const char *hostname_cstr, uint64_t reference_time)
Definition ffi_cert.cpp:950
int botan_x509_cert_excluded_name_constraints_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:846
int botan_x509_cert_is_ca(botan_x509_cert_t cert)
Definition ffi_cert.cpp:426
int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char *hostname)
Definition ffi_cert.cpp:937
int botan_x509_crl_entry_create(botan_x509_crl_entry_t *entry, botan_x509_cert_t cert, int reason_code)
int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:640
int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:687
int botan_x509_crl_create(botan_x509_crl_t *crl_obj, botan_rng_t rng, botan_x509_cert_t ca_cert, botan_privkey_t ca_key, uint64_t issue_time, uint32_t next_update, const char *hash_fn, const char *padding)
int botan_x509_cert_allowed_extended_usage_str(botan_x509_cert_t cert, const char *oid)
Definition ffi_cert.cpp:569
int botan_x509_cert_view_public_key_bits(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_bin_fn view)
Definition ffi_cert.cpp:700
int botan_x509_crl_view_string_values(botan_x509_crl_t crl_obj, botan_x509_value_type value_type, size_t index, botan_view_ctx ctx, botan_view_str_fn view)
int botan_x509_crl_verify_signature(botan_x509_crl_t crl, botan_pubkey_t key)
int botan_x509_crl_load_file(botan_x509_crl_t *crl_obj, const char *crl_path)
int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage)
Definition ffi_cert.cpp:554
int botan_x509_cert_view_string_values_count(botan_x509_cert_t cert, botan_x509_value_type value_type, size_t *count)
Definition ffi_cert.cpp:414
int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t *time_since_epoch)
Definition ffi_cert.cpp:631
int botan_x509_general_name_view_string_value(botan_x509_general_name_t name, botan_view_ctx ctx, botan_view_str_fn view)
Definition ffi_cert.cpp:735
int botan_x509_crl_entry_reason(botan_x509_crl_entry_t entry, int *reason_code)
int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:696
int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char *hash, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:665
int botan_x509_cert_get_path_length_constraint(botan_x509_cert_t cert, size_t *path_limit)
Definition ffi_cert.cpp:435
int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:541
int botan_x509_crl_view_string_values_count(botan_x509_crl_t crl_obj, botan_x509_value_type value_type, size_t *count)
int botan_x509_general_name_get_type(botan_x509_general_name_t name, unsigned int *type)
Definition ffi_cert.cpp:710
int botan_x509_cert_permitted_name_constraints_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:811
int botan_x509_cert_view_string_values(botan_x509_cert_t cert, botan_x509_value_type value_type, size_t index, botan_view_ctx ctx, botan_view_str_fn view_fn)
Definition ffi_cert.cpp:345
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:158
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:185
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition asn1_obj.cpp:177
std::vector< uint8_t > BER_encode(const Private_Key &key, RandomNumberGenerator &rng, std::string_view pass, std::chrono::milliseconds msec, std::string_view pbe_algo)
Definition pkcs8.cpp:161
std::string PEM_encode(const Private_Key &key)
Definition pkcs8.cpp:116
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, std::span< const uint8_t > buf)
Definition ffi_util.h:187
int copy_view_bin(uint8_t out[], size_t *out_len, Fn fn, Args... args)
Definition ffi_util.h:211
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:79
BOTAN_FFI_ERROR ffi_new_object(T *obj, Args &&... args)
Definition ffi_util.h:178
int copy_view_str(uint8_t out[], size_t *out_len, Fn fn, Args... args)
Definition ffi_util.h:217
int ffi_guard_thunk(const char *func_name, T thunk)
Definition ffi_util.h:95
int write_vec_output(uint8_t out[], size_t *out_len, std::span< const uint8_t > buf)
Definition ffi_util.h:261
int write_str_output(char out[], size_t *out_len, const std::string &str)
Definition ffi_util.h:265
Certificate_Status_Code
Definition pkix_enums.h:20
Path_Validation_Result x509_path_validate(const std::vector< X509_Certificate > &end_certs, const Path_Validation_Restrictions &restrictions, const std::vector< Certificate_Store * > &trusted_roots, std::string_view hostname, Usage_Type usage, std::chrono::system_clock::time_point ref_time, std::chrono::milliseconds ocsp_timeout, const std::vector< std::optional< OCSP::Response > > &ocsp_resp)
Definition x509path.cpp:868
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745
bool any_null_pointers(Ptrs... ptr)
Definition mem_utils.h:54