1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Add support for Curve25519 + Curve448 based keys

For openssl_pkey_get_details we export the priv+pub parameters.

ED25519/ED448 do not support streaming, so we need to use
EVP_Digest{Sign,Verify} instead. In general the older EVP_{Sign,Verify}
interface should be avoided as the key is passed very late.
See BUGS section in OpenSSL manpages of EVP_{Sign,Verify}Final

Additionally per requirement we need to allow sign/verify without
digest. So we need to allow passing 0 as digest. In OpenSSL 3.0+ this also
corresponds to the default digest (see EVP_PKEY_get_default_digest_name).

For CSR creation we need to allow "null" as digest_alg option.

Closes GH-14052
This commit is contained in:
Manuel Mausz
2024-04-26 13:26:46 +02:00
committed by Jakub Zelenka
parent 6e1d20c86f
commit 5f2a0c8383
9 changed files with 516 additions and 11 deletions

1
NEWS
View File

@@ -132,6 +132,7 @@ PHP NEWS
. Bumped minimum required OpenSSL version to 1.1.1. (Ayesh Karunaratne)
. Added compile-time option --with-openssl-legacy-provider to enable legacy
provider. (Adam Saponara)
. Added support for Curve25519 + Curve448 based keys. (Manuel Mausz)
- Output:
. Clear output handler status flags during handler initialization. (haszi)

View File

@@ -222,6 +222,13 @@ PHP 8.4 UPGRADE NOTES
. NumberFormatter::ROUND_HALFODD added to complement existing
NumberFormatter::ROUND_HALFEVEN functionality.
- OpenSSL:
. Added support for Curve25519 + Curve448 based keys. Specifically x25519,
ed25519, x448 and ed448 fields are supported in openssl_pkey_new and
openssl_pkey_get_details as well as openssl_sign and openssl_verify were
extended to support those keys.
- Phar:
. Added support for the unix timestamp extension for zip archives.

View File

