From 73bae6b065ab659fec84ad70c27c1b3162646f8c Mon Sep 17 00:00:00 2001 From: Rob Thomas Date: Fri, 5 Feb 2016 07:47:48 +1000 Subject: [PATCH 1/2] Add 'serialNumberHex' variable to openssl_x509_parse Currently, openssl_x509_parse returns an integer. This can be unexpected, as the common way of handling serial numbers is with a hex string. This is compounded as php's dechex() function cannot handle >32 bit numbers which will leave people trying to handle large serial numbers frustrated. By adding this extra return variable to openssl_x509_parse, the consumer of the variable is certain that the serialNumberHex that is returned is the exact Hex Serial number as OpenSSL returns everywhere else. --- ext/openssl/openssl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 3eea7afae0fb4..1efe050ab98da 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1984,6 +1984,7 @@ PHP_FUNCTION(openssl_x509_parse) char *extname; BIO *bio_out; BUF_MEM *bio_buf; + char * hexserial; char buf[256]; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &zcert, &useshortnames) == FAILURE) { @@ -2013,6 +2014,18 @@ PHP_FUNCTION(openssl_x509_parse) add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert))); + /* Return the hex representation of the serial number, as defined by OpenSSL */ + hexserial = BN_bn2hex(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), NULL)); + + /* If we received null back from BN_bn2hex, there was a critical error in openssl, + * and we should not continue. + */ + if (!hexserial) { + RETURN_FALSE; + } + add_assoc_string(return_value, "serialNumberHex", hexserial, 1); + OPENSSL_free(hexserial); + add_assoc_asn1_string(return_value, "validFrom", X509_get_notBefore(cert)); add_assoc_asn1_string(return_value, "validTo", X509_get_notAfter(cert)); From 2854f3292d46a4be67b181055c32aaf093fa09fe Mon Sep 17 00:00:00 2001 From: Rob Thomas Date: Fri, 5 Feb 2016 10:19:02 +1000 Subject: [PATCH 2/2] Fix patch to work against PHP7 This also updates the testcases so they now return correct data with the extra return value. --- ext/openssl/openssl.c | 2 +- ext/openssl/tests/openssl_x509_parse_basic.phpt | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 1efe050ab98da..0462548508053 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -2023,7 +2023,7 @@ PHP_FUNCTION(openssl_x509_parse) if (!hexserial) { RETURN_FALSE; } - add_assoc_string(return_value, "serialNumberHex", hexserial, 1); + add_assoc_string(return_value, "serialNumberHex", hexserial); OPENSSL_free(hexserial); add_assoc_asn1_string(return_value, "validFrom", X509_get_notBefore(cert)); diff --git a/ext/openssl/tests/openssl_x509_parse_basic.phpt b/ext/openssl/tests/openssl_x509_parse_basic.phpt index 00e32c3b60064..59daedcc6b2bc 100644 --- a/ext/openssl/tests/openssl_x509_parse_basic.phpt +++ b/ext/openssl/tests/openssl_x509_parse_basic.phpt @@ -12,7 +12,7 @@ var_dump(openssl_x509_parse($cert)); var_dump(openssl_x509_parse($cert, false)); ?> --EXPECTF-- -array(15) { +array(16) { ["name"]=> string(96) "/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net" ["subject"]=> @@ -47,6 +47,8 @@ array(15) { int(2) ["serialNumber"]=> string(20) "12593567369101004962" + ["serialNumberHex"]=> + string(16) "AEC556CC723750A2" ["validFrom"]=> string(13) "080630102843Z" ["validTo"]=> @@ -158,7 +160,7 @@ serial:AE:C5:56:CC:72:37:50:A2 string(7) "CA:TRUE" } } -array(15) { +array(16) { ["name"]=> string(96) "/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net" ["subject"]=> @@ -193,6 +195,8 @@ array(15) { int(2) ["serialNumber"]=> string(20) "12593567369101004962" + ["serialNumberHex"]=> + string(16) "AEC556CC723750A2" ["validFrom"]=> string(13) "080630102843Z" ["validTo"]=>