Giter Site home page Giter Site logo

fgrosse / phpasn1 Goto Github PK

View Code? Open in Web Editor NEW
180.0 8.0 48.0 744 KB

A PHP library to encode and decode arbitrary ASN.1 structures using ITU-T X.690 encoding rules.

License: MIT License

PHP 100.00%
asn1 binary encoding decoding x509 x690 php asn csr pki

phpasn1's Introduction

PHPASN1

Latest Stable Version Total Downloads License


Notice: This library is no longer actively maintained!

If you are currently using PHPASN1, this might not be an immediate problem for you, since this library was always rather stable.

However, you are advised to migrate to alternative packages to ensure that your applications remain functional also with newer PHP versions.

Another option is to fork this repository or use one of the existing forks.

If you are using another fork, please make sure you trust the author and validate the code you are relying upon!


A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules. This encoding is very frequently used in X.509 PKI environments or the communication between heterogeneous computer systems.

The API allows you to encode ASN.1 structures to create binary data such as certificate signing requests (CSR), X.509 certificates or certificate revocation lists (CRL). PHPASN1 can also read BER encoded binary data into separate PHP objects that can be manipulated by the user and reencoded afterwards.

The changelog can now be found at CHANGELOG.md.

Dependencies

PHPASN1 requires at least PHP 7.0 and either the gmp or bcmath extension. Support for older PHP versions (i.e. PHP 5.6) was dropped starting with v2.0. If you must use an outdated PHP version consider using PHPASN v1.5.

For the loading of object identifier names directly from the web curl is used.

Installation

The preferred way to install this library is to rely on Composer:

$ composer require fgrosse/phpasn1

Usage

Encoding ASN.1 Structures

PHPASN1 offers you a class for each of the implemented ASN.1 universal types. The constructors should be pretty self explanatory so you should have no big trouble getting started. All data will be encoded using DER encoding

use FG\ASN1\OID;
use FG\ASN1\Universal\Integer;
use FG\ASN1\Universal\Boolean;
use FG\ASN1\Universal\Enumerated;
use FG\ASN1\Universal\IA5String;
use FG\ASN1\Universal\ObjectIdentifier;
use FG\ASN1\Universal\PrintableString;
use FG\ASN1\Universal\Sequence;
use FG\ASN1\Universal\Set;
use FG\ASN1\Universal\NullObject;

$integer = new Integer(123456);        
$boolean = new Boolean(true);
$enum = new Enumerated(1);
$ia5String = new IA5String('Hello world');

$asnNull = new NullObject();
$objectIdentifier1 = new ObjectIdentifier('1.2.250.1.16.9');
$objectIdentifier2 = new ObjectIdentifier(OID::RSA_ENCRYPTION);
$printableString = new PrintableString('Foo bar');

$sequence = new Sequence($integer, $boolean, $enum, $ia5String);
$set = new Set($sequence, $asnNull, $objectIdentifier1, $objectIdentifier2, $printableString);

$myBinary  = $sequence->getBinary();
$myBinary .= $set->getBinary();

echo base64_encode($myBinary);

Decoding binary data

Decoding BER encoded binary data is just as easy as encoding it:

use FG\ASN1\ASNObject;

$base64String = ...
$binaryData = base64_decode($base64String);        
$asnObject = ASNObject::fromBinary($binaryData);


// do stuff

If you already know exactly how your expected data should look like you can use the FG\ASN1\TemplateParser:

use FG\ASN1\TemplateParser;

// first define your template
$template = [
    Identifier::SEQUENCE => [
        Identifier::SET => [
            Identifier::OBJECT_IDENTIFIER,
            Identifier::SEQUENCE => [
                Identifier::INTEGER,
                Identifier::BITSTRING,
            ]
        ]
    ]
];

// if your binary data is not matching the template you provided this will throw an `\Exception`:
$parser = new TemplateParser();
$object = $parser->parseBinary($data, $template);

// there is also a convenience function if you parse binary data from base64:
$object = $parser->parseBase64($data, $template);

You can use this function to make sure your data has exactly the format you are expecting.

Navigating decoded data

All constructed classes (i.e. Sequence and Set) can be navigated by array access or using an iterator. You can find examples here, here and here.

