/** * * @see \X501\StringPrep\StringPrep::prepare() * @throws \LogicException If string type is not supported * @param string $string String to prepare * @return string UTF-8 encoded string */ public function apply($string) { switch ($this->_type) { // UTF-8 string as is case Element::TYPE_UTF8_STRING: return $string; // PrintableString maps directly to UTF-8 // PrintableString maps directly to UTF-8 case Element::TYPE_PRINTABLE_STRING: return $string; // UCS-2 to UTF-8 // UCS-2 to UTF-8 case Element::TYPE_BMP_STRING: return mb_convert_encoding($string, "UTF-8", "UCS-2BE"); // UCS-4 to UTF-8 // UCS-4 to UTF-8 case Element::TYPE_UNIVERSAL_STRING: return mb_convert_encoding($string, "UTF-8", "UCS-4BE"); // TeletexString mapping is a local matter. // We take a shortcut here and encode it as a hexstring. // TeletexString mapping is a local matter. // We take a shortcut here and encode it as a hexstring. case Element::TYPE_T61_STRING: $el = new T61String($string); return "#" . bin2hex($el->toDER()); } throw new \LogicException("Unsupported string type " . Element::tagToName($this->_type) . "."); }
public function string() { return $this->_type . "/#" . bin2hex($this->_element->toDER()); }
/** * * @deprecated Use any <code>as*</code> accessor method first to ensure * type strictness. * @see \ASN1\Feature\ElementBase::expectTagged() * @return TaggedType */ public function expectTagged($tag = null) { return $this->_element->expectTagged($tag); }
/** * Generate ASN.1 element. * * @throws \UnexpectedValueException * @return StringType */ public function toASN1() { switch ($this->_tag) { case Element::TYPE_IA5_STRING: return new IA5String($this->_text); case Element::TYPE_VISIBLE_STRING: return new VisibleString($this->_text); case Element::TYPE_BMP_STRING: return new BMPString($this->_text); case Element::TYPE_UTF8_STRING: return new UTF8String($this->_text); default: throw new \UnexpectedValueException("Type " . Element::tagToName($this->_tag) . " not supported."); } }
/** * * @see \ASN1\Element::_decodeFromDER() * @return self */ protected static function _decodeFromDER(Identifier $identifier, $data, &$offset) { $idx = $offset; if (!$identifier->isConstructed()) { throw new DecodeException("Structured element must have constructed bit set."); } $length = Length::expectFromDER($data, $idx); $end = $idx + $length->length(); $elements = array(); while ($idx < $end) { $elements[] = Element::fromDER($data, $idx); // check that element didn't overflow length if ($idx > $end) { throw new DecodeException("Structure's content overflows length."); } } $offset = $idx; // return instance by static late binding return new static(...$elements); }
/** * * @see \X501\ASN1\AttributeValue\AttributeValue::stringValue() * @return string */ public function stringValue() { // return DER encoding as a hexstring return "#" . bin2hex($this->_element->toDER()); }
/** * Parse 'attributeTypeAndValue'. * * attributeType "=" attributeValue * * @param int $offset * @throws \UnexpectedValueException * @return array A tuple of [type, value]. Value may be either a string or * an Element, if it's encoded as hexstring. */ private function _parseAttrTypeAndValue(&$offset) { $idx = $offset; $type = $this->_parseAttrType($idx); $this->_skipWs($idx); if ($idx >= $this->_len || "=" != $this->_dn[$idx++]) { throw new \UnexpectedValueException("Invalid type and value pair."); } $this->_skipWs($idx); // hexstring if ($idx < $this->_len && "#" == $this->_dn[$idx]) { ++$idx; $data = $this->_parseAttrHexValue($idx); try { $value = Element::fromDER($data); } catch (DecodeException $e) { throw new \UnexpectedValueException("Invalid DER encoding from hexstring.", 0, $e); } } else { $value = $this->_parseAttrStringValue($idx); } $offset = $idx; return array($type, $value); }
/** * Generate ASN.1 structure. * * @throws \LogicException * @return Element */ public function toASN1() { switch ($this->_type) { case Element::TYPE_OCTET_STRING: return new OctetString($this->_value); case Element::TYPE_UTF8_STRING: return new UTF8String($this->_value); case Element::TYPE_OBJECT_IDENTIFIER: return new ObjectIdentifier($this->_value); } throw new \LogicException("Type " . Element::tagToName($this->_type) . " not supported."); }
/** * * @see \ASN1\Type\Tagged\ExplicitTagging::explicit() * @return UnspecifiedType */ public function explicit($expectedTag = null) { $idx = $this->_offset; Length::expectFromDER($this->_data, $idx); $element = Element::fromDER($this->_data, $idx); if (isset($expectedTag)) { $element->expectType($expectedTag); } return new UnspecifiedType($element); }
/** * Generate ASN.1. * * @throws \UnexpectedValueException * @return TimeType */ public function toASN1() { $dt = $this->_dt; switch ($this->_type) { case Element::TYPE_UTC_TIME: return new UTCTime($dt); case Element::TYPE_GENERALIZED_TIME: // GeneralizedTime must not contain fractional seconds // (rfc5280 4.1.2.5.2) if ($dt->format("u") != 0) { // remove fractional seconds (round down) $dt = \DateTimeImmutable::createFromFormat("Y-m-d H:i:s", $dt->format("Y-m-d H:i:s"), $dt->getTimezone()); } return new GeneralizedTime($dt); } throw new \UnexpectedValueException("Time type " . Element::tagToName($this->_type) . " not supported."); }
/** * Get ASN.1 class name for given DirectoryString type tag. * * @param int $tag * @throws \UnexpectedValueException * @return string */ private static function _tagToASN1Class($tag) { if (!array_key_exists($tag, self::MAP_TAG_TO_CLASS)) { throw new \UnexpectedValueException("Type " . Element::tagToName($tag) . " is not valid DirectoryString."); } return self::MAP_TAG_TO_CLASS[$tag]; }