Botan 3.12.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 index -= altnames.ipv4_address().size();
78
79 if(index < altnames.ipv6_address().size()) {
80 auto itr = altnames.ipv6_address().begin();
81 std::advance(itr, index);
83 }
84
85 return std::nullopt;
86}
87
88/**
89 * Counts the total number of GeneralNames contained in the given
90 * AlternativeName @p alt_names.
91 *
92 * NOTE: if the set of alternative name types handled here is extended,
93 * extract_general_name_at() must be updated accordingly!
94 */
95size_t count_general_names_in(const Botan::AlternativeName& alt_names) {
96 return alt_names.email().size() + alt_names.dns().size() + alt_names.directory_names().size() +
97 alt_names.uris().size() + alt_names.ipv4_address().size() + alt_names.ipv6_address().size();
98}
99
100std::optional<botan_x509_general_name_types> to_botan_x509_general_name_types(Botan::GeneralName::NameType gn_type) {
101 using Type = Botan::GeneralName::NameType;
102 switch(gn_type) {
103 case Type::Unknown:
104 return std::nullopt;
105 case Type::RFC822:
107 case Type::DNS:
108 return BOTAN_X509_DNS_NAME;
109 case Type::URI:
110 return BOTAN_X509_URI;
111 case Type::DN:
113 case Type::IPv4:
114 case Type::IPv6:
116 case Type::Other:
118 }
119
121}
122
123/**
124 * Given some enumerator-style function @p fn, count how many values it can
125 * produce before returning BOTAN_FFI_ERROR_OUT_OF_RANGE. If the first call to
126 * @p fn returns BOTAN_FFI_ERROR_NO_VALUE, zero is written to @p count.
127 *
128 * If this function returns BOTAN_FFI_SUCCESS, @p count contains the number of
129 * values that can be enumerated. Otherwise, the value of @p count is undefined.
130 */
131template <std::invocable<size_t> EnumeratorT>
132int enumerator_count_values(size_t* count, EnumeratorT fn) {
133 if(Botan::any_null_pointers(count)) {
135 }
136
137 *count = 0;
138 for(;; ++(*count)) {
139 const auto rc = fn(*count);
140 switch(rc) {
143 // hit the end of the enumeration
144 return BOTAN_FFI_SUCCESS;
146 // got a value, continue counting
147 break;
148 default:
149 // unexpected error from enumerator function
150 return rc;
151 }
152 }
153}
154
155std::chrono::system_clock::time_point timepoint_from_timestamp(uint64_t time_since_epoch) {
156 return std::chrono::system_clock::time_point(std::chrono::seconds(time_since_epoch));
157}
158
159std::string default_from_ptr(const char* value) {
160 std::string ret;
161 if(value != nullptr) {
162 ret = value;
163 }
164 return ret;
165}
166
167} // namespace
168
169} // namespace Botan_FFI
170
171#endif
172
173extern "C" {
174
175using namespace Botan_FFI;
176
177int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* cert_path) {
178 if(cert_obj == nullptr || cert_path == nullptr) {
180 }
181
182#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
183
184 return ffi_guard_thunk(__func__, [=]() -> int {
185 auto c = std::make_unique<Botan::X509_Certificate>(cert_path);
186 return ffi_new_object(cert_obj, std::move(c));
187 });
188
189#else
191#endif
192}
193
195 if(cert_obj == nullptr) {
197 }
198
199#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
200
201 return ffi_guard_thunk(__func__, [=]() -> int {
202 auto c = std::make_unique<Botan::X509_Certificate>(safe_get(cert));
203 return ffi_new_object(cert_obj, std::move(c));
204 });
205
206#else
207 BOTAN_UNUSED(cert);
209#endif
210}
211
212int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert_bits[], size_t cert_bits_len) {
213 if(cert_obj == nullptr || cert_bits == nullptr) {
215 }
216
217#if defined(BOTAN_HAS_X509_CERTIFICATES)
218 return ffi_guard_thunk(__func__, [=]() -> int {
219 Botan::DataSource_Memory bits(cert_bits, cert_bits_len);
220 auto c = std::make_unique<Botan::X509_Certificate>(bits);
221 return ffi_new_object(cert_obj, std::move(c));
222 });
223#else
224 BOTAN_UNUSED(cert_bits_len);
226#endif
227}
228}
229
230namespace {
231
232#if defined(BOTAN_HAS_X509_CERTIFICATES)
233
234int botan_x509_object_view_value(const Botan::X509_Object& object,
235 botan_x509_value_type value_type,
236 size_t index,
237 botan_view_ctx ctx,
238 botan_view_str_fn view_fn) {
239 if(index != 0) {
240 // As of now there are no multi-value generic string entries.
242 }
243
244 auto view = [=](const std::string& value) { return invoke_view_callback(view_fn, ctx, value); };
245
246 switch(value_type) {
248 return view(object.PEM_encode());
249 default:
250 BOTAN_ASSERT_UNREACHABLE(); /* called with unexpected (non-generic) value_type */
251 }
252}
253
254int botan_x509_object_view_value(const Botan::X509_Object& object,
255 botan_x509_value_type value_type,
256 size_t index,
257 botan_view_ctx ctx,
258 botan_view_bin_fn view_fn) {
259 if(index != 0) {
260 // As of now there are no multi-value generic binary entries.
262 }
263
264 auto view = [=](std::span<const uint8_t> value) { return invoke_view_callback(view_fn, ctx, value); };
265
266 switch(value_type) {
268 return view(object.tbs_data());
270 return view(object.signature_algorithm().BER_encode());
272 return view(object.signature());
274 return view(object.BER_encode());
275 default:
276 BOTAN_ASSERT_UNREACHABLE(); /* called with unexpected (non-generic) value_type */
277 }
278}
279
280#endif
281
282} // namespace
283
284extern "C" {
285
287 botan_x509_value_type value_type,
288 size_t index,
289 botan_view_ctx ctx,
290 botan_view_bin_fn view_fn) {
291#if defined(BOTAN_HAS_X509_CERTIFICATES)
292 if(index != 0) {
293 // As of now there are no multi-value binary entries.
295 }
296
297 auto view = [=](std::span<const uint8_t> value) -> int {
298 if(value.empty()) {
300 } else {
301 return invoke_view_callback(view_fn, ctx, value);
302 }
303 };
304
305 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) -> int {
306 switch(value_type) {
308 return view(c.serial_number());
310 return view(c.raw_subject_dn());
312 return view(c.raw_issuer_dn());
314 return view(c.subject_key_id());
316 return view(c.authority_key_id());
318 return view(c.subject_public_key_info());
319
324 return botan_x509_object_view_value(c, value_type, index, ctx, view_fn);
325
331 }
332
334 });
335#else
336 BOTAN_UNUSED(cert, value_type, index, ctx, view_fn);
338#endif
339}
340
342#if defined(BOTAN_HAS_X509_CERTIFICATES)
343 return enumerator_count_values(count, [=](size_t index) {
345 cert, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
346 });
347#else
348 BOTAN_UNUSED(cert, value_type, count);
350#endif
351}
352
354 botan_x509_value_type value_type,
355 size_t index,
356 botan_view_ctx ctx,
357 botan_view_str_fn view_fn) {
358#if defined(BOTAN_HAS_X509_CERTIFICATES)
359 auto enumerate = [view_fn, ctx](auto values, size_t idx) -> int {
360 if(idx >= values.size()) {
362 } else {
363 return invoke_view_callback(view_fn, ctx, values[idx]);
364 }
365 };
366
367 auto enumerate_crl_distribution_points = [view_fn, ctx](const Botan::X509_Certificate& c, size_t idx) -> int {
368 const auto* crl_dp_ext =
369 c.v3_extensions().get_extension_object_as<Botan::Cert_Extension::CRL_Distribution_Points>();
370 if(crl_dp_ext == nullptr) {
371 return BOTAN_FFI_ERROR_OUT_OF_RANGE; // essentially an empty list
372 }
373
374 const auto& dps = crl_dp_ext->distribution_points();
375 for(size_t i = idx; const auto& dp : dps) {
376 const auto& uris = dp.point().uris();
377 if(i >= uris.size()) {
378 i -= uris.size();
379 continue;
380 }
381
382 auto itr = uris.begin();
383 std::advance(itr, i);
384 return invoke_view_callback(view_fn, ctx, *itr);
385 }
386
388 };
389
390 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) -> int {
391 switch(value_type) {
393 return enumerate_crl_distribution_points(c, index);
395 return enumerate(c.ocsp_responders(), index);
397 return enumerate(c.ca_issuers(), index);
399 return botan_x509_object_view_value(c, value_type, index, ctx, view_fn);
400
412 }
413
415 });
416#else
417 BOTAN_UNUSED(cert, value_type, index, ctx, view_fn);
419#endif
420}
421
423#if defined(BOTAN_HAS_X509_CERTIFICATES)
424 return enumerator_count_values(count, [=](size_t index) {
426 cert, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
427 });
428#else
429 BOTAN_UNUSED(cert, value_type, count);
431#endif
432}
433
435#if defined(BOTAN_HAS_X509_CERTIFICATES)
436 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return c.is_CA_cert() ? 1 : 0; });
437#else
438 BOTAN_UNUSED(cert);
440#endif
441}
442
444#if defined(BOTAN_HAS_X509_CERTIFICATES)
445 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
446 if(Botan::any_null_pointers(path_limit)) {
448 }
449
450 if(const auto path_len = c.path_length_constraint()) {
451 *path_limit = path_len.value();
452 return BOTAN_FFI_SUCCESS;
453 } else {
455 }
456 });
457#else
458 BOTAN_UNUSED(cert, path_limit);
460#endif
461}
462
464 if(key == nullptr) {
466 }
467
468 *key = nullptr;
469
470#if defined(BOTAN_HAS_X509_CERTIFICATES)
471 return ffi_guard_thunk(__func__, [=]() -> int {
472 auto public_key = safe_get(cert).subject_public_key();
473 return ffi_new_object(key, std::move(public_key));
474 });
475#else
476 BOTAN_UNUSED(cert);
478#endif
479}
480
482 botan_x509_cert_t cert, const char* key, size_t index, uint8_t out[], size_t* out_len) {
483 if(key == nullptr) {
485 }
486#if defined(BOTAN_HAS_X509_CERTIFICATES)
487 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
488 auto issuer_info = c.issuer_info(key);
489 if(index < issuer_info.size()) {
490 // TODO(Botan4) change the type of out and remove this cast
491 return write_str_output(reinterpret_cast<char*>(out), out_len, c.issuer_info(key).at(index));
492 } else {
493 return BOTAN_FFI_ERROR_BAD_PARAMETER; // TODO(Botan4): use BOTAN_FFI_ERROR_OUT_OF_RANGE
494 }
495 });
496#else
497 BOTAN_UNUSED(cert, key, index, out, out_len);
499#endif
500}
501
502int botan_x509_cert_get_issuer_dn_count(botan_x509_cert_t cert, const char* key, size_t* count) {
503#if defined(BOTAN_HAS_X509_CERTIFICATES)
504 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
505 if(Botan::any_null_pointers(count)) {
507 }
508
509 *count = c.issuer_info(key).size();
510 return BOTAN_FFI_SUCCESS;
511 });
512#else
513 BOTAN_UNUSED(cert, key, count);
515#endif
516}
517
519 botan_x509_cert_t cert, const char* key, size_t index, uint8_t out[], size_t* out_len) {
520 if(key == nullptr) {
522 }
523#if defined(BOTAN_HAS_X509_CERTIFICATES)
524 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
525 auto subject_info = c.subject_info(key);
526 if(index < subject_info.size()) {
527 // TODO(Botan4) change the type of out and remove this cast
528 return write_str_output(reinterpret_cast<char*>(out), out_len, c.subject_info(key).at(index));
529 } else {
530 return BOTAN_FFI_ERROR_BAD_PARAMETER; // TODO(Botan4): use BOTAN_FFI_ERROR_OUT_OF_RANGE
531 }
532 });
533#else
534 BOTAN_UNUSED(cert, key, index, out, out_len);
536#endif
537}
538
539int botan_x509_cert_get_subject_dn_count(botan_x509_cert_t cert, const char* key, size_t* count) {
540#if defined(BOTAN_HAS_X509_CERTIFICATES)
541 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
542 if(Botan::any_null_pointers(count)) {
544 }
545
546 *count = c.subject_info(key).size();
547 return BOTAN_FFI_SUCCESS;
548 });
549#else
550 BOTAN_UNUSED(cert, key, count);
552#endif
553}
554
555int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len) {
556 return copy_view_str(reinterpret_cast<uint8_t*>(out), out_len, botan_x509_cert_view_as_string, cert);
557}
558
560#if defined(BOTAN_HAS_X509_CERTIFICATES)
561 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return invoke_view_callback(view, ctx, c.to_string()); });
562#else
563 BOTAN_UNUSED(cert, ctx, view);
565#endif
566}
567
568int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage) {
569#if defined(BOTAN_HAS_X509_CERTIFICATES)
570 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
571 const Botan::Key_Constraints k = static_cast<Botan::Key_Constraints>(key_usage);
572 if(c.allowed_usage(k)) {
573 return BOTAN_FFI_SUCCESS;
574 }
575 return 1;
576 });
577#else
578 BOTAN_UNUSED(cert, key_usage);
580#endif
581}
582
584#if defined(BOTAN_HAS_X509_CERTIFICATES)
585 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
586 if(Botan::any_null_pointers(oid)) {
588 }
589
590 return c.has_ex_constraint(oid) ? 1 : 0;
591 });
592#else
593 BOTAN_UNUSED(cert, oid);
595#endif
596}
597
599#if defined(BOTAN_HAS_X509_CERTIFICATES)
600 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int { return c.has_ex_constraint(safe_get(oid)) ? 1 : 0; });
601#else
602 BOTAN_UNUSED(cert, oid);
604#endif
605}
606
608#if defined(BOTAN_HAS_X509_CERTIFICATES)
609 return BOTAN_FFI_CHECKED_DELETE(cert);
610#else
611 BOTAN_UNUSED(cert);
613#endif
614}
615
616int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len) {
617#if defined(BOTAN_HAS_X509_CERTIFICATES)
618 return BOTAN_FFI_VISIT(cert,
619 [=](const auto& c) { return write_str_output(out, out_len, c.not_before().to_string()); });
620#else
621 BOTAN_UNUSED(cert, out, out_len);
623#endif
624}
625
626int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len) {
627#if defined(BOTAN_HAS_X509_CERTIFICATES)
628 return BOTAN_FFI_VISIT(cert,
629 [=](const auto& c) { return write_str_output(out, out_len, c.not_after().to_string()); });
630#else
631 BOTAN_UNUSED(cert, out, out_len);
633#endif
634}
635
636int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t* time_since_epoch) {
637 if(time_since_epoch == nullptr) {
639 }
640#if defined(BOTAN_HAS_X509_CERTIFICATES)
641 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *time_since_epoch = c.not_before().time_since_epoch(); });
642#else
643 BOTAN_UNUSED(cert, time_since_epoch);
645#endif
646}
647
648int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t* time_since_epoch) {
649 if(time_since_epoch == nullptr) {
651 }
652#if defined(BOTAN_HAS_X509_CERTIFICATES)
653 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *time_since_epoch = c.not_after().time_since_epoch(); });
654#else
655 BOTAN_UNUSED(cert, time_since_epoch);
657#endif
658}
659
660int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
661#if defined(BOTAN_HAS_X509_CERTIFICATES)
662 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.serial_number()); });
663#else
664 BOTAN_UNUSED(cert, out, out_len);
666#endif
667}
668
670#if defined(BOTAN_HAS_X509_CERTIFICATES)
671 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
672 if(Botan::any_null_pointers(serial_number)) {
674 }
675
676 auto serial_bn = Botan::BigInt::from_bytes(c.serial_number());
677 return ffi_new_object(serial_number, std::make_unique<Botan::BigInt>(std::move(serial_bn)));
678 });
679#else
680 BOTAN_UNUSED(cert, serial_number);
682#endif
683}
684
685int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len) {
686 if(hash == nullptr) {
688 }
689#if defined(BOTAN_HAS_X509_CERTIFICATES)
690 // TODO(Botan4) change the type of out and remove this cast
691
692 return BOTAN_FFI_VISIT(cert, [=](const auto& c) {
693 return write_str_output(reinterpret_cast<char*>(out), out_len, c.fingerprint(hash));
694 });
695#else
696 BOTAN_UNUSED(cert, hash, out, out_len);
698#endif
699}
700
701int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
702#if defined(BOTAN_HAS_X509_CERTIFICATES)
703 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.authority_key_id()); });
704#else
705 BOTAN_UNUSED(cert, out, out_len);
707#endif
708}
709
710int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
711#if defined(BOTAN_HAS_X509_CERTIFICATES)
712 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.subject_key_id()); });
713#else
714 BOTAN_UNUSED(cert, out, out_len);
716#endif
717}
718
719int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
720 return copy_view_bin(out, out_len, botan_x509_cert_view_public_key_bits, cert);
721}
722
724#if defined(BOTAN_HAS_X509_CERTIFICATES)
725 return BOTAN_FFI_VISIT(cert,
726 [=](const auto& c) { return invoke_view_callback(view, ctx, c.subject_public_key_bits()); });
727#else
728 BOTAN_UNUSED(cert, ctx, view);
730#endif
731}
732
734#if defined(BOTAN_HAS_X509_CERTIFICATES)
735 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) {
736 if(Botan::any_null_pointers(type)) {
738 }
739
740 const auto mapped_type = to_botan_x509_general_name_types(n.type_code());
741 if(!mapped_type.has_value()) {
743 }
744
745 *type = mapped_type.value();
746 if(*type == BOTAN_X509_OTHER_NAME /* ... viewing of other-names not supported */) {
748 }
749
750 return BOTAN_FFI_SUCCESS;
751 });
752#else
753 BOTAN_UNUSED(name, type);
755#endif
756}
757
759 botan_view_ctx ctx,
760 botan_view_str_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_EMAIL_ADDRESS && type != BOTAN_X509_DNS_NAME && type != BOTAN_X509_URI &&
769 type != BOTAN_X509_IP_ADDRESS) {
771 }
772
773 return invoke_view_callback(view, ctx, n.name());
774 });
775#else
776 BOTAN_UNUSED(name, ctx, view);
778#endif
779}
780
782 botan_view_ctx ctx,
783 botan_view_bin_fn view) {
784#if defined(BOTAN_HAS_X509_CERTIFICATES)
785 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) -> int {
786 const auto type = to_botan_x509_general_name_types(n.type_code());
787 if(!type) {
789 }
790
791 if(type != BOTAN_X509_DIRECTORY_NAME && type != BOTAN_X509_IP_ADDRESS) {
793 }
794
795 return invoke_view_callback(view, ctx, n.binary_name());
796 });
797#else
798 BOTAN_UNUSED(name, ctx, view);
800#endif
801}
802
804#if defined(BOTAN_HAS_X509_CERTIFICATES)
805 return BOTAN_FFI_CHECKED_DELETE(name);
806#else
807 BOTAN_UNUSED(name);
809#endif
810}
811
813 size_t index,
814 botan_x509_general_name_t* constraint) {
815#if defined(BOTAN_HAS_X509_CERTIFICATES)
816 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
817 if(Botan::any_null_pointers(constraint)) {
819 }
820
821 const auto& constraints = c.name_constraints().permitted();
822 if(index >= constraints.size()) {
824 }
825
826 return ffi_new_object(constraint, std::make_unique<Botan::GeneralName>(constraints[index].base()));
827 });
828#else
829 BOTAN_UNUSED(cert, index, constraint);
831#endif
832}
833
835#if defined(BOTAN_HAS_X509_CERTIFICATES)
836 if(Botan::any_null_pointers(count)) {
838 }
839
840 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *count = c.name_constraints().permitted().size(); });
841#else
842 BOTAN_UNUSED(cert, count);
844#endif
845}
846
848 size_t index,
849 botan_x509_general_name_t* constraint) {
850#if defined(BOTAN_HAS_X509_CERTIFICATES)
851 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
852 if(Botan::any_null_pointers(constraint)) {
854 }
855
856 const auto& constraints = c.name_constraints().excluded();
857 if(index >= constraints.size()) {
859 }
860
861 return ffi_new_object(constraint, std::make_unique<Botan::GeneralName>(constraints[index].base()));
862 });
863#else
864 BOTAN_UNUSED(cert, index, constraint);
866#endif
867}
868
870#if defined(BOTAN_HAS_X509_CERTIFICATES)
871 if(Botan::any_null_pointers(count)) {
873 }
874
875 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *count = c.name_constraints().excluded().size(); });
876#else
877 BOTAN_UNUSED(cert, count);
879#endif
880}
881
883 size_t index,
884 botan_x509_general_name_t* alt_name) {
885#if defined(BOTAN_HAS_X509_CERTIFICATES)
886 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
887 if(Botan::any_null_pointers(alt_name)) {
889 }
890
891 if(!c.v3_extensions().extension_set(Botan::OID::from_string("X509v3.SubjectAlternativeName"))) {
893 }
894
895 if(auto name = extract_general_name_at(c.subject_alt_name(), index)) {
896 return ffi_new_object(alt_name, std::make_unique<Botan::GeneralName>(std::move(name).value()));
897 }
898
900 });
901#else
902 BOTAN_UNUSED(cert, index, alt_name);
904#endif
905}
906
908#if defined(BOTAN_HAS_X509_CERTIFICATES)
909 if(Botan::any_null_pointers(count)) {
911 }
912
913 return BOTAN_FFI_VISIT(
914 cert, [=](const Botan::X509_Certificate& c) { *count = count_general_names_in(c.subject_alt_name()); });
915#else
916 BOTAN_UNUSED(cert, count);
918#endif
919}
920
922 size_t index,
923 botan_x509_general_name_t* alt_name) {
924#if defined(BOTAN_HAS_X509_CERTIFICATES)
925 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
926 if(Botan::any_null_pointers(alt_name)) {
928 }
929
930 if(!c.v3_extensions().extension_set(Botan::OID::from_string("X509v3.IssuerAlternativeName"))) {
932 }
933
934 if(auto name = extract_general_name_at(c.issuer_alt_name(), index)) {
935 return ffi_new_object(alt_name, std::make_unique<Botan::GeneralName>(std::move(name).value()));
936 }
937
939 });
940#else
941 BOTAN_UNUSED(cert, index, alt_name);
943#endif
944}
945
947#if defined(BOTAN_HAS_X509_CERTIFICATES)
948 if(Botan::any_null_pointers(count)) {
950 }
951
952 return BOTAN_FFI_VISIT(
953 cert, [=](const Botan::X509_Certificate& c) { *count = count_general_names_in(c.issuer_alt_name()); });
954#else
955 BOTAN_UNUSED(cert, count);
957#endif
958}
959
960int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char* hostname) {
961 if(hostname == nullptr) {
963 }
964
965#if defined(BOTAN_HAS_X509_CERTIFICATES)
966 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return c.matches_dns_name(hostname) ? 0 : -1; });
967#else
968 BOTAN_UNUSED(cert);
970#endif
971}
972
973int botan_x509_cert_verify(int* result_code,
975 const botan_x509_cert_t* intermediates,
976 size_t intermediates_len,
977 const botan_x509_cert_t* trusted,
978 size_t trusted_len,
979 const char* trusted_path,
980 size_t required_strength,
981 const char* hostname_cstr,
982 uint64_t reference_time) {
983 if(required_strength == 0) {
984 required_strength = 110;
985 }
986
987#if defined(BOTAN_HAS_X509_CERTIFICATES)
988 return ffi_guard_thunk(__func__, [=]() -> int {
989 const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);
991 const auto validation_time = reference_time == 0
992 ? std::chrono::system_clock::now()
993 : std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));
994
995 std::vector<Botan::X509_Certificate> end_certs;
996 end_certs.push_back(safe_get(cert));
997 for(size_t i = 0; i != intermediates_len; ++i) {
998 end_certs.push_back(safe_get(intermediates[i]));
999 }
1000
1001 std::unique_ptr<Botan::Certificate_Store> trusted_from_path;
1002 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra;
1003 std::vector<Botan::Certificate_Store*> trusted_roots;
1004
1005 if(trusted_path != nullptr && *trusted_path != 0) {
1006 trusted_from_path = std::make_unique<Botan::Certificate_Store_In_Memory>(trusted_path);
1007 trusted_roots.push_back(trusted_from_path.get());
1008 }
1009
1010 if(trusted_len > 0) {
1011 trusted_extra = std::make_unique<Botan::Certificate_Store_In_Memory>();
1012 for(size_t i = 0; i != trusted_len; ++i) {
1013 trusted_extra->add_certificate(safe_get(trusted[i]));
1014 }
1015 trusted_roots.push_back(trusted_extra.get());
1016 }
1017
1018 const Botan::Path_Validation_Restrictions restrictions(false, required_strength);
1019
1020 auto validation_result =
1021 Botan::x509_path_validate(end_certs, restrictions, trusted_roots, hostname, usage, validation_time);
1022
1023 if(result_code != nullptr) {
1024 *result_code = static_cast<int>(validation_result.result());
1025 }
1026
1027 if(validation_result.successful_validation()) {
1028 return 0;
1029 } else {
1030 return 1;
1031 }
1032 });
1033#else
1034 BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);
1035 BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time);
1037#endif
1038}
1039
1041 if(code < 0) {
1042 return nullptr;
1043 }
1044
1045#if defined(BOTAN_HAS_X509_CERTIFICATES)
1047 return Botan::to_string(sc);
1048#else
1049 return nullptr;
1050#endif
1051}
1052
1053int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path) {
1054 if(crl_obj == nullptr || crl_path == nullptr) {
1056 }
1057
1058#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
1059
1060 return ffi_guard_thunk(__func__, [=]() -> int {
1061 auto c = std::make_unique<Botan::X509_CRL>(crl_path);
1062 return ffi_new_object(crl_obj, std::move(c));
1063 });
1064
1065#else
1067#endif
1068}
1069
1070int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len) {
1071 if(crl_obj == nullptr || crl_bits == nullptr) {
1073 }
1074
1075#if defined(BOTAN_HAS_X509_CERTIFICATES)
1076 return ffi_guard_thunk(__func__, [=]() -> int {
1077 Botan::DataSource_Memory bits(crl_bits, crl_bits_len);
1078 auto c = std::make_unique<Botan::X509_CRL>(bits);
1079 return ffi_new_object(crl_obj, std::move(c));
1080 });
1081#else
1082 BOTAN_UNUSED(crl_bits_len);
1084#endif
1085}
1086
1087int botan_x509_crl_this_update(botan_x509_crl_t crl, uint64_t* time_since_epoch) {
1088#if defined(BOTAN_HAS_X509_CERTIFICATES)
1089 return BOTAN_FFI_VISIT(crl, [=](const auto& c) {
1090 if(Botan::any_null_pointers(time_since_epoch)) {
1092 }
1093 *time_since_epoch = c.this_update().time_since_epoch();
1094 return BOTAN_FFI_SUCCESS;
1095 });
1096#else
1097 BOTAN_UNUSED(crl, time_since_epoch);
1099#endif
1100}
1101
1102int botan_x509_crl_next_update(botan_x509_crl_t crl, uint64_t* time_since_epoch) {
1103#if defined(BOTAN_HAS_X509_CERTIFICATES)
1104 return BOTAN_FFI_VISIT(crl, [=](const auto& c) {
1105 const auto& time = c.next_update();
1106 if(!time.time_is_set()) {
1108 }
1109
1110 if(Botan::any_null_pointers(time_since_epoch)) {
1112 }
1113
1114 *time_since_epoch = c.next_update().time_since_epoch();
1115 return BOTAN_FFI_SUCCESS;
1116 });
1117#else
1118 BOTAN_UNUSED(crl, time_since_epoch);
1120#endif
1121}
1122
1124 botan_rng_t rng,
1125 botan_x509_cert_t ca_cert,
1126 botan_privkey_t ca_key,
1127 uint64_t issue_time,
1128 uint32_t next_update,
1129 const char* hash_fn,
1130 const char* padding) {
1131 if(Botan::any_null_pointers(crl_obj)) {
1133 }
1134#if defined(BOTAN_HAS_X509_CERTIFICATES)
1135 return ffi_guard_thunk(__func__, [=]() -> int {
1136 auto& rng_ = safe_get(rng);
1137 auto ca = Botan::X509_CA(
1138 safe_get(ca_cert), safe_get(ca_key), default_from_ptr(hash_fn), default_from_ptr(padding), rng_);
1139 auto crl = std::make_unique<Botan::X509_CRL>(
1140 ca.new_crl(rng_, timepoint_from_timestamp(issue_time), std::chrono::seconds(next_update)));
1141 return ffi_new_object(crl_obj, std::move(crl));
1142 });
1143#else
1144 BOTAN_UNUSED(rng, ca_cert, ca_key, hash_fn, padding, issue_time, next_update);
1146#endif
1147}
1148
1150 if(Botan::any_null_pointers(entry)) {
1152 }
1153#if defined(BOTAN_HAS_X509_CERTIFICATES)
1154 return ffi_guard_thunk(__func__, [=]() -> int {
1155 return ffi_new_object(
1156 entry, std::make_unique<Botan::CRL_Entry>(safe_get(cert), static_cast<Botan::CRL_Code>(reason_code)));
1157 });
1158#else
1159 BOTAN_UNUSED(cert, reason_code);
1161#endif
1162}
1163
1165 botan_x509_crl_t last_crl,
1166 botan_rng_t rng,
1167 botan_x509_cert_t ca_cert,
1168 botan_privkey_t ca_key,
1169 uint64_t issue_time,
1170 uint32_t next_update,
1171 const botan_x509_crl_entry_t* new_entries,
1172 size_t new_entries_len,
1173 const char* hash_fn,
1174 const char* padding) {
1175 if(Botan::any_null_pointers(crl_obj)) {
1177 }
1178 if(new_entries_len > 0 && Botan::any_null_pointers(new_entries)) {
1180 }
1181#if defined(BOTAN_HAS_X509_CERTIFICATES)
1182 return ffi_guard_thunk(__func__, [=]() -> int {
1183 auto& rng_ = safe_get(rng);
1184 auto ca = Botan::X509_CA(
1185 safe_get(ca_cert), safe_get(ca_key), default_from_ptr(hash_fn), default_from_ptr(padding), rng_);
1186
1187 std::vector<Botan::CRL_Entry> entries;
1188 entries.reserve(new_entries_len);
1189 for(size_t i = 0; i < new_entries_len; i++) {
1190 entries.push_back(safe_get(new_entries[i]));
1191 }
1192
1193 auto crl = std::make_unique<Botan::X509_CRL>(ca.update_crl(
1194 safe_get(last_crl), entries, rng_, timepoint_from_timestamp(issue_time), std::chrono::seconds(next_update)));
1195 return ffi_new_object(crl_obj, std::move(crl));
1196 });
1197#else
1199 last_crl, rng, ca_cert, ca_key, hash_fn, padding, issue_time, next_update, new_entries, new_entries_len);
1201#endif
1202}
1203
1205#if defined(BOTAN_HAS_X509_CERTIFICATES)
1206 return BOTAN_FFI_VISIT(crl, [=](const auto& c) -> int { return c.check_signature(safe_get(key)) ? 1 : 0; });
1207#else
1208 BOTAN_UNUSED(crl, key);
1210#endif
1211}
1212
1214#if defined(BOTAN_HAS_X509_CERTIFICATES)
1215 return BOTAN_FFI_CHECKED_DELETE(crl);
1216#else
1217 BOTAN_UNUSED(crl);
1219#endif
1220}
1221
1223 botan_x509_value_type value_type,
1224 size_t index,
1225 botan_view_ctx ctx,
1226 botan_view_bin_fn view_fn) {
1227#if defined(BOTAN_HAS_X509_CERTIFICATES)
1228 if(index != 0) {
1229 // As of now there are no multi-value binary entries.
1231 }
1232
1233 auto view = [=](std::span<const uint8_t> value) -> int {
1234 if(value.empty()) {
1236 } else {
1237 return invoke_view_callback(view_fn, ctx, value);
1238 }
1239 };
1240
1241 return BOTAN_FFI_VISIT(crl_obj, [=](const Botan::X509_CRL& crl) -> int {
1242 switch(value_type) {
1244 return view(Botan::store_be(crl.crl_number()));
1246 return view(Botan::ASN1::put_in_sequence(crl.issuer_dn().get_bits()));
1248 return view(crl.authority_key_id());
1249
1254 return botan_x509_object_view_value(crl, value_type, index, ctx, view_fn);
1255
1264 }
1265
1267 });
1268#else
1269 BOTAN_UNUSED(crl_obj, value_type, index, ctx, view_fn);
1271#endif
1272}
1273
1275#if defined(BOTAN_HAS_X509_CERTIFICATES)
1276 return enumerator_count_values(count, [=](size_t index) {
1278 crl_obj, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
1279 });
1280#else
1281 BOTAN_UNUSED(crl_obj, value_type, count);
1283#endif
1284}
1285
1287 botan_x509_value_type value_type,
1288 size_t index,
1289 botan_view_ctx ctx,
1290 botan_view_str_fn view) {
1291#if defined(BOTAN_HAS_X509_CERTIFICATES)
1292 return BOTAN_FFI_VISIT(crl_obj, [=](const Botan::X509_CRL& crl) -> int {
1293 switch(value_type) {
1295 return botan_x509_object_view_value(crl, value_type, index, ctx, view);
1296
1311 }
1312
1314 });
1315#else
1316 BOTAN_UNUSED(crl_obj, value_type, index, ctx, view);
1318#endif
1319}
1320
1322#if defined(BOTAN_HAS_X509_CERTIFICATES)
1323 return enumerator_count_values(count, [=](size_t index) {
1325 crl_obj, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
1326 });
1327#else
1328 BOTAN_UNUSED(crl_obj, value_type, count);
1330#endif
1331}
1332
1334#if defined(BOTAN_HAS_X509_CERTIFICATES)
1335 return BOTAN_FFI_VISIT(crl, [=](const auto& c) { return c.is_revoked(safe_get(cert)) ? 0 : -1; });
1336#else
1337 BOTAN_UNUSED(cert);
1338 BOTAN_UNUSED(crl);
1340#endif
1341}
1342
1344#if defined(BOTAN_HAS_X509_CERTIFICATES)
1345 return BOTAN_FFI_VISIT(crl, [=](const Botan::X509_CRL& c) -> int {
1346 const auto& entries = c.get_revoked();
1347 if(index >= entries.size()) {
1349 }
1350
1351 if(Botan::any_null_pointers(entry)) {
1353 }
1354
1355 return ffi_new_object(entry, std::make_unique<Botan::CRL_Entry>(entries[index]));
1356 });
1357#else
1358 BOTAN_UNUSED(crl, index, entry);
1360#endif
1361}
1362
1364#if defined(BOTAN_HAS_X509_CERTIFICATES)
1365 if(Botan::any_null_pointers(count)) {
1367 }
1368
1369 return BOTAN_FFI_VISIT(crl, [=](const Botan::X509_CRL& c) { *count = c.get_revoked().size(); });
1370#else
1371 BOTAN_UNUSED(crl, count);
1373#endif
1374}
1375
1377#if defined(BOTAN_HAS_X509_CERTIFICATES)
1378 return BOTAN_FFI_CHECKED_DELETE(entry);
1379#else
1380 BOTAN_UNUSED(entry);
1382#endif
1383}
1384
1386#if defined(BOTAN_HAS_X509_CERTIFICATES)
1387 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1388 if(Botan::any_null_pointers(reason_code)) {
1390 }
1391
1392 *reason_code = static_cast<int>(e.reason_code());
1393 return BOTAN_FFI_SUCCESS;
1394 });
1395#else
1396 BOTAN_UNUSED(entry, reason_code);
1398#endif
1399}
1400
1402#if defined(BOTAN_HAS_X509_CERTIFICATES)
1403 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1404 if(Botan::any_null_pointers(serial_number)) {
1406 }
1407
1408 auto serial_bn = Botan::BigInt::from_bytes(e.serial_number());
1409 return ffi_new_object(serial_number, std::make_unique<Botan::BigInt>(std::move(serial_bn)));
1410 });
1411#else
1412 BOTAN_UNUSED(entry, serial_number);
1414#endif
1415}
1416
1418#if defined(BOTAN_HAS_X509_CERTIFICATES)
1419 return BOTAN_FFI_VISIT(
1420 entry, [=](const Botan::CRL_Entry& e) { return invoke_view_callback(view, ctx, e.serial_number()); });
1421#else
1422 BOTAN_UNUSED(entry, ctx, view);
1424#endif
1425}
1426
1427int botan_x509_crl_entry_revocation_date(botan_x509_crl_entry_t entry, uint64_t* time_since_epoch) {
1428#if defined(BOTAN_HAS_X509_CERTIFICATES)
1429 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1430 if(Botan::any_null_pointers(time_since_epoch)) {
1432 }
1433
1434 *time_since_epoch = e.expire_time().time_since_epoch();
1435 return BOTAN_FFI_SUCCESS;
1436 });
1437#else
1438 BOTAN_UNUSED(entry, time_since_epoch);
1440#endif
1441}
1442
1444 botan_x509_cert_t cert,
1445 const botan_x509_cert_t* intermediates,
1446 size_t intermediates_len,
1447 const botan_x509_cert_t* trusted,
1448 size_t trusted_len,
1449 const botan_x509_crl_t* crls,
1450 size_t crls_len,
1451 const char* trusted_path,
1452 size_t required_strength,
1453 const char* hostname_cstr,
1454 uint64_t reference_time) {
1455 if(required_strength == 0) {
1456 required_strength = 110;
1457 }
1458
1459#if defined(BOTAN_HAS_X509_CERTIFICATES)
1460 return ffi_guard_thunk(__func__, [=]() -> int {
1461 const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);
1463 const auto validation_time = reference_time == 0
1464 ? std::chrono::system_clock::now()
1465 : std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));
1466
1467 std::vector<Botan::X509_Certificate> end_certs;
1468 end_certs.push_back(safe_get(cert));
1469 for(size_t i = 0; i != intermediates_len; ++i) {
1470 end_certs.push_back(safe_get(intermediates[i]));
1471 }
1472
1473 std::unique_ptr<Botan::Certificate_Store> trusted_from_path;
1474 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra;
1475 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_crls;
1476 std::vector<Botan::Certificate_Store*> trusted_roots;
1477
1478 if(trusted_path != nullptr && *trusted_path != 0) {
1479 trusted_from_path = std::make_unique<Botan::Certificate_Store_In_Memory>(trusted_path);
1480 trusted_roots.push_back(trusted_from_path.get());
1481 }
1482
1483 if(trusted_len > 0) {
1484 trusted_extra = std::make_unique<Botan::Certificate_Store_In_Memory>();
1485 for(size_t i = 0; i != trusted_len; ++i) {
1486 trusted_extra->add_certificate(safe_get(trusted[i]));
1487 }
1488 trusted_roots.push_back(trusted_extra.get());
1489 }
1490
1491 if(crls_len > 0) {
1492 trusted_crls = std::make_unique<Botan::Certificate_Store_In_Memory>();
1493 for(size_t i = 0; i != crls_len; ++i) {
1494 trusted_crls->add_crl(safe_get(crls[i]));
1495 }
1496 trusted_roots.push_back(trusted_crls.get());
1497 }
1498
1499 const Botan::Path_Validation_Restrictions restrictions(false, required_strength);
1500
1501 auto validation_result =
1502 Botan::x509_path_validate(end_certs, restrictions, trusted_roots, hostname, usage, validation_time);
1503
1504 if(result_code != nullptr) {
1505 *result_code = static_cast<int>(validation_result.result());
1506 }
1507
1508 if(validation_result.successful_validation()) {
1509 return 0;
1510 } else {
1511 return 1;
1512 }
1513 });
1514#else
1515 BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);
1516 BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time, crls, crls_len);
1518#endif
1519}
1520}
#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:198
const std::set< uint32_t > & ipv4_address() const
Return the set of IPv4 addresses included in this alternative name.
Definition pkix_types.h:186
const std::set< std::string > & uris() const
Return the set of URIs included in this alternative name.
Definition pkix_types.h:177
const std::set< std::string > & dns() const
Return the set of DNS names included in this alternative name.
Definition pkix_types.h:183
const std::set< IPv6Address > & ipv6_address() const
Return the set of IPv6 addresses included in this alternative name.
Definition pkix_types.h:189
const std::set< std::string > & email() const
Return the set of email addresses included in this alternative name.
Definition pkix_types.h:180
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:126
const X509_Time & expire_time() const
Definition crl_ent.cpp:122
const std::vector< uint8_t > & serial_number() const
Definition crl_ent.cpp:118
const std::vector< Distribution_Point > & distribution_points() const
Definition x509_ext.h:450
bool extension_set(const OID &oid) const
Definition x509_ext.cpp:211
X.509 GeneralName Type.
Definition pkix_types.h:286
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
static GeneralName ipv6_address(const IPv6Address &ipv6)
NameType type_code() const
Definition pkix_types.h:328
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:449
const std::vector< GeneralSubtree > & excluded() const
Definition pkix_types.h:456
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:220
const std::vector< uint8_t > & authority_key_id() const
Definition x509_crl.cpp:238
uint32_t crl_number() const
Definition x509_crl.cpp:245
const X509_DN & issuer_dn() const
Definition x509_crl.cpp:231
const NameConstraints & name_constraints() const
Definition x509cert.cpp:473
const std::vector< uint8_t > & serial_number() const
Definition x509cert.cpp:406
const std::vector< uint8_t > & authority_key_id() const
Definition x509cert.cpp:398
const AlternativeName & issuer_alt_name() const
Definition x509cert.cpp:606
const std::vector< uint8_t > & raw_subject_dn() const
Definition x509cert.cpp:426
const std::vector< uint8_t > & subject_key_id() const
Definition x509cert.cpp:402
const Extensions & v3_extensions() const
Definition x509cert.cpp:477
const std::vector< uint8_t > & raw_issuer_dn() const
Definition x509cert.cpp:422
const AlternativeName & subject_alt_name() const
Definition x509cert.cpp:602
const std::vector< uint8_t > & subject_public_key_info() const
Definition x509cert.cpp:382
const std::vector< uint8_t > & get_bits() const
Definition pkix_types.h:84
struct botan_pubkey_struct * botan_pubkey_t
Definition ffi.h:1797
struct botan_asn1_oid_struct * botan_asn1_oid_t
Definition ffi.h:1253
struct botan_privkey_struct * botan_privkey_t
Definition ffi.h:1564
struct botan_x509_crl_entry_struct * botan_x509_crl_entry_t
Definition ffi.h:2702
struct botan_x509_crl_struct * botan_x509_crl_t
Definition ffi.h:2701
struct botan_x509_general_name_struct * botan_x509_general_name_t
Definition ffi.h:2570
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:559
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:2387
@ BOTAN_X509_DNS_NAME
Definition ffi.h:2580
@ BOTAN_X509_DIRECTORY_NAME
Definition ffi.h:2581
@ BOTAN_X509_OTHER_NAME
Definition ffi.h:2578
@ BOTAN_X509_EMAIL_ADDRESS
Definition ffi.h:2579
@ BOTAN_X509_IP_ADDRESS
Definition ffi.h:2583
@ BOTAN_X509_URI
Definition ffi.h:2582
struct botan_mp_struct * botan_mp_t
Definition ffi.h:1032
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:723
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:2402
@ BOTAN_X509_AUTHORITY_KEY_IDENTIFIER
Definition ffi.h:2407
@ BOTAN_X509_SUBJECT_KEY_IDENTIFIER
Definition ffi.h:2406
@ BOTAN_X509_TBS_DATA_BITS
Definition ffi.h:2410
@ BOTAN_X509_SIGNATURE_BITS
Definition ffi.h:2412
@ BOTAN_X509_PUBLIC_KEY_PKCS8_BITS
Definition ffi.h:2409
@ BOTAN_X509_DER_ENCODING
Definition ffi.h:2414
@ BOTAN_X509_PEM_ENCODING
Definition ffi.h:2415
@ BOTAN_X509_OCSP_RESPONDER_URLS
Definition ffi.h:2418
@ BOTAN_X509_SIGNATURE_SCHEME_BITS
Definition ffi.h:2411
@ BOTAN_X509_SUBJECT_DN_BITS
Definition ffi.h:2404
@ BOTAN_X509_CRL_DISTRIBUTION_URLS
Definition ffi.h:2417
@ BOTAN_X509_SERIAL_NUMBER
Definition ffi.h:2403
@ BOTAN_X509_ISSUER_DN_BITS
Definition ffi.h:2405
@ BOTAN_X509_CA_ISSUERS_URLS
Definition ffi.h:2419
int botan_x509_cert_get_subject_dn_count(botan_x509_cert_t cert, const char *key, size_t *count)
Definition ffi_cert.cpp:539
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:607
int botan_x509_cert_load_file(botan_x509_cert_t *cert_obj, const char *cert_path)
Definition ffi_cert.cpp:177
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:803
int botan_x509_cert_dup(botan_x509_cert_t *cert_obj, botan_x509_cert_t cert)
Definition ffi_cert.cpp:194
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:502
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:946
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:781
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:341
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:463
int botan_x509_cert_allowed_extended_usage_oid(botan_x509_cert_t cert, botan_asn1_oid_t oid)
Definition ffi_cert.cpp:598
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:286
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:701
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:481
int botan_x509_cert_subject_alternative_names_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:907
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:847
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:882
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:921
int botan_x509_cert_serial_number(botan_x509_cert_t cert, botan_mp_t *serial_number)
Definition ffi_cert.cpp:669
int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:626
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:812
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:559
int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:616
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:212
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:518
int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t *time_since_epoch)
Definition ffi_cert.cpp:636
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:973
int botan_x509_cert_excluded_name_constraints_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:869
int botan_x509_cert_is_ca(botan_x509_cert_t cert)
Definition ffi_cert.cpp:434
int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char *hostname)
Definition ffi_cert.cpp:960
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:660
int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:710
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:583
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:723
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:568
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:422
int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t *time_since_epoch)
Definition ffi_cert.cpp:648
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:758
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:719
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:685
int botan_x509_cert_get_path_length_constraint(botan_x509_cert_t cert, size_t *path_limit)
Definition ffi_cert.cpp:443
int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:555
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:733
int botan_x509_cert_permitted_name_constraints_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:834
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:353
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:158
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:188
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:166
std::string PEM_encode(const Private_Key &key)
Definition pkcs8.cpp:121
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, std::span< const uint8_t > buf)
Definition ffi_util.h:190
int copy_view_bin(uint8_t out[], size_t *out_len, Fn fn, Args... args)
Definition ffi_util.h:214
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:220
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:264
int write_str_output(char out[], size_t *out_len, const std::string &str)
Definition ffi_util.h:268
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:933
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