Give me more examples!

To see some example usage of the API classes or some generated output check out the examples.

How do I contribute?

This project is no longer maintained and thus does not accept any new contributions.

Thanks

To all contributors so far!

License

This library is distributed under the MIT License.

phpasn1's People

Contributors

afk11 avatar bilogic avatar blaimi avatar devicenull avatar ekman avatar fgrosse avatar herndlm avatar kgilden avatar lcts avatar nathanntg avatar naugrimm avatar orastor avatar philetaylor avatar sanderkruger avatar staabm avatar tatikoma avatar timwolla avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phpasn1's Issues

How to get a printable content of a OID

I need to get a OID content fom Subject alternative name (SAN), OID value: 2.16.76.1.3.3
CNPJ from brasilian certificates.

By the ASN1 class i got only this Octet string :

3081AFA03D0605604C010304A03404323230313031393539303532323535333738383030303030303030303030303030303030303038383734333732787373705350A0210605604C010302A01804164665726E616E646F204A6F7365204B616972616C6C61A0190605604C010303A010040E3538373136353233303030313139A0170605604C010307A00E040C30303030303030303030303081176665726E616E646F4066696D617465632E636F6D2E6272

But is a other way to get this content directly ?

010303A010040E3538373136353233303030313139A0

35 38 37 31 36 35 32 33 30 30 30 31 31 39 => 58716523000119 (this is a CNPJ number)

Tks, for you help

CSR parsing ends in 'PHP Fatal error' => ParserException

I try to parse a CSR from binary. This following example ends with the following fatal error:

PHP Fatal error:  Uncaught exception 'FG\ASN1\Exception\ParserException' with message 'ASN.1 Parser Exception at offset 544: Context-Specific explicitly tagged object [0] starting at offset 544 is longer than allowed in the outer tag' in /tmp/foo/vendor/fgrosse/phpasn1/lib/ASN1/ExplicitlyTaggedObject.php:97
Stack trace:
#0 /tmp/foo/vendor/fgrosse/phpasn1/lib/ASN1/Object.php(201): FG\ASN1\ExplicitlyTaggedObject::fromBinary('0??X0??????0W1?...', 555)
#1 /tmp/foo/vendor/fgrosse/phpasn1/lib/ASN1/Construct.php(149): FG\ASN1\Object::fromBinary('0??X0??????0W1?...', 555)
#2 /tmp/foo/vendor/fgrosse/phpasn1/lib/ASN1/Object.php(222): FG\ASN1\Construct::fromBinary('0??X0??????0W1?...', 555)
#3 /tmp/foo/vendor/fgrosse/phpasn1/lib/ASN1/Construct.php(149): FG\ASN1\Object::fromBinary('0??X0??????0W1?...', 555)
#4 /tmp/foo/vendor/fgrosse/phpasn1/lib/ASN1/Object.php(222): FG\ASN1\Construct::fromBinary('0??X0??????0W1?...', 555)
#5 /tmp/foo/test.php(50): FG\ASN1\Object::fromBinary('0??X0??????0W1?...')
#6 {main}
  thrown in /tmp/foo/vendor/fgrosse/phpasn1/lib/ASN1/ExplicitlyTaggedObject.php on line 97
<?php

require_once __DIR__ . '/vendor/autoload.php';

use FG\ASN1\Object;

