diff --git a/builtin-functions/_functions.txt b/builtin-functions/_functions.txt index b6a52aab20..3630fc46fc 100644 --- a/builtin-functions/_functions.txt +++ b/builtin-functions/_functions.txt @@ -498,6 +498,7 @@ function openssl_sign ($data ::: string, &$signature ::: string, $priv_key_id :: function openssl_verify ($data ::: string, $signature ::: string, $pub_key_id ::: string, $signature_alg ::: int = 1) ::: int; function openssl_random_pseudo_bytes ($length ::: int) ::: string | false; function openssl_x509_parse ($x509cert ::: string, $shortnames ::: bool = true) ::: mixed[] | false; +function openssl_x509_verify ($x509cert ::: string, $public_key ::: string) ::: int; function openssl_x509_checkpurpose ($x509cert ::: string, $purpose ::: int) ::: mixed; define('PKCS7_TEXT', 0x1); diff --git a/runtime/openssl.cpp b/runtime/openssl.cpp index e794e5ad0b..a85ce4c62f 100644 --- a/runtime/openssl.cpp +++ b/runtime/openssl.cpp @@ -1247,6 +1247,26 @@ class X509_parser { return static_cast(ret); } + int64_t verify(const string &public_key) const noexcept { + if (!x509_) { + return -1; + } + dl::CriticalSectionSmartGuard critical_section; + + bool from_cache = false; + EVP_PKEY *pkey = openssl_get_public_evp(public_key, from_cache); + if (pkey == nullptr) { + critical_section.leave_critical_section(); + php_warning("Parameter key is not a valid public key"); + return -1; + } + int64_t result = X509_verify(x509_, pkey); + if (!from_cache) { + EVP_PKEY_free(pkey); + } + return result; + } + ~X509_parser() noexcept { dl::CriticalSectionGuard critical_section; stop_x509_processing(x509_); @@ -1393,6 +1413,10 @@ Optional> f$openssl_x509_parse(const string &data, bool shortnames return X509_parser{data}.parse(shortnames); } +int64_t f$openssl_x509_verify(const string &signature, const string &public_key) { + return X509_parser{signature}.verify(public_key); +} + mixed f$openssl_x509_checkpurpose(const string &data, int64_t purpose) { return X509_parser{data}.check_purpose(purpose); } diff --git a/runtime/openssl.h b/runtime/openssl.h index eb76f40da5..06ba6d70be 100644 --- a/runtime/openssl.h +++ b/runtime/openssl.h @@ -61,6 +61,8 @@ Optional f$openssl_random_pseudo_bytes(int64_t length); Optional> f$openssl_x509_parse(const string &data, bool shortnames = true); +int64_t f$openssl_x509_verify(const string &certificate, const string &public_key); + mixed f$openssl_x509_checkpurpose(const string &data, int64_t purpose); bool f$openssl_pkcs7_sign(const string &infile, const string &outfile, diff --git a/tests/phpt/openssl/8_openssl_x509_verify.php b/tests/phpt/openssl/8_openssl_x509_verify.php new file mode 100644 index 0000000000..790201b41c --- /dev/null +++ b/tests/phpt/openssl/8_openssl_x509_verify.php @@ -0,0 +1,73 @@ +@ok +