@@ -121,7 +121,13 @@ enum php_openssl_key_type {
OPENSSL_KEYTYPE_DH,
OPENSSL_KEYTYPE_DEFAULT = OPENSSL_KEYTYPE_RSA,
#ifdef HAVE_EVP_PKEY_EC
OPENSSL_KEYTYPE_EC = OPENSSL_KEYTYPE_DH +1
OPENSSL_KEYTYPE_EC = OPENSSL_KEYTYPE_DH +1,
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
OPENSSL_KEYTYPE_X25519 = OPENSSL_KEYTYPE_DH +2,
OPENSSL_KEYTYPE_ED25519 = OPENSSL_KEYTYPE_DH +3,
OPENSSL_KEYTYPE_X448 = OPENSSL_KEYTYPE_DH +4,
OPENSSL_KEYTYPE_ED448 = OPENSSL_KEYTYPE_DH +5,
#endif
};
@@ -1012,7 +1018,11 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
req->digest_name = php_openssl_conf_get_string(req->req_config, req->section_name, "default_md");
}
if (req->digest_name != NULL) {
req->digest = req->md_alg = EVP_get_digestbyname(req->digest_name);
if (strcmp(req->digest_name, "null") == 0) {
req->digest = req->md_alg = EVP_md_null();
} else {
req->digest = req->md_alg = EVP_get_digestbyname(req->digest_name);
}
}
if (req->md_alg == NULL) {
req->md_alg = req->digest = EVP_sha1();
@@ -3737,6 +3747,16 @@ static int php_openssl_get_evp_pkey_type(int key_type) {
#ifdef HAVE_EVP_PKEY_EC
case OPENSSL_KEYTYPE_EC:
return EVP_PKEY_EC;
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
case OPENSSL_KEYTYPE_X25519:
return EVP_PKEY_X25519;
case OPENSSL_KEYTYPE_ED25519:
return EVP_PKEY_ED25519;
case OPENSSL_KEYTYPE_X448:
return EVP_PKEY_X448;
case OPENSSL_KEYTYPE_ED448:
return EVP_PKEY_ED448;
#endif
default:
return -1;
@@ -3807,6 +3827,16 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
goto cleanup;
}
break;
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
case EVP_PKEY_X25519:
break;
case EVP_PKEY_ED25519:
break;
case EVP_PKEY_X448:
break;
case EVP_PKEY_ED448:
break;
#endif
EMPTY_SWITCH_DEFAULT_CASE()
}
@@ -4473,6 +4503,10 @@ static EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) {
*is_private = false;
if (!ctx || !bld || !bctx) {
goto cleanup;
}
zval *curve_name_zv = zend_hash_str_find(Z_ARRVAL_P(data), "curve_name", sizeof("curve_name") - 1);
if (curve_name_zv && Z_TYPE_P(curve_name_zv) == IS_STRING && Z_STRLEN_P(curve_name_zv) > 0) {
nid = OBJ_sn2nid(Z_STRVAL_P(curve_name_zv));
@@ -4674,6 +4708,66 @@ cleanup:
}
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
static void php_openssl_pkey_object_curve_25519_448(zval *return_value, int key_type, zval *data) {
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
OSSL_PARAM *params = NULL;
OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
bool is_private;
RETVAL_FALSE;
if (!bld) {
goto cleanup;
}
zval *priv_key = zend_hash_str_find(Z_ARRVAL_P(data), "priv_key", sizeof("priv_key") - 1);
if (priv_key && Z_TYPE_P(priv_key) == IS_STRING && Z_STRLEN_P(priv_key) > 0) {
if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PRIV_KEY, Z_STRVAL_P(priv_key), Z_STRLEN_P(priv_key))) {
goto cleanup;
}
}
zval *pub_key = zend_hash_str_find(Z_ARRVAL_P(data), "pub_key", sizeof("pub_key") - 1);
if (pub_key && Z_TYPE_P(pub_key) == IS_STRING && Z_STRLEN_P(pub_key) > 0) {
if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, Z_STRVAL_P(pub_key), Z_STRLEN_P(pub_key))) {
goto cleanup;
}
}
params = OSSL_PARAM_BLD_to_param(bld);
ctx = EVP_PKEY_CTX_new_id(key_type, NULL);
if (!params || !ctx) {
goto cleanup;
}
if (pub_key || priv_key) {
if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
goto cleanup;
}
is_private = priv_key != NULL;
} else {
is_private = true;
PHP_OPENSSL_RAND_ADD_TIME();
if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_keygen(ctx, &pkey) <= 0) {
goto cleanup;
}
}
if (pkey) {
php_openssl_pkey_object_init(return_value, pkey, is_private);
}
cleanup:
php_openssl_store_errors();
EVP_PKEY_CTX_free(ctx);
OSSL_PARAM_free(params);
OSSL_PARAM_BLD_free(bld);
}
#endif
/* {{{ Generates a new private key */
PHP_FUNCTION(openssl_pkey_new)
{
@@ -4725,6 +4819,24 @@ PHP_FUNCTION(openssl_pkey_new)
}
php_openssl_pkey_object_init(return_value, pkey, is_private);
return;
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
} else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "x25519", sizeof("x25519") - 1)) != NULL &&
Z_TYPE_P(data) == IS_ARRAY) {
php_openssl_pkey_object_curve_25519_448(return_value, EVP_PKEY_X25519, data);
return;
} else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "ed25519", sizeof("ed25519") - 1)) != NULL &&
Z_TYPE_P(data) == IS_ARRAY) {
php_openssl_pkey_object_curve_25519_448(return_value, EVP_PKEY_ED25519, data);
return;
} else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "x448", sizeof("x448") - 1)) != NULL &&
Z_TYPE_P(data) == IS_ARRAY) {
php_openssl_pkey_object_curve_25519_448(return_value, EVP_PKEY_X448, data);
return;
} else if ((data = zend_hash_str_find(Z_ARRVAL_P(args), "ed448", sizeof("ed448") - 1)) != NULL &&
Z_TYPE_P(data) == IS_ARRAY) {
php_openssl_pkey_object_curve_25519_448(return_value, EVP_PKEY_ED448, data);
return;
#endif
}
}
@@ -4957,6 +5069,27 @@ static zend_string *php_openssl_get_utf8_param(
return NULL;
}
#endif
static void php_openssl_copy_octet_string_param(
zval *ary, EVP_PKEY *pkey, const char *param, const char *name) {
unsigned char buf[64];
size_t len;
if (EVP_PKEY_get_octet_string_param(pkey, param, buf, sizeof(buf), &len) > 0) {
zend_string *str = zend_string_alloc(len, 0);
memcpy(ZSTR_VAL(str), buf, len);
ZSTR_VAL(str)[len] = '\0';
add_assoc_str(ary, name, str);
}
}
static void php_openssl_copy_curve_25519_448_params(
zval *return_value, const char *assoc_name, EVP_PKEY *pkey) {
zval ary;
array_init(&ary);
add_assoc_zval(return_value, assoc_name, &ary);
php_openssl_copy_octet_string_param(&ary, pkey, OSSL_PKEY_PARAM_PRIV_KEY, "priv_key");
php_openssl_copy_octet_string_param(&ary, pkey, OSSL_PKEY_PARAM_PUB_KEY, "pub_key");
}
#endif
/* {{{ returns an array with the key details (bits, pkey, type)*/
@@ -5065,6 +5198,28 @@ PHP_FUNCTION(openssl_pkey_get_details)
php_openssl_copy_bn_param(&ary, pkey, OSSL_PKEY_PARAM_PRIV_KEY, "d");
break;
}
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
case EVP_PKEY_X25519: {
ktype = OPENSSL_KEYTYPE_X25519;
php_openssl_copy_curve_25519_448_params(return_value, "x25519", pkey);
break;
}
case EVP_PKEY_ED25519: {
ktype = OPENSSL_KEYTYPE_ED25519;
php_openssl_copy_curve_25519_448_params(return_value, "ed25519", pkey);
break;
}
case EVP_PKEY_X448: {
ktype = OPENSSL_KEYTYPE_X448;
php_openssl_copy_curve_25519_448_params(return_value, "x448", pkey);
break;
}
case EVP_PKEY_ED448: {
ktype = OPENSSL_KEYTYPE_ED448;
php_openssl_copy_curve_25519_448_params(return_value, "ed448", pkey);
break;
}
#endif
default:
ktype = -1;
@@ -6942,14 +7097,14 @@ PHP_FUNCTION(openssl_sign)
{
zval *key, *signature;
EVP_PKEY *pkey;
unsigned int siglen;
zend_string *sigbuf;
zend_string *sigbuf = NULL;
char * data;
size_t data_len;
EVP_MD_CTX *md_ctx;
zend_string *method_str = NULL;
zend_long method_long = OPENSSL_ALGO_SHA1;
const EVP_MD *mdtype;
bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0;
ZEND_PARSE_PARAMETERS_START(3, 4)
Z_PARAM_STRING(data, data_len)
@@ -6972,19 +7127,27 @@ PHP_FUNCTION(openssl_sign)
} else {
mdtype = php_openssl_get_evp_md_from_algo(method_long);
}
if (!mdtype) {
if (!mdtype && (!can_default_digest || method_long != 0)) {
php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
RETURN_FALSE;
}
siglen = EVP_PKEY_size(pkey);
sigbuf = zend_string_alloc(siglen, 0);
md_ctx = EVP_MD_CTX_create();
size_t siglen;
#if PHP_OPENSSL_API_VERSION >= 0x10100
if (md_ctx != NULL &&
EVP_DigestSignInit(md_ctx, NULL, mdtype, NULL, pkey) &&
EVP_DigestSign(md_ctx, NULL, &siglen, (unsigned char*)data, data_len) &&
(sigbuf = zend_string_alloc(siglen, 0)) != NULL &&
EVP_DigestSign(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), &siglen, (unsigned char*)data, data_len)) {
#else
if (md_ctx != NULL &&
EVP_SignInit(md_ctx, mdtype) &&
EVP_SignUpdate(md_ctx, data, data_len) &&
EVP_SignFinal(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), &siglen, pkey)) {
(siglen = EVP_PKEY_size(pkey)) &&
(sigbuf = zend_string_alloc(siglen, 0)) != NULL &&
EVP_SignFinal(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), (unsigned int*)&siglen, pkey)) {
#endif
ZSTR_VAL(sigbuf)[siglen] = '\0';
ZSTR_LEN(sigbuf) = siglen;
ZEND_TRY_ASSIGN_REF_NEW_STR(signature, sigbuf);
@@ -7013,6 +7176,7 @@ PHP_FUNCTION(openssl_verify)
size_t signature_len;
zend_string *method_str = NULL;
zend_long method_long = OPENSSL_ALGO_SHA1;
bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0;
ZEND_PARSE_PARAMETERS_START(3, 4)
Z_PARAM_STRING(data, data_len)
@@ -7029,7 +7193,7 @@ PHP_FUNCTION(openssl_verify)
} else {
mdtype = php_openssl_get_evp_md_from_algo(method_long);
}
if (!mdtype) {
if (!mdtype && (!can_default_digest || method_long != 0)) {
php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
RETURN_FALSE;
}
@@ -7044,9 +7208,14 @@ PHP_FUNCTION(openssl_verify)
md_ctx = EVP_MD_CTX_create();
if (md_ctx == NULL ||
#if PHP_OPENSSL_API_VERSION >= 0x10100
!EVP_DigestVerifyInit(md_ctx, NULL, mdtype, NULL, pkey) ||
(err = EVP_DigestVerify(md_ctx, (unsigned char *)signature, signature_len, (unsigned char*)data, data_len)) < 0) {
#else
!EVP_VerifyInit (md_ctx, mdtype) ||
!EVP_VerifyUpdate (md_ctx, data, data_len) ||
(err = EVP_VerifyFinal(md_ctx, (unsigned char *)signature, (unsigned int)signature_len, pkey)) < 0) {
#endif
php_openssl_store_errors();
}
EVP_MD_CTX_destroy(md_ctx);

View File

@@ -331,6 +331,28 @@ const OPENSSL_KEYTYPE_DH = UNKNOWN;
*/
const OPENSSL_KEYTYPE_EC = UNKNOWN;
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
/**
* @var int
* @cvalue OPENSSL_KEYTYPE_X25519
*/
const OPENSSL_KEYTYPE_X25519 = UNKNOWN;
/**
* @var int
* @cvalue OPENSSL_KEYTYPE_ED25519
*/
const OPENSSL_KEYTYPE_ED25519 = UNKNOWN;
/**
* @var int
* @cvalue OPENSSL_KEYTYPE_X448
*/
const OPENSSL_KEYTYPE_X448 = UNKNOWN;
/**
* @var int
* @cvalue OPENSSL_KEYTYPE_ED448
*/
const OPENSSL_KEYTYPE_ED448 = UNKNOWN;
#endif
/**
* @var int

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 295c11739a3588a8254db2fe904be6f9911f85b3 */
* Stub hash: 1867498c895461f81aad433c21cf899ffdb65b3d */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_export_to_file, 0, 2, _IS_BOOL, 0)
ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL)
@@ -622,6 +622,18 @@ static void register_openssl_symbols(int module_number)
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_DH", OPENSSL_KEYTYPE_DH, CONST_PERSISTENT);
#if defined(HAVE_EVP_PKEY_EC)
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_EC", OPENSSL_KEYTYPE_EC, CONST_PERSISTENT);
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_X25519", OPENSSL_KEYTYPE_X25519, CONST_PERSISTENT);
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_ED25519", OPENSSL_KEYTYPE_ED25519, CONST_PERSISTENT);
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_X448", OPENSSL_KEYTYPE_X448, CONST_PERSISTENT);
#endif
#if PHP_OPENSSL_API_VERSION >= 0x30000
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_ED448", OPENSSL_KEYTYPE_ED448, CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("OPENSSL_RAW_DATA", OPENSSL_RAW_DATA, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_ZERO_PADDING", OPENSSL_ZERO_PADDING, CONST_PERSISTENT);

