From c9fbce874148bbd68ae588f72ba6116819974e6f Mon Sep 17 00:00:00 2001 From: "aleksandr.danilov" Date: Sat, 2 Aug 2025 16:30:52 +0300 Subject: [PATCH 1/7] adopt to modern phpunit --- .github/workflows/tests.yaml | 63 +++++++++++++++++++ .travis.yml | 3 + src/ASN1/AbstractTime.php | 2 +- src/ASN1/ElementBuilder.php | 2 +- src/ASN1/Universal/GeneralizedTime.php | 2 +- src/ASN1/Universal/UTCTime.php | 5 +- tests/ASN1/ASN1ObjectTest.php | 35 ++++++----- tests/ASN1/Base128Test.php | 7 +-- tests/ASN1/Universal/BitStringTest.php | 7 ++- tests/ASN1/Universal/BooleanTest.php | 10 +-- tests/ASN1/Universal/IntegerTest.php | 5 +- tests/ASN1/Universal/NullObjectTest.php | 5 +- tests/ASN1/Universal/ObjectIdentifierTest.php | 14 ++--- 13 files changed, 117 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/tests.yaml diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..1019f7a --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,63 @@ +name: PHP Unit Tests + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + matrix: + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + dependency-version: [prefer-lowest, prefer-stable] + + name: PHP ${{ matrix.php-versions }} - ${{ matrix.dependency-version }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, dom, fileinfo, mysql, redis + coverage: xdebug + tools: composer:v2 + + - name: Check PHP Version + run: php -v + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ matrix.dependency-version }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ matrix.dependency-version }}- + + - name: Install dependencies + run: | + composer update --${{ matrix.dependency-version }} --prefer-dist --no-progress --no-suggest + + - name: Run test suite + run: vendor/bin/phpunit + + - name: Run PHPUnit with coverage + run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml + + - name: Upload coverage to Coveralls + if: matrix.php-versions == '8.4' && matrix.dependency-version == 'prefer-stable' + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: build/logs/clover.xml + format: clover diff --git a/.travis.yml b/.travis.yml index 74de807..7b015a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,9 @@ php: - 7.4 - 8.0 - 8.1 + - 8.2 + - 8.3 + - 8.4 cache: directories: diff --git a/src/ASN1/AbstractTime.php b/src/ASN1/AbstractTime.php index 8638f8e..2432ee1 100644 --- a/src/ASN1/AbstractTime.php +++ b/src/ASN1/AbstractTime.php @@ -64,5 +64,5 @@ protected static function extractTimeZoneData(&$binaryData, &$offsetIndex, DateT return $dateTime; } - abstract public static function createFormDateTime(\DateTimeInterface $dateTime = null, array $options = []); + abstract public static function createFormDateTime(?\DateTimeInterface $dateTime = null, array $options = []); } diff --git a/src/ASN1/ElementBuilder.php b/src/ASN1/ElementBuilder.php index 5b9e914..552b1c3 100644 --- a/src/ASN1/ElementBuilder.php +++ b/src/ASN1/ElementBuilder.php @@ -180,7 +180,7 @@ protected static function createIdentifier($tagClass, $isConstructed, $tagNumber public static function createContentLength($content, $lengthForm) { - $length = strlen($content); + $length = strlen((string) $content); if ($lengthForm === ContentLength::INDEFINITE_FORM) { $lengthOctets = chr(128); } else { diff --git a/src/ASN1/Universal/GeneralizedTime.php b/src/ASN1/Universal/GeneralizedTime.php index 39e1365..f004ea3 100644 --- a/src/ASN1/Universal/GeneralizedTime.php +++ b/src/ASN1/Universal/GeneralizedTime.php @@ -152,7 +152,7 @@ public static function encodeValue(string $dateTime) return $dateTime; } - public static function createFormDateTime(\DateTimeInterface $dateTime = null, array $options = []) + public static function createFormDateTime(?\DateTimeInterface $dateTime = null, array $options = []) { $dateTime = $dateTime ?? new DateTime('now', new DateTimeZone('UTC')); diff --git a/src/ASN1/Universal/UTCTime.php b/src/ASN1/Universal/UTCTime.php index f9102d9..0701637 100644 --- a/src/ASN1/Universal/UTCTime.php +++ b/src/ASN1/Universal/UTCTime.php @@ -86,11 +86,10 @@ public function setValue(Content $content) $this->value = $dateTime; } - public static function createFormDateTime(\DateTimeInterface $dateTime = null, array $options = []) + public static function createFormDateTime(?\DateTimeInterface $dateTime = null, array $options = []) { $dateTime = $dateTime ?? new DateTime('now', new DateTimeZone('UTC')); - $isConstructed = false; $lengthForm = $options['lengthForm'] ?? ContentLength::SHORT_FORM; $string = $dateTime->format('ymdHis') . 'Z'; @@ -99,7 +98,7 @@ public static function createFormDateTime(\DateTimeInterface $dateTime = null, a ElementBuilder::createObject( Identifier::CLASS_UNIVERSAL, static::getType(), - $isConstructed, + false, $string, $lengthForm ); diff --git a/tests/ASN1/ASN1ObjectTest.php b/tests/ASN1/ASN1ObjectTest.php index b37a81c..fe807a3 100644 --- a/tests/ASN1/ASN1ObjectTest.php +++ b/tests/ASN1/ASN1ObjectTest.php @@ -201,79 +201,86 @@ public function testFromBinary() } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 10: Can not parse binary from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryThrowsException() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 10: Can not parse binary from data: Offset index larger than input size'); + $binaryData = 0x0; $offset = 10; ASN1Object::fromBinary($binaryData, $offset); } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 0: Can not parse binary from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryWithEmptyStringThrowsException() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 0: Can not parse binary from data: Offset index larger than input size'); + $data = ''; ASN1Object::fromBinary($data); } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 2: Can not parse binary from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryWithSpacyStringThrowsException() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 2: Can not parse binary from data: Offset index larger than input size'); + $data = ' '; ASN1Object::fromBinary($data); } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 1: Can not parse content length from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryWithNumberStringThrowsException() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 1: Can not parse content length from data: Offset index larger than input size'); + $data = '1'; ASN1Object::fromBinary($data); } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 25: Can not parse content length from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryWithGarbageStringThrowsException() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 25: Can not parse content length from data: Offset index larger than input size'); + $data = 'certainly no asn.1 object'; ASN1Object::fromBinary($data); } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 1: Can not parse identifier (long form) from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryUnknownObjectMissingLength() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 1: Can not parse identifier (long form) from data: Offset index larger than input size'); + $data = hex2bin('1f'); ASN1Object::fromBinary($data); } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 4: Can not parse content length (long form) from data: Offset index larger than input size * @depends testFromBinary */ public function testFromBinaryInalidLongFormContentLength() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 4: Can not parse content length (long form) from data: Offset index larger than input size'); + $binaryData = chr(Identifier::INTEGER); $binaryData .= chr(0x8f); //denotes a long-form content length with 15 length-octets $binaryData .= chr(0x1); //only give one content-length-octet diff --git a/tests/ASN1/Base128Test.php b/tests/ASN1/Base128Test.php index e4def35..5884050 100644 --- a/tests/ASN1/Base128Test.php +++ b/tests/ASN1/Base128Test.php @@ -79,12 +79,11 @@ public function getDataToDecode() ]; } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Malformed base-128 encoded value (0xFFFF). - */ public function testDecodeFailsIfLastOctetSignificantBitSet() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Malformed base-128 encoded value (0xFFFF).'); + Base128::decode("\xFF\xFF"); } } diff --git a/tests/ASN1/Universal/BitStringTest.php b/tests/ASN1/Universal/BitStringTest.php index 39394e2..7adce5c 100644 --- a/tests/ASN1/Universal/BitStringTest.php +++ b/tests/ASN1/Universal/BitStringTest.php @@ -138,12 +138,13 @@ public function testFromBinaryWithOffset() } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 3: Malformed bit string - * @depends testFromBinary + * @depends testFromBinary */ public function testFromBinaryWithInvalidLength01() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 3: Malformed bit string'); + $binaryData = chr(Identifier::BITSTRING); $binaryData .= chr(0x01); $binaryData .= chr(0x00); diff --git a/tests/ASN1/Universal/BooleanTest.php b/tests/ASN1/Universal/BooleanTest.php index eef1695..a228494 100644 --- a/tests/ASN1/Universal/BooleanTest.php +++ b/tests/ASN1/Universal/BooleanTest.php @@ -97,12 +97,13 @@ public function testFromBinaryWithOffset() } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 4: An ASN.1 Boolean should not have a length other than one. Extracted length was 2 * @depends testFromBinary */ public function testFromBinaryWithInvalidLength01() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 4: An ASN.1 Boolean should not have a length other than one. Extracted length was 2'); + $binaryData = chr(Identifier::BOOLEAN); $binaryData .= chr(0x02); $binaryData .= chr(0xFF); @@ -110,12 +111,13 @@ public function testFromBinaryWithInvalidLength01() } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 2: An ASN.1 Boolean should not have a length other than one. Extracted length was 0 * @depends testFromBinary */ public function testFromBinaryWithInvalidLength02() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 2: An ASN.1 Boolean should not have a length other than one. Extracted length was 0'); + $binaryData = chr(Identifier::BOOLEAN); $binaryData .= chr(0x00); $binaryData .= chr(0xFF); diff --git a/tests/ASN1/Universal/IntegerTest.php b/tests/ASN1/Universal/IntegerTest.php index b8c3be0..b23a668 100644 --- a/tests/ASN1/Universal/IntegerTest.php +++ b/tests/ASN1/Universal/IntegerTest.php @@ -29,11 +29,10 @@ public function testGetIdentifierCode() $this->assertEquals('Integer', $object->getIdentifier()->getCode()); } - /** - * @expectedException \Exception - */ public function testCreateInstanceCanFail() { + $this->expectException(\Exception::class); + Integer::create('a'); } diff --git a/tests/ASN1/Universal/NullObjectTest.php b/tests/ASN1/Universal/NullObjectTest.php index 9252d62..69cf6fa 100644 --- a/tests/ASN1/Universal/NullObjectTest.php +++ b/tests/ASN1/Universal/NullObjectTest.php @@ -74,12 +74,13 @@ public function testFromBinaryWithOffset() } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 3: An ASN.1 Null should not have a length other than zero. Extracted length was 1 * @depends testFromBinary */ public function testFromBinaryWithInvalidLength01() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 3: An ASN.1 Null should not have a length other than zero. Extracted length was 1'); + $binaryData = chr(Identifier::NULL); $binaryData .= chr(0x01); NullObject::fromBinary($binaryData); diff --git a/tests/ASN1/Universal/ObjectIdentifierTest.php b/tests/ASN1/Universal/ObjectIdentifierTest.php index 24388b3..5b43520 100644 --- a/tests/ASN1/Universal/ObjectIdentifierTest.php +++ b/tests/ASN1/Universal/ObjectIdentifierTest.php @@ -89,12 +89,13 @@ public function testFromBinaryWithOffset() } /** - * @expectedException \FG\ASN1\Exception\ParserException - * @expectedExceptionMessage ASN.1 Parser Exception at offset 2: Malformed ASN.1 Object Identifier - * @depends testFromBinary + * @depends testFromBinary */ public function testFromBinaryWithMalformedOID() { + $this->expectException(\FG\ASN1\Exception\ParserException::class); + $this->expectExceptionMessage('ASN.1 Parser Exception at offset 2: Malformed ASN.1 Object Identifier'); + $binaryData = chr(Identifier::OBJECT_IDENTIFIER); $binaryData .= chr(0x03); $binaryData .= chr(42); @@ -103,12 +104,11 @@ public function testFromBinaryWithMalformedOID() ObjectIdentifier::fromBinary($binaryData); } - /** - * @expectedException \Exception - * @expectedExceptionMessage [1.Foo.3] is no valid object identifier (sub identifier 2 is not numeric)! - */ public function testCreateWithInvalidObjectIdentifier() { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('[1.Foo.3] is no valid object identifier (sub identifier 2 is not numeric)!'); + ObjectIdentifier::create('1.Foo.3'); } } From 02bead06313ffe4018214671c0cf7d0b32656cb1 Mon Sep 17 00:00:00 2001 From: "aleksandr.danilov" Date: Sat, 2 Aug 2025 16:35:03 +0300 Subject: [PATCH 2/7] github actions --- .github/workflows/tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 65f586e..19e3e06 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -2,9 +2,9 @@ name: PHP Unit Tests on: push: - branches: [ main, develop ] + branches: [ master ] pull_request: - branches: [ main, develop ] + branches: [ master ] jobs: test: From 5e7b62dbbd58e056ef1290195dc3d481704dc8aa Mon Sep 17 00:00:00 2001 From: "aleksandr.danilov" Date: Sat, 2 Aug 2025 16:38:41 +0300 Subject: [PATCH 3/7] github actions --- .github/workflows/tests.yaml | 2 +- composer.json | 4 ++-- phpunit.xml.dist | 33 +++++++++++---------------------- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 19e3e06..74413fd 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] dependency-version: [prefer-lowest, prefer-stable] name: PHP ${{ matrix.php-versions }} - ${{ matrix.dependency-version }} diff --git a/composer.json b/composer.json index 2c77c7e..d69daf3 100644 --- a/composer.json +++ b/composer.json @@ -25,11 +25,11 @@ "keywords": [ "x690", "x.690", "x.509", "x509", "asn1", "asn.1", "ber", "der", "binary", "encoding", "decoding" ], "require": { - "php": ">=7.2", + "php": ">=7.4", "ext-gmp": "*" }, "require-dev": { - "phpunit/phpunit": "^8.0", + "phpunit/phpunit": "^9.0", "php-coveralls/php-coveralls": "^2.4" }, "suggest": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c30a483..b33165d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,24 +1,13 @@ - - - - - tests - - - - - - src - - + + + + src + + + + + tests + + From 6ff19ce21c88ec51a9460328c201ff60ee00f5a0 Mon Sep 17 00:00:00 2001 From: "aleksandr.danilov" Date: Sat, 2 Aug 2025 16:43:31 +0300 Subject: [PATCH 4/7] github actions --- .github/workflows/tests.yaml | 12 +++++++----- composer.json | 3 +-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 74413fd..c15a76c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -52,10 +52,12 @@ jobs: - name: Run PHPUnit with coverage run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml - - name: Upload coverage to Coveralls + - name: Upload coverage to Codecov if: matrix.php-versions == '8.4' && matrix.dependency-version == 'prefer-stable' - uses: coverallsapp/github-action@v2 + uses: codecov/codecov-action@v3 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: build/logs/clover.xml - format: clover \ No newline at end of file + token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.xml + flags: unittests + name: codecov-umbrella + fail_ci_if_error: false \ No newline at end of file diff --git a/composer.json b/composer.json index d69daf3..4d213ae 100644 --- a/composer.json +++ b/composer.json @@ -29,8 +29,7 @@ "ext-gmp": "*" }, "require-dev": { - "phpunit/phpunit": "^9.0", - "php-coveralls/php-coveralls": "^2.4" + "phpunit/phpunit": "^9.0" }, "suggest": { "php-curl": "For loading OID information from the web if they have not bee defined statically" From 03094282c0336e0958eacecc4b0b4174f7e9f945 Mon Sep 17 00:00:00 2001 From: "aleksandr.danilov" Date: Sat, 2 Aug 2025 16:45:34 +0300 Subject: [PATCH 5/7] github actions --- .github/workflows/tests.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c15a76c..490f05f 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -50,6 +50,7 @@ jobs: run: vendor/bin/phpunit - name: Run PHPUnit with coverage + if: matrix.php-versions == '8.4' && matrix.dependency-version == 'prefer-stable' run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml - name: Upload coverage to Codecov From 0cc9d9610e5e1193378926486b042c255cdf3b62 Mon Sep 17 00:00:00 2001 From: "aleksandr.danilov" Date: Sat, 2 Aug 2025 16:52:31 +0300 Subject: [PATCH 6/7] github actions --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 490f05f..04d82cc 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -58,7 +58,7 @@ jobs: uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} - file: ./coverage.xml + file: ./build/logs/clover.xml flags: unittests name: codecov-umbrella fail_ci_if_error: false \ No newline at end of file From 896befe8783760949d1cd1022619b83c3836cad6 Mon Sep 17 00:00:00 2001 From: "aleksandr.danilov" Date: Sat, 2 Aug 2025 16:59:49 +0300 Subject: [PATCH 7/7] github actions --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c80b965..d252675 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ PHPASN1 ======= -[![Build Status](https://secure.travis-ci.org/Adapik/PHPASN1.png?branch=master)](http://travis-ci.org/Adapik/PHPASN1) -[![PHP 7 ready](http://php7ready.timesplinter.ch/Adapik/PHPASN1/badge.svg)](https://travis-ci.org/Adapik/PHPASN1) -[![Coverage Status](https://coveralls.io/repos/Adapik/PHPASN1/badge.svg?branch=master&service=github)](https://coveralls.io/github/Adapik/PHPASN1?branch=master) +![build status](https://github.com/github/docs/actions/workflows/tests.yml/badge.svg) +[![codecov](https://codecov.io/github/adapik/phpasn1/graph/badge.svg?token=KCBH7EV2J0)](https://codecov.io/github/adapik/phpasn1) [![Latest Stable Version](https://poser.pugx.org/Adapik/phpasn1/v/stable.png)](https://packagist.org/packages/Adapik/phpasn1) [![Total Downloads](https://poser.pugx.org/Adapik/phpasn1/downloads.png)](https://packagist.org/packages/Adapik/phpasn1) -[![Latest Unstable Version](https://poser.pugx.org/Adapik/phpasn1/v/unstable.png)](https://packagist.org/packages/Adapik/phpasn1) [![License](https://poser.pugx.org/Adapik/phpasn1/license.png)](https://packagist.org/packages/Adapik/phpasn1) A PHP Framework that allows you to encode and decode arbitrary [ASN.1][3] structures