Skip to content

Commit 040ea4a

Browse files
authored
Revert "Fix phpGH-7737: openssl_seal/openssl_open do not handle tagged algorithm…" (php#20698)
This reverts commit 2ee5e6b.
1 parent 2ee5e6b commit 040ea4a

File tree

4 files changed

+50
-165
lines changed

4 files changed

+50
-165
lines changed

ext/openssl/openssl.c

Lines changed: 47 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -4171,57 +4171,42 @@ PHP_FUNCTION(openssl_verify)
41714171
/* {{{ Seals data */
41724172
PHP_FUNCTION(openssl_seal)
41734173
{
4174-
zval *pubkeys, *pubkey, *sealdata, *ekeys, *iv = NULL, *tag = NULL;
4174+
zval *pubkeys, *pubkey, *sealdata, *ekeys, *iv = NULL;
41754175
HashTable *pubkeysht;
4176-
EVP_PKEY **pkeys = NULL;
4177-
int i, len1, len2, *eksl = NULL, nkeys = 0, iv_len;
4178-
unsigned char iv_buf[EVP_MAX_IV_LENGTH + 1], *buf = NULL, **eks = NULL;
4176+
EVP_PKEY **pkeys;
4177+
int i, len1, len2, *eksl, nkeys, iv_len;
4178+
unsigned char iv_buf[EVP_MAX_IV_LENGTH + 1], *buf = NULL, **eks;
41794179
char * data;
41804180
size_t data_len;
41814181
char *method;
41824182
size_t method_len;
41834183
const EVP_CIPHER *cipher;
4184-
EVP_CIPHER_CTX *ctx = NULL;
4185-
size_t tag_len;
4184+
EVP_CIPHER_CTX *ctx;
41864185

4187-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "szzas|z!z!", &data, &data_len,
4188-
&sealdata, &ekeys, &pubkeys, &method, &method_len, &iv, &tag) == FAILURE) {
4186+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "szzas|z", &data, &data_len,
4187+
&sealdata, &ekeys, &pubkeys, &method, &method_len, &iv) == FAILURE) {
41894188
RETURN_THROWS();
41904189
}
4191-
RETVAL_FALSE;
41924190

41934191
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data, 1);
41944192

41954193
pubkeysht = Z_ARRVAL_P(pubkeys);
41964194
nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
41974195
if (!nkeys) {
41984196
zend_argument_must_not_be_empty_error(4);
4199-
goto clean_exit;
4197+
RETURN_THROWS();
42004198
}
42014199

42024200
cipher = php_openssl_get_evp_cipher_by_name(method);
42034201
if (!cipher) {
42044202
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
4205-
goto clean_exit;
4203+
RETURN_FALSE;
42064204
}
42074205

42084206
iv_len = EVP_CIPHER_iv_length(cipher);
42094207
if (!iv && iv_len > 0) {
42104208
zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm");
4211-
goto clean_exit;
4212-
}
4213-
4214-
ctx = EVP_CIPHER_CTX_new();
4215-
if (ctx == NULL || !EVP_EncryptInit(ctx,cipher,NULL,NULL)) {
4216-
php_openssl_store_errors();
4217-
goto clean_exit;
4218-
}
4219-
4220-
tag_len = EVP_CIPHER_CTX_get_tag_length(ctx);
4221-
if ((tag != NULL) != (tag_len > 0)) {
4222-
const char *imp = tag ? "cannot" : "must";
4223-
zend_argument_value_error(7, "%s be specified for the chosen cipher algorithm", imp);
4224-
goto clean_exit;
4209+
RETURN_THROWS();
42254210
}
42264211

42274212
pkeys = safe_emalloc(nkeys, sizeof(*pkeys), 0);
@@ -4238,12 +4223,21 @@ PHP_FUNCTION(openssl_seal)
42384223
if (!EG(exception)) {
42394224
php_error_docref(NULL, E_WARNING, "Not a public key (%dth member of pubkeys)", i+1);
42404225
}
4226+
RETVAL_FALSE;
42414227
goto clean_exit;
42424228
}
42434229
eks[i] = emalloc(EVP_PKEY_size(pkeys[i]) + 1);
42444230
i++;
42454231
} ZEND_HASH_FOREACH_END();
42464232

4233+
ctx = EVP_CIPHER_CTX_new();
4234+
if (ctx == NULL || !EVP_EncryptInit(ctx,cipher,NULL,NULL)) {
4235+
EVP_CIPHER_CTX_free(ctx);
4236+
php_openssl_store_errors();
4237+
RETVAL_FALSE;
4238+
goto clean_exit;
4239+
}
4240+
42474241
/* allocate one byte extra to make room for \0 */
42484242
buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(ctx));
42494243
EVP_CIPHER_CTX_reset(ctx);
@@ -4252,23 +4246,19 @@ PHP_FUNCTION(openssl_seal)
42524246
!EVP_SealUpdate(ctx, buf, &len1, (unsigned char *)data, (int)data_len) ||
42534247
!EVP_SealFinal(ctx, buf + len1, &len2)) {
42544248
efree(buf);
4249+
EVP_CIPHER_CTX_free(ctx);
42554250
php_openssl_store_errors();
4251+
RETVAL_FALSE;
42564252
goto clean_exit;
42574253
}
42584254

4259-
if (tag) {
4260-
zend_string *tag_str = zend_string_alloc(tag_len, 0);
4261-
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, ZSTR_LEN(tag_str), ZSTR_VAL(tag_str));
4262-
ZSTR_VAL(tag_str)[ZSTR_LEN(tag_str)] = 0;
4263-
ZEND_TRY_ASSIGN_REF_NEW_STR(tag, tag_str);
4264-
}
4265-
42664255
if (len1 + len2 > 0) {
42674256
ZEND_TRY_ASSIGN_REF_NEW_STR(sealdata, zend_string_init((char*)buf, len1 + len2, 0));
42684257
efree(buf);
42694258

42704259
ekeys = zend_try_array_init(ekeys);
42714260
if (!ekeys) {
4261+
EVP_CIPHER_CTX_free(ctx);
42724262
goto clean_exit;
42734263
}
42744264

@@ -4286,61 +4276,44 @@ PHP_FUNCTION(openssl_seal)
42864276
} else {
42874277
efree(buf);
42884278
}
4289-
42904279
RETVAL_LONG(len1 + len2);
4280+
EVP_CIPHER_CTX_free(ctx);
42914281

42924282
clean_exit:
4293-
if (ctx) {
4294-
EVP_CIPHER_CTX_free(ctx);
4295-
}
4296-
4297-
if (pkeys) {
4298-
for (i=0; i<nkeys; i++) {
4299-
if (pkeys[i] != NULL) {
4300-
EVP_PKEY_free(pkeys[i]);
4301-
}
4283+
for (i=0; i<nkeys; i++) {
4284+
if (pkeys[i] != NULL) {
4285+
EVP_PKEY_free(pkeys[i]);
43024286
}
4303-
efree(pkeys);
4304-
}
4305-
4306-
if (eks) {
4307-
for (i=0; i<nkeys; i++) {
4308-
if (eks[i]) {
4309-
efree(eks[i]);
4310-
}
4287+
if (eks[i]) {
4288+
efree(eks[i]);
43114289
}
4312-
efree(eks);
4313-
}
4314-
4315-
if (eksl) {
4316-
efree(eksl);
43174290
}
4291+
efree(eks);
4292+
efree(eksl);
4293+
efree(pkeys);
43184294
}
43194295
/* }}} */
43204296

43214297
/* {{{ Opens data */
43224298
PHP_FUNCTION(openssl_open)
43234299
{
43244300
zval *privkey, *opendata;
4325-
EVP_PKEY *pkey = NULL;
4301+
EVP_PKEY *pkey;
43264302
int len1, len2, cipher_iv_len;
4327-
unsigned char *buf = NULL, *iv_buf;
4328-
EVP_CIPHER_CTX *ctx = NULL;
4303+
unsigned char *buf, *iv_buf;
4304+
EVP_CIPHER_CTX *ctx;
43294305
char * data;
43304306
size_t data_len;
43314307
char * ekey;
43324308
size_t ekey_len;
43334309
char *method, *iv = NULL;
43344310
size_t method_len, iv_len = 0;
4335-
zend_string *tag = NULL;
43364311
const EVP_CIPHER *cipher;
4337-
int tag_len;
43384312

4339-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "szszs|s!S!", &data, &data_len, &opendata,
4340-
&ekey, &ekey_len, &privkey, &method, &method_len, &iv, &iv_len, &tag) == FAILURE) {
4313+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "szszs|s!", &data, &data_len, &opendata,
4314+
&ekey, &ekey_len, &privkey, &method, &method_len, &iv, &iv_len) == FAILURE) {
43414315
RETURN_THROWS();
43424316
}
4343-
RETVAL_FALSE;
43444317

43454318
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data, 1);
43464319
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(ekey_len, ekey, 3);
@@ -4350,24 +4323,24 @@ PHP_FUNCTION(openssl_open)
43504323
if (!EG(exception)) {
43514324
php_error_docref(NULL, E_WARNING, "Unable to coerce parameter 4 into a private key");
43524325
}
4353-
goto clean_exit;
4326+
RETURN_FALSE;
43544327
}
43554328

43564329
cipher = php_openssl_get_evp_cipher_by_name(method);
43574330
if (!cipher) {
43584331
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
4359-
goto clean_exit;
4332+
RETURN_FALSE;
43604333
}
43614334

