mirror of
https://github.com/danog/phpseclib.git
synced 2024-12-12 09:09:39 +01:00
Merge branch 'datetime-1.0' into datetime-2.0
This commit is contained in:
commit
221a9be8e6
@ -25,6 +25,8 @@ namespace phpseclib\File;
|
|||||||
|
|
||||||
use phpseclib\File\ASN1\Element;
|
use phpseclib\File\ASN1\Element;
|
||||||
use phpseclib\Math\BigInteger;
|
use phpseclib\Math\BigInteger;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP ASN.1 Parser
|
* Pure-PHP ASN.1 Parser
|
||||||
@ -707,7 +709,7 @@ class ASN1
|
|||||||
if (isset($mapping['implicit'])) {
|
if (isset($mapping['implicit'])) {
|
||||||
$decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
|
$decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
|
||||||
}
|
}
|
||||||
return @date($this->format, $decoded['content']);
|
return $decoded['content'] ? $decoded['content']->format($this->format) : false;
|
||||||
case self::TYPE_BIT_STRING:
|
case self::TYPE_BIT_STRING:
|
||||||
if (isset($mapping['mapping'])) {
|
if (isset($mapping['mapping'])) {
|
||||||
$offset = ord($decoded['content'][0]);
|
$offset = ord($decoded['content'][0]);
|
||||||
@ -956,7 +958,8 @@ class ASN1
|
|||||||
case self::TYPE_GENERALIZED_TIME:
|
case self::TYPE_GENERALIZED_TIME:
|
||||||
$format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
|
$format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
|
||||||
$format.= 'mdHis';
|
$format.= 'mdHis';
|
||||||
$value = @gmdate($format, strtotime($source)) . 'Z';
|
$date = new DateTime($source, new DateTimeZone('GMT'));
|
||||||
|
$value = $date->format($format) . 'Z';
|
||||||
break;
|
break;
|
||||||
case self::TYPE_BIT_STRING:
|
case self::TYPE_BIT_STRING:
|
||||||
if (isset($mapping['mapping'])) {
|
if (isset($mapping['mapping'])) {
|
||||||
@ -1137,33 +1140,32 @@ class ASN1
|
|||||||
http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
|
http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
|
||||||
http://www.obj-sys.com/asn1tutorial/node14.html */
|
http://www.obj-sys.com/asn1tutorial/node14.html */
|
||||||
|
|
||||||
$pattern = $tag == self::TYPE_UTC_TIME ?
|
$format = 'YmdHis';
|
||||||
'#^(..)(..)(..)(..)(..)(..)?(.*)$#' :
|
|
||||||
'#(....)(..)(..)(..)(..)(..).*([Z+-].*)$#';
|
|
||||||
|
|
||||||
preg_match($pattern, $content, $matches);
|
|
||||||
|
|
||||||
list(, $year, $month, $day, $hour, $minute, $second, $timezone) = $matches;
|
|
||||||
|
|
||||||
if ($tag == self::TYPE_UTC_TIME) {
|
if ($tag == self::TYPE_UTC_TIME) {
|
||||||
$year = $year >= 50 ? "19$year" : "20$year";
|
// https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds
|
||||||
}
|
// element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the
|
||||||
|
// browsers parse it phpseclib ought to too
|
||||||
if ($timezone == 'Z') {
|
if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) {
|
||||||
$mktime = 'gmmktime';
|
$content = $matches[1] . '00' . $matches[2];
|
||||||
$timezone = 0;
|
|
||||||
} elseif (preg_match('#([+-])(\d\d)(\d\d)#', $timezone, $matches)) {
|
|
||||||
$mktime = 'gmmktime';
|
|
||||||
$timezone = 60 * $matches[3] + 3600 * $matches[2];
|
|
||||||
if ($matches[1] == '-') {
|
|
||||||
$timezone = -$timezone;
|
|
||||||
}
|
}
|
||||||
} else {
|
$prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
|
||||||
$mktime = 'mktime';
|
$content = $prefix . $content;
|
||||||
$timezone = 0;
|
} elseif (strpos($content, '.') !== false) {
|
||||||
|
$format.= '.u';
|
||||||
}
|
}
|
||||||
|
|
||||||
return @$mktime((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$year) + $timezone;
|
if ($content[strlen($content) - 1] == 'Z') {
|
||||||
|
$content = substr($content, 0, -1) . '+0000';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($content, '-') !== false || strpos($content, '+') !== false) {
|
||||||
|
$format.= 'O';
|
||||||
|
}
|
||||||
|
|
||||||
|
// error supression isn't necessary as of PHP 7.0:
|
||||||
|
// http://php.net/manual/en/migration70.other-changes.php
|
||||||
|
return @DateTime::createFromFormat($format, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,6 +31,8 @@ use phpseclib\Crypt\Random;
|
|||||||
use phpseclib\Crypt\RSA;
|
use phpseclib\Crypt\RSA;
|
||||||
use phpseclib\File\ASN1\Element;
|
use phpseclib\File\ASN1\Element;
|
||||||
use phpseclib\Math\BigInteger;
|
use phpseclib\Math\BigInteger;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP X.509 Parser
|
* Pure-PHP X.509 Parser
|
||||||
@ -2082,7 +2084,7 @@ class X509
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($date)) {
|
if (!isset($date)) {
|
||||||
$date = time();
|
$date = new DateTime($date, new DateTimeZone(date_default_timezone_get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
|
$notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
|
||||||
@ -2092,8 +2094,8 @@ class X509
|
|||||||
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
||||||
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case $date < @strtotime($notBefore):
|
case $date < new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get())):
|
||||||
case $date > @strtotime($notAfter):
|
case $date > new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get())):
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3338,7 +3340,11 @@ class X509
|
|||||||
*/
|
*/
|
||||||
function _timeField($date)
|
function _timeField($date)
|
||||||
{
|
{
|
||||||
$year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
|
if ($date instanceof Element) {
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
|
$dateObj = new DateTime($date, new DateTimeZone('GMT'));
|
||||||
|
$year = $dateObj->format('Y'); // the same way ASN1.php parses this
|
||||||
if ($year < 2050) {
|
if ($year < 2050) {
|
||||||
return array('utcTime' => $date);
|
return array('utcTime' => $date);
|
||||||
} else {
|
} else {
|
||||||
@ -3403,8 +3409,12 @@ class X509
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
|
$startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||||
$endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
|
$startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O');
|
||||||
|
|
||||||
|
$endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
$endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O');
|
||||||
|
|
||||||
/* "The serial number MUST be a positive integer"
|
/* "The serial number MUST be a positive integer"
|
||||||
"Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
|
"Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
|
||||||
-- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
|
-- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
|
||||||
@ -3672,7 +3682,9 @@ class X509
|
|||||||
|
|
||||||
$currentCert = isset($this->currentCert) ? $this->currentCert : null;
|
$currentCert = isset($this->currentCert) ? $this->currentCert : null;
|
||||||
$signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
|
$signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
|
||||||
$thisUpdate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
|
|
||||||
|
$thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
$thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O');
|
||||||
|
|
||||||
if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
|
if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
|
||||||
$this->currentCert = $crl->currentCert;
|
$this->currentCert = $crl->currentCert;
|
||||||
@ -3823,7 +3835,11 @@ class X509
|
|||||||
*/
|
*/
|
||||||
function setStartDate($date)
|
function setStartDate($date)
|
||||||
{
|
{
|
||||||
$this->startDate = @date('D, d M Y H:i:s O', @strtotime($date));
|
if (!is_object($date) || !is_a($date, 'DateTime')) {
|
||||||
|
$date = new DateTime($date);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->startDate = $date->format('D, d M Y H:i:s O');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3847,7 +3863,11 @@ class X509
|
|||||||
$temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
|
$temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
|
||||||
$this->endDate = new Element($temp);
|
$this->endDate = new Element($temp);
|
||||||
} else {
|
} else {
|
||||||
$this->endDate = @date('D, d M Y H:i:s O', @strtotime($date));
|
if (!is_object($date) || !is_a($date, 'DateTime')) {
|
||||||
|
$date = new DateTime($date);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDate = $date->format('D, d M Y H:i:s O');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4577,8 +4597,9 @@ class X509
|
|||||||
}
|
}
|
||||||
|
|
||||||
$i = count($rclist);
|
$i = count($rclist);
|
||||||
|
$revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||||
$rclist[] = array('userCertificate' => $serial,
|
$rclist[] = array('userCertificate' => $serial,
|
||||||
'revocationDate' => $this->_timeField(@date('D, d M Y H:i:s O')));
|
'revocationDate' => $this->_timeField($revocationDate->format('D, d M Y H:i:s O')));
|
||||||
return $i;
|
return $i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user