]> git.mxchange.org Git - friendica.git/commitdiff
Crypto to src
authorAdam Magness <adam.magness@gmail.com>
Sat, 30 Dec 2017 16:51:49 +0000 (11:51 -0500)
committerAdam Magness <adam.magness@gmail.com>
Sat, 30 Dec 2017 16:51:49 +0000 (11:51 -0500)
move Crypto to src and Friendica\Util namespace

15 files changed:
include/crypto.php [deleted file]
include/items.php
mod/dfrn_confirm.php
mod/fetch.php
mod/hostxrd.php
mod/item.php
mod/receive.php
mod/salmon.php
mod/xrd.php
src/Model/User.php
src/Network/Probe.php
src/Protocol/DFRN.php
src/Protocol/Diaspora.php
src/Protocol/Salmon.php
src/Util/Crypto.php [new file with mode: 0644]

diff --git a/include/crypto.php b/include/crypto.php
deleted file mode 100644 (file)
index dfc44c1..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-
-use Friendica\Core\Config;
-
-require_once 'library/ASNValue.class.php';
-require_once 'library/asn1.php';
-
-// supported algorithms are 'sha256', 'sha1'
-
-function rsa_sign($data, $key, $alg = 'sha256') {
-       openssl_sign($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
-       return $sig;
-}
-
-function rsa_verify($data, $sig, $key, $alg = 'sha256') {
-       return openssl_verify($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
-}
-
-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;
-}
-
-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 new_keypair($bits) {
-       $openssl_options = array(
-               'digest_alg'       => 'sha1',
-               'private_key_bits' => $bits,
-               'encrypt_key'      => false
-       );
-
-       $conf = Config::get('system', 'openssl_conf_file');
-       if ($conf) {
-               $openssl_options['config'] = $conf;
-       }
-       $result = openssl_pkey_new($openssl_options);
-
-       if (empty($result)) {
-               logger('new_keypair: failed');
-               return false;
-       }
-
-       // Get private key
-       $response = array('prvkey' => '', 'pubkey' => '');
-
-       openssl_pkey_export($result, $response['prvkey']);
-
-       // Get public key
-       $pkey = openssl_pkey_get_details($result);
-       $response['pubkey'] = $pkey["key"];
-
-       return $response;
-}
index 275052c1fdb73deab8337c78b2b840f8168994ad..a3f3c823b74432f09de3950dae4db50f368c0c5c 100644 (file)
@@ -21,7 +21,6 @@ use Friendica\Protocol\Feed;
 
 require_once 'include/bbcode.php';
 require_once 'include/oembed.php';
-require_once 'include/crypto.php';
 require_once 'include/tags.php';
 require_once 'include/files.php';
 require_once 'include/text.php';
index 112ee34ab3195bd906e0bd97cbfd5ff22a4f1b37..a5f5f1bd34b6cc9bea72aad5ea22381c5f08cf7b 100644 (file)
@@ -29,6 +29,7 @@ use Friendica\Model\Group;
 use Friendica\Model\User;
 use Friendica\Network\Probe;
 use Friendica\Protocol\Diaspora;
+use Friendica\Util\Crypto;
 
 require_once 'include/enotify.php';
 
@@ -162,9 +163,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) {
                         * worried about key leakage than anybody cracking it.
                         *
                         */
-                       require_once 'include/crypto.php';
-
-                       $res = new_keypair(4096);
+                       $res = Crypto::newKeypair(4096);
 
 
                        $private_key = $res['prvkey'];
index 68f6acc917196a4c3ce16c942063309a6a92c3d2..c097ee4c46f02418e1a3be5409d7b6df911dc73e 100644 (file)
@@ -8,8 +8,6 @@ use Friendica\Core\System;
 use Friendica\Protocol\Diaspora;
 use Friendica\Util\XML;
 
-require_once "include/crypto.php";
-
 function fetch_init(App $a)
 {
 
index 0403945efcc0ed7b422889d2426fc4eaf9209f4c..a38d3ab61f6bac663338c03cbc0e54a212651427 100644 (file)
@@ -1,18 +1,20 @@
 <?php
-
+/**
+ * @file mod/hostxrd.php
+ */
 use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\System;
+use Friendica\Util\Crypto;
 
-require_once('include/crypto.php');
-
-function hostxrd_init(App $a) {
+function hostxrd_init(App $a)
+{
        header('Access-Control-Allow-Origin: *');
        header("Content-type: text/xml");
-       $pubkey = Config::get('system','site_pubkey');
+       $pubkey = Config::get('system', 'site_pubkey');
 
-       if(! $pubkey) {
-               $res = new_keypair(1024);
+       if (! $pubkey) {
+               $res = Crypto::newKeypair(1024);
 
                Config::set('system','site_prvkey', $res['prvkey']);
                Config::set('system','site_pubkey', $res['pubkey']);
@@ -23,8 +25,8 @@ function hostxrd_init(App $a) {
                '$zhost' => $a->get_hostname(),
                '$zroot' => System::baseUrl(),
                '$domain' => System::baseUrl(),
-               '$bigkey' => salmon_key(Config::get('system','site_pubkey')),
-       ));
-       exit();
+               '$bigkey' => Crypto::salmonKey(Config::get('system', 'site_pubkey')))
+       );
 
+       exit();
 }
index 13877fb356944f1c039aaafe95d45db83a21cfd4..1faef960163c7845bad16b15a814d58a747dd667 100644 (file)
@@ -29,7 +29,6 @@ use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\Email;
 use Friendica\Util\Emailer;
 
-require_once 'include/crypto.php';
 require_once 'include/enotify.php';
 require_once 'include/tags.php';
 require_once 'include/files.php';
index 467a0d00a5982a3622c45b8bef04b3fda2bca7d9..fcc898a0c0375a0d97065c71f5162078cb18b621 100644 (file)
@@ -9,8 +9,6 @@ use Friendica\Core\Config;
 use Friendica\Database\DBM;
 use Friendica\Protocol\Diaspora;
 
-require_once 'include/crypto.php';
-
 /**
  * @param object $a App
  * @return void
index 4d8b130f94cca342700f343a58299b8a7b8651b8..bd08431a4cfeea8f5a878c5845b6656647f6ad32 100644 (file)
@@ -7,8 +7,8 @@ use Friendica\Core\PConfig;
 use Friendica\Database\DBM;
 use Friendica\Protocol\OStatus;
 use Friendica\Protocol\Salmon;
+use Friendica\Util\Crypto;
 
-require_once 'include/crypto.php';
 require_once 'include/items.php';
 require_once 'include/follow.php';
 
@@ -117,23 +117,23 @@ function salmon_post(App $a) {
 
        logger('mod-salmon: key details: ' . print_r($key_info,true), LOGGER_DEBUG);
 
-       $pubkey = metopem($m,$e);
+       $pubkey = Crypto::meToPem($m, $e);
 
        // We should have everything we need now. Let's see if it verifies.
 
        // Try GNU Social format
-       $verify = rsa_verify($signed_data, $signature, $pubkey);
+       $verify = Crypto::rsaVerify($signed_data, $signature, $pubkey);
        $mode = 1;
 
        if (! $verify) {
                logger('mod-salmon: message did not verify using protocol. Trying compliant format.');
-               $verify = rsa_verify($compliant_format, $signature, $pubkey);
+               $verify = Crypto::rsaVerify($compliant_format, $signature, $pubkey);
                $mode = 2;
        }
 
        if (! $verify) {
                logger('mod-salmon: message did not verify using padding. Trying old statusnet format.');
-               $verify = rsa_verify($stnet_signed_data, $signature, $pubkey);
+               $verify = Crypto::rsaVerify($stnet_signed_data, $signature, $pubkey);
                $mode = 3;
        }
 
index 49fdde25448a215881883802971c00d64dc529ca..599ee3794b24ab2cd3c73b44831aa59c7d31c8bf 100644 (file)
@@ -1,12 +1,14 @@
 <?php
-
+/**
+ * @file mod/xrd.php
+ */
 use Friendica\App;
 use Friendica\Core\System;
 use Friendica\Database\DBM;
+use Friendica\Util\Crypto;
 
-require_once('include/crypto.php');
-
-function xrd_init(App $a) {
+function xrd_init(App $a)
+{
        if ($a->argv[0] == 'xrd') {
                $uri = urldecode(notags(trim($_GET['uri'])));
                if ($_SERVER['HTTP_ACCEPT'] == 'application/jrd+json') {
@@ -54,8 +56,9 @@ function xrd_init(App $a) {
        }
 }
 
-function xrd_json($a, $uri, $alias, $profile_url, $r) {
-       $salmon_key = salmon_key($r['spubkey']);
+function xrd_json($a, $uri, $alias, $profile_url, $r)
+{
+       $salmon_key = Crypto::salmonKey($r['spubkey']);
 
        header('Access-Control-Allow-Origin: *');
        header("Content-type: application/json; charset=utf-8");
@@ -79,8 +82,9 @@ function xrd_json($a, $uri, $alias, $profile_url, $r) {
        killme();
 }
 
-function xrd_xml($a, $uri, $alias, $profile_url, $r) {
-       $salmon_key = salmon_key($r['spubkey']);
+function xrd_xml($a, $uri, $alias, $profile_url, $r)
+{
+       $salmon_key = Crypto::salmonKey($r['spubkey']);
 
        header('Access-Control-Allow-Origin: *');
        header("Content-type: text/xml");
@@ -100,8 +104,8 @@ function xrd_xml($a, $uri, $alias, $profile_url, $r) {
                '$salmon'      => System::baseUrl() . '/salmon/'        . $r['nickname'],
                '$salmen'      => System::baseUrl() . '/salmon/'        . $r['nickname'] . '/mention',
                '$subscribe'   => System::baseUrl() . '/follow?url={uri}',
-               '$modexp'      => 'data:application/magic-public-key,'  . $salmon_key,
-       ));
+               '$modexp'      => 'data:application/magic-public-key,'  . $salmon_key)
+       );
 
        $arr = array('user' => $r, 'xml' => $o);
        call_hooks('personal_xrd', $arr);
index f487de7661821b72af445d27b676935d342cf652..4f294f6e8939eed672d4f03c7b15fe9f5bc66bef 100644 (file)
@@ -16,11 +16,11 @@ use Friendica\Model\Contact;
 use Friendica\Model\Group;
 use Friendica\Model\Photo;
 use Friendica\Object\Image;
+use Friendica\Util\Crypto;
 use dba;
 use Exception;
 
 require_once 'boot.php';
-require_once 'include/crypto.php';
 require_once 'include/dba.php';
 require_once 'include/enotify.php';
 require_once 'include/network.php';
@@ -299,7 +299,7 @@ class User
 
                $return['password'] = $new_password;
 
-               $keys = new_keypair(4096);
+               $keys = Crypto::newKeypair(4096);
                if ($keys === false) {
                        throw new Exception(t('SERIOUS ERROR: Generation of security keys failed.'));
                }
@@ -308,7 +308,7 @@ class User
                $pubkey = $keys['pubkey'];
 
                // Create another keypair for signing/verifying salmon protocol messages.
-               $sres = new_keypair(512);
+               $sres = Crypto::newKeypair(512);
                $sprvkey = $sres['prvkey'];
                $spubkey = $sres['pubkey'];
 
index 56abbb7fdc3905d8edbeb96b828bd92fd2426c75..539803b6e4d93acfc56ea918f5c2bc59f3ff75f4 100644 (file)
@@ -17,6 +17,7 @@ use Friendica\Database\DBM;
 use Friendica\Model\Profile;
 use Friendica\Protocol\Email;
 use Friendica\Protocol\Feed;
+use Friendica\Util\Crypto;
 use Friendica\Util\XML;
 
 use dba;
@@ -25,7 +26,6 @@ use DOMDocument;
 
 require_once 'include/dba.php';
 require_once 'include/network.php';
-require_once "include/crypto.php";
 
 /**
  * @brief This class contain functions for probing URL
@@ -944,7 +944,7 @@ class Probe
 
                                //if (strstr($data["pubkey"], 'RSA ') || ($link["type"] == "RSA"))
                                if (strstr($data["pubkey"], 'RSA ')) {
-                                       $data["pubkey"] = rsatopem($data["pubkey"]);
+                                       $data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
                                }
                        }
                }
@@ -1043,7 +1043,7 @@ class Probe
                        if ($search->length > 0) {
                                $data["pubkey"] = $search->item(0)->nodeValue;
                                if (strstr($data["pubkey"], 'RSA ')) {
-                                       $data["pubkey"] = rsatopem($data["pubkey"]);
+                                       $data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
                                }
                        }
 
@@ -1133,7 +1133,7 @@ class Probe
 
                                //if (strstr($data["pubkey"], 'RSA ') || ($link["type"] == "RSA"))
                                if (strstr($data["pubkey"], 'RSA ')) {
-                                       $data["pubkey"] = rsatopem($data["pubkey"]);
+                                       $data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
                                }
                        }
                }
@@ -1244,7 +1244,7 @@ class Probe
                                        if (sizeof($key) >= 3) {
                                                $m = base64url_decode($key[1]);
                                                $e = base64url_decode($key[2]);
-                                               $data["pubkey"] = metopem($m, $e);
+                                               $data["pubkey"] = Crypto::meToPem($m, $e);
                                        }
                                }
                        }
index eeedd6324de1170c6047a985507639ae112904a1..5e9c91645bb6d567623786beffbf2be5bb3e31a3 100644 (file)
@@ -463,7 +463,7 @@ class DFRN
                /* get site pubkey. this could be a new installation with no site keys*/
                $pubkey = Config::get('system', 'site_pubkey');
                if (! $pubkey) {
-                       $res = new_keypair(1024);
+                       $res = Crypto::newKeypair(1024);
                        Config::set('system', 'site_prvkey', $res['prvkey']);
                        Config::set('system', 'site_pubkey', $res['pubkey']);
                }
index 15a30f532e30f433ae7a9ff114a309e2c6675652..59ca2757f367ddfae9235bd954f11060304454a1 100644 (file)
@@ -22,6 +22,7 @@ use Friendica\Model\Group;
 use Friendica\Model\Profile;
 use Friendica\Model\User;
 use Friendica\Network\Probe;
+use Friendica\Util\Crypto;
 use Friendica\Util\XML;
 
 use dba;
@@ -173,7 +174,7 @@ class Diaspora
 
                $key = self::key($handle);
 
-               $verify = rsa_verify($signable_data, $sig, $key);
+               $verify = Crypto::rsaVerify($signable_data, $sig, $key);
                if (!$verify) {
                        logger('Message did not verify. Discarding.');
                        return false;
@@ -273,7 +274,7 @@ class Diaspora
                $author_addr = base64_decode($key_id);
                $key = self::key($author_addr);
 
-               $verify = rsa_verify($signed_data, $signature, $key);
+               $verify = Crypto::rsaVerify($signed_data, $signature, $key);
                if (!$verify) {
                        logger('Message did not verify. Discarding.');
                        http_status_exit(400);
@@ -406,7 +407,7 @@ class Diaspora
                        http_status_exit(400);
                }
 
-               $verify = rsa_verify($signed_data, $signature, $key);
+               $verify = Crypto::rsaVerify($signed_data, $signature, $key);
 
                if (!$verify) {
                        logger('Message did not verify. Discarding.');
@@ -699,7 +700,7 @@ class Diaspora
 
                        $key = self::key($msg["author"]);
 
-                       if (!rsa_verify($signed_data, $parent_author_signature, $key, "sha256")) {
+                       if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) {
                                logger("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG);
                                return false;
                        }
@@ -709,7 +710,7 @@ class Diaspora
 
                $key = self::key($fields->author);
 
-               if (!rsa_verify($signed_data, $author_signature, $key, "sha256")) {
+               if (!Crypto::rsaVerify($signed_data, $author_signature, $key, "sha256")) {
                        logger("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG);
                        return false;
                } else {
@@ -1432,7 +1433,7 @@ class Diaspora
                // Check signature
                $signed_text = 'AccountMigration:'.$old_handle.':'.$new_handle;
                $key = self::key($old_handle);
-               if (!rsa_verify($signed_text, $signature, $key, "sha256")) {
+               if (!Crypto::rsaVerify($signed_text, $signature, $key, "sha256")) {
                        logger('No valid signature for migration.');
                        return false;
                }
@@ -3032,7 +3033,7 @@ class Diaspora
                        $user['uprvkey'] = $user['prvkey'];
                }
 
-               $signature = rsa_sign($signable_data, $user["uprvkey"]);
+               $signature = Crypto::rsaSign($signable_data, $user["uprvkey"]);
                $sig = base64url_encode($signature);
 
                $xmldata = array("me:env" => array("me:data" => $data,
@@ -3088,7 +3089,7 @@ class Diaspora
 
                $signed_text = implode(";", $sigmsg);
 
-               return base64_encode(rsa_sign($signed_text, $owner["uprvkey"], "sha256"));
+               return base64_encode(Crypto::rsaSign($signed_text, $owner["uprvkey"], "sha256"));
        }
 
        /**
@@ -3282,7 +3283,7 @@ class Diaspora
                $profile = self::createProfileData($uid);
 
                $signed_text = 'AccountMigration:'.$old_handle.':'.$profile['author'];
-               $signature = base64_encode(rsa_sign($signed_text, $owner["uprvkey"], "sha256"));
+               $signature = base64_encode(Crypto::rsaSign($signed_text, $owner["uprvkey"], "sha256"));
 
                $message = array("author" => $old_handle,
                                "profile" => $profile,
index d26a3229d11433e8d98df245b3174fd7d2f560b4..38a88c14afe48a9659bef69f8f57cd96565f5338 100644 (file)
@@ -5,10 +5,9 @@
 namespace Friendica\Protocol;
 
 use Friendica\Network\Probe;
+use Friendica\Util\Crypto;
 use Friendica\Util\XML;
 
-require_once 'include/crypto.php';
-
 /**
  * @brief Salmon Protocol class
  * The Salmon Protocol is a message exchange protocol running over HTTP designed to decentralize commentary
@@ -107,18 +106,18 @@ class Salmon
                $data_type = 'application/atom+xml';
                $encoding  = 'base64url';
                $algorithm = 'RSA-SHA256';
-               $keyhash   = base64url_encode(hash('sha256', salmon_key($owner['spubkey'])), true);
+               $keyhash   = base64url_encode(hash('sha256', Crypto::salmonKey($owner['spubkey'])), true);
 
                $precomputed = '.' . base64url_encode($data_type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($algorithm);
 
                // GNU Social format
-               $signature   = base64url_encode(rsa_sign($data . $precomputed, $owner['sprvkey']));
+               $signature   = base64url_encode(Crypto::rsaSign($data . $precomputed, $owner['sprvkey']));
 
                // Compliant format
-               $signature2  = base64url_encode(rsa_sign(str_replace('=', '', $data . $precomputed), $owner['sprvkey']));
+               $signature2  = base64url_encode(Crypto::rsaSign(str_replace('=', '', $data . $precomputed), $owner['sprvkey']));
 
                // Old Status.net format
-               $signature3  = base64url_encode(rsa_sign($data, $owner['sprvkey']));
+               $signature3  = base64url_encode(Crypto::rsaSign($data, $owner['sprvkey']));
 
                // At first try the non compliant method that works for GNU Social
                $xmldata = array("me:env" => array("me:data" => $data,
diff --git a/src/Util/Crypto.php b/src/Util/Crypto.php
new file mode 100644 (file)
index 0000000..433a5cd
--- /dev/null
@@ -0,0 +1,260 @@
+<?php
+/**
+ * @file src/Util/Crypto.php
+ */
+namespace Friendica\Util;
+
+use Friendica\Core\Config;
+
+require_once 'library/ASNValue.class.php';
+require_once 'library/asn1.php';
+
+/**
+ * @brief Crypto class
+ */
+class Crypto
+{
+       // supported algorithms are 'sha256', 'sha1'
+       /**
+        * @param string $data data
+        * @param string $key  key
+        * @param string $alg  algorithm
+        * @return string
+        */
+       public static function rsaSign($data, $key, $alg = 'sha256')
+       {
+               openssl_sign($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
+               return $sig;
+       }
+
+       /**
+        * @param string $data data
+        * @param string $sig  signature
+        * @param string $key  key
+        * @param string $alg  algorithm
+        * @return boolean
+        */
+       public static function rsaVerify($data, $sig, $key, $alg = 'sha256')
+       {
+               return openssl_verify($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
+       }
+
+       /**
+        * @param string $Der     der formatted string
+        * @param string $Private key type optional, default false
+        * @return string
+        */
+       private static 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;
+       }
+
+       /**
+        * @param string $Der der formatted string
+        * @return string
+        */
+       private static 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;
+       }
+
+       /**
+        * @param string $Modulus        modulo
+        * @param string $PublicExponent exponent
+        * @return string
+        */
+       private static function pkcs8Encode($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;
+       }
+
+       /**
+        * @param string $Modulus        modulo
+        * @param string $PublicExponent exponent
+        * @return string
+        */
+       private static function pkcs1Encode($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;
+       }
+
+       /**
+        * @param string $m modulo
+        * @param string $e exponent
+        * @return string
+        */
+       public static function meToPem($m, $e)
+       {
+               $der = self::pkcs8Encode($m, $e);
+               $key = self::DerToPem($der, false);
+               return $key;
+       }
+
+       /**
+        * @param string $key key
+        * @param string $m   modulo reference
+        * @param object $e   exponent reference
+        * @return void
+        */
+       private static function pubRsaToMe($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[0]->asnData);
+               $e = base64url_decode($r[0]->asnData[1]->asnData);
+       }
+
+       /**
+        * @param string $key key
+        * @return string
+        */
+       public static function rsaToPem($key)
+       {
+               self::pubRsaToMe($key, $m, $e);
+               return self::meToPem($m, $e);
+       }
+
+       /**
+        * @param string $key key
+        * @return string
+        */
+       private static function pemToRsa($key)
+       {
+               self::pemToMe($key, $m, $e);
+               return self::meToRsa($m, $e);
+       }
+
+       /**
+        * @param string $key key
+        * @param string $m   modulo reference
+        * @param string $e   exponent reference
+        * @return void
+        */
+       private static 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);
+       }
+
+       /**
+        * @param string $m modulo
+        * @param string $e exponent
+        * @return string
+        */
+       private static function meToRsa($m, $e)
+       {
+               $der = self::pkcs1Encode($m, $e);
+               $key = self::DerToRsa($der);
+               return $key;
+       }
+
+       /**
+        * @param string $pubkey public key
+        * @return string
+        */
+       public static function salmonKey($pubkey)
+       {
+               self::pemToMe($pubkey, $m, $e);
+               return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true);
+       }
+
+       /**
+        * @param integer $bits number of bits
+        * @return mixed
+        */
+       public static function newKeypair($bits)
+       {
+               $openssl_options = array(
+                       'digest_alg'       => 'sha1',
+                       'private_key_bits' => $bits,
+                       'encrypt_key'      => false
+               );
+
+               $conf = Config::get('system', 'openssl_conf_file');
+               if ($conf) {
+                       $openssl_options['config'] = $conf;
+               }
+               $result = openssl_pkey_new($openssl_options);
+
+               if (empty($result)) {
+                       logger('new_keypair: failed');
+                       return false;
+               }
+
+               // Get private key
+               $response = array('prvkey' => '', 'pubkey' => '');
+
+               openssl_pkey_export($result, $response['prvkey']);
+
+               // Get public key
+               $pkey = openssl_pkey_get_details($result);
+               $response['pubkey'] = $pkey["key"];
+
+               return $response;
+       }
+}