View File

@@ -0,0 +1,122 @@
--TEST--
openssl_*() with OPENSSL_KEYTYPE_ED25519
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!defined("OPENSSL_KEYTYPE_ED25519")) die("skip ED25519 not available");
?>
--FILE--
<?php
echo "Testing openssl_pkey_new\n";
$key1 = openssl_pkey_new([ "private_key_type" => OPENSSL_KEYTYPE_ED25519 ]);
var_dump($key1);
$d1 = openssl_pkey_get_details($key1);
var_dump($d1["bits"] === 256);
var_dump(strlen($d1["key"]) === 113);
var_dump(strlen($d1["ed25519"]["priv_key"]) === 32);
var_dump($d1["type"] === OPENSSL_KEYTYPE_ED25519);
$key2 = openssl_pkey_new($d1);
var_dump($key2);
$d2 = openssl_pkey_get_details($key2);
// Compare array
var_dump($d1 == $d2);
// Check that the public key info is computed from the private key if it is missing.
$d1_priv = $d1;
unset($d1_priv["ed25519"]["pub_key"]);
$key3 = openssl_pkey_new($d1_priv);
var_dump($key3);
$d3 = openssl_pkey_get_details($key3);
var_dump($d1 == $d3);
// create public key from private
$d1_pub = $d1;
unset($d1_pub["ed25519"]["priv_key"]);
$pubkey1 = openssl_pkey_new($d1_pub);
var_dump($pubkey1);
$pubkey1_d = openssl_pkey_get_details($pubkey1);
var_dump($d1_pub == $pubkey1_d);
// sign and verify
echo "Testing openssl_sign and openssl_verify\n";
$payload = "somedata";
var_dump(openssl_sign($payload, $signature, $key1, 0));
var_dump(strlen($signature) === 64);
var_dump(openssl_verify($payload, $signature, $pubkey1, 0));
$dn = array(
"countryName" => "BR",
"stateOrProvinceName" => "Rio Grande do Sul",
"localityName" => "Porto Alegre",
"commonName" => "Henrique do N. Angelo",
"emailAddress" => "hnangelo@php.net"
);
$config = __DIR__ . DIRECTORY_SEPARATOR . 'openssl.cnf';
$args = array(
"private_key_type" => OPENSSL_KEYTYPE_ED25519,
"config" => $config,
"digest_alg" => "null",
);
// openssl_csr_new creates a new public key pair if the key argument is null
echo "Testing openssl_csr_new with key generation\n";
$keyGenerate = null;
$csr = openssl_csr_new($dn, $keyGenerate, $args);
var_dump($keyGenerate);
var_dump($csr);
echo "Testing openssl_csr_new with existing key\n";
$csr = openssl_csr_new($dn, $key1, $args);
$pubkey_csr = openssl_pkey_get_details(openssl_csr_get_public_key($csr));
var_dump($pubkey_csr == $pubkey1_d);
echo "Testing openssl_csr_sign\n";
$x509 = openssl_csr_sign($csr, null, $key1, 365, $args);
var_dump($x509);
echo "Testing openssl_x509_{verify,check_private_key}\n";
var_dump(openssl_x509_check_private_key($x509, $key1));
var_dump(openssl_x509_verify($x509, $pubkey1));
var_dump(openssl_x509_check_private_key($x509, $keyGenerate));
?>
--EXPECTF--
Testing openssl_pkey_new
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
bool(true)
bool(true)
bool(true)
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
Testing openssl_sign and openssl_verify
bool(true)
bool(true)
int(1)
Testing openssl_csr_new with key generation
object(OpenSSLAsymmetricKey)#%d (0) {
}
object(OpenSSLCertificateSigningRequest)#%d (0) {
}
Testing openssl_csr_new with existing key
bool(true)
Testing openssl_csr_sign
object(OpenSSLCertificate)#%d (0) {
}
Testing openssl_x509_{verify,check_private_key}
bool(true)
int(1)
bool(false)

