Skip to content

Commit c51af22

Browse files
committed
implement openssl_256 and openssl_512 for phar singatures
1 parent 8bb0c74 commit c51af22

14 files changed

+128
-18
lines changed

ext/openssl/openssl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
#define MIN_KEY_LENGTH 384
7171

72+
/* constants used in ext/phar/util.c, keep in sync */
7273
#define OPENSSL_ALGO_SHA1 1
7374
#define OPENSSL_ALGO_MD5 2
7475
#define OPENSSL_ALGO_MD4 3

ext/phar/phar.1.in

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,15 @@ SHA512
475475
.TP
476476
.PD
477477
.B openssl
478-
OpenSSL
478+
OpenSSL using SHA-1
479+
.TP
480+
.PD
481+
.B openssl_sha256
482+
OpenSSL using SHA-256
483+
.TP
484+
.PD
485+
.B openssl_sha512
486+
OpenSSL using SHA-512
479487

480488
.SH SEE ALSO
481489
For a more or less complete description of PHAR look here:

ext/phar/phar.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch
858858
PHAR_GET_32(sig_ptr, sig_flags);
859859

860860
switch(sig_flags) {
861+
case PHAR_SIG_OPENSSL_SHA512:
862+
case PHAR_SIG_OPENSSL_SHA256:
861863
case PHAR_SIG_OPENSSL: {
862864
uint32_t signature_len;
863865
char *sig;
@@ -892,7 +894,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch
892894
return FAILURE;
893895
}
894896

895-
if (FAILURE == phar_verify_signature(fp, end_of_phar, PHAR_SIG_OPENSSL, sig, signature_len, fname, &signature, &sig_len, error)) {
897+
if (FAILURE == phar_verify_signature(fp, end_of_phar, sig_flags, sig, signature_len, fname, &signature, &sig_len, error)) {
896898
efree(savebuf);
897899
efree(sig);
898900
php_stream_close(fp);
@@ -3146,7 +3148,9 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
31463148

31473149
php_stream_write(newfile, digest, digest_len);
31483150
efree(digest);
3149-
if (phar->sig_flags == PHAR_SIG_OPENSSL) {
3151+
if (phar->sig_flags == PHAR_SIG_OPENSSL ||
3152+
phar->sig_flags == PHAR_SIG_OPENSSL_SHA256 ||
3153+
phar->sig_flags == PHAR_SIG_OPENSSL_SHA512) {
31503154
phar_set_32(sig_buf, digest_len);
31513155
php_stream_write(newfile, sig_buf, 4);
31523156
}

ext/phar/phar/pharcommand.inc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class PharCommand extends CLICommand
9292
'typ' => 'select',
9393
'val' => NULL,
9494
'inf' => '<method> Selects the hash algorithm.',
95-
'select' => array('md5' => 'MD5','sha1' => 'SHA1', 'sha256' => 'SHA256', 'sha512' => 'SHA512', 'openssl' => 'OPENSSL')
95+
'select' => ['md5' => 'MD5','sha1' => 'SHA1', 'sha256' => 'SHA256', 'sha512' => 'SHA512', 'openssl' => 'OPENSSL', 'openssl_sha256' => 'OPENSSL_SHA256', 'openssl_sha512' => 'OPENSSL_SHA512']
9696
),
9797
'i' => array(
9898
'typ' => 'regex',
@@ -156,6 +156,8 @@ class PharCommand extends CLICommand
156156
$hash_avail = Phar::getSupportedSignatures();
157157
$hash_optional = array('SHA-256' => 'SHA256',
158158
'SHA-512' => 'SHA512',
159+
'OpenSSL_sha256' => 'OpenSSL_SHA256',
160+
'OpenSSL_sha512' => 'OpenSSL_SHA512',
159161
'OpenSSL' => 'OpenSSL');
160162
if (!in_array('OpenSSL', $hash_avail)) {
161163
unset($phar_args['y']);
@@ -429,6 +431,16 @@ class PharCommand extends CLICommand
429431
self::error("Cannot use OpenSSL signing without key.\n");
430432
}
431433
return Phar::OPENSSL;
434+
case 'openssl_sha256':
435+
if (!$privkey) {
436+
self::error("Cannot use OpenSSL signing without key.\n");
437+
}
438+
return Phar::OPENSSL_SHA256;
439+
case 'openssl_sha512':
440+
if (!$privkey) {
441+
self::error("Cannot use OpenSSL signing without key.\n");
442+
}
443+
return Phar::OPENSSL_SHA512;
432444
}
433445
}
434446
// }}}

ext/phar/phar_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@
8888
#define PHAR_SIG_SHA256 0x0003
8989
#define PHAR_SIG_SHA512 0x0004
9090
#define PHAR_SIG_OPENSSL 0x0010
91+
#define PHAR_SIG_OPENSSL_SHA256 0x0011
92+
#define PHAR_SIG_OPENSSL_SHA512 0x0012
9193

9294
/* flags byte for each file adheres to these bitmasks.
9395
All unused values are reserved */

ext/phar/phar_object.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,9 +1239,13 @@ PHP_METHOD(Phar, getSupportedSignatures)
12391239
add_next_index_stringl(return_value, "SHA-512", 7);
12401240
#ifdef PHAR_HAVE_OPENSSL
12411241
add_next_index_stringl(return_value, "OpenSSL", 7);
1242+
add_next_index_stringl(return_value, "OpenSSL_SHA256", 14);
1243+
add_next_index_stringl(return_value, "OpenSSL_SHA512", 14);
12421244
#else
12431245
if (zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) {
12441246
add_next_index_stringl(return_value, "OpenSSL", 7);
1247+
add_next_index_stringl(return_value, "OpenSSL_SHA256", 14);
1248+
add_next_index_stringl(return_value, "OpenSSL_SHA512", 14);
12451249
}
12461250
#endif
12471251
}
@@ -3003,6 +3007,8 @@ PHP_METHOD(Phar, setSignatureAlgorithm)
30033007
case PHAR_SIG_MD5:
30043008
case PHAR_SIG_SHA1:
30053009
case PHAR_SIG_OPENSSL:
3010+
case PHAR_SIG_OPENSSL_SHA256:
3011+
case PHAR_SIG_OPENSSL_SHA512:
30063012
if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) {
30073013
zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname);
30083014
RETURN_THROWS();
@@ -3041,19 +3047,25 @@ PHP_METHOD(Phar, getSignature)
30413047
add_assoc_stringl(return_value, "hash", phar_obj->archive->signature, phar_obj->archive->sig_len);
30423048
switch(phar_obj->archive->sig_flags) {
30433049
case PHAR_SIG_MD5:
3044-
add_assoc_stringl(return_value, "hash_type", "MD5", 3);
3050+
add_assoc_string(return_value, "hash_type", "MD5");
30453051
break;
30463052
case PHAR_SIG_SHA1:
3047-
add_assoc_stringl(return_value, "hash_type", "SHA-1", 5);
3053+
add_assoc_string(return_value, "hash_type", "SHA-1");
30483054
break;
30493055
case PHAR_SIG_SHA256:
3050-
add_assoc_stringl(return_value, "hash_type", "SHA-256", 7);
3056+
add_assoc_string(return_value, "hash_type", "SHA-256");
30513057
break;
30523058
case PHAR_SIG_SHA512:
3053-
add_assoc_stringl(return_value, "hash_type", "SHA-512", 7);
3059+
add_assoc_string(return_value, "hash_type", "SHA-512");
30543060
break;
30553061
case PHAR_SIG_OPENSSL:
3056-
add_assoc_stringl(return_value, "hash_type", "OpenSSL", 7);
3062+
add_assoc_string(return_value, "hash_type", "OpenSSL");
3063+
break;
3064+
case PHAR_SIG_OPENSSL_SHA256:
3065+
add_assoc_string(return_value, "hash_type", "OpenSSL_SHA256");
3066+
break;
3067+
case PHAR_SIG_OPENSSL_SHA512:
3068+
add_assoc_string(return_value, "hash_type", "OpenSSL_SHA512");
30573069
break;
30583070
default:
30593071
unknown = strpprintf(0, "Unknown (%u)", phar_obj->archive->sig_flags);
@@ -5064,6 +5076,8 @@ void phar_object_init(void) /* {{{ */
50645076
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "PHPS", PHAR_MIME_PHPS)
50655077
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "MD5", PHAR_SIG_MD5)
50665078
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "OPENSSL", PHAR_SIG_OPENSSL)
5079+
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "OPENSSL_SHA256", PHAR_SIG_OPENSSL_SHA256)
5080+
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "OPENSSL_SHA512", PHAR_SIG_OPENSSL_SHA512)
50675081
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA1", PHAR_SIG_SHA1)
50685082
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA256", PHAR_SIG_SHA256)
50695083
REGISTER_PHAR_CLASS_CONST_LONG(phar_ce_archive, "SHA512", PHAR_SIG_SHA512)