// Test vector CSR from https://github.com/pyca/cryptography/blob/b5bb49d115e9f325d90bb96aebc15e6a1ef30f0d/vectors/cryptography_vectors/x509/requests/dsa_sha1.pem
$origCsr = <<<'EOF'
# Use this command to check the if the ASN1 parsing of openssl
(cat <<CATEOF | openssl asn1parse -inform PEM
-----BEGIN CERTIFICATE REQUEST-----
MIICWDCCAhgCAQAwVzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMQ0wCwYDVQQK
DARQeUNBMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1
c3RpbjCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCNf628CeKEqvppFUzqJBdwBJCe
UZ+LNdaFzeW07NyVg+dNNwoPiK2pjwJvJ3Yvs9XaeDb5ht/Ns1ieW5Jb6hFN78A+
+B2uMMJLvG3z1YjpNCe7pkID1KWxaHsrXjtkPUxhSXb4n5WjjT5MiQZfupdRTCLF
Ctu/KJFjp0tUhZs1twIVAINd5WvQfPf4LiAy/niUmu0ReqLvAoGAH3F7Wgd4L8Lk
5o4xH+qRpU7dNrhqxjTRTwWmipfq6dLvMfse895Cw9EA35ymT1vcKux7/ftHTPgx
/qBYU7XgWfLSSYCgrEY/HoGK81I+PLeaOdRfqScxiXdShCRpz4VAsBSRAk6q+85g
GOih9GWMND9Lp8CyHlN2oh9L64SRlh4DgYQAAoGABxPwdkH2Npu1qVRSdKLUwBmY
Nn+zcbueE0NjY2cu1o+CF0wt4FyOg5vG3laN1QuijY2dhxlCOq7FVX3xDXc6si1t
Zcu4eASml7yP2WW5Uvn36FDt8TyKzbXXU7bRDlngtXMuPIK6+hQDQrxKO7oWvQaB
yKai27t+/mziuEY7FwugADAJBgcqhkjOOAQDAy8AMCwCFGHVjcAo0BEIGKfYF9dC
NXJ8Ss/fAhQJe1LhmOzpXeFyc/CpJN8jzp2BiA==
-----END CERTIFICATE REQUEST-----
CATEOF
)

EOF;

echo $origCsr;

$csr = <<<'EOF'
MIICWDCCAhgCAQAwVzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMQ0wCwYDVQQK
DARQeUNBMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1
c3RpbjCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCNf628CeKEqvppFUzqJBdwBJCe
UZ+LNdaFzeW07NyVg+dNNwoPiK2pjwJvJ3Yvs9XaeDb5ht/Ns1ieW5Jb6hFN78A+
+B2uMMJLvG3z1YjpNCe7pkID1KWxaHsrXjtkPUxhSXb4n5WjjT5MiQZfupdRTCLF
Ctu/KJFjp0tUhZs1twIVAINd5WvQfPf4LiAy/niUmu0ReqLvAoGAH3F7Wgd4L8Lk
5o4xH+qRpU7dNrhqxjTRTwWmipfq6dLvMfse895Cw9EA35ymT1vcKux7/ftHTPgx
/qBYU7XgWfLSSYCgrEY/HoGK81I+PLeaOdRfqScxiXdShCRpz4VAsBSRAk6q+85g
GOih9GWMND9Lp8CyHlN2oh9L64SRlh4DgYQAAoGABxPwdkH2Npu1qVRSdKLUwBmY
Nn+zcbueE0NjY2cu1o+CF0wt4FyOg5vG3laN1QuijY2dhxlCOq7FVX3xDXc6si1t
Zcu4eASml7yP2WW5Uvn36FDt8TyKzbXXU7bRDlngtXMuPIK6+hQDQrxKO7oWvQaB
yKai27t+/mziuEY7FwugADAJBgcqhkjOOAQDAy8AMCwCFGHVjcAo0BEIGKfYF9dC
NXJ8Ss/fAhQJe1LhmOzpXeFyc/CpJN8jzp2BiA==
EOF;

// $csr = str_replace("\n", '', $csr);
$asnObject = Object::fromBinary(base64_decode($csr));

Can you figure out what I'm doing wrong or do you spot the problem. Currently used version is 1.3.2 due to a local limitation of using PHP 5.6 requirement.

Implement the indefinite length form

The Basic Encoding Rules (BER) describe a indefinite form for the length of an object.
this might be useful for handling data streams later.

See ITU-T X690 section 8.1.3.3

BitString encapsulating Sequence of Integers

Hi,

I have RSA details n and e (modulo and exponent) from a plubic key.
I would like to convert these values into a PKCS#8 file, but a encounter some problems with Integer and BitString classes.

According to the specification and this useful page, the sequence is:

Sequence:
    Sequence:
        ObjectIdentifier: 1.2.840.113549.1.1.1
        NullObject
    BitString:
        Sequence:
            Integer: n value
            Integer: e value

Hereafter my code:

$result = new Sequence();
$oid_sequence = new Sequence();
$oid_sequence->addChild(new ObjectIdentifier('1.2.840.113549.1.1.1'));
$oid_sequence->addChild(new NullObject());
$result ->addChild($oid_sequence);