View File

@@ -0,0 +1,122 @@
--TEST--
openssl_*() with OPENSSL_KEYTYPE_ED448
--EXTENSIONS--
openssl
--SKIPIF--
<?php
if (!defined("OPENSSL_KEYTYPE_ED448")) die("skip ED448 not available");
?>
--FILE--
<?php
echo "Testing openssl_pkey_new\n";
$key1 = openssl_pkey_new([ "private_key_type" => OPENSSL_KEYTYPE_ED448 ]);
var_dump($key1);
$d1 = openssl_pkey_get_details($key1);
var_dump($d1["bits"] === 456);
var_dump(strlen($d1["key"]) === 146);
var_dump(strlen($d1["ed448"]["priv_key"]) === 57);
var_dump($d1["type"] === OPENSSL_KEYTYPE_ED448);
$key2 = openssl_pkey_new($d1);
var_dump($key2);
$d2 = openssl_pkey_get_details($key2);
// Compare array
var_dump($d1 == $d2);
// Check that the public key info is computed from the private key if it is missing.
$d1_priv = $d1;
unset($d1_priv["ed448"]["pub_key"]);
$key3 = openssl_pkey_new($d1_priv);
var_dump($key3);
$d3 = openssl_pkey_get_details($key3);
var_dump($d1 == $d3);
// create public key from private
$d1_pub = $d1;
unset($d1_pub["ed448"]["priv_key"]);
$pubkey1 = openssl_pkey_new($d1_pub);
var_dump($pubkey1);
$pubkey1_d = openssl_pkey_get_details($pubkey1);
var_dump($d1_pub == $pubkey1_d);
// sign and verify
echo "Testing openssl_sign and openssl_verify\n";
$payload = "somedata";
var_dump(openssl_sign($payload, $signature, $key1, 0));
var_dump(strlen($signature) === 114);
var_dump(openssl_verify($payload, $signature, $pubkey1, 0));
$dn = array(
"countryName" => "BR",
"stateOrProvinceName" => "Rio Grande do Sul",
"localityName" => "Porto Alegre",
"commonName" => "Henrique do N. Angelo",
"emailAddress" => "hnangelo@php.net"
);
$config = __DIR__ . DIRECTORY_SEPARATOR . 'openssl.cnf';
$args = array(
"private_key_type" => OPENSSL_KEYTYPE_ED448,
"config" => $config,
"digest_alg" => "null",
);
// openssl_csr_new creates a new public key pair if the key argument is null
echo "Testing openssl_csr_new with key generation\n";
$keyGenerate = null;
$csr = openssl_csr_new($dn, $keyGenerate, $args);
var_dump($keyGenerate);
var_dump($csr);
echo "Testing openssl_csr_new with existing key\n";
$csr = openssl_csr_new($dn, $key1, $args);
$pubkey_csr = openssl_pkey_get_details(openssl_csr_get_public_key($csr));
var_dump($pubkey_csr == $pubkey1_d);
echo "Testing openssl_csr_sign\n";
$x509 = openssl_csr_sign($csr, null, $key1, 365, $args);
var_dump($x509);
echo "Testing openssl_x509_{verify,check_private_key}\n";
var_dump(openssl_x509_check_private_key($x509, $key1));
var_dump(openssl_x509_verify($x509, $pubkey1));
var_dump(openssl_x509_check_private_key($x509, $keyGenerate));
?>
--EXPECTF--
Testing openssl_pkey_new
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
bool(true)
bool(true)
bool(true)
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
object(OpenSSLAsymmetricKey)#%d (0) {
}
bool(true)
Testing openssl_sign and openssl_verify
bool(true)
bool(true)
int(1)
Testing openssl_csr_new with key generation
object(OpenSSLAsymmetricKey)#%d (0) {
}
object(OpenSSLCertificateSigningRequest)#%d (0) {
}
Testing openssl_csr_new with existing key
bool(true)
Testing openssl_csr_sign
object(OpenSSLCertificate)#%d (0) {
}
Testing openssl_x509_{verify,check_private_key}
bool(true)
int(1)
bool(false)

