public static function fromBinary(&$binaryData, &$offsetIndex = 0)
 {
     self::parseIdentifier($binaryData[$offsetIndex], Identifier::OCTETSTRING, $offsetIndex++);
     $contentLength = self::parseContentLength($binaryData, $offsetIndex);
     if ($contentLength < 2) {
         throw new ParserException('Can not parse Subject Alternative Names: The Sequence within the octet string after the Object identifier ' . OID::CERT_EXT_SUBJECT_ALT_NAME . " is too short ({$contentLength} octets)", $offsetIndex);
     }
     $offsetOfSequence = $offsetIndex;
     $sequence = Sequence::fromBinary($binaryData, $offsetIndex);
     $offsetOfSequence += $sequence->getNumberOfLengthOctets() + 1;
     if ($sequence->getObjectLength() != $contentLength) {
         throw new ParserException('Can not parse Subject Alternative Names: The Sequence length does not match the length of the surrounding octet string', $offsetIndex);
     }
     $parsedObject = new self();
     /** @var \FG\ASN1\Object $object */
     foreach ($sequence as $object) {
         if ($object->getType() == DNSName::IDENTIFIER) {
             $domainName = DNSName::fromBinary($binaryData, $offsetOfSequence);
             $parsedObject->addDomainName($domainName);
         } elseif ($object->getType() == IPAddress::IDENTIFIER) {
             $ip = IPAddress::fromBinary($binaryData, $offsetOfSequence);
             $parsedObject->addIP($ip);
         } else {
             throw new ParserException('Could not parse Subject Alternative Name: Only DNSName and IP SANs are currently supported', $offsetIndex);
         }
     }
     $parsedObject->getBinary();
     // Determine the number of content octets and object sizes once (just to let the equality unit tests pass :/ )
     return $parsedObject;
 }
 public static function fromBinary(&$binaryData, &$offsetIndex = 0)
 {
     self::parseIdentifier($binaryData[$offsetIndex], Identifier::SET, $offsetIndex++);
     self::parseContentLength($binaryData, $offsetIndex);
     $tmpOffset = $offsetIndex;
     $extensions = Sequence::fromBinary($binaryData, $offsetIndex);
     $tmpOffset += 1 + $extensions->getNumberOfLengthOctets();
     $parsedObject = new self();
     foreach ($extensions as $extension) {
         if ($extension->getType() != Identifier::SEQUENCE) {
             //FIXME wrong offset index
             throw new ParserException('Could not parse Certificate Extensions: Expected ASN.1 Sequence but got ' . $extension->getTypeName(), $offsetIndex);
         }
         $tmpOffset += 1 + $extension->getNumberOfLengthOctets();
         $children = $extension->getChildren();
         if (count($children) < 2) {
             throw new ParserException('Could not parse Certificate Extensions: Needs at least two child elements per extension sequence (object identifier and octet string)', $tmpOffset);
         }
         /** @var \FG\ASN1\Object $objectIdentifier */
         $objectIdentifier = $children[0];
         /** @var OctetString $octetString */
         $octetString = $children[1];
         if ($objectIdentifier->getType() != Identifier::OBJECT_IDENTIFIER) {
             throw new ParserException('Could not parse Certificate Extensions: Expected ASN.1 Object Identifier but got ' . $extension->getTypeName(), $tmpOffset);
         }
         $tmpOffset += $objectIdentifier->getObjectLength();
         if ($objectIdentifier->getContent() == OID::CERT_EXT_SUBJECT_ALT_NAME) {
             $sans = SubjectAlternativeNames::fromBinary($binaryData, $tmpOffset);
             $parsedObject->addSubjectAlternativeNames($sans);
         } else {
             // can now only parse SANs. There might be more in the future
             $tmpOffset += $octetString->getObjectLength();
         }
     }
     $parsedObject->getBinary();
     // Determine the number of content octets and object sizes once (just to let the equality unit tests pass :/ )
     return $parsedObject;
 }
Beispiel #3
0
 /**
  * @depends testFromBinary
  */
 public function testFromBinaryWithOffset()
 {
     $originalObject1 = new Sequence(new Boolean(true), new Integer(123));
     $originalObject2 = new Sequence(new Integer(64), new Boolean(false));
     $binaryData = $originalObject1->getBinary();
     $binaryData .= $originalObject2->getBinary();
     $offset = 0;
     $parsedObject = Sequence::fromBinary($binaryData, $offset);
     $this->assertEquals($originalObject1, $parsedObject);
     $this->assertEquals(8, $offset);
     $parsedObject = Sequence::fromBinary($binaryData, $offset);
     $this->assertEquals($originalObject2, $parsedObject);
     $this->assertEquals(16, $offset);
 }