$key_sequence = new Sequence();
$n = "23048702444524490053025563207470260339027703388228696677413189217645523615585428278678890992016618560435...";
$e = "65537";
$key_sequence->addChild(new Integer($n));
$key_sequence->addChild(new Integer($e));

$key_bit_string = new BitString(???);
$result ->addChild($key_bit_string);

My questions are:

  • It seems that the size calculated for Integer($n) is wrong. I get 2 but I should have 257. Is there a bug or am I wrong?
  • How can I encapsulate my key sequence into the BitString object?

Creating ExplicitlyTaggedObject with huge tags gives surprising results

I dont quite understand why we missed this in #33 but choosing big integers as tags for ExplicitlyTaggedObject breaks.

The issue is effectivly caused by Base128
I already added a failing (but currently skipped) test to master:

public function testFromBinaryWithHugeTagNumber()
{
    $originalStringObject = new PrintableString('test');
    $originalObject = new ExplicitlyTaggedObject(0xDEADBEEF, $originalStringObject);
    $binaryData = $originalObject->getBinary();

    $parsedObject = ExplicitlyTaggedObject::fromBinary($binaryData);
    $this->assertEquals($originalObject, $parsedObject);
}

Environment:

fgrosse@argp ➤ php --version
PHP 5.6.6 (cli) (built: Feb 19 2015 13:46:45) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Xdebug v2.3.1, Copyright (c) 2002-2015, by Derick Rethans

fgrosse@argp ➤ php -r "echo PHP_INT_SIZE;"
fgrosse@argp ➤ 4

Describe the Project in the README

The README.md should contain information some general information about the project, the background (with links to ASN1, DER some RFCs etc) and how to use the API

big integer return -1

Hello,
i've found a problem with big number :

$int1= new ASN_Integer('27329582247986455021744172946096660569051589561051333490087175127133313409704369258177580117032300463239993069430188108780068522375921597249886196875635840025258877325690136352074442377928793199004608912275282905559887563288327636213273678741723145705319413687612690511917113685687906266196637448477719878688233171348877591039878469329172797804033242737837693698612298959413778391800316619493399655906166823553525901757394365546962768131813370312748053879456690650062862686879658478717150437787160014784003559410568381409235269389437859772386421117258753064748885099584872337063364464241324800715578256068913666258773');

$x=$int1->getBinary();
$res=ASN_Object::fromBinary($x);
var_dump($int1);
var_dump($res);

PHPASN1\classes\asn1\universal\ASN_Integer.class.php

calculateContentLength use abs() who doesn't like big number,

$tmpValue =  gmp_strval(gmp_abs($this->value));

help, but the resultant byte string is wrong, haven't figured why ...

PHP 5.4 and 5.5

Hi,

I noted that you tagged v1.4.0 yesterday.
This new release adds cool stuf, but you dropped PHP 5.4 and 5.5 that are still maintained (security support).

What are the reasons that I missed for that choice?

PHP 8.2.0

Hi !
Think the changes from php 8.1.0 to 8.2.0 have no impact .. ?
Can you add PHP 8.2.0 support? Especially in composer.json?
Y

Encoder usage question

I now understand how the decoder works, but how can I encode [0] CONTEXT-SPECIFIC (0X80), [2] CONTEXT-SPECIFIC (0XA2), [2] CONTEXT-SPECIFIC (0XA2) things from the results of the following gist?

https://gist.github.com/korusdipl/7b145d2c67a4a03c8873

Not having the profound knowledge on ASN.1, I am having quite difficulties in encoding those stuffs back. A live snippet would be a great help.

The first result was from the binary of the OCSP output in https://gist.github.com/korusdipl/f0c3075cd61cc8d0616c

Thanks.

Further OCSP Decoding/Encoding Ability

I met your library today, and it's awesome!

However, when I try to deal with an OCSP Response, it seemed standardized timestamps for publishing, next-update or cert-status of an ocsp response were misinterpreted as unknown objects

The following gist was derived from OCTETSTRING from the OCSP Response.
https://gist.github.com/korusdipl/f0c3075cd61cc8d0616c

Hope this improves your script.
Thanks again for building this stuff up! :)

