Z-Botan-0.4.0.0: cbits/hs_botan_certstore.cpp
#include <botan/ffi.h>
#include <botan/internal/ffi_util.h>
#include <botan/internal/ffi_pkey.h>
#include <botan/x509cert.h>
#include <botan/x509path.h>
#include <botan/x509_crl.h>
#include <botan/certstor.h>
#include <botan/data_src.h>
#if defined(BOTAN_HAS_CERTSTOR_FLATFILE)
#include <botan/certstor_flatfile.h>
#endif
#if defined(BOTAN_HAS_CERTSTOR_MACOS)
#include <botan/certstor_macos.h>
#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)
#include <botan/certstor_windows.h>
#endif
#include <HsFFI.h>
#include <string.h>
extern "C" {
using namespace Botan_FFI;
// Cert Store
BOTAN_FFI_DECLARE_STRUCT(botan_x509_certstore_struct, Botan::Certificate_Store, 0x8BD3442A);
typedef struct botan_x509_certstore_struct* botan_x509_certstore_t;
int botan_x509_certstore_load_file(botan_x509_certstore_t* certstore_obj, const char* certstore_path)
{
if(!certstore_obj || !certstore_path)
return BOTAN_FFI_ERROR_NULL_POINTER;
#if defined(BOTAN_HAS_CERTSTOR_FLATFILE)
return ffi_guard_thunk(__func__, [=]() -> int {
std::unique_ptr<Botan::Certificate_Store> c(new Botan::Flatfile_Certificate_Store(certstore_path));
*certstore_obj = new botan_x509_certstore_struct(c.release());
return BOTAN_FFI_SUCCESS;
});
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
}
int botan_x509_certstore_load_system(botan_x509_certstore_t* certstore_obj)
{
if(!certstore_obj)
return BOTAN_FFI_ERROR_NULL_POINTER;
return ffi_guard_thunk(__func__, [=]() -> int {
#if defined(BOTAN_HAS_CERTSTOR_MACOS)
std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_MacOS);
#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)
std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_Windows);
#elif defined(BOTAN_HAS_CERTSTOR_FLATFILE) && defined(BOTAN_SYSTEM_CERT_BUNDLE)
std::unique_ptr<Botan::Certificate_Store> c(
new Botan::Flatfile_Certificate_Store(BOTAN_SYSTEM_CERT_BUNDLE, true));
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
*certstore_obj = new botan_x509_certstore_struct(c.release());
return BOTAN_FFI_SUCCESS;
});
}
int botan_x509_certstore_destroy(botan_x509_certstore_t certstore)
{
return BOTAN_FFI_CHECKED_DELETE(certstore);
}
int botan_x509_cert_verify_with_certstore_crl(
int* result_code,
botan_x509_cert_t cert,
const botan_x509_cert_t* intermediates,
size_t intermediates_len,
const botan_x509_certstore_t store,
const botan_x509_crl_t* crls,
size_t crls_len,
size_t required_strength,
const char* hostname_cstr,
uint64_t reference_time)
{
if(required_strength == 0)
required_strength = 110;
return ffi_guard_thunk(__func__, [=]() -> int {
const std::string hostname((hostname_cstr == nullptr) ? "" : hostname_cstr);
const Botan::Usage_Type usage = Botan::Usage_Type::UNSPECIFIED;
const auto validation_time = reference_time == 0 ?
std::chrono::system_clock::now() :
std::chrono::system_clock::from_time_t(static_cast<time_t>(reference_time));
std::vector<Botan::X509_Certificate> end_certs;
end_certs.push_back(safe_get((Botan_FFI::botan_struct<Botan::X509_Certificate, 0x8F628937>*)cert));
for(size_t i = 0; i != intermediates_len; ++i)
end_certs.push_back(safe_get((Botan_FFI::botan_struct<Botan::X509_Certificate, 0x8F628937>*)intermediates[i]));
std::vector<Botan::Certificate_Store*> trusted_roots;
std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_crls;
trusted_roots.push_back(&safe_get(store));
if(crls_len > 0)
{
trusted_crls.reset(new Botan::Certificate_Store_In_Memory);
for(size_t i = 0; i != crls_len; ++i)
{
trusted_crls->add_crl(safe_get((Botan_FFI::botan_struct<Botan::X509_CRL, 0x2C628910>*)crls[i]));
}
trusted_roots.push_back(trusted_crls.get());
}
Botan::Path_Validation_Restrictions restrictions(false, required_strength);
auto validation_result = Botan::x509_path_validate(end_certs,
restrictions,
trusted_roots,
hostname,
usage,
validation_time);
if(result_code)
*result_code = static_cast<int>(validation_result.result());
if(validation_result.successful_validation())
return 0;
else
return 1;
});
}
int hs_botan_x509_cert_verify_with_certstore_crl(
botan_x509_cert_t cert,
const botan_x509_cert_t* intermediates, HsInt intermediates_len,
const botan_x509_certstore_t store,
const botan_x509_crl_t* crls, HsInt crls_len,
size_t required_strength,
const char* hostname,
uint64_t reference_time) {
int r1;
int r2 = botan_x509_cert_verify_with_certstore_crl(&r1, cert
, intermediates, intermediates_len
, store
, crls, crls_len
, required_strength, hostname, reference_time);
if (r2 < 0){
return r2;
} else {
return r1;
}
}
}