From 2a93e80afc3efee046d2e5584fa22cee57d83e5f Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 30 Jun 2021 14:35:57 +0200 Subject: [PATCH 1/3] Fix #52093: openssl_csr_sign silently truncates $serial We must not silently truncate integer arguments passed to a function. In this case we could use `ASN1_INTEGER_set_int64()` on LLP64 architectures, but that might be regarded a BC break; instead we choose to raise a warning regarding the truncation for now. --- ext/openssl/openssl.c | 4 +++- ext/openssl/tests/bug52093.phpt | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 ext/openssl/tests/bug52093.phpt diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index b3ca042306eee..7608bd7a629ec 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -3524,7 +3524,9 @@ PHP_FUNCTION(openssl_csr_sign) goto cleanup; } - + if (serial < LONG_MIN || serial > LONG_MAX) { + php_error_docref(NULL, E_WARNING, "serial out of range, will be truncated"); + } ASN1_INTEGER_set(X509_get_serialNumber(new_cert), (long)serial); X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr)); diff --git a/ext/openssl/tests/bug52093.phpt b/ext/openssl/tests/bug52093.phpt new file mode 100644 index 0000000000000..ffe227d91d257 --- /dev/null +++ b/ext/openssl/tests/bug52093.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #52093 (openssl_csr_sign silently truncates $serial) +--SKIPIF-- + +--FILE-- + "BR", + "stateOrProvinceName" => "Rio Grande do Sul", + "localityName" => "Porto Alegre", + "commonName" => "Henrique do N. Angelo", + "emailAddress" => "hnangelo@php.net" +); + +$privkey = openssl_pkey_new(); +$csr = openssl_csr_new($dn, $privkey); +var_dump(openssl_csr_sign($csr, null, $privkey, 365, [], PHP_INT_MAX)); +?> +--EXPECTF-- +Warning: openssl_csr_sign(): serial out of range, will be truncated in %s on line %d +resource(6) of type (OpenSSL X.509) From cf1ee620cd5f6c73ad8b2a71fefdc3e61bc9f7b7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 30 Jun 2021 15:36:15 +0200 Subject: [PATCH 2/3] Don't truncate at all We actually use `ASN1_INTEGER_set_int64()`[1] on 64bit Windows which is the only LLP64 platform we support, and where we can be reasonably sure that nobody uses OpenSSL 1.0 anymore (the official Windows dependencies ship OppenSSL 1.1 for years). We also adapt the test to actually verify the serial number. [1] --- ext/openssl/openssl.c | 9 +++++---- ext/openssl/tests/bug52093.phpt | 15 +++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 7608bd7a629ec..c8cf9b67b2228 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -3524,10 +3524,11 @@ PHP_FUNCTION(openssl_csr_sign) goto cleanup; } - if (serial < LONG_MIN || serial > LONG_MAX) { - php_error_docref(NULL, E_WARNING, "serial out of range, will be truncated"); - } - ASN1_INTEGER_set(X509_get_serialNumber(new_cert), (long)serial); +#if defined(PHP_WIN32) && defined(ZEND_ENABLE_ZVAL_LONG64) + ASN1_INTEGER_set_int64(X509_get_serialNumber(new_cert), serial); +#else + ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial); +#endif X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr)); diff --git a/ext/openssl/tests/bug52093.phpt b/ext/openssl/tests/bug52093.phpt index ffe227d91d257..63eaceb5acc92 100644 --- a/ext/openssl/tests/bug52093.phpt +++ b/ext/openssl/tests/bug52093.phpt @@ -1,7 +1,10 @@ --TEST-- -Bug #52093 (openssl_csr_sign silently truncates $serial) +Bug #52093 (openssl_csr_sign truncates $serial) --SKIPIF-- - + --FILE-- ---EXPECTF-- -Warning: openssl_csr_sign(): serial out of range, will be truncated in %s on line %d -resource(6) of type (OpenSSL X.509) +--EXPECT-- +string(19) "9223372036854775807" From ce2fc7b2d95dbba4187065758ffb49252e63f381 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 1 Jul 2021 11:47:46 +0200 Subject: [PATCH 3/3] Call ASN1_INTEGER_set_int64() if available --- ext/openssl/openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index c8cf9b67b2228..4af09b0e0f1cc 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -3524,7 +3524,7 @@ PHP_FUNCTION(openssl_csr_sign) goto cleanup; } -#if defined(PHP_WIN32) && defined(ZEND_ENABLE_ZVAL_LONG64) +#if PHP_OPENSSL_API_VERSION >= 0x10100 ASN1_INTEGER_set_int64(X509_get_serialNumber(new_cert), serial); #else ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);