]> git.mxchange.org Git - friendica.git/commitdiff
helper functions for Diaspora cert mangling
authorFriendika <info@friendika.com>
Tue, 26 Jul 2011 02:57:17 +0000 (19:57 -0700)
committerFriendika <info@friendika.com>
Tue, 26 Jul 2011 02:57:17 +0000 (19:57 -0700)
include/certfns.php [new file with mode: 0644]
library/ASNValue.class.php [new file with mode: 0644]

diff --git a/include/certfns.php b/include/certfns.php
new file mode 100644 (file)
index 0000000..70d2b54
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+require_once('library/ASNValue.class.php');
+
+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 pkcs8_encode($Modulus,$PublicExponent) {
+       //Encode key sequence
+       $modulus = new ASNValue(ASNValue::TAG_INTEGER);
+       $modulus->SetIntBuffer($Modulus);
+       $publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
+       $publicExponent->SetInt($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 metopem($m,$e) {
+       $der = pkcs8_emcode($m,$e);
+       $key = DerToPem($der,true);
+       return $key;
+}      
+
+
diff --git a/library/ASNValue.class.php b/library/ASNValue.class.php
new file mode 100644 (file)
index 0000000..8a6aced
--- /dev/null
@@ -0,0 +1,172 @@
+<?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;
+    }    
+}
+
+
+?>