43624335
cipher_iv_len = EVP_CIPHER_iv_length(cipher);
43634336
if (cipher_iv_len > 0) {
43644337
if (!iv) {
43654338
zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm");
4366-
goto clean_exit;
4339+
RETURN_THROWS();
43674340
}
43684341
if ((size_t)cipher_iv_len != iv_len) {
43694342
php_error_docref(NULL, E_WARNING, "IV length is invalid");
4370-
goto clean_exit;
4343+
RETURN_FALSE;
43714344
}
43724345
iv_buf = (unsigned char *)iv;
43734346
} else {
@@ -4377,48 +4350,20 @@ PHP_FUNCTION(openssl_open)
43774350
buf = emalloc(data_len + 1);
43784351

43794352
ctx = EVP_CIPHER_CTX_new();
4380-
if (ctx == NULL || !EVP_OpenInit(ctx, cipher, (unsigned char *)ekey, (int)ekey_len, iv_buf, pkey)) {
4381-
php_openssl_store_errors();
4382-
goto clean_exit;
4383-
}
4384-
4385-
tag_len = EVP_CIPHER_CTX_get_tag_length(ctx);
4386-
if ((tag != NULL) != (tag_len > 0)) {
4387-
const char *imp = tag ? "cannot" : "must";
4388-
zend_argument_value_error(7, "%s be specified for the chosen cipher algorithm", imp);
4389-
goto clean_exit;
4390-
}
4391-
if (tag) {
4392-
if (ZSTR_LEN(tag) != tag_len) {
4393-
zend_argument_value_error(7, "must be %d bytes long", tag_len);
4394-
goto clean_exit;
4395-
}
4396-
4397-
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, ZSTR_LEN(tag), ZSTR_VAL(tag))) {
4398-
php_openssl_store_errors();
4399-
goto clean_exit;
4400-
}
4401-
}
4402-
4403-
if (EVP_OpenUpdate(ctx, buf, &len1, (unsigned char *)data, (int)data_len) &&
4404-
EVP_OpenFinal(ctx, buf + len1, &len2) && (len1 + len2 > 0)) {
4353+
if (ctx != NULL && EVP_OpenInit(ctx, cipher, (unsigned char *)ekey, (int)ekey_len, iv_buf, pkey) &&
4354+
EVP_OpenUpdate(ctx, buf, &len1, (unsigned char *)data, (int)data_len) &&
4355+
EVP_OpenFinal(ctx, buf + len1, &len2) && (len1 + len2 > 0)) {
44054356
buf[len1 + len2] = '\0';
44064357
ZEND_TRY_ASSIGN_REF_NEW_STR(opendata, zend_string_init((char*)buf, len1 + len2, 0));
44074358
RETVAL_TRUE;
44084359
} else {
44094360
php_openssl_store_errors();
4361+
RETVAL_FALSE;
44104362
}
44114363

4412-
clean_exit:
4413-
if (buf) {
4414-
efree(buf);
4415-
}
4416-
if (pkey) {
4417-
EVP_PKEY_free(pkey);
4418-
}
4419-
if (ctx) {
4420-
EVP_CIPHER_CTX_free(ctx);
4421-
}
4364+
efree(buf);
4365+
EVP_PKEY_free(pkey);
4366+
EVP_CIPHER_CTX_free(ctx);
44224367
}
44234368
/* }}} */
44244369

ext/openssl/openssl.stub.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,15 +628,14 @@ function openssl_verify(string $data, string $signature, $public_key, string|int
628628
* @param string $sealed_data
629629
* @param array $encrypted_keys
630630
* @param string $iv
631-
* @param string $tag
632631
*/
633-
function openssl_seal(#[\SensitiveParameter] string $data, &$sealed_data, &$encrypted_keys, array $public_key, string $cipher_algo, &$iv = null, &$tag = null): int|false {}
632+
function openssl_seal(#[\SensitiveParameter] string $data, &$sealed_data, &$encrypted_keys, array $public_key, string $cipher_algo, &$iv = null): int|false {}
634633

635634
/**
636635
* @param string $output
637636
* @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key
638637
*/
639-
function openssl_open(string $data, #[\SensitiveParameter] &$output, string $encrypted_key, #[\SensitiveParameter] $private_key, string $cipher_algo, ?string $iv = null, ?string $tag = null): bool {}
638+
function openssl_open(string $data, #[\SensitiveParameter] &$output, string $encrypted_key, #[\SensitiveParameter] $private_key, string $cipher_algo, ?string $iv = null): bool {}
640639

641640
/**
642641
* @return array<int, string>

ext/openssl/openssl_arginfo.h

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/openssl/tests/gh7737.phpt

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)