Beispiel #4
0
    // this should contain a sequence of extensions
    $certExtensions = $certExtensions->getFirstChild();
    assert($certExtensions->getType() == Identifier::SEQUENCE);
    // now check all extensions and search for the SAN
    /** @var Object $extensionSequence */
    foreach ($certExtensions as $extensionSequence) {
        assert($extensionSequence->getType() == Identifier::SEQUENCE);
        assert($extensionSequence->getNumberofChildren() >= 2);
        $extensionSequenceChildren = $extensionSequence->getChildren();
        $objectIdentifier = $extensionSequenceChildren[0];
        /* @var ObjectIdentifier $objectIdentifier */
        assert($objectIdentifier->getType() == Identifier::OBJECT_IDENTIFIER);
        if ($objectIdentifier->getContent() == OID::CERT_EXT_SUBJECT_ALT_NAME) {
            // now we have the wanted octet string
            $octetString = $extensionSequenceChildren[1];
            /* @var OctetString $octetString */
            $octetStringBinary = $octetString->getBinaryContent();
            // At this point you may want to create the sequence from the binary value of
            // the octet string and parse its structure like we did so far.
            // However a more general approach would be to understand the format of the
            // contained SAN fields and implement them in SubjectAlternativeNames.
            $sequence = Sequence::fromBinary($octetStringBinary);
            echo 'This is the parsed content of the SAN certificate extension field so far:' . PHP_EOL;
            printObject($sequence);
            // The following does not work yet because PHPASN1 SAn does only support DNS and IP
            //SubjectAlternativeNames::fromBinary($octetStringBinary);
        }
    }
} catch (\Exception $exception) {
    echo '[ERROR] Caught exception:' . PHP_EOL . $exception->getMessage() . PHP_EOL;
}
Beispiel #5
0
 /**
  * @param string $binaryData
  * @param int $offsetIndex
  *
  * @throws ParserException
  *
  * @return \FG\ASN1\Object
  */
 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);
             }
     }
 }
Beispiel #6
0
mk+8uP4/x61UWBliqW08/1jMA83Qj2yuCAvhMhmuq8BvyWP4jnXoxTy3iTZFDXIj
5Vg2FlHWna0TMsU5jlmv8W/mu9U3+q7i1+339JrEZkrDLNDpJ23gqKBgC1OaNH7+
vicBRmoP5kj2X62XMaKT5TMFBZzTtSF7IaUjt9SVXQjG3aHIy7D1mOypvEw4LSS+
RvvJTezSQeCoLpX7HziRnoVUNkJWZHL2wG5rb/SJzpXwHkRa7R250vN8TFtSSsp4
YXzK6aks/qkxRJ1UkBLUAZlRasUD+zu8gyTIz0sNgFrOtx8EOzjZRiJ/vBiVOn88
Brf4i0D+fVXmJQIDAQABow8wDTALBgNVHQ8EBAMCAAIwCwYJKoZIhvcNAQEFA4IB
AQBfubKPTvmDGrDxoqCbPwFoPRC0STwPL2GV8f5sD/Sbyc0NoJdygUO2DvquGGn5
6UJCfLo1u6Dn4zuuDs3m6if86HTpAf9Z3a72ok2Tor/NFwYt+vDOrFY5F4bXDZkf
u4zuDLmjpj26Dk4te3BVohsLTXbvJ5a/TT2VanwNOyx85lXPxy3V8Rr1AwlmHZoz
DDbUGbe/noUDJCgMjvaKKvLykIhIcW+g6W7SOcKRflw5H8kzDv816XFODSC3X1Uw
o3aVy9du/0mH+g4HvyVVplO90tdoHD1gHUMZwuen4dbTzhWv4dtLFelWM5lGWbLE
Wn7kJghclgIxv10nkGyfrowt';
// OCSP response status according to
// https://tools.ietf.org/html/rfc6960#section-4.2.1
$validResponseStatuses = array(0 => 'Response has valid confirmations', 1 => 'Illegal confirmation request', 2 => 'Internal error in issuer', 3 => 'Try again later', 5 => 'Must sign the request', 6 => 'Request unauthorized');
$ocspResponse = Sequence::fromBinary(base64_decode($data));
/* @var Enumerated $responseStatus */
$elements = $ocspResponse->getChildren();
$responseStatus = $elements[0];
$responseStatusCode = $responseStatus->getContent();
echo PHP_EOL;
echo "OCSP response status: {$responseStatusCode} ({$validResponseStatuses[$responseStatusCode]})" . PHP_EOL;
/** @var ExplicitlyTaggedObject $responseBytes */
$responseBytes = $elements[1];
/** @var Sequence $responseBytesSequence */
$responseBytesSequence = $responseBytes->getContent();
/** @var ObjectIdentifier $responseType */
$responseType = $responseBytesSequence->getChildren()[0];
echo "ResponseType: {$responseType}" . PHP_EOL;
$response = $responseBytesSequence->getChildren()[1];
echo "Response (octet string): {$response}" . PHP_EOL;