/* * (C) 2015,2017 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include #include #include #include #include extern "C" { using namespace Botan_FFI; BOTAN_FFI_DECLARE_STRUCT(botan_x509_cert_struct, Botan::X509_Certificate, 0x8F628937); int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* cert_path) { return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int { if(!cert_obj || !cert_path) return BOTAN_FFI_ERROR_NULL_POINTER; #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) std::unique_ptr c(new Botan::X509_Certificate(cert_path)); *cert_obj = new botan_x509_cert_struct(c.release()); return BOTAN_FFI_SUCCESS; #else return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; #endif }); } int botan_x509_cert_load(botan_x509_cert_t* cert_obj, const uint8_t cert_bits[], size_t cert_bits_len) { return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int { if(!cert_obj || !cert_bits) return BOTAN_FFI_ERROR_NULL_POINTER; Botan::DataSource_Memory bits(cert_bits, cert_bits_len); std::unique_ptr c(new Botan::X509_Certificate(bits)); *cert_obj = new botan_x509_cert_struct(c.release()); return BOTAN_FFI_SUCCESS; }); } int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key) { return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int { if(key == nullptr) return BOTAN_FFI_ERROR_NULL_POINTER; *key = nullptr; #if defined(BOTAN_HAS_RSA) std::unique_ptr publicKey = safe_get(cert).load_subject_public_key(); *key = new botan_pubkey_struct(publicKey.release()); return BOTAN_FFI_SUCCESS; #else return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; #endif }); } 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) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_str_output(out, out_len, c.issuer_info(key).at(index)); }); } 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) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_str_output(out, out_len, c.subject_info(key).at(index)); }); } int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_str_output(out, out_len, c.to_string()); }); } int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { const Botan::Key_Constraints k = static_cast(key_usage); if(c.allowed_usage(k)) return BOTAN_FFI_SUCCESS; return 1; }); } int botan_x509_cert_destroy(botan_x509_cert_t cert) { return BOTAN_FFI_CHECKED_DELETE(cert); } int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_str_output(out, out_len, c.not_before().to_string()); }); } int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_str_output(out, out_len, c.not_after().to_string()); }); } int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_vec_output(out, out_len, c.serial_number()); }); } int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_str_output(out, out_len, c.fingerprint(hash)); }); } int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_vec_output(out, out_len, c.authority_key_id()); }); } int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_vec_output(out, out_len, c.subject_key_id()); }); } int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, uint8_t out[], size_t* out_len) { return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return write_vec_output(out, out_len, c.subject_public_key_bits()); }); } int botan_x509_cert_hostname_match(botan_x509_cert_t cert, const char* hostname) { if(hostname == nullptr) return BOTAN_FFI_ERROR_NULL_POINTER; return BOTAN_FFI_DO(Botan::X509_Certificate, cert, c, { return c.matches_dns_name(hostname) ? 0 : -1; }); } }