File manager - Edit - /home/opticamezl/www/newok/ASN1.tar
Back
Construct.php 0000644 00000011167 15176121033 0007246 0 ustar 00 <?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\ASN1; use ArrayAccess; use ArrayIterator; use Countable; use FG\ASN1\Exception\ParserException; use Iterator; abstract class Construct extends ASNObject implements Countable, ArrayAccess, Iterator, Parsable { /** @var \FG\ASN1\ASNObject[] */ protected $children; private $iteratorPosition; /** * @param \FG\ASN1\ASNObject[] $children the variadic type hint is commented due to https://github.com/facebook/hhvm/issues/4858 */ public function __construct(/* HH_FIXME[4858]: variadic + strict */ ...$children) { $this->children = $children; $this->iteratorPosition = 0; } public function getContent() { return $this->children; } #[\ReturnTypeWillChange] public function rewind() { $this->iteratorPosition = 0; } #[\ReturnTypeWillChange] public function current() { return $this->children[$this->iteratorPosition]; } #[\ReturnTypeWillChange] public function key() { return $this->iteratorPosition; } #[\ReturnTypeWillChange] public function next() { $this->iteratorPosition++; } #[\ReturnTypeWillChange] public function valid() { return isset($this->children[$this->iteratorPosition]); } #[\ReturnTypeWillChange] public function offsetExists($offset) { return array_key_exists($offset, $this->children); } #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->children[$offset]; } #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if ($offset === null) { $offset = count($this->children); } $this->children[$offset] = $value; } #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->children[$offset]); } protected function calculateContentLength() { $length = 0; foreach ($this->children as $component) { $length += $component->getObjectLength(); } return $length; } protected function getEncodedValue() { $result = ''; foreach ($this->children as $component) { $result .= $component->getBinary(); } return $result; } public function addChild(ASNObject $child) { $this->children[] = $child; } public function addChildren(array $children) { foreach ($children as $child) { $this->addChild($child); } } public function __toString() { $nrOfChildren = $this->getNumberOfChildren(); $childString = $nrOfChildren == 1 ? 'child' : 'children'; return "[{$nrOfChildren} {$childString}]"; } public function getNumberOfChildren() { return count($this->children); } /** * @return \FG\ASN1\ASNObject[] */ public function getChildren() { return $this->children; } /** * @return \FG\ASN1\ASNObject */ public function getFirstChild() { return $this->children[0]; } /** * @param string $binaryData * @param int $offsetIndex * * @throws Exception\ParserException * * @return Construct|static */ #[\ReturnTypeWillChange] public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $parsedObject = new static(); self::parseIdentifier($binaryData[$offsetIndex], $parsedObject->getType(), $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $startIndex = $offsetIndex; $children = []; $octetsToRead = $contentLength; while ($octetsToRead > 0) { $newChild = ASNObject::fromBinary($binaryData, $offsetIndex); $octetsToRead -= $newChild->getObjectLength(); $children[] = $newChild; } if ($octetsToRead !== 0) { throw new ParserException("Sequence length incorrect", $startIndex); } $parsedObject->addChildren($children); $parsedObject->setContentLength($contentLength); return $parsedObject; } #[\ReturnTypeWillChange] public function count($mode = COUNT_NORMAL) { return count($this->children, $mode); } public function getIterator() { return new ArrayIterator($this->children); } } AbstractString.php 0000644 00000006505 15176121033 0010214 0 ustar 00 <?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\ASN1; use Exception; abstract class AbstractString extends ASNObject implements Parsable { /** @var string */ protected $value; private $checkStringForIllegalChars = true; private $allowedCharacters = []; /** * The abstract base class for ASN.1 classes which represent some string of character. * * @param string $string */ public function __construct($string) { $this->value = $string; } public function getContent() { return $this->value; } protected function allowCharacter($character) { $this->allowedCharacters[] = $character; } protected function allowCharacters(...$characters) { foreach ($characters as $character) { $this->allowedCharacters[] = $character; } } protected function allowNumbers() { foreach (range('0', '9') as $char) { $this->allowedCharacters[] = (string) $char; } } protected function allowAllLetters() { $this->allowSmallLetters(); $this->allowCapitalLetters(); } protected function allowSmallLetters() { foreach (range('a', 'z') as $char) { $this->allowedCharacters[] = $char; } } protected function allowCapitalLetters() { foreach (range('A', 'Z') as $char) { $this->allowedCharacters[] = $char; } } protected function allowSpaces() { $this->allowedCharacters[] = ' '; } protected function allowAll() { $this->checkStringForIllegalChars = false; } protected function calculateContentLength() { return strlen($this->value); } protected function getEncodedValue() { if ($this->checkStringForIllegalChars) { $this->checkString(); } return $this->value; } protected function checkString() { $stringLength = $this->getContentLength(); for ($i = 0; $i < $stringLength; $i++) { if (in_array($this->value[$i], $this->allowedCharacters) == false) { $typeName = Identifier::getName($this->getType()); throw new Exception("Could not create a {$typeName} from the character sequence '{$this->value}'."); } } } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $parsedObject = new static(''); self::parseIdentifier($binaryData[$offsetIndex], $parsedObject->getType(), $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $string = substr($binaryData, $offsetIndex, $contentLength); $offsetIndex += $contentLength; $parsedObject->value = $string; $parsedObject->setContentLength($contentLength); return $parsedObject; } public static function isValid($string) { $testObject = new static($string); try { $testObject->checkString(); return true; } catch (Exception $exception) { return false; } } } Base128.php 0000644 00000002715 15176121033 0006366 0 ustar 00 <?php namespace FG\ASN1; use FG\Utility\BigInteger; use InvalidArgumentException; /** * A base-128 decoder. */ class Base128 { /** * @param int $value * * @return string */ public static function encode($value) { $value = BigInteger::create($value); $octets = chr($value->modulus(0x80)->toInteger()); $value = $value->shiftRight(7); while ($value->compare(0) > 0) { $octets .= chr(0x80 | $value->modulus(0x80)->toInteger()); $value = $value->shiftRight(7); } return strrev($octets); } /** * @param string $octets * * @throws InvalidArgumentException if the given octets represent a malformed base-128 value or the decoded value would exceed the the maximum integer length * * @return int */ public static function decode($octets) { $bitsPerOctet = 7; $value = BigInteger::create(0); $i = 0; while (true) { if (!isset($octets[$i])) { throw new InvalidArgumentException(sprintf('Malformed base-128 encoded value (0x%s).', strtoupper(bin2hex($octets)) ?: '0')); } $octet = ord($octets[$i++]); $l1 = $value->shiftLeft($bitsPerOctet); $r1 = $octet & 0x7f; $value = $l1->add($r1); if (0 === ($octet & 0x80)) { break; } } return (string)$value; } } Composite/AttributeTypeAndValue.php 0000644 00000001626 15176121033 0013450 0 ustar 00 <?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\ASN1\Composite; use FG\ASN1\ASNObject; use FG\ASN1\Universal\Sequence; use FG\ASN1\Universal\ObjectIdentifier; class AttributeTypeAndValue extends Sequence { /** * @param ObjectIdentifier|string $objIdentifier * @param \FG\ASN1\ASNObject $value */ public function __construct($objIdentifier, ASNObject $value) { if ($objIdentifier instanceof ObjectIdentifier == false) { $objIdentifier = new ObjectIdentifier($objIdentifier); } parent::__construct($objIdentifier, $value); } public function __toString() { return $this->children[0].': '.$this->children[1]; } } Composite/RDNString.php 0000644 00000002010 15176121033 0011021 0 ustar 00 <?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\ASN1\Composite; use FG\ASN1\Universal\PrintableString; use FG\ASN1\Universal\IA5String; use FG\ASN1\Universal\UTF8String; class RDNString extends RelativeDistinguishedName { /** * @param string|\FG\ASN1\Universal\ObjectIdentifier $objectIdentifierString * @param string|\FG\ASN1\ASNObject $value */ public function __construct($objectIdentifierString, $value) { if (PrintableString::isValid($value)) { $value = new PrintableString($value); } else { if (IA5String::isValid($value)) { $value = new IA5String($value); } else { $value = new UTF8String($value); } } parent::__construct($objectIdentifierString, $value); } } Composite/RelativeDistinguishedName.php 0000644 00000003152 15176121033 0014317 0 ustar 00 <?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\ASN1\Composite; use FG\ASN1\Exception\NotImplementedException; use FG\ASN1\ASNObject; use FG\ASN1\Universal\Set; class RelativeDistinguishedName extends Set { /** * @param string|\FG\ASN1\Universal\ObjectIdentifier $objIdentifierString * @param \FG\ASN1\ASNObject $value */ public function __construct($objIdentifierString, ASNObject $value) { // TODO: This does only support one element in the RelativeDistinguishedName Set but it it is defined as follows: // RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue parent::__construct(new AttributeTypeAndValue($objIdentifierString, $value)); } public function getContent() { /** @var \FG\ASN1\ASNObject $firstObject */ $firstObject = $this->children[0]; return $firstObject->__toString(); } /** * At the current version this code can not work since the implementation of Construct requires * the class to support a constructor without arguments. * * @deprecated this function is not yet implemented! Feel free to submit a pull request on github * @param string $binaryData * @param int $offsetIndex * @throws NotImplementedException */ public static function fromBinary(&$binaryData, &$offsetIndex = 0) { throw new NotImplementedException(); } } TemplateParser.php 0000644 00000003577 15176121033 0010220 0 ustar 00 <?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\ASN1; use Exception; use FG\ASN1\Exception\ParserException; use FG\ASN1\Universal\Sequence; class TemplateParser { /** * @param string $data * @param array $template * @return \FG\ASN1\ASNObject|Sequence * @throws ParserException if there was an issue parsing */ public function parseBase64($data, array $template) { // TODO test with invalid data return $this->parseBinary(base64_decode($data), $template); } /** * @param string $binary * @param array $template * @return \FG\ASN1\ASNObject|Sequence * @throws ParserException if there was an issue parsing */ public function parseBinary($binary, array $template) { $parsedObject = ASNObject::fromBinary($binary); foreach ($template as $key => $value) { $this->validate($parsedObject, $key, $value); } return $parsedObject; } private function validate(ASNObject $object, $key, $value) { if (is_array($value)) { $this->assertTypeId($key, $object); /* @var Construct $object */ foreach ($value as $key => $child) { $this->validate($object->current(), $key, $child); $object->next(); } } else { $this->assertTypeId($value, $object); } } private function assertTypeId($expectedTypeId, ASNObject $object) { $actualType = $object->getType(); if ($expectedTypeId != $actualType) { throw new Exception("Expected type ($expectedTypeId) does not match actual type ($actualType"); } } } OID.php 0000644 00000152412 15176121033 0005674 0 ustar 00 <?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\ASN1; class OID { const RSA_ENCRYPTION = '1.2.840.113549.1.1.1'; const MD5_WITH_RSA_ENCRYPTION = '1.2.840.113549.1.1.4'; const SHA1_WITH_RSA_SIGNATURE = '1.2.840.113549.1.1.5'; const SHA256_WITH_RSA_SIGNATURE = '1.2.840.113549.1.1.11'; const PKCS9_EMAIL = '1.2.840.113549.1.9.1'; const PKCS9_UNSTRUCTURED_NAME = '1.2.840.113549.1.9.2'; const PKCS9_CONTENT_TYPE = '1.2.840.113549.1.9.3'; const PKCS9_MESSAGE_DIGEST = '1.2.840.113549.1.9.4'; const PKCS9_SIGNING_TIME = '1.2.840.113549.1.9.5'; const PKCS9_EXTENSION_REQUEST = '1.2.840.113549.1.9.14'; // certificate extension identifier const CERT_EXT_SUBJECT_DIRECTORY_ATTR = '2.5.29.9'; const CERT_EXT_SUBJECT_KEY_IDENTIFIER = '2.5.29.14'; const CERT_EXT_KEY_USAGE = '2.5.29.15'; const CERT_EXT_PRIVATE_KEY_USAGE_PERIOD = '2.5.29.16'; const CERT_EXT_SUBJECT_ALT_NAME = '2.5.29.17'; const CERT_EXT_ISSUER_ALT_NAME = '2.5.29.18'; const CERT_EXT_BASIC_CONSTRAINTS = '2.5.29.19'; const CERT_EXT_CRL_NUMBER = '2.5.29.20'; const CERT_EXT_REASON_CODE = '2.5.29.21'; const CERT_EXT_INVALIDITY_DATE = '2.5.29.24'; const CERT_EXT_DELTA_CRL_INDICATOR = '2.5.29.27'; const CERT_EXT_ISSUING_DIST_POINT = '2.5.29.28'; const CERT_EXT_CERT_ISSUER = '2.5.29.29'; const CERT_EXT_NAME_CONSTRAINTS = '2.5.29.30'; const CERT_EXT_CRL_DISTRIBUTION_POINTS = '2.5.29.31'; const CERT_EXT_CERT_POLICIES = '2.5.29.32'; const CERT_EXT_AUTHORITY_KEY_IDENTIFIER = '2.5.29.35'; const CERT_EXT_EXTENDED_KEY_USAGE = '2.5.29.37'; // standard certificate files const COMMON_NAME = '2.5.4.3'; const SURNAME = '2.5.4.4'; const SERIAL_NUMBER = '2.5.4.5'; const COUNTRY_NAME = '2.5.4.6'; const LOCALITY_NAME = '2.5.4.7'; const STATE_OR_PROVINCE_NAME = '2.5.4.8'; const STREET_ADDRESS = '2.5.4.9'; const ORGANIZATION_NAME = '2.5.4.10'; const OU_NAME = '2.5.4.11'; const TITLE = '2.5.4.12'; const DESCRIPTION = '2.5.4.13'; const POSTAL_ADDRESS = '2.5.4.16'; const POSTAL_CODE = '2.5.4.17'; const AUTHORITY_REVOCATION_LIST = '2.5.4.38'; const AUTHORITY_INFORMATION_ACCESS = '1.3.6.1.5.5.7.1.1'; /** * Returns the name of the given object identifier. * * Some OIDs are saved as class constants in this class. * If the wanted oidString is not among them, this method will * query http://oid-info.com for the right name. * This behavior can be suppressed by setting the second method parameter to false. * * @param string $oidString * @param bool $loadFromWeb * * @see self::loadFromWeb($oidString) * * @return string */ public static function getName($oidString, $loadFromWeb = true) { $oids = [ '1.2' => 'ISO Member Body', '1.3' => 'org', '1.3.6.1.5.5.8.1.1' => 'hmac-md5', '1.3.6.1.5.5.8.1.2' => 'hmac-sha1', '1.3.132' => 'certicom-arc', '2.23' => 'International Organizations', '2.23.43' => 'wap', '2.23.43.1' => 'wap-wsg', '2.5.1.5' => 'Selected Attribute Types', '2.5.1.5.55' => 'clearance', '1.2.840' => 'ISO US Member Body', '1.2.840.10040' => 'X9.57', '1.2.840.10040.4' => 'X9.57 CM ?', '1.2.840.10040.4.1' => 'dsaEncryption', '1.2.840.10040.4.3' => 'dsaWithSHA1', '1.2.840.10045' => 'ANSI X9.62', '1.2.840.10045.1' => 'X9-62_id-fieldType', '1.2.840.10045.1.1' => 'X9-62_prime-field', '1.2.840.10045.1.2' => 'X9-62_characteristic-two-field', '1.2.840.10045.1.2.3' => 'X9-62_id-characteristic-two-basis', '1.2.840.10045.1.2.3.1' => 'X9-62_onBasis', '1.2.840.10045.1.2.3.2' => 'X9-62_tpBasis', '1.2.840.10045.1.2.3.3' => 'X9-62_ppBasis', '1.2.840.10045.2' => 'X9-62_id-publicKeyType', '1.2.840.10045.2.1' => 'X9-62_id-ecPublicKey', '1.2.840.10045.3' => 'X9-62_ellipticCurve', '1.2.840.10045.3.0' => 'X9-62_c-TwoCurve', '1.2.840.10045.3.0.1' => 'X9-62_c2pnb163v1', '1.2.840.10045.3.0.2' => 'X9-62_c2pnb163v2', '1.2.840.10045.3.0.3' => 'X9-62_c2pnb163v3', '1.2.840.10045.3.0.4' => 'X9-62_c2pnb176v1', '1.2.840.10045.3.0.5' => 'X9-62_c2tnb191v1', '1.2.840.10045.3.0.6' => 'X9-62_c2tnb191v2', '1.2.840.10045.3.0.7' => 'X9-62_c2tnb191v3', '1.2.840.10045.3.0.8' => 'X9-62_c2onb191v4', '1.2.840.10045.3.0.9' => 'X9-62_c2onb191v5', '1.2.840.10045.3.0.10' => 'X9-62_c2pnb208w1', '1.2.840.10045.3.0.11' => 'X9-62_c2tnb239v1', '1.2.840.10045.3.0.12' => 'X9-62_c2tnb239v2', '1.2.840.10045.3.0.13' => 'X9-62_c2tnb239v3', '1.2.840.10045.3.0.14' => 'X9-62_c2onb239v4', '1.2.840.10045.3.0.15' => 'X9-62_c2onb239v5', '1.2.840.10045.3.0.16' => 'X9-62_c2pnb272w1', '1.2.840.10045.3.0.17' => 'X9-62_c2pnb304w1', '1.2.840.10045.3.0.18' => 'X9-62_c2tnb359v1', '1.2.840.10045.3.0.19' => 'X9-62_c2pnb368w1', '1.2.840.10045.3.0.20' => 'X9-62_c2tnb431r1', '1.2.840.10045.3.1' => 'X9-62_primeCurve', '1.2.840.10045.3.1.1' => 'X9-62_prime192v1', '1.2.840.10045.3.1.2' => 'X9-62_prime192v2', '1.2.840.10045.3.1.3' => 'X9-62_prime192v3', '1.2.840.10045.3.1.4' => 'X9-62_prime239v1', '1.2.840.10045.3.1.5' => 'X9-62_prime239v2', '1.2.840.10045.3.1.6' => 'X9-62_prime239v3', '1.2.840.10045.3.1.7' => 'X9-62_prime256v1', '1.2.840.10045.4' => 'X9-62_id-ecSigType', '1.2.840.10045.4.1' => 'ecdsa-with-SHA1', '1.2.840.10045.4.2' => 'ecdsa-with-Recommended', '1.2.840.10045.4.3' => 'ecdsa-with-Specified', '1.2.840.10045.4.3.1' => 'ecdsa-with-SHA224', '1.2.840.10045.4.3.2' => 'ecdsa-with-SHA256', '1.2.840.10045.4.3.3' => 'ecdsa-with-SHA384', '1.2.840.10045.4.3.4' => 'ecdsa-with-SHA512', '1.3.132.0' => 'secg_ellipticCurve', '2.23.43.1.4' => 'wap-wsg-idm-ecid', '2.23.43.1.4.1' => 'wap-wsg-idm-ecid-wtls1', '2.23.43.1.4.3' => 'wap-wsg-idm-ecid-wtls3', '2.23.43.1.4.4' => 'wap-wsg-idm-ecid-wtls4', '2.23.43.1.4.5' => 'wap-wsg-idm-ecid-wtls5', '2.23.43.1.4.6' => 'wap-wsg-idm-ecid-wtls6', '2.23.43.1.4.7' => 'wap-wsg-idm-ecid-wtls7', '2.23.43.1.4.8' => 'wap-wsg-idm-ecid-wtls8', '2.23.43.1.4.9' => 'wap-wsg-idm-ecid-wtls9', '2.23.43.1.4.10' => 'wap-wsg-idm-ecid-wtls10', '2.23.43.1.4.11' => 'wap-wsg-idm-ecid-wtls11', '2.23.43.1.4.12' => 'wap-wsg-idm-ecid-wtls12', '1.2.840.113533.7.66.10' => 'cast5-cbc', '1.2.840.113533.7.66.12' => 'pbeWithMD5AndCast5CBC', '1.2.840.113533.7.66.13' => 'password based MAC', '1.2.840.113533.7.66.30' => 'Diffie-Hellman based MAC', '1.2.840.113549' => 'RSA Data Security, Inc.', '1.2.840.113549.1' => 'RSA Data Security, Inc. PKCS', '1.2.840.113549.1.1' => 'pkcs1', '1.2.840.113549.1.1.1' => 'rsaEncryption', '1.2.840.113549.1.1.2' => 'md2WithRSAEncryption', '1.2.840.113549.1.1.3' => 'md4WithRSAEncryption', '1.2.840.113549.1.1.4' => 'md5WithRSAEncryption', '1.2.840.113549.1.1.5' => 'sha1WithRSAEncryption', '1.2.840.113549.1.1.7' => 'rsaesOaep', '1.2.840.113549.1.1.8' => 'mgf1', '1.2.840.113549.1.1.9' => 'pSpecified', '1.2.840.113549.1.1.10' => 'rsassaPss', '1.2.840.113549.1.1.11' => 'sha256WithRSAEncryption', '1.2.840.113549.1.1.12' => 'sha384WithRSAEncryption', '1.2.840.113549.1.1.13' => 'sha512WithRSAEncryption', '1.2.840.113549.1.1.14' => 'sha224WithRSAEncryption', '1.2.840.113549.1.3' => 'pkcs3', '1.2.840.113549.1.3.1' => 'dhKeyAgreement', '1.2.840.113549.1.5' => 'pkcs5', '1.2.840.113549.1.5.1' => 'pbeWithMD2AndDES-CBC', '1.2.840.113549.1.5.3' => 'pbeWithMD5AndDES-CBC', '1.2.840.113549.1.5.4' => 'pbeWithMD2AndRC2-CBC', '1.2.840.113549.1.5.6' => 'pbeWithMD5AndRC2-CBC', '1.2.840.113549.1.5.10' => 'pbeWithSHA1AndDES-CBC', '1.2.840.113549.1.5.11' => 'pbeWithSHA1AndRC2-CBC', '1.2.840.113549.1.5.12' => 'PBKDF2', '1.2.840.113549.1.5.13' => 'PBES2', '1.2.840.113549.1.5.14' => 'PBMAC1', '1.2.840.113549.1.7' => 'pkcs7', '1.2.840.113549.1.7.1' => 'pkcs7-data', '1.2.840.113549.1.7.2' => 'pkcs7-signedData', '1.2.840.113549.1.7.3' => 'pkcs7-envelopedData', '1.2.840.113549.1.7.4' => 'pkcs7-signedAndEnvelopedData', '1.2.840.113549.1.7.5' => 'pkcs7-digestData', '1.2.840.113549.1.7.6' => 'pkcs7-encryptedData', '1.2.840.113549.1.9' => 'pkcs9', '1.2.840.113549.1.9.1' => 'emailAddress', '1.2.840.113549.1.9.2' => 'unstructuredName', '1.2.840.113549.1.9.3' => 'contentType', '1.2.840.113549.1.9.4' => 'messageDigest', '1.2.840.113549.1.9.5' => 'signingTime', '1.2.840.113549.1.9.6' => 'countersignature', '1.2.840.113549.1.9.7' => 'challengePassword', '1.2.840.113549.1.9.8' => 'unstructuredAddress', '1.2.840.113549.1.9.9' => 'extendedCertificateAttributes', '1.2.840.113549.1.9.14' => 'Extension Request', '1.2.840.113549.1.9.15' => 'S/MIME Capabilities', '1.2.840.113549.1.9.16' => 'S/MIME', '1.2.840.113549.1.9.16.0' => 'id-smime-mod', '1.2.840.113549.1.9.16.1' => 'id-smime-ct', '1.2.840.113549.1.9.16.2' => 'id-smime-aa', '1.2.840.113549.1.9.16.3' => 'id-smime-alg', '1.2.840.113549.1.9.16.4' => 'id-smime-cd', '1.2.840.113549.1.9.16.5' => 'id-smime-spq', '1.2.840.113549.1.9.16.6' => 'id-smime-cti', '1.2.840.113549.1.9.16.0.1' => 'id-smime-mod-cms', '1.2.840.113549.1.9.16.0.2' => 'id-smime-mod-ess', '1.2.840.113549.1.9.16.0.3' => 'id-smime-mod-oid', '1.2.840.113549.1.9.16.0.4' => 'id-smime-mod-msg-v3', '1.2.840.113549.1.9.16.0.5' => 'id-smime-mod-ets-eSignature-88', '1.2.840.113549.1.9.16.0.6' => 'id-smime-mod-ets-eSignature-97', '1.2.840.113549.1.9.16.0.7' => 'id-smime-mod-ets-eSigPolicy-88', '1.2.840.113549.1.9.16.0.8' => 'id-smime-mod-ets-eSigPolicy-97', '1.2.840.113549.1.9.16.1.1' => 'id-smime-ct-receipt', '1.2.840.113549.1.9.16.1.2' => 'id-smime-ct-authData', '1.2.840.113549.1.9.16.1.3' => 'id-smime-ct-publishCert', '1.2.840.113549.1.9.16.1.4' => 'id-smime-ct-TSTInfo', '1.2.840.113549.1.9.16.1.5' => 'id-smime-ct-TDTInfo', '1.2.840.113549.1.9.16.1.6' => 'id-smime-ct-contentInfo', '1.2.840.113549.1.9.16.1.7' => 'id-smime-ct-DVCSRequestData', '1.2.840.113549.1.9.16.1.8' => 'id-smime-ct-DVCSResponseData', '1.2.840.113549.1.9.16.1.9' => 'id-smime-ct-compressedData', '1.2.840.113549.1.9.16.1.27' => 'id-ct-asciiTextWithCRLF', '1.2.840.113549.1.9.16.2.1' => 'id-smime-aa-receiptRequest', '1.2.840.113549.1.9.16.2.2' => 'id-smime-aa-securityLabel', '1.2.840.113549.1.9.16.2.3' => 'id-smime-aa-mlExpandHistory', '1.2.840.113549.1.9.16.2.4' => 'id-smime-aa-contentHint', '1.2.840.113549.1.9.16.2.5' => 'id-smime-aa-msgSigDigest', '1.2.840.113549.1.9.16.2.6' => 'id-smime-aa-encapContentType', '1.2.840.113549.1.9.16.2.7' => 'id-smime-aa-contentIdentifier', '1.2.840.113549.1.9.16.2.8' => 'id-smime-aa-macValue', '1.2.840.113549.1.9.16.2.9' => 'id-smime-aa-equivalentLabels', '1.2.840.113549.1.9.16.2.10' => 'id-smime-aa-contentReference', '1.2.840.113549.1.9.16.2.11' => 'id-smime-aa-encrypKeyPref', '1.2.840.113549.1.9.16.2.12' => 'id-smime-aa-signingCertificate', '1.2.840.113549.1.9.16.2.13' => 'id-smime-aa-smimeEncryptCerts', '1.2.840.113549.1.9.16.2.14' => 'id-smime-aa-timeStampToken', '1.2.840.113549.1.9.16.2.15' => 'id-smime-aa-ets-sigPolicyId', '1.2.840.113549.1.9.16.2.16' => 'id-smime-aa-ets-commitmentType', '1.2.840.113549.1.9.16.2.17' => 'id-smime-aa-ets-signerLocation', '1.2.840.113549.1.9.16.2.18' => 'id-smime-aa-ets-signerAttr', '1.2.840.113549.1.9.16.2.19' => 'id-smime-aa-ets-otherSigCert', '1.2.840.113549.1.9.16.2.20' => 'id-smime-aa-ets-contentTimestamp', '1.2.840.113549.1.9.16.2.21' => 'id-smime-aa-ets-CertificateRefs', '1.2.840.113549.1.9.16.2.22' => 'id-smime-aa-ets-RevocationRefs', '1.2.840.113549.1.9.16.2.23' => 'id-smime-aa-ets-certValues', '1.2.840.113549.1.9.16.2.24' => 'id-smime-aa-ets-revocationValues', '1.2.840.113549.1.9.16.2.25' => 'id-smime-aa-ets-escTimeStamp', '1.2.840.113549.1.9.16.2.26' => 'id-smime-aa-ets-certCRLTimestamp', '1.2.840.113549.1.9.16.2.27' => 'id-smime-aa-ets-archiveTimeStamp', '1.2.840.113549.1.9.16.2.28' => 'id-smime-aa-signatureType', '1.2.840.113549.1.9.16.2.29' => 'id-smime-aa-dvcs-dvc', '1.2.840.113549.1.9.16.3.1' => 'id-smime-alg-ESDHwith3DES', '1.2.840.113549.1.9.16.3.2' => 'id-smime-alg-ESDHwithRC2', '1.2.840.113549.1.9.16.3.3' => 'id-smime-alg-3DESwrap', '1.2.840.113549.1.9.16.3.4' => 'id-smime-alg-RC2wrap', '1.2.840.113549.1.9.16.3.5' => 'id-smime-alg-ESDH', '1.2.840.113549.1.9.16.3.6' => 'id-smime-alg-CMS3DESwrap', '1.2.840.113549.1.9.16.3.7' => 'id-smime-alg-CMSRC2wrap', '1.2.840.113549.1.9.16.3.9' => 'id-alg-PWRI-KEK', '1.2.840.113549.1.9.16.4.1' => 'id-smime-cd-ldap', '1.2.840.113549.1.9.16.5.1' => 'id-smime-spq-ets-sqt-uri', '1.2.840.113549.1.9.16.5.2' => 'id-smime-spq-ets-sqt-unotice', '1.2.840.113549.1.9.16.6.1' => 'id-smime-cti-ets-proofOfOrigin', '1.2.840.113549.1.9.16.6.2' => 'id-smime-cti-ets-proofOfReceipt', '1.2.840.113549.1.9.16.6.3' => 'id-smime-cti-ets-proofOfDelivery', '1.2.840.113549.1.9.16.6.4' => 'id-smime-cti-ets-proofOfSender', '1.2.840.113549.1.9.16.6.5' => 'id-smime-cti-ets-proofOfApproval', '1.2.840.113549.1.9.16.6.6' => 'id-smime-cti-ets-proofOfCreation', '1.2.840.113549.1.9.20' => 'friendlyName', '1.2.840.113549.1.9.21' => 'localKeyID', '1.3.6.1.4.1.311.17.1' => 'Microsoft CSP Name', '1.3.6.1.4.1.311.17.2' => 'Microsoft Local Key set', '1.2.840.113549.1.9.22' => 'certTypes', '1.2.840.113549.1.9.22.1' => 'x509Certificate', '1.2.840.113549.1.9.22.2' => 'sdsiCertificate', '1.2.840.113549.1.9.23' => 'crlTypes', '1.2.840.113549.1.9.23.1' => 'x509Crl', '1.2.840.113549.1.12' => 'pkcs12', '1.2.840.113549.1.12.1' => 'pkcs12-pbeids', '1.2.840.113549.1.12.1.1' => 'pbeWithSHA1And128BitRC4', '1.2.840.113549.1.12.1.2' => 'pbeWithSHA1And40BitRC4', '1.2.840.113549.1.12.1.3' => 'pbeWithSHA1And3-KeyTripleDES-CBC', '1.2.840.113549.1.12.1.4' => 'pbeWithSHA1And2-KeyTripleDES-CBC', '1.2.840.113549.1.12.1.5' => 'pbeWithSHA1And128BitRC2-CBC', '1.2.840.113549.1.12.1.6' => 'pbeWithSHA1And40BitRC2-CBC', '1.2.840.113549.1.12.10' => 'pkcs12-Version1', '1.2.840.113549.1.12.10.1' => 'pkcs12-BagIds', '1.2.840.113549.1.12.10.1.1' => 'keyBag', '1.2.840.113549.1.12.10.1.2' => 'pkcs8ShroudedKeyBag', '1.2.840.113549.1.12.10.1.3' => 'certBag', '1.2.840.113549.1.12.10.1.4' => 'crlBag', '1.2.840.113549.1.12.10.1.5' => 'secretBag', '1.2.840.113549.1.12.10.1.6' => 'safeContentsBag', '1.2.840.113549.2.2' => 'md2', '1.2.840.113549.2.4' => 'md4', '1.2.840.113549.2.5' => 'md5', '1.2.840.113549.2.6' => 'hmacWithMD5', '1.2.840.113549.2.7' => 'hmacWithSHA1', '1.2.840.113549.2.8' => 'hmacWithSHA224', '1.2.840.113549.2.9' => 'hmacWithSHA256', '1.2.840.113549.2.10' => 'hmacWithSHA384', '1.2.840.113549.2.11' => 'hmacWithSHA512', '1.2.840.113549.3.2' => 'rc2-cbc', '1.2.840.113549.3.4' => 'rc4', '1.2.840.113549.3.7' => 'des-ede3-cbc', '1.2.840.113549.3.8' => 'rc5-cbc', '1.3.6.1.4.1.311.2.1.14' => 'Microsoft Extension Request', '1.3.6.1.4.1.311.2.1.21' => 'Microsoft Individual Code Signing', '1.3.6.1.4.1.311.2.1.22' => 'Microsoft Commercial Code Signing', '1.3.6.1.4.1.311.10.3.1' => 'Microsoft Trust List Signing', '1.3.6.1.4.1.311.10.3.3' => 'Microsoft Server Gated Crypto', '1.3.6.1.4.1.311.10.3.4' => 'Microsoft Encrypted File System', '1.3.6.1.4.1.311.20.2.2' => 'Microsoft Smartcardlogin', '1.3.6.1.4.1.311.20.2.3' => 'Microsoft Universal Principal Name', '1.3.6.1.4.1.188.7.1.1.2' => 'idea-cbc', '1.3.6.1.4.1.3029.1.2' => 'bf-cbc', '1.3.6.1.5.5.7' => 'PKIX', '1.3.6.1.5.5.7.0' => 'id-pkix-mod', '1.3.6.1.5.5.7.1' => 'id-pe', '1.3.6.1.5.5.7.2' => 'id-qt', '1.3.6.1.5.5.7.3' => 'id-kp', '1.3.6.1.5.5.7.4' => 'id-it', '1.3.6.1.5.5.7.5' => 'id-pkip', '1.3.6.1.5.5.7.6' => 'id-alg', '1.3.6.1.5.5.7.7' => 'id-cmc', '1.3.6.1.5.5.7.8' => 'id-on', '1.3.6.1.5.5.7.9' => 'id-pda', '1.3.6.1.5.5.7.10' => 'id-aca', '1.3.6.1.5.5.7.11' => 'id-qcs', '1.3.6.1.5.5.7.12' => 'id-cct', '1.3.6.1.5.5.7.21' => 'id-ppl', '1.3.6.1.5.5.7.48' => 'id-ad', '1.3.6.1.5.5.7.0.1' => 'id-pkix1-explicit-88', '1.3.6.1.5.5.7.0.2' => 'id-pkix1-implicit-88', '1.3.6.1.5.5.7.0.3' => 'id-pkix1-explicit-93', '1.3.6.1.5.5.7.0.4' => 'id-pkix1-implicit-93', '1.3.6.1.5.5.7.0.5' => 'id-mod-crmf', '1.3.6.1.5.5.7.0.6' => 'id-mod-cmc', '1.3.6.1.5.5.7.0.7' => 'id-mod-kea-profile-88', '1.3.6.1.5.5.7.0.8' => 'id-mod-kea-profile-93', '1.3.6.1.5.5.7.0.9' => 'id-mod-cmp', '1.3.6.1.5.5.7.0.10' => 'id-mod-qualified-cert-88', '1.3.6.1.5.5.7.0.11' => 'id-mod-qualified-cert-93', '1.3.6.1.5.5.7.0.12' => 'id-mod-attribute-cert', '1.3.6.1.5.5.7.0.13' => 'id-mod-timestamp-protocol', '1.3.6.1.5.5.7.0.14' => 'id-mod-ocsp', '1.3.6.1.5.5.7.0.15' => 'id-mod-dvcs', '1.3.6.1.5.5.7.0.16' => 'id-mod-cmp2000', '1.3.6.1.5.5.7.1.1' => 'Authority Information Access', '1.3.6.1.5.5.7.1.2' => 'Biometric Info', '1.3.6.1.5.5.7.1.3' => 'qcStatements', '1.3.6.1.5.5.7.1.4' => 'ac-auditEntity', '1.3.6.1.5.5.7.1.5' => 'ac-targeting', '1.3.6.1.5.5.7.1.6' => 'aaControls', '1.3.6.1.5.5.7.1.7' => 'sbgp-ipAddrBlock', '1.3.6.1.5.5.7.1.8' => 'sbgp-autonomousSysNum', '1.3.6.1.5.5.7.1.9' => 'sbgp-routerIdentifier', '1.3.6.1.5.5.7.1.10' => 'ac-proxying', '1.3.6.1.5.5.7.1.11' => 'Subject Information Access', '1.3.6.1.5.5.7.1.14' => 'Proxy Certificate Information', '1.3.6.1.5.5.7.2.1' => 'Policy Qualifier CPS', '1.3.6.1.5.5.7.2.2' => 'Policy Qualifier User Notice', '1.3.6.1.5.5.7.2.3' => 'textNotice', '1.3.6.1.5.5.7.3.1' => 'TLS Web Server Authentication', '1.3.6.1.5.5.7.3.2' => 'TLS Web Client Authentication', '1.3.6.1.5.5.7.3.3' => 'Code Signing', '1.3.6.1.5.5.7.3.4' => 'E-mail Protection', '1.3.6.1.5.5.7.3.5' => 'IPSec End System', '1.3.6.1.5.5.7.3.6' => 'IPSec Tunnel', '1.3.6.1.5.5.7.3.7' => 'IPSec User', '1.3.6.1.5.5.7.3.8' => 'Time Stamping', '1.3.6.1.5.5.7.3.9' => 'OCSP Signing', '1.3.6.1.5.5.7.3.10' => 'dvcs', '1.3.6.1.5.5.7.4.1' => 'id-it-caProtEncCert', '1.3.6.1.5.5.7.4.2' => 'id-it-signKeyPairTypes', '1.3.6.1.5.5.7.4.3' => 'id-it-encKeyPairTypes', '1.3.6.1.5.5.7.4.4' => 'id-it-preferredSymmAlg', '1.3.6.1.5.5.7.4.5' => 'id-it-caKeyUpdateInfo', '1.3.6.1.5.5.7.4.6' => 'id-it-currentCRL', '1.3.6.1.5.5.7.4.7' => 'id-it-unsupportedOIDs', '1.3.6.1.5.5.7.4.8' => 'id-it-subscriptionRequest', '1.3.6.1.5.5.7.4.9' => 'id-it-subscriptionResponse', '1.3.6.1.5.5.7.4.10' => 'id-it-keyPairParamReq', '1.3.6.1.5.5.7.4.11' => 'id-it-keyPairParamRep', '1.3.6.1.5.5.7.4.12' => 'id-it-revPassphrase', '1.3.6.1.5.5.7.4.13' => 'id-it-implicitConfirm', '1.3.6.1.5.5.7.4.14' => 'id-it-confirmWaitTime', '1.3.6.1.5.5.7.4.15' => 'id-it-origPKIMessage', '1.3.6.1.5.5.7.4.16' => 'id-it-suppLangTags', '1.3.6.1.5.5.7.5.1' => 'id-regCtrl', '1.3.6.1.5.5.7.5.2' => 'id-regInfo', '1.3.6.1.5.5.7.5.1.1' => 'id-regCtrl-regToken', '1.3.6.1.5.5.7.5.1.2' => 'id-regCtrl-authenticator', '1.3.6.1.5.5.7.5.1.3' => 'id-regCtrl-pkiPublicationInfo', '1.3.6.1.5.5.7.5.1.4' => 'id-regCtrl-pkiArchiveOptions', '1.3.6.1.5.5.7.5.1.5' => 'id-regCtrl-oldCertID', '1.3.6.1.5.5.7.5.1.6' => 'id-regCtrl-protocolEncrKey', '1.3.6.1.5.5.7.5.2.1' => 'id-regInfo-utf8Pairs', '1.3.6.1.5.5.7.5.2.2' => 'id-regInfo-certReq', '1.3.6.1.5.5.7.6.1' => 'id-alg-des40', '1.3.6.1.5.5.7.6.2' => 'id-alg-noSignature', '1.3.6.1.5.5.7.6.3' => 'id-alg-dh-sig-hmac-sha1', '1.3.6.1.5.5.7.6.4' => 'id-alg-dh-pop', '1.3.6.1.5.5.7.7.1' => 'id-cmc-statusInfo', '1.3.6.1.5.5.7.7.2' => 'id-cmc-identification', '1.3.6.1.5.5.7.7.3' => 'id-cmc-identityProof', '1.3.6.1.5.5.7.7.4' => 'id-cmc-dataReturn', '1.3.6.1.5.5.7.7.5' => 'id-cmc-transactionId', '1.3.6.1.5.5.7.7.6' => 'id-cmc-senderNonce', '1.3.6.1.5.5.7.7.7' => 'id-cmc-recipientNonce', '1.3.6.1.5.5.7.7.8' => 'id-cmc-addExtensions', '1.3.6.1.5.5.7.7.9' => 'id-cmc-encryptedPOP', '1.3.6.1.5.5.7.7.10' => 'id-cmc-decryptedPOP', '1.3.6.1.5.5.7.7.11' => 'id-cmc-lraPOPWitness', '1.3.6.1.5.5.7.7.15' => 'id-cmc-getCert', '1.3.6.1.5.5.7.7.16' => 'id-cmc-getCRL', '1.3.6.1.5.5.7.7.17' => 'id-cmc-revokeRequest', '1.3.6.1.5.5.7.7.18' => 'id-cmc-regInfo', '1.3.6.1.5.5.7.7.19' => 'id-cmc-responseInfo', '1.3.6.1.5.5.7.7.21' => 'id-cmc-queryPending', '1.3.6.1.5.5.7.7.22' => 'id-cmc-popLinkRandom', '1.3.6.1.5.5.7.7.23' => 'id-cmc-popLinkWitness', '1.3.6.1.5.5.7.7.24' => 'id-cmc-confirmCertAcceptance', '1.3.6.1.5.5.7.8.1' => 'id-on-personalData', '1.3.6.1.5.5.7.8.3' => 'Permanent Identifier', '1.3.6.1.5.5.7.9.1' => 'id-pda-dateOfBirth', '1.3.6.1.5.5.7.9.2' => 'id-pda-placeOfBirth', '1.3.6.1.5.5.7.9.3' => 'id-pda-gender', '1.3.6.1.5.5.7.9.4' => 'id-pda-countryOfCitizenship', '1.3.6.1.5.5.7.9.5' => 'id-pda-countryOfResidence', '1.3.6.1.5.5.7.10.1' => 'id-aca-authenticationInfo', '1.3.6.1.5.5.7.10.2' => 'id-aca-accessIdentity', '1.3.6.1.5.5.7.10.3' => 'id-aca-chargingIdentity', '1.3.6.1.5.5.7.10.4' => 'id-aca-group', '1.3.6.1.5.5.7.10.5' => 'id-aca-role', '1.3.6.1.5.5.7.10.6' => 'id-aca-encAttrs', '1.3.6.1.5.5.7.11.1' => 'id-qcs-pkixQCSyntax-v1', '1.3.6.1.5.5.7.12.1' => 'id-cct-crs', '1.3.6.1.5.5.7.12.2' => 'id-cct-PKIData', '1.3.6.1.5.5.7.12.3' => 'id-cct-PKIResponse', '1.3.6.1.5.5.7.21.0' => 'Any language', '1.3.6.1.5.5.7.21.1' => 'Inherit all', '1.3.6.1.5.5.7.21.2' => 'Independent', '1.3.6.1.5.5.7.48.1' => 'OCSP', '1.3.6.1.5.5.7.48.2' => 'CA Issuers', '1.3.6.1.5.5.7.48.3' => 'AD Time Stamping', '1.3.6.1.5.5.7.48.4' => 'ad dvcs', '1.3.6.1.5.5.7.48.5' => 'CA Repository', '1.3.6.1.5.5.7.48.1.1' => 'Basic OCSP Response', '1.3.6.1.5.5.7.48.1.2' => 'OCSP Nonce', '1.3.6.1.5.5.7.48.1.3' => 'OCSP CRL ID', '1.3.6.1.5.5.7.48.1.4' => 'Acceptable OCSP Responses', '1.3.6.1.5.5.7.48.1.5' => 'OCSP No Check', '1.3.6.1.5.5.7.48.1.6' => 'OCSP Archive Cutoff', '1.3.6.1.5.5.7.48.1.7' => 'OCSP Service Locator', '1.3.6.1.5.5.7.48.1.8' => 'Extended OCSP Status', '1.3.6.1.5.5.7.48.1.9' => 'id-pkix-OCSP_valid', '1.3.6.1.5.5.7.48.1.10' => 'id-pkix-OCSP_path', '1.3.6.1.5.5.7.48.1.11' => 'Trust Root', '1.3.14.3.2' => 'algorithm', '1.3.14.3.2.3' => 'md5WithRSA', '1.3.14.3.2.6' => 'des-ecb', '1.3.14.3.2.7' => 'des-cbc', '1.3.14.3.2.8' => 'des-ofb', '1.3.14.3.2.9' => 'des-cfb', '1.3.14.3.2.11' => 'rsaSignature', '1.3.14.3.2.12' => 'dsaEncryption-old', '1.3.14.3.2.13' => 'dsaWithSHA', '1.3.14.3.2.15' => 'shaWithRSAEncryption', '1.3.14.3.2.17' => 'des-ede', '1.3.14.3.2.18' => 'sha', '1.3.14.3.2.26' => 'sha1', '1.3.14.3.2.27' => 'dsaWithSHA1-old', '1.3.14.3.2.29' => 'sha1WithRSA', '1.3.36.3.2.1' => 'ripemd160', '1.3.36.3.3.1.2' => 'ripemd160WithRSA', '1.3.101.1.4.1' => 'Strong Extranet ID', '2.5' => 'directory services (X.500)', '2.5.4' => 'X509', '2.5.4.3' => 'commonName', '2.5.4.4' => 'surname', '2.5.4.5' => 'serialNumber', '2.5.4.6' => 'countryName', '2.5.4.7' => 'localityName', '2.5.4.8' => 'stateOrProvinceName', '2.5.4.9' => 'streetAddress', '2.5.4.10' => 'organizationName', '2.5.4.11' => 'organizationalUnitName', '2.5.4.12' => 'title', '2.5.4.13' => 'description', '2.5.4.14' => 'searchGuide', '2.5.4.15' => 'businessCategory', '2.5.4.16' => 'postalAddress', '2.5.4.17' => 'postalCode', '2.5.4.18' => 'postOfficeBox', '2.5.4.19' => 'physicalDeliveryOfficeName', '2.5.4.20' => 'telephoneNumber', '2.5.4.21' => 'telexNumber', '2.5.4.22' => 'teletexTerminalIdentifier', '2.5.4.23' => 'facsimileTelephoneNumber', '2.5.4.24' => 'x121Address', '2.5.4.25' => 'internationaliSDNNumber', '2.5.4.26' => 'registeredAddress', '2.5.4.27' => 'destinationIndicator', '2.5.4.28' => 'preferredDeliveryMethod', '2.5.4.29' => 'presentationAddress', '2.5.4.30' => 'supportedApplicationContext', '2.5.4.31' => 'member', '2.5.4.32' => 'owner', '2.5.4.33' => 'roleOccupant', '2.5.4.34' => 'seeAlso', '2.5.4.35' => 'userPassword', '2.5.4.36' => 'userCertificate', '2.5.4.37' => 'cACertificate', '2.5.4.38' => 'authorityRevocationList', '2.5.4.39' => 'certificateRevocationList', '2.5.4.40' => 'crossCertificatePair', '2.5.4.41' => 'name', '2.5.4.42' => 'givenName', '2.5.4.43' => 'initials', '2.5.4.44' => 'generationQualifier', '2.5.4.45' => 'x500UniqueIdentifier', '2.5.4.46' => 'dnQualifier', '2.5.4.47' => 'enhancedSearchGuide', '2.5.4.48' => 'protocolInformation', '2.5.4.49' => 'distinguishedName', '2.5.4.50' => 'uniqueMember', '2.5.4.51' => 'houseIdentifier', '2.5.4.52' => 'supportedAlgorithms', '2.5.4.53' => 'deltaRevocationList', '2.5.4.54' => 'dmdName', '2.5.4.65' => 'pseudonym', '2.5.4.72' => 'role', '2.5.8' => 'directory services - algorithms', '2.5.8.1.1' => 'rsa', '2.5.8.3.100' => 'mdc2WithRSA', '2.5.8.3.101' => 'mdc2', '2.5.29' => 'id-ce', '2.5.29.9' => 'X509v3 Subject Directory Attributes', '2.5.29.14' => 'X509v3 Subject Key Identifier', '2.5.29.15' => 'X509v3 Key Usage', '2.5.29.16' => 'X509v3 Private Key Usage Period', '2.5.29.17' => 'X509v3 Subject Alternative Name', '2.5.29.18' => 'X509v3 Issuer Alternative Name', '2.5.29.19' => 'X509v3 Basic Constraints', '2.5.29.20' => 'X509v3 CRL Number', '2.5.29.21' => 'X509v3 CRL Reason Code', '2.5.29.24' => 'Invalidity Date', '2.5.29.27' => 'X509v3 Delta CRL Indicator', '2.5.29.28' => 'X509v3 Issuing Distribution Point', '2.5.29.29' => 'X509v3 Certificate Issuer', '2.5.29.30' => 'X509v3 Name Constraints', '2.5.29.31' => 'X509v3 CRL Distribution Points', '2.5.29.32' => 'X509v3 Certificate Policies', '2.5.29.32.0' => 'X509v3 Any Policy', '2.5.29.33' => 'X509v3 Policy Mappings', '2.5.29.35' => 'X509v3 Authority Key Identifier', '2.5.29.36' => 'X509v3 Policy Constraints', '2.5.29.37' => 'X509v3 Extended Key Usage', '2.5.29.46' => 'X509v3 Freshest CRL', '2.5.29.54' => 'X509v3 Inhibit Any Policy', '2.5.29.55' => 'X509v3 AC Targeting', '2.5.29.56' => 'X509v3 No Revocation Available', '2.5.29.37.0' => 'Any Extended Key Usage', '2.16.840.1.113730' => 'Netscape Communications Corp.', '2.16.840.1.113730.1' => 'Netscape Certificate Extension', '2.16.840.1.113730.2' => 'Netscape Data Type', '2.16.840.1.113730.1.1' => 'Netscape Cert Type', '2.16.840.1.113730.1.2' => 'Netscape Base Url', '2.16.840.1.113730.1.3' => 'Netscape Revocation Url', '2.16.840.1.113730.1.4' => 'Netscape CA Revocation Url', '2.16.840.1.113730.1.7' => 'Netscape Renewal Url', '2.16.840.1.113730.1.8' => 'Netscape CA Policy Url', '2.16.840.1.113730.1.12' => 'Netscape SSL Server Name', '2.16.840.1.113730.1.13' => 'Netscape Comment', '2.16.840.1.113730.2.5' => 'Netscape Certificate Sequence', '2.16.840.1.113730.4.1' => 'Netscape Server Gated Crypto', '1.3.6' => 'dod', '1.3.6.1' => 'iana', '1.3.6.1.1' => 'Directory', '1.3.6.1.2' => 'Management', '1.3.6.1.3' => 'Experimental', '1.3.6.1.4' => 'Private', '1.3.6.1.5' => 'Security', '1.3.6.1.6' => 'SNMPv2', '1.3.6.1.7' => 'Mail', '1.3.6.1.4.1' => 'Enterprises', '1.3.6.1.4.1.1466.344' => 'dcObject', '1.2.840.113549.1.9.16.3.8' => 'zlib compression', '2.16.840.1.101.3' => 'csor', '2.16.840.1.101.3.4' => 'nistAlgorithms', '2.16.840.1.101.3.4.1' => 'aes', '2.16.840.1.101.3.4.1.1' => 'aes-128-ecb', '2.16.840.1.101.3.4.1.2' => 'aes-128-cbc', '2.16.840.1.101.3.4.1.3' => 'aes-128-ofb', '2.16.840.1.101.3.4.1.4' => 'aes-128-cfb', '2.16.840.1.101.3.4.1.5' => 'id-aes128-wrap', '2.16.840.1.101.3.4.1.6' => 'aes-128-gcm', '2.16.840.1.101.3.4.1.7' => 'aes-128-ccm', '2.16.840.1.101.3.4.1.8' => 'id-aes128-wrap-pad', '2.16.840.1.101.3.4.1.21' => 'aes-192-ecb', '2.16.840.1.101.3.4.1.22' => 'aes-192-cbc', '2.16.840.1.101.3.4.1.23' => 'aes-192-ofb', '2.16.840.1.101.3.4.1.24' => 'aes-192-cfb', '2.16.840.1.101.3.4.1.25' => 'id-aes192-wrap', '2.16.840.1.101.3.4.1.26' => 'aes-192-gcm', '2.16.840.1.101.3.4.1.27' => 'aes-192-ccm', '2.16.840.1.101.3.4.1.28' => 'id-aes192-wrap-pad', '2.16.840.1.101.3.4.1.41' => 'aes-256-ecb', '2.16.840.1.101.3.4.1.42' => 'aes-256-cbc', '2.16.840.1.101.3.4.1.43' => 'aes-256-ofb', '2.16.840.1.101.3.4.1.44' => 'aes-256-cfb', '2.16.840.1.101.3.4.1.45' => 'id-aes256-wrap', '2.16.840.1.101.3.4.1.46' => 'aes-256-gcm', '2.16.840.1.101.3.4.1.47' => 'aes-256-ccm', '2.16.840.1.101.3.4.1.48' => 'id-aes256-wrap-pad', '2.16.840.1.101.3.4.2' => 'nist_hashalgs', '2.16.840.1.101.3.4.2.1' => 'sha256', '2.16.840.1.101.3.4.2.2' => 'sha384', '2.16.840.1.101.3.4.2.3' => 'sha512', '2.16.840.1.101.3.4.2.4' => 'sha224', '2.16.840.1.101.3.4.3' => 'dsa_with_sha2', '2.16.840.1.101.3.4.3.1' => 'dsa_with_SHA224', '2.16.840.1.101.3.4.3.2' => 'dsa_with_SHA256', '2.5.29.23' => 'Hold Instruction Code', '0.9' => 'data', '0.9.2342' => 'pss', '0.9.2342.19200300' => 'ucl', '0.9.2342.19200300.100' => 'pilot', '0.9.2342.19200300.100.1' => 'pilotAttributeType', '0.9.2342.19200300.100.3' => 'pilotAttributeSyntax', '0.9.2342.19200300.100.4' => 'pilotObjectClass', '0.9.2342.19200300.100.10' => 'pilotGroups', '2.23.42' => 'Secure Electronic Transactions', '2.23.42.0' => 'content types', '2.23.42.1' => 'message extensions', '2.23.42.3' => 'set-attr', '2.23.42.5' => 'set-policy', '2.23.42.7' => 'certificate extensions', '2.23.42.8' => 'set-brand', '2.23.42.0.0' => 'setct-PANData', '2.23.42.0.1' => 'setct-PANToken', '2.23.42.0.2' => 'setct-PANOnly', '2.23.42.0.3' => 'setct-OIData', '2.23.42.0.4' => 'setct-PI', '2.23.42.0.5' => 'setct-PIData', '2.23.42.0.6' => 'setct-PIDataUnsigned', '2.23.42.0.7' => 'setct-HODInput', '2.23.42.0.8' => 'setct-AuthResBaggage', '2.23.42.0.9' => 'setct-AuthRevReqBaggage', '2.23.42.0.10' => 'setct-AuthRevResBaggage', '2.23.42.0.11' => 'setct-CapTokenSeq', '2.23.42.0.12' => 'setct-PInitResData', '2.23.42.0.13' => 'setct-PI-TBS', '2.23.42.0.14' => 'setct-PResData', '2.23.42.0.16' => 'setct-AuthReqTBS', '2.23.42.0.17' => 'setct-AuthResTBS', '2.23.42.0.18' => 'setct-AuthResTBSX', '2.23.42.0.19' => 'setct-AuthTokenTBS', '2.23.42.0.20' => 'setct-CapTokenData', '2.23.42.0.21' => 'setct-CapTokenTBS', '2.23.42.0.22' => 'setct-AcqCardCodeMsg', '2.23.42.0.23' => 'setct-AuthRevReqTBS', '2.23.42.0.24' => 'setct-AuthRevResData', '2.23.42.0.25' => 'setct-AuthRevResTBS', '2.23.42.0.26' => 'setct-CapReqTBS', '2.23.42.0.27' => 'setct-CapReqTBSX', '2.23.42.0.28' => 'setct-CapResData', '2.23.42.0.29' => 'setct-CapRevReqTBS', '2.23.42.0.30' => 'setct-CapRevReqTBSX', '2.23.42.0.31' => 'setct-CapRevResData', '2.23.42.0.32' => 'setct-CredReqTBS', '2.23.42.0.33' => 'setct-CredReqTBSX', '2.23.42.0.34' => 'setct-CredResData', '2.23.42.0.35' => 'setct-CredRevReqTBS', '2.23.42.0.36' => 'setct-CredRevReqTBSX', '2.23.42.0.37' => 'setct-CredRevResData', '2.23.42.0.38' => 'setct-PCertReqData', '2.23.42.0.39' => 'setct-PCertResTBS', '2.23.42.0.40' => 'setct-BatchAdminReqData', '2.23.42.0.41' => 'setct-BatchAdminResData', '2.23.42.0.42' => 'setct-CardCInitResTBS', '2.23.42.0.43' => 'setct-MeAqCInitResTBS', '2.23.42.0.44' => 'setct-RegFormResTBS', '2.23.42.0.45' => 'setct-CertReqData', '2.23.42.0.46' => 'setct-CertReqTBS', '2.23.42.0.47' => 'setct-CertResData', '2.23.42.0.48' => 'setct-CertInqReqTBS', '2.23.42.0.49' => 'setct-ErrorTBS', '2.23.42.0.50' => 'setct-PIDualSignedTBE', '2.23.42.0.51' => 'setct-PIUnsignedTBE', '2.23.42.0.52' => 'setct-AuthReqTBE', '2.23.42.0.53' => 'setct-AuthResTBE', '2.23.42.0.54' => 'setct-AuthResTBEX', '2.23.42.0.55' => 'setct-AuthTokenTBE', '2.23.42.0.56' => 'setct-CapTokenTBE', '2.23.42.0.57' => 'setct-CapTokenTBEX', '2.23.42.0.58' => 'setct-AcqCardCodeMsgTBE', '2.23.42.0.59' => 'setct-AuthRevReqTBE', '2.23.42.0.60' => 'setct-AuthRevResTBE', '2.23.42.0.61' => 'setct-AuthRevResTBEB', '2.23.42.0.62' => 'setct-CapReqTBE', '2.23.42.0.63' => 'setct-CapReqTBEX', '2.23.42.0.64' => 'setct-CapResTBE', '2.23.42.0.65' => 'setct-CapRevReqTBE', '2.23.42.0.66' => 'setct-CapRevReqTBEX', '2.23.42.0.67' => 'setct-CapRevResTBE', '2.23.42.0.68' => 'setct-CredReqTBE', '2.23.42.0.69' => 'setct-CredReqTBEX', '2.23.42.0.70' => 'setct-CredResTBE', '2.23.42.0.71' => 'setct-CredRevReqTBE', '2.23.42.0.72' => 'setct-CredRevReqTBEX', '2.23.42.0.73' => 'setct-CredRevResTBE', '2.23.42.0.74' => 'setct-BatchAdminReqTBE', '2.23.42.0.75' => 'setct-BatchAdminResTBE', '2.23.42.0.76' => 'setct-RegFormReqTBE', '2.23.42.0.77' => 'setct-CertReqTBE', '2.23.42.0.78' => 'setct-CertReqTBEX', '2.23.42.0.79' => 'setct-CertResTBE', '2.23.42.0.80' => 'setct-CRLNotificationTBS', '2.23.42.0.81' => 'setct-CRLNotificationResTBS', '2.23.42.0.82' => 'setct-BCIDistributionTBS', '2.23.42.1.1' => 'generic cryptogram', '2.23.42.1.3' => 'merchant initiated auth', '2.23.42.1.4' => 'setext-pinSecure', '2.23.42.1.5' => 'setext-pinAny', '2.23.42.1.7' => 'setext-track2', '2.23.42.1.8' => 'additional verification', '2.23.42.5.0' => 'set-policy-root', '2.23.42.7.0' => 'setCext-hashedRoot', '2.23.42.7.1' => 'setCext-certType', '2.23.42.7.2' => 'setCext-merchData', '2.23.42.7.3' => 'setCext-cCertRequired', '2.23.42.7.4' => 'setCext-tunneling', '2.23.42.7.5' => 'setCext-setExt', '2.23.42.7.6' => 'setCext-setQualf', '2.23.42.7.7' => 'setCext-PGWYcapabilities', '2.23.42.7.8' => 'setCext-TokenIdentifier', '2.23.42.7.9' => 'setCext-Track2Data', '2.23.42.7.10' => 'setCext-TokenType', '2.23.42.7.11' => 'setCext-IssuerCapabilities', '2.23.42.3.0' => 'setAttr-Cert', '2.23.42.3.1' => 'payment gateway capabilities', '2.23.42.3.2' => 'setAttr-TokenType', '2.23.42.3.3' => 'issuer capabilities', '2.23.42.3.0.0' => 'set-rootKeyThumb', '2.23.42.3.0.1' => 'set-addPolicy', '2.23.42.3.2.1' => 'setAttr-Token-EMV', '2.23.42.3.2.2' => 'setAttr-Token-B0Prime', '2.23.42.3.3.3' => 'setAttr-IssCap-CVM', '2.23.42.3.3.4' => 'setAttr-IssCap-T2', '2.23.42.3.3.5' => 'setAttr-IssCap-Sig', '2.23.42.3.3.3.1' => 'generate cryptogram', '2.23.42.3.3.4.1' => 'encrypted track 2', '2.23.42.3.3.4.2' => 'cleartext track 2', '2.23.42.3.3.5.1' => 'ICC or token signature', '2.23.42.3.3.5.2' => 'secure device signature', '2.23.42.8.1' => 'set-brand-IATA-ATA', '2.23.42.8.30' => 'set-brand-Diners', '2.23.42.8.34' => 'set-brand-AmericanExpress', '2.23.42.8.35' => 'set-brand-JCB', '2.23.42.8.4' => 'set-brand-Visa', '2.23.42.8.5' => 'set-brand-MasterCard', '2.23.42.8.6011' => 'set-brand-Novus', '1.2.840.113549.3.10' => 'des-cdmf', '1.2.840.113549.1.1.6' => 'rsaOAEPEncryptionSET', '1.0.10118.3.0.55' => 'whirlpool', '1.2.643.2.2' => 'cryptopro', '1.2.643.2.9' => 'cryptocom', '1.2.643.2.2.3' => 'GOST R 34.11-94 with GOST R 34.10-2001', '1.2.643.2.2.4' => 'GOST R 34.11-94 with GOST R 34.10-94', '1.2.643.2.2.9' => 'GOST R 34.11-94', '1.2.643.2.2.10' => 'HMAC GOST 34.11-94', '1.2.643.2.2.19' => 'GOST R 34.10-2001', '1.2.643.2.2.20' => 'GOST R 34.10-94', '1.2.643.2.2.21' => 'GOST 28147-89', '1.2.643.2.2.22' => 'GOST 28147-89 MAC', '1.2.643.2.2.23' => 'GOST R 34.11-94 PRF', '1.2.643.2.2.98' => 'GOST R 34.10-2001 DH', '1.2.643.2.2.99' => 'GOST R 34.10-94 DH', '1.2.643.2.2.14.1' => 'id-Gost28147-89-CryptoPro-KeyMeshing', '1.2.643.2.2.14.0' => 'id-Gost28147-89-None-KeyMeshing', '1.2.643.2.2.30.0' => 'id-GostR3411-94-TestParamSet', '1.2.643.2.2.30.1' => 'id-GostR3411-94-CryptoProParamSet', '1.2.643.2.2.31.0' => 'id-Gost28147-89-TestParamSet', '1.2.643.2.2.31.1' => 'id-Gost28147-89-CryptoPro-A-ParamSet', '1.2.643.2.2.31.2' => 'id-Gost28147-89-CryptoPro-B-ParamSet', '1.2.643.2.2.31.3' => 'id-Gost28147-89-CryptoPro-C-ParamSet', '1.2.643.2.2.31.4' => 'id-Gost28147-89-CryptoPro-D-ParamSet', '1.2.643.2.2.31.5' => 'id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet', '1.2.643.2.2.31.6' => 'id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet', '1.2.643.2.2.31.7' => 'id-Gost28147-89-CryptoPro-RIC-1-ParamSet', '1.2.643.2.2.32.0' => 'id-GostR3410-94-TestParamSet', '1.2.643.2.2.32.2' => 'id-GostR3410-94-CryptoPro-A-ParamSet', '1.2.643.2.2.32.3' => 'id-GostR3410-94-CryptoPro-B-ParamSet', '1.2.643.2.2.32.4' => 'id-GostR3410-94-CryptoPro-C-ParamSet', '1.2.643.2.2.32.5' => 'id-GostR3410-94-CryptoPro-D-ParamSet', '1.2.643.2.2.33.1' => 'id-GostR3410-94-CryptoPro-XchA-ParamSet', '1.2.643.2.2.33.2' => 'id-GostR3410-94-CryptoPro-XchB-ParamSet', '1.2.643.2.2.33.3' => 'id-GostR3410-94-CryptoPro-XchC-ParamSet', '1.2.643.2.2.35.0' => 'id-GostR3410-2001-TestParamSet', '1.2.643.2.2.35.1' => 'id-GostR3410-2001-CryptoPro-A-ParamSet', '1.2.643.2.2.35.2' => 'id-GostR3410-2001-CryptoPro-B-ParamSet', '1.2.643.2.2.35.3' => 'id-GostR3410-2001-CryptoPro-C-ParamSet', '1.2.643.2.2.36.0' => 'id-GostR3410-2001-CryptoPro-XchA-ParamSet', '1.2.643.2.2.36.1' => 'id-GostR3410-2001-CryptoPro-XchB-ParamSet', '1.2.643.2.2.20.1' => 'id-GostR3410-94-a', '1.2.643.2.2.20.2' => 'id-GostR3410-94-aBis', '1.2.643.2.2.20.3' => 'id-GostR3410-94-b', '1.2.643.2.2.20.4' => 'id-GostR3410-94-bBis', '1.2.643.2.9.1.6.1' => 'GOST 28147-89 Cryptocom ParamSet', '1.2.643.2.9.1.5.3' => 'GOST 34.10-94 Cryptocom', '1.2.643.2.9.1.5.4' => 'GOST 34.10-2001 Cryptocom', '1.2.643.2.9.1.3.3' => 'GOST R 34.11-94 with GOST R 34.10-94 Cryptocom', '1.2.643.2.9.1.3.4' => 'GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom', '1.2.643.2.9.1.8.1' => 'GOST R 3410-2001 Parameter Set Cryptocom', '1.2.392.200011.61.1.1.1.2' => 'camellia-128-cbc', '1.2.392.200011.61.1.1.1.3' => 'camellia-192-cbc', '1.2.392.200011.61.1.1.1.4' => 'camellia-256-cbc', '1.2.392.200011.61.1.1.3.2' => 'id-camellia128-wrap', '1.2.392.200011.61.1.1.3.3' => 'id-camellia192-wrap', '1.2.392.200011.61.1.1.3.4' => 'id-camellia256-wrap', '0.3.4401.5' => 'ntt-ds', '0.3.4401.5.3.1.9' => 'camellia', '0.3.4401.5.3.1.9.1' => 'camellia-128-ecb', '0.3.4401.5.3.1.9.3' => 'camellia-128-ofb', '0.3.4401.5.3.1.9.4' => 'camellia-128-cfb', '0.3.4401.5.3.1.9.6' => 'camellia-128-gcm', '0.3.4401.5.3.1.9.7' => 'camellia-128-ccm', '0.3.4401.5.3.1.9.9' => 'camellia-128-ctr', '0.3.4401.5.3.1.9.10' => 'camellia-128-cmac', '0.3.4401.5.3.1.9.21' => 'camellia-192-ecb', '0.3.4401.5.3.1.9.23' => 'camellia-192-ofb', '0.3.4401.5.3.1.9.24' => 'camellia-192-cfb', '0.3.4401.5.3.1.9.26' => 'camellia-192-gcm', '0.3.4401.5.3.1.9.27' => 'camellia-192-ccm', '0.3.4401.5.3.1.9.29' => 'camellia-192-ctr', '0.3.4401.5.3.1.9.30' => 'camellia-192-cmac', '0.3.4401.5.3.1.9.41' => 'camellia-256-ecb', '0.3.4401.5.3.1.9.43' => 'camellia-256-ofb', '0.3.4401.5.3.1.9.44' => 'camellia-256-cfb', '0.3.4401.5.3.1.9.46' => 'camellia-256-gcm', '0.3.4401.5.3.1.9.47' => 'camellia-256-ccm', '0.3.4401.5.3.1.9.49' => 'camellia-256-ctr', '0.3.4401.5.3.1.9.50' => 'camellia-256-cmac', '1.2.410.200004' => 'kisa', '1.2.410.200004.1.3' => 'seed-ecb', '1.2.410.200004.1.4' => 'seed-cbc', '1.2.410.200004.1.5' => 'seed-cfb', '1.2.410.200004.1.6' => 'seed-ofb', '1.2.840.10046.2.1' => 'X9.42 DH', '1.3.36.3.3.2.8.1.1.1' => 'brainpoolP160r1', '1.3.36.3.3.2.8.1.1.2' => 'brainpoolP160t1', '1.3.36.3.3.2.8.1.1.3' => 'brainpoolP192r1', '1.3.36.3.3.2.8.1.1.4' => 'brainpoolP192t1', '1.3.36.3.3.2.8.1.1.5' => 'brainpoolP224r1', '1.3.36.3.3.2.8.1.1.6' => 'brainpoolP224t1', '1.3.36.3.3.2.8.1.1.7' => 'brainpoolP256r1', '1.3.36.3.3.2.8.1.1.8' => 'brainpoolP256t1', '1.3.36.3.3.2.8.1.1.9' => 'brainpoolP320r1', '1.3.36.3.3.2.8.1.1.10' => 'brainpoolP320t1', '1.3.36.3.3.2.8.1.1.11' => 'brainpoolP384r1', '1.3.36.3.3.2.8.1.1.12' => 'brainpoolP384t1', '1.3.36.3.3.2.8.1.1.13' => 'brainpoolP512r1', '1.3.36.3.3.2.8.1.1.14' => 'brainpoolP512t1', '1.3.133.16.840.63.0' => 'x9-63-scheme', '1.3.132.1' => 'secg-scheme', '1.3.133.16.840.63.0.2' => 'dhSinglePass-stdDH-sha1kdf-scheme', '1.3.132.1.11.0' => 'dhSinglePass-stdDH-sha224kdf-scheme', '1.3.132.1.11.1' => 'dhSinglePass-stdDH-sha256kdf-scheme', '1.3.132.1.11.2' => 'dhSinglePass-stdDH-sha384kdf-scheme', '1.3.132.1.11.3' => 'dhSinglePass-stdDH-sha512kdf-scheme', '1.3.133.16.840.63.0.3' => 'dhSinglePass-cofactorDH-sha1kdf-scheme', '1.3.132.1.14.0' => 'dhSinglePass-cofactorDH-sha224kdf-scheme', '1.3.132.1.14.1' => 'dhSinglePass-cofactorDH-sha256kdf-scheme', '1.3.132.1.14.2' => 'dhSinglePass-cofactorDH-sha384kdf-scheme', '1.3.132.1.14.3' => 'dhSinglePass-cofactorDH-sha512kdf-scheme', '1.3.6.1.4.1.11129.2.4.2' => 'CT Precertificate SCTs', '1.3.6.1.4.1.11129.2.4.3' => 'CT Precertificate Poison', '1.3.6.1.4.1.11129.2.4.4' => 'CT Precertificate Signer', '1.3.6.1.4.1.11129.2.4.5' => 'CT Certificate SCTs', '1.3.6.1.4.1.311.60.2.1.1' => 'jurisdictionLocalityName', '1.3.6.1.4.1.311.60.2.1.2' => 'jurisdictionStateOrProvinceName', '1.3.6.1.4.1.311.60.2.1.3' => 'jurisdictionCountryName', '1.3.6.1.4.1.11591.4.11' => 'id-scrypt', ]; if (array_key_exists($oidString, $oids)) { return $oids[$oidString]; } switch ($oidString) { case self::RSA_ENCRYPTION: return 'RSA Encryption'; case self::MD5_WITH_RSA_ENCRYPTION: return 'MD5 with RSA Encryption'; case self::SHA1_WITH_RSA_SIGNATURE: return 'SHA-1 with RSA Signature'; case self::PKCS9_EMAIL: return 'PKCS #9 Email Address'; case self::PKCS9_UNSTRUCTURED_NAME: return 'PKCS #9 Unstructured Name'; case self::PKCS9_CONTENT_TYPE: return 'PKCS #9 Content Type'; case self::PKCS9_MESSAGE_DIGEST: return 'PKCS #9 Message Digest'; case self::PKCS9_SIGNING_TIME: return 'PKCS #9 Signing Time'; case self::COMMON_NAME: return 'Common Name'; case self::SURNAME: return 'Surname'; case self::SERIAL_NUMBER: return 'Serial Number'; case self::COUNTRY_NAME: return 'Country Name'; case self::LOCALITY_NAME: return 'Locality Name'; case self::STATE_OR_PROVINCE_NAME: return 'State or Province Name'; case self::STREET_ADDRESS: return 'Street Address'; case self::ORGANIZATION_NAME: return 'Organization Name'; case self::OU_NAME: return 'Organization Unit Name'; case self::TITLE: return 'Title'; case self::DESCRIPTION: return 'Description'; case self::POSTAL_ADDRESS: return 'Postal Address'; case self::POSTAL_CODE: return 'Postal Code'; case self::AUTHORITY_REVOCATION_LIST: return 'Authority Revocation List'; case self::CERT_EXT_SUBJECT_DIRECTORY_ATTR: return 'Subject directory attributes'; case self::CERT_EXT_SUBJECT_KEY_IDENTIFIER: return 'Subject key identifier'; case self::CERT_EXT_KEY_USAGE: return 'Key usage certificate extension'; case self::CERT_EXT_PRIVATE_KEY_USAGE_PERIOD: return 'Private key usage'; case self::CERT_EXT_SUBJECT_ALT_NAME: return 'Subject alternative name (SAN)'; case self::CERT_EXT_ISSUER_ALT_NAME: return 'Issuer alternative name'; case self::CERT_EXT_BASIC_CONSTRAINTS: return 'Basic constraints'; case self::CERT_EXT_CRL_NUMBER: return 'CRL number'; case self::CERT_EXT_REASON_CODE: return 'Reason code'; case self::CERT_EXT_INVALIDITY_DATE: return 'Invalidity code'; case self::CERT_EXT_DELTA_CRL_INDICATOR: return 'Delta CRL indicator'; case self::CERT_EXT_ISSUING_DIST_POINT: return 'Issuing distribution point'; case self::CERT_EXT_CERT_ISSUER: return 'Certificate issuer'; case self::CERT_EXT_NAME_CONSTRAINTS: return 'Name constraints'; case self::CERT_EXT_CRL_DISTRIBUTION_POINTS: return 'CRL distribution points'; case self::CERT_EXT_CERT_POLICIES: return 'Certificate policies '; case self::CERT_EXT_AUTHORITY_KEY_IDENTIFIER: return 'Authority key identifier'; case self::CERT_EXT_EXTENDED_KEY_USAGE: return 'Extended key usage'; case self::AUTHORITY_INFORMATION_ACCESS: return 'Certificate Authority Information Access (AIA)'; default: if ($loadFromWeb) { return self::loadFromWeb($oidString); } else { return $oidString; } } } public static function loadFromWeb($oidString) { $ch = curl_init("http://oid-info.com/get/{$oidString}"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); $contents = curl_exec($ch); curl_close($ch); // This pattern needs to be updated as soon as the website layout of oid-info.com changes preg_match_all('#<tt>(.+)\(\d+\)</tt>#si', $contents, $oidName); if (empty($oidName[1])) { return "{$oidString} (unknown)"; } $oidName = ucfirst(strtolower(preg_replace('/([A-Z][a-z])/', ' $1', $oidName[1][0]))); $oidName = str_replace('-', ' ', $oidName); return "{$oidName} ({$oidString})"; } } Exception/NotImplementedException.php 0000644 00000000521 15176121033 0014013 0 ustar 00 <?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\ASN1\Exception; class NotImplementedException extends \Exception { } Exception/ParserException.php 0000644 00000001277 15176121033 0012334 0 ustar 00 <?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\ASN1\Exception; class ParserException extends \Exception { private $errorMessage; private $offset; public function __construct($errorMessage, $offset) { $this->errorMessage = $errorMessage; $this->offset = $offset; parent::__construct("ASN.1 Parser Exception at offset {$this->offset}: {$this->errorMessage}"); } public function getOffset() { return $this->offset; } } Parsable.php 0000644 00000001771 15176121033 0007013 0 ustar 00 <?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\ASN1; use FG\ASN1\Exception\ParserException; /** * The Parsable interface describes classes that can be parsed from their binary DER representation. */ interface Parsable { /** * Parse an instance of this class from its binary DER encoded representation. * * @param string $binaryData * @param int $offsetIndex the offset at which parsing of the $binaryData is started. This parameter ill be modified * to contain the offset index of the next object after this object has been parsed * * @throws ParserException if the given binary data is either invalid or not currently supported * * @return static */ public static function fromBinary(&$binaryData, &$offsetIndex = null); } AbstractTime.php 0000644 00000004445 15176121033 0007645 0 ustar 00 <?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\ASN1; use DateInterval; use DateTime; use DateTimeZone; use Exception; abstract class AbstractTime extends ASNObject { /** @var DateTime */ protected $value; public function __construct($dateTime = null, $dateTimeZone = 'UTC') { if ($dateTime == null || is_string($dateTime)) { $timeZone = new DateTimeZone($dateTimeZone); $dateTimeObject = new DateTime($dateTime, $timeZone); if ($dateTimeObject == false) { $errorMessage = $this->getLastDateTimeErrors(); $className = Identifier::getName($this->getType()); throw new Exception(sprintf("Could not create %s from date time string '%s': %s", $className, $dateTime, $errorMessage)); } $dateTime = $dateTimeObject; } elseif (!$dateTime instanceof DateTime) { throw new Exception('Invalid first argument for some instance of AbstractTime constructor'); } $this->value = $dateTime; } public function getContent() { return $this->value; } protected function getLastDateTimeErrors() { $messages = ''; $lastErrors = DateTime::getLastErrors() ?: ['errors' => []]; foreach ($lastErrors['errors'] as $errorMessage) { $messages .= "{$errorMessage}, "; } return substr($messages, 0, -2); } public function __toString() { return $this->value->format("Y-m-d\tH:i:s"); } protected static function extractTimeZoneData(&$binaryData, &$offsetIndex, DateTime $dateTime) { $sign = $binaryData[$offsetIndex++]; $timeOffsetHours = intval(substr($binaryData, $offsetIndex, 2)); $timeOffsetMinutes = intval(substr($binaryData, $offsetIndex + 2, 2)); $offsetIndex += 4; $interval = new DateInterval("PT{$timeOffsetHours}H{$timeOffsetMinutes}M"); if ($sign == '+') { $dateTime->sub($interval); } else { $dateTime->add($interval); } return $dateTime; } } ASNObject.php 0000644 00000031534 15176121033 0007032 0 ustar 00 <?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\ASN1; use FG\ASN1\Exception\ParserException; use FG\ASN1\Universal\BitString; use FG\ASN1\Universal\Boolean; use FG\ASN1\Universal\Enumerated; use FG\ASN1\Universal\GeneralizedTime; use FG\ASN1\Universal\Integer; use FG\ASN1\Universal\NullObject; use FG\ASN1\Universal\ObjectIdentifier; use FG\ASN1\Universal\RelativeObjectIdentifier; use FG\ASN1\Universal\OctetString; use FG\ASN1\Universal\Sequence; use FG\ASN1\Universal\Set; use FG\ASN1\Universal\UTCTime; use FG\ASN1\Universal\IA5String; use FG\ASN1\Universal\PrintableString; use FG\ASN1\Universal\NumericString; use FG\ASN1\Universal\UTF8String; use FG\ASN1\Universal\UniversalString; use FG\ASN1\Universal\CharacterString; use FG\ASN1\Universal\GeneralString; use FG\ASN1\Universal\VisibleString; use FG\ASN1\Universal\GraphicString; use FG\ASN1\Universal\BMPString; use FG\ASN1\Universal\T61String; use FG\ASN1\Universal\ObjectDescriptor; use FG\Utility\BigInteger; use LogicException; /** * Class ASNObject is the base class for all concrete ASN.1 objects. */ abstract class ASNObject implements Parsable { private $contentLength; private $nrOfLengthOctets; /** * Must return the number of octets of the content part. * * @return int */ abstract protected function calculateContentLength(); /** * Encode the object using DER encoding. * * @see http://en.wikipedia.org/wiki/X.690#DER_encoding * * @return string the binary representation of an objects value */ abstract protected function getEncodedValue(); /** * Return the content of this object in a non encoded form. * This can be used to print the value in human readable form. * * @return mixed */ abstract public function getContent(); /** * Return the object type octet. * This should use the class constants of Identifier. * * @see Identifier * * @return int */ abstract public function getType(); /** * Returns all identifier octets. If an inheriting class models a tag with * the long form identifier format, it MUST reimplement this method to * return all octets of the identifier. * * @throws LogicException If the identifier format is long form * * @return string Identifier as a set of octets */ public function getIdentifier() { $firstOctet = $this->getType(); if (Identifier::isLongForm($firstOctet)) { throw new LogicException(sprintf('Identifier of %s uses the long form and must therefor override "ASNObject::getIdentifier()".', get_class($this))); } return chr($firstOctet); } /** * Encode this object using DER encoding. * * @return string the full binary representation of the complete object */ public function getBinary() { $result = $this->getIdentifier(); $result .= $this->createLengthPart(); $result .= $this->getEncodedValue(); return $result; } private function createLengthPart() { $contentLength = $this->getContentLength(); $nrOfLengthOctets = $this->getNumberOfLengthOctets($contentLength); if ($nrOfLengthOctets == 1) { return chr($contentLength); } else { // the first length octet determines the number subsequent length octets $lengthOctets = chr(0x80 | ($nrOfLengthOctets - 1)); for ($shiftLength = 8 * ($nrOfLengthOctets - 2); $shiftLength >= 0; $shiftLength -= 8) { $lengthOctets .= chr($contentLength >> $shiftLength); } return $lengthOctets; } } protected function getNumberOfLengthOctets($contentLength = null) { if (!isset($this->nrOfLengthOctets)) { if ($contentLength == null) { $contentLength = $this->getContentLength(); } $this->nrOfLengthOctets = 1; if ($contentLength > 127) { do { // long form $this->nrOfLengthOctets++; $contentLength = $contentLength >> 8; } while ($contentLength > 0); } } return $this->nrOfLengthOctets; } protected function getContentLength() { if (!isset($this->contentLength)) { $this->contentLength = $this->calculateContentLength(); } return $this->contentLength; } protected function setContentLength($newContentLength) { $this->contentLength = $newContentLength; $this->getNumberOfLengthOctets($newContentLength); } /** * Returns the length of the whole object (including the identifier and length octets). */ public function getObjectLength() { $nrOfIdentifierOctets = strlen($this->getIdentifier()); $contentLength = $this->getContentLength(); $nrOfLengthOctets = $this->getNumberOfLengthOctets($contentLength); return $nrOfIdentifierOctets + $nrOfLengthOctets + $contentLength; } public function __toString() { return $this->getContent(); } /** * Returns the name of the ASN.1 Type of this object. * * @see Identifier::getName() */ public function getTypeName() { return Identifier::getName($this->getType()); } /** * @param string $binaryData * @param int $offsetIndex * * @throws ParserException * * @return \FG\ASN1\ASNObject */ public static function fromBinary(&$binaryData, &$offsetIndex = 0) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse binary from data: Offset index larger than input size', $offsetIndex); } $identifierOctet = ord($binaryData[$offsetIndex]); if (Identifier::isContextSpecificClass($identifierOctet) && Identifier::isConstructed($identifierOctet)) { return ExplicitlyTaggedObject::fromBinary($binaryData, $offsetIndex); } switch ($identifierOctet) { case Identifier::BITSTRING: return BitString::fromBinary($binaryData, $offsetIndex); case Identifier::BOOLEAN: return Boolean::fromBinary($binaryData, $offsetIndex); case Identifier::ENUMERATED: return Enumerated::fromBinary($binaryData, $offsetIndex); case Identifier::INTEGER: return Integer::fromBinary($binaryData, $offsetIndex); case Identifier::NULL: return NullObject::fromBinary($binaryData, $offsetIndex); case Identifier::OBJECT_IDENTIFIER: return ObjectIdentifier::fromBinary($binaryData, $offsetIndex); case Identifier::RELATIVE_OID: return RelativeObjectIdentifier::fromBinary($binaryData, $offsetIndex); case Identifier::OCTETSTRING: return OctetString::fromBinary($binaryData, $offsetIndex); case Identifier::SEQUENCE: return Sequence::fromBinary($binaryData, $offsetIndex); case Identifier::SET: return Set::fromBinary($binaryData, $offsetIndex); case Identifier::UTC_TIME: return UTCTime::fromBinary($binaryData, $offsetIndex); case Identifier::GENERALIZED_TIME: return GeneralizedTime::fromBinary($binaryData, $offsetIndex); case Identifier::IA5_STRING: return IA5String::fromBinary($binaryData, $offsetIndex); case Identifier::PRINTABLE_STRING: return PrintableString::fromBinary($binaryData, $offsetIndex); case Identifier::NUMERIC_STRING: return NumericString::fromBinary($binaryData, $offsetIndex); case Identifier::UTF8_STRING: return UTF8String::fromBinary($binaryData, $offsetIndex); case Identifier::UNIVERSAL_STRING: return UniversalString::fromBinary($binaryData, $offsetIndex); case Identifier::CHARACTER_STRING: return CharacterString::fromBinary($binaryData, $offsetIndex); case Identifier::GENERAL_STRING: return GeneralString::fromBinary($binaryData, $offsetIndex); case Identifier::VISIBLE_STRING: return VisibleString::fromBinary($binaryData, $offsetIndex); case Identifier::GRAPHIC_STRING: return GraphicString::fromBinary($binaryData, $offsetIndex); case Identifier::BMP_STRING: return BMPString::fromBinary($binaryData, $offsetIndex); case Identifier::T61_STRING: return T61String::fromBinary($binaryData, $offsetIndex); case Identifier::OBJECT_DESCRIPTOR: return ObjectDescriptor::fromBinary($binaryData, $offsetIndex); default: // At this point the identifier may be >1 byte. if (Identifier::isConstructed($identifierOctet)) { return new UnknownConstructedObject($binaryData, $offsetIndex); } else { $identifier = self::parseBinaryIdentifier($binaryData, $offsetIndex); $lengthOfUnknownObject = self::parseContentLength($binaryData, $offsetIndex); $offsetIndex += $lengthOfUnknownObject; return new UnknownObject($identifier, $lengthOfUnknownObject); } } } protected static function parseIdentifier($identifierOctet, $expectedIdentifier, $offsetForExceptionHandling) { if (is_string($identifierOctet) || is_numeric($identifierOctet) == false) { $identifierOctet = ord($identifierOctet); } if ($identifierOctet != $expectedIdentifier) { $message = 'Can not create an '.Identifier::getName($expectedIdentifier).' from an '.Identifier::getName($identifierOctet); throw new ParserException($message, $offsetForExceptionHandling); } } protected static function parseBinaryIdentifier($binaryData, &$offsetIndex) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse identifier from data: Offset index larger than input size', $offsetIndex); } $identifier = $binaryData[$offsetIndex++]; if (Identifier::isLongForm(ord($identifier)) == false) { return $identifier; } while (true) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse identifier (long form) from data: Offset index larger than input size', $offsetIndex); } $nextOctet = $binaryData[$offsetIndex++]; $identifier .= $nextOctet; if ((ord($nextOctet) & 0x80) === 0) { // the most significant bit is 0 to we have reached the end of the identifier break; } } return $identifier; } protected static function parseContentLength(&$binaryData, &$offsetIndex, $minimumLength = 0) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse content length from data: Offset index larger than input size', $offsetIndex); } $contentLength = ord($binaryData[$offsetIndex++]); if (($contentLength & 0x80) != 0) { // bit 8 is set -> this is the long form $nrOfLengthOctets = $contentLength & 0x7F; $contentLength = BigInteger::create(0x00); for ($i = 0; $i < $nrOfLengthOctets; $i++) { if (strlen($binaryData) <= $offsetIndex) { throw new ParserException('Can not parse content length (long form) from data: Offset index larger than input size', $offsetIndex); } $contentLength = $contentLength->shiftLeft(8)->add(ord($binaryData[$offsetIndex++])); } if ($contentLength->compare(PHP_INT_MAX) > 0) { throw new ParserException("Can not parse content length from data: length > maximum integer", $offsetIndex); } $contentLength = $contentLength->toInteger(); } if ($contentLength < $minimumLength) { throw new ParserException('A '.get_called_class()." should have a content length of at least {$minimumLength}. Extracted length was {$contentLength}", $offsetIndex); } $lenDataRemaining = strlen($binaryData) - $offsetIndex; if ($lenDataRemaining < $contentLength) { throw new ParserException("Content length {$contentLength} exceeds remaining data length {$lenDataRemaining}", $offsetIndex); } return $contentLength; } } Identifier.php 0000644 00000025106 15176121033 0007342 0 ustar 00 <?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\ASN1; use Exception; /** * The Identifier encodes the ASN.1 tag (class and number) of the type of a data value. * * Every identifier whose number is in the range 0 to 30 has the following structure: * * Bits: 8 7 6 5 4 3 2 1 * | Class | P/C | Tag number | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Bits 8 and 7 define the class of this type ( Universal, Application, Context-specific or Private). * Bit 6 encoded whether this type is primitive or constructed * The remaining bits 5 - 1 encode the tag number */ class Identifier { const CLASS_UNIVERSAL = 0x00; const CLASS_APPLICATION = 0x01; const CLASS_CONTEXT_SPECIFIC = 0x02; const CLASS_PRIVATE = 0x03; const EOC = 0x00; // unsupported for now const BOOLEAN = 0x01; const INTEGER = 0x02; const BITSTRING = 0x03; const OCTETSTRING = 0x04; const NULL = 0x05; const OBJECT_IDENTIFIER = 0x06; const OBJECT_DESCRIPTOR = 0x07; const EXTERNAL = 0x08; // unsupported for now const REAL = 0x09; // unsupported for now const ENUMERATED = 0x0A; const EMBEDDED_PDV = 0x0B; // unsupported for now const UTF8_STRING = 0x0C; const RELATIVE_OID = 0x0D; // value 0x0E and 0x0F are reserved for future use const SEQUENCE = 0x30; const SET = 0x31; const NUMERIC_STRING = 0x12; const PRINTABLE_STRING = 0x13; const T61_STRING = 0x14; // sometimes referred to as TeletextString const VIDEOTEXT_STRING = 0x15; const IA5_STRING = 0x16; const UTC_TIME = 0x17; const GENERALIZED_TIME = 0x18; const GRAPHIC_STRING = 0x19; const VISIBLE_STRING = 0x1A; const GENERAL_STRING = 0x1B; const UNIVERSAL_STRING = 0x1C; const CHARACTER_STRING = 0x1D; // Unrestricted character type const BMP_STRING = 0x1E; const LONG_FORM = 0x1F; const IS_CONSTRUCTED = 0x20; /** * Creates an identifier. Short form identifiers are returned as integers * for BC, long form identifiers will be returned as a string of octets. * * @param int $class * @param bool $isConstructed * @param int $tagNumber * * @throws Exception if the given arguments are invalid * * @return int|string */ public static function create($class, $isConstructed, $tagNumber) { if (!is_numeric($class) || $class < self::CLASS_UNIVERSAL || $class > self::CLASS_PRIVATE) { throw new Exception(sprintf('Invalid class %d given', $class)); } if (!is_bool($isConstructed)) { throw new Exception("\$isConstructed must be a boolean value ($isConstructed given)"); } $tagNumber = self::makeNumeric($tagNumber); if ($tagNumber < 0) { throw new Exception(sprintf('Invalid $tagNumber %d given. You can only use positive integers.', $tagNumber)); } if ($tagNumber < self::LONG_FORM) { return ($class << 6) | ($isConstructed << 5) | $tagNumber; } $firstOctet = ($class << 6) | ($isConstructed << 5) | self::LONG_FORM; // Tag numbers formatted in long form are base-128 encoded. See X.609#8.1.2.4 return chr($firstOctet).Base128::encode($tagNumber); } public static function isConstructed($identifierOctet) { return ($identifierOctet & self::IS_CONSTRUCTED) === self::IS_CONSTRUCTED; } public static function isLongForm($identifierOctet) { return ($identifierOctet & self::LONG_FORM) === self::LONG_FORM; } /** * Return the name of the mapped ASN.1 type with a preceding "ASN.1 ". * * Example: ASN.1 Octet String * * @see Identifier::getShortName() * * @param int|string $identifier * * @return string */ public static function getName($identifier) { $identifierOctet = self::makeNumeric($identifier); $typeName = static::getShortName($identifier); if (($identifierOctet & self::LONG_FORM) < self::LONG_FORM) { $typeName = "ASN.1 {$typeName}"; } return $typeName; } /** * Return the short version of the type name. * * If the given identifier octet can be mapped to a known universal type this will * return its name. Else Identifier::getClassDescription() is used to retrieve * information about the identifier. * * @see Identifier::getName() * @see Identifier::getClassDescription() * * @param int|string $identifier * * @return string */ public static function getShortName($identifier) { $identifierOctet = self::makeNumeric($identifier); switch ($identifierOctet) { case self::EOC: return 'End-of-contents octet'; case self::BOOLEAN: return 'Boolean'; case self::INTEGER: return 'Integer'; case self::BITSTRING: return 'Bit String'; case self::OCTETSTRING: return 'Octet String'; case self::NULL: return 'NULL'; case self::OBJECT_IDENTIFIER: return 'Object Identifier'; case self::OBJECT_DESCRIPTOR: return 'Object Descriptor'; case self::EXTERNAL: return 'External Type'; case self::REAL: return 'Real'; case self::ENUMERATED: return 'Enumerated'; case self::EMBEDDED_PDV: return 'Embedded PDV'; case self::UTF8_STRING: return 'UTF8 String'; case self::RELATIVE_OID: return 'Relative OID'; case self::SEQUENCE: return 'Sequence'; case self::SET: return 'Set'; case self::NUMERIC_STRING: return 'Numeric String'; case self::PRINTABLE_STRING: return 'Printable String'; case self::T61_STRING: return 'T61 String'; case self::VIDEOTEXT_STRING: return 'Videotext String'; case self::IA5_STRING: return 'IA5 String'; case self::UTC_TIME: return 'UTC Time'; case self::GENERALIZED_TIME: return 'Generalized Time'; case self::GRAPHIC_STRING: return 'Graphic String'; case self::VISIBLE_STRING: return 'Visible String'; case self::GENERAL_STRING: return 'General String'; case self::UNIVERSAL_STRING: return 'Universal String'; case self::CHARACTER_STRING: return 'Character String'; case self::BMP_STRING: return 'BMP String'; case 0x0E: return 'RESERVED (0x0E)'; case 0x0F: return 'RESERVED (0x0F)'; case self::LONG_FORM: default: $classDescription = self::getClassDescription($identifier); if (is_int($identifier)) { $identifier = chr($identifier); } return "$classDescription (0x".strtoupper(bin2hex($identifier)).')'; } } /** * Returns a textual description of the information encoded in a given identifier octet. * * The first three (most significant) bytes are evaluated to determine if this is a * constructed or primitive type and if it is either universal, application, context-specific or * private. * * Example: * Constructed context-specific * Primitive universal * * @param int|string $identifier * * @return string */ public static function getClassDescription($identifier) { $identifierOctet = self::makeNumeric($identifier); if (self::isConstructed($identifierOctet)) { $classDescription = 'Constructed '; } else { $classDescription = 'Primitive '; } $classBits = $identifierOctet >> 6; switch ($classBits) { case self::CLASS_UNIVERSAL: $classDescription .= 'universal'; break; case self::CLASS_APPLICATION: $classDescription .= 'application'; break; case self::CLASS_CONTEXT_SPECIFIC: $tagNumber = self::getTagNumber($identifier); $classDescription = "[$tagNumber] Context-specific"; break; case self::CLASS_PRIVATE: $classDescription .= 'private'; break; default: return "INVALID IDENTIFIER OCTET: {$identifierOctet}"; } return $classDescription; } /** * @param int|string $identifier * * @return int */ public static function getTagNumber($identifier) { $firstOctet = self::makeNumeric($identifier); $tagNumber = $firstOctet & self::LONG_FORM; if ($tagNumber < self::LONG_FORM) { return $tagNumber; } if (is_numeric($identifier)) { $identifier = chr($identifier); } return Base128::decode(substr($identifier, 1)); } public static function isUniversalClass($identifier) { $identifier = self::makeNumeric($identifier); return $identifier >> 6 == self::CLASS_UNIVERSAL; } public static function isApplicationClass($identifier) { $identifier = self::makeNumeric($identifier); return $identifier >> 6 == self::CLASS_APPLICATION; } public static function isContextSpecificClass($identifier) { $identifier = self::makeNumeric($identifier); return $identifier >> 6 == self::CLASS_CONTEXT_SPECIFIC; } public static function isPrivateClass($identifier) { $identifier = self::makeNumeric($identifier); return $identifier >> 6 == self::CLASS_PRIVATE; } private static function makeNumeric($identifierOctet) { if (!is_numeric($identifierOctet)) { return ord($identifierOctet); } else { return $identifierOctet; } } } Universal/NumericString.php 0000644 00000001511 15176121033 0012013 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class NumericString extends AbstractString { /** * Creates a new ASN.1 NumericString. * * The following characters are permitted: * Digits 0,1, ... 9 * SPACE (space) * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowNumbers(); $this->allowSpaces(); } public function getType() { return Identifier::NUMERIC_STRING; } } Universal/NullObject.php 0000644 00000002440 15176121033 0011265 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\ASNObject; use FG\ASN1\Parsable; use FG\ASN1\Identifier; use FG\ASN1\Exception\ParserException; class NullObject extends ASNObject implements Parsable { public function getType() { return Identifier::NULL; } protected function calculateContentLength() { return 0; } protected function getEncodedValue() { return null; } public function getContent() { return 'NULL'; } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::NULL, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex); if ($contentLength != 0) { throw new ParserException("An ASN.1 Null should not have a length other than zero. Extracted length was {$contentLength}", $offsetIndex); } $parsedObject = new self(); $parsedObject->setContentLength(0); return $parsedObject; } } Universal/IA5String.php 0000644 00000001437 15176121033 0010776 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; /** * The International Alphabet No.5 (IA5) references the encoding of the ASCII characters. * * Each character in the data is encoded as 1 byte. */ class IA5String extends AbstractString { public function __construct($string) { parent::__construct($string); for ($i = 1; $i < 128; $i++) { $this->allowCharacter(chr($i)); } } public function getType() { return Identifier::IA5_STRING; } } Universal/BMPString.php 0000644 00000002071 15176121033 0011031 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class BMPString extends AbstractString { /** * Creates a new ASN.1 BMP String. * * BMPString is a subtype of UniversalString that has its own * unique tag and contains only the characters in the * Basic Multilingual Plane (those corresponding to the first * 64K-2 cells, less cells whose encoding is used to address * characters outside the Basic Multilingual Plane) of ISO/IEC 10646-1. * * TODO The encodable characters of this type are not yet checked. * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::BMP_STRING; } } Universal/Boolean.php 0000644 00000003403 15176121033 0010603 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\ASNObject; use FG\ASN1\Parsable; use FG\ASN1\Identifier; use FG\ASN1\Exception\ParserException; class Boolean extends ASNObject implements Parsable { private $value; /** * @param bool $value */ public function __construct($value) { $this->value = $value; } public function getType() { return Identifier::BOOLEAN; } protected function calculateContentLength() { return 1; } protected function getEncodedValue() { if ($this->value == false) { return chr(0x00); } else { return chr(0xFF); } } public function getContent() { if ($this->value == true) { return 'TRUE'; } else { return 'FALSE'; } } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::BOOLEAN, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex); if ($contentLength != 1) { throw new ParserException("An ASN.1 Boolean should not have a length other than one. Extracted length was {$contentLength}", $offsetIndex); } $value = ord($binaryData[$offsetIndex++]); $booleanValue = $value == 0xFF ? true : false; $parsedObject = new self($booleanValue); $parsedObject->setContentLength($contentLength); return $parsedObject; } } Universal/OctetString.php 0000644 00000004411 15176121033 0011471 0 ustar 00 <?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\ASN1\Universal; use Exception; use FG\ASN1\ASNObject; use FG\ASN1\Parsable; use FG\ASN1\Identifier; class OctetString extends ASNObject implements Parsable { protected $value; public function __construct($value) { if (is_string($value)) { // remove gaps between hex digits $value = preg_replace('/\s|0x/', '', $value); } elseif (is_numeric($value)) { $value = dechex($value); } elseif ($value === null) { return; } else { throw new Exception('OctetString: unrecognized input type!'); } if (strlen($value) % 2 != 0) { // transform values like 1F2 to 01F2 $value = '0'.$value; } $this->value = $value; } public function getType() { return Identifier::OCTETSTRING; } protected function calculateContentLength() { return strlen($this->value) / 2; } protected function getEncodedValue() { $value = $this->value; $result = ''; //Actual content while (strlen($value) >= 2) { // get the hex value byte by byte from the string and and add it to binary result $result .= chr(hexdec(substr($value, 0, 2))); $value = substr($value, 2); } return $result; } public function getContent() { return strtoupper($this->value); } public function getBinaryContent() { return $this->getEncodedValue(); } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::OCTETSTRING, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex); $value = substr($binaryData, $offsetIndex, $contentLength); $offsetIndex += $contentLength; $parsedObject = new self(bin2hex($value)); $parsedObject->setContentLength($contentLength); return $parsedObject; } } Universal/PrintableString.php 0000644 00000002577 15176121033 0012346 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class PrintableString extends AbstractString { /** * Creates a new ASN.1 PrintableString. * * The ITU-T X.680 Table 8 permits the following characters: * Latin capital letters A,B, ... Z * Latin small letters a,b, ... z * Digits 0,1, ... 9 * SPACE (space) * APOSTROPHE ' * LEFT PARENTHESIS ( * RIGHT PARENTHESIS ) * PLUS SIGN + * COMMA , * HYPHEN-MINUS - * FULL STOP . * SOLIDUS / * COLON : * EQUALS SIGN = * QUESTION MARK ? * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowNumbers(); $this->allowAllLetters(); $this->allowSpaces(); $this->allowCharacters("'", '(', ')', '+', '-', '.', ',', '/', ':', '=', '?'); } public function getType() { return Identifier::PRINTABLE_STRING; } } Universal/BitString.php 0000644 00000005465 15176121033 0011143 0 ustar 00 <?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\ASN1\Universal; use Exception; use FG\ASN1\Exception\ParserException; use FG\ASN1\Parsable; use FG\ASN1\Identifier; class BitString extends OctetString implements Parsable { private $nrOfUnusedBits; /** * Creates a new ASN.1 BitString object. * * @param string|int $value Either the hexadecimal value as a string (spaces are allowed - leading 0x is optional) or a numeric value * @param int $nrOfUnusedBits the number of unused bits in the last octet [optional]. * * @throws Exception if the second parameter is no positive numeric value */ public function __construct($value, $nrOfUnusedBits = 0) { parent::__construct($value); if (!is_numeric($nrOfUnusedBits) || $nrOfUnusedBits < 0) { throw new Exception('BitString: second parameter needs to be a positive number (or zero)!'); } $this->nrOfUnusedBits = $nrOfUnusedBits; } public function getType() { return Identifier::BITSTRING; } protected function calculateContentLength() { // add one to the length for the first octet which encodes the number of unused bits in the last octet return parent::calculateContentLength() + 1; } protected function getEncodedValue() { // the first octet determines the number of unused bits $nrOfUnusedBitsOctet = chr($this->nrOfUnusedBits); $actualContent = parent::getEncodedValue(); return $nrOfUnusedBitsOctet.$actualContent; } public function getNumberOfUnusedBits() { return $this->nrOfUnusedBits; } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::BITSTRING, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex, 2); $nrOfUnusedBits = ord($binaryData[$offsetIndex]); $value = substr($binaryData, $offsetIndex + 1, $contentLength - 1); if ($nrOfUnusedBits > 7 || // no less than 1 used, otherwise non-minimal ($contentLength - 1) == 1 && $nrOfUnusedBits > 0 || // content length only 1, no (ord($value[strlen($value)-1])&((1<<$nrOfUnusedBits)-1)) != 0 // unused bits set ) { throw new ParserException("Can not parse bit string with invalid padding", $offsetIndex); } $offsetIndex += $contentLength; $parsedObject = new self(bin2hex($value), $nrOfUnusedBits); $parsedObject->setContentLength($contentLength); return $parsedObject; } } Universal/VisibleString.php 0000644 00000001354 15176121033 0012013 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class VisibleString extends AbstractString { /** * Creates a new ASN.1 Visible String. * TODO The encodable characters of this type are not yet checked. * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::VISIBLE_STRING; } } Universal/UniversalString.php 0000644 00000001472 15176121033 0012367 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class UniversalString extends AbstractString { /** * Creates a new ASN.1 Universal String. * TODO The encodable characters of this type are not yet checked. * * @see http://en.wikipedia.org/wiki/Universal_Character_Set * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::UNIVERSAL_STRING; } } Universal/RelativeObjectIdentifier.php 0000644 00000003460 15176121033 0014134 0 ustar 00 <?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\ASN1\Universal; use Exception; use FG\ASN1\Parsable; use FG\ASN1\Identifier; use FG\ASN1\Exception\ParserException; class RelativeObjectIdentifier extends ObjectIdentifier implements Parsable { public function __construct($subIdentifiers) { $this->value = $subIdentifiers; $this->subIdentifiers = explode('.', $subIdentifiers); $nrOfSubIdentifiers = count($this->subIdentifiers); for ($i = 0; $i < $nrOfSubIdentifiers; $i++) { if (is_numeric($this->subIdentifiers[$i])) { // enforce the integer type $this->subIdentifiers[$i] = intval($this->subIdentifiers[$i]); } else { throw new Exception("[{$subIdentifiers}] is no valid object identifier (sub identifier ".($i + 1).' is not numeric)!'); } } } public function getType() { return Identifier::RELATIVE_OID; } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::RELATIVE_OID, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex, 1); try { $oidString = self::parseOid($binaryData, $offsetIndex, $contentLength); } catch (ParserException $e) { throw new ParserException('Malformed ASN.1 Relative Object Identifier', $e->getOffset()); } $parsedObject = new self($oidString); $parsedObject->setContentLength($contentLength); return $parsedObject; } } Universal/Sequence.php 0000644 00000000752 15176121033 0011000 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\Construct; use FG\ASN1\Parsable; use FG\ASN1\Identifier; class Sequence extends Construct implements Parsable { public function getType() { return Identifier::SEQUENCE; } } Universal/Integer.php 0000644 00000007446 15176121033 0010634 0 ustar 00 <?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\ASN1\Universal; use Exception; use FG\Utility\BigInteger; use FG\ASN1\Exception\ParserException; use FG\ASN1\ASNObject; use FG\ASN1\Parsable; use FG\ASN1\Identifier; class Integer extends ASNObject implements Parsable { /** @var int */ private $value; /** * @param int $value * * @throws Exception if the value is not numeric */ public function __construct($value) { if (is_numeric($value) == false) { throw new Exception("Invalid VALUE [{$value}] for ASN1_INTEGER"); } $this->value = $value; } public function getType() { return Identifier::INTEGER; } public function getContent() { return $this->value; } protected function calculateContentLength() { return strlen($this->getEncodedValue()); } protected function getEncodedValue() { $value = BigInteger::create($this->value, 10); $negative = $value->compare(0) < 0; if ($negative) { $value = $value->absoluteValue(); $limit = 0x80; } else { $limit = 0x7f; } $mod = 0xff+1; $values = []; while($value->compare($limit) > 0) { $values[] = $value->modulus($mod)->toInteger(); $value = $value->shiftRight(8); } $values[] = $value->modulus($mod)->toInteger(); $numValues = count($values); if ($negative) { for ($i = 0; $i < $numValues; $i++) { $values[$i] = 0xff - $values[$i]; } for ($i = 0; $i < $numValues; $i++) { $values[$i] += 1; if ($values[$i] <= 0xff) { break; } assert($i != $numValues - 1); $values[$i] = 0; } if ($values[$numValues - 1] == 0x7f) { $values[] = 0xff; } } $values = array_reverse($values); $r = pack("C*", ...$values); return $r; } private static function ensureMinimalEncoding($binaryData, $offsetIndex) { // All the first nine bits cannot equal 0 or 1, which would // be non-minimal encoding for positive and negative integers respectively if ((ord($binaryData[$offsetIndex]) == 0x00 && (ord($binaryData[$offsetIndex+1]) & 0x80) == 0) || (ord($binaryData[$offsetIndex]) == 0xff && (ord($binaryData[$offsetIndex+1]) & 0x80) == 0x80)) { throw new ParserException("Integer not minimally encoded", $offsetIndex); } } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $parsedObject = new static(0); self::parseIdentifier($binaryData[$offsetIndex], $parsedObject->getType(), $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex, 1); if ($contentLength > 1) { self::ensureMinimalEncoding($binaryData, $offsetIndex); } $isNegative = (ord($binaryData[$offsetIndex]) & 0x80) != 0x00; $number = BigInteger::create(ord($binaryData[$offsetIndex++]) & 0x7F); for ($i = 0; $i < $contentLength - 1; $i++) { $number = $number->multiply(0x100)->add(ord($binaryData[$offsetIndex++])); } if ($isNegative) { $number = $number->subtract(BigInteger::create(2)->toPower(8 * $contentLength - 1)); } $parsedObject = new static((string)$number); $parsedObject->setContentLength($contentLength); return $parsedObject; } } Universal/CharacterString.php 0000644 00000001112 15176121033 0012302 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class CharacterString extends AbstractString { public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::CHARACTER_STRING; } } Universal/GeneralString.php 0000644 00000001353 15176121033 0011772 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class GeneralString extends AbstractString { /** * Creates a new ASN.1 GeneralString. * TODO The encodable characters of this type are not yet checked. * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::GENERAL_STRING; } } Universal/GraphicString.php 0000644 00000001354 15176121033 0011773 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class GraphicString extends AbstractString { /** * Creates a new ASN.1 Graphic String. * TODO The encodable characters of this type are not yet checked. * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::GRAPHIC_STRING; } } Universal/ObjectDescriptor.php 0000644 00000001060 15176121033 0012466 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\Identifier; class ObjectDescriptor extends GraphicString { public function __construct($objectDescription) { parent::__construct($objectDescription); } public function getType() { return Identifier::OBJECT_DESCRIPTOR; } } Universal/UTF8String.php 0000644 00000001350 15176121033 0011140 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class UTF8String extends AbstractString { /** * Creates a new ASN.1 Universal String. * TODO The encodable characters of this type are not yet checked. * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::UTF8_STRING; } } Universal/UTCTime.php 0000644 00000004601 15176121033 0010477 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractTime; use FG\ASN1\Parsable; use FG\ASN1\Identifier; use FG\ASN1\Exception\ParserException; /** * This ASN.1 universal type contains the calendar date and time. * * The precision is one minute or one second and optionally a * local time differential from coordinated universal time. * * Decoding of this type will accept the Basic Encoding Rules (BER) * The encoding will comply with the Distinguished Encoding Rules (DER). */ class UTCTime extends AbstractTime implements Parsable { public function getType() { return Identifier::UTC_TIME; } protected function calculateContentLength() { return 13; // Content is a string o the following format: YYMMDDhhmmssZ (13 octets) } protected function getEncodedValue() { return $this->value->format('ymdHis').'Z'; } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::UTC_TIME, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex, 11); $format = 'ymdGi'; $dateTimeString = substr($binaryData, $offsetIndex, 10); $offsetIndex += 10; // extract optional seconds part if ($binaryData[$offsetIndex] != 'Z' && $binaryData[$offsetIndex] != '+' && $binaryData[$offsetIndex] != '-') { $dateTimeString .= substr($binaryData, $offsetIndex, 2); $offsetIndex += 2; $format .= 's'; } $dateTime = \DateTime::createFromFormat($format, $dateTimeString, new \DateTimeZone('UTC')); // extract time zone settings if ($binaryData[$offsetIndex] == '+' || $binaryData[$offsetIndex] == '-') { $dateTime = static::extractTimeZoneData($binaryData, $offsetIndex, $dateTime); } elseif ($binaryData[$offsetIndex++] != 'Z') { throw new ParserException('Invalid UTC String', $offsetIndex); } $parsedObject = new self($dateTime); $parsedObject->setContentLength($contentLength); return $parsedObject; } } Universal/Set.php 0000644 00000000636 15176121033 0007764 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\Identifier; class Set extends Sequence { public function getType() { return Identifier::SET; } } Universal/Enumerated.php 0000644 00000000653 15176121033 0011321 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\Identifier; class Enumerated extends Integer { public function getType() { return Identifier::ENUMERATED; } } Universal/T61String.php 0000644 00000001431 15176121033 0010764 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractString; use FG\ASN1\Identifier; class T61String extends AbstractString { /** * Creates a new ASN.1 T61 String. * TODO The encodable characters of this type are not yet checked. * * @see http://en.wikipedia.org/wiki/ITU_T.61 * * @param string $string */ public function __construct($string) { $this->value = $string; $this->allowAll(); } public function getType() { return Identifier::T61_STRING; } } Universal/GeneralizedTime.php 0000644 00000011422 15176121033 0012274 0 ustar 00 <?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\ASN1\Universal; use FG\ASN1\AbstractTime; use FG\ASN1\Parsable; use FG\ASN1\Identifier; use FG\ASN1\Exception\ParserException; /** * This ASN.1 universal type contains date and time information according to ISO 8601. * * The type consists of values representing: * a) a calendar date, as defined in ISO 8601; and * b) a time of day, to any of the precisions defined in ISO 8601, except for the hours value 24 which shall not be used; and * c) the local time differential factor as defined in ISO 8601. * * Decoding of this type will accept the Basic Encoding Rules (BER) * The encoding will comply with the Distinguished Encoding Rules (DER). */ class GeneralizedTime extends AbstractTime implements Parsable { private $microseconds; public function __construct($dateTime = null, $dateTimeZone = 'UTC') { parent::__construct($dateTime, $dateTimeZone); $this->microseconds = $this->value->format('u'); if ($this->containsFractionalSecondsElement()) { // DER requires us to remove trailing zeros $this->microseconds = preg_replace('/([1-9]+)0+$/', '$1', $this->microseconds); } } public function getType() { return Identifier::GENERALIZED_TIME; } protected function calculateContentLength() { $contentSize = 15; // YYYYMMDDHHmmSSZ if ($this->containsFractionalSecondsElement()) { $contentSize += 1 + strlen($this->microseconds); } return $contentSize; } public function containsFractionalSecondsElement() { return intval($this->microseconds) > 0; } protected function getEncodedValue() { $encodedContent = $this->value->format('YmdHis'); if ($this->containsFractionalSecondsElement()) { $encodedContent .= ".{$this->microseconds}"; } return $encodedContent.'Z'; } public function __toString() { if ($this->containsFractionalSecondsElement()) { return $this->value->format("Y-m-d\tH:i:s.uP"); } else { return $this->value->format("Y-m-d\tH:i:sP"); } } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::GENERALIZED_TIME, $offsetIndex++); $lengthOfMinimumTimeString = 14; // YYYYMMDDHHmmSS $contentLength = self::parseContentLength($binaryData, $offsetIndex, $lengthOfMinimumTimeString); $maximumBytesToRead = $contentLength; $format = 'YmdGis'; $content = substr($binaryData, $offsetIndex, $contentLength); $dateTimeString = substr($content, 0, $lengthOfMinimumTimeString); $offsetIndex += $lengthOfMinimumTimeString; $maximumBytesToRead -= $lengthOfMinimumTimeString; if ($contentLength == $lengthOfMinimumTimeString) { $localTimeZone = new \DateTimeZone(date_default_timezone_get()); $dateTime = \DateTime::createFromFormat($format, $dateTimeString, $localTimeZone); } else { if ($binaryData[$offsetIndex] == '.') { $maximumBytesToRead--; // account for the '.' $nrOfFractionalSecondElements = 1; // account for the '.' while ($maximumBytesToRead > 0 && $binaryData[$offsetIndex + $nrOfFractionalSecondElements] != '+' && $binaryData[$offsetIndex + $nrOfFractionalSecondElements] != '-' && $binaryData[$offsetIndex + $nrOfFractionalSecondElements] != 'Z') { $nrOfFractionalSecondElements++; $maximumBytesToRead--; } $dateTimeString .= substr($binaryData, $offsetIndex, $nrOfFractionalSecondElements); $offsetIndex += $nrOfFractionalSecondElements; $format .= '.u'; } $dateTime = \DateTime::createFromFormat($format, $dateTimeString, new \DateTimeZone('UTC')); if ($maximumBytesToRead > 0) { if ($binaryData[$offsetIndex] == '+' || $binaryData[$offsetIndex] == '-') { $dateTime = static::extractTimeZoneData($binaryData, $offsetIndex, $dateTime); } elseif ($binaryData[$offsetIndex++] != 'Z') { throw new ParserException('Invalid ISO 8601 Time String', $offsetIndex); } } } $parsedObject = new self($dateTime); $parsedObject->setContentLength($contentLength); return $parsedObject; } } Universal/ObjectIdentifier.php 0000644 00000007477 15176121033 0012454 0 ustar 00 <?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\ASN1\Universal; use Exception; use FG\ASN1\Base128; use FG\ASN1\OID; use FG\ASN1\ASNObject; use FG\ASN1\Parsable; use FG\ASN1\Identifier; use FG\ASN1\Exception\ParserException; class ObjectIdentifier extends ASNObject implements Parsable { protected $subIdentifiers; protected $value; public function __construct($value) { $this->subIdentifiers = explode('.', $value); $nrOfSubIdentifiers = count($this->subIdentifiers); for ($i = 0; $i < $nrOfSubIdentifiers; $i++) { if (is_numeric($this->subIdentifiers[$i])) { // enforce the integer type $this->subIdentifiers[$i] = intval($this->subIdentifiers[$i]); } else { throw new Exception("[{$value}] is no valid object identifier (sub identifier ".($i + 1).' is not numeric)!'); } } // Merge the first to arcs of the OID registration tree (per ASN definition!) if ($nrOfSubIdentifiers >= 2) { $this->subIdentifiers[1] = ($this->subIdentifiers[0] * 40) + $this->subIdentifiers[1]; unset($this->subIdentifiers[0]); } $this->value = $value; } public function getContent() { return $this->value; } public function getType() { return Identifier::OBJECT_IDENTIFIER; } protected function calculateContentLength() { $length = 0; foreach ($this->subIdentifiers as $subIdentifier) { do { $subIdentifier = $subIdentifier >> 7; $length++; } while ($subIdentifier > 0); } return $length; } protected function getEncodedValue() { $encodedValue = ''; foreach ($this->subIdentifiers as $subIdentifier) { $encodedValue .= Base128::encode($subIdentifier); } return $encodedValue; } public function __toString() { return OID::getName($this->value); } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { self::parseIdentifier($binaryData[$offsetIndex], Identifier::OBJECT_IDENTIFIER, $offsetIndex++); $contentLength = self::parseContentLength($binaryData, $offsetIndex, 1); $firstOctet = ord($binaryData[$offsetIndex++]); $oidString = floor($firstOctet / 40).'.'.($firstOctet % 40); $oidString .= '.'.self::parseOid($binaryData, $offsetIndex, $contentLength - 1); $parsedObject = new self($oidString); $parsedObject->setContentLength($contentLength); return $parsedObject; } /** * Parses an object identifier except for the first octet, which is parsed * differently. This way relative object identifiers can also be parsed * using this. * * @param $binaryData * @param $offsetIndex * @param $octetsToRead * * @throws ParserException * * @return string */ protected static function parseOid(&$binaryData, &$offsetIndex, $octetsToRead) { $oid = ''; while ($octetsToRead > 0) { $octets = ''; do { if (0 === $octetsToRead) { throw new ParserException('Malformed ASN.1 Object Identifier', $offsetIndex - 1); } $octetsToRead--; $octet = $binaryData[$offsetIndex++]; $octets .= $octet; } while (ord($octet) & 0x80); $oid .= sprintf('%d.', Base128::decode($octets)); } // Remove trailing '.' return substr($oid, 0, -1) ?: ''; } } UnknownObject.php 0000644 00000002421 15176121033 0010041 0 ustar 00 <?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\ASN1; class UnknownObject extends ASNObject { /** @var string */ private $value; private $identifier; /** * @param string|int $identifier Either the first identifier octet as int or all identifier bytes as a string * @param int $contentLength */ public function __construct($identifier, $contentLength) { if (is_int($identifier)) { $identifier = chr($identifier); } $this->identifier = $identifier; $this->value = "Unparsable Object ({$contentLength} bytes)"; $this->setContentLength($contentLength); } public function getContent() { return $this->value; } public function getType() { return ord($this->identifier[0]); } public function getIdentifier() { return $this->identifier; } protected function calculateContentLength() { return $this->getContentLength(); } protected function getEncodedValue() { return ''; } } ExplicitlyTaggedObject.php 0000644 00000010325 15176121033 0011646 0 ustar 00 <?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\ASN1; use FG\ASN1\Exception\ParserException; /** * Class ExplicitlyTaggedObject decorate an inner object with an additional tag that gives information about * its context specific meaning. * * Explanation taken from A Layman's Guide to a Subset of ASN.1, BER, and DER: * >>> An RSA Laboratories Technical Note * >>> Burton S. Kaliski Jr. * >>> Revised November 1, 1993 * * [...] * Explicitly tagged types are derived from other types by adding an outer tag to the underlying type. * In effect, explicitly tagged types are structured types consisting of one component, the underlying type. * Explicit tagging is denoted by the ASN.1 keywords [class number] EXPLICIT (see Section 5.2). * [...] * * @see http://luca.ntop.org/Teaching/Appunti/asn1.html */ class ExplicitlyTaggedObject extends ASNObject { /** @var \FG\ASN1\ASNObject[] */ private $decoratedObjects; private $tag; /** * @param int $tag * @param \FG\ASN1\ASNObject $objects,... */ public function __construct($tag, /* HH_FIXME[4858]: variadic + strict */ ...$objects) { $this->tag = $tag; $this->decoratedObjects = $objects; } protected function calculateContentLength() { $length = 0; foreach ($this->decoratedObjects as $object) { $length += $object->getObjectLength(); } return $length; } protected function getEncodedValue() { $encoded = ''; foreach ($this->decoratedObjects as $object) { $encoded .= $object->getBinary(); } return $encoded; } public function getContent() { return $this->decoratedObjects; } public function __toString() { switch ($length = count($this->decoratedObjects)) { case 0: return "Context specific empty object with tag [{$this->tag}]"; case 1: $decoratedType = Identifier::getShortName($this->decoratedObjects[0]->getType()); return "Context specific $decoratedType with tag [{$this->tag}]"; default: return "$length context specific objects with tag [{$this->tag}]"; } } public function getType() { return ord($this->getIdentifier()); } public function getIdentifier() { $identifier = Identifier::create(Identifier::CLASS_CONTEXT_SPECIFIC, true, $this->tag); return is_int($identifier) ? chr($identifier) : $identifier; } public function getTag() { return $this->tag; } public static function fromBinary(&$binaryData, &$offsetIndex = 0) { $identifier = self::parseBinaryIdentifier($binaryData, $offsetIndex); $firstIdentifierOctet = ord($identifier); assert(Identifier::isContextSpecificClass($firstIdentifierOctet), 'identifier octet should indicate context specific class'); assert(Identifier::isConstructed($firstIdentifierOctet), 'identifier octet should indicate constructed object'); $tag = Identifier::getTagNumber($identifier); $totalContentLength = self::parseContentLength($binaryData, $offsetIndex); $remainingContentLength = $totalContentLength; $offsetIndexOfDecoratedObject = $offsetIndex; $decoratedObjects = []; while ($remainingContentLength > 0) { $nextObject = ASNObject::fromBinary($binaryData, $offsetIndex); $remainingContentLength -= $nextObject->getObjectLength(); $decoratedObjects[] = $nextObject; } if ($remainingContentLength != 0) { throw new ParserException("Context-Specific explicitly tagged object [$tag] starting at offset $offsetIndexOfDecoratedObject specifies a length of $totalContentLength octets but $remainingContentLength remain after parsing the content", $offsetIndexOfDecoratedObject); } $parsedObject = new self($tag, ...$decoratedObjects); $parsedObject->setContentLength($totalContentLength); return $parsedObject; } } UnknownConstructedObject.php 0000644 00000002621 15176121033 0012261 0 ustar 00 <?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\ASN1; class UnknownConstructedObject extends Construct { private $identifier; private $contentLength; /** * @param string $binaryData * @param int $offsetIndex * * @throws \FG\ASN1\Exception\ParserException */ public function __construct($binaryData, &$offsetIndex) { $this->identifier = self::parseBinaryIdentifier($binaryData, $offsetIndex); $this->contentLength = self::parseContentLength($binaryData, $offsetIndex); $children = []; $octetsToRead = $this->contentLength; while ($octetsToRead > 0) { $newChild = ASNObject::fromBinary($binaryData, $offsetIndex); $octetsToRead -= $newChild->getObjectLength(); $children[] = $newChild; } parent::__construct(...$children); } public function getType() { return ord($this->identifier); } public function getIdentifier() { return $this->identifier; } protected function calculateContentLength() { return $this->contentLength; } protected function getEncodedValue() { return ''; } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings