Botan 3.13.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/stl_util.h>
25#endif
26
27#if defined(BOTAN_HAS_X509_CERTIFICATES)
28
29namespace Botan_FFI {
30
31namespace {
32
33/**
34 * As specified in RFC 5280 Section 4.2.1.6. alternative names essentially are a
35 * collection of GeneralNames. This allows mapping a single entry of @p altnames
36 * to a GeneralName by its @p index. If the index is out of range, std::nullopt
37 * is returned.
38 *
39 * NOTE: if the set of alternative name types handled here is extended,
40 * count_general_names_in() must be updated accordingly!
41 */
42std::optional<Botan::GeneralName> extract_general_name_at(const Botan::AlternativeName& altnames, size_t index) {
43 if(index < altnames.email_addresses().size()) {
44 auto itr = altnames.email_addresses().begin();
45 std::advance(itr, index);
46 return Botan::GeneralName::email(itr->to_string());
47 }
48 index -= altnames.email_addresses().size();
49
50 if(index < altnames.dns_names().size()) {
51 auto itr = altnames.dns_names().begin();
52 std::advance(itr, index);
53 return Botan::GeneralName::_dns_san_value(itr->to_string());
54 }
55 index -= altnames.dns_names().size();
56
57 if(index < altnames.directory_names().size()) {
58 auto itr = altnames.directory_names().begin();
59 std::advance(itr, index);
61 }
62 index -= altnames.directory_names().size();
63
64 if(index < altnames.uri_names().size()) {
65 auto itr = altnames.uri_names().begin();
66 std::advance(itr, index);
67 return Botan::GeneralName::_uri_san_value(itr->original_input());
68 }
69 index -= altnames.uri_names().size();
70
71 if(index < altnames.ipv4_addresses().size()) {
72 auto itr = altnames.ipv4_addresses().begin();
73 std::advance(itr, index);
75 }
76 index -= altnames.ipv4_addresses().size();
77
78 if(index < altnames.ipv6_addresses().size()) {
79 auto itr = altnames.ipv6_addresses().begin();
80 std::advance(itr, index);
82 }
83
84 return std::nullopt;
85}
86
87/**
88 * Counts the total number of GeneralNames contained in the given
89 * AlternativeName @p alt_names.
90 *
91 * NOTE: if the set of alternative name types handled here is extended,
92 * extract_general_name_at() must be updated accordingly!
93 */
94size_t count_general_names_in(const Botan::AlternativeName& alt_names) {
95 return alt_names.email_addresses().size() + alt_names.dns_names().size() + alt_names.directory_names().size() +
96 alt_names.uri_names().size() + alt_names.ipv4_addresses().size() + alt_names.ipv6_addresses().size();
97}
98
99std::optional<botan_x509_general_name_types> to_botan_x509_general_name_types(Botan::GeneralName::NameType gn_type) {
100 using Type = Botan::GeneralName::NameType;
101 switch(gn_type) {
102 case Type::Unknown:
103 return std::nullopt;
104 case Type::RFC822:
106 case Type::DNS:
107 return BOTAN_X509_DNS_NAME;
108 case Type::URI:
109 return BOTAN_X509_URI;
110 case Type::DN:
112 case Type::IPv4:
113 case Type::IPv6:
115 case Type::Other:
117 }
118
120}
121
122/**
123 * Given some enumerator-style function @p fn, count how many values it can
124 * produce before returning BOTAN_FFI_ERROR_OUT_OF_RANGE. If the first call to
125 * @p fn returns BOTAN_FFI_ERROR_NO_VALUE, zero is written to @p count.
126 *
127 * If this function returns BOTAN_FFI_SUCCESS, @p count contains the number of
128 * values that can be enumerated. Otherwise, the value of @p count is undefined.
129 */
130template <std::invocable<size_t> EnumeratorT>
131int enumerator_count_values(size_t* count, EnumeratorT fn) {
132 if(Botan::any_null_pointers(count)) {
134 }
135
136 *count = 0;
137 for(;; ++(*count)) {
138 const auto rc = fn(*count);
139 switch(rc) {
142 // hit the end of the enumeration
143 return BOTAN_FFI_SUCCESS;
145 // got a value, continue counting
146 break;
147 default:
148 // unexpected error from enumerator function
149 return rc;
150 }
151 }
152}
153
154std::chrono::system_clock::time_point timepoint_from_timestamp(uint64_t time_since_epoch) {
155 return std::chrono::system_clock::time_point(std::chrono::seconds(time_since_epoch));
156}
157
158std::string default_from_ptr(const char* value) {
159 std::string ret;
160 if(value != nullptr) {
161 ret = value;
162 }
163 return ret;
164}
165
166} // namespace
167
168} // namespace Botan_FFI
169
170#endif
171
172extern "C" {
173
174using namespace Botan_FFI;
175
176int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* cert_path) {
177 if(Botan::any_null_pointers(cert_obj, cert_path)) {
179 }
180
181#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
182
183 return ffi_guard_thunk(__func__, [=]() -> int {
184 auto c = std::make_unique<Botan::X509_Certificate>(cert_path);
185 return ffi_new_object(cert_obj, std::move(c));
186 });
187
188#else
190#endif
191}
192
194 if(cert_obj == nullptr) {
196 }
197
198#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
199
200 return ffi_guard_thunk(__func__, [=]() -> int {
201 auto c = std::make_unique<Botan::X509_Certificate>(safe_get(cert));
202 return ffi_new_object(cert_obj, std::move(c));
203 });
204
205#else
206 BOTAN_UNUSED(cert);
208#endif
209}
210
211int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert_bits[], size_t cert_bits_len) {
212 if(Botan::any_null_pointers(cert_obj, cert_bits)) {
214 }
215
216#if defined(BOTAN_HAS_X509_CERTIFICATES)
217 return ffi_guard_thunk(__func__, [=]() -> int {
218 Botan::DataSource_Memory bits(cert_bits, cert_bits_len);
219 auto c = std::make_unique<Botan::X509_Certificate>(bits);
220 return ffi_new_object(cert_obj, std::move(c));
221 });
222#else
223 BOTAN_UNUSED(cert_bits_len);
225#endif
226}
227}
228
229namespace {
230
231#if defined(BOTAN_HAS_X509_CERTIFICATES)
232
233int botan_x509_object_view_value(const Botan::X509_Object& object,
234 botan_x509_value_type value_type,
235 size_t index,
236 botan_view_ctx ctx,
237 botan_view_str_fn view_fn) {
238 if(index != 0) {
239 // As of now there are no multi-value generic string entries.
241 }
242
243 auto view = [=](const std::string& value) { return invoke_view_callback(view_fn, ctx, value); };
244
245 switch(value_type) {
247 return view(object.PEM_encode());
248 default:
249 BOTAN_ASSERT_UNREACHABLE(); /* called with unexpected (non-generic) value_type */
250 }
251}
252
253int botan_x509_object_view_value(const Botan::X509_Object& object,
254 botan_x509_value_type value_type,
255 size_t index,
256 botan_view_ctx ctx,
257 botan_view_bin_fn view_fn) {
258 if(index != 0) {
259 // As of now there are no multi-value generic binary entries.
261 }
262
263 auto view = [=](std::span<const uint8_t> value) { return invoke_view_callback(view_fn, ctx, value); };
264
265 switch(value_type) {
267 return view(object.tbs_data());
269 return view(object.signature_algorithm().BER_encode());
271 return view(object.signature());
273 return view(object.BER_encode());
274 default:
275 BOTAN_ASSERT_UNREACHABLE(); /* called with unexpected (non-generic) value_type */
276 }
277}
278
279#endif
280
281} // namespace
282
283extern "C" {
284
286 botan_x509_value_type value_type,
287 size_t index,
288 botan_view_ctx ctx,
289 botan_view_bin_fn view_fn) {
290#if defined(BOTAN_HAS_X509_CERTIFICATES)
291 if(index != 0) {
292 // As of now there are no multi-value binary entries.
294 }
295
296 auto view = [=](std::span<const uint8_t> value) -> int {
297 if(value.empty()) {
299 } else {
300 return invoke_view_callback(view_fn, ctx, value);
301 }
302 };
303
304 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) -> int {
305 switch(value_type) {
307 return view(c.serial_number());
309 return view(c.raw_subject_dn());
311 return view(c.raw_issuer_dn());
313 return view(c.subject_key_id());
315 return view(c.authority_key_id());
317 return view(c.subject_public_key_info());
318
323 return botan_x509_object_view_value(c, value_type, index, ctx, view_fn);
324
330 }
331
333 });
334#else
335 BOTAN_UNUSED(cert, value_type, index, ctx, view_fn);
337#endif
338}
339
341#if defined(BOTAN_HAS_X509_CERTIFICATES)
342 return enumerator_count_values(count, [=](size_t index) {
344 cert, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
345 });
346#else
347 BOTAN_UNUSED(cert, value_type, count);
349#endif
350}
351
353 botan_x509_value_type value_type,
354 size_t index,
355 botan_view_ctx ctx,
356 botan_view_str_fn view_fn) {
357#if defined(BOTAN_HAS_X509_CERTIFICATES)
358 auto enumerate_uris = [view_fn, ctx](const std::vector<Botan::URI>& values, size_t idx) -> int {
359 if(idx >= values.size()) {
361 } else {
362 return invoke_view_callback(view_fn, ctx, values[idx].original_input());
363 }
364 };
365
366 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) -> int {
367 switch(value_type) {
369 return enumerate_uris(c.crl_distribution_point_uris(), index);
371 return enumerate_uris(c.ocsp_responder_uris(), index);
373 return enumerate_uris(c.ca_issuer_uris(), index);
375 return botan_x509_object_view_value(c, value_type, index, ctx, view_fn);
376
388 }
389
391 });
392#else
393 BOTAN_UNUSED(cert, value_type, index, ctx, view_fn);
395#endif
396}
397
399#if defined(BOTAN_HAS_X509_CERTIFICATES)
400 return enumerator_count_values(count, [=](size_t index) {
402 cert, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
403 });
404#else
405 BOTAN_UNUSED(cert, value_type, count);
407#endif
408}
409
411#if defined(BOTAN_HAS_X509_CERTIFICATES)
412 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return c.is_CA_cert() ? 1 : 0; });
413#else
414 BOTAN_UNUSED(cert);
416#endif
417}
418
420#if defined(BOTAN_HAS_X509_CERTIFICATES)
421 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
422 if(Botan::any_null_pointers(path_limit)) {
424 }
425
426 if(const auto path_len = c.path_length_constraint()) {
427 *path_limit = path_len.value();
428 return BOTAN_FFI_SUCCESS;
429 } else {
431 }
432 });
433#else
434 BOTAN_UNUSED(cert, path_limit);
436#endif
437}
438
440 if(key == nullptr) {
442 }
443
444 *key = nullptr;
445
446#if defined(BOTAN_HAS_X509_CERTIFICATES)
447 return ffi_guard_thunk(__func__, [=]() -> int {
448 auto public_key = safe_get(cert).subject_public_key();
449 return ffi_new_object(key, std::move(public_key));
450 });
451#else
452 BOTAN_UNUSED(cert);
454#endif
455}
456
458 botan_x509_cert_t cert, const char* key, size_t index, uint8_t out[], size_t* out_len) {
459 if(key == nullptr) {
461 }
462#if defined(BOTAN_HAS_X509_CERTIFICATES)
463 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
464 auto issuer_info = c.issuer_info(key);
465 if(index < issuer_info.size()) {
466 // TODO(Botan4) change the type of out and remove this cast
467 return write_str_output(reinterpret_cast<char*>(out), out_len, c.issuer_info(key).at(index));
468 } else {
469 return BOTAN_FFI_ERROR_BAD_PARAMETER; // TODO(Botan4): use BOTAN_FFI_ERROR_OUT_OF_RANGE
470 }
471 });
472#else
473 BOTAN_UNUSED(cert, key, index, out, out_len);
475#endif
476}
477
478int botan_x509_cert_get_issuer_dn_count(botan_x509_cert_t cert, const char* key, size_t* count) {
479#if defined(BOTAN_HAS_X509_CERTIFICATES)
480 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
481 if(Botan::any_null_pointers(key, count)) {
483 }
484
485 *count = c.issuer_info(key).size();
486 return BOTAN_FFI_SUCCESS;
487 });
488#else
489 BOTAN_UNUSED(cert, key, count);
491#endif
492}
493
495 botan_x509_cert_t cert, const char* key, size_t index, uint8_t out[], size_t* out_len) {
496 if(key == nullptr) {
498 }
499#if defined(BOTAN_HAS_X509_CERTIFICATES)
500 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
501 auto subject_info = c.subject_info(key);
502 if(index < subject_info.size()) {
503 // TODO(Botan4) change the type of out and remove this cast
504 return write_str_output(reinterpret_cast<char*>(out), out_len, c.subject_info(key).at(index));
505 } else {
506 return BOTAN_FFI_ERROR_BAD_PARAMETER; // TODO(Botan4): use BOTAN_FFI_ERROR_OUT_OF_RANGE
507 }
508 });
509#else
510 BOTAN_UNUSED(cert, key, index, out, out_len);
512#endif
513}
514
515int botan_x509_cert_get_subject_dn_count(botan_x509_cert_t cert, const char* key, size_t* count) {
516#if defined(BOTAN_HAS_X509_CERTIFICATES)
517 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
518 if(Botan::any_null_pointers(key, count)) {
520 }
521
522 *count = c.subject_info(key).size();
523 return BOTAN_FFI_SUCCESS;
524 });
525#else
526 BOTAN_UNUSED(cert, key, count);
528#endif
529}
530
531int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len) {
532 return copy_view_str(reinterpret_cast<uint8_t*>(out), out_len, botan_x509_cert_view_as_string, cert);
533}
534
536#if defined(BOTAN_HAS_X509_CERTIFICATES)
537 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return invoke_view_callback(view, ctx, c.to_string()); });
538#else
539 BOTAN_UNUSED(cert, ctx, view);
541#endif
542}
543
544int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage) {
545#if defined(BOTAN_HAS_X509_CERTIFICATES)
546 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
547 const Botan::Key_Constraints k = static_cast<Botan::Key_Constraints>(key_usage);
548 if(c.allowed_usage(k)) {
549 return BOTAN_FFI_SUCCESS;
550 }
551 return 1;
552 });
553#else
554 BOTAN_UNUSED(cert, key_usage);
556#endif
557}
558
560#if defined(BOTAN_HAS_X509_CERTIFICATES)
561 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int {
562 if(Botan::any_null_pointers(oid)) {
564 }
565
566 return c.has_ex_constraint(oid) ? 1 : 0;
567 });
568#else
569 BOTAN_UNUSED(cert, oid);
571#endif
572}
573
575#if defined(BOTAN_HAS_X509_CERTIFICATES)
576 return BOTAN_FFI_VISIT(cert, [=](const auto& c) -> int { return c.has_ex_constraint(safe_get(oid)) ? 1 : 0; });
577#else
578 BOTAN_UNUSED(cert, oid);
580#endif
581}
582
584#if defined(BOTAN_HAS_X509_CERTIFICATES)
585 return BOTAN_FFI_CHECKED_DELETE(cert);
586#else
587 BOTAN_UNUSED(cert);
589#endif
590}
591
592int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len) {
593#if defined(BOTAN_HAS_X509_CERTIFICATES)
594 return BOTAN_FFI_VISIT(cert,
595 [=](const auto& c) { return write_str_output(out, out_len, c.not_before().to_string()); });
596#else
597 BOTAN_UNUSED(cert, out, out_len);
599#endif
600}
601
602int botan_x509_cert_get_time_expires(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_after().to_string()); });
606#else
607 BOTAN_UNUSED(cert, out, out_len);
609#endif
610}
611
612int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t* time_since_epoch) {
613 if(time_since_epoch == nullptr) {
615 }
616#if defined(BOTAN_HAS_X509_CERTIFICATES)
617 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *time_since_epoch = c.not_before().time_since_epoch(); });
618#else
619 BOTAN_UNUSED(cert, time_since_epoch);
621#endif
622}
623
624int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t* time_since_epoch) {
625 if(time_since_epoch == nullptr) {
627 }
628#if defined(BOTAN_HAS_X509_CERTIFICATES)
629 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *time_since_epoch = c.not_after().time_since_epoch(); });
630#else
631 BOTAN_UNUSED(cert, time_since_epoch);
633#endif
634}
635
636int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
637#if defined(BOTAN_HAS_X509_CERTIFICATES)
638 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.serial_number()); });
639#else
640 BOTAN_UNUSED(cert, out, out_len);
642#endif
643}
644
646#if defined(BOTAN_HAS_X509_CERTIFICATES)
647 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
648 if(Botan::any_null_pointers(serial_number)) {
650 }
651
652 auto serial_bn = c.serial().to_bigint();
653 return ffi_new_object(serial_number, std::make_unique<Botan::BigInt>(std::move(serial_bn)));
654 });
655#else
656 BOTAN_UNUSED(cert, serial_number);
658#endif
659}
660
661int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len) {
662 if(hash == nullptr) {
664 }
665#if defined(BOTAN_HAS_X509_CERTIFICATES)
666 // TODO(Botan4) change the type of out and remove this cast
667
668 return BOTAN_FFI_VISIT(cert, [=](const auto& c) {
669 return write_str_output(reinterpret_cast<char*>(out), out_len, c.fingerprint(hash));
670 });
671#else
672 BOTAN_UNUSED(cert, hash, out, out_len);
674#endif
675}
676
677int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
678#if defined(BOTAN_HAS_X509_CERTIFICATES)
679 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.authority_key_id()); });
680#else
681 BOTAN_UNUSED(cert, out, out_len);
683#endif
684}
685
686int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
687#if defined(BOTAN_HAS_X509_CERTIFICATES)
688 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return write_vec_output(out, out_len, c.subject_key_id()); });
689#else
690 BOTAN_UNUSED(cert, out, out_len);
692#endif
693}
694
695int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) {
696 return copy_view_bin(out, out_len, botan_x509_cert_view_public_key_bits, cert);
697}
698
700#if defined(BOTAN_HAS_X509_CERTIFICATES)
701 return BOTAN_FFI_VISIT(cert,
702 [=](const auto& c) { return invoke_view_callback(view, ctx, c.subject_public_key_bits()); });
703#else
704 BOTAN_UNUSED(cert, ctx, view);
706#endif
707}
708
710#if defined(BOTAN_HAS_X509_CERTIFICATES)
711 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) {
712 if(Botan::any_null_pointers(type)) {
714 }
715
716 const auto mapped_type = to_botan_x509_general_name_types(n.type_code());
717 if(!mapped_type.has_value()) {
719 }
720
721 *type = mapped_type.value();
722 if(*type == BOTAN_X509_OTHER_NAME /* ... viewing of other-names not supported */) {
724 }
725
726 return BOTAN_FFI_SUCCESS;
727 });
728#else
729 BOTAN_UNUSED(name, type);
731#endif
732}
733
735 botan_view_ctx ctx,
736 botan_view_str_fn view) {
737#if defined(BOTAN_HAS_X509_CERTIFICATES)
738 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) -> int {
739 const auto type = to_botan_x509_general_name_types(n.type_code());
740 if(!type) {
742 }
743
744 if(type != BOTAN_X509_EMAIL_ADDRESS && type != BOTAN_X509_DNS_NAME && type != BOTAN_X509_URI &&
745 type != BOTAN_X509_IP_ADDRESS) {
747 }
748
749 return invoke_view_callback(view, ctx, n.name());
750 });
751#else
752 BOTAN_UNUSED(name, ctx, view);
754#endif
755}
756
758 botan_view_ctx ctx,
759 botan_view_bin_fn view) {
760#if defined(BOTAN_HAS_X509_CERTIFICATES)
761 return BOTAN_FFI_VISIT(name, [=](const Botan::GeneralName& n) -> int {
762 const auto type = to_botan_x509_general_name_types(n.type_code());
763 if(!type) {
765 }
766
767 if(type != BOTAN_X509_DIRECTORY_NAME && type != BOTAN_X509_IP_ADDRESS) {
769 }
770
771 return invoke_view_callback(view, ctx, n.binary_name());
772 });
773#else
774 BOTAN_UNUSED(name, ctx, view);
776#endif
777}
778
780#if defined(BOTAN_HAS_X509_CERTIFICATES)
781 return BOTAN_FFI_CHECKED_DELETE(name);
782#else
783 BOTAN_UNUSED(name);
785#endif
786}
787
789 size_t index,
790 botan_x509_general_name_t* constraint) {
791#if defined(BOTAN_HAS_X509_CERTIFICATES)
792 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
793 if(Botan::any_null_pointers(constraint)) {
795 }
796
797 const auto& constraints = c.name_constraints().permitted();
798 if(index >= constraints.size()) {
800 }
801
802 return ffi_new_object(constraint, std::make_unique<Botan::GeneralName>(constraints[index].base()));
803 });
804#else
805 BOTAN_UNUSED(cert, index, constraint);
807#endif
808}
809
811#if defined(BOTAN_HAS_X509_CERTIFICATES)
812 if(Botan::any_null_pointers(count)) {
814 }
815
816 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *count = c.name_constraints().permitted().size(); });
817#else
818 BOTAN_UNUSED(cert, count);
820#endif
821}
822
824 size_t index,
825 botan_x509_general_name_t* constraint) {
826#if defined(BOTAN_HAS_X509_CERTIFICATES)
827 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
828 if(Botan::any_null_pointers(constraint)) {
830 }
831
832 const auto& constraints = c.name_constraints().excluded();
833 if(index >= constraints.size()) {
835 }
836
837 return ffi_new_object(constraint, std::make_unique<Botan::GeneralName>(constraints[index].base()));
838 });
839#else
840 BOTAN_UNUSED(cert, index, constraint);
842#endif
843}
844
846#if defined(BOTAN_HAS_X509_CERTIFICATES)
847 if(Botan::any_null_pointers(count)) {
849 }
850
851 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { *count = c.name_constraints().excluded().size(); });
852#else
853 BOTAN_UNUSED(cert, count);
855#endif
856}
857
859 size_t index,
860 botan_x509_general_name_t* alt_name) {
861#if defined(BOTAN_HAS_X509_CERTIFICATES)
862 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
863 if(Botan::any_null_pointers(alt_name)) {
865 }
866
867 if(!c.v3_extensions().extension_set(Botan::OID::from_string("X509v3.SubjectAlternativeName"))) {
869 }
870
871 if(auto name = extract_general_name_at(c.subject_alt_name(), index)) {
872 return ffi_new_object(alt_name, std::make_unique<Botan::GeneralName>(std::move(name).value()));
873 }
874
876 });
877#else
878 BOTAN_UNUSED(cert, index, alt_name);
880#endif
881}
882
884#if defined(BOTAN_HAS_X509_CERTIFICATES)
885 if(Botan::any_null_pointers(count)) {
887 }
888
889 return BOTAN_FFI_VISIT(
890 cert, [=](const Botan::X509_Certificate& c) { *count = count_general_names_in(c.subject_alt_name()); });
891#else
892 BOTAN_UNUSED(cert, count);
894#endif
895}
896
898 size_t index,
899 botan_x509_general_name_t* alt_name) {
900#if defined(BOTAN_HAS_X509_CERTIFICATES)
901 return BOTAN_FFI_VISIT(cert, [=](const Botan::X509_Certificate& c) {
902 if(Botan::any_null_pointers(alt_name)) {
904 }
905
906 if(!c.v3_extensions().extension_set(Botan::OID::from_string("X509v3.IssuerAlternativeName"))) {
908 }
909
910 if(auto name = extract_general_name_at(c.issuer_alt_name(), index)) {
911 return ffi_new_object(alt_name, std::make_unique<Botan::GeneralName>(std::move(name).value()));
912 }
913
915 });
916#else
917 BOTAN_UNUSED(cert, index, alt_name);
919#endif
920}
921
923#if defined(BOTAN_HAS_X509_CERTIFICATES)
924 if(Botan::any_null_pointers(count)) {
926 }
927
928 return BOTAN_FFI_VISIT(
929 cert, [=](const Botan::X509_Certificate& c) { *count = count_general_names_in(c.issuer_alt_name()); });
930#else
931 BOTAN_UNUSED(cert, count);
933#endif
934}
935
936int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char* hostname) {
937 if(hostname == nullptr) {
939 }
940
941#if defined(BOTAN_HAS_X509_CERTIFICATES)
942 return BOTAN_FFI_VISIT(cert, [=](const auto& c) { return c.matches_dns_name(hostname) ? 0 : -1; });
943#else
944 BOTAN_UNUSED(cert);
946#endif
947}
948
949int botan_x509_cert_verify(int* result_code,
951 const botan_x509_cert_t* intermediates,
952 size_t intermediates_len,
953 const botan_x509_cert_t* trusted,
954 size_t trusted_len,
955 const char* trusted_path,
956 size_t required_strength,
957 const char* hostname_cstr,
958 uint64_t reference_time) {
959 if(required_strength == 0) {
960 required_strength = 110;
961 }
962
963#if defined(BOTAN_HAS_X509_CERTIFICATES)
964 return ffi_guard_thunk(__func__, [=]() -> int {
965 const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);
967 const auto validation_time = reference_time == 0
968 ? std::chrono::system_clock::now()
969 : std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));
970
971 if(intermediates_len > 0 && intermediates == nullptr) {
973 }
974 if(trusted_len > 0 && trusted == nullptr) {
976 }
977
978 std::vector<Botan::X509_Certificate> end_certs;
979 end_certs.push_back(safe_get(cert));
980 for(size_t i = 0; i != intermediates_len; ++i) {
981 end_certs.push_back(safe_get(intermediates[i]));
982 }
983
984 std::unique_ptr<Botan::Certificate_Store> trusted_from_path;
985 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra;
986 std::vector<Botan::Certificate_Store*> trusted_roots;
987
988 if(trusted_path != nullptr && *trusted_path != 0) {
989 trusted_from_path = std::make_unique<Botan::Certificate_Store_In_Memory>(trusted_path);
990 trusted_roots.push_back(trusted_from_path.get());
991 }
992
993 if(trusted_len > 0) {
994 trusted_extra = std::make_unique<Botan::Certificate_Store_In_Memory>();
995 for(size_t i = 0; i != trusted_len; ++i) {
996 trusted_extra->add_certificate(safe_get(trusted[i]));
997 }
998 trusted_roots.push_back(trusted_extra.get());
999 }
1000
1001 const Botan::Path_Validation_Restrictions restrictions(false, required_strength);
1002
1003 auto validation_result =
1004 Botan::x509_path_validate(end_certs, restrictions, trusted_roots, hostname, usage, validation_time);
1005
1006 if(result_code != nullptr) {
1007 *result_code = static_cast<int>(validation_result.result());
1008 }
1009
1010 if(validation_result.successful_validation()) {
1011 return 0;
1012 } else {
1013 return 1;
1014 }
1015 });
1016#else
1017 BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);
1018 BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time);
1020#endif
1021}
1022
1024 if(code < 0) {
1025 return nullptr;
1026 }
1027
1028#if defined(BOTAN_HAS_X509_CERTIFICATES)
1030 return Botan::to_string(sc);
1031#else
1032 return nullptr;
1033#endif
1034}
1035
1036int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path) {
1037 if(Botan::any_null_pointers(crl_obj, crl_path)) {
1039 }
1040
1041#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
1042
1043 return ffi_guard_thunk(__func__, [=]() -> int {
1044 auto c = std::make_unique<Botan::X509_CRL>(crl_path);
1045 return ffi_new_object(crl_obj, std::move(c));
1046 });
1047
1048#else
1050#endif
1051}
1052
1053int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len) {
1054 if(Botan::any_null_pointers(crl_obj, crl_bits)) {
1056 }
1057
1058#if defined(BOTAN_HAS_X509_CERTIFICATES)
1059 return ffi_guard_thunk(__func__, [=]() -> int {
1060 Botan::DataSource_Memory bits(crl_bits, crl_bits_len);
1061 auto c = std::make_unique<Botan::X509_CRL>(bits);
1062 return ffi_new_object(crl_obj, std::move(c));
1063 });
1064#else
1065 BOTAN_UNUSED(crl_bits_len);
1067#endif
1068}
1069
1070int botan_x509_crl_this_update(botan_x509_crl_t crl, uint64_t* time_since_epoch) {
1071#if defined(BOTAN_HAS_X509_CERTIFICATES)
1072 return BOTAN_FFI_VISIT(crl, [=](const auto& c) {
1073 if(Botan::any_null_pointers(time_since_epoch)) {
1075 }
1076 *time_since_epoch = c.this_update().time_since_epoch();
1077 return BOTAN_FFI_SUCCESS;
1078 });
1079#else
1080 BOTAN_UNUSED(crl, time_since_epoch);
1082#endif
1083}
1084
1085int botan_x509_crl_next_update(botan_x509_crl_t crl, uint64_t* time_since_epoch) {
1086#if defined(BOTAN_HAS_X509_CERTIFICATES)
1087 return BOTAN_FFI_VISIT(crl, [=](const auto& c) {
1088 const auto& time = c.next_update();
1089 if(!time.time_is_set()) {
1091 }
1092
1093 if(Botan::any_null_pointers(time_since_epoch)) {
1095 }
1096
1097 *time_since_epoch = c.next_update().time_since_epoch();
1098 return BOTAN_FFI_SUCCESS;
1099 });
1100#else
1101 BOTAN_UNUSED(crl, time_since_epoch);
1103#endif
1104}
1105
1107 botan_rng_t rng,
1108 botan_x509_cert_t ca_cert,
1109 botan_privkey_t ca_key,
1110 uint64_t issue_time,
1111 uint32_t next_update,
1112 const char* hash_fn,
1113 const char* padding) {
1114 if(Botan::any_null_pointers(crl_obj)) {
1116 }
1117#if defined(BOTAN_HAS_X509_CERTIFICATES)
1118 return ffi_guard_thunk(__func__, [=]() -> int {
1119 auto& rng_ = safe_get(rng);
1120 auto ca = Botan::X509_CA(
1121 safe_get(ca_cert), safe_get(ca_key), default_from_ptr(hash_fn), default_from_ptr(padding), rng_);
1122 auto crl = std::make_unique<Botan::X509_CRL>(
1123 ca.new_crl(rng_, timepoint_from_timestamp(issue_time), std::chrono::seconds(next_update)));
1124 return ffi_new_object(crl_obj, std::move(crl));
1125 });
1126#else
1127 BOTAN_UNUSED(rng, ca_cert, ca_key, hash_fn, padding, issue_time, next_update);
1129#endif
1130}
1131
1133 if(Botan::any_null_pointers(entry)) {
1135 }
1136#if defined(BOTAN_HAS_X509_CERTIFICATES)
1137 return ffi_guard_thunk(__func__, [=]() -> int {
1138 return ffi_new_object(
1139 entry, std::make_unique<Botan::CRL_Entry>(safe_get(cert), static_cast<Botan::CRL_Code>(reason_code)));
1140 });
1141#else
1142 BOTAN_UNUSED(cert, reason_code);
1144#endif
1145}
1146
1148 botan_x509_crl_t last_crl,
1149 botan_rng_t rng,
1150 botan_x509_cert_t ca_cert,
1151 botan_privkey_t ca_key,
1152 uint64_t issue_time,
1153 uint32_t next_update,
1154 const botan_x509_crl_entry_t* new_entries,
1155 size_t new_entries_len,
1156 const char* hash_fn,
1157 const char* padding) {
1158 if(Botan::any_null_pointers(crl_obj)) {
1160 }
1161 if(new_entries_len > 0 && Botan::any_null_pointers(new_entries)) {
1163 }
1164#if defined(BOTAN_HAS_X509_CERTIFICATES)
1165 return ffi_guard_thunk(__func__, [=]() -> int {
1166 auto& rng_ = safe_get(rng);
1167 auto ca = Botan::X509_CA(
1168 safe_get(ca_cert), safe_get(ca_key), default_from_ptr(hash_fn), default_from_ptr(padding), rng_);
1169
1170 std::vector<Botan::CRL_Entry> entries;
1171 entries.reserve(new_entries_len);
1172 for(size_t i = 0; i < new_entries_len; i++) {
1173 entries.push_back(safe_get(new_entries[i]));
1174 }
1175
1176 auto crl = std::make_unique<Botan::X509_CRL>(ca.update_crl(
1177 safe_get(last_crl), entries, rng_, timepoint_from_timestamp(issue_time), std::chrono::seconds(next_update)));
1178 return ffi_new_object(crl_obj, std::move(crl));
1179 });
1180#else
1182 last_crl, rng, ca_cert, ca_key, hash_fn, padding, issue_time, next_update, new_entries, new_entries_len);
1184#endif
1185}
1186
1188#if defined(BOTAN_HAS_X509_CERTIFICATES)
1189 return BOTAN_FFI_VISIT(crl, [=](const auto& c) -> int { return c.check_signature(safe_get(key)) ? 1 : 0; });
1190#else
1191 BOTAN_UNUSED(crl, key);
1193#endif
1194}
1195
1197#if defined(BOTAN_HAS_X509_CERTIFICATES)
1198 return BOTAN_FFI_CHECKED_DELETE(crl);
1199#else
1200 BOTAN_UNUSED(crl);
1202#endif
1203}
1204
1206 botan_x509_value_type value_type,
1207 size_t index,
1208 botan_view_ctx ctx,
1209 botan_view_bin_fn view_fn) {
1210#if defined(BOTAN_HAS_X509_CERTIFICATES)
1211 if(index != 0) {
1212 // As of now there are no multi-value binary entries.
1214 }
1215
1216 auto view = [=](std::span<const uint8_t> value) -> int {
1217 if(value.empty()) {
1219 } else {
1220 return invoke_view_callback(view_fn, ctx, value);
1221 }
1222 };
1223
1224 return BOTAN_FFI_VISIT(crl_obj, [=](const Botan::X509_CRL& crl) -> int {
1225 switch(value_type) {
1227 if(const auto& crln = crl.crl_number_bigint()) {
1228 // Previously CRL number was a fixed 4 byte value, continue this for small CRL numbers
1229 const size_t view_bytes = std::min<size_t>(crln->bytes(), 4);
1230 return view(crln->serialize<std::vector<uint8_t>>(view_bytes));
1231 } else {
1233 }
1234 }
1236 return view(Botan::ASN1::put_in_sequence(crl.issuer_dn().get_bits()));
1238 return view(crl.authority_key_id());
1239
1244 return botan_x509_object_view_value(crl, value_type, index, ctx, view_fn);
1245
1254 }
1255
1257 });
1258#else
1259 BOTAN_UNUSED(crl_obj, value_type, index, ctx, view_fn);
1261#endif
1262}
1263
1265#if defined(BOTAN_HAS_X509_CERTIFICATES)
1266 return enumerator_count_values(count, [=](size_t index) {
1268 crl_obj, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
1269 });
1270#else
1271 BOTAN_UNUSED(crl_obj, value_type, count);
1273#endif
1274}
1275
1277 botan_x509_value_type value_type,
1278 size_t index,
1279 botan_view_ctx ctx,
1280 botan_view_str_fn view) {
1281#if defined(BOTAN_HAS_X509_CERTIFICATES)
1282 return BOTAN_FFI_VISIT(crl_obj, [=](const Botan::X509_CRL& crl) -> int {
1283 switch(value_type) {
1285 return botan_x509_object_view_value(crl, value_type, index, ctx, view);
1286
1301 }
1302
1304 });
1305#else
1306 BOTAN_UNUSED(crl_obj, value_type, index, ctx, view);
1308#endif
1309}
1310
1312#if defined(BOTAN_HAS_X509_CERTIFICATES)
1313 return enumerator_count_values(count, [=](size_t index) {
1315 crl_obj, value_type, index, nullptr, [](auto, auto, auto) -> int { return BOTAN_FFI_SUCCESS; });
1316 });
1317#else
1318 BOTAN_UNUSED(crl_obj, value_type, count);
1320#endif
1321}
1322
1324#if defined(BOTAN_HAS_X509_CERTIFICATES)
1325 return BOTAN_FFI_VISIT(crl, [=](const auto& c) { return c.is_revoked(safe_get(cert)) ? 0 : -1; });
1326#else
1327 BOTAN_UNUSED(cert);
1328 BOTAN_UNUSED(crl);
1330#endif
1331}
1332
1334#if defined(BOTAN_HAS_X509_CERTIFICATES)
1335 return BOTAN_FFI_VISIT(crl, [=](const Botan::X509_CRL& c) -> int {
1336 const auto& entries = c.get_revoked();
1337 if(index >= entries.size()) {
1339 }
1340
1341 if(Botan::any_null_pointers(entry)) {
1343 }
1344
1345 return ffi_new_object(entry, std::make_unique<Botan::CRL_Entry>(entries[index]));
1346 });
1347#else
1348 BOTAN_UNUSED(crl, index, entry);
1350#endif
1351}
1352
1354#if defined(BOTAN_HAS_X509_CERTIFICATES)
1355 if(Botan::any_null_pointers(count)) {
1357 }
1358
1359 return BOTAN_FFI_VISIT(crl, [=](const Botan::X509_CRL& c) { *count = c.get_revoked().size(); });
1360#else
1361 BOTAN_UNUSED(crl, count);
1363#endif
1364}
1365
1367#if defined(BOTAN_HAS_X509_CERTIFICATES)
1368 return BOTAN_FFI_CHECKED_DELETE(entry);
1369#else
1370 BOTAN_UNUSED(entry);
1372#endif
1373}
1374
1376#if defined(BOTAN_HAS_X509_CERTIFICATES)
1377 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1378 if(Botan::any_null_pointers(reason_code)) {
1380 }
1381
1382 *reason_code = static_cast<int>(e.reason_code());
1383 return BOTAN_FFI_SUCCESS;
1384 });
1385#else
1386 BOTAN_UNUSED(entry, reason_code);
1388#endif
1389}
1390
1392#if defined(BOTAN_HAS_X509_CERTIFICATES)
1393 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1394 if(Botan::any_null_pointers(serial_number)) {
1396 }
1397
1398 auto serial_bn = e.serial().to_bigint();
1399 return ffi_new_object(serial_number, std::make_unique<Botan::BigInt>(std::move(serial_bn)));
1400 });
1401#else
1402 BOTAN_UNUSED(entry, serial_number);
1404#endif
1405}
1406
1408#if defined(BOTAN_HAS_X509_CERTIFICATES)
1409 return BOTAN_FFI_VISIT(
1410 entry, [=](const Botan::CRL_Entry& e) { return invoke_view_callback(view, ctx, e.serial_number()); });
1411#else
1412 BOTAN_UNUSED(entry, ctx, view);
1414#endif
1415}
1416
1417int botan_x509_crl_entry_revocation_date(botan_x509_crl_entry_t entry, uint64_t* time_since_epoch) {
1418#if defined(BOTAN_HAS_X509_CERTIFICATES)
1419 return BOTAN_FFI_VISIT(entry, [=](const Botan::CRL_Entry& e) {
1420 if(Botan::any_null_pointers(time_since_epoch)) {
1422 }
1423
1424 *time_since_epoch = e.expire_time().time_since_epoch();
1425 return BOTAN_FFI_SUCCESS;
1426 });
1427#else
1428 BOTAN_UNUSED(entry, time_since_epoch);
1430#endif
1431}
1432
1434 botan_x509_cert_t cert,
1435 const botan_x509_cert_t* intermediates,
1436 size_t intermediates_len,
1437 const botan_x509_cert_t* trusted,
1438 size_t trusted_len,
1439 const botan_x509_crl_t* crls,
1440 size_t crls_len,
1441 const char* trusted_path,
1442 size_t required_strength,
1443 const char* hostname_cstr,
1444 uint64_t reference_time) {
1445 if(required_strength == 0) {
1446 required_strength = 110;
1447 }
1448
1449#if defined(BOTAN_HAS_X509_CERTIFICATES)
1450 return ffi_guard_thunk(__func__, [=]() -> int {
1451 const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);
1453 const auto validation_time = reference_time == 0
1454 ? std::chrono::system_clock::now()
1455 : std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));
1456
1457 if(intermediates_len > 0 && intermediates == nullptr) {
1459 }
1460 if(trusted_len > 0 && trusted == nullptr) {
1462 }
1463 if(crls_len > 0 && crls == nullptr) {
1465 }
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:166
uint64_t time_since_epoch() const
Return time since epoch.
const std::set< IPv6Address > & ipv6_addresses() const
Return the set of IPv6 addresses included in this alternative name.
Definition pkix_types.h:423
const std::set< DNSName > & dns_names() const
Return the set of DNS names included in this alternative name.
Definition pkix_types.h:409
const std::set< X509_DN > & directory_names() const
Return the set of directory names included in this alternative name.
Definition pkix_types.h:443
const std::set< EmailAddress > & email_addresses() const
Return the set of email addresses included in this alternative name.
Definition pkix_types.h:400
const std::set< IPv4Address > & ipv4_addresses() const
Return the set of IPv4 addresses included in this alternative name.
Definition pkix_types.h:420
const std::set< URI > & uri_names() const
Return the set of URIs included in this alternative name.
Definition pkix_types.h:391
Definition x509_crl.h:32
CRL_Code reason_code() const
Definition crl_ent.cpp:149
const X509_Serial_Number & serial() const
Definition crl_ent.cpp:141
const X509_Time & expire_time() const
Definition crl_ent.cpp:145
const std::vector< uint8_t > & serial_number() const
Definition crl_ent.cpp:137
bool extension_set(const OID &oid) const
Definition x509_ext.cpp:235
X.509 GeneralName Type.
Definition pkix_types.h:543
static GeneralName email(std::string_view email)
static GeneralName ipv4_address(uint32_t ipv4)
static GeneralName _dns_san_value(std::string_view dns)
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:596
static GeneralName _uri_san_value(std::string_view full_uri)
static GeneralName directory_name(Botan::X509_DN dn)
const std::vector< GeneralSubtree > & permitted() const
Definition pkix_types.h:768
const std::vector< GeneralSubtree > & excluded() const
Definition pkix_types.h:775
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:80
const std::vector< CRL_Entry > & get_revoked() const
Definition x509_crl.cpp:260
const std::vector< uint8_t > & authority_key_id() const
Definition x509_crl.cpp:282
const X509_DN & issuer_dn() const
Definition x509_crl.cpp:275
const std::optional< BigInt > & crl_number_bigint() const
Definition x509_crl.cpp:289
const NameConstraints & name_constraints() const
Definition x509cert.cpp:515
const std::vector< uint8_t > & serial_number() const
Definition x509cert.cpp:440
const std::vector< URI > & ocsp_responder_uris() const
Definition x509cert.cpp:641
const X509_Serial_Number & serial() const
Definition x509cert.cpp:444
const std::vector< uint8_t > & authority_key_id() const
Definition x509cert.cpp:432
const AlternativeName & issuer_alt_name() const
Definition x509cert.cpp:692
const std::vector< uint8_t > & raw_subject_dn() const
Definition x509cert.cpp:468
const std::vector< uint8_t > & subject_key_id() const
Definition x509cert.cpp:436
const Extensions & v3_extensions() const
Definition x509cert.cpp:519
const std::vector< URI > & crl_distribution_point_uris() const
Definition x509cert.cpp:657
const std::vector< URI > & ca_issuer_uris() const
Definition x509cert.cpp:649
const std::vector< uint8_t > & raw_issuer_dn() const
Definition x509cert.cpp:464
const AlternativeName & subject_alt_name() const
Definition x509cert.cpp:688
const std::vector< uint8_t > & subject_public_key_info() const
Definition x509cert.cpp:412
const std::vector< uint8_t > & get_bits() const
Definition pkix_types.h:198
struct botan_pubkey_struct * botan_pubkey_t
Definition ffi.h:2112
struct botan_asn1_oid_struct * botan_asn1_oid_t
Definition ffi.h:1415
struct botan_privkey_struct * botan_privkey_t
Definition ffi.h:1777
struct botan_x509_crl_entry_struct * botan_x509_crl_entry_t
Definition ffi.h:4091
struct botan_x509_crl_struct * botan_x509_crl_t
Definition ffi.h:4086
struct botan_x509_general_name_struct * botan_x509_general_name_t
Definition ffi.h:3844
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:535
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
Definition ffi.h:161
struct botan_x509_cert_struct * botan_x509_cert_t
Definition ffi.h:3483
@ BOTAN_X509_DNS_NAME
Definition ffi.h:3854
@ BOTAN_X509_DIRECTORY_NAME
Definition ffi.h:3855
@ BOTAN_X509_OTHER_NAME
Definition ffi.h:3852
@ BOTAN_X509_EMAIL_ADDRESS
Definition ffi.h:3853
@ BOTAN_X509_IP_ADDRESS
Definition ffi.h:3857
@ BOTAN_X509_URI
Definition ffi.h:3856
struct botan_mp_struct * botan_mp_t
Definition ffi.h:1040
void * botan_view_ctx
Definition ffi.h:152
struct botan_rng_struct * botan_rng_t
Definition ffi.h:289
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:138
@ BOTAN_FFI_ERROR_OUT_OF_RANGE
Definition ffi.h:136
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:131
@ BOTAN_FFI_SUCCESS
Definition ffi.h:114
@ BOTAN_FFI_ERROR_NO_VALUE
Definition ffi.h:120
@ BOTAN_FFI_ERROR_INVALID_OBJECT_STATE
Definition ffi.h:135
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:132
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:699
int(* botan_view_str_fn)(botan_view_ctx view_ctx, const char *str, size_t len)
Definition ffi.h:170
botan_x509_value_type
Definition ffi.h:3498
@ BOTAN_X509_AUTHORITY_KEY_IDENTIFIER
Definition ffi.h:3503
@ BOTAN_X509_SUBJECT_KEY_IDENTIFIER
Definition ffi.h:3502
@ BOTAN_X509_TBS_DATA_BITS
Definition ffi.h:3506
@ BOTAN_X509_SIGNATURE_BITS
Definition ffi.h:3508
@ BOTAN_X509_PUBLIC_KEY_PKCS8_BITS
Definition ffi.h:3505
@ BOTAN_X509_DER_ENCODING
Definition ffi.h:3510
@ BOTAN_X509_PEM_ENCODING
Definition ffi.h:3511
@ BOTAN_X509_OCSP_RESPONDER_URLS
Definition ffi.h:3514
@ BOTAN_X509_SIGNATURE_SCHEME_BITS
Definition ffi.h:3507
@ BOTAN_X509_SUBJECT_DN_BITS
Definition ffi.h:3500
@ BOTAN_X509_CRL_DISTRIBUTION_URLS
Definition ffi.h:3513
@ BOTAN_X509_SERIAL_NUMBER
Definition ffi.h:3499
@ BOTAN_X509_ISSUER_DN_BITS
Definition ffi.h:3501
@ BOTAN_X509_CA_ISSUERS_URLS
Definition ffi.h:3515
int botan_x509_cert_get_subject_dn_count(botan_x509_cert_t cert, const char *key, size_t *count)
Definition ffi_cert.cpp:515
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:583
int botan_x509_cert_load_file(botan_x509_cert_t *cert_obj, const char *cert_path)
Definition ffi_cert.cpp:176
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:779
int botan_x509_cert_dup(botan_x509_cert_t *cert_obj, botan_x509_cert_t cert)
Definition ffi_cert.cpp:193
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:478
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:922
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:757
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:340
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:439
int botan_x509_cert_allowed_extended_usage_oid(botan_x509_cert_t cert, botan_asn1_oid_t oid)
Definition ffi_cert.cpp:574
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:285
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:677
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:457
int botan_x509_cert_subject_alternative_names_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:883
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:823
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:858
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:897
int botan_x509_cert_serial_number(botan_x509_cert_t cert, botan_mp_t *serial_number)
Definition ffi_cert.cpp:645
int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:602
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:788
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:535
int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:592
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:211
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:494
int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t *time_since_epoch)
Definition ffi_cert.cpp:612
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:949
int botan_x509_cert_excluded_name_constraints_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:845
int botan_x509_cert_is_ca(botan_x509_cert_t cert)
Definition ffi_cert.cpp:410
int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char *hostname)
Definition ffi_cert.cpp:936
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:636
int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
Definition ffi_cert.cpp:686
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:559
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:699
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:544
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:398
int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t *time_since_epoch)
Definition ffi_cert.cpp:624
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:734
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:695
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:661
int botan_x509_cert_get_path_length_constraint(botan_x509_cert_t cert, size_t *path_limit)
Definition ffi_cert.cpp:419
int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t *out_len)
Definition ffi_cert.cpp:531
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:709
int botan_x509_cert_permitted_name_constraints_count(botan_x509_cert_t cert, size_t *count)
Definition ffi_cert.cpp:810
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:352
#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:208
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:167
std::string PEM_encode(const Private_Key &key)
Definition pkcs8.cpp:122
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:223
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:267
int write_str_output(char out[], size_t *out_len, const std::string &str)
Definition ffi_util.h:271
Certificate_Status_Code
Definition pkix_enums.h:21
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)
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13
bool any_null_pointers(Ptrs... ptr)
Definition mem_utils.h:54