ext/phar/tests/files/openssl256.phar

6.96 KB
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA3ADUiKZIEhekYShzPCZ3LFbg
3+
rDuV44jH94OdJQfqaCQBvZXqMoG1bWOeYfbc3iO0gHWW3SKB27Sf1ZBnc5c1+YzB
4+
mx9bFipOX2W2ouKS2YoHeIoR9leDNu4yqwBsuggFPGVPxM9ikEI+YAOGVTCd4mV5
5+
agpkVsHLNJWbz/nPVwIDAQAB
6+
-----END PUBLIC KEY-----

ext/phar/tests/files/openssl512.phar

6.96 KB
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA3ADUiKZIEhekYShzPCZ3LFbg
3+
rDuV44jH94OdJQfqaCQBvZXqMoG1bWOeYfbc3iO0gHWW3SKB27Sf1ZBnc5c1+YzB
4+
mx9bFipOX2W2ouKS2YoHeIoR9leDNu4yqwBsuggFPGVPxM9ikEI+YAOGVTCd4mV5
5+
agpkVsHLNJWbz/nPVwIDAQAB
6+
-----END PUBLIC KEY-----

ext/phar/tests/phar_get_supported_signatures_002a.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ phar.readonly=0
1515
var_dump(Phar::getSupportedSignatures());
1616
?>
1717
--EXPECT--
18-
array(5) {
18+
array(7) {
1919
[0]=>
2020
string(3) "MD5"
2121
[1]=>
@@ -26,4 +26,8 @@ array(5) {
2626
string(7) "SHA-512"
2727
[4]=>
2828
string(7) "OpenSSL"
29+
[5]=>
30+
string(14) "OpenSSL_SHA256"
31+
[6]=>
32+
string(14) "OpenSSL_SHA512"
2933
}

ext/phar/tests/tar/phar_setsignaturealgo2.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ $pkey = '';
3939
openssl_pkey_export($private, $pkey, NULL, $config_arg);
4040
$p->setSignatureAlgorithm(Phar::OPENSSL, $pkey);
4141
var_dump($p->getSignature());
42+
$p->setSignatureAlgorithm(Phar::OPENSSL_SHA512, $pkey);
43+
var_dump($p->getSignature());
44+
$p->setSignatureAlgorithm(Phar::OPENSSL_SHA256, $pkey);
45+
var_dump($p->getSignature());
4246
} catch (Exception $e) {
4347
echo $e->getMessage();
4448
}
@@ -84,3 +88,15 @@ array(2) {
8488
["hash_type"]=>
8589
string(7) "OpenSSL"
8690
}
91+
array(2) {
92+
["hash"]=>
93+
string(%d) "%s"
94+
["hash_type"]=>
95+
string(14) "OpenSSL_SHA512"
96+
}
97+
array(2) {
98+
["hash"]=>
99+
string(%d) "%s"
100+
["hash_type"]=>
101+
string(14) "OpenSSL_SHA256"
102+
}

ext/phar/tests/test_signaturealgos.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,18 @@ var_dump($r['hash_type']);
2727
$a = new Phar(__DIR__ . '/files/openssl.phar');
2828
$r = $a->getSignature();
2929
var_dump($r['hash_type']);
30+
$a = new Phar(__DIR__ . '/files/openssl256.phar');
31+
$r = $a->getSignature();
32+
var_dump($r['hash_type']);
33+
$a = new Phar(__DIR__ . '/files/openssl512.phar');
34+
$r = $a->getSignature();
35+
var_dump($r['hash_type']);
3036
?>
3137
--EXPECT--
3238
string(5) "SHA-1"
3339
string(7) "SHA-512"
3440
string(7) "SHA-256"
3541
string(3) "MD5"
3642
string(7) "OpenSSL"
43+
string(14) "OpenSSL_SHA256"
44+
string(14) "OpenSSL_SHA512"

ext/phar/util.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include <openssl/ssl.h>
3535
#include <openssl/pkcs12.h>
3636
#else
37-
static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len);
37+
static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type);
3838
#endif
3939