php -l errors.

PHP Fatal error:  Cannot use 'Null' as class name as it is reserved in ./vendor/fgrosse/phpasn1/lib/ASN1/Universal/Null.php on line 16

Fatal error: Cannot use 'Null' as class name as it is reserved in ./vendor/fgrosse/phpasn1/lib/ASN1/Universal/Null.php on line 16

Errors parsing ./vendor/fgrosse/phpasn1/lib/ASN1/Universal/Null.php

NullObject is undefined

In the example provided in the readme page, the object FG\Universal\NullObject is used. Does this object exists? Should it be replaced by FG\Universal\Null?

OIDs 2.40+ are not supported

I have looked at your implementation of Object Identifiers and found out that there is following problem:

The modulo-40 code is not correct, since it does not support the case of OID 2.40, 2.41, etc. Your modulo-40 code would encode 2.40 as 3.0.

You can find a implementation which implements 2.40+ OIDs correctly here. Testcases/checks of the DER encoding can be done here.

(Update: Ignore my initial comment about 128bit UUIDs)

Doesn't detect gmp

ISSUE:
composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.

Problem 1
- fgrosse/phpasn1 1.5.3 requires ext-gmp * -> the requested PHP extension gmp is missing from your system.
- fgrosse/phpasn1 1.5.3 requires ext-gmp * -> the requested PHP extension gmp is missing from your system.
- Installation request for fgrosse/phpasn1 1.5.3 -> satisfiable by fgrosse/phpasn1[1.5.3].

PHPINFO OUTPUT:

gmp support enabled
GMP version 6.1.2

SYSTEM: OS HIGH SIERRA
I have installed php71 and php71-gmp. php.ini has gmp extension enabled

Register project with Packagist

Yet another issue, sorry to be bugging you...

