9#include <botan/internal/ffi_pkey.h>
10#include <botan/internal/ffi_util.h>
13#if defined(BOTAN_HAS_X509_CERTIFICATES)
14 #include <botan/data_src.h>
15 #include <botan/x509_crl.h>
16 #include <botan/x509cert.h>
17 #include <botan/x509path.h>
24#if defined(BOTAN_HAS_X509_CERTIFICATES)
31 if(cert_obj ==
nullptr || cert_path ==
nullptr) {
35#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
38 auto c = std::make_unique<Botan::X509_Certificate>(cert_path);
48 if(cert_obj ==
nullptr) {
52#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
55 auto c = std::make_unique<Botan::X509_Certificate>(
safe_get(cert));
66 if(cert_obj ==
nullptr || cert_bits ==
nullptr) {
70#if defined(BOTAN_HAS_X509_CERTIFICATES)
73 auto c = std::make_unique<Botan::X509_Certificate>(bits);
89#if defined(BOTAN_HAS_X509_CERTIFICATES)
91 auto public_key =
safe_get(cert).subject_public_key();
101 botan_x509_cert_t cert,
const char* key,
size_t index, uint8_t out[],
size_t* out_len) {
102#if defined(BOTAN_HAS_X509_CERTIFICATES)
104 auto issuer_info = c.issuer_info(key);
105 if(index < issuer_info.size()) {
107 return write_str_output(
reinterpret_cast<char*
>(out), out_len, c.issuer_info(key).at(index));
119 botan_x509_cert_t cert,
const char* key,
size_t index, uint8_t out[],
size_t* out_len) {
120#if defined(BOTAN_HAS_X509_CERTIFICATES)
122 auto subject_info = c.subject_info(key);
123 if(index < subject_info.size()) {
125 return write_str_output(
reinterpret_cast<char*
>(out), out_len, c.subject_info(key).at(index));
141#if defined(BOTAN_HAS_X509_CERTIFICATES)
150#if defined(BOTAN_HAS_X509_CERTIFICATES)
153 if(c.allowed_usage(k)) {
165#if defined(BOTAN_HAS_X509_CERTIFICATES)
174#if defined(BOTAN_HAS_X509_CERTIFICATES)
176 [=](
const auto& c) {
return write_str_output(out, out_len, c.not_before().to_string()); });
184#if defined(BOTAN_HAS_X509_CERTIFICATES)
186 [=](
const auto& c) {
return write_str_output(out, out_len, c.not_after().to_string()); });
194#if defined(BOTAN_HAS_X509_CERTIFICATES)
195 return BOTAN_FFI_VISIT(cert, [=](
const auto& c) { *time_since_epoch = c.not_before().time_since_epoch(); });
203#if defined(BOTAN_HAS_X509_CERTIFICATES)
204 return BOTAN_FFI_VISIT(cert, [=](
const auto& c) { *time_since_epoch = c.not_after().time_since_epoch(); });
212#if defined(BOTAN_HAS_X509_CERTIFICATES)
221#if defined(BOTAN_HAS_X509_CERTIFICATES)
225 return write_str_output(
reinterpret_cast<char*
>(out), out_len, c.fingerprint(hash));
234#if defined(BOTAN_HAS_X509_CERTIFICATES)
243#if defined(BOTAN_HAS_X509_CERTIFICATES)
256#if defined(BOTAN_HAS_X509_CERTIFICATES)
266 if(hostname ==
nullptr) {
270#if defined(BOTAN_HAS_X509_CERTIFICATES)
271 return BOTAN_FFI_VISIT(cert, [=](
const auto& c) {
return c.matches_dns_name(hostname) ? 0 : -1; });
281 size_t intermediates_len,
284 const char* trusted_path,
285 size_t required_strength,
286 const char* hostname_cstr,
287 uint64_t reference_time) {
288 if(required_strength == 0) {
289 required_strength = 110;
292#if defined(BOTAN_HAS_X509_CERTIFICATES)
294 const std::string hostname((hostname_cstr ==
nullptr) ?
"" : hostname_cstr);
296 const auto validation_time = reference_time == 0
297 ? std::chrono::system_clock::now()
298 : std::chrono::system_clock::from_time_t(
static_cast<time_t
>(reference_time));
300 std::vector<Botan::X509_Certificate> end_certs;
301 end_certs.push_back(
safe_get(cert));
302 for(
size_t i = 0; i != intermediates_len; ++i) {
303 end_certs.push_back(
safe_get(intermediates[i]));
306 std::unique_ptr<Botan::Certificate_Store> trusted_from_path;
307 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra;
308 std::vector<Botan::Certificate_Store*> trusted_roots;
310 if(trusted_path !=
nullptr && *trusted_path != 0) {
311 trusted_from_path = std::make_unique<Botan::Certificate_Store_In_Memory>(trusted_path);
312 trusted_roots.push_back(trusted_from_path.get());
315 if(trusted_len > 0) {
316 trusted_extra = std::make_unique<Botan::Certificate_Store_In_Memory>();
317 for(
size_t i = 0; i != trusted_len; ++i) {
318 trusted_extra->add_certificate(
safe_get(trusted[i]));
320 trusted_roots.push_back(trusted_extra.get());
325 auto validation_result =
328 if(result_code !=
nullptr) {
329 *result_code =
static_cast<int>(validation_result.result());
332 if(validation_result.successful_validation()) {
339 BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);
340 BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time);
350#if defined(BOTAN_HAS_X509_CERTIFICATES)
358#if defined(BOTAN_HAS_X509_CERTIFICATES)
365 if(crl_obj ==
nullptr || crl_path ==
nullptr) {
369#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
372 auto c = std::make_unique<Botan::X509_CRL>(crl_path);
382 if(crl_obj ==
nullptr || crl_bits ==
nullptr) {
386#if defined(BOTAN_HAS_X509_CERTIFICATES)
389 auto c = std::make_unique<Botan::X509_CRL>(bits);
399#if defined(BOTAN_HAS_X509_CERTIFICATES)
408#if defined(BOTAN_HAS_X509_CERTIFICATES)
420 size_t intermediates_len,
425 const char* trusted_path,
426 size_t required_strength,
427 const char* hostname_cstr,
428 uint64_t reference_time) {
429 if(required_strength == 0) {
430 required_strength = 110;
433#if defined(BOTAN_HAS_X509_CERTIFICATES)
435 const std::string hostname((hostname_cstr ==
nullptr) ?
"" : hostname_cstr);
437 const auto validation_time = reference_time == 0
438 ? std::chrono::system_clock::now()
439 : std::chrono::system_clock::from_time_t(
static_cast<time_t
>(reference_time));
441 std::vector<Botan::X509_Certificate> end_certs;
442 end_certs.push_back(
safe_get(cert));
443 for(
size_t i = 0; i != intermediates_len; ++i) {
444 end_certs.push_back(
safe_get(intermediates[i]));
447 std::unique_ptr<Botan::Certificate_Store> trusted_from_path;
448 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra;
449 std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_crls;
450 std::vector<Botan::Certificate_Store*> trusted_roots;
452 if(trusted_path !=
nullptr && *trusted_path != 0) {
453 trusted_from_path = std::make_unique<Botan::Certificate_Store_In_Memory>(trusted_path);
454 trusted_roots.push_back(trusted_from_path.get());
457 if(trusted_len > 0) {
458 trusted_extra = std::make_unique<Botan::Certificate_Store_In_Memory>();
459 for(
size_t i = 0; i != trusted_len; ++i) {
460 trusted_extra->add_certificate(
safe_get(trusted[i]));
462 trusted_roots.push_back(trusted_extra.get());
466 trusted_crls = std::make_unique<Botan::Certificate_Store_In_Memory>();
467 for(
size_t i = 0; i != crls_len; ++i) {
468 trusted_crls->add_crl(
safe_get(crls[i]));
470 trusted_roots.push_back(trusted_crls.get());
475 auto validation_result =
478 if(result_code !=
nullptr) {
479 *result_code =
static_cast<int>(validation_result.result());
482 if(validation_result.successful_validation()) {
489 BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted);
490 BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time, crls, crls_len);
struct botan_pubkey_struct * botan_pubkey_t
struct botan_x509_crl_struct * botan_x509_crl_t
int botan_x509_cert_view_as_string(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_str_fn view)
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
struct botan_x509_cert_struct * botan_x509_cert_t
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
@ BOTAN_FFI_ERROR_NULL_POINTER
@ BOTAN_FFI_ERROR_BAD_PARAMETER
int botan_x509_cert_view_public_key_bits(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_bin_fn view)
int(* botan_view_str_fn)(botan_view_ctx view_ctx, const char *str, size_t len)
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)
int botan_x509_cert_load_file(botan_x509_cert_t *cert_obj, const char *cert_path)
int botan_x509_cert_dup(botan_x509_cert_t *cert_obj, botan_x509_cert_t cert)
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_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t *key)
const char * botan_x509_cert_validation_status(int code)
int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
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)
int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t *out_len)
int botan_x509_cert_view_as_string(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_str_fn view)
int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t *out_len)
int botan_x509_cert_load(botan_x509_cert_t *cert_obj, const uint8_t cert_bits[], size_t cert_bits_len)
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)
int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t *time_since_epoch)
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)
int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char *hostname)
int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
int botan_x509_cert_view_public_key_bits(botan_x509_cert_t cert, botan_view_ctx ctx, botan_view_bin_fn view)
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)
int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t *time_since_epoch)
int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, uint8_t out[], size_t *out_len)
int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char *hash, uint8_t out[], size_t *out_len)
int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t *out_len)
#define BOTAN_FFI_VISIT(obj, lambda)
#define BOTAN_FFI_CHECKED_DELETE(o)
#define BOTAN_FFI_DECLARE_STRUCT(NAME, TYPE, MAGIC)
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, std::span< const uint8_t > buf)
int copy_view_bin(uint8_t out[], size_t *out_len, Fn fn, Args... args)
T & safe_get(botan_struct< T, M > *p)
BOTAN_FFI_ERROR ffi_new_object(T *obj, Args &&... args)
int copy_view_str(uint8_t out[], size_t *out_len, Fn fn, Args... args)
int ffi_guard_thunk(const char *func_name, T thunk)
int write_vec_output(uint8_t out[], size_t *out_len, std::span< const uint8_t > buf)
int write_str_output(char out[], size_t *out_len, const std::string &str)
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.