summaryrefslogtreecommitdiffstats
path: root/vendor/fgrosse/phpasn1/lib/X509
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2022-01-11 12:35:47 +0100
committerAnton Luka Šijanec <anton@sijanec.eu>2022-01-11 12:35:47 +0100
commit19985dbb8c0aa66dc4bf7905abc1148de909097d (patch)
tree2cd5a5d20d7e80fc2a51adf60d838d8a2c40999e /vendor/fgrosse/phpasn1/lib/X509
download1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.gz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.bz2
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.lz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.xz
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.tar.zst
1ka-19985dbb8c0aa66dc4bf7905abc1148de909097d.zip
Diffstat (limited to 'vendor/fgrosse/phpasn1/lib/X509')
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/AlgorithmIdentifier.php22
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/CSR/Attributes.php68
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/CSR/CSR.php159
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/CertificateExtensions.php100
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/CertificateSubject.php108
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/PrivateKey.php35
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/PublicKey.php35
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/SAN/DNSName.php28
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/SAN/IPAddress.php73
-rw-r--r--vendor/fgrosse/phpasn1/lib/X509/SAN/SubjectAlternativeNames.php96
10 files changed, 724 insertions, 0 deletions
diff --git a/vendor/fgrosse/phpasn1/lib/X509/AlgorithmIdentifier.php b/vendor/fgrosse/phpasn1/lib/X509/AlgorithmIdentifier.php
new file mode 100644
index 0000000..a06b56f
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/AlgorithmIdentifier.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509;
+
+use FG\ASN1\Universal\NullObject;
+use FG\ASN1\Composite\AttributeTypeAndValue;
+
+class AlgorithmIdentifier extends AttributeTypeAndValue
+{
+ public function __construct($objectIdentifierString)
+ {
+ parent::__construct($objectIdentifierString, new NullObject());
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/CSR/Attributes.php b/vendor/fgrosse/phpasn1/lib/X509/CSR/Attributes.php
new file mode 100644
index 0000000..5a965e2
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/CSR/Attributes.php
@@ -0,0 +1,68 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509\CSR;
+
+use FG\ASN1\ASNObject;
+use FG\X509\CertificateExtensions;
+use FG\ASN1\OID;
+use FG\ASN1\Parsable;
+use FG\ASN1\Construct;
+use FG\ASN1\Identifier;
+use FG\ASN1\Universal\Set;
+use FG\ASN1\Universal\Sequence;
+use FG\ASN1\Universal\ObjectIdentifier;
+
+class Attributes extends Construct implements Parsable
+{
+ public function getType()
+ {
+ return 0xA0;
+ }
+
+ public function addAttribute($objectIdentifier, Set $attribute)
+ {
+ if (is_string($objectIdentifier)) {
+ $objectIdentifier = new ObjectIdentifier($objectIdentifier);
+ }
+ $attributeSequence = new Sequence($objectIdentifier, $attribute);
+ $attributeSequence->getNumberOfLengthOctets(); // length and number of length octets is calculated
+ $this->addChild($attributeSequence);
+ }
+
+ public static function fromBinary(&$binaryData, &$offsetIndex = 0)
+ {
+ self::parseIdentifier($binaryData[$offsetIndex], 0xA0, $offsetIndex++);
+ $contentLength = self::parseContentLength($binaryData, $offsetIndex);
+ $octetsToRead = $contentLength;
+
+ $parsedObject = new self();
+ while ($octetsToRead > 0) {
+ $initialOffset = $offsetIndex; // used to calculate how much bits have been read
+ self::parseIdentifier($binaryData[$offsetIndex], Identifier::SEQUENCE, $offsetIndex++);
+ self::parseContentLength($binaryData, $offsetIndex);
+
+ $objectIdentifier = ObjectIdentifier::fromBinary($binaryData, $offsetIndex);
+ $oidString = $objectIdentifier->getContent();
+ if ($oidString == OID::PKCS9_EXTENSION_REQUEST) {
+ $attribute = CertificateExtensions::fromBinary($binaryData, $offsetIndex);
+ } else {
+ $attribute = ASNObject::fromBinary($binaryData, $offsetIndex);
+ }
+
+ $parsedObject->addAttribute($objectIdentifier, $attribute);
+ $octetsToRead -= ($offsetIndex - $initialOffset);
+ }
+
+ $parsedObject->setContentLength($contentLength);
+
+ return $parsedObject;
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/CSR/CSR.php b/vendor/fgrosse/phpasn1/lib/X509/CSR/CSR.php
new file mode 100644
index 0000000..53f9aeb
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/CSR/CSR.php
@@ -0,0 +1,159 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509\CSR;
+
+use FG\ASN1\OID;
+use FG\ASN1\Universal\Integer;
+use FG\ASN1\Universal\BitString;
+use FG\ASN1\Universal\Sequence;
+use FG\X509\CertificateSubject;
+use FG\X509\AlgorithmIdentifier;
+use FG\X509\PublicKey;
+
+class CSR extends Sequence
+{
+ const CSR_VERSION_NR = 0;
+
+ protected $subject;
+ protected $publicKey;
+ protected $signature;
+ protected $signatureAlgorithm;
+
+ protected $startSequence;
+
+ /**
+ * @param string $commonName
+ * @param string $email
+ * @param string $organization
+ * @param string $locality
+ * @param string $state
+ * @param string $country
+ * @param string $organizationalUnit
+ * @param string $publicKey
+ * @param string $signature
+ * @param string $signatureAlgorithm
+ */
+ public function __construct($commonName, $email, $organization, $locality, $state, $country, $organizationalUnit, $publicKey, $signature = null, $signatureAlgorithm = OID::SHA1_WITH_RSA_SIGNATURE)
+ {
+ $this->subject = new CertificateSubject(
+ $commonName,
+ $email,
+ $organization,
+ $locality,
+ $state,
+ $country,
+ $organizationalUnit
+ );
+ $this->publicKey = $publicKey;
+ $this->signature = $signature;
+ $this->signatureAlgorithm = $signatureAlgorithm;
+
+ if (isset($signature)) {
+ $this->createCSRSequence();
+ }
+ }
+
+ protected function createCSRSequence()
+ {
+ $versionNr = new Integer(self::CSR_VERSION_NR);
+ $publicKey = new PublicKey($this->publicKey);
+ $signature = new BitString($this->signature);
+ $signatureAlgorithm = new AlgorithmIdentifier($this->signatureAlgorithm);
+
+ $certRequestInfo = new Sequence($versionNr, $this->subject, $publicKey);
+
+ // Clear the underlying Construct
+ $this->rewind();
+ $this->children = [];
+ $this->addChild($certRequestInfo);
+ $this->addChild($signatureAlgorithm);
+ $this->addChild($signature);
+ }
+
+ public function getSignatureSubject()
+ {
+ $versionNr = new Integer(self::CSR_VERSION_NR);
+ $publicKey = new PublicKey($this->publicKey);
+
+ $certRequestInfo = new Sequence($versionNr, $this->subject, $publicKey);
+ return $certRequestInfo->getBinary();
+ }
+
+ public function setSignature($signature, $signatureAlgorithm = OID::SHA1_WITH_RSA_SIGNATURE)
+ {
+ $this->signature = $signature;
+ $this->signatureAlgorithm = $signatureAlgorithm;
+
+ $this->createCSRSequence();
+ }
+
+ public function __toString()
+ {
+ $tmp = base64_encode($this->getBinary());
+
+ for ($i = 0; $i < strlen($tmp); $i++) {
+ if (($i + 2) % 65 == 0) {
+ $tmp = substr($tmp, 0, $i + 1)."\n".substr($tmp, $i + 1);
+ }
+ }
+
+ $result = '-----BEGIN CERTIFICATE REQUEST-----'.PHP_EOL;
+ $result .= $tmp.PHP_EOL;
+ $result .= '-----END CERTIFICATE REQUEST-----';
+
+ return $result;
+ }
+
+ public function getVersion()
+ {
+ return self::CSR_VERSION_NR;
+ }
+
+ public function getOrganizationName()
+ {
+ return $this->subject->getOrganization();
+ }
+
+ public function getLocalName()
+ {
+ return $this->subject->getLocality();
+ }
+
+ public function getState()
+ {
+ return $this->subject->getState();
+ }
+
+ public function getCountry()
+ {
+ return $this->subject->getCountry();
+ }
+
+ public function getOrganizationalUnit()
+ {
+ return $this->subject->getOrganizationalUnit();
+ }
+
+ public function getPublicKey()
+ {
+ return $this->publicKey;
+ }
+
+ public function getSignature()
+ {
+ return $this->signature;
+ }
+
+ public function getSignatureAlgorithm()
+ {
+ return $this->signatureAlgorithm;
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/CertificateExtensions.php b/vendor/fgrosse/phpasn1/lib/X509/CertificateExtensions.php
new file mode 100644
index 0000000..6ed1c6a
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/CertificateExtensions.php
@@ -0,0 +1,100 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509;
+
+use FG\ASN1\Exception\ParserException;
+use FG\ASN1\OID;
+use FG\ASN1\ASNObject;
+use FG\ASN1\Parsable;
+use FG\ASN1\Identifier;
+use FG\ASN1\Universal\OctetString;
+use FG\ASN1\Universal\Set;
+use FG\ASN1\Universal\Sequence;
+use FG\ASN1\Universal\ObjectIdentifier;
+use FG\X509\SAN\SubjectAlternativeNames;
+
+class CertificateExtensions extends Set implements Parsable
+{
+ private $innerSequence;
+ private $extensions = [];
+
+ public function __construct()
+ {
+ $this->innerSequence = new Sequence();
+ parent::__construct($this->innerSequence);
+ }
+
+ public function addSubjectAlternativeNames(SubjectAlternativeNames $sans)
+ {
+ $this->addExtension(OID::CERT_EXT_SUBJECT_ALT_NAME, $sans);
+ }
+
+ private function addExtension($oidString, ASNObject $extension)
+ {
+ $sequence = new Sequence();
+ $sequence->addChild(new ObjectIdentifier($oidString));
+ $sequence->addChild($extension);
+
+ $this->innerSequence->addChild($sequence);
+ $this->extensions[] = $extension;
+ }
+
+ public function getContent()
+ {
+ return $this->extensions;
+ }
+
+ public static function fromBinary(&$binaryData, &$offsetIndex = 0)
+ {
+ self::parseIdentifier($binaryData[$offsetIndex], Identifier::SET, $offsetIndex++);
+ self::parseContentLength($binaryData, $offsetIndex);
+
+ $tmpOffset = $offsetIndex;
+ $extensions = Sequence::fromBinary($binaryData, $offsetIndex);
+ $tmpOffset += 1 + $extensions->getNumberOfLengthOctets();
+
+ $parsedObject = new self();
+ foreach ($extensions as $extension) {
+ if ($extension->getType() != Identifier::SEQUENCE) {
+ //FIXME wrong offset index
+ throw new ParserException('Could not parse Certificate Extensions: Expected ASN.1 Sequence but got '.$extension->getTypeName(), $offsetIndex);
+ }
+
+ $tmpOffset += 1 + $extension->getNumberOfLengthOctets();
+ $children = $extension->getChildren();
+ if (count($children) < 2) {
+ throw new ParserException('Could not parse Certificate Extensions: Needs at least two child elements per extension sequence (object identifier and octet string)', $tmpOffset);
+ }
+ /** @var \FG\ASN1\ASNObject $objectIdentifier */
+ $objectIdentifier = $children[0];
+
+ /** @var OctetString $octetString */
+ $octetString = $children[1];
+
+ if ($objectIdentifier->getType() != Identifier::OBJECT_IDENTIFIER) {
+ throw new ParserException('Could not parse Certificate Extensions: Expected ASN.1 Object Identifier but got '.$extension->getTypeName(), $tmpOffset);
+ }
+
+ $tmpOffset += $objectIdentifier->getObjectLength();
+
+ if ($objectIdentifier->getContent() == OID::CERT_EXT_SUBJECT_ALT_NAME) {
+ $sans = SubjectAlternativeNames::fromBinary($binaryData, $tmpOffset);
+ $parsedObject->addSubjectAlternativeNames($sans);
+ } else {
+ // can now only parse SANs. There might be more in the future
+ $tmpOffset += $octetString->getObjectLength();
+ }
+ }
+
+ $parsedObject->getBinary(); // Determine the number of content octets and object sizes once (just to let the equality unit tests pass :/ )
+ return $parsedObject;
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/CertificateSubject.php b/vendor/fgrosse/phpasn1/lib/X509/CertificateSubject.php
new file mode 100644
index 0000000..0a04d57
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/CertificateSubject.php
@@ -0,0 +1,108 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509;
+
+use FG\ASN1\Composite\RelativeDistinguishedName;
+use FG\ASN1\Identifier;
+use FG\ASN1\OID;
+use FG\ASN1\Parsable;
+use FG\ASN1\Composite\RDNString;
+use FG\ASN1\Universal\Sequence;
+
+class CertificateSubject extends Sequence implements Parsable
+{
+ private $commonName;
+ private $email;
+ private $organization;
+ private $locality;
+ private $state;
+ private $country;
+ private $organizationalUnit;
+
+ /**
+ * @param string $commonName
+ * @param string $email
+ * @param string $organization
+ * @param string $locality
+ * @param string $state
+ * @param string $country
+ * @param string $organizationalUnit
+ */
+ public function __construct($commonName, $email, $organization, $locality, $state, $country, $organizationalUnit)
+ {
+ parent::__construct(
+ new RDNString(OID::COUNTRY_NAME, $country),
+ new RDNString(OID::STATE_OR_PROVINCE_NAME, $state),
+ new RDNString(OID::LOCALITY_NAME, $locality),
+ new RDNString(OID::ORGANIZATION_NAME, $organization),
+ new RDNString(OID::OU_NAME, $organizationalUnit),
+ new RDNString(OID::COMMON_NAME, $commonName),
+ new RDNString(OID::PKCS9_EMAIL, $email)
+ );
+
+ $this->commonName = $commonName;
+ $this->email = $email;
+ $this->organization = $organization;
+ $this->locality = $locality;
+ $this->state = $state;
+ $this->country = $country;
+ $this->organizationalUnit = $organizationalUnit;
+ }
+
+ public function getCommonName()
+ {
+ return $this->commonName;
+ }
+
+ public function getEmail()
+ {
+ return $this->email;
+ }
+
+ public function getOrganization()
+ {
+ return $this->organization;
+ }
+
+ public function getLocality()
+ {
+ return $this->locality;
+ }
+
+ public function getState()
+ {
+ return $this->state;
+ }
+
+ public function getCountry()
+ {
+ return $this->country;
+ }
+
+ public function getOrganizationalUnit()
+ {
+ return $this->organizationalUnit;
+ }
+
+ public static function fromBinary(&$binaryData, &$offsetIndex = 0)
+ {
+ self::parseIdentifier($binaryData[$offsetIndex], Identifier::SEQUENCE, $offsetIndex++);
+ $contentLength = self::parseContentLength($binaryData, $offsetIndex);
+
+ $names = [];
+ $octetsToRead = $contentLength;
+ while ($octetsToRead > 0) {
+ $relativeDistinguishedName = RelativeDistinguishedName::fromBinary($binaryData, $offsetIndex);
+ $octetsToRead -= $relativeDistinguishedName->getObjectLength();
+ $names[] = $relativeDistinguishedName;
+ }
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/PrivateKey.php b/vendor/fgrosse/phpasn1/lib/X509/PrivateKey.php
new file mode 100644
index 0000000..d57ad86
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/PrivateKey.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509;
+
+use FG\ASN1\OID;
+use FG\ASN1\Universal\NullObject;
+use FG\ASN1\Universal\Sequence;
+use FG\ASN1\Universal\BitString;
+use FG\ASN1\Universal\ObjectIdentifier;
+
+class PrivateKey extends Sequence
+{
+ /**
+ * @param string $hexKey
+ * @param \FG\ASN1\ASNObject|string $algorithmIdentifierString
+ */
+ public function __construct($hexKey, $algorithmIdentifierString = OID::RSA_ENCRYPTION)
+ {
+ parent::__construct(
+ new Sequence(
+ new ObjectIdentifier($algorithmIdentifierString),
+ new NullObject()
+ ),
+ new BitString($hexKey)
+ );
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/PublicKey.php b/vendor/fgrosse/phpasn1/lib/X509/PublicKey.php
new file mode 100644
index 0000000..ab8b451
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/PublicKey.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509;
+
+use FG\ASN1\OID;
+use FG\ASN1\Universal\NullObject;
+use FG\ASN1\Universal\Sequence;
+use FG\ASN1\Universal\BitString;
+use FG\ASN1\Universal\ObjectIdentifier;
+
+class PublicKey extends Sequence
+{
+ /**
+ * @param string $hexKey
+ * @param \FG\ASN1\ASNObject|string $algorithmIdentifierString
+ */
+ public function __construct($hexKey, $algorithmIdentifierString = OID::RSA_ENCRYPTION)
+ {
+ parent::__construct(
+ new Sequence(
+ new ObjectIdentifier($algorithmIdentifierString),
+ new NullObject()
+ ),
+ new BitString($hexKey)
+ );
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/SAN/DNSName.php b/vendor/fgrosse/phpasn1/lib/X509/SAN/DNSName.php
new file mode 100644
index 0000000..502738b
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/SAN/DNSName.php
@@ -0,0 +1,28 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509\SAN;
+
+use FG\ASN1\Universal\GeneralString;
+
+class DNSName extends GeneralString
+{
+ const IDENTIFIER = 0x82; // not sure yet why this is the identifier used in SAN extensions
+
+ public function __construct($dnsNameString)
+ {
+ parent::__construct($dnsNameString);
+ }
+
+ public function getType()
+ {
+ return self::IDENTIFIER;
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/SAN/IPAddress.php b/vendor/fgrosse/phpasn1/lib/X509/SAN/IPAddress.php
new file mode 100644
index 0000000..f55be95
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/SAN/IPAddress.php
@@ -0,0 +1,73 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509\SAN;
+
+use FG\ASN1\ASNObject;
+use FG\ASN1\Parsable;
+use FG\ASN1\Exception\ParserException;
+
+class IPAddress extends ASNObject implements Parsable
+{
+ const IDENTIFIER = 0x87; // not sure yet why this is the identifier used in SAN extensions
+
+ /** @var string */
+ private $value;
+
+ public function __construct($ipAddressString)
+ {
+ $this->value = $ipAddressString;
+ }
+
+ public function getType()
+ {
+ return self::IDENTIFIER;
+ }
+
+ public function getContent()
+ {
+ return $this->value;
+ }
+
+ protected function calculateContentLength()
+ {
+ return 4;
+ }
+
+ protected function getEncodedValue()
+ {
+ $ipParts = explode('.', $this->value);
+ $binary = chr($ipParts[0]);
+ $binary .= chr($ipParts[1]);
+ $binary .= chr($ipParts[2]);
+ $binary .= chr($ipParts[3]);
+
+ return $binary;
+ }
+
+ public static function fromBinary(&$binaryData, &$offsetIndex = 0)
+ {
+ self::parseIdentifier($binaryData[$offsetIndex], self::IDENTIFIER, $offsetIndex++);
+ $contentLength = self::parseContentLength($binaryData, $offsetIndex);
+ if ($contentLength != 4) {
+ throw new ParserException("A FG\\X509\SAN\IPAddress should have a content length of 4. Extracted length was {$contentLength}", $offsetIndex);
+ }
+
+ $ipAddressString = ord($binaryData[$offsetIndex++]).'.';
+ $ipAddressString .= ord($binaryData[$offsetIndex++]).'.';
+ $ipAddressString .= ord($binaryData[$offsetIndex++]).'.';
+ $ipAddressString .= ord($binaryData[$offsetIndex++]);
+
+ $parsedObject = new self($ipAddressString);
+ $parsedObject->getObjectLength();
+
+ return $parsedObject;
+ }
+}
diff --git a/vendor/fgrosse/phpasn1/lib/X509/SAN/SubjectAlternativeNames.php b/vendor/fgrosse/phpasn1/lib/X509/SAN/SubjectAlternativeNames.php
new file mode 100644
index 0000000..271ddde
--- /dev/null
+++ b/vendor/fgrosse/phpasn1/lib/X509/SAN/SubjectAlternativeNames.php
@@ -0,0 +1,96 @@
+<?php
+/*
+ * This file is part of the PHPASN1 library.
+ *
+ * Copyright © Friedrich Große <friedrich.grosse@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace FG\X509\SAN;
+
+use FG\ASN1\Exception\ParserException;
+use FG\ASN1\ASNObject;
+use FG\ASN1\OID;
+use FG\ASN1\Parsable;
+use FG\ASN1\Identifier;
+use FG\ASN1\Universal\Sequence;
+
+/**
+ * See section 8.3.2.1 of ITU-T X.509.
+ */
+class SubjectAlternativeNames extends ASNObject implements Parsable
+{
+ private $alternativeNamesSequence;
+
+ public function __construct()
+ {
+ $this->alternativeNamesSequence = new Sequence();
+ }
+
+ protected function calculateContentLength()
+ {
+ return $this->alternativeNamesSequence->getObjectLength();
+ }
+
+ public function getType()
+ {
+ return Identifier::OCTETSTRING;
+ }
+
+ public function addDomainName(DNSName $domainName)
+ {
+ $this->alternativeNamesSequence->addChild($domainName);
+ }
+
+ public function addIP(IPAddress $ip)
+ {
+ $this->alternativeNamesSequence->addChild($ip);
+ }
+
+ public function getContent()
+ {
+ return $this->alternativeNamesSequence->getContent();
+ }
+
+ protected function getEncodedValue()
+ {
+ return $this->alternativeNamesSequence->getBinary();
+ }
+
+ public static function fromBinary(&$binaryData, &$offsetIndex = 0)
+ {
+ self::parseIdentifier($binaryData[$offsetIndex], Identifier::OCTETSTRING, $offsetIndex++);
+ $contentLength = self::parseContentLength($binaryData, $offsetIndex);
+
+ if ($contentLength < 2) {
+ throw new ParserException('Can not parse Subject Alternative Names: The Sequence within the octet string after the Object identifier '.OID::CERT_EXT_SUBJECT_ALT_NAME." is too short ({$contentLength} octets)", $offsetIndex);
+ }
+
+ $offsetOfSequence = $offsetIndex;
+ $sequence = Sequence::fromBinary($binaryData, $offsetIndex);
+ $offsetOfSequence += $sequence->getNumberOfLengthOctets() + 1;
+
+ if ($sequence->getObjectLength() != $contentLength) {
+ throw new ParserException('Can not parse Subject Alternative Names: The Sequence length does not match the length of the surrounding octet string', $offsetIndex);
+ }
+
+ $parsedObject = new self();
+ /** @var \FG\ASN1\ASNObject $object */
+ foreach ($sequence as $object) {
+ if ($object->getType() == DNSName::IDENTIFIER) {
+ $domainName = DNSName::fromBinary($binaryData, $offsetOfSequence);
+ $parsedObject->addDomainName($domainName);
+ } elseif ($object->getType() == IPAddress::IDENTIFIER) {
+ $ip = IPAddress::fromBinary($binaryData, $offsetOfSequence);
+ $parsedObject->addIP($ip);
+ } else {
+ throw new ParserException('Could not parse Subject Alternative Name: Only DNSName and IP SANs are currently supported', $offsetIndex);
+ }
+ }
+
+ $parsedObject->getBinary(); // Determine the number of content octets and object sizes once (just to let the equality unit tests pass :/ )
+ return $parsedObject;
+ }
+}