diff options
author | Pavol Žáčik <[email protected]> | 2019-12-03 14:14:28 +0100 |
---|---|---|
committer | Pavol Žáčik <[email protected]> | 2019-12-03 14:21:50 +0100 |
commit | 45e6d019fa11de84cd88d56d7e7c607714ac555d (patch) | |
tree | b6f4c7e2fed50a54fc4dafeafeb31204ccf9e38d | |
parent | 30f1967a83c9607ef840f0786c93299eef56d015 (diff) |
Add basic CRL handling to FFI API
-rw-r--r-- | src/lib/ffi/ffi.h | 28 | ||||
-rw-r--r-- | src/lib/ffi/ffi_cert.cpp | 153 |
2 files changed, 181 insertions, 0 deletions
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index aac196494..17d5a282a 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -1603,6 +1603,34 @@ int botan_key_unwrap3394(const uint8_t wrapped_key[], size_t wrapped_key_len, const uint8_t kek[], size_t kek_len, uint8_t key[], size_t *key_len); +/* +* X.509 CRL +**************************/ + +typedef struct botan_x509_crl_struct* botan_x509_crl_t; + +BOTAN_PUBLIC_API(2,13) int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path); +BOTAN_PUBLIC_API(2,13) int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len); + +BOTAN_PUBLIC_API(2,13) int botan_x509_crl_destroy(botan_x509_crl_t crl); + +BOTAN_PUBLIC_API(2,13) int botan_x509_is_revoked(botan_x509_crl_t crl, botan_x509_cert_t cert); + +BOTAN_PUBLIC_API(2,13) int botan_x509_cert_verify_with_crl( + int* validation_result, + 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, + uint64_t reference_time); + + /** * HOTP */ diff --git a/src/lib/ffi/ffi_cert.cpp b/src/lib/ffi/ffi_cert.cpp index dd7f37ecb..2aa6f5f3c 100644 --- a/src/lib/ffi/ffi_cert.cpp +++ b/src/lib/ffi/ffi_cert.cpp @@ -11,6 +11,7 @@ #if defined(BOTAN_HAS_X509_CERTIFICATES) #include <botan/x509cert.h> #include <botan/x509path.h> + #include <botan/x509_crl.h> #include <botan/data_src.h> #endif @@ -349,4 +350,156 @@ const char* botan_x509_cert_validation_status(int code) #endif } +#if defined(BOTAN_HAS_X509_CERTIFICATES) + +BOTAN_FFI_DECLARE_STRUCT(botan_x509_crl_struct, Botan::X509_CRL, 0x2C628910); + +#endif + +int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* crl_path) + { + if(!crl_obj || !crl_path) + return BOTAN_FFI_ERROR_NULL_POINTER; + +#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + + return ffi_guard_thunk(__func__, [=]() -> int { + std::unique_ptr<Botan::X509_CRL> c(new Botan::X509_CRL(crl_path)); + *crl_obj = new botan_x509_crl_struct(c.release()); + return BOTAN_FFI_SUCCESS; + }); + +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +int botan_x509_crl_load(botan_x509_crl_t* crl_obj, const uint8_t crl_bits[], size_t crl_bits_len) + { + if(!crl_obj || !crl_bits) + return BOTAN_FFI_ERROR_NULL_POINTER; + +#if defined(BOTAN_HAS_X509_CERTIFICATES) + return ffi_guard_thunk(__func__, [=]() -> int { + Botan::DataSource_Memory bits(crl_bits, crl_bits_len); + std::unique_ptr<Botan::X509_CRL> c(new Botan::X509_CRL(bits)); + *crl_obj = new botan_x509_crl_struct(c.release()); + return BOTAN_FFI_SUCCESS; + }); +#else + BOTAN_UNUSED(crl_bits_len); + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +int botan_x509_crl_destroy(botan_x509_crl_t crl) + { +#if defined(BOTAN_HAS_X509_CERTIFICATES) + return BOTAN_FFI_CHECKED_DELETE(crl); +#else + BOTAN_UNUSED(crl); + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +int botan_x509_is_revoked(botan_x509_crl_t crl, botan_x509_cert_t cert) + { +#if defined(BOTAN_HAS_X509_CERTIFICATES) + return ffi_guard_thunk(__func__, [=]() -> int { + int result = BOTAN_FFI_DO(Botan::X509_CRL, crl, c, + { return c.is_revoked(safe_get(cert)) ? 0 : -1; }); + return result; + }); +#else + BOTAN_UNUSED(cert); + BOTAN_UNUSED(crl); + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +BOTAN_PUBLIC_API(2,13) 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) + { + if(required_strength == 0) + required_strength = 110; + +#if defined(BOTAN_HAS_X509_CERTIFICATES) + 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(cert)); + for(size_t i = 0; i != intermediates_len; ++i) + end_certs.push_back(safe_get(intermediates[i])); + + std::unique_ptr<Botan::Certificate_Store> trusted_from_path; + std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_extra; + std::unique_ptr<Botan::Certificate_Store_In_Memory> trusted_crls; + std::vector<Botan::Certificate_Store*> trusted_roots; + + if(trusted_path && *trusted_path) + { + trusted_from_path.reset(new Botan::Certificate_Store_In_Memory(trusted_path)); + trusted_roots.push_back(trusted_from_path.get()); + } + + if(trusted_len > 0) + { + trusted_extra.reset(new Botan::Certificate_Store_In_Memory); + for(size_t i = 0; i != trusted_len; ++i) + { + trusted_extra->add_certificate(safe_get(trusted[i])); + } + trusted_roots.push_back(trusted_extra.get()); + } + + 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(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; + }); +#else + BOTAN_UNUSED(result_code, cert, intermediates, intermediates_len, trusted); + BOTAN_UNUSED(trusted_len, trusted_path, hostname_cstr, reference_time, crls, crls_len); + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + } |