aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs/Lib')
-rw-r--r--Zotlabs/Lib/Crypto.php205
-rw-r--r--Zotlabs/Lib/JSalmon.php4
-rw-r--r--Zotlabs/Lib/LDSignatures.php12
-rw-r--r--Zotlabs/Lib/Libzot.php16
-rw-r--r--Zotlabs/Lib/Zotfinger.php12
5 files changed, 227 insertions, 22 deletions
diff --git a/Zotlabs/Lib/Crypto.php b/Zotlabs/Lib/Crypto.php
new file mode 100644
index 000000000..3dba1bcf3
--- /dev/null
+++ b/Zotlabs/Lib/Crypto.php
@@ -0,0 +1,205 @@
+<?php
+
+namespace Zotlabs\Lib;
+use Exception;
+
+class Crypto {
+
+ public static $openssl_algorithms = [
+
+ // zot6 nickname, opensslname, keylength, ivlength
+
+ [ 'aes256ctr', 'aes-256-ctr', 32, 16 ],
+ [ 'camellia256cfb', 'camellia-256-cfb', 32, 16 ],
+ [ 'cast5cfb', 'cast5-cfb', 16, 8 ]
+
+ ];
+
+ public static function methods() {
+ $ret = [];
+
+ foreach(self::$openssl_algorithms as $ossl) {
+ $ret[] = $ossl[0] . '.oaep';
+ }
+
+ call_hooks('crypto_methods',$ret);
+ return $ret;
+ }
+
+ public static function signing_methods() {
+
+ $ret = [ 'sha256' ];
+ call_hooks('signing_methods',$ret);
+ return $ret;
+
+ }
+
+ public static function new_keypair($bits) {
+
+ $openssl_options = [
+ 'digest_alg' => 'sha1',
+ 'private_key_bits' => $bits,
+ 'encrypt_key' => false
+ ];
+
+ $conf = get_config('system','openssl_conf_file');
+
+ if ($conf) {
+ $openssl_options['config'] = $conf;
+ }
+
+ $result = openssl_pkey_new($openssl_options);
+
+ if (empty($result)) {
+ return false;
+ }
+
+ // Get private key
+
+ $response = [ 'prvkey' => '', 'pubkey' => '' ];
+
+ openssl_pkey_export($result, $response['prvkey']);
+
+ // Get public key
+ $pkey = openssl_pkey_get_details($result);
+ $response['pubkey'] = $pkey["key"];
+
+ return $response;
+
+ }
+
+ public static function sign($data,$key,$alg = 'sha256') {
+
+ if (! $key) {
+ return false;
+ }
+
+ $sig = '';
+ openssl_sign($data,$sig,$key,$alg);
+ return $sig;
+ }
+
+ public static function verify($data,$sig,$key,$alg = 'sha256') {
+
+ if (! $key) {
+ return false;
+ }
+
+ try {
+ $verify = openssl_verify($data,$sig,$key,$alg);
+ }
+ catch (Exception $e) {
+ $verify = (-1);
+ }
+
+ if ($verify === (-1)) {
+ while ($msg = openssl_error_string()) {
+ logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR);
+ }
+ btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR);
+ }
+
+ return (($verify > 0) ? true : false);
+ }
+
+ public static function encapsulate($data,$pubkey,$alg) {
+
+ if (! ($alg && $pubkey)) {
+ return $data;
+ }
+
+ $alg_base = $alg;
+ $padding = OPENSSL_PKCS1_PADDING;
+
+ $exts = explode('.',$alg);
+ if (count($exts) > 1) {
+ switch ($exts[1]) {
+ case 'oaep':
+ $padding = OPENSSL_PKCS1_OAEP_PADDING;
+ break;
+ default:
+ break;
+ }
+ $alg_base = $exts[0];
+ }
+
+ $method = null;
+
+ foreach (self::$openssl_algorithms as $ossl) {
+ if ($ossl[0] === $alg_base) {
+ $method = $ossl;
+ break;
+ }
+ }
+
+ if ($method) {
+ $result = [ 'encrypted' => true ];
+
+ $key = openssl_random_pseudo_bytes(256);
+ $iv = openssl_random_pseudo_bytes(256);
+
+ $key1 = substr($key, 0, $method[2]);
+ $iv1 = substr($iv, 0, $method[3]);
+
+ $result['data'] = base64url_encode(openssl_encrypt($data,$method[1],$key1,OPENSSL_RAW_DATA,$iv1),true);
+
+ openssl_public_encrypt($key, $k, $pubkey, $padding);
+ openssl_public_encrypt($iv, $i, $pubkey, $padding);
+
+ $result['alg'] = $alg;
+ $result['key'] = base64url_encode($k,true);
+ $result['iv'] = base64url_encode($i,true);
+ return $result;
+
+ }
+ else {
+ $x = [ 'data' => $data, 'pubkey' => $pubkey, 'alg' => $alg, 'result' => $data ];
+ call_hooks('crypto_encapsulate', $x);
+ return $x['result'];
+ }
+ }
+
+ public static function unencapsulate($data,$prvkey) {
+
+ if (! (is_array($data) && array_key_exists('encrypted',$data) && array_key_exists('alg',$data) && $data['alg'])) {
+ logger('not encrypted');
+
+ return $data;
+ }
+
+ $alg_base = $data['alg'];
+ $padding = OPENSSL_PKCS1_PADDING;
+
+ $exts = explode('.',$data['alg']);
+ if (count($exts) > 1) {
+ switch ($exts[1]) {
+ case 'oaep':
+ $padding = OPENSSL_PKCS1_OAEP_PADDING;
+ break;
+ default:
+ break;
+ }
+ $alg_base = $exts[0];
+ }
+
+ $method = null;
+
+ foreach (self::$openssl_algorithms as $ossl) {
+ if ($ossl[0] === $alg_base) {
+ $method = $ossl;
+ break;
+ }
+ }
+
+ if ($method) {
+ openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey,$padding);
+ openssl_private_decrypt(base64url_decode($data['iv']), $i,$prvkey,$padding);
+ return openssl_decrypt(base64url_decode($data['data']),$method[1],substr($k,0,$method[2]),OPENSSL_RAW_DATA,substr($i,0,$method[3]));
+ }
+ else {
+ $x = [ 'data' => $data, 'prvkey' => $prvkey, 'alg' => $data['alg'], 'result' => $data ];
+ call_hooks('crypto_unencapsulate',$x);
+ return $x['result'];
+ }
+ }
+}
diff --git a/Zotlabs/Lib/JSalmon.php b/Zotlabs/Lib/JSalmon.php
index 7f63cf914..f9fe99706 100644
--- a/Zotlabs/Lib/JSalmon.php
+++ b/Zotlabs/Lib/JSalmon.php
@@ -18,7 +18,7 @@ class JSalmon {
$precomputed = '.' . base64url_encode($data_type,true) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng';
- $signature = base64url_encode(rsa_sign($data . $precomputed, $key), true);
+ $signature = base64url_encode(Crypto::sign($data . $precomputed, $key), true);
return ([
'signed' => true,
@@ -54,7 +54,7 @@ class JSalmon {
$key = HTTPSig::get_key(EMPTY_STR,'zot6',base64url_decode($x['sigs']['key_id']));
logger('key: ' . print_r($key,true));
if($key['portable_id'] && $key['public_key']) {
- if(rsa_verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
+ if(Crypto::verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
logger('verified');
$ret = [ 'success' => true, 'signer' => $key['portable_id'], 'hubloc' => $key['hubloc'] ];
}
diff --git a/Zotlabs/Lib/LDSignatures.php b/Zotlabs/Lib/LDSignatures.php
index 2eba66ccf..1c2095f10 100644
--- a/Zotlabs/Lib/LDSignatures.php
+++ b/Zotlabs/Lib/LDSignatures.php
@@ -12,7 +12,7 @@ class LDSignatures {
$ohash = self::hash(self::signable_options($data['signature']));
$dhash = self::hash(self::signable_data($data));
- $x = rsa_verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey);
+ $x = Crypto::verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey);
logger('LD-verify: ' . intval($x));
return $x;
@@ -35,11 +35,11 @@ class LDSignatures {
$ohash = self::hash(self::signable_options($options));
$dhash = self::hash(self::signable_data($data));
- $options['signatureValue'] = base64_encode(rsa_sign($ohash . $dhash,$channel['channel_prvkey']));
+ $options['signatureValue'] = base64_encode(Crypto::sign($ohash . $dhash,$channel['channel_prvkey']));
$signed = array_merge([
- '@context' => [
- ACTIVITYSTREAMS_JSONLD_REV,
+ '@context' => [
+ ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1' ],
],$options);
@@ -88,7 +88,7 @@ class LDSignatures {
return '';
jsonld_set_document_loader('jsonld_document_loader');
-
+
try {
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
}
@@ -117,7 +117,7 @@ class LDSignatures {
$precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
- $signature = base64url_encode(rsa_sign($data . $precomputed,$channel['channel_prvkey']));
+ $signature = base64url_encode(Crypto::sign($data . $precomputed,$channel['channel_prvkey']));
return ([
'id' => $arr['id'],
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index 0ead8402e..a615cee6e 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -130,7 +130,7 @@ class Libzot {
if ($remote_key) {
$algorithm = self::best_algorithm($methods);
if ($algorithm) {
- $data = crypto_encapsulate(json_encode($data), $remote_key, $algorithm);
+ $data = Crypto::encapsulate(json_encode($data), $remote_key, $algorithm);
}
}
@@ -143,7 +143,7 @@ class Libzot {
*
* @param string $methods
* Comma separated list of encryption methods
- * @return string first match from our site method preferences crypto_methods() array
+ * @return string first match from our site method preferences Crypto::methods() array
* of a method which is common to both sites; or 'aes256cbc' if no matches are found.
*/
static function best_algorithm($methods) {
@@ -167,7 +167,7 @@ class Libzot {
if ($methods) {
$x = explode(',', $methods);
if ($x) {
- $y = crypto_methods();
+ $y = Crypto::methods();
if ($y) {
foreach ($y as $yv) {
$yv = trim($yv);
@@ -763,8 +763,8 @@ class Libzot {
'xchan_guid' => $arr['id'],
'xchan_guid_sig' => $arr['id_sig'],
'xchan_pubkey' => $arr['public_key'],
- 'xchan_photo_mimetype' => $arr['photo']['type'],
- 'xchan_photo_l' => $arr['photo']['url'],
+ 'xchan_photo_mimetype' => $arr['photo_mimetype'],
+ 'xchan_photo_l' => $arr['photo'],
'xchan_addr' => escape_tags($arr['primary_location']['address']),
'xchan_url' => escape_tags($arr['primary_location']['url']),
'xchan_connurl' => $arr['primary_location']['connections_url'],
@@ -772,7 +772,7 @@ class Libzot {
'xchan_connpage' => $arr['connect_url'],
'xchan_name' => (($arr['name']) ? escape_tags($arr['name']) : '-'),
'xchan_network' => 'zot6',
- 'xchan_photo_date' => $arr['photo']['updated'],
+ 'xchan_photo_date' => $arr['photo_updated'],
'xchan_name_date' => $arr['name_updated'],
'xchan_hidden' => intval(1 - intval($arr['searchable'])),
'xchan_selfcensored' => $arr['adult_content'],
@@ -983,7 +983,7 @@ class Libzot {
logger('Headers: ' . print_r($arr['header'], true), LOGGER_DATA, LOG_DEBUG);
}
- $x = crypto_unencapsulate($x, get_config('system', 'prvkey'));
+ $x = Crypto::unencapsulate($x, get_config('system', 'prvkey'));
if (!is_array($x)) {
$x = json_decode($x, true);
@@ -3020,7 +3020,7 @@ class Libzot {
$ret['site']['directory_url'] = z_root() . '/dirsearch';
- $ret['site']['encryption'] = crypto_methods();
+ $ret['site']['encryption'] = Crypto::methods();
$ret['site']['zot'] = System::get_zot_revision();
// hide detailed site information if you're off the grid
diff --git a/Zotlabs/Lib/Zotfinger.php b/Zotlabs/Lib/Zotfinger.php
index faaf28f35..840d91403 100644
--- a/Zotlabs/Lib/Zotfinger.php
+++ b/Zotlabs/Lib/Zotfinger.php
@@ -18,8 +18,8 @@ class Zotfinger {
if($channel && $m) {
- $headers = [
- 'Accept' => 'application/x-zot+json',
+ $headers = [
+ 'Accept' => 'application/x-zot+json',
'Content-Type' => 'application/x-zot+json',
'X-Zot-Token' => random_string(),
'Digest' => HTTPSig::generate_digest_header($data),
@@ -29,9 +29,9 @@ class Zotfinger {
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
}
else {
- $h = [ 'Accept: application/x-zot+json' ];
+ $h = [ 'Accept: application/x-zot+json' ];
}
-
+
$result = [];
$redirects = 0;
@@ -43,11 +43,11 @@ class Zotfinger {
if ($verify) {
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
}
-
+
$result['data'] = json_decode($x['body'],true);
if($result['data'] && is_array($result['data']) && array_key_exists('encrypted',$result['data']) && $result['data']['encrypted']) {
- $result['data'] = json_decode(crypto_unencapsulate($result['data'],get_config('system','prvkey')),true);
+ $result['data'] = json_decode(Crypto::unencapsulate($result['data'],get_config('system','prvkey')),true);
}
logger('decrypted: ' . print_r($result,true));