44#include <openssl/evp.h>
45#include <openssl/bn.h>
46#include <openssl/rsa.h>
47#include <openssl/dsa.h>
48#include <openssl/dh.h>
49#include <openssl/x509.h>
50#include <openssl/x509v3.h>
51#include <openssl/crypto.h>
52#include <openssl/pem.h>
53#include <openssl/err.h>
54#include <openssl/conf.h>
55#include <openssl/rand.h>
56#include <openssl/ssl.h>
57#include <openssl/pkcs12.h>
58#include <openssl/cms.h>
59#if PHP_OPENSSL_API_VERSION >= 0x30000
60#include <openssl/core_names.h>
61#include <openssl/param_build.h>
62#include <openssl/provider.h>
65#if defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_NO_ENGINE)
66#include <openssl/engine.h>
72#if (defined(PHP_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1900)
73#define timezone _timezone
76#define MIN_KEY_LENGTH 384
79#define OPENSSL_ALGO_SHA1 1
80#define OPENSSL_ALGO_MD5 2
82#define OPENSSL_ALGO_MD4 3
85#define OPENSSL_ALGO_MD2 4
87#if PHP_OPENSSL_API_VERSION < 0x10100
88#define OPENSSL_ALGO_DSS1 5
90#define OPENSSL_ALGO_SHA224 6
91#define OPENSSL_ALGO_SHA256 7
92#define OPENSSL_ALGO_SHA384 8
93#define OPENSSL_ALGO_SHA512 9
94#ifndef OPENSSL_NO_RMD160
95#define OPENSSL_ALGO_RMD160 10
99#if !defined(OPENSSL_NO_EC) && defined(EVP_PKEY_EC)
100#define HAVE_EVP_PKEY_EC 1
106#ifndef OPENSSL_EC_EXPLICIT_CURVE
107#define OPENSSL_EC_EXPLICIT_CURVE 0x000
123#ifdef HAVE_EVP_PKEY_EC
126#if PHP_OPENSSL_API_VERSION >= 0x30000
166 php_openssl_certificate_object *intern = zend_object_alloc(
sizeof(php_openssl_certificate_object), class_type);
175 zend_throw_error(
NULL,
"Cannot directly construct OpenSSLCertificate, use openssl_x509_read() instead");
179static void php_openssl_certificate_free_obj(
zend_object *
object)
181 php_openssl_certificate_object *x509_object = php_openssl_certificate_from_obj(
object);
183 X509_free(x509_object->x509);
200#define Z_OPENSSL_REQUEST_P(zv) php_openssl_request_from_obj(Z_OBJ_P(zv))
214 zend_throw_error(
NULL,
"Cannot directly construct OpenSSLCertificateSigningRequest, use openssl_csr_new() instead");
218static void php_openssl_request_free_obj(
zend_object *
object)
222 X509_REQ_free(x509_request->
csr);
240#define Z_OPENSSL_PKEY_P(zv) php_openssl_pkey_from_obj(Z_OBJ_P(zv))
253static void php_openssl_pkey_object_init(
zval *
zv, EVP_PKEY *pkey,
bool is_private) {
261 zend_throw_error(
NULL,
"Cannot directly construct OpenSSLAsymmetricKey, use openssl_pkey_new() instead");
265static void php_openssl_pkey_free_obj(
zend_object *
object)
269 EVP_PKEY_free(key_object->
pkey);
273#if defined(HAVE_OPENSSL_ARGON2)
281#if defined(HAVE_OPENSSL_ARGON2)
303#ifdef COMPILE_DL_OPENSSL
308#if PHP_OPENSSL_API_VERSION < 0x10100
310#define EVP_PKEY_get0_RSA(_pkey) _pkey->pkey.rsa
311#define EVP_PKEY_get0_DH(_pkey) _pkey->pkey.dh
312#define EVP_PKEY_get0_DSA(_pkey) _pkey->pkey.dsa
313#define EVP_PKEY_get0_EC_KEY(_pkey) _pkey->pkey.ec
315static int RSA_set0_key(RSA *r, BIGNUM *
n, BIGNUM *e, BIGNUM *d)
324static int RSA_set0_factors(RSA *r, BIGNUM *
p, BIGNUM *q)
332static int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
341static void RSA_get0_key(
const RSA *r,
const BIGNUM **
n,
const BIGNUM **e,
const BIGNUM **d)
348static void RSA_get0_factors(
const RSA *r,
const BIGNUM **
p,
const BIGNUM **q)
354static void RSA_get0_crt_params(
const RSA *r,
const BIGNUM **dmp1,
const BIGNUM **dmq1,
const BIGNUM **iqmp)
361static void DH_get0_pqg(
const DH *dh,
const BIGNUM **
p,
const BIGNUM **q,
const BIGNUM **g)
368static int DH_set0_pqg(DH *dh, BIGNUM *
p, BIGNUM *q, BIGNUM *g)
377static void DH_get0_key(
const DH *dh,
const BIGNUM **pub_key,
const BIGNUM **priv_key)
379 *pub_key = dh->pub_key;
380 *priv_key = dh->priv_key;
383static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
385 dh->pub_key = pub_key;
386 dh->priv_key = priv_key;
391static void DSA_get0_pqg(
const DSA *d,
const BIGNUM **
p,
const BIGNUM **q,
const BIGNUM **g)
407static void DSA_get0_key(
const DSA *d,
const BIGNUM **pub_key,
const BIGNUM **priv_key)
409 *pub_key = d->pub_key;
410 *priv_key = d->priv_key;
415 d->pub_key = pub_key;
416 d->priv_key = priv_key;
421static const unsigned char *ASN1_STRING_get0_data(
const ASN1_STRING *asn1)
423 return M_ASN1_STRING_data(asn1);
426static int EVP_PKEY_up_ref(EVP_PKEY *pkey)
428 return CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
431#if PHP_OPENSSL_API_VERSION < 0x10002
433static int X509_get_signature_nid(
const X509 *x)
435 return OBJ_obj2nid(x->sig_alg->algorithm);
440#define OpenSSL_version SSLeay_version
441#define OPENSSL_VERSION SSLEAY_VERSION
442#define X509_getm_notBefore X509_get_notBefore
443#define X509_getm_notAfter X509_get_notAfter
444#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_cleanup
450#define PHP_OPENSSL_CHECK_NUMBER_CONVERSION(_cond, _name, _arg_num) \
453 zend_argument_value_error((_arg_num), #_name" is too long"); \
457#define PHP_OPENSSL_CHECK_NUMBER_CONVERSION_NULL_RETURN(_cond, _name) \
460 zend_value_error(#_name" is too long"); \
465#define PHP_OPENSSL_CHECK_SIZE_T_TO_INT(_var, _name, _arg_num) \
466 PHP_OPENSSL_CHECK_NUMBER_CONVERSION(ZEND_SIZE_T_INT_OVFL(_var), _name, _arg_num)
467#define PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(_var, _name) \
468 PHP_OPENSSL_CHECK_NUMBER_CONVERSION_NULL_RETURN(ZEND_SIZE_T_INT_OVFL(_var), _name)
470#define PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(_var, _name, _arg_num) \
471 PHP_OPENSSL_CHECK_NUMBER_CONVERSION(ZEND_SIZE_T_UINT_OVFL(_var), _name, _arg_num)
473#define PHP_OPENSSL_CHECK_LONG_TO_INT(_var, _name, _arg_num) \
474 PHP_OPENSSL_CHECK_NUMBER_CONVERSION(ZEND_LONG_EXCEEDS_INT(_var), _name, _arg_num)
475#define PHP_OPENSSL_CHECK_LONG_TO_INT_NULL_RETURN(_var, _name) \
476 PHP_OPENSSL_CHECK_NUMBER_CONVERSION_NULL_RETURN(ZEND_LONG_EXCEEDS_INT(_var), _name)
481 struct php_openssl_errors *errors;
488 if (!OPENSSL_G(errors)) {
489 OPENSSL_G(errors) =
pecalloc(1,
sizeof(
struct php_openssl_errors), 1);
492 errors = OPENSSL_G(errors);
495 errors->top = (errors->top + 1) % ERR_NUM_ERRORS;
496 if (errors->top == errors->bottom) {
497 errors->bottom = (errors->bottom + 1) % ERR_NUM_ERRORS;
506static void php_openssl_errors_set_mark(
void) {
507 if (!OPENSSL_G(errors)) {
511 if (!OPENSSL_G(errors_mark)) {
512 OPENSSL_G(errors_mark) =
pecalloc(1,
sizeof(
struct php_openssl_errors), 1);
515 memcpy(OPENSSL_G(errors_mark), OPENSSL_G(errors),
sizeof(
struct php_openssl_errors));
520static void php_openssl_errors_restore_mark(
void) {
521 if (!OPENSSL_G(errors)) {
525 struct php_openssl_errors *errors = OPENSSL_G(errors);
527 if (!OPENSSL_G(errors_mark)) {
531 memcpy(errors, OPENSSL_G(errors_mark),
sizeof(
struct php_openssl_errors));
537static void php_openssl_check_path_error(uint32_t
arg_num,
int type,
const char *format, ...)
540 const char *arg_name;
542 va_start(va, format);
555 const char *file_path,
size_t file_path_len,
char *real_path, uint32_t
arg_num,
556 bool contains_file_protocol,
bool is_from_array,
const char *option_name)
558 const char *fs_file_path;
559 size_t fs_file_path_len;
563 if (file_path_len == 0) {
568 if (contains_file_protocol) {
569 size_t path_prefix_len =
sizeof(
"file://") - 1;
570 if (file_path_len <= path_prefix_len) {
573 fs_file_path = file_path + path_prefix_len;
574 fs_file_path_len = file_path_len - path_prefix_len;
576 fs_file_path = file_path;
577 fs_file_path_len = file_path_len;
581 error_msg =
"must not contain any null bytes";
589 const char *option_title = option_name ? option_name :
"unknown";
590 const char *option_label = is_from_array ?
"array item" :
"option";
593 }
else if (is_from_array && option_name !=
NULL) {
594 php_openssl_check_path_error(
596 }
else if (is_from_array) {
597 php_openssl_check_path_error(
arg_num, error_type,
"array item %s",
error_msg);
598 }
else if (option_name !=
NULL) {
599 php_openssl_check_path_error(
611static int ssl_stream_data_index;
615 return (
php_stream*)SSL_get_ex_data(ssl, ssl_stream_data_index);
620 return ssl_stream_data_index;
625static char default_ssl_conf_filename[
MAXPATHLEN];
642#ifdef HAVE_EVP_PKEY_EC
652static X509 *php_openssl_x509_from_param(
654static X509 *php_openssl_x509_from_zval(
655 zval *
val,
bool *free_cert, uint32_t
arg_num,
bool is_from_array,
const char *option_name);
656static X509_REQ *php_openssl_csr_from_param(
658static EVP_PKEY *php_openssl_pkey_from_zval(
659 zval *
val,
int public_key,
char *passphrase,
size_t passphrase_len, uint32_t
arg_num);
661static X509_STORE * php_openssl_setup_verify(
zval * calist, uint32_t
arg_num);
662static STACK_OF(X509) * php_openssl_load_all_certs_from_file(
663 char *cert_file,
size_t cert_file_len, uint32_t
arg_num);
664static EVP_PKEY * php_openssl_generate_private_key(
struct php_x509_request * req);
666static void php_openssl_add_assoc_name_entry(
zval *
val,
char *
key, X509_NAME *
name,
int shortname)
673 X509_NAME_ENTRY * ne;
674 ASN1_STRING * str =
NULL;
683 for (i = 0; i < X509_NAME_entry_count(
name); i++) {
684 const unsigned char *to_add =
NULL;
686 unsigned char *to_add_buf =
NULL;
688 ne = X509_NAME_get_entry(
name, i);
689 obj = X509_NAME_ENTRY_get_object(ne);
690 nid = OBJ_obj2nid(obj);
693 sname = (
char *) OBJ_nid2sn(nid);
695 sname = (
char *) OBJ_nid2ln(nid);
698 str = X509_NAME_ENTRY_get_data(ne);
699 if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) {
701 to_add_len = ASN1_STRING_to_UTF8(&to_add_buf, str);
705 to_add = ASN1_STRING_get0_data(str);
706 to_add_len = ASN1_STRING_length(str);
709 if (to_add_len != -1) {
723 add_assoc_stringl(&subitem, sname, (
char *)to_add, to_add_len);
729 if (to_add_buf !=
NULL) {
730 OPENSSL_free(to_add_buf);
740static void php_openssl_add_assoc_asn1_string(
zval *
val,
char *
key, ASN1_STRING * str)
742 add_assoc_stringl(
val,
key, (
char *)str->data, str->length);
746static time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr)
762 if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME && ASN1_STRING_type(timestr) != V_ASN1_GENERALIZEDTIME) {
767 timestr_len = (size_t)ASN1_STRING_length(timestr);
769 if (timestr_len !=
strlen((
const char *)ASN1_STRING_get0_data(timestr))) {
774 if (timestr_len < 13) {
779 if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && timestr_len < 15) {
784 strbuf =
estrdup((
const char *)ASN1_STRING_get0_data(timestr));
786 memset(&thetime, 0,
sizeof(thetime));
790 thestr = strbuf + timestr_len - 3;
792 thetime.tm_sec = atoi(thestr);
795 thetime.tm_min = atoi(thestr);
798 thetime.tm_hour = atoi(thestr);
801 thetime.tm_mday = atoi(thestr);
804 thetime.tm_mon = atoi(thestr)-1;
807 if( ASN1_STRING_type(timestr) == V_ASN1_UTCTIME ) {
809 thetime.tm_year = atoi(thestr);
811 if (thetime.tm_year < 68) {
812 thetime.tm_year += 100;
814 }
else if( ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME ) {
816 thetime.tm_year = atoi(thestr) - 1900;
820 thetime.tm_isdst = -1;
823#ifdef HAVE_STRUCT_TM_TM_GMTOFF
824 gmadjust = thetime.tm_gmtoff;
841static inline int php_openssl_config_check_syntax(
const char * section_label,
const char * config_filename,
const char * section, CONF *config)
845 X509V3_set_ctx_test(&ctx);
846 X509V3_set_nconf(&ctx, config);
847 if (!X509V3_EXT_add_nconf(config, &ctx, (
char *)section,
NULL)) {
859static char *php_openssl_conf_get_string(CONF *conf,
const char *group,
const char *
name) {
863 char *str = NCONF_get_string(conf, group,
name);
868static long php_openssl_conf_get_number(CONF *conf,
const char *group,
const char *
name) {
872 NCONF_get_number(conf, group,
name, &
res);
880 STACK_OF(CONF_VALUE) * sktmp;
884 str = php_openssl_conf_get_string(req->
req_config,
NULL,
"oid_section");
888 sktmp = NCONF_get_section(req->
req_config, str);
894 for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
895 cnf = sk_CONF_VALUE_value(sktmp, i);
896 if (OBJ_sn2nid(cnf->name) == NID_undef && OBJ_ln2nid(cnf->name) == NID_undef &&
897 OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
907#define PHP_SSL_REQ_INIT(req) memset(req, 0, sizeof(*req))
908#define PHP_SSL_REQ_DISPOSE(req) php_openssl_dispose_config(req)
909#define PHP_SSL_REQ_PARSE(req, zval) php_openssl_parse_config(req, zval)
911#define PHP_SSL_CONFIG_SYNTAX_CHECK(var) if (req->var && php_openssl_config_check_syntax(#var, \
912 req->config_filename, req->var, req->req_config) == FAILURE) return FAILURE
914#define SET_OPTIONAL_STRING_ARG(key, varname, defval) \
916 if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_STRING) { \
917 varname = Z_STRVAL_P(item); \
920 if (varname == NULL) { \
921 php_openssl_store_errors(); \
926#define SET_OPTIONAL_LONG_ARG(key, varname, defval) \
927 if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_LONG) \
928 varname = (int)Z_LVAL_P(item); \
932static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(
zend_long algo);
935static int php_openssl_spki_cleanup(
const char *src,
char *dest)
940 if (*src !=
'\n' && *src !=
'\r') {
970 str = php_openssl_conf_get_string(req->
req_config,
NULL,
"oid_file");
972 BIO *oid_bio = BIO_new_file(path, PHP_OPENSSL_BIO_MODE_R(
PKCS7_BINARY));
974 OBJ_create_objects(oid_bio);
979 if (php_openssl_add_oid_section(req) ==
FAILURE) {
1012 const EVP_CIPHER* cipher = php_openssl_get_evp_cipher_from_algo(cipher_algo);
1013 if (cipher ==
NULL) {
1040#ifdef HAVE_EVP_PKEY_EC
1042 req->curve_name = NID_undef;
1045 req->curve_name = OBJ_sn2nid(
Z_STRVAL_P(item));
1046 if (req->curve_name == NID_undef) {
1055 if (str !=
NULL && !ASN1_STRING_set_default_mask_asc(str)) {
1083#if defined(PHP_WIN32) || PHP_OPENSSL_API_VERSION >= 0x10100
1084#define PHP_OPENSSL_RAND_ADD_TIME() ((void) 0)
1086#define PHP_OPENSSL_RAND_ADD_TIME() php_openssl_rand_add_timeval()
1088static inline void php_openssl_rand_add_timeval(
void)
1093 RAND_add(&
tv,
sizeof(
tv), 0.0);
1099static int php_openssl_load_rand_file(
const char *
file,
int *egdsocket,
int *seeded)
1109 }
else if (RAND_egd(
file) > 0) {
1117 if (RAND_status() == 0) {
1129static int php_openssl_write_rand_file(
const char *
file,
int egdsocket,
int seeded)
1134 if (egdsocket || !seeded) {
1152static EVP_MD * php_openssl_get_evp_md_from_algo(
zend_long algo) {
1157 mdtype = (EVP_MD *) EVP_sha1();
1160 mdtype = (EVP_MD *) EVP_md5();
1162#ifndef OPENSSL_NO_MD4
1164 mdtype = (EVP_MD *) EVP_md4();
1167#ifndef OPENSSL_NO_MD2
1169 mdtype = (EVP_MD *) EVP_md2();
1172#if PHP_OPENSSL_API_VERSION < 0x10100
1174 mdtype = (EVP_MD *) EVP_dss1();
1178 mdtype = (EVP_MD *) EVP_sha224();
1181 mdtype = (EVP_MD *) EVP_sha256();
1184 mdtype = (EVP_MD *) EVP_sha384();
1187 mdtype = (EVP_MD *) EVP_sha512();
1189#ifndef OPENSSL_NO_RMD160
1191 mdtype = (EVP_MD *) EVP_ripemd160();
1202static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(
zend_long algo) {
1204#ifndef OPENSSL_NO_RC2
1206 return EVP_rc2_40_cbc();
1209 return EVP_rc2_64_cbc();
1212 return EVP_rc2_cbc();
1216#ifndef OPENSSL_NO_DES
1218 return EVP_des_cbc();
1221 return EVP_des_ede3_cbc();
1225#ifndef OPENSSL_NO_AES
1227 return EVP_aes_128_cbc();
1230 return EVP_aes_192_cbc();
1233 return EVP_aes_256_cbc();
1255 char * config_filename;
1262 php_openssl_certificate_object_handlers.offset =
XtOffsetOf(php_openssl_certificate_object, std);
1263 php_openssl_certificate_object_handlers.free_obj = php_openssl_certificate_free_obj;
1264 php_openssl_certificate_object_handlers.get_constructor = php_openssl_certificate_get_constructor;
1265 php_openssl_certificate_object_handlers.clone_obj =
NULL;
1268 php_openssl_request_ce = register_class_OpenSSLCertificateSigningRequest();
1269 php_openssl_request_ce->create_object = php_openssl_request_create_object;
1270 php_openssl_request_ce->default_object_handlers = &php_openssl_request_object_handlers;
1274 php_openssl_request_object_handlers.free_obj = php_openssl_request_free_obj;
1275 php_openssl_request_object_handlers.get_constructor = php_openssl_request_get_constructor;
1276 php_openssl_request_object_handlers.clone_obj =
NULL;
1279 php_openssl_pkey_ce = register_class_OpenSSLAsymmetricKey();
1280 php_openssl_pkey_ce->create_object = php_openssl_pkey_create_object;
1281 php_openssl_pkey_ce->default_object_handlers = &php_openssl_pkey_object_handlers;
1285 php_openssl_pkey_object_handlers.free_obj = php_openssl_pkey_free_obj;
1286 php_openssl_pkey_object_handlers.get_constructor = php_openssl_pkey_get_constructor;
1287 php_openssl_pkey_object_handlers.clone_obj =
NULL;
1290#ifdef LIBRESSL_VERSION_NUMBER
1291 OPENSSL_config(
NULL);
1293 OpenSSL_add_all_ciphers();
1294 OpenSSL_add_all_digests();
1295 OpenSSL_add_all_algorithms();
1296 SSL_load_error_strings();
1298#if PHP_OPENSSL_API_VERSION >= 0x30000 && defined(LOAD_OPENSSL_LEGACY_PROVIDER)
1299 OSSL_PROVIDER_load(
NULL,
"legacy");
1300 OSSL_PROVIDER_load(
NULL,
"default");
1302 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG,
NULL);
1307 ssl_stream_data_index = SSL_get_ex_new_index(0,
"PHP stream index",
NULL,
NULL,
NULL);
1309 register_openssl_symbols(module_number);
1312 config_filename =
getenv(
"OPENSSL_CONF");
1313 if (config_filename ==
NULL) {
1314 config_filename =
getenv(
"SSLEAY_CONF");
1318 if (config_filename ==
NULL) {
1319 snprintf(default_ssl_conf_filename,
sizeof(default_ssl_conf_filename),
"%s/%s",
1320 X509_get_default_cert_area(),
1323 strlcpy(default_ssl_conf_filename, config_filename,
sizeof(default_ssl_conf_filename));
1327#ifndef OPENSSL_NO_SSL3
1344#if defined(HAVE_OPENSSL_ARGON2)
1357#if defined(COMPILE_DL_OPENSSL) && defined(ZTS)
1360 openssl_globals->errors =
NULL;
1361 openssl_globals->errors_mark =
NULL;
1368 if (openssl_globals->errors) {
1369 pefree(openssl_globals->errors, 1);
1371 if (openssl_globals->errors_mark) {
1372 pefree(openssl_globals->errors_mark, 1);
1393#ifdef LIBRESSL_VERSION_NUMBER
1397 CRYPTO_set_locking_callback(
NULL);
1399#ifndef OPENSSL_NO_ENGINE
1406 CONF_modules_free();
1413#ifndef OPENSSL_NO_SSL3
1442 add_assoc_string(
return_value,
"default_cert_file", (
char *) X509_get_default_cert_file());
1443 add_assoc_string(
return_value,
"default_cert_file_env", (
char *) X509_get_default_cert_file_env());
1444 add_assoc_string(
return_value,
"default_cert_dir", (
char *) X509_get_default_cert_dir());
1445 add_assoc_string(
return_value,
"default_cert_dir_env", (
char *) X509_get_default_cert_dir_env());
1446 add_assoc_string(
return_value,
"default_private_dir", (
char *) X509_get_default_private_dir());
1447 add_assoc_string(
return_value,
"default_default_cert_area", (
char *) X509_get_default_cert_area());
1455static X509 *php_openssl_x509_from_str(
1456 zend_string *cert_str, uint32_t
arg_num,
bool is_from_array,
const char *option_name) {
1461 if (
ZSTR_LEN(cert_str) > 7 && memcmp(
ZSTR_VAL(cert_str),
"file://",
sizeof(
"file://") - 1) == 0) {
1462 if (!php_openssl_check_path_str_ex(cert_str, cert_path,
arg_num,
true, is_from_array, option_name)) {
1466 in = BIO_new_file(cert_path, PHP_OPENSSL_BIO_MODE_R(
PKCS7_BINARY));
1478#ifdef TYPEDEF_D2I_OF
1479 cert = (X509 *) PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in,
NULL,
NULL,
NULL);
1481 cert = (X509 *) PEM_ASN1_read_bio((
char *(*)())d2i_X509, PEM_STRING_X509, in,
NULL,
NULL,
NULL);
1485 if (!BIO_free(in)) {
1504static X509 *php_openssl_x509_from_param(
1507 return php_openssl_certificate_from_obj(cert_obj)->x509;
1512 return php_openssl_x509_from_str(cert_str,
arg_num,
false,
NULL);
1516static X509 *php_openssl_x509_from_zval(
1517 zval *
val,
bool *free_cert, uint32_t
arg_num,
bool is_from_array,
const char *option_name)
1522 return php_openssl_certificate_from_obj(
Z_OBJ_P(
val))->x509;
1531 X509 *cert = php_openssl_x509_from_str(str,
arg_num, is_from_array, option_name);
1532 zend_string_release(str);
1558 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
1564 if (!php_openssl_check_path(filename,
filename_len, file_path, 2)) {
1565 goto exit_cleanup_cert;
1568 bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
1570 if (!notext && !X509_print(bio_out, cert)) {
1573 if (!PEM_write_bio_X509(bio_out, cert)) {
1583 if (!BIO_free(bio_out)) {
1598 size_t challenge_len;
1599 char * challenge =
NULL, *spkstr =
NULL;
1601 const char *spkac =
"SPKAC=";
1605 EVP_PKEY *pkey =
NULL;
1606 NETSCAPE_SPKI *spki=
NULL;
1607 const EVP_MD *mdtype;
1616 pkey = php_openssl_pkey_from_zval(zpkey, 0, challenge, challenge_len, 1);
1624 mdtype = php_openssl_get_evp_md_from_algo(algo);
1631 if ((spki = NETSCAPE_SPKI_new()) ==
NULL) {
1638 if (!ASN1_STRING_set(spki->spkac->challenge, challenge, (
int)challenge_len)) {
1645 if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
1651 if (!NETSCAPE_SPKI_sign(spki, pkey, mdtype)) {
1657 spkstr = NETSCAPE_SPKI_b64_encode(spki);
1665 OPENSSL_free(spkstr);
1671 EVP_PKEY_free(pkey);
1673 NETSCAPE_SPKI_free(spki);
1686 int i = 0, spkstr_cleaned_len = 0;
1687 char *spkstr, * spkstr_cleaned =
NULL;
1689 EVP_PKEY *pkey =
NULL;
1690 NETSCAPE_SPKI *spki =
NULL;
1697 spkstr_cleaned =
emalloc(spkstr_len + 1);
1698 spkstr_cleaned_len = (int)(spkstr_len - php_openssl_spki_cleanup(spkstr, spkstr_cleaned));
1700 if (spkstr_cleaned_len == 0) {
1705 spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, spkstr_cleaned_len);
1712 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
1719 i = NETSCAPE_SPKI_verify(spki, pkey);
1724 NETSCAPE_SPKI_free(spki);
1726 EVP_PKEY_free(pkey);
1727 if (spkstr_cleaned !=
NULL) {
1728 efree(spkstr_cleaned);
1743 char *spkstr, * spkstr_cleaned =
NULL;
1744 int spkstr_cleaned_len;
1746 EVP_PKEY *pkey =
NULL;
1747 NETSCAPE_SPKI *spki =
NULL;
1755 spkstr_cleaned =
emalloc(spkstr_len + 1);
1756 spkstr_cleaned_len = (int)(spkstr_len - php_openssl_spki_cleanup(spkstr, spkstr_cleaned));
1758 if (spkstr_cleaned_len == 0) {
1763 spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, spkstr_cleaned_len);
1770 pkey = X509_PUBKEY_get(spki->spkac->pubkey);
1777 out = BIO_new(BIO_s_mem());
1778 if (
out && PEM_write_bio_PUBKEY(
out, pkey)) {
1781 BIO_get_mem_ptr(
out, &bio_buf);
1791 NETSCAPE_SPKI_free(spki);
1794 EVP_PKEY_free(pkey);
1795 if (spkstr_cleaned !=
NULL) {
1796 efree(spkstr_cleaned);
1805 char *spkstr, * spkstr_cleaned =
NULL;
1806 int spkstr_cleaned_len;
1808 NETSCAPE_SPKI *spki =
NULL;
1815 spkstr_cleaned =
emalloc(spkstr_len + 1);
1816 spkstr_cleaned_len = (int)(spkstr_len - php_openssl_spki_cleanup(spkstr, spkstr_cleaned));
1818 if (spkstr_cleaned_len == 0) {
1823 spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, spkstr_cleaned_len);
1830 RETVAL_STRING((
const char *)ASN1_STRING_get0_data(spki->spkac->challenge));
1834 if (spkstr_cleaned !=
NULL) {
1835 efree(spkstr_cleaned);
1838 NETSCAPE_SPKI_free(spki);
1862 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
1868 bio_out = BIO_new(BIO_s_mem());
1873 if (!notext && !X509_print(bio_out, cert)) {
1876 if (PEM_write_bio_X509(bio_out, cert)) {
1879 BIO_get_mem_ptr(bio_out, &bio_buf);
1898 unsigned char md[EVP_MAX_MD_SIZE];
1899 const EVP_MD *mdtype;
1903 if (!(mdtype = EVP_get_digestbyname(method))) {
1906 }
else if (!X509_digest(peer, mdtype, md, &
n)) {
1913 ret = zend_string_init((
char*)md,
n, 0);
1915 ret = zend_string_alloc(
n * 2, 0);
1928 bool raw_output = 0;
1929 char *method =
"sha1";
1940 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
1972 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
1979 key = php_openssl_pkey_from_zval(zkey, 0,
"", 0, 2);
2006 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
2011 key = php_openssl_pkey_from_zval(zkey, 1,
NULL, 0, 2);
2013 err = X509_verify(cert,
key);
2033static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
2035 GENERAL_NAMES *names;
2036 const X509V3_EXT_METHOD *method =
NULL;
2037 ASN1_OCTET_STRING *extension_data;
2038 long i, length, num;
2039 const unsigned char *
p;
2041 method = X509V3_EXT_get(extension);
2042 if (method ==
NULL) {
2046 extension_data = X509_EXTENSION_get_data(extension);
2047 p = extension_data->data;
2048 length = extension_data->length;
2050 names = (GENERAL_NAMES*) (ASN1_item_d2i(
NULL, &
p, length,
2051 ASN1_ITEM_ptr(method->it)));
2053 names = (GENERAL_NAMES*) (method->d2i(
NULL, &
p, length));
2055 if (names ==
NULL) {
2060 num = sk_GENERAL_NAME_num(names);
2061 for (i = 0; i < num; i++) {
2064 name = sk_GENERAL_NAME_value(names, i);
2065 switch (
name->type) {
2067 BIO_puts(bio,
"email:");
2068 as =
name->d.rfc822Name;
2069 BIO_write(bio, ASN1_STRING_get0_data(as),
2070 ASN1_STRING_length(as));
2073 BIO_puts(bio,
"DNS:");
2074 as =
name->d.dNSName;
2075 BIO_write(bio, ASN1_STRING_get0_data(as),
2076 ASN1_STRING_length(as));
2079 BIO_puts(bio,
"URI:");
2080 as =
name->d.uniformResourceIdentifier;
2081 BIO_write(bio, ASN1_STRING_get0_data(as),
2082 ASN1_STRING_length(as));
2088 GENERAL_NAME_print(bio,
name);
2091 if (i < (num - 1)) {
2092 BIO_puts(bio,
", ");
2095 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2107 bool useshortnames = 1;
2110 X509_EXTENSION *extension;
2111 X509_NAME *subject_name;
2116 ASN1_INTEGER *asn1_serial;
2128 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
2135 subject_name = X509_get_subject_name(cert);
2136 cert_name = X509_NAME_oneline(subject_name,
NULL, 0);
2138 OPENSSL_free(cert_name);
2140 php_openssl_add_assoc_name_entry(
return_value,
"subject", subject_name, useshortnames);
2144 snprintf(
buf,
sizeof(
buf),
"%08lx", X509_subject_name_hash(cert));
2148 php_openssl_add_assoc_name_entry(
return_value,
"issuer", X509_get_issuer_name(cert), useshortnames);
2149 add_assoc_long(
return_value,
"version", X509_get_version(cert));
2151 asn1_serial = X509_get_serialNumber(cert);
2153 bn_serial = ASN1_INTEGER_to_BN(asn1_serial,
NULL);
2160 hex_serial = BN_bn2hex(bn_serial);
2168 str_serial = i2s_ASN1_INTEGER(
NULL, asn1_serial);
2169 add_assoc_string(
return_value,
"serialNumber", str_serial);
2170 OPENSSL_free(str_serial);
2173 add_assoc_string(
return_value,
"serialNumberHex", hex_serial);
2174 OPENSSL_free(hex_serial);
2182 tmpstr = (
char *)X509_alias_get0(cert,
NULL);
2187 sig_nid = X509_get_signature_nid(cert);
2188 add_assoc_string(
return_value,
"signatureTypeSN", (
char*)OBJ_nid2sn(sig_nid));
2189 add_assoc_string(
return_value,
"signatureTypeLN", (
char*)OBJ_nid2ln(sig_nid));
2190 add_assoc_long(
return_value,
"signatureTypeNID", sig_nid);
2195 for (i = 0; i < X509_PURPOSE_get_count(); i++) {
2198 X509_PURPOSE * purp;
2203 purp = X509_PURPOSE_get0(i);
2204 id = X509_PURPOSE_get_id(purp);
2206 purpset = X509_check_purpose(cert,
id, 0);
2209 purpset = X509_check_purpose(cert,
id, 1);
2212 pname = useshortnames ? X509_PURPOSE_get0_sname(purp) : X509_PURPOSE_get0_name(purp);
2217 add_index_zval(&subitem,
id, &subsub);
2224 for (i = 0; i < X509_get_ext_count(cert); i++) {
2226 extension = X509_get_ext(cert, i);
2227 nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
2228 if (nid != NID_undef) {
2229 extname = (
char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension)));
2231 OBJ_obj2txt(
buf,
sizeof(
buf)-1, X509_EXTENSION_get_object(extension), 1);
2234 bio_out = BIO_new(BIO_s_mem());
2235 if (bio_out ==
NULL) {
2239 if (nid == NID_subject_alt_name) {
2240 if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
2241 BIO_get_mem_ptr(bio_out, &bio_buf);
2242 add_assoc_stringl(&subitem, extname, bio_buf->data, bio_buf->length);
2248 else if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
2249 BIO_get_mem_ptr(bio_out, &bio_buf);
2250 add_assoc_stringl(&subitem, extname, bio_buf->data, bio_buf->length);
2252 php_openssl_add_assoc_asn1_string(&subitem, extname, X509_EXTENSION_get_data(extension));
2274static STACK_OF(X509) *php_openssl_load_all_certs_from_file(
2275 char *cert_file,
size_t cert_file_len, uint32_t
arg_num)
2277 STACK_OF(X509_INFO) *sk=
NULL;
2283 if(!(stack = sk_X509_new_null())) {
2289 if (!php_openssl_check_path(cert_file, cert_file_len, cert_path,
arg_num)) {
2290 sk_X509_free(stack);
2294 if (!(in = BIO_new_file(cert_path, PHP_OPENSSL_BIO_MODE_R(
PKCS7_BINARY)))) {
2297 sk_X509_free(stack);
2302 if (!(sk = PEM_X509_INFO_read_bio(in,
NULL,
NULL,
NULL))) {
2305 sk_X509_free(stack);
2310 while (sk_X509_INFO_num(sk)) {
2311 xi=sk_X509_INFO_shift(sk);
2312 if (xi->x509 !=
NULL) {
2313 sk_X509_push(stack,xi->x509);
2318 if (!sk_X509_num(stack)) {
2320 sk_X509_free(stack);
2326 sk_X509_INFO_free(sk);
2333static int check_cert(X509_STORE *ctx, X509 *x, STACK_OF(X509) *untrustedchain,
int purpose)
2336 X509_STORE_CTX *csc;
2338 csc = X509_STORE_CTX_new();
2344 if (!X509_STORE_CTX_init(csc, ctx, x, untrustedchain)) {
2349 if (purpose >= 0 && !X509_STORE_CTX_set_purpose(csc, purpose)) {
2352 ret = X509_verify_cert(csc);
2356 X509_STORE_CTX_free(csc);
2369 X509_STORE *cainfo =
NULL;
2370 STACK_OF(X509) *untrustedchain =
NULL;
2372 char * untrusted =
NULL;
2373 size_t untrusted_len = 0;
2387 untrustedchain = php_openssl_load_all_certs_from_file(untrusted, untrusted_len, 4);
2388 if (untrustedchain ==
NULL) {
2393 cainfo = php_openssl_setup_verify(zcainfo, 3);
2394 if (cainfo ==
NULL) {
2397 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
2403 ret = check_cert(cainfo, cert, untrustedchain, (
int)purpose);
2404 if (
ret != 0 &&
ret != 1) {
2414 X509_STORE_free(cainfo);
2416 if (untrustedchain) {
2417 sk_X509_pop_free(untrustedchain, X509_free);
2426static X509_STORE *php_openssl_setup_verify(
zval *calist, uint32_t
arg_num)
2429 X509_LOOKUP * dir_lookup, * file_lookup;
2430 int ndirs = 0, nfiles = 0;
2435 store = X509_STORE_new();
2437 if (store ==
NULL) {
2449 if (!php_openssl_check_path_str_ex(str, file_path,
arg_num,
false,
true,
NULL)) {
2450 zend_string_release(str);
2453 zend_string_release(str);
2460 if ((sb.st_mode & S_IFREG) == S_IFREG) {
2461 file_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
2462 if (file_lookup ==
NULL || !X509_LOOKUP_load_file(file_lookup, file_path, X509_FILETYPE_PEM)) {
2470 dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
2471 if (dir_lookup ==
NULL || !X509_LOOKUP_add_dir(dir_lookup, file_path, X509_FILETYPE_PEM)) {
2482 file_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
2483 if (file_lookup ==
NULL || !X509_LOOKUP_load_file(file_lookup,
NULL, X509_FILETYPE_DEFAULT)) {
2488 dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
2489 if (dir_lookup ==
NULL || !X509_LOOKUP_add_dir(dir_lookup,
NULL, X509_FILETYPE_DEFAULT)) {
2501 php_openssl_certificate_object *x509_cert_obj;
2509 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
2517 x509_cert_obj->x509 = cert_obj ? X509_dup(cert) : cert;
2535static void php_sk_X509_free(STACK_OF(X509) * sk)
2538 X509* x = sk_X509_pop(sk);
2546static STACK_OF(X509) *php_array_to_X509_sk(
zval * zcerts, uint32_t
arg_num,
const char *option_name)
2549 STACK_OF(X509) * sk =
NULL;
2553 sk = sk_X509_new_null();
2558 cert = php_openssl_x509_from_zval(zcertval, &free_cert,
arg_num,
true, option_name);
2565 cert = X509_dup(cert);
2573 sk_X509_push(sk, cert);
2577 cert = php_openssl_x509_from_zval(zcerts, &free_cert,
arg_num,
false, option_name);
2585 cert = X509_dup(cert);
2591 sk_X509_push(sk, cert);
2605 BIO * bio_out =
NULL;
2606 PKCS12 * p12 =
NULL;
2608 char * friendly_name =
NULL;
2613 EVP_PKEY *priv_key =
NULL;
2615 STACK_OF(X509) *ca =
NULL;
2628 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
2634 priv_key = php_openssl_pkey_from_zval(zpkey, 0,
"", 0, 3);
2635 if (priv_key ==
NULL) {
2641 if (!X509_check_private_key(cert, priv_key)) {
2646 if (!php_openssl_check_path(filename,
filename_len, file_path, 2)) {
2663 ca = php_array_to_X509_sk(item, 5,
"extracerts");
2670 p12 = PKCS12_create(
pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
2672 bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
2673 if (bio_out !=
NULL) {
2674 if (i2d_PKCS12_bio(bio_out, p12) == 0) {
2691 php_sk_X509_free(ca);
2694 EVP_PKEY_free(priv_key);
2709 PKCS12 * p12 =
NULL;
2711 EVP_PKEY *priv_key =
NULL;
2714 char * friendly_name =
NULL;
2716 STACK_OF(X509) *ca =
NULL;
2729 cert = php_openssl_x509_from_param(cert_obj, cert_str, 1);
2735 priv_key = php_openssl_pkey_from_zval(zpkey, 0,
"", 0, 3);
2736 if (priv_key ==
NULL) {
2742 if (!X509_check_private_key(cert, priv_key)) {
2756 ca = php_array_to_X509_sk(item, 5,
"extracerts");
2760 p12 = PKCS12_create(
pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
2763 bio_out = BIO_new(BIO_s_mem());
2764 if (i2d_PKCS12_bio(bio_out, p12)) {
2767 BIO_get_mem_ptr(bio_out, &bio_buf);
2780 php_sk_X509_free(ca);
2783 EVP_PKEY_free(priv_key);
2793 zval *zout =
NULL, zextracerts, zcert, zpkey;
2795 size_t pass_len, zp12_len;
2796 PKCS12 * p12 =
NULL;
2797 EVP_PKEY * pkey =
NULL;
2799 STACK_OF(X509) * ca =
NULL;
2800 BIO * bio_in =
NULL;
2811 bio_in = BIO_new(BIO_s_mem());
2813 if (0 >= BIO_write(bio_in, zp12, (
int)zp12_len)) {
2818 if (d2i_PKCS12_bio(bio_in, &p12) && PKCS12_parse(p12,
pass, &pkey, &cert, &ca)) {
2822 zout = zend_try_array_init(zout);
2828 bio_out = BIO_new(BIO_s_mem());
2829 if (PEM_write_bio_X509(bio_out, cert)) {
2831 BIO_get_mem_ptr(bio_out, &bio_buf);
2833 add_assoc_zval(zout,
"cert", &zcert);
2841 bio_out = BIO_new(BIO_s_mem());
2842 if (PEM_write_bio_PrivateKey(bio_out, pkey,
NULL,
NULL, 0, 0,
NULL)) {
2844 BIO_get_mem_ptr(bio_out, &bio_buf);
2846 add_assoc_zval(zout,
"pkey", &zpkey);
2853 cert_num = sk_X509_num(ca);
2854 if (ca && cert_num) {
2857 for (i = 0; i < cert_num; i++) {
2859 X509* aCA = sk_X509_pop(ca);
2862 bio_out = BIO_new(BIO_s_mem());
2863 if (PEM_write_bio_X509(bio_out, aCA)) {
2865 BIO_get_mem_ptr(bio_out, &bio_buf);
2866 ZVAL_STRINGL(&zextracert, bio_buf->data, bio_buf->length);
2867 add_index_zval(&zextracerts, i, &zextracert);
2875 add_assoc_zval(zout,
"extracerts", &zextracerts);
2885 EVP_PKEY_free(pkey);
2897static zend_result php_openssl_csr_add_subj_entry(
zval *item, X509_NAME *subj,
int nid)
2899 zend_string *str_item = zval_try_get_string(item);
2903 if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
2904 (
unsigned char*)
ZSTR_VAL(str_item), -1, -1, 0))
2908 "dn: add_entry_by_NID %d -> %s (failed; check error"
2909 " queue and value of string_mask OpenSSL option "
2910 "if illegal characters are reported)",
2912 zend_string_release(str_item);
2915 zend_string_release(str_item);
2921 STACK_OF(CONF_VALUE) * dn_sk, *attr_sk =
NULL;
2922 char * str, *dn_sect, *attr_sect;
2925 if (dn_sect ==
NULL) {
2929 dn_sk = NCONF_get_section(req->
req_config, dn_sect);
2930 if (dn_sk ==
NULL) {
2935 if (attr_sect ==
NULL) {
2938 attr_sk = NCONF_get_section(req->
req_config, attr_sect);
2939 if (attr_sk ==
NULL) {
2945 if (X509_REQ_set_version(csr, 0L)) {
2950 zval *item, *subitem;
2953 subj = X509_REQ_get_subject_name(csr);
2957 int nid = OBJ_txt2nid(
ZSTR_VAL(strindex));
2958 if (nid != NID_undef) {
2961 if (php_openssl_csr_add_subj_entry(subitem, subj, nid) ==
FAILURE) {
2965 }
else if (php_openssl_csr_add_subj_entry(item, subj, nid) ==
FAILURE) {
2975 for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
2979 v = sk_CONF_VALUE_value(dn_sk, i);
2983 if (
len <
sizeof(
"_default")) {
2986 len -=
sizeof(
"_default") - 1;
2999 for (str =
type; *str; str++) {
3000 if (*str ==
':' || *str ==
',' || *str ==
'.') {
3009 nid = OBJ_txt2nid(
type);
3010 if (X509_NAME_get_index_by_NID(subj, nid, -1) >= 0) {
3013 if (!X509_NAME_add_entry_by_txt(subj,
type, MBSTRING_UTF8, (
unsigned char*)
v->value, -1, -1, 0)) {
3018 if (!X509_NAME_entry_count(subj)) {
3027 if (
NULL == strindex) {
3032 nid = OBJ_txt2nid(
ZSTR_VAL(strindex));
3033 if (nid != NID_undef) {
3034 zend_string *str_item = zval_try_get_string(item);
3038 if (!X509_REQ_add1_attr_by_NID(csr, nid, MBSTRING_UTF8, (
unsigned char*)
ZSTR_VAL(str_item), (
int)
ZSTR_LEN(str_item))) {
3041 zend_string_release(str_item);
3044 zend_string_release(str_item);
3049 for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
3050 v = sk_CONF_VALUE_value(attr_sk, i);
3052 nid = OBJ_txt2nid(
v->name);
3053 if (X509_REQ_get_attr_by_NID(csr, nid, -1) >= 0) {
3056 if (!X509_REQ_add1_attr_by_txt(csr,
v->name, MBSTRING_UTF8, (
unsigned char*)
v->value, -1)) {
3059 "add1_attr_by_txt %s -> %s (failed; check error queue "
3060 "and value of string_mask OpenSSL option if illegal "
3061 "characters are reported)",
3071 if (!X509_REQ_set_pubkey(csr, req->
priv_key)) {
3079 X509_REQ * csr =
NULL;
3083 if (
ZSTR_LEN(csr_str) > 7 && memcmp(
ZSTR_VAL(csr_str),
"file://",
sizeof(
"file://") - 1) == 0) {
3084 if (!php_openssl_check_path_str(csr_str, file_path,
arg_num)) {
3087 in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(
PKCS7_BINARY));
3107static X509_REQ *php_openssl_csr_from_param(
3111 return php_openssl_request_from_obj(csr_obj)->csr;
3116 return php_openssl_csr_from_str(csr_str,
arg_num);
3126 char * filename =
NULL;
3140 csr = php_openssl_csr_from_param(csr_obj, csr_str, 1);
3146 if (!php_openssl_check_path(filename,
filename_len, file_path, 2)) {
3150 bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
3151 if (bio_out !=
NULL) {
3152 if (!notext && !X509_REQ_print(bio_out, csr)) {
3155 if (!PEM_write_bio_X509_REQ(bio_out, csr)) {
3193 csr = php_openssl_csr_from_param(csr_obj, csr_str, 1);
3201 bio_out = BIO_new(BIO_s_mem());
3202 if (!notext && !X509_REQ_print(bio_out, csr)) {
3206 if (PEM_write_bio_X509_REQ(bio_out, csr)) {
3209 BIO_get_mem_ptr(bio_out, &bio_buf);
3224#if PHP_OPENSSL_API_VERSION >= 0x10100 && !defined (LIBRESSL_VERSION_NUMBER)
3225#define PHP_OPENSSL_ASN1_INTEGER_set ASN1_INTEGER_set_int64
3227#define PHP_OPENSSL_ASN1_INTEGER_set ASN1_INTEGER_set
3237 php_openssl_certificate_object *cert_object;
3244 X509 *cert =
NULL, *new_cert =
NULL;
3247 bool new_cert_used =
false;
3263 csr = php_openssl_csr_from_param(csr_obj, csr_str, 1);
3271 if (cert_str || cert_obj) {
3272 cert = php_openssl_x509_from_param(cert_obj, cert_str, 2);
3279 priv_key = php_openssl_pkey_from_zval(zpkey, 0,
"", 0, 3);
3286 if (cert && !X509_check_private_key(cert,
priv_key)) {
3292 if (num_days < 0 || num_days >
LONG_MAX / 86400) {
3301 key = X509_REQ_get_pubkey(csr);
3307 i = X509_REQ_verify(csr,
key);
3321 new_cert = X509_new();
3322 if (new_cert ==
NULL) {
3328 if (!X509_set_version(new_cert, 2)) {
3332 if (serial_hex !=
NULL) {
3344 int success = a2i_ASN1_INTEGER(in, X509_get_serialNumber(new_cert),
buffer,
sizeof(
buffer));
3355 X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
3360 if (!X509_set_issuer_name(new_cert, X509_get_subject_name(cert))) {
3366 i = X509_set_pubkey(new_cert,
key);
3374 X509V3_set_ctx(&ctx, cert, new_cert, csr,
NULL, 0);
3391 cert_object->x509 = new_cert;
3392 new_cert_used =
true;
3396 if (!new_cert_used && new_cert) {
3397 X509_free(new_cert);
3406 if (cert_str && cert && cert != new_cert) {
3419 X509_REQ *csr =
NULL;
3429 int we_made_the_key = 0;
3430 zval *out_pkey_val = out_pkey;
3435 req.
priv_key = php_openssl_pkey_from_zval(out_pkey_val, 0,
NULL, 0, 2);
3438 php_openssl_generate_private_key(&req);
3439 we_made_the_key = 1;
3444 csr = X509_REQ_new();
3446 if (php_openssl_csr_make(&req, csr, dn, attribs) ==
SUCCESS) {
3464 x509_request_obj->csr = csr;
3471 if (we_made_the_key) {
3474 php_openssl_pkey_object_init(
3500 bool use_shortnames = 1;
3509 csr = php_openssl_csr_from_param(csr_obj, csr_str, 1);
3514 subject = X509_REQ_get_subject_name(csr);
3517 php_openssl_add_assoc_name_entry(
return_value,
NULL, subject, use_shortnames);
3525static EVP_PKEY *php_openssl_extract_public_key(EVP_PKEY *
priv_key)
3528 BIO *bio = BIO_new(BIO_s_mem());
3529 if (!bio || !PEM_write_bio_PUBKEY(bio,
priv_key)) {
3534 EVP_PKEY *pub_key = PEM_read_bio_PUBKEY(bio,
NULL,
NULL,
NULL);
3544 bool use_shortnames = 1;
3552 X509_REQ *csr = php_openssl_csr_from_param(csr_obj, csr_str, 1);
3558 EVP_PKEY *orig_key = X509_REQ_get_pubkey(csr);
3559 EVP_PKEY *tpubkey = php_openssl_extract_public_key(orig_key);
3560 EVP_PKEY_free(orig_key);
3567 if (tpubkey ==
NULL) {
3572 php_openssl_pkey_object_init(
return_value, tpubkey,
false);
3586static int php_openssl_pem_password_cb(
char *
buf,
int size,
int rwflag,
void *userdata)
3601static EVP_PKEY *php_openssl_pkey_from_zval(
3602 zval *
val,
int public_key,
char *passphrase,
size_t passphrase_len, uint32_t
arg_num)
3606 bool free_cert =
false,
is_file =
false;
3613 if (Z_TYPE(tmp) == IS_STRING) {\
3614 zval_ptr_dtor_str(&tmp); \
3624 zend_value_error(
"Key array must be of the form array(0 => key, 1 => phrase)");
3633 if (!try_convert_to_string(&tmp)) {
3644 zend_value_error(
"Key array must be of the form array(0 => key, 1 => phrase)");
3655 if (!public_key && !is_priv) {
3660 if (public_key && is_priv) {
3665 zval_ptr_dtor_str(&tmp);
3668 EVP_PKEY_up_ref(
key);
3672 cert = php_openssl_certificate_from_obj(
Z_OBJ_P(
val))->x509;
3686 if (
ZSTR_LEN(val_str) > 7 && memcmp(
ZSTR_VAL(val_str),
"file://",
sizeof(
"file://") - 1) == 0) {
3687 if (!php_openssl_check_path_str(val_str, file_path,
arg_num)) {
3695 php_openssl_errors_set_mark();
3696 cert = php_openssl_x509_from_str(val_str,
arg_num,
false,
NULL);
3702 php_openssl_errors_restore_mark();
3705 in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(
PKCS7_BINARY));
3722 in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(
PKCS7_BINARY));
3731 if (passphrase ==
NULL) {
3735 password.
key = passphrase;
3736 password.len = passphrase_len;
3737 key = PEM_read_bio_PrivateKey(in,
NULL, php_openssl_pem_password_cb, &password);
3748 if (public_key && cert) {
3750 key = (EVP_PKEY *) X509_get_pubkey(cert);
3762 zval_ptr_dtor_str(&tmp);
3768static int php_openssl_get_evp_pkey_type(
int key_type) {
3771 return EVP_PKEY_RSA;
3772#if !defined(OPENSSL_NO_DSA)
3774 return EVP_PKEY_DSA;
3780#ifdef HAVE_EVP_PKEY_EC
3784#if PHP_OPENSSL_API_VERSION >= 0x30000
3786 return EVP_PKEY_X25519;
3788 return EVP_PKEY_ED25519;
3790 return EVP_PKEY_X448;
3792 return EVP_PKEY_ED448;
3800static EVP_PKEY * php_openssl_generate_private_key(
struct php_x509_request * req)
3814 int egdsocket, seeded;
3816 php_openssl_load_rand_file(randfile, &egdsocket, &seeded);
3820 EVP_PKEY *params =
NULL;
3821 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(
type,
NULL);
3827 if (
type != EVP_PKEY_RSA) {
3828 if (EVP_PKEY_paramgen_init(ctx) <= 0) {
3834#if !defined(OPENSSL_NO_DSA)
3836 if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, req->
priv_key_bits) <= 0) {
3844 if (EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, req->
priv_key_bits) <= 0) {
3850#ifdef HAVE_EVP_PKEY_EC
3852 if (req->curve_name == NID_undef) {
3857 if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, req->curve_name) <= 0 ||
3858 EVP_PKEY_CTX_set_ec_param_enc(ctx, OPENSSL_EC_NAMED_CURVE) <= 0) {
3864#if PHP_OPENSSL_API_VERSION >= 0x30000
3865 case EVP_PKEY_X25519:
3867 case EVP_PKEY_ED25519:
3871 case EVP_PKEY_ED448:
3877 if (EVP_PKEY_paramgen(ctx, ¶ms) <= 0) {
3882 EVP_PKEY_CTX_free(ctx);
3883 ctx = EVP_PKEY_CTX_new(params,
NULL);
3890 if (EVP_PKEY_keygen_init(ctx) <= 0) {
3895 if (
type == EVP_PKEY_RSA && EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, req->
priv_key_bits) <= 0) {
3900 if (EVP_PKEY_keygen(ctx, &
key) <= 0) {
3908 php_openssl_write_rand_file(randfile, egdsocket, seeded);
3909 EVP_PKEY_free(params);
3910 EVP_PKEY_CTX_free(ctx);
3915static void php_openssl_add_bn_to_array(
zval *
ary,
const BIGNUM *bn,
const char *
name) {
3917 int len = BN_num_bytes(bn);
3919 BN_bn2bin(bn, (
unsigned char *)
ZSTR_VAL(str));
3921 add_assoc_str(
ary,
name, str);
3925#define OPENSSL_PKEY_GET_BN(_type, _name) php_openssl_add_bn_to_array(&_type, _name, #_name)
3927#define OPENSSL_PKEY_SET_BN(_data, _name) do { \
3929 if ((bn = zend_hash_str_find(Z_ARRVAL_P(_data), #_name, sizeof(#_name)-1)) != NULL && \
3930 Z_TYPE_P(bn) == IS_STRING) { \
3931 _name = BN_bin2bn( \
3932 (unsigned char*)Z_STRVAL_P(bn), \
3933 (int)Z_STRLEN_P(bn), NULL); \
3939#if PHP_OPENSSL_API_VERSION < 0x30000
3940static bool php_openssl_pkey_init_legacy_rsa(RSA *rsa,
zval *
data)
3942 BIGNUM *
n, *e, *d, *
p, *q, *dmp1, *dmq1, *iqmp;
3947 if (!
n || !d || !RSA_set0_key(rsa,
n, e, d)) {
3953 if ((
p || q) && !RSA_set0_factors(rsa,
p, q)) {
3960 if ((dmp1 || dmq1 || iqmp) && !RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) {
3968static EVP_PKEY *php_openssl_pkey_init_rsa(
zval *
data)
3970#if PHP_OPENSSL_API_VERSION >= 0x30000
3973 EVP_PKEY *pkey =
NULL;
3974 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA,
NULL);
3975 OSSL_PARAM *params =
NULL;
3976 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
3987 if (!ctx || !bld || !
n || !d) {
3991 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N,
n);
3992 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, d);
3994 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e);
3997 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR1,
p);
4000 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR2, q);
4003 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1);
4006 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1);
4009 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp);
4012 params = OSSL_PARAM_BLD_to_param(bld);
4017 if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
4018 EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
4024 EVP_PKEY_CTX_free(ctx);
4025 OSSL_PARAM_free(params);
4026 OSSL_PARAM_BLD_free(bld);
4037 EVP_PKEY *pkey = EVP_PKEY_new();
4043 RSA *rsa = RSA_new();
4046 EVP_PKEY_free(pkey);
4050 if (!php_openssl_pkey_init_legacy_rsa(rsa,
data)
4051 || !EVP_PKEY_assign_RSA(pkey, rsa)) {
4053 EVP_PKEY_free(pkey);
4062#if PHP_OPENSSL_API_VERSION < 0x30000
4063static bool php_openssl_pkey_init_legacy_dsa(DSA *dsa,
zval *
data,
bool *is_private)
4065 BIGNUM *
p, *q, *g, *priv_key, *pub_key;
4066 const BIGNUM *priv_key_const, *pub_key_const;
4077 *is_private = priv_key !=
NULL;
4084 if (!DSA_generate_key(dsa)) {
4091 DSA_get0_key(dsa, &pub_key_const, &priv_key_const);
4092 if (!pub_key_const || BN_is_zero(pub_key_const)) {
4101static EVP_PKEY *php_openssl_pkey_init_dsa(
zval *
data,
bool *is_private)
4103#if PHP_OPENSSL_API_VERSION >= 0x30000
4105 EVP_PKEY *param_key =
NULL, *pkey =
NULL;
4106 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA,
NULL);
4107 OSSL_PARAM *params =
NULL;
4108 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
4116 *is_private =
false;
4118 if (!ctx || !bld || !
p || !q || !g) {
4122 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P,
p);
4123 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q);
4124 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g);
4127 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key);
4129 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv_key);
4133 params = OSSL_PARAM_BLD_to_param(bld);
4138 if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
4139 EVP_PKEY_fromdata(ctx, ¶m_key, EVP_PKEY_KEYPAIR, params) <= 0) {
4144 *is_private = priv_key !=
NULL;
4145 EVP_PKEY_up_ref(param_key);
4150 EVP_PKEY_CTX_free(ctx);
4151 ctx = EVP_PKEY_CTX_new(param_key,
NULL);
4152 if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_keygen(ctx, &pkey) <= 0) {
4159 EVP_PKEY_free(param_key);
4160 EVP_PKEY_CTX_free(ctx);
4161 OSSL_PARAM_free(params);
4162 OSSL_PARAM_BLD_free(bld);
4170 EVP_PKEY *pkey = EVP_PKEY_new();
4176 DSA *dsa = DSA_new();
4179 EVP_PKEY_free(pkey);
4183 if (!php_openssl_pkey_init_legacy_dsa(dsa,
data, is_private)
4184 || !EVP_PKEY_assign_DSA(pkey, dsa)) {
4186 EVP_PKEY_free(pkey);
4196static BIGNUM *php_openssl_dh_pub_from_priv(BIGNUM *priv_key, BIGNUM *g, BIGNUM *
p)
4198 BIGNUM *pub_key, *priv_key_const_time;
4202 if (pub_key ==
NULL) {
4207 priv_key_const_time = BN_new();
4208 if (priv_key_const_time ==
NULL) {
4216 BN_free(priv_key_const_time);
4221 BN_with_flags(priv_key_const_time, priv_key, BN_FLG_CONSTTIME);
4223 if (!BN_mod_exp_mont(pub_key, g, priv_key_const_time,
p, ctx,
NULL)) {
4229 BN_free(priv_key_const_time);
4236#if PHP_OPENSSL_API_VERSION < 0x30000
4237static bool php_openssl_pkey_init_legacy_dh(DH *dh,
zval *
data,
bool *is_private)
4239 BIGNUM *
p, *q, *g, *priv_key, *pub_key;
4244 if (!
p || !g || !DH_set0_pqg(dh,
p, q, g)) {
4250 *is_private = priv_key !=
NULL;
4252 return DH_set0_key(dh, pub_key, priv_key);
4255 pub_key = php_openssl_dh_pub_from_priv(priv_key, g,
p);
4256 if (pub_key ==
NULL) {
4259 return DH_set0_key(dh, pub_key, priv_key);
4264 if (!DH_generate_key(dh)) {
4274static EVP_PKEY *php_openssl_pkey_init_dh(
zval *
data,
bool *is_private)
4276#if PHP_OPENSSL_API_VERSION >= 0x30000
4278 EVP_PKEY *param_key =
NULL, *pkey =
NULL;
4279 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH,
NULL);
4280 OSSL_PARAM *params =
NULL;
4281 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
4289 *is_private =
false;
4291 if (!ctx || !bld || !
p || !g) {
4295 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P,
p);
4296 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g);
4298 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q);
4301 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv_key);
4303 pub_key = php_openssl_dh_pub_from_priv(priv_key, g,
p);
4310 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key);
4313 params = OSSL_PARAM_BLD_to_param(bld);
4318 if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
4319 EVP_PKEY_fromdata(ctx, ¶m_key, EVP_PKEY_KEYPAIR, params) <= 0) {
4323 if (pub_key || priv_key) {
4324 *is_private = priv_key !=
NULL;
4325 EVP_PKEY_up_ref(param_key);
4330 EVP_PKEY_CTX_free(ctx);
4331 ctx = EVP_PKEY_CTX_new(param_key,
NULL);
4332 if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_keygen(ctx, &pkey) <= 0) {
4339 EVP_PKEY_free(param_key);
4340 EVP_PKEY_CTX_free(ctx);
4341 OSSL_PARAM_free(params);
4342 OSSL_PARAM_BLD_free(bld);
4350 EVP_PKEY *pkey = EVP_PKEY_new();
4358 EVP_PKEY_free(pkey);
4362 if (!php_openssl_pkey_init_legacy_dh(dh,
data, is_private)
4363 || !EVP_PKEY_assign_DH(pkey, dh)) {
4365 EVP_PKEY_free(pkey);
4374#ifdef HAVE_EVP_PKEY_EC
4375#if PHP_OPENSSL_API_VERSION < 0x30000
4376static bool php_openssl_pkey_init_legacy_ec(EC_KEY *eckey,
zval *
data,
bool *is_private) {
4379 EC_POINT *point_g =
NULL;
4380 EC_POINT *point_q =
NULL;
4381 EC_GROUP *group =
NULL;
4382 BN_CTX *bctx = BN_CTX_new();
4384 *is_private =
false;
4388 int nid = OBJ_sn2nid(
Z_STRVAL_P(curve_name_zv));
4389 if (nid == NID_undef) {
4394 if (!(group = EC_GROUP_new_by_curve_name(nid))) {
4397 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
4404 if (!(
p &&
a && b && order)) {
4405 if (!
p && !
a && !b && !order) {
4409 NULL,
E_WARNING,
"Missing params: curve_name or p, a, b, order");
4414 if (!(group = EC_GROUP_new_curve_GFp(
p,
a, b, bctx))) {
4418 if (!(point_g = EC_POINT_new(group))) {
4424 if (!(EC_POINT_oct2point(group, point_g, (
unsigned char *)
Z_STRVAL_P(generator_zv),
Z_STRLEN_P(generator_zv), bctx))) {
4433 NULL,
E_WARNING,
"Missing params: generator or g_x and g_y");
4437 if (!EC_POINT_set_affine_coordinates_GFp(group, point_g, g_x, g_y, bctx)) {
4455 if (!EC_GROUP_set_generator(group, point_g, order, cofactor)) {
4458 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
4461 EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
4463 if (!EC_KEY_set_group(eckey, group)) {
4473 if (!EC_KEY_set_private_key(eckey, d)) {
4477 point_q = EC_POINT_new(group);
4478 if (!point_q || !EC_POINT_mul(group, point_q, d,
NULL,
NULL, bctx)) {
4481 }
else if (x && y) {
4483 point_q = EC_POINT_new(group);
4484 if (!point_q || !EC_POINT_set_affine_coordinates_GFp(group, point_q, x, y, bctx)) {
4489 if (point_q !=
NULL) {
4490 if (!EC_KEY_set_public_key(eckey, point_q)) {
4495 if (!EC_KEY_check_key(eckey)) {
4498 EC_KEY_generate_key(eckey);
4504 EC_GROUP_free(group);
4505 EC_POINT_free(point_g);
4506 EC_POINT_free(point_q);
4517 return EC_KEY_check_key(eckey);
4521static EVP_PKEY *php_openssl_pkey_init_ec(
zval *
data,
bool *is_private) {
4522#if PHP_OPENSSL_API_VERSION >= 0x30000
4523 int nid = NID_undef;
4526 EC_POINT *point_g =
NULL;
4527 EC_POINT *point_q =
NULL;
4528 unsigned char *point_g_buf =
NULL;
4529 unsigned char *point_q_buf =
NULL;
4530 EC_GROUP *group =
NULL;
4531 EVP_PKEY *param_key =
NULL, *pkey =
NULL;
4532 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC,
NULL);
4533 BN_CTX *bctx = BN_CTX_new();
4534 OSSL_PARAM *params =
NULL;
4535 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
4537 *is_private =
false;
4539 if (!ctx || !bld || !bctx) {
4546 if (nid == NID_undef) {
4551 if (!(group = EC_GROUP_new_by_curve_name(nid))) {
4555 if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
Z_STRVAL_P(curve_name_zv),
Z_STRLEN_P(curve_name_zv))) {
4564 if (!(
p &&
a && b && order)) {
4565 if (!
p && !
a && !b && !order) {
4573 if (!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P,
p) ||
4574 !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A,
a) ||
4575 !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b) ||
4576 !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER, order) ||
4577 !OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE, SN_X9_62_prime_field, 0)) {
4581 if (!(group = EC_GROUP_new_curve_GFp(
p,
a, b, bctx))) {
4585 if (!(point_g = EC_POINT_new(group))) {
4591 if (!EC_POINT_oct2point(group, point_g, (
unsigned char *)
Z_STRVAL_P(generator_zv),
Z_STRLEN_P(generator_zv), bctx) ||
4592 !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_GENERATOR,
Z_STRVAL_P(generator_zv),
Z_STRLEN_P(generator_zv))) {
4601 NULL,
E_WARNING,
"Missing params: generator or g_x and g_y");
4605 if (!EC_POINT_set_affine_coordinates(group, point_g, g_x, g_y, bctx)) {
4609 size_t point_g_buf_len =
4610 EC_POINT_point2buf(group, point_g, POINT_CONVERSION_COMPRESSED, &point_g_buf, bctx);
4611 if (!point_g_buf_len) {
4615 if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_GENERATOR, point_g_buf, point_g_buf_len)) {
4623 !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_SEED,
Z_STRVAL_P(seed_zv),
Z_STRLEN_P(seed_zv))) {
4629 if (!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR, cofactor) ||
4630 !EC_GROUP_set_generator(group, point_g, order, cofactor)) {
4634 nid = EC_GROUP_check_named_curve(group, 0, bctx);
4638 if (nid != NID_sm2) {
4644 point_q = EC_POINT_new(group);
4645 if (!point_q || !EC_POINT_mul(group, point_q, d,
NULL,
NULL, bctx) ||
4646 !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, d)) {
4649 }
else if (x && y) {
4651 point_q = EC_POINT_new(group);
4652 if (!point_q || !EC_POINT_set_affine_coordinates(group, point_q, x, y, bctx)) {
4658 size_t point_q_buf_len =
4659 EC_POINT_point2buf(group, point_q, POINT_CONVERSION_COMPRESSED, &point_q_buf, bctx);
4660 if (!point_q_buf_len ||
4661 !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, point_q_buf, point_q_buf_len)) {
4667 params = OSSL_PARAM_BLD_to_param(bld);
4672 if (d || (x && y)) {
4673 if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
4674 EVP_PKEY_fromdata(ctx, ¶m_key, EVP_PKEY_KEYPAIR, params) <= 0) {
4677 EVP_PKEY_CTX_free(ctx);
4678 ctx = EVP_PKEY_CTX_new(param_key,
NULL);
4681 if (EVP_PKEY_check(ctx) || EVP_PKEY_public_check_quick(ctx)) {
4682 *is_private = d !=
NULL;
4683 EVP_PKEY_up_ref(param_key);
4688 if (EVP_PKEY_keygen_init(ctx) != 1 ||
4689 EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
4690 EVP_PKEY_generate(ctx, &pkey) != 1) {
4697 EVP_PKEY_free(param_key);
4698 EVP_PKEY_CTX_free(ctx);
4700 OSSL_PARAM_free(params);
4701 OSSL_PARAM_BLD_free(bld);
4702 EC_GROUP_free(group);
4703 EC_POINT_free(point_g);
4704 EC_POINT_free(point_q);
4705 OPENSSL_free(point_g_buf);
4706 OPENSSL_free(point_q_buf);
4719 EVP_PKEY *pkey = EVP_PKEY_new();
4725 EC_KEY *ec = EC_KEY_new();
4727 EVP_PKEY_free(pkey);
4731 if (!php_openssl_pkey_init_legacy_ec(ec,
data, is_private)
4732 || !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
4734 EVP_PKEY_free(pkey);
4744#if PHP_OPENSSL_API_VERSION >= 0x30000
4746 EVP_PKEY *pkey =
NULL;
4747 EVP_PKEY_CTX *ctx =
NULL;
4748 OSSL_PARAM *params =
NULL;
4749 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
4760 if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PRIV_KEY,
Z_STRVAL_P(priv_key),
Z_STRLEN_P(priv_key))) {
4767 if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY,
Z_STRVAL_P(pub_key),
Z_STRLEN_P(pub_key))) {
4772 params = OSSL_PARAM_BLD_to_param(bld);
4774 if (!params || !ctx) {
4778 if (pub_key || priv_key) {
4779 if (EVP_PKEY_fromdata_init(ctx) <= 0 ||
4780 EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
4783 is_private = priv_key !=
NULL;
4787 if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_keygen(ctx, &pkey) <= 0) {
4793 php_openssl_pkey_object_init(
return_value, pkey, is_private);
4798 EVP_PKEY_CTX_free(ctx);
4799 OSSL_PARAM_free(params);
4800 OSSL_PARAM_BLD_free(bld);
4821 pkey = php_openssl_pkey_init_rsa(
data);
4825 php_openssl_pkey_object_init(
return_value, pkey,
true);
4830 pkey = php_openssl_pkey_init_dsa(
data, &is_private);
4834 php_openssl_pkey_object_init(
return_value, pkey, is_private);
4839 pkey = php_openssl_pkey_init_dh(
data, &is_private);
4843 php_openssl_pkey_object_init(
return_value, pkey, is_private);
4845#ifdef HAVE_EVP_PKEY_EC
4849 pkey = php_openssl_pkey_init_ec(
data, &is_private);
4853 php_openssl_pkey_object_init(
return_value, pkey, is_private);
4856#if PHP_OPENSSL_API_VERSION >= 0x30000
4859 php_openssl_pkey_object_curve_25519_448(
return_value, EVP_PKEY_X25519,
data);
4863 php_openssl_pkey_object_curve_25519_448(
return_value, EVP_PKEY_ED25519,
data);
4867 php_openssl_pkey_object_curve_25519_448(
return_value, EVP_PKEY_X448,
data);
4871 php_openssl_pkey_object_curve_25519_448(
return_value, EVP_PKEY_ED448,
data);
4880 if (php_openssl_generate_private_key(&req)) {
4896 char * passphrase =
NULL;
4897 size_t passphrase_len = 0;
4902 BIO * bio_out =
NULL;
4903 const EVP_CIPHER * cipher;
4912 key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len, 1);
4920 if (!php_openssl_check_path(filename,
filename_len, file_path, 2)) {
4921 goto clean_exit_key;
4927 bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
4928 if (bio_out ==
NULL) {
4937 cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
4943 pem_write = PEM_write_bio_PrivateKey(
4944 bio_out,
key, cipher,
4945 (
unsigned char *)passphrase, (
int)passphrase_len,
NULL,
NULL);
4968 char * passphrase =
NULL;
size_t passphrase_len = 0;
4971 BIO * bio_out =
NULL;
4972 const EVP_CIPHER * cipher;
4981 key = php_openssl_pkey_from_zval(zpkey, 0, passphrase, passphrase_len, 1);
4992 bio_out = BIO_new(BIO_s_mem());
4998 cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
5004 pem_write = PEM_write_bio_PrivateKey(
5005 bio_out,
key, cipher,
5006 (
unsigned char *)passphrase, (
int)passphrase_len,
NULL,
NULL);
5015 bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr);
5036 pkey = php_openssl_pkey_from_zval(cert, 1,
NULL, 0, 1);
5041 php_openssl_pkey_object_init(
return_value, pkey,
false);
5061 char * passphrase =
"";
5062 size_t passphrase_len =
sizeof(
"")-1;
5072 pkey = php_openssl_pkey_from_zval(cert, 0, passphrase, passphrase_len, 1);
5077 php_openssl_pkey_object_init(
return_value, pkey,
true);
5082#if PHP_OPENSSL_API_VERSION >= 0x30000
5083static void php_openssl_copy_bn_param(
5084 zval *
ary, EVP_PKEY *pkey,
const char *param,
const char *
name) {
5086 if (EVP_PKEY_get_bn_param(pkey, param, &bn) > 0) {
5087 php_openssl_add_bn_to_array(
ary, bn,
name);
5092#ifdef HAVE_EVP_PKEY_EC
5094 EVP_PKEY *pkey,
const char *param,
const char *
name) {
5097 if (EVP_PKEY_get_utf8_string_param(pkey, param,
buf,
sizeof(
buf), &
len) > 0) {
5107static void php_openssl_copy_octet_string_param(
5108 zval *
ary, EVP_PKEY *pkey,
const char *param,
const char *
name) {
5109 unsigned char buf[64];
5111 if (EVP_PKEY_get_octet_string_param(pkey, param,
buf,
sizeof(
buf), &
len) > 0) {
5115 add_assoc_str(
ary,
name, str);
5119static void php_openssl_copy_curve_25519_448_params(
5124 php_openssl_copy_octet_string_param(&
ary, pkey, OSSL_PKEY_PARAM_PRIV_KEY,
"priv_key");
5125 php_openssl_copy_octet_string_param(&
ary, pkey, OSSL_PKEY_PARAM_PUB_KEY,
"pub_key");
5133 unsigned int pbio_len;
5143 BIO *
out = BIO_new(BIO_s_mem());
5144 if (!PEM_write_bio_PUBKEY(
out, pkey)) {
5149 pbio_len = BIO_get_mem_data(
out, &pbio);
5152 add_assoc_long(
return_value,
"bits", EVP_PKEY_bits(pkey));
5153 add_assoc_stringl(
return_value,
"key", pbio, pbio_len);
5157#if PHP_OPENSSL_API_VERSION >= 0x30000
5161 if (EVP_PKEY_id(pkey) != EVP_PKEY_KEYMGMT) {
5162 base_id = EVP_PKEY_base_id(pkey);
5164 const char *type_name = EVP_PKEY_get0_type_name(pkey);
5166 int nid = OBJ_txt2nid(type_name);
5167 if (nid != NID_undef) {
5168 base_id = EVP_PKEY_type(nid);
5178 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_N,
"n");
5179 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_E,
"e");
5180 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_D,
"d");
5181 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_FACTOR1,
"p");
5182 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_FACTOR2,
"q");
5183 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1,
"dmp1");
5184 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2,
"dmq1");
5185 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
"iqmp");
5191 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_FFC_P,
"p");
5192 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_FFC_Q,
"q");
5193 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_FFC_G,
"g");
5194 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_PRIV_KEY,
"priv_key");
5195 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_PUB_KEY,
"pub_key");
5201 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_FFC_P,
"p");
5202 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_FFC_G,
"g");
5203 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_PRIV_KEY,
"priv_key");
5204 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_PUB_KEY,
"pub_key");
5206#ifdef HAVE_EVP_PKEY_EC
5212 zend_string *curve_name = php_openssl_get_utf8_param(
5213 pkey, OSSL_PKEY_PARAM_GROUP_NAME,
"curve_name");
5215 add_assoc_str(&
ary,
"curve_name", curve_name);
5217 int nid = OBJ_sn2nid(
ZSTR_VAL(curve_name));
5218 if (nid != NID_undef) {
5219 ASN1_OBJECT *obj = OBJ_nid2obj(nid);
5223 int oir_len = OBJ_obj2txt(oir_buf,
sizeof(oir_buf), obj, 1);
5224 add_assoc_stringl(&
ary,
"curve_oid", oir_buf, oir_len);
5225 ASN1_OBJECT_free(obj);
5230 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_EC_PUB_X,
"x");
5231 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_EC_PUB_Y,
"y");
5232 php_openssl_copy_bn_param(&
ary, pkey, OSSL_PKEY_PARAM_PRIV_KEY,
"d");
5236#if PHP_OPENSSL_API_VERSION >= 0x30000
5237 case EVP_PKEY_X25519: {
5239 php_openssl_copy_curve_25519_448_params(
return_value,
"x25519", pkey);
5242 case EVP_PKEY_ED25519: {
5244 php_openssl_copy_curve_25519_448_params(
return_value,
"ed25519", pkey);
5247 case EVP_PKEY_X448: {
5249 php_openssl_copy_curve_25519_448_params(
return_value,
"x448", pkey);
5252 case EVP_PKEY_ED448: {
5254 php_openssl_copy_curve_25519_448_params(
return_value,
"ed448", pkey);
5263 switch (EVP_PKEY_base_id(pkey)) {
5272 const BIGNUM *
n, *e, *d, *
p, *q, *dmp1, *dmq1, *iqmp;
5274 RSA_get0_key(rsa, &
n, &e, &d);
5275 RSA_get0_factors(rsa, &
p, &q);
5276 RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
5301 const BIGNUM *
p, *q, *g, *
priv_key, *pub_key;
5303 DSA_get0_pqg(dsa, &
p, &q, &g);
5304 DSA_get0_key(dsa, &pub_key, &
priv_key);
5323 const BIGNUM *
p, *q, *g, *
priv_key, *pub_key;
5325 DH_get0_pqg(dh, &
p, &q, &g);
5326 DH_get0_key(dh, &pub_key, &
priv_key);
5337#ifdef HAVE_EVP_PKEY_EC
5342 const EC_GROUP *ec_group;
5343 const EC_POINT *pub;
5350 BIGNUM *x = BN_new();
5351 BIGNUM *y = BN_new();
5354 ec_group = EC_KEY_get0_group(ec_key);
5359 nid = EC_GROUP_get_curve_name(ec_group);
5360 if (nid != NID_undef) {
5361 crv_sn = (
char*) OBJ_nid2sn(nid);
5362 if (crv_sn !=
NULL) {
5363 add_assoc_string(&ec,
"curve_name", crv_sn);
5366 obj = OBJ_nid2obj(nid);
5368 int oir_len = OBJ_obj2txt(oir_buf,
sizeof(oir_buf), obj, 1);
5369 add_assoc_stringl(&ec,
"curve_oid", (
char*) oir_buf, oir_len);
5370 ASN1_OBJECT_free(obj);
5374 pub = EC_KEY_get0_public_key(ec_key);
5376 if (EC_POINT_get_affine_coordinates_GFp(ec_group, pub, x, y,
NULL)) {
5377 php_openssl_add_bn_to_array(&ec, x,
"x");
5378 php_openssl_add_bn_to_array(&ec, y,
"y");
5384 php_openssl_add_bn_to_array(&ec, d,
"d");
5405static zend_string *php_openssl_pkey_derive(EVP_PKEY *
key, EVP_PKEY *peer_key,
size_t key_size) {
5406 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(
key,
NULL);
5411 if (EVP_PKEY_derive_init(ctx) <= 0 ||
5412 EVP_PKEY_derive_set_peer(ctx, peer_key) <= 0 ||
5413 (key_size == 0 && EVP_PKEY_derive(ctx,
NULL, &key_size) <= 0)) {
5415 EVP_PKEY_CTX_free(ctx);
5420 if (EVP_PKEY_derive(ctx, (
unsigned char *)
ZSTR_VAL(
result), &key_size) <= 0) {
5423 EVP_PKEY_CTX_free(ctx);
5429 EVP_PKEY_CTX_free(ctx);
5433static zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey,
char *pub_str,
size_t pub_len) {
5434#if PHP_OPENSSL_API_VERSION >= 0x30000
5435 EVP_PKEY *peer_key = EVP_PKEY_new();
5436 if (!peer_key || EVP_PKEY_copy_parameters(peer_key, pkey) <= 0 ||
5437 EVP_PKEY_set1_encoded_public_key(peer_key, (
unsigned char *) pub_str, pub_len) <= 0) {
5439 EVP_PKEY_free(peer_key);
5444 EVP_PKEY_free(peer_key);
5452 BIGNUM *pub = BN_bin2bn((
unsigned char*)pub_str, (
int)pub_len,
NULL);
5483 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
5512 EVP_PKEY *pkey = php_openssl_pkey_from_zval(
priv_key, 0,
"", 0, 2);
5517 EVP_PKEY *peer_key = php_openssl_pkey_from_zval(peer_pub_key, 1,
NULL, 0, 1);
5519 EVP_PKEY_free(pkey);
5524 EVP_PKEY_free(pkey);
5525 EVP_PKEY_free(peer_key);
5539 zend_long key_length = 0, iterations = 0;
5541 size_t password_len;
5545 size_t method_len = 0;
5551 &password, &password_len,
5553 &key_length, &iterations,
5554 &method, &method_len) ==
FAILURE) {
5563 if (key_length <= 0) {
5569 digest = EVP_get_digestbyname(method);
5579 out_buffer = zend_string_alloc(key_length, 0);
5581 if (PKCS5_PBKDF2_HMAC(password, (
int)password_len, (
unsigned char *)salt, (
int)salt_len, (
int)iterations,
digest, (
int)key_length, (
unsigned char*)
ZSTR_VAL(out_buffer)) == 1) {
5582 ZSTR_VAL(out_buffer)[key_length] = 0;
5593static BIO *php_openssl_bio_new_file(
5602 bio = BIO_new_file(file_path,
mode);
5616 X509_STORE * store =
NULL;
5618 STACK_OF(X509) *signers=
NULL;
5619 STACK_OF(X509) *others =
NULL;
5625 char * extracerts =
NULL;
5626 size_t extracerts_len = 0;
5627 char * signersfilename =
NULL;
5628 size_t signersfilename_len = 0;
5629 char * datafilename =
NULL;
5630 size_t datafilename_len = 0;
5631 char * p7bfilename =
NULL;
5632 size_t p7bfilename_len = 0;
5637 &
flags, &signersfilename, &signersfilename_len, &cainfo,
5638 &extracerts, &extracerts_len, &datafilename, &datafilename_len, &p7bfilename, &p7bfilename_len) ==
FAILURE) {
5643 others = php_openssl_load_all_certs_from_file(extracerts, extracerts_len, 5);
5644 if (others ==
NULL) {
5651 store = php_openssl_setup_verify(cainfo, 4);
5657 in = php_openssl_bio_new_file(filename,
filename_len, 1, PHP_OPENSSL_BIO_MODE_R(
flags));
5662 p7 = SMIME_read_PKCS7(in, &datain);
5671 dataout = php_openssl_bio_new_file(
5672 datafilename, datafilename_len, 6, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
5673 if (dataout ==
NULL) {
5678 p7bout = php_openssl_bio_new_file(
5679 p7bfilename, p7bfilename_len, 7, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
5680 if (p7bout ==
NULL) {
5688 if (PKCS7_verify(p7, others, store, datain, dataout, (
int)
flags)) {
5692 if (signersfilename) {
5695 certout = php_openssl_bio_new_file(
5696 signersfilename, signersfilename_len, 3, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
5699 signers = PKCS7_get0_signers(p7, others, (
int)
flags);
5700 if (signers !=
NULL) {
5702 for (i = 0; i < sk_X509_num(signers); i++) {
5703 if (!PEM_write_bio_X509(certout, sk_X509_value(signers, i))) {
5710 sk_X509_free(signers);
5723 if (PEM_write_bio_PKCS7(p7bout, p7) == 0) {
5738 X509_STORE_free(store);
5743 sk_X509_pop_free(others, X509_free);
5750 zval * zrecipcerts, * zheaders =
NULL;
5751 STACK_OF(X509) * recipcerts =
NULL;
5752 BIO * infile =
NULL, * outfile =
NULL;
5757 const EVP_CIPHER *cipher =
NULL;
5760 char * infilename =
NULL;
5761 size_t infilename_len;
5762 char * outfilename =
NULL;
5763 size_t outfilename_len;
5768 &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &
flags, &cipherid) ==
FAILURE) {
5772 infile = php_openssl_bio_new_file(infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(
flags));
5773 if (infile ==
NULL) {
5777 outfile = php_openssl_bio_new_file(outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(
flags));
5778 if (outfile ==
NULL) {
5782 recipcerts = sk_X509_new_null();
5789 cert = php_openssl_x509_from_zval(zcertval, &free_cert, 3,
true,
NULL);
5798 cert = X509_dup(cert);
5804 sk_X509_push(recipcerts, cert);
5810 cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert, 3,
false,
NULL);
5819 cert = X509_dup(cert);
5825 sk_X509_push(recipcerts, cert);
5829 cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
5830 if (cipher ==
NULL) {
5836 p7 = PKCS7_encrypt(recipcerts, infile, (EVP_CIPHER*)cipher, (
int)
flags);
5853 BIO_printf(outfile,
"%s\n",
ZSTR_VAL(str));
5855 zend_string_release(str);
5859 (
void)BIO_reset(infile);
5862 if (!SMIME_write_PKCS7(outfile, p7, infile, (
int)
flags)) {
5874 sk_X509_pop_free(recipcerts, X509_free);
5885 STACK_OF(X509) *certs =
NULL;
5886 STACK_OF(X509_CRL) *crls =
NULL;
5887 BIO * bio_in =
NULL, * bio_out =
NULL;
5900 bio_in = BIO_new(BIO_s_mem());
5901 if (bio_in ==
NULL) {
5905 if (0 >= BIO_write(bio_in, p7b, (
int)p7b_len)) {
5916 switch (OBJ_obj2nid(p7->type)) {
5917 case NID_pkcs7_signed:
5918 if (p7->d.sign !=
NULL) {
5919 certs = p7->d.sign->cert;
5920 crls = p7->d.sign->crl;
5923 case NID_pkcs7_signedAndEnveloped:
5924 if (p7->d.signed_and_enveloped !=
NULL) {
5925 certs = p7->d.signed_and_enveloped->cert;
5926 crls = p7->d.signed_and_enveloped->crl;
5933 zout = zend_try_array_init(zout);
5938 if (certs !=
NULL) {
5939 for (i = 0; i < sk_X509_num(certs); i++) {
5940 X509* ca = sk_X509_value(certs, i);
5942 bio_out = BIO_new(BIO_s_mem());
5943 if (bio_out && PEM_write_bio_X509(bio_out, ca)) {
5945 BIO_get_mem_ptr(bio_out, &bio_buf);
5947 add_index_zval(zout, i, &zcert);
5954 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
5955 X509_CRL* crl = sk_X509_CRL_value(crls, i);
5957 bio_out = BIO_new(BIO_s_mem());
5958 if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) {
5960 BIO_get_mem_ptr(bio_out, &bio_buf);
5962 add_index_zval(zout, i, &zcert);
5986 zval *zprivkey, * zheaders;
5988 EVP_PKEY * privkey =
NULL;
5991 BIO * infile =
NULL, * outfile =
NULL;
5992 STACK_OF(X509) *others =
NULL;
5995 size_t infilename_len;
5997 size_t outfilename_len;
5998 char * extracertsfilename =
NULL;
5999 size_t extracertsfilename_len;
6014 if (extracertsfilename) {
6015 others = php_openssl_load_all_certs_from_file(
6016 extracertsfilename, extracertsfilename_len, 7);
6017 if (others ==
NULL) {
6022 privkey = php_openssl_pkey_from_zval(zprivkey, 0,
"", 0, 4);
6023 if (privkey ==
NULL) {
6030 cert = php_openssl_x509_from_param(cert_obj, cert_str, 3);
6036 infile = php_openssl_bio_new_file(infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(
flags));
6037 if (infile ==
NULL) {
6042 outfile = php_openssl_bio_new_file(outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
6043 if (outfile ==
NULL) {
6048 p7 = PKCS7_sign(cert, privkey, others, infile, (
int)
flags);
6055 (
void)BIO_reset(infile);
6071 zend_string_release(str);
6078 if (!SMIME_write_PKCS7(outfile, p7, infile, (
int)
flags)) {
6090 sk_X509_pop_free(others, X509_free);
6092 EVP_PKEY_free(privkey);
6093 if (cert && cert_str) {
6105 bool free_recipcert;
6110 size_t infilename_len;
6112 size_t outfilename_len;
6124 cert = php_openssl_x509_from_zval(recipcert, &free_recipcert, 3,
false,
NULL);
6130 key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0,
"", 0, 4);
6138 in = php_openssl_bio_new_file(
6139 infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(
PKCS7_BINARY));
6144 out = php_openssl_bio_new_file(
6145 outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(
PKCS7_BINARY));
6150 p7 = SMIME_read_PKCS7(in, &datain);
6166 if (cert && free_recipcert) {
6180 X509_STORE * store =
NULL;
6182 STACK_OF(X509) *signers=
NULL;
6183 STACK_OF(X509) *others =
NULL;
6184 CMS_ContentInfo * cms =
NULL;
6186 BIO *certout =
NULL, *sigbio =
NULL;
6190 char * extracerts =
NULL;
6191 size_t extracerts_len = 0;
6192 char * signersfilename =
NULL;
6193 size_t signersfilename_len = 0;
6194 char * datafilename =
NULL;
6195 size_t datafilename_len = 0;
6196 char * p7bfilename =
NULL;
6197 size_t p7bfilename_len = 0;
6198 char * sigfile =
NULL;
6199 size_t sigfile_len = 0;
6205 &
flags, &signersfilename, &signersfilename_len, &cainfo,
6206 &extracerts, &extracerts_len, &datafilename, &datafilename_len,
6207 &p7bfilename, &p7bfilename_len,
6212 in = php_openssl_bio_new_file(filename,
filename_len, 1, PHP_OPENSSL_BIO_MODE_R(
flags));
6216 if (sigfile && (
flags & CMS_DETACHED)) {
6219 "Detached signatures not possible with S/MIME encoding");
6222 sigbio = php_openssl_bio_new_file(sigfile, sigfile_len, 1, PHP_OPENSSL_BIO_MODE_R(
flags));
6223 if (sigbio ==
NULL) {
6232 cms = PEM_read_bio_CMS(sigbio,
NULL, 0,
NULL);
6236 cms = d2i_CMS_bio(sigbio,
NULL);
6240 cms = SMIME_read_CMS(sigbio, &datain);
6255 others = php_openssl_load_all_certs_from_file(extracerts, extracerts_len, 5);
6256 if (others ==
NULL) {
6261 store = php_openssl_setup_verify(cainfo, 4);
6268 dataout = php_openssl_bio_new_file(
6269 datafilename, datafilename_len, 6, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
6270 if (dataout ==
NULL) {
6276 p7bout = php_openssl_bio_new_file(
6277 p7bfilename, p7bfilename_len, 7, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
6278 if (p7bout ==
NULL) {
6285 if (CMS_verify(cms, others, store, datain, dataout, (
unsigned int)
flags)) {
6288 if (signersfilename) {
6289 certout = php_openssl_bio_new_file(
6290 signersfilename, signersfilename_len, 3, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
6293 signers = CMS_get0_signers(cms);
6294 if (signers !=
NULL) {
6296 for (i = 0; i < sk_X509_num(signers); i++) {
6297 if (!PEM_write_bio_X509(certout, sk_X509_value(signers, i))) {
6304 sk_X509_free(signers);
6315 if (PEM_write_bio_CMS(p7bout, cms) == 0) {
6329 X509_STORE_free(store);
6341 CMS_ContentInfo_free(cms);
6344 sk_X509_pop_free(others, X509_free);
6352 zval * zrecipcerts, * zheaders =
NULL;
6353 STACK_OF(X509) * recipcerts =
NULL;
6354 BIO * infile =
NULL, * outfile =
NULL;
6357 CMS_ContentInfo * cms =
NULL;
6360 const EVP_CIPHER *cipher =
NULL;
6363 char * infilename =
NULL;
6364 size_t infilename_len;
6365 char * outfilename =
NULL;
6366 size_t outfilename_len;
6372 &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &
flags, &
encoding, &cipherid) ==
FAILURE) {
6377 infile = php_openssl_bio_new_file(
6378 infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(
flags));
6379 if (infile ==
NULL) {
6383 outfile = php_openssl_bio_new_file(
6384 outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(
flags));
6385 if (outfile ==
NULL) {
6389 recipcerts = sk_X509_new_null();
6396 cert = php_openssl_x509_from_zval(zcertval, &free_cert, 3,
true,
NULL);
6404 cert = X509_dup(cert);
6410 sk_X509_push(recipcerts, cert);
6416 cert = php_openssl_x509_from_zval(zrecipcerts, &free_cert, 3,
false,
NULL);
6424 cert = X509_dup(cert);
6430 sk_X509_push(recipcerts, cert);
6434 cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
6435 if (cipher ==
NULL) {
6441 cms = CMS_encrypt(recipcerts, infile, (EVP_CIPHER*)cipher, (
unsigned int)
flags);
6448 if (
flags & CMS_PARTIAL && !(
flags & CMS_STREAM)) {
6462 BIO_printf(outfile,
"%s\n",
ZSTR_VAL(str));
6464 zend_string_release(str);
6468 (
void)BIO_reset(infile);
6472 if (!SMIME_write_CMS(outfile, cms, infile, (
int)
flags)) {
6479 if (CMS_final(cms, infile,
NULL, (
unsigned int)
flags) != 1) {
6484 if (i2d_CMS_bio(outfile, cms) != 1) {
6491 if (CMS_final(cms, infile,
NULL, (
unsigned int)
flags) != 1) {
6496 if (
flags & CMS_STREAM) {
6497 if (PEM_write_bio_CMS_stream(outfile, cms, infile,
flags) == 0) {
6502 if (PEM_write_bio_CMS(outfile, cms) == 0) {
6517 CMS_ContentInfo_free(cms);
6522 sk_X509_pop_free(recipcerts, X509_free);
6533 STACK_OF(X509) *certs =
NULL;
6534 STACK_OF(X509_CRL) *crls =
NULL;
6535 BIO * bio_in =
NULL, * bio_out =
NULL;
6536 CMS_ContentInfo * cms =
NULL;
6548 bio_in = BIO_new(BIO_s_mem());
6549 if (bio_in ==
NULL) {
6553 if (0 >= BIO_write(bio_in, p7b, (
int)p7b_len)) {
6564 switch (OBJ_obj2nid(CMS_get0_type(cms))) {
6565 case NID_pkcs7_signed:
6566 case NID_pkcs7_signedAndEnveloped:
6567 certs = CMS_get1_certs(cms);
6568 crls = CMS_get1_crls(cms);
6574 zout = zend_try_array_init(zout);
6579 if (certs !=
NULL) {
6580 for (i = 0; i < sk_X509_num(certs); i++) {
6581 X509* ca = sk_X509_value(certs, i);
6583 bio_out = BIO_new(BIO_s_mem());
6584 if (bio_out && PEM_write_bio_X509(bio_out, ca)) {
6586 BIO_get_mem_ptr(bio_out, &bio_buf);
6588 add_index_zval(zout, i, &zcert);
6595 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
6596 X509_CRL* crl = sk_X509_CRL_value(crls, i);
6598 bio_out = BIO_new(BIO_s_mem());
6599 if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) {
6601 BIO_get_mem_ptr(bio_out, &bio_buf);
6603 add_index_zval(zout, i, &zcert);
6614 CMS_ContentInfo_free(cms);
6616 if (certs !=
NULL) {
6617 sk_X509_pop_free(certs, X509_free);
6620 sk_X509_CRL_pop_free(crls, X509_CRL_free);
6632 zval *zprivkey, *zheaders;
6634 EVP_PKEY * privkey =
NULL;
6637 CMS_ContentInfo * cms =
NULL;
6638 BIO * infile =
NULL, * outfile =
NULL;
6639 STACK_OF(X509) *others =
NULL;
6642 size_t infilename_len;
6644 size_t outfilename_len;
6645 char * extracertsfilename =
NULL;
6646 size_t extracertsfilename_len;
6663 if (extracertsfilename) {
6664 others = php_openssl_load_all_certs_from_file(
6665 extracertsfilename, extracertsfilename_len, 8);
6666 if (others ==
NULL) {
6671 privkey = php_openssl_pkey_from_zval(zprivkey, 0,
"", 0, 4);
6672 if (privkey ==
NULL) {
6679 cert = php_openssl_x509_from_param(cert_obj, cert_str, 3);
6687 E_WARNING,
"Detached signatures not possible with S/MIME encoding");
6698 if (
flags & CMS_PARTIAL && !(
flags & CMS_STREAM)) {
6702 infile = php_openssl_bio_new_file(
6703 infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(
flags));
6704 if (infile ==
NULL) {
6709 outfile = php_openssl_bio_new_file(
6710 outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
6711 if (outfile ==
NULL) {
6716 cms = CMS_sign(cert, privkey, others, infile, (
unsigned int)
flags);
6722 if (BIO_reset(infile) != 0) {
6741 zend_string_release(str);
6750 if (!SMIME_write_CMS(outfile, cms, infile, (
int)
flags)) {
6757 if (CMS_final(cms, infile,
NULL, (
unsigned int)
flags) != 1) {
6762 if (i2d_CMS_bio(outfile, cms) != 1) {
6769 if (CMS_final(cms, infile,
NULL, (
unsigned int)
flags) != 1) {
6774 if (
flags & CMS_STREAM) {
6775 if (PEM_write_bio_CMS_stream(outfile, cms, infile,
flags) == 0) {
6780 if (PEM_write_bio_CMS(outfile, cms) == 0) {
6794 CMS_ContentInfo_free(cms);
6799 sk_X509_pop_free(others, X509_free);
6801 EVP_PKEY_free(privkey);
6802 if (cert && cert_str) {
6814 bool free_recipcert;
6818 CMS_ContentInfo * cms =
NULL;
6820 size_t infilename_len;
6822 size_t outfilename_len;
6835 cert = php_openssl_x509_from_zval(recipcert, &free_recipcert, 3,
false,
NULL);
6841 key = php_openssl_pkey_from_zval(recipkey ? recipkey : recipcert, 0,
"", 0, recipkey ? 4 : 3);
6849 in = php_openssl_bio_new_file(
6850 infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(CMS_BINARY));
6855 out = php_openssl_bio_new_file(
6856 outfilename, outfilename_len, 2, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
6863 cms = d2i_CMS_bio(in,
NULL);
6866 cms = PEM_read_bio_CMS(in,
NULL, 0,
NULL);
6869 cms = SMIME_read_CMS(in, &datain);
6880 if (CMS_decrypt(cms,
key, cert,
NULL,
out, 0)) {
6887 CMS_ContentInfo_free(cms);
6892 if (cert && free_recipcert) {
6915 EVP_PKEY *pkey = php_openssl_pkey_from_zval(
key, 0,
"", 0, 3);
6924 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey,
NULL);
6925 if (!ctx || EVP_PKEY_sign_init(ctx) <= 0 ||
6926 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
6927 EVP_PKEY_sign(ctx,
NULL, &out_len, (
unsigned char *)
data, data_len) <= 0) {
6934 if (EVP_PKEY_sign(ctx, (
unsigned char *)
ZSTR_VAL(
out), &out_len,
6935 (
unsigned char *)
data, data_len) <= 0) {
6936 zend_string_release(
out);
6947 EVP_PKEY_CTX_free(ctx);
6948 EVP_PKEY_free(pkey);
6964 EVP_PKEY *pkey = php_openssl_pkey_from_zval(
key, 0,
"", 0, 3);
6973 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey,
NULL);
6974 if (!ctx || EVP_PKEY_decrypt_init(ctx) <= 0 ||
6975 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
6976 EVP_PKEY_decrypt(ctx,
NULL, &out_len, (
unsigned char *)
data, data_len) <= 0) {
6983 if (EVP_PKEY_decrypt(ctx, (
unsigned char *)
ZSTR_VAL(
out), &out_len,
6984 (
unsigned char *)
data, data_len) <= 0) {
6985 zend_string_release(
out);
6991 out = zend_string_truncate(
out, out_len, 0);
6997 EVP_PKEY_CTX_free(ctx);
6998 EVP_PKEY_free(pkey);
7014 EVP_PKEY *pkey = php_openssl_pkey_from_zval(
key, 1,
NULL, 0, 3);
7023 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey,
NULL);
7024 if (!ctx || EVP_PKEY_encrypt_init(ctx) <= 0 ||
7025 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
7026 EVP_PKEY_encrypt(ctx,
NULL, &out_len, (
unsigned char *)
data, data_len) <= 0) {
7033 if (EVP_PKEY_encrypt(ctx, (
unsigned char *)
ZSTR_VAL(
out), &out_len,
7034 (
unsigned char *)
data, data_len) <= 0) {
7035 zend_string_release(
out);
7046 EVP_PKEY_CTX_free(ctx);
7047 EVP_PKEY_free(pkey);
7063 EVP_PKEY *pkey = php_openssl_pkey_from_zval(
key, 1,
NULL, 0, 3);
7072 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey,
NULL);
7073 if (!ctx || EVP_PKEY_verify_recover_init(ctx) <= 0 ||
7074 EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
7075 EVP_PKEY_verify_recover(ctx,
NULL, &out_len, (
unsigned char *)
data, data_len) <= 0) {
7082 if (EVP_PKEY_verify_recover(ctx, (
unsigned char *)
ZSTR_VAL(
out), &out_len,
7083 (
unsigned char *)
data, data_len) <= 0) {
7084 zend_string_release(
out);
7090 out = zend_string_truncate(
out, out_len, 0);
7096 EVP_PKEY_CTX_free(ctx);
7097 EVP_PKEY_free(pkey);
7113 if (OPENSSL_G(errors) ==
NULL || OPENSSL_G(errors)->
top == OPENSSL_G(errors)->bottom) {
7117 OPENSSL_G(errors)->bottom = (OPENSSL_G(errors)->bottom + 1) % ERR_NUM_ERRORS;
7118 val = OPENSSL_G(errors)->buffer[OPENSSL_G(errors)->bottom];
7121 ERR_error_string_n(
val,
buf, 256);
7140 const EVP_MD *mdtype;
7151 pkey = php_openssl_pkey_from_zval(
key, 0,
"", 0, 3);
7160 mdtype = EVP_get_digestbyname(
ZSTR_VAL(method_str));
7162 mdtype = php_openssl_get_evp_md_from_algo(method_long);
7164 if (!mdtype && (!can_default_digest || method_long != 0)) {
7165 EVP_PKEY_free(pkey);
7170 md_ctx = EVP_MD_CTX_create();
7172#if PHP_OPENSSL_API_VERSION >= 0x10100
7173 if (md_ctx !=
NULL &&
7174 EVP_DigestSignInit(md_ctx,
NULL, mdtype,
NULL, pkey) &&
7175 EVP_DigestSign(md_ctx,
NULL, &siglen, (
unsigned char*)
data, data_len) &&
7176 (sigbuf = zend_string_alloc(siglen, 0)) !=
NULL &&
7177 EVP_DigestSign(md_ctx, (
unsigned char*)
ZSTR_VAL(sigbuf), &siglen, (
unsigned char*)
data, data_len)) {
7179 if (md_ctx !=
NULL &&
7180 EVP_SignInit(md_ctx, mdtype) &&
7181 EVP_SignUpdate(md_ctx,
data, data_len) &&
7182 (siglen = EVP_PKEY_size(pkey)) &&
7183 (sigbuf = zend_string_alloc(siglen, 0)) !=
NULL &&
7184 EVP_SignFinal(md_ctx, (
unsigned char*)
ZSTR_VAL(sigbuf), (
unsigned int*)&siglen, pkey)) {
7195 EVP_MD_CTX_destroy(md_ctx);
7196 EVP_PKEY_free(pkey);
7207 const EVP_MD *mdtype;
7211 size_t signature_len;
7227 mdtype = EVP_get_digestbyname(
ZSTR_VAL(method_str));
7229 mdtype = php_openssl_get_evp_md_from_algo(method_long);
7231 if (!mdtype && (!can_default_digest || method_long != 0)) {
7236 pkey = php_openssl_pkey_from_zval(
key, 1,
NULL, 0, 3);
7244 md_ctx = EVP_MD_CTX_create();
7245 if (md_ctx ==
NULL ||
7246#
if PHP_OPENSSL_API_VERSION >= 0x10100
7247 !EVP_DigestVerifyInit(md_ctx,
NULL, mdtype,
NULL, pkey) ||
7248 (
err = EVP_DigestVerify(md_ctx, (
unsigned char *)signature, signature_len, (
unsigned char*)
data, data_len)) < 0) {
7250 !EVP_VerifyInit (md_ctx, mdtype) ||
7251 !EVP_VerifyUpdate (md_ctx,
data, data_len) ||
7252 (
err = EVP_VerifyFinal(md_ctx, (
unsigned char *)signature, (
unsigned int)signature_len, pkey)) < 0) {
7256 EVP_MD_CTX_destroy(md_ctx);
7257 EVP_PKEY_free(pkey);
7265 zval *pubkeys, *pubkey, *sealdata, *ekeys, *iv =
NULL;
7268 int i, len1, len2, *eksl, nkeys, iv_len;
7269 unsigned char iv_buf[EVP_MAX_IV_LENGTH + 1], *
buf =
NULL, **eks;
7274 const EVP_CIPHER *cipher;
7275 EVP_CIPHER_CTX *ctx;
7278 &sealdata, &ekeys, &pubkeys, &method, &method_len, &iv) ==
FAILURE) {
7285 nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
7291 cipher = EVP_get_cipherbyname(method);
7297 iv_len = EVP_CIPHER_iv_length(cipher);
7298 if (!iv && iv_len > 0) {
7306 memset(eks, 0,
sizeof(*eks) * nkeys);
7307 memset(pkeys, 0,
sizeof(*pkeys) * nkeys);
7312 pkeys[i] = php_openssl_pkey_from_zval(pubkey, 1,
NULL, 0, 4);
7313 if (pkeys[i] ==
NULL) {
7320 eks[i] =
emalloc(EVP_PKEY_size(pkeys[i]) + 1);
7324 ctx = EVP_CIPHER_CTX_new();
7325 if (ctx ==
NULL || !EVP_EncryptInit(ctx,cipher,
NULL,
NULL)) {
7326 EVP_CIPHER_CTX_free(ctx);
7333 buf =
emalloc(data_len + EVP_CIPHER_CTX_block_size(ctx));
7336 if (EVP_SealInit(ctx, cipher, eks, eksl, &iv_buf[0], pkeys, nkeys) <= 0 ||
7337 !EVP_SealUpdate(ctx,
buf, &len1, (
unsigned char *)
data, (
int)data_len) ||
7338 !EVP_SealFinal(ctx,
buf + len1, &len2)) {
7340 EVP_CIPHER_CTX_free(ctx);
7346 if (len1 + len2 > 0) {
7350 ekeys = zend_try_array_init(ekeys);
7352 EVP_CIPHER_CTX_free(ctx);
7356 for (i=0; i<nkeys; i++) {
7357 eks[i][eksl[i]] =
'\0';
7364 iv_buf[iv_len] =
'\0';
7371 EVP_CIPHER_CTX_free(ctx);
7374 for (i=0; i<nkeys; i++) {
7375 if (pkeys[i] !=
NULL) {
7376 EVP_PKEY_free(pkeys[i]);
7391 zval *privkey, *opendata;
7393 int len1, len2, cipher_iv_len;
7394 unsigned char *
buf, *iv_buf;
7395 EVP_CIPHER_CTX *ctx;
7400 char *method, *iv =
NULL;
7401 size_t method_len, iv_len = 0;
7402 const EVP_CIPHER *cipher;
7405 &ekey, &ekey_len, &privkey, &method, &method_len, &iv, &iv_len) ==
FAILURE) {
7411 pkey = php_openssl_pkey_from_zval(privkey, 0,
"", 0, 4);
7420 cipher = EVP_get_cipherbyname(method);
7426 cipher_iv_len = EVP_CIPHER_iv_length(cipher);
7427 if (cipher_iv_len > 0) {
7432 if ((
size_t)cipher_iv_len != iv_len) {
7436 iv_buf = (
unsigned char *)iv;
7443 ctx = EVP_CIPHER_CTX_new();
7444 if (ctx !=
NULL && EVP_OpenInit(ctx, cipher, (
unsigned char *)ekey, (
int)ekey_len, iv_buf, pkey) &&
7445 EVP_OpenUpdate(ctx,
buf, &len1, (
unsigned char *)
data, (
int)data_len) &&
7446 EVP_OpenFinal(ctx,
buf + len1, &len2) && (len1 + len2 > 0)) {
7447 buf[len1 + len2] =
'\0';
7456 EVP_PKEY_free(pkey);
7457 EVP_CIPHER_CTX_free(ctx);
7461static void php_openssl_add_method_or_alias(
const OBJ_NAME *
name,
void *
arg)
7467static void php_openssl_add_method(
const OBJ_NAME *
name,
void *
arg)
7469 if (
name->alias == 0) {
7484 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
7485 aliases ? php_openssl_add_method_or_alias: php_openssl_add_method,
7490#if PHP_OPENSSL_API_VERSION >= 0x30000
7491static void php_openssl_add_cipher_name(
const char *
name,
void *
arg)
7499static void php_openssl_add_cipher_or_alias(EVP_CIPHER *cipher,
void *
arg)
7501 EVP_CIPHER_names_do_all(cipher, php_openssl_add_cipher_name,
arg);
7504static void php_openssl_add_cipher(EVP_CIPHER *cipher,
void *
arg)
7506 php_openssl_add_cipher_name(EVP_CIPHER_get0_name(cipher),
arg);
7524#if PHP_OPENSSL_API_VERSION >= 0x30000
7525 EVP_CIPHER_do_all_provided(
NULL,
7526 aliases ? php_openssl_add_cipher_or_alias : php_openssl_add_cipher,
7530 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
7531 aliases ? php_openssl_add_method_or_alias : php_openssl_add_method,
7538#ifdef HAVE_EVP_PKEY_EC
7541 EC_builtin_curve *curves =
NULL;
7544 size_t len = EC_get_builtin_curves(
NULL, 0);
7550 curves =
emalloc(
sizeof(EC_builtin_curve) *
len);
7551 if (!EC_get_builtin_curves(curves,
len)) {
7556 for (i = 0; i <
len; i++) {
7557 sname = OBJ_nid2sn(curves[i].nid);
7558 if (sname !=
NULL) {
7570 bool raw_output = 0;
7571 char *
data, *method;
7572 size_t data_len, method_len;
7573 const EVP_MD *mdtype;
7575 unsigned int siglen;
7581 mdtype = EVP_get_digestbyname(method);
7587 siglen = EVP_MD_size(mdtype);
7588 sigbuf = zend_string_alloc(siglen, 0);
7590 md_ctx = EVP_MD_CTX_create();
7591 if (EVP_DigestInit(md_ctx, mdtype) &&
7592 EVP_DigestUpdate(md_ctx, (
unsigned char *)
data, data_len) &&
7593 EVP_DigestFinal (md_ctx, (
unsigned char *)
ZSTR_VAL(sigbuf), &siglen)) {
7599 int digest_str_len = siglen * 2;
7600 zend_string *digest_str = zend_string_alloc(digest_str_len, 0);
7603 ZSTR_VAL(digest_str)[digest_str_len] =
'\0';
7613 EVP_MD_CTX_destroy(md_ctx);
7628#if PHP_OPENSSL_API_VERSION >= 0x10100
7630 mode->is_aead =
true;
7631 mode->aead_get_tag_flag = EVP_CTRL_AEAD_GET_TAG;
7632 mode->aead_set_tag_flag = EVP_CTRL_AEAD_SET_TAG;
7633 mode->aead_ivlen_flag = EVP_CTRL_AEAD_SET_IVLEN;
7639 int cipher_mode = EVP_CIPHER_mode(cipher_type);
7641 switch (cipher_mode) {
7642#if PHP_OPENSSL_API_VERSION >= 0x10100
7645 case EVP_CIPH_GCM_MODE:
7646 case EVP_CIPH_CCM_MODE:
7647# ifdef EVP_CIPH_OCB_MODE
7648 case EVP_CIPH_OCB_MODE:
7651 mode->set_tag_length_always = cipher_mode == EVP_CIPH_OCB_MODE;
7653 php_openssl_set_aead_flags(
mode);
7654 mode->set_tag_length_when_encrypting = cipher_mode == EVP_CIPH_CCM_MODE;
7655 mode->is_single_run_aead = cipher_mode == EVP_CIPH_CCM_MODE;
7657# ifdef NID_chacha20_poly1305
7659 if (EVP_CIPHER_nid(cipher_type) == NID_chacha20_poly1305) {
7660 php_openssl_set_aead_flags(
mode);
7666# ifdef EVP_CIPH_GCM_MODE
7667 case EVP_CIPH_GCM_MODE:
7669 mode->aead_get_tag_flag = EVP_CTRL_GCM_GET_TAG;
7670 mode->aead_set_tag_flag = EVP_CTRL_GCM_SET_TAG;
7671 mode->aead_ivlen_flag = EVP_CTRL_GCM_SET_IVLEN;
7674# ifdef EVP_CIPH_CCM_MODE
7675 case EVP_CIPH_CCM_MODE:
7677 mode->is_single_run_aead = 1;
7678 mode->set_tag_length_when_encrypting = 1;
7679 mode->aead_get_tag_flag = EVP_CTRL_CCM_GET_TAG;
7680 mode->aead_set_tag_flag = EVP_CTRL_CCM_SET_TAG;
7681 mode->aead_ivlen_flag = EVP_CTRL_CCM_SET_IVLEN;
7688static int php_openssl_validate_iv(
const char **piv,
size_t *piv_len,
size_t iv_required_len,
7693 if (
mode->is_aead) {
7694 if (EVP_CIPHER_CTX_ctrl(cipher_ctx,
mode->aead_ivlen_flag, *piv_len,
NULL) != 1) {
7702 if (*piv_len == iv_required_len) {
7706 iv_new =
ecalloc(1, iv_required_len + 1);
7708 if (*piv_len == 0) {
7710 *piv_len = iv_required_len;
7717 if (*piv_len < iv_required_len) {
7719 "IV passed is only %zd bytes long, cipher expects an IV of precisely %zd bytes, padding with \\0",
7720 *piv_len, iv_required_len);
7721 memcpy(iv_new, *piv, *piv_len);
7722 *piv_len = iv_required_len;
7729 "IV passed is %zd bytes long which is longer than the %zd expected by selected cipher, truncating",
7730 *piv_len, iv_required_len);
7731 memcpy(iv_new, *piv, iv_required_len);
7732 *piv_len = iv_required_len;
7740static int php_openssl_cipher_init(
const EVP_CIPHER *cipher_type,
7742 const char **ppassword,
size_t *ppassword_len,
bool *free_password,
7743 const char **piv,
size_t *piv_len,
bool *free_iv,
7747 int key_len, password_len;
7752 max_iv_len = EVP_CIPHER_iv_length(cipher_type);
7753 if (enc && *piv_len == 0 && max_iv_len > 0 && !
mode->is_aead) {
7755 "Using an empty Initialization Vector (iv) is potentially insecure and not recommended");
7758 if (!EVP_CipherInit_ex(cipher_ctx, cipher_type,
NULL,
NULL,
NULL, enc)) {
7762 if (php_openssl_validate_iv(piv, piv_len, max_iv_len, free_iv, cipher_ctx,
mode) ==
FAILURE) {
7765 if (
mode->set_tag_length_always || (enc &&
mode->set_tag_length_when_encrypting)) {
7766 if (!EVP_CIPHER_CTX_ctrl(cipher_ctx,
mode->aead_set_tag_flag, tag_len,
NULL)) {
7771 if (!enc && tag && tag_len > 0) {
7772 if (!
mode->is_aead) {
7774 }
else if (!EVP_CIPHER_CTX_ctrl(cipher_ctx,
mode->aead_set_tag_flag, tag_len, (
unsigned char *) tag)) {
7780 password_len = (int) *ppassword_len;
7781 key_len = EVP_CIPHER_key_length(cipher_type);
7782 if (key_len > password_len) {
7791 *ppassword = (
char *)
key;
7792 *ppassword_len = key_len;
7795 if (password_len > key_len && !EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len)) {
7798 key = (
unsigned char*)*ppassword;
7801 if (!EVP_CipherInit_ex(cipher_ctx,
NULL,
NULL,
key, (
unsigned char *)*piv, enc)) {
7806 EVP_CIPHER_CTX_set_padding(cipher_ctx, 0);
7813static int php_openssl_cipher_update(
const EVP_CIPHER *cipher_type,
7815 zend_string **poutbuf,
int *poutlen,
const char *
data,
size_t data_len,
7816 const char *aad,
size_t aad_len,
int enc)
7820 if (
mode->is_single_run_aead && !EVP_CipherUpdate(cipher_ctx,
NULL, &i,
NULL, (
int)data_len)) {
7826 if (
mode->is_aead && !EVP_CipherUpdate(cipher_ctx,
NULL, &i, (
const unsigned char *) aad, (
int) aad_len)) {
7832 *poutbuf = zend_string_alloc((
int)data_len + EVP_CIPHER_block_size(cipher_type), 0);
7834 if (!EVP_CipherUpdate(cipher_ctx, (
unsigned char*)
ZSTR_VAL(*poutbuf),
7835 &i, (
const unsigned char *)
data, (
int)data_len)) {
7856 const char *
data,
size_t data_len,
7857 const char *method,
size_t method_len,
7858 const char *password,
size_t password_len,
7860 const char *iv,
size_t iv_len,
7862 const char *aad,
size_t aad_len)
7864 const EVP_CIPHER *cipher_type;
7865 EVP_CIPHER_CTX *cipher_ctx;
7868 bool free_iv = 0, free_password = 0;
7877 cipher_type = EVP_get_cipherbyname(method);
7883 cipher_ctx = EVP_CIPHER_CTX_new();
7889 php_openssl_load_cipher_mode(&
mode, cipher_type);
7891 if (php_openssl_cipher_init(cipher_type, cipher_ctx, &
mode,
7892 &password, &password_len, &free_password,
7894 php_openssl_cipher_update(cipher_type, cipher_ctx, &
mode, &outbuf, &outlen,
7897 }
else if (EVP_EncryptFinal(cipher_ctx, (
unsigned char *)
ZSTR_VAL(outbuf) + outlen, &i)) {
7905 base64_str = php_base64_encode((
unsigned char*)
ZSTR_VAL(outbuf), outlen);
7907 outbuf = base64_str;
7909 if (
mode.is_aead && tag) {
7910 zend_string *tag_str = zend_string_alloc(tag_len, 0);
7912 if (EVP_CIPHER_CTX_ctrl(cipher_ctx,
mode.aead_get_tag_flag, tag_len,
ZSTR_VAL(tag_str)) == 1) {
7924 }
else if (
mode.is_aead) {
7935 if (free_password) {
7936 efree((
void *) password);
7942 EVP_CIPHER_CTX_free(cipher_ctx);
7950 char *
data, *method, *password, *iv =
"", *aad =
"";
7951 size_t data_len, method_len, password_len, iv_len = 0, aad_len = 0;
7956 &password, &password_len, &
options, &iv, &iv_len, &tag, &aad, &aad_len, &tag_len) ==
FAILURE) {
7960 if ((
ret =
php_openssl_encrypt(
data, data_len, method, method_len, password, password_len,
options, iv, iv_len, tag, tag_len, aad, aad_len))) {
7969 const char *
data,
size_t data_len,
7970 const char *method,
size_t method_len,
7971 const char *password,
size_t password_len,
7973 const char *iv,
size_t iv_len,
7975 const char *aad,
size_t aad_len)
7977 const EVP_CIPHER *cipher_type;
7978 EVP_CIPHER_CTX *cipher_ctx;
7982 bool free_iv = 0, free_password = 0;
7991 cipher_type = EVP_get_cipherbyname(method);
7997 cipher_ctx = EVP_CIPHER_CTX_new();
8003 php_openssl_load_cipher_mode(&
mode, cipher_type);
8006 base64_str = php_base64_decode((
unsigned char*)
data, data_len);
8009 EVP_CIPHER_CTX_free(cipher_ctx);
8016 if (php_openssl_cipher_init(cipher_type, cipher_ctx, &
mode,
8017 &password, &password_len, &free_password,
8019 php_openssl_cipher_update(cipher_type, cipher_ctx, &
mode, &outbuf, &outlen,
8022 }
else if (
mode.is_single_run_aead ||
8023 EVP_DecryptFinal(cipher_ctx, (
unsigned char *)
ZSTR_VAL(outbuf) + outlen, &i)) {
8033 if (free_password) {
8034 efree((
void *) password);
8043 EVP_CIPHER_CTX_free(cipher_ctx);
8051 char *
data, *method, *password, *iv =
"", *tag =
NULL, *aad =
"";
8052 size_t data_len, method_len, password_len, iv_len = 0, tag_len = 0, aad_len = 0;
8056 &password, &password_len, &
options, &iv, &iv_len, &tag, &tag_len, &aad, &aad_len) ==
FAILURE) {
8065 if ((
ret =
php_openssl_decrypt(
data, data_len, method, method_len, password, password_len,
options, iv, iv_len, tag, tag_len, aad, aad_len))) {
8073static inline const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(
const char *method)
8075 const EVP_CIPHER *cipher_type;
8077 cipher_type = EVP_get_cipherbyname(method);
8088 const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
8090 return cipher_type ==
NULL ? -1 : EVP_CIPHER_iv_length(cipher_type);
8117 const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
8119 return cipher_type ==
NULL ? -1 : EVP_CIPHER_key_length(cipher_type);
8147 if (buffer_length <= 0) {
8155 buffer = zend_string_alloc(buffer_length, 0);
8159 if (RAND_bytes((
unsigned char*)
ZSTR_VAL(
buffer), (
int)buffer_length) <= 0) {
8174 zval *zstrong_result_returned =
NULL;
8184 if (zstrong_result_returned) {
8187 }
else if (zstrong_result_returned) {
getenv(?string $name=null, bool $local_only=false)
file(string $filename, int $flags=0, $context=null)
is_file(string $filename)
gettimeofday(bool $as_float=false)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
PHPAPI int php_check_open_basedir(const char *path)
PHPAPI char * expand_filepath(const char *filepath, char *real_path)
PHPAPI const php_stream_wrapper php_stream_ftp_wrapper
#define pass(a, b, c, mul)
PHPAPI const php_stream_wrapper php_stream_http_wrapper
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args)
PHPAPI void make_digest_ex(char *md5str, const unsigned char *digest, int len)
#define EVP_PKEY_get0_DSA(_pkey)
@ OPENSSL_KEYTYPE_DEFAULT
int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
PHP_OPENSSL_API zend_string * php_openssl_encrypt(const char *data, size_t data_len, const char *method, size_t method_len, const char *password, size_t password_len, zend_long options, const char *iv, size_t iv_len, zval *tag, zend_long tag_len, const char *aad, size_t aad_len)
#define PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(_var, _name)
#define OPENSSL_ALGO_RMD160
#define EVP_PKEY_get0_RSA(_pkey)
#define EVP_CIPHER_CTX_reset
#define PHP_OPENSSL_CHECK_LONG_TO_INT(_var, _name, _arg_num)
PHP_OPENSSL_API zend_string * php_openssl_random_pseudo_bytes(zend_long buffer_length)
#define PHP_OPENSSL_ASN1_INTEGER_set
#define SET_OPTIONAL_STRING_ARG(key, varname, defval)
#define PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(_var, _name, _arg_num)
#define X509_getm_notAfter
#define SET_OPTIONAL_LONG_ARG(key, varname, defval)
#define OPENSSL_ALGO_SHA256
zend_string * php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw)
PHP_OPENSSL_API zend_long php_openssl_cipher_key_length(const char *method)
#define OPENSSL_ALGO_DSS1
struct _php_openssl_x509_request_object php_openssl_request_object
#define X509_getm_notBefore
#define Z_OPENSSL_REQUEST_P(zv)
void php_openssl_store_errors(void)
#define OPENSSL_ALGO_SHA384
#define PHP_SSL_REQ_INIT(req)
@ PHP_OPENSSL_CIPHER_RC2_40
@ PHP_OPENSSL_CIPHER_DEFAULT
@ PHP_OPENSSL_CIPHER_AES_128_CBC
@ PHP_OPENSSL_CIPHER_AES_192_CBC
@ PHP_OPENSSL_CIPHER_AES_256_CBC
@ PHP_OPENSSL_CIPHER_RC2_128
@ PHP_OPENSSL_CIPHER_3DES
@ PHP_OPENSSL_CIPHER_RC2_64
php_stream * php_openssl_get_stream_from_ssl_handle(const SSL *ssl)
zend_module_entry openssl_module_entry
#define OPENSSL_PKEY_GET_BN(_type, _name)
#define EVP_PKEY_get0_DH(_pkey)
#define OPENSSL_ALGO_SHA224
int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
PHP_OPENSSL_API zend_string * php_openssl_decrypt(const char *data, size_t data_len, const char *method, size_t method_len, const char *password, size_t password_len, zend_long options, const char *iv, size_t iv_len, const char *tag, zend_long tag_len, const char *aad, size_t aad_len)
#define PHP_SSL_REQ_PARSE(req, zval)
struct _php_openssl_pkey_object php_openssl_pkey_object
#define Z_OPENSSL_PKEY_P(zv)
#define EVP_PKEY_get0_EC_KEY(_pkey)
#define OPENSSL_PKEY_SET_BN(_data, _name)
#define OPENSSL_ALGO_SHA1
#define PHP_OPENSSL_CHECK_LONG_TO_INT_NULL_RETURN(_var, _name)
#define OPENSSL_ALGO_SHA512
zend_class_entry * php_openssl_certificate_ce
#define PHP_SSL_CONFIG_SYNTAX_CHECK(var)
#define PHP_SSL_REQ_DISPOSE(req)
PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method)
#define PHP_OPENSSL_RAND_ADD_TIME()
#define PHP_OPENSSL_CHECK_SIZE_T_TO_INT(_var, _name, _arg_num)
int php_openssl_get_ssl_stream_data_index(void)
bool php_openssl_check_path_ex(const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num, bool contains_file_protocol, bool is_from_array, const char *option_name)
const OPENSSL_DONT_ZERO_PAD_KEY
openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm=OPENSSL_ALGO_SHA1)
openssl_pkey_free(OpenSSLAsymmetricKey $key)
openssl_x509_export(OpenSSLCertificate|string $certificate, &$output, bool $no_text=true)
openssl_csr_export_to_file(OpenSSLCertificateSigningRequest|string $csr, string $output_filename, bool $no_text=true)
openssl_pkcs12_read(string $pkcs12, &$certificates, #[\SensitiveParameter] string $passphrase)
openssl_dh_compute_key(string $public_key, #[\SensitiveParameter] OpenSSLAsymmetricKey $private_key)
const OPENSSL_ZERO_PADDING
openssl_x509_check_private_key(OpenSSLCertificate|string $certificate, #[\SensitiveParameter] $private_key)
openssl_x509_free(OpenSSLCertificate $certificate)
openssl_get_curve_names()
openssl_seal(#[\SensitiveParameter] string $data, &$sealed_data, &$encrypted_keys, array $public_key, string $cipher_algo, &$iv=null)
openssl_pkcs7_decrypt(string $input_filename, string $output_filename, #[\SensitiveParameter] $certificate, #[\SensitiveParameter] $private_key=null)
openssl_x509_parse(OpenSSLCertificate|string $certificate, bool $short_names=true)
openssl_pkey_derive($public_key, #[\SensitiveParameter] $private_key, int $key_length=0)
openssl_spki_new(#[\SensitiveParameter] OpenSSLAsymmetricKey $private_key, string $challenge, int $digest_algo=OPENSSL_ALGO_MD5)
openssl_pkcs12_export_to_file(OpenSSLCertificate|string $certificate, string $output_filename, #[\SensitiveParameter] $private_key, #[\SensitiveParameter] string $passphrase, array $options=[])
openssl_pkey_get_details(OpenSSLAsymmetricKey $key)
openssl_cms_read(string $input_filename, &$certificates)
openssl_pkey_export_to_file(#[\SensitiveParameter] $key, string $output_filename, #[\SensitiveParameter] ?string $passphrase=null, ?array $options=null)
openssl_pkcs12_export(OpenSSLCertificate|string $certificate, &$output, #[\SensitiveParameter] $private_key, #[\SensitiveParameter] string $passphrase, array $options=[])
openssl_csr_export(OpenSSLCertificateSigningRequest|string $csr, &$output, bool $no_text=true)
openssl_csr_get_public_key(OpenSSLCertificateSigningRequest|string $csr, bool $short_names=true)
openssl_spki_export(string $spki)
openssl_digest(string $data, string $digest_algo, bool $binary=false)
openssl_x509_verify(OpenSSLCertificate|string $certificate, $public_key)
openssl_pkcs7_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags=0, int $cipher_algo=OPENSSL_CIPHER_AES_128_CBC)
openssl_get_cert_locations()
openssl_x509_checkpurpose(OpenSSLCertificate|string $certificate, int $purpose, array $ca_info=[], ?string $untrusted_certificates_file=null)
openssl_pkey_get_public($public_key)
openssl_cms_sign(string $input_filename, string $output_filename, OpenSSLCertificate|string $certificate, #[\SensitiveParameter] $private_key, ?array $headers, int $flags=0, int $encoding=OPENSSL_ENCODING_SMIME, ?string $untrusted_certificates_filename=null)
openssl_get_md_methods(bool $aliases=false)
openssl_private_encrypt(#[\SensitiveParameter] string $data, &$encrypted_data, #[\SensitiveParameter] $private_key, int $padding=OPENSSL_PKCS1_PADDING)
const OPENSSL_VERSION_TEXT
openssl_x509_fingerprint(OpenSSLCertificate|string $certificate, string $digest_algo="sha1", bool $binary=false)
openssl_spki_verify(string $spki)
openssl_csr_get_subject(OpenSSLCertificateSigningRequest|string $csr, bool $short_names=true)
openssl_random_pseudo_bytes(int $length, &$strong_result=null)
openssl_public_encrypt(#[\SensitiveParameter] string $data, &$encrypted_data, $public_key, int $padding=OPENSSL_PKCS1_PADDING)
openssl_pbkdf2(#[\SensitiveParameter] string $password, string $salt, int $key_length, int $iterations, string $digest_algo="sha1")
const OPENSSL_KEYTYPE_X448
openssl_spki_export_challenge(string $spki)
openssl_verify(string $data, string $signature, $public_key, string|int $algorithm=OPENSSL_ALGO_SHA1)
openssl_cipher_key_length(string $cipher_algo)
openssl_private_decrypt(string $data, #[\SensitiveParameter] &$decrypted_data, #[\SensitiveParameter] $private_key, int $padding=OPENSSL_PKCS1_PADDING)
openssl_encrypt(#[\SensitiveParameter] string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options=0, string $iv="", &$tag=null, string $aad="", int $tag_length=16)
openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options=0, string $iv="", ?string $tag=null, string $aad="")
const OPENSSL_KEYTYPE_ED448
openssl_open(string $data, #[\SensitiveParameter] &$output, string $encrypted_key, #[\SensitiveParameter] $private_key, string $cipher_algo, ?string $iv=null)
openssl_csr_sign(OpenSSLCertificateSigningRequest|string $csr, OpenSSLCertificate|string|null $ca_certificate, #[\SensitiveParameter] $private_key, int $days, ?array $options=null, int $serial=0, ?string $serial_hex=null)
openssl_cms_decrypt(string $input_filename, string $output_filename, #[\SensitiveParameter] $certificate, #[\SensitiveParameter] $private_key=null, int $encoding=OPENSSL_ENCODING_SMIME)
openssl_cms_verify(string $input_filename, int $flags=0, ?string $certificates=null, array $ca_info=[], ?string $untrusted_certificates_filename=null, ?string $content=null, ?string $pk7=null, ?string $sigfile=null, int $encoding=OPENSSL_ENCODING_SMIME)
openssl_public_decrypt(string $data, #[\SensitiveParameter] &$decrypted_data, $public_key, int $padding=OPENSSL_PKCS1_PADDING)
openssl_cipher_iv_length(string $cipher_algo)
const OPENSSL_KEYTYPE_ED25519
openssl_pkey_new(?array $options=null)
openssl_pkey_get_private(#[\SensitiveParameter] $private_key, #[\SensitiveParameter] ?string $passphrase=null)
openssl_get_cipher_methods(bool $aliases=false)
openssl_x509_export_to_file(OpenSSLCertificate|string $certificate, string $output_filename, bool $no_text=true)
const OPENSSL_KEYTYPE_X25519
openssl_pkey_export(#[\SensitiveParameter] $key, &$output, #[\SensitiveParameter] ?string $passphrase=null, ?array $options=null)
openssl_x509_read(OpenSSLCertificate|string $certificate)
openssl_csr_new(array $distinguished_names, #[\SensitiveParameter] &$private_key, ?array $options=null, ?array $extra_attributes=null)
openssl_cms_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags=0, int $encoding=OPENSSL_ENCODING_SMIME, int $cipher_algo=OPENSSL_CIPHER_AES_128_CBC)
openssl_pkcs7_verify(string $input_filename, int $flags, ?string $signers_certificates_filename=null, array $ca_info=[], ?string $untrusted_certificates_filename=null, ?string $content=null, ?string $output_filename=null)
openssl_pkcs7_sign(string $input_filename, string $output_filename, OpenSSLCertificate|string $certificate, #[\SensitiveParameter] $private_key, ?array $headers, int $flags=PKCS7_DETACHED, ?string $untrusted_certificates_filename=null)
openssl_pkcs7_read(string $data, &$certificates)
php_info_print_table_start()
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
#define PHP_MSHUTDOWN_FUNCTION
#define PHP_MINIT_FUNCTION
#define PHP_MINFO_FUNCTION
#define PHP_GINIT_FUNCTION
#define PHP_GSHUTDOWN_FUNCTION
#define PHP_MODULE_GLOBALS
mktime(int $hour, ?int $minute=null, ?int $second=null, ?int $month=null, ?int $day=null, ?int $year=null)
unsigned const char * end
PHP_JSON_API size_t int options
php_json_error_code error_code
unsigned char key[REFLECTION_KEY_LEN]
xmlCharEncodingHandlerPtr encoding
PHPAPI php_stream_transport_factory_func php_stream_generic_socket_factory
PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory)
PHPAPI int php_stream_xport_unregister(const char *protocol)
struct _php_stream php_stream
PHPAPI zend_result php_register_url_stream_wrapper(const char *protocol, const php_stream_wrapper *wrapper)
PHPAPI zend_result php_unregister_url_stream_wrapper(const char *protocol)
bool set_tag_length_always
bool set_tag_length_when_encrypting
const EVP_CIPHER * priv_key_encrypt_cipher
char * request_extensions_section
char * extensions_section
php_stream * php_openssl_ssl_socket_factory(const char *proto, size_t protolen, const char *resourcename, size_t resourcenamelen, const char *persistent_id, int options, int flags, struct timeval *timeout, php_stream_context *context STREAMS_DC)
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
ZEND_API size_t(* zend_printf)(const char *format,...)
#define ZEND_TSRMLS_CACHE_UPDATE()
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
ZEND_API void add_index_string(zval *arg, zend_ulong index, const char *str)
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
ZEND_API void add_index_bool(zval *arg, zend_ulong index, bool b)
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va)
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type)
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
ZEND_API zend_result add_next_index_str(zval *arg, zend_string *str)
#define ZEND_TRY_ASSIGN_REF_FALSE(zv)
#define CHECK_NULL_PATH(p, l)
#define Z_PARAM_OBJ_OF_CLASS_OR_STR(destination_object, base_ce, destination_string)
#define Z_PARAM_PATH_OR_NULL(dest, dest_len)
#define Z_PARAM_ARRAY_OR_NULL(dest)
#define ZEND_TRY_ASSIGN_REF_STRINGL(zv, string, len)
#define ZEND_PARSE_PARAMETERS_END()
#define Z_PARAM_STR_OR_NULL(dest)
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
#define ZEND_TRY_ASSIGN_REF_TMP(zv, other_zv)
#define RETVAL_NEW_STR(s)
#define ZEND_GET_MODULE(name)
#define zend_parse_parameters_none()
#define Z_PARAM_STRING(dest, dest_len)
#define Z_PARAM_STRING_OR_NULL(dest, dest_len)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define ZEND_TRY_ASSIGN_REF_NULL(zv)
#define Z_PARAM_LONG(dest)
#define RETURN_NEW_STR(s)
#define Z_PARAM_OBJ_OF_CLASS_OR_STR_OR_NULL(destination_object, base_ce, destination_string)
#define ZEND_TRY_ASSIGN_REF_TRUE(zv)
#define ZEND_TRY_ASSIGN_REF_NEW_STR(zv, str)
#define Z_PARAM_STR_OR_LONG(dest_str, dest_long)
#define Z_PARAM_BOOL(dest)
#define Z_PARAM_OBJECT_OF_CLASS(dest, _ce)
#define Z_PARAM_PATH(dest, dest_len)
#define Z_PARAM_ARRAY(dest)
#define Z_PARAM_ZVAL_OR_NULL(dest)
#define Z_PARAM_ZVAL(dest)
#define ZVAL_STRINGL(z, s, l)
#define RETVAL_STRINGL(s, l)
#define ecalloc(nmemb, size)
#define pefree(ptr, persistent)
#define safe_emalloc(nmemb, size, offset)
#define pecalloc(nmemb, size, persistent)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API zend_class_entry * zend_ce_exception
ZEND_API zend_class_entry * zend_ce_value_error
ZEND_API ZEND_COLD zend_object * zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API const char * get_active_function_arg_name(uint32_t arg_num)
union _zend_function zend_function
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h)
#define ZEND_HASH_FOREACH_NUM_KEY_VAL(ht, _h, _val)
#define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_FOREACH_VAL(ht, _val)
ZEND_API char * zend_ini_string(const char *name, size_t name_length, int orig)
#define UNREGISTER_INI_ENTRIES()
#define REGISTER_INI_ENTRIES()
#define DISPLAY_INI_ENTRIES()
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
#define INIT_FUNC_ARGS_PASSTHRU
struct _zend_module_dep zend_module_dep
struct _zend_module_entry zend_module_entry
#define ZEND_MOD_REQUIRED(name)
#define STANDARD_MODULE_PROPERTIES_EX
#define STANDARD_MODULE_HEADER_EX
ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2)
ZEND_API const zend_object_handlers std_object_handlers
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
ZEND_API char *ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length)
ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2)
#define ZEND_THREEWAY_COMPARE(a, b)
#define XtOffsetOf(s_type, field)
#define EMPTY_SWITCH_DEFAULT_CASE()
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define ZEND_LONG_INT_OVFL(zlong)
ZEND_API zend_string * zend_string_concat2(const char *str1, size_t str1_len, const char *str2, size_t str2_len)
#define Z_STRVAL_P(zval_p)
#define Z_ARRVAL_P(zval_p)
struct _zend_array HashTable
#define Z_STRLEN_P(zval_p)
#define Z_OBJCE_P(zval_p)
ZEND_RESULT_CODE zend_result
struct _zend_object_handlers zend_object_handlers
#define ZVAL_COPY_VALUE(z, v)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define VCWD_STAT(path, buff)