diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 3aaa3090..8a7286b1 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -702,7 +702,14 @@ class ASN1 return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content']; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: - if (isset($mapping['implicit'])) { + // for explicitly tagged optional stuff + if (is_array($decoded['content'])) { + $decoded['content'] = $decoded['content'][0]['content']; + } + // for implicitly tagged optional stuff + // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist + // in the wild that OpenSSL decodes without issue so we'll support them as well + if (!is_object($decoded['content'])) { $decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']); } return $decoded['content'] ? $decoded['content']->format($this->format) : false; diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 78d0e91d..b4963fc8 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -963,6 +963,13 @@ class X509 'children' => $AccessDescription ); + $this->SubjectInfoAccessSyntax = array( + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => $AccessDescription + ); + $this->SubjectAltName = $GeneralNames; $this->PrivateKeyUsagePeriod = array( @@ -1892,6 +1899,8 @@ class X509 return $this->ExtKeyUsageSyntax; case 'id-pe-authorityInfoAccess': return $this->AuthorityInfoAccessSyntax; + case 'id-pe-subjectInfoAccess': + return $this->SubjectInfoAccessSyntax; case 'id-ce-subjectAltName': return $this->SubjectAltName; case 'id-ce-subjectDirectoryAttributes': diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 6c8c3175..b75333b7 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -363,4 +363,33 @@ class Unit_File_ASN1Test extends PhpseclibTestCase $this->assertSame(pack('H*', '6983f09da7ebcfdee0c7a1a7b2c0948cc8f9d776'), $new); $this->assertSame($orig, $asn1->_decodeOID($new)); } + + /** + * @group github1388 + */ + public function testExplicitImplicitDate() + { + $map = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'notBefore' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME], + 'notAfter' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME] + ] + ]; + + $asn1 = new ASN1(); + $a = pack('H*', '3026a011180f32303137303432313039303535305aa111180f32303138303432313230353935395a'); + $a = $asn1->decodeBER($a); + $a = $asn1->asn1map($a[0], $map); + + $this->assertInternalType('array', $a); + } }