4040
/* for links to relative location, prepend cwd of the entry */
@@ -1381,11 +1381,11 @@ static int phar_hex_str(const char *digest, size_t digest_len, char **signature)
13811381
/* }}} */
13821382

13831383
#ifndef PHAR_HAVE_OPENSSL
1384-
static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len) /* {{{ */
1384+
static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type) /* {{{ */
13851385
{
13861386
zend_fcall_info fci;
13871387
zend_fcall_info_cache fcc;
1388-
zval retval, zp[3], openssl;
1388+
zval retval, zp[4], openssl;
13891389
zend_string *str;
13901390

13911391
ZVAL_STRINGL(&openssl, is_sign ? "openssl_sign" : "openssl_verify", is_sign ? sizeof("openssl_sign")-1 : sizeof("openssl_verify")-1);
@@ -1402,6 +1402,14 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t
14021402
} else {
14031403
ZVAL_EMPTY_STRING(&zp[0]);
14041404
}
1405+
if (sig_type == PHAR_SIG_OPENSSL_SHA512) {
1406+
ZVAL_LONG(&zp[3], 9); /* value from openssl.c #define OPENSSL_ALGO_SHA512 9 */
1407+
} else if (sig_type == PHAR_SIG_OPENSSL_SHA256) {
1408+
ZVAL_LONG(&zp[3], 7); /* value from openssl.c #define OPENSSL_ALGO_SHA256 7 */
1409+
} else {
1410+
/* don't rely on default value which may change in the future */
1411+
ZVAL_LONG(&zp[3], 1); /* value from openssl.c #define OPENSSL_ALGO_SHA1 1 */
1412+
}
14051413