View File

@@ -0,0 +1,24 @@
--TEST--
openssl_pkey_derive() X25519
--EXTENSIONS--
openssl
--SKIPIF--
<?php if (!defined("OPENSSL_KEYTYPE_X25519")) print "skip"; ?>
--FILE--
<?php
$priv = openssl_pkey_get_private("-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIEhxWrgdpbkAlbNgjSjuqodVy4w/SJzmxlsOlUdXUm5r
-----END PRIVATE KEY-----
");
$pub = openssl_pkey_get_public("-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEAaKrFGJv6L6JrVmkxhtU5+xrPZU2MHNQJcsGZY71WhX8=
-----END PUBLIC KEY-----
");
echo bin2hex(openssl_pkey_derive($pub, $priv));
echo "\n";
?>
--EXPECT--
76feeefed1d6bc01f3406d87759db371893ec6dc2cb912a130b33c3c91abcb21

View File

@@ -0,0 +1,26 @@
--TEST--
openssl_pkey_derive() X448
--EXTENSIONS--
openssl
--SKIPIF--
<?php if (!defined("OPENSSL_KEYTYPE_X448")) print "skip"; ?>
--FILE--
<?php
$priv = openssl_pkey_get_private("-----BEGIN PRIVATE KEY-----
MEYCAQAwBQYDK2VvBDoEOABW8gZe1+BFOHcZVBkfQzh3zmBiw6FXptYcDF7ojpt3
FpYcdiiwj9ETnLHzDXBXxucgdfg866TM
-----END PRIVATE KEY-----
");
$pub = openssl_pkey_get_details(openssl_pkey_get_private("-----BEGIN PRIVATE KEY-----
MEYCAQAwBQYDK2VvBDoEOKSnpre4xISbWGaOu7URKR1lmr/p4diTP7rN7R/+hTv3
l098WrtwPEBim4nNogxKVHs9z7lqm2LF
-----END PRIVATE KEY-----
"))["key"];
echo bin2hex(openssl_pkey_derive($pub, $priv));
echo "\n";
?>
--EXPECT--
f57eea2028d773685334f3117d87d7f3b97d99373ff532a3ab50fbab8002c2e55bb4b39c11fc835d59e83d3d00c649e8566c013e0062fe9b