From be7be82d9d73c6a1c79bbb43b2a95d0bf6e80610 Mon Sep 17 00:00:00 2001 From: Moritz Fain Date: Thu, 30 Mar 2017 16:20:52 +0200 Subject: [PATCH 1/7] Fix #74341: openssl_x509_parse fails to parse ASN.1 UTCTime without seconds Added support for ASN.1 UTCTime without seconds part (being 11 characters long instead of 13) --- ext/openssl/openssl.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index da60bb9486074..2548ef48b4a35 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -739,23 +739,26 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr) /* {{{ */ char * strbuf; char * thestr; long gmadjust = 0; + size_t timestr_len; if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME && ASN1_STRING_type(timestr) != V_ASN1_GENERALIZEDTIME) { php_error_docref(NULL, E_WARNING, "illegal ASN1 data type for timestamp"); return (time_t)-1; } - if (ASN1_STRING_length(timestr) != strlen((const char*)ASN1_STRING_data(timestr))) { + timestr_len = (size_t)ASN1_STRING_length(timestr); + + if (timestr_len != strlen((const char*)ASN1_STRING_data(timestr))) { php_error_docref(NULL, E_WARNING, "illegal length in timestamp"); return (time_t)-1; } - if (ASN1_STRING_length(timestr) < 13) { + if (timestr_len < 13 && timestr_len != 11) { php_error_docref(NULL, E_WARNING, "unable to parse time string %s correctly", timestr->data); return (time_t)-1; } - if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && ASN1_STRING_length(timestr) < 15) { + if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && timestr_len < 15) { php_error_docref(NULL, E_WARNING, "unable to parse time string %s correctly", timestr->data); return (time_t)-1; } @@ -766,11 +769,15 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr) /* {{{ */ /* we work backwards so that we can use atoi more easily */ - thestr = strbuf + ASN1_STRING_length(timestr) - 3; + thestr = strbuf + timestr_len - 3; - thetime.tm_sec = atoi(thestr); - *thestr = '\0'; - thestr -= 2; + if (timestr_len == 11) { + thetime.tm_sec = 0; + } else { + thetime.tm_sec = atoi(thestr); + *thestr = '\0'; + thestr -= 2; + } thetime.tm_min = atoi(thestr); *thestr = '\0'; thestr -= 2; From 65b265db9ecac728c9a9a47c3c3f8b35c2c36c41 Mon Sep 17 00:00:00 2001 From: Moritz Fain Date: Thu, 30 Mar 2017 21:10:41 +0200 Subject: [PATCH 2/7] Added test for bugfix #74341 --- ext/openssl/tests/bug74341.phpt | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 ext/openssl/tests/bug74341.phpt diff --git a/ext/openssl/tests/bug74341.phpt b/ext/openssl/tests/bug74341.phpt new file mode 100644 index 0000000000000..6682b72bd1a76 --- /dev/null +++ b/ext/openssl/tests/bug74341.phpt @@ -0,0 +1,52 @@ +--TEST-- +Bug #74341 (openssl_x509_parse fails to parse ASN.1 UTCTime without seconds) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(1389052800) +int(1459494000) From 3d18ca4d3f4bc35e70ccdd329fcffbb98e2c9f94 Mon Sep 17 00:00:00 2001 From: Moritz Fain Date: Fri, 31 Mar 2017 09:36:40 +0200 Subject: [PATCH 3/7] Adjusted test to use a predefined default timezone --- ext/openssl/tests/bug74341.phpt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/openssl/tests/bug74341.phpt b/ext/openssl/tests/bug74341.phpt index 6682b72bd1a76..de15dbd256c8a 100644 --- a/ext/openssl/tests/bug74341.phpt +++ b/ext/openssl/tests/bug74341.phpt @@ -43,6 +43,8 @@ lOzTF7xAUxmPUnNb2teatMf2Rmj0fs+d -----END CERTIFICATE----- '; +date_default_timezone_set('Europe/Berlin'); + $parsed_cert = openssl_x509_parse($pem_cert); var_dump($parsed_cert['validFrom_time_t']); var_dump($parsed_cert['validTo_time_t']); From 3f83a198e859c0e8dff19d691a245264443f78a7 Mon Sep 17 00:00:00 2001 From: Moritz Fain Date: Fri, 31 Mar 2017 12:01:02 +0200 Subject: [PATCH 4/7] Adjusted the test to pass AppVeyor build --- ext/openssl/tests/bug74341.phpt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/openssl/tests/bug74341.phpt b/ext/openssl/tests/bug74341.phpt index de15dbd256c8a..c6aeb57eccc08 100644 --- a/ext/openssl/tests/bug74341.phpt +++ b/ext/openssl/tests/bug74341.phpt @@ -43,12 +43,12 @@ lOzTF7xAUxmPUnNb2teatMf2Rmj0fs+d -----END CERTIFICATE----- '; -date_default_timezone_set('Europe/Berlin'); +date_default_timezone_set('UTC'); $parsed_cert = openssl_x509_parse($pem_cert); var_dump($parsed_cert['validFrom_time_t']); var_dump($parsed_cert['validTo_time_t']); ?> --EXPECT-- -int(1389052800) -int(1459494000) +int(13890%d) +int(14594%d) From b586853a9c5c5d94ec3fd464c66264dd16b4815f Mon Sep 17 00:00:00 2001 From: Moritz Fain Date: Fri, 31 Mar 2017 12:15:56 +0200 Subject: [PATCH 5/7] Adjusted the test to pass AppVeyor build --- ext/openssl/tests/bug74341.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/openssl/tests/bug74341.phpt b/ext/openssl/tests/bug74341.phpt index c6aeb57eccc08..451c3732d707b 100644 --- a/ext/openssl/tests/bug74341.phpt +++ b/ext/openssl/tests/bug74341.phpt @@ -49,6 +49,6 @@ $parsed_cert = openssl_x509_parse($pem_cert); var_dump($parsed_cert['validFrom_time_t']); var_dump($parsed_cert['validTo_time_t']); ?> ---EXPECT-- +--EXPECTF-- int(13890%d) int(14594%d) From 403684bdc407789dc3eb3b842e97d38d9c600417 Mon Sep 17 00:00:00 2001 From: Moritz Fain Date: Fri, 31 Mar 2017 19:58:15 +0200 Subject: [PATCH 6/7] Cleaned up test --- ext/openssl/tests/bug74341.phpt | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/openssl/tests/bug74341.phpt b/ext/openssl/tests/bug74341.phpt index 451c3732d707b..24a7ce2ba994b 100644 --- a/ext/openssl/tests/bug74341.phpt +++ b/ext/openssl/tests/bug74341.phpt @@ -43,8 +43,6 @@ lOzTF7xAUxmPUnNb2teatMf2Rmj0fs+d -----END CERTIFICATE----- '; -date_default_timezone_set('UTC'); - $parsed_cert = openssl_x509_parse($pem_cert); var_dump($parsed_cert['validFrom_time_t']); var_dump($parsed_cert['validTo_time_t']); From 9a92e3ba36772236b317789daaba4107e7664d39 Mon Sep 17 00:00:00 2001 From: Moritz Fain Date: Sat, 1 Apr 2017 22:35:12 +0200 Subject: [PATCH 7/7] Fixed DST problem on systems without gmtoff --- ext/openssl/openssl.c | 2 +- ext/openssl/tests/bug74341.phpt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 2548ef48b4a35..51f2667e8214b 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -814,7 +814,7 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr) /* {{{ */ ** the value of timezone - 3600 seconds. Otherwise, we need to overcorrect and ** set the adjustment to the main timezone + 3600 seconds. */ - gmadjust = -(thetime.tm_isdst ? (long)timezone - 3600 : (long)timezone + 3600); + gmadjust = -(thetime.tm_isdst ? (long)timezone - 3600 : (long)timezone); #endif ret += gmadjust; diff --git a/ext/openssl/tests/bug74341.phpt b/ext/openssl/tests/bug74341.phpt index 24a7ce2ba994b..a3c78cfab0bea 100644 --- a/ext/openssl/tests/bug74341.phpt +++ b/ext/openssl/tests/bug74341.phpt @@ -48,5 +48,5 @@ var_dump($parsed_cert['validFrom_time_t']); var_dump($parsed_cert['validTo_time_t']); ?> --EXPECTF-- -int(13890%d) -int(14594%d) +int(1389052800) +int(1459494000)