mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
remove long deprecated crypto functions
This commit is contained in:
@@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
use Zotlabs\Lib\Config;
|
use Zotlabs\Lib\Config;
|
||||||
|
|
||||||
require_once('library/ASNValue.class.php');
|
|
||||||
require_once('library/asn1.php');
|
|
||||||
|
|
||||||
function rsa_sign($data,$key,$alg = 'sha256') {
|
function rsa_sign($data,$key,$alg = 'sha256') {
|
||||||
if(! $key)
|
if(! $key)
|
||||||
return 'no key';
|
return 'no key';
|
||||||
@@ -309,158 +306,6 @@ function new_keypair($bits) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DerToPem($Der, $Private=false)
|
|
||||||
{
|
|
||||||
//Encode:
|
|
||||||
$Der = base64_encode($Der);
|
|
||||||
//Split lines:
|
|
||||||
$lines = str_split($Der, 65);
|
|
||||||
$body = implode("\n", $lines);
|
|
||||||
//Get title:
|
|
||||||
$title = $Private? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
|
|
||||||
//Add wrapping:
|
|
||||||
$result = "-----BEGIN {$title}-----\n";
|
|
||||||
$result .= $body . "\n";
|
|
||||||
$result .= "-----END {$title}-----\n";
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function DerToRsa($Der)
|
|
||||||
{
|
|
||||||
//Encode:
|
|
||||||
$Der = base64_encode($Der);
|
|
||||||
//Split lines:
|
|
||||||
$lines = str_split($Der, 64);
|
|
||||||
$body = implode("\n", $lines);
|
|
||||||
//Get title:
|
|
||||||
$title = 'RSA PUBLIC KEY';
|
|
||||||
//Add wrapping:
|
|
||||||
$result = "-----BEGIN {$title}-----\n";
|
|
||||||
$result .= $body . "\n";
|
|
||||||
$result .= "-----END {$title}-----\n";
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function pkcs8_encode($Modulus,$PublicExponent) {
|
|
||||||
//Encode key sequence
|
|
||||||
$modulus = new ASNValue(ASNValue::TAG_INTEGER);
|
|
||||||
$modulus->SetIntBuffer($Modulus);
|
|
||||||
$publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
|
|
||||||
$publicExponent->SetIntBuffer($PublicExponent);
|
|
||||||
$keySequenceItems = array($modulus, $publicExponent);
|
|
||||||
$keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
|
|
||||||
$keySequence->SetSequence($keySequenceItems);
|
|
||||||
//Encode bit string
|
|
||||||
$bitStringValue = $keySequence->Encode();
|
|
||||||
$bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte
|
|
||||||
$bitString = new ASNValue(ASNValue::TAG_BITSTRING);
|
|
||||||
$bitString->Value = $bitStringValue;
|
|
||||||
//Encode body
|
|
||||||
$bodyValue = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" . $bitString->Encode();
|
|
||||||
$body = new ASNValue(ASNValue::TAG_SEQUENCE);
|
|
||||||
$body->Value = $bodyValue;
|
|
||||||
//Get DER encoded public key:
|
|
||||||
$PublicDER = $body->Encode();
|
|
||||||
return $PublicDER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function pkcs1_encode($Modulus,$PublicExponent) {
|
|
||||||
//Encode key sequence
|
|
||||||
$modulus = new ASNValue(ASNValue::TAG_INTEGER);
|
|
||||||
$modulus->SetIntBuffer($Modulus);
|
|
||||||
$publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
|
|
||||||
$publicExponent->SetIntBuffer($PublicExponent);
|
|
||||||
$keySequenceItems = array($modulus, $publicExponent);
|
|
||||||
$keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
|
|
||||||
$keySequence->SetSequence($keySequenceItems);
|
|
||||||
//Encode bit string
|
|
||||||
$bitStringValue = $keySequence->Encode();
|
|
||||||
return $bitStringValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// http://stackoverflow.com/questions/27568570/how-to-convert-raw-modulus-exponent-to-rsa-public-key-pem-format
|
|
||||||
function metopem($m,$e) {
|
|
||||||
$der = pkcs8_encode($m,$e);
|
|
||||||
$key = DerToPem($der,false);
|
|
||||||
return $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function pubrsatome($key,&$m,&$e) {
|
|
||||||
require_once('library/asn1.php');
|
|
||||||
|
|
||||||
$lines = explode("\n",$key);
|
|
||||||
unset($lines[0]);
|
|
||||||
unset($lines[count($lines)]);
|
|
||||||
$x = base64_decode(implode('',$lines));
|
|
||||||
|
|
||||||
$r = ASN_BASE::parseASNString($x);
|
|
||||||
|
|
||||||
$m = base64url_decode($r[0]->asnData[0]->asnData);
|
|
||||||
$e = base64url_decode($r[0]->asnData[1]->asnData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function rsatopem($key) {
|
|
||||||
pubrsatome($key,$m,$e);
|
|
||||||
return(metopem($m,$e));
|
|
||||||
}
|
|
||||||
|
|
||||||
function pemtorsa($key) {
|
|
||||||
pemtome($key,$m,$e);
|
|
||||||
return(metorsa($m,$e));
|
|
||||||
}
|
|
||||||
|
|
||||||
function pemtome($key,&$m,&$e) {
|
|
||||||
$lines = explode("\n",$key);
|
|
||||||
unset($lines[0]);
|
|
||||||
unset($lines[count($lines)]);
|
|
||||||
$x = base64_decode(implode('',$lines));
|
|
||||||
|
|
||||||
$r = ASN_BASE::parseASNString($x);
|
|
||||||
|
|
||||||
$m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData);
|
|
||||||
$e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);
|
|
||||||
}
|
|
||||||
|
|
||||||
function metorsa($m,$e) {
|
|
||||||
$der = pkcs1_encode($m,$e);
|
|
||||||
$key = DerToRsa($der);
|
|
||||||
return $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function salmon_key($pubkey) {
|
|
||||||
pemtome($pubkey,$m,$e);
|
|
||||||
return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function convert_salmon_key($key) {
|
|
||||||
|
|
||||||
if(strstr($key,','))
|
|
||||||
$rawkey = substr($key,strpos($key,',')+1);
|
|
||||||
else
|
|
||||||
$rawkey = substr($key,5);
|
|
||||||
|
|
||||||
$key_info = explode('.',$rawkey);
|
|
||||||
|
|
||||||
$m = base64url_decode($key_info[1]);
|
|
||||||
$e = base64url_decode($key_info[2]);
|
|
||||||
|
|
||||||
logger('key details: ' . print_r($key_info,true), LOGGER_DATA);
|
|
||||||
$salmon_key = metopem($m,$e);
|
|
||||||
return $salmon_key;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function z_obscure($s) {
|
function z_obscure($s) {
|
||||||
return json_encode(crypto_encapsulate($s,Config::Get('system','pubkey')));
|
return json_encode(crypto_encapsulate($s,Config::Get('system','pubkey')));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
<?php
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// ASNValue class by A.Oliinyk
|
|
||||||
// contact@pumka.net
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
class ASNValue
|
|
||||||
{
|
|
||||||
const TAG_INTEGER = 0x02;
|
|
||||||
const TAG_BITSTRING = 0x03;
|
|
||||||
const TAG_SEQUENCE = 0x30;
|
|
||||||
|
|
||||||
public $Tag;
|
|
||||||
public $Value;
|
|
||||||
|
|
||||||
function __construct($Tag=0x00, $Value='')
|
|
||||||
{
|
|
||||||
$this->Tag = $Tag;
|
|
||||||
$this->Value = $Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Encode()
|
|
||||||
{
|
|
||||||
//Write type
|
|
||||||
$result = chr($this->Tag);
|
|
||||||
|
|
||||||
//Write size
|
|
||||||
$size = strlen($this->Value);
|
|
||||||
if ($size < 127) {
|
|
||||||
//Write size as is
|
|
||||||
$result .= chr($size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//Prepare length sequence
|
|
||||||
$sizeBuf = self::IntToBin($size);
|
|
||||||
|
|
||||||
//Write length sequence
|
|
||||||
$firstByte = 0x80 + strlen($sizeBuf);
|
|
||||||
$result .= chr($firstByte) . $sizeBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Write value
|
|
||||||
$result .= $this->Value;
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Decode(&$Buffer)
|
|
||||||
{
|
|
||||||
//Read type
|
|
||||||
$this->Tag = self::ReadByte($Buffer);
|
|
||||||
|
|
||||||
//Read first byte
|
|
||||||
$firstByte = self::ReadByte($Buffer);
|
|
||||||
|
|
||||||
if ($firstByte < 127) {
|
|
||||||
$size = $firstByte;
|
|
||||||
}
|
|
||||||
else if ($firstByte > 127) {
|
|
||||||
$sizeLen = $firstByte - 0x80;
|
|
||||||
//Read length sequence
|
|
||||||
$size = self::BinToInt(self::ReadBytes($Buffer, $sizeLen));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Exception("Invalid ASN length value");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Value = self::ReadBytes($Buffer, $size);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function ReadBytes(&$Buffer, $Length)
|
|
||||||
{
|
|
||||||
$result = substr($Buffer, 0, $Length);
|
|
||||||
$Buffer = substr($Buffer, $Length);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function ReadByte(&$Buffer)
|
|
||||||
{
|
|
||||||
return ord(self::ReadBytes($Buffer, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function BinToInt($Bin)
|
|
||||||
{
|
|
||||||
$len = strlen($Bin);
|
|
||||||
$result = 0;
|
|
||||||
for ($i=0; $i<$len; $i++) {
|
|
||||||
$curByte = self::ReadByte($Bin);
|
|
||||||
$result += $curByte << (($len-$i-1)*8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function IntToBin($Int)
|
|
||||||
{
|
|
||||||
$result = '';
|
|
||||||
do {
|
|
||||||
$curByte = $Int % 256;
|
|
||||||
$result .= chr($curByte);
|
|
||||||
|
|
||||||
$Int = ($Int - $curByte) / 256;
|
|
||||||
} while ($Int > 0);
|
|
||||||
|
|
||||||
$result = strrev($result);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetIntBuffer($Value)
|
|
||||||
{
|
|
||||||
if (strlen($Value) > 1) {
|
|
||||||
$firstByte = ord($Value[0]);
|
|
||||||
if ($firstByte & 0x80) { //first bit set
|
|
||||||
$Value = chr(0x00) . $Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Value = $Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetIntBuffer()
|
|
||||||
{
|
|
||||||
$result = $this->Value;
|
|
||||||
if (ord($result[0]) == 0x00) {
|
|
||||||
$result = substr($result, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetInt($Value)
|
|
||||||
{
|
|
||||||
$Value = self::IntToBin($Value);
|
|
||||||
|
|
||||||
$this->SetIntBuffer($Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetInt()
|
|
||||||
{
|
|
||||||
$result = $this->GetIntBuffer();
|
|
||||||
$result = self::BinToInt($result);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetSequence($Values)
|
|
||||||
{
|
|
||||||
$result = '';
|
|
||||||
foreach ($Values as $item) {
|
|
||||||
$result .= $item->Encode();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Value = $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetSequence()
|
|
||||||
{
|
|
||||||
$result = array();
|
|
||||||
$seq = $this->Value;
|
|
||||||
while (strlen($seq)) {
|
|
||||||
$val = new ASNValue();
|
|
||||||
$val->Decode($seq);
|
|
||||||
$result[] = $val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
291
library/asn1.php
291
library/asn1.php
@@ -1,291 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// ASN.1 parsing library
|
|
||||||
// Attribution: http://www.krisbailey.com
|
|
||||||
// license: unknown
|
|
||||||
// modified: Mike Macgrivin mike@macgirvin.com 6-oct-2010 to support Salmon auto-discovery
|
|
||||||
// from openssl public keys
|
|
||||||
|
|
||||||
|
|
||||||
class ASN_BASE {
|
|
||||||
public $asnData = null;
|
|
||||||
private $cursor = 0;
|
|
||||||
private $parent = null;
|
|
||||||
|
|
||||||
public static $ASN_MARKERS = array(
|
|
||||||
'ASN_UNIVERSAL' => 0x00,
|
|
||||||
'ASN_APPLICATION' => 0x40,
|
|
||||||
'ASN_CONTEXT' => 0x80,
|
|
||||||
'ASN_PRIVATE' => 0xC0,
|
|
||||||
|
|
||||||
'ASN_PRIMITIVE' => 0x00,
|
|
||||||
'ASN_CONSTRUCTOR' => 0x20,
|
|
||||||
|
|
||||||
'ASN_LONG_LEN' => 0x80,
|
|
||||||
'ASN_EXTENSION_ID' => 0x1F,
|
|
||||||
'ASN_BIT' => 0x80,
|
|
||||||
);
|
|
||||||
|
|
||||||
public static $ASN_TYPES = array(
|
|
||||||
1 => 'ASN_BOOLEAN',
|
|
||||||
2 => 'ASN_INTEGER',
|
|
||||||
3 => 'ASN_BIT_STR',
|
|
||||||
4 => 'ASN_OCTET_STR',
|
|
||||||
5 => 'ASN_NULL',
|
|
||||||
6 => 'ASN_OBJECT_ID',
|
|
||||||
9 => 'ASN_REAL',
|
|
||||||
10 => 'ASN_ENUMERATED',
|
|
||||||
13 => 'ASN_RELATIVE_OID',
|
|
||||||
48 => 'ASN_SEQUENCE',
|
|
||||||
49 => 'ASN_SET',
|
|
||||||
19 => 'ASN_PRINT_STR',
|
|
||||||
22 => 'ASN_IA5_STR',
|
|
||||||
23 => 'ASN_UTC_TIME',
|
|
||||||
24 => 'ASN_GENERAL_TIME',
|
|
||||||
);
|
|
||||||
|
|
||||||
function __construct($v = false)
|
|
||||||
{
|
|
||||||
if (false !== $v) {
|
|
||||||
$this->asnData = $v;
|
|
||||||
if (is_array($this->asnData)) {
|
|
||||||
foreach ($this->asnData as $key => $value) {
|
|
||||||
if (is_object($value)) {
|
|
||||||
$this->asnData[$key]->setParent($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (is_object($this->asnData)) {
|
|
||||||
$this->asnData->setParent($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setParent($parent)
|
|
||||||
{
|
|
||||||
if (false !== $parent) {
|
|
||||||
$this->parent = $parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will take the markers and types arrays and
|
|
||||||
* dynamically generate classes that extend this class for each one,
|
|
||||||
* and also define constants for them.
|
|
||||||
*/
|
|
||||||
public static function generateSubclasses()
|
|
||||||
{
|
|
||||||
define('ASN_BASE', 0);
|
|
||||||
foreach (self::$ASN_MARKERS as $name => $bit)
|
|
||||||
self::makeSubclass($name, $bit);
|
|
||||||
foreach (self::$ASN_TYPES as $bit => $name)
|
|
||||||
self::makeSubclass($name, $bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function for generateSubclasses()
|
|
||||||
*/
|
|
||||||
public static function makeSubclass($name, $bit)
|
|
||||||
{
|
|
||||||
define($name, $bit);
|
|
||||||
eval("class ".$name." extends ASN_BASE {}");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function reset's the internal cursor used for value iteration.
|
|
||||||
*/
|
|
||||||
public function reset()
|
|
||||||
{
|
|
||||||
$this->cursor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function catches calls to get the value for the type, typeName, value, values, and data
|
|
||||||
* from the object. For type calls we just return the class name or the value of the constant that
|
|
||||||
* is named the same as the class.
|
|
||||||
*/
|
|
||||||
public function __get($name)
|
|
||||||
{
|
|
||||||
if ('type' == $name) {
|
|
||||||
// int flag of the data type
|
|
||||||
return constant(get_class($this));
|
|
||||||
} elseif ('typeName' == $name) {
|
|
||||||
// name of the data type
|
|
||||||
return get_class($this);
|
|
||||||
} elseif ('value' == $name) {
|
|
||||||
// will always return one value and can be iterated over with:
|
|
||||||
// while ($v = $obj->value) { ...
|
|
||||||
// because $this->asnData["invalid key"] will return false
|
|
||||||
return is_array($this->asnData) ? $this->asnData[$this->cursor++] : $this->asnData;
|
|
||||||
} elseif ('values' == $name) {
|
|
||||||
// will always return an array
|
|
||||||
return is_array($this->asnData) ? $this->asnData : array($this->asnData);
|
|
||||||
} elseif ('data' == $name) {
|
|
||||||
// will always return the raw data
|
|
||||||
return $this->asnData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse an ASN.1 binary string.
|
|
||||||
*
|
|
||||||
* This function takes a binary ASN.1 string and parses it into it's respective
|
|
||||||
* pieces and returns it. It can optionally stop at any depth.
|
|
||||||
*
|
|
||||||
* @param string $string The binary ASN.1 String
|
|
||||||
* @param int $level The current parsing depth level
|
|
||||||
* @param int $maxLevel The max parsing depth level
|
|
||||||
* @return ASN_BASE The array representation of the ASN.1 data contained in $string
|
|
||||||
*/
|
|
||||||
public static function parseASNString($string=false, $level=1, $maxLevels=false){
|
|
||||||
if (!class_exists('ASN_UNIVERSAL'))
|
|
||||||
self::generateSubclasses();
|
|
||||||
if ($level>$maxLevels && $maxLevels)
|
|
||||||
return array(new ASN_BASE($string));
|
|
||||||
$parsed = array();
|
|
||||||
$endLength = strlen($string);
|
|
||||||
$bigLength = $length = $type = $dtype = $p = 0;
|
|
||||||
while ($p<$endLength){
|
|
||||||
$type = ord($string[$p++]);
|
|
||||||
$dtype = ($type & 192) >> 6;
|
|
||||||
if ($type==0){ // if we are type 0, just continue
|
|
||||||
} else {
|
|
||||||
$length = ord($string[$p++]);
|
|
||||||
if (($length & ASN_LONG_LEN)==ASN_LONG_LEN){
|
|
||||||
$tempLength = 0;
|
|
||||||
for ($x=0; $x<($length & (ASN_LONG_LEN-1)); $x++){
|
|
||||||
$tempLength = ord($string[$p++]) + ($tempLength * 256);
|
|
||||||
}
|
|
||||||
$length = $tempLength;
|
|
||||||
}
|
|
||||||
$data = substr($string, $p, intval($length));
|
|
||||||
$parsed[] = self::parseASNData($type, $data, $level, $maxLevels);
|
|
||||||
$p = $p + $length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $parsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse an ASN.1 field value.
|
|
||||||
*
|
|
||||||
* This function takes a binary ASN.1 value and parses it according to it's specified type
|
|
||||||
*
|
|
||||||
* @param int $type The type of data being provided
|
|
||||||
* @param string $data The raw binary data string
|
|
||||||
* @param int $level The current parsing depth
|
|
||||||
* @param int $maxLevels The max parsing depth
|
|
||||||
* @return mixed The data that was parsed from the raw binary data string
|
|
||||||
*/
|
|
||||||
public static function parseASNData($type, $data, $level, $maxLevels){
|
|
||||||
$type = $type%50; // strip out context
|
|
||||||
switch ($type){
|
|
||||||
default:
|
|
||||||
return new ASN_BASE($data);
|
|
||||||
case ASN_BOOLEAN:
|
|
||||||
return new ASN_BOOLEAN((bool)$data);
|
|
||||||
case ASN_INTEGER:
|
|
||||||
return new ASN_INTEGER(strtr(base64_encode($data),'+/','-_'));
|
|
||||||
case ASN_BIT_STR:
|
|
||||||
return new ASN_BIT_STR(self::parseASNString($data, $level+1, $maxLevels));
|
|
||||||
case ASN_OCTET_STR:
|
|
||||||
return new ASN_OCTET_STR($data);
|
|
||||||
case ASN_NULL:
|
|
||||||
return new ASN_NULL(null);
|
|
||||||
case ASN_REAL:
|
|
||||||
return new ASN_REAL($data);
|
|
||||||
case ASN_ENUMERATED:
|
|
||||||
return new ASN_ENUMERATED(self::parseASNString($data, $level+1, $maxLevels));
|
|
||||||
case ASN_RELATIVE_OID: // I don't really know how this works and don't have an example :-)
|
|
||||||
// so, lets just return it ...
|
|
||||||
return new ASN_RELATIVE_OID($data);
|
|
||||||
case ASN_SEQUENCE:
|
|
||||||
return new ASN_SEQUENCE(self::parseASNString($data, $level+1, $maxLevels));
|
|
||||||
case ASN_SET:
|
|
||||||
return new ASN_SET(self::parseASNString($data, $level+1, $maxLevels));
|
|
||||||
case ASN_PRINT_STR:
|
|
||||||
return new ASN_PRINT_STR($data);
|
|
||||||
case ASN_IA5_STR:
|
|
||||||
return new ASN_IA5_STR($data);
|
|
||||||
case ASN_UTC_TIME:
|
|
||||||
return new ASN_UTC_TIME($data);
|
|
||||||
case ASN_GENERAL_TIME:
|
|
||||||
return new ASN_GENERAL_TIME($data);
|
|
||||||
case ASN_OBJECT_ID:
|
|
||||||
return new ASN_OBJECT_ID(self::parseOID($data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse an ASN.1 OID value.
|
|
||||||
*
|
|
||||||
* This takes the raw binary string that represents an OID value and parses it into its
|
|
||||||
* dot notation form. example - 1.2.840.113549.1.1.5
|
|
||||||
* look up OID's here: http://www.oid-info.com/
|
|
||||||
* (the multi-byte OID section can be done in a more efficient way, I will fix it later)
|
|
||||||
*
|
|
||||||
* @param string $data The raw binary data string
|
|
||||||
* @return string The OID contained in $data
|
|
||||||
*/
|
|
||||||
public static function parseOID($string){
|
|
||||||
$ret = floor(ord($string[0])/40).".";
|
|
||||||
$ret .= (ord($string[0]) % 40);
|
|
||||||
$build = array();
|
|
||||||
$cs = 0;
|
|
||||||
|
|
||||||
for ($i=1; $i<strlen($string); $i++){
|
|
||||||
$v = ord($string[$i]);
|
|
||||||
if ($v>127){
|
|
||||||
$build[] = ord($string[$i])-ASN_BIT;
|
|
||||||
} elseif ($build){
|
|
||||||
// do the build here for multibyte values
|
|
||||||
$build[] = ord($string[$i])-ASN_BIT;
|
|
||||||
// you know, it seems there should be a better way to do this...
|
|
||||||
$build = array_reverse($build);
|
|
||||||
$num = 0;
|
|
||||||
for ($x=0; $x<count($build); $x++){
|
|
||||||
$mult = $x==0?1:pow(256, $x);
|
|
||||||
if ($x+1==count($build)){
|
|
||||||
$value = ((($build[$x] & (ASN_BIT-1)) >> $x)) * $mult;
|
|
||||||
} else {
|
|
||||||
$value = ((($build[$x] & (ASN_BIT-1)) >> $x) ^ ($build[$x+1] << (7 - $x) & 255)) * $mult;
|
|
||||||
}
|
|
||||||
$num += $value;
|
|
||||||
}
|
|
||||||
$ret .= ".".$num;
|
|
||||||
$build = array(); // start over
|
|
||||||
} else {
|
|
||||||
$ret .= ".".$v;
|
|
||||||
$build = array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function printASN($x, $indent=''){
|
|
||||||
if (is_object($x)) {
|
|
||||||
echo $indent.$x->typeName."\n";
|
|
||||||
if (ASN_NULL == $x->type) return;
|
|
||||||
if (is_array($x->data)) {
|
|
||||||
while ($d = $x->value) {
|
|
||||||
echo self::printASN($d, $indent.'. ');
|
|
||||||
}
|
|
||||||
$x->reset();
|
|
||||||
} else {
|
|
||||||
echo self::printASN($x->data, $indent.'. ');
|
|
||||||
}
|
|
||||||
} elseif (is_array($x)) {
|
|
||||||
foreach ($x as $d) {
|
|
||||||
echo self::printASN($d, $indent);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (preg_match('/[^[:print:]]/', $x)) // if we have non-printable characters that would
|
|
||||||
$x = base64_encode($x); // mess up the console, then print the base64 of them...
|
|
||||||
echo $indent.$x."\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user