Can you register your project in the Packagist repository ( https://packagist.org/ ), it takes roughly two minutes, otherwise, people can't include your project as a dependency in their projects.

I could do it, but it's better if the owner of the repo does it...

Would you consider switching to a more permissive license?

Hey, just stumbled upon Your library and it looks really polished, kudos!

I would be happy to contribute to the project. Been thinking of the following stuff:

  • more complete classes for X.509;
  • full set of classes for OCSP;
  • perhaps have a parser to generate PHP classes from ASN.1 specifications;

Unfortunately I'm a little bit concerned by the GPLv3 license preventing the use of this library by most commercial endeavors. Would You ever consider something more permissive, say MIT or Apache2?

Some signatures cannot be parsed

I have a live examples. Both correct (working at another script), but one will not be decoded while ASNObject::fromBinary, I get only this:

FG\ASN1\Universal\Sequence Object
(
[children:protected] => Array
(
)

[iteratorPosition:FG\ASN1\Construct:private] => 0
[contentLength:FG\ASN1\ASNObject:private] => 0
[nrOfLengthOctets:FG\ASN1\ASNObject:private] => 1

)

I was send both (correct and incorrect) to developer's e-mail (not allow to public stream).

PHP 7

Hi,

This library is not compatible with PHP 7 ; I got the following error:
Cannot use FG\ASN1\Universal\Null as Null because 'Null' is a special class name in /home/travis/build/mdanter/phpecc/vendor/fgrosse/phpasn1/lib/ASN1/Object.php on line 28

I think it could be easy to reach compatiblity, but it requires to rename some classes and bump to a major release.

Do you think it could be possible to update this library in this way?

`Object` is a special class name

Hi,

I have the following error on PHP 7.2 (unstable):

Fatal error: Cannot use FG\ASN1\Object as Object because 'Object' is a special class name in ...

It looks like the Object name is reserved in the next major release.
Maybe something similar as the #35.

Modifying an existing object failing

Thanks for the great library, it has helped me understand a lot more of ASN1,
I have a question, might be simply that the problem exists with me, but I cannot seem to find how to debug.
Trying to add a TSA timestamp to a pdf signature
I have an ASN.s object that I load that contains the TSA response:

$asnObject = ASNObject::fromBinary($tsa_ts);
$oid = new ObjectIdentifier('1.2.840.113549.1.9.16.2.14');
$children = $asnObject->getChildren();
$set = new Set($children[1]);
file_put_contents('asn.tsa',$asnObject->getBinary());
$sequence = new ExplicitlyTaggedObject(1, new Sequence($oid,$set));
// $sequence = new Sequence($oid,$set);
$old_sig = ASNObject::fromBinary($signature);
/**
* we need to add this new attribute as an unsigned attribute within the signerInfo node
* https://datatracker.ietf.org/doc/html/rfc2630#section-5.3
* */
			
$old_sig->getChildren()[1]->getContent()[0]->getChildren()[4]->getChildren()[0]->addChild($sequence);
file_put_contents('sig_prev.tsa', $sequence->getBinary());
$signature = $old_sig->getBinary();
file_put_contents('sig_aft.tsa', $signature);
return $signature;

The $sequence object is perfectly formed you can see it here

And the final signature is in essence just the original one, even though I added the child

there are no errors thrown, the count of children increases when checking with count($old_sig->getChildren()[1]->getContent()[0]->getChildren()[4]->getChildren()[0]);

Any hints to what I should be looking at?

OCSP CertStatus Info Again

Thanks for the last update which resolved the generalized time issue.

However, when parsing OCSP Response, it still interprets the cert status data as unknown or unparsable objects. It was tested with the same gist as provided #41 .

According to the RFC6960, the ASN.1 structure of OCSP response should include the following.

CertStatus ::= CHOICE {
good [0] IMPLICIT NULL,
revoked [1] IMPLICIT RevokedInfo,
unknown [2] IMPLICIT UnknownInfo }

RevokedInfo ::= SEQUENCE {
revocationTime GeneralizedTime,
revocationReason [0] EXPLICIT CRLReason OPTIONAL }

https://tools.ietf.org/html/rfc6960#section-4.2.1

Is this non-standard, so you don't support it, or was it not just implemented?
Hope your library can decode and encode these too as I am considering making an OCSP Responder with pure PHP, and your library is a great tool to help me reduce tremendous amount of work.

Thanks.

Additional Reference : https://gist.github.com/korusdipl/eeb27b36efdac5c7045f

Autoloader too aggressive

I was trying to use this library in a CakePHP environment, but it would break the autoloading done by some of the magical elements of CakePHP. I figured out that the autoloader was being too aggressive, in that it tried to autoload for all unknown classes, not just the ones from this library. This is easily fixed with:

diff --git a/classes/PHPASN_Autoloader.php b/classes/PHPASN_Autoloader.php
index 0c51793..70a3fe9 100644
--- a/classes/PHPASN_Autoloader.php
+++ b/classes/PHPASN_Autoloader.php
@@ -72,6 +72,9 @@ class PHPASN_Autoloader {
     }

     public static function autoload($className) {
+        if (strpos($className, 'PHPASN1') !== 0) {
+            return;
+        }
         $simpleClassName = substr($className, strrpos($className, '\\') + 1);
         $instance = self::getInstance();
         require_once $instance->getPathOfClass($simpleClassName);

to make sure that this autoloader only attempts to autoload classes in the PHPASN1 namespace.

PHPUnit tests fail on 32bit systems due to out-of-bounds integer.

Hi,
when running the test suite on 32bit systems (I tested on ARM & x86), tests fail with

There were 2 errors:

1) FG\Test\ASN1\Universal\BitStringTest::testContent
TypeError: dechex(): Argument #1 ($num) must be of type int, float given

/builddir/build/BUILDROOT/php-fgrosse-phpasn1-2.3.0-1.fc35.arm/usr/share/php/FG/ASN1/Universal/OctetString.php:28
/builddir/build/BUILDROOT/php-fgrosse-phpasn1-2.3.0-1.fc35.arm/usr/share/php/FG/ASN1/Universal/BitString.php:32
/builddir/build/BUILD/PHPASN1-20299033c35f4300eb656e7e8e88cf52d1d6694e/tests/ASN1/Universal/BitStringTest.php:45

2) FG\Test\ASN1\Universal\OctetStringTest::testContent
TypeError: dechex(): Argument #1 ($num) must be of type int, float given