14061414
if ((size_t)end != Z_STRLEN(zp[0])) {
14071415
zval_ptr_dtor_str(&zp[0]);
@@ -1419,7 +1427,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t
14191427
return FAILURE;
14201428
}
14211429

1422-
fci.param_count = 3;
1430+
fci.param_count = 4;
14231431
fci.params = zp;
14241432
Z_ADDREF(zp[0]);
14251433
if (is_sign) {
@@ -1482,12 +1490,22 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type,
14821490
php_stream_rewind(fp);
14831491

14841492
switch (sig_type) {
1493+
case PHAR_SIG_OPENSSL_SHA512:
1494+
case PHAR_SIG_OPENSSL_SHA256:
14851495
case PHAR_SIG_OPENSSL: {
14861496
#ifdef PHAR_HAVE_OPENSSL
14871497
BIO *in;
14881498
EVP_PKEY *key;
1489-
EVP_MD *mdtype = (EVP_MD *) EVP_sha1();
1499+
const EVP_MD *mdtype;
14901500
EVP_MD_CTX *md_ctx;
1501+
1502+
if (sig_type == PHAR_SIG_OPENSSL_SHA512) {
1503+
mdtype = EVP_sha512();
1504+
} else if (sig_type == PHAR_SIG_OPENSSL_SHA256) {
1505+
mdtype = EVP_sha256();
1506+
} else {
1507+
mdtype = EVP_sha1();
1508+
}
14911509
#else
14921510
size_t tempsig;
14931511
#endif
@@ -1521,7 +1539,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type,
15211539
#ifndef PHAR_HAVE_OPENSSL
15221540
tempsig = sig_len;
15231541

1524-
if (FAILURE == phar_call_openssl_signverify(0, fp, end_of_phar, pubkey ? ZSTR_VAL(pubkey) : NULL, pubkey ? ZSTR_LEN(pubkey) : 0, &sig, &tempsig)) {
1542+
if (FAILURE == phar_call_openssl_signverify(0, fp, end_of_phar, pubkey ? ZSTR_VAL(pubkey) : NULL, pubkey ? ZSTR_LEN(pubkey) : 0, &sig, &tempsig, sig_type)) {
15251543
if (pubkey) {
15261544
zend_string_release_ex(pubkey, 0);
15271545
}
@@ -1816,13 +1834,24 @@ int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signat
18161834
*signature_length = 32;
18171835
break;
18181836
}
1837+
case PHAR_SIG_OPENSSL_SHA512:
1838+
case PHAR_SIG_OPENSSL_SHA256:
18191839
case PHAR_SIG_OPENSSL: {
18201840
unsigned char *sigbuf;
18211841
#ifdef PHAR_HAVE_OPENSSL
18221842
unsigned int siglen;
18231843
BIO *in;
18241844
EVP_PKEY *key;
18251845
EVP_MD_CTX *md_ctx;
1846+
const EVP_MD *mdtype;
1847+
1848+
if (phar->sig_flags == PHAR_SIG_OPENSSL_SHA512) {
1849+
mdtype = EVP_sha512();
1850+
} else if (phar->sig_flags == PHAR_SIG_OPENSSL_SHA256) {
1851+
mdtype = EVP_sha256();
1852+
} else {
1853+
mdtype = EVP_sha1();
1854+
}
18261855

18271856
in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len));
18281857

@@ -1848,7 +1877,7 @@ int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signat
18481877
siglen = EVP_PKEY_size(key);
18491878
sigbuf = emalloc(siglen + 1);
18501879

1851-
if (!EVP_SignInit(md_ctx, EVP_sha1())) {
1880+
if (!EVP_SignInit(md_ctx, mdtype)) {
18521881
EVP_PKEY_free(key);
18531882
efree(sigbuf);
18541883
if (error) {
@@ -1886,7 +1915,7 @@ int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signat
18861915
siglen = 0;
18871916
php_stream_seek(fp, 0, SEEK_END);
18881917

1889-
if (FAILURE == phar_call_openssl_signverify(1, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen)) {
1918+
if (FAILURE == phar_call_openssl_signverify(1, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) {
18901919
if (error) {
18911920
spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname);
18921921
}

0 commit comments

Comments
 (0)