Your IP : 3.137.176.198
<?php
/*
* SimpleJWT
*
* Copyright (C) Kelvin Mo 2015
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Bitrix\Sale\PaySystem;
/**
* Functions for interacting with ASN.1 data streams.
*
* Note that this class only implements a small subset of the ASN.1 DER, and should
* not be used as a general-purpose ASN.1 encoder/decoder.
*/
class ASN1 {
const UNIVERSAL_CLASS = 0x00;
const APPLICATION_CLASS = 0x40;
const CONTEXT_CLASS = 0x80;
const PRIVATE_CLASS = 0xC0;
const INTEGER_TYPE = 0x02;
const BIT_STRING = 0x03;
const OCTET_STRING = 0x04;
const NULL_TYPE = 0x05;
const OID = 0x06;
const SEQUENCE = 0x10;
/**
* Reads a DER stream and decodes a single object
*
* @param string $der the data stream
* @param int $offset the offset of the data stream containing the object
* to decode
* @param mixed &$data the decoded object
* @param bool $ignore_bit_strings whether to refrain from moving the
* offset when reading a bit string - this allows the caller to read the
* bit string manually
* @return int the number of bytes read, or 0 if there is an error
*/
static function readDER($der, $offset, &$data, $ignore_bit_strings = FALSE) {
$pos = $offset;
$size = strlen($der);
if ($size < 2) return 0;
// Tag/Type
$constructed = (ord($der[$pos]) >> 5) & 0x01;
$type = ord($der[$pos++]) & 0x1f;
if ($type == 0x1f) return 0; // Long-form type: not supported
if ($pos >= $size) return 0;
// Length
$len = ord($der[$pos++]);
if ($len & 0x80) {
$n = $len & 0x1f;
$len = 0;
while ($n-- && $pos < $size) {
$len = ($len << 8) | ord($der[$pos++]);
}
}
if ($pos >= $size || $len > $size - $pos) return 0;
// Value
if ($type == self::BIT_STRING) { // BIT STRING
$pos++; // Skip the first contents octet (padding indicator)
$data = substr($der, $pos, $len - 1);
if (!$ignore_bit_strings) $pos += $len - 1;
} elseif (!$constructed /*&& ($type != 0x04)*/) {
$data = substr($der, $pos, $len);
$pos += $len;
}
return $pos - $offset;
}
/**
* Encodes a value into a DER object.
*
* @param int $type the DER tag of the object
* @param string $value the value to encode
* @param bool $primitive whether the object is of a primitive or
* constructed type
* @return string the encoded object
*/
static function encodeDER($type, $value = '', $primitive = true, $class = 0) {
$tag_header = $class;
if (!$primitive) $tag_header |= 0x20;
// Type
if ($type < 0x1f) {
$der = chr($tag_header | $type);
} else {
return NULL; // Long form required. not supported.
}
// Length
$len = strlen($value);
if ($len <= 0x7f) {
$der .= chr($len);
} else {
$pack = '';
$n = 0;
while ($len) {
$pack .= chr($len & 0xff);
$len >>= 8;
$n++;
}
$der .= chr($n | 0x80);
if (pack('V', 65534) == pack('L', 65534)) {
$der .= strrev($pack); // Little endian machine - need to convert to big endian
} else {
$der = $pack;
}
}
return $der . $value;
}
/**
* Decodes a DER-encoded object identifier into a string.
*
* @param $string oid the binary DER-encoded object identifier
* @return $string the decoded string
*/
static function decodeOID($oid) {
$pos = 0;
$size = strlen($oid);
// First octet
$oct = ord($oid[$pos++]);
$str = floor($oct / 40) . '.' . ($oct % 40);
// Subsequent octets
while ($pos < $size) {
$num = 0;
do {
$oct = ord($oid[$pos++]);
$num = ($num << 7) + ($oct & 0x7F);
} while (($oct & 0x80) && ($pos < $size));
$str .= '.' . $num;
}
return $str;
}
/**
* Encodes a string into a DER-encoded object identifier.
*
* @param $string $str the object identifier string
* @return $string the binary DER-encoded object identifier
*/
static function encodeOID($str) {
$numbers = explode('.', $str);
// First octet
$oid = chr(array_shift($numbers) * 40 + array_shift($numbers));
// Subsequent octets
foreach ($numbers as $num) {
if ($num == 0) {
$oid .= chr(0x00);
continue;
}
$pack = '';
while ($num) {
$pack .= chr(0x80 | ($num & 0x7f));
$num >>= 7;
}
$pack[0] = $pack[0] & chr(0x7f);
if (pack('V', 65534) == pack('L', 65534)) {
$oid .= strrev($pack); // Little endian machine - need to convert to big endian
} else {
$oid .= $pack;
}
}
return $oid;
}
}
?>