/builddir/build/BUILDROOT/php-fgrosse-phpasn1-2.3.0-1.fc35.arm/usr/share/php/FG/ASN1/Universal/OctetString.php:28
/builddir/build/BUILD/PHPASN1-20299033c35f4300eb656e7e8e88cf52d1d6694e/tests/ASN1/Universal/OctetStringTest.php:45

I think what happens here is that the number used for testing, 0xA01200C3, exceeds PHP_INT_MAX on 32bit and so gets cast to float before being passed to dechex().

Is the library supposed to be able to deal with larger ints in there or is this just an error in the tests?

made you a composer.json

too lazy for a PR :( ;)

{
    "name" : "fgrosse/phpasn1",
    "description" : "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.",
    "homepage" : "https://github.com/FGrosse/PHPASN1",
    "license" : "GPLv3",
    "authors" : [
        {
            "name" : "Friedrich Große",
            "email" : "[email protected]"
        }
    ],
    "type" : "library",
    "require" : {
        "php" : ">=5.3"
    },
    "suggests" : {
        "php-curl" : "*"
    },
    "require-dev": {
        "phpunit/phpunit": "*"
    },
    "autoload": {
        "classmap": [
            "classes"
        ]
    }
}

Most efficient way to parse structures?

This library makes it easy to create encoded structures, but when it comes to parsing them, I'm a little unsure about the best way.

I have been imperatively checking the type of each element in the structure after doing Object::fromBinary().

I wondered if it's possible to do anything similar to this, and parse a structure according to a template? If not I might take a look at PRing something for this.

I notice some of the structures have optional parameters (eg, tbsCertificateInfo), so I'd hope to handle that also.

$structure = new Sequence(
   new Set(
      new ObjectIdentifier(),
      new Sequence(
         new Integer(),
         new BitString()
      )
   )
);

$structure->fromBinary($byteString);

a few typos

In examples/allClasses.php you have this:

printVariableInfo(new ASN_ObjectIdentifier(OID::EMAIL));

You probably mean to do this:

printVariableInfo(new ASN_ObjectIdentifier(OID::PKCS9_EMAIL));

I say that because there is no EMAIL constant in OID.

Also, in that same file, you have this:

printVariableInfo(new CSR_SignatureKeyAlgorithm(OID::SHA1_WITH_RSA_ENCRYPTION));

You probably mean to do this:

printVariableInfo(new CSR_SignatureKeyAlgorithm(OID::SHA1_WITH_RSA_SIGNATURE));

From CSR_PublicKeyClass.php:

new ASN_NULL()

You probably meant to do this:

new ASN_Null()

Tag a version

In order to ease adoption of your library, and so that it can be adopted by other projects, it would be nice to tag/release a version of the project using semantic version (ie. v0.0.1)

In current state, when using your lib through composer, it's not usable by projects that have a minimum stability setting of "stable".

ASN_AbstractString generates huge allowedCharacters array

When using var_dump() on a populated ASN_Sequence, it generates a huge output, because there are two char wide elements in allowedCharacters. allowSmallCharacters() will add strings in range 'a' .. 'z' .. 'za' .. 'zy'.

Proposing to use range('a', 'z') instead.

diff --git a/classes/asn1/ASN_AbstractString.class.php b/classes/asn1/ASN_AbstractString.class.php
index 222aea4..d301939 100644
--- a/classes/asn1/ASN_AbstractString.class.php
+++ b/classes/asn1/ASN_AbstractString.class.php
@@ -62,7 +62,7 @@ abstract class ASN_AbstractString extends ASN_Object implements Parseable {
     }

     protected function allowNumbers() {
-        for ($char='0'; $char <= '9' ; $char++) { 
+        foreach (range('0', '9') as $char) { 
             $this->allowedCharacters[] = $char;
         }
     }
@@ -73,13 +73,13 @@ abstract class ASN_AbstractString extends ASN_Object implements Parseable {
     }

     protected function allowSmallLetters() {
-        for ($char='a'; $char <= 'z' ; $char++) { 
+        foreach (range('a', 'z') as $char) {
             $this->allowedCharacters[] = $char;
         }
     }

     protected function allowCapitalLetters() {    
-        for ($char='A'; $char <= 'Z' ; $char++) { 
+        foreach (range('A', 'Z') as $char) {
             $this->allowedCharacters[] = $char;
         }
     }

Remove a node

I can't remove(detach) last [1] (which is "[1] => FG\ASN1\ExplicitlyTaggedObject Object" ) how can I do this ? This file is too large, I can't make a new one...

FG\ASN1\Universal\Sequence Object
(
    [children:protected] => Array
        (
            [0] => FG\ASN1\Universal\ObjectIdentifier Object
                (
                    [subIdentifiers:protected] => Array
                        (
                            [1] => 42
                            [2] => 840
                            [3] => 113549
                            [4] => 1
                            [5] => 7
                            [6] => 2
                        )

                    [value:protected] => 1.2.840.113549.1.7.2
                    [contentLength:FG\ASN1\ASNObject:private] => 9
                    [nrOfLengthOctets:FG\ASN1\ASNObject:private] => 1
                )

            [1] => FG\ASN1\ExplicitlyTaggedObject Object
                (
                    [decoratedObjects:FG\ASN1\ExplicitlyTaggedObject:private] => Array
                        (
                            [0] => FG\ASN1\Universal\Sequence Object
                                (
                                    [children:protected] => Array
                                        (
                                            [0] => FG\ASN1\Universal\Integer Object
                                                (
                                                    [value:FG\ASN1\Universal\Integer:private] => 1
                                                    [contentLength:FG\ASN1\ASNObject:private] => 1
                                                    [nrOfLengthOctets:FG\ASN1\ASNObject:private] => 1
                                                )

                                            [1] => FG\ASN1\Universal\Set Object
                                                (
                                                    [children:protected] => Array
                                                        (
                                                            [0] => FG\ASN1\Universal\Sequence Object
                                                                (
                                                                    [children:protected] => Array
                                                                        (
                                                                            [0] => FG\ASN1\Universal\ObjectIdentifier Object
                                                                                (
                                                                                    [subIdentifiers:protected] => Array
                                                                                        (
                                                                                            [1] => 96
                                                                                            [2] => 840
                                                                                            [3] => 1
                                                                                            [4] => 101
                                                                                            [5] => 3
                                                                                            [6] => 4
                                                                                            [7] => 2
                                                                                            [8] => 1
                                                                                        )

                                                                                    [value:protected] => 2.16.840.1.101.3.4.2.1
                                                                                    [contentLength:FG\ASN1\ASNObject:private] => 9
                                                                                    [nrOfLengthOctets:FG\ASN1\ASNObject:private] => 1
                                                                                )

                                                                        )

                                                                    [iteratorPosition:FG\ASN1\Construct:private] => 0
                                                                    [contentLength:FG\ASN1\ASNObject:private] => 11
                                                                    [nrOfLengthOctets:FG\ASN1\ASNObject:private] => 1
                                                                )

                                                        )

                                                    [iteratorPosition:FG\ASN1\Construct:private] => 0
                                                    [contentLength:FG\ASN1\ASNObject:private] => 13
                                                    [nrOfLengthOctets:FG\ASN1\ASNObject:private] => 1
                                                )

                                            [2] => FG\ASN1\Universal\Sequence Object
                                                (
                                                    [children:protected] => Array
                                                        (
                                                            [0] => FG\ASN1\Universal\ObjectIdentifier Object
                                                                (
                                                                    [subIdentifiers:protected] => Array
                                                                        (
                                                                            [1] => 42
                                                                            [2] => 840
                                                                            [3] => 113549
                                                                            [4] => 1
                                                                            [5] => 7
                                                                            [6] => 1
                                                                        )

                                                                    [value:protected] => 1.2.840.113549.1.7.1
                                                                    [contentLength:FG\ASN1\ASNObject:private] => 9
                                                                    [nrOfLengthOctets:FG\ASN1\ASNObject:private] => 1
                                                                )

                                                            [1] => FG\ASN1\ExplicitlyTaggedObject Object
                                                                (
                                                                    [decoratedObjects:FG\ASN1\ExplicitlyTaggedObject:private] => Array
                                                                        (
                                                                            [0] => FG\ASN1\Universal\OctetSt.................................

Make Autoloader caching optional

Currently the caching is done if the user wants this or not..
It may be useful to disable caching, for example if the script has no write access to the cache folder or cache folder can not be created

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.