base64url calls

implement base64UrlEncode and base64UrlDecode functions
This commit is contained in:
Adam Magness 2018-11-08 10:37:08 -05:00
parent 0efcbe5d15
commit 6fc9c6de3b
13 changed files with 64 additions and 59 deletions

View file

@ -58,7 +58,7 @@ function salmon_post(App $a, $xml = '') {
// Stash the signature away for now. We have to find their key or it won't be good for anything. // Stash the signature away for now. We have to find their key or it won't be good for anything.
$signature = base64url_decode($base->sig); $signature = Strings::base64UrlDecode($base->sig);
// unpack the data // unpack the data
@ -77,13 +77,13 @@ function salmon_post(App $a, $xml = '') {
$stnet_signed_data = $data; $stnet_signed_data = $data;
$signed_data = $data . '.' . base64url_encode($type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($alg); $signed_data = $data . '.' . Strings::base64UrlEncode($type) . '.' . Strings::base64UrlEncode($encoding) . '.' . Strings::base64UrlEncode($alg);
$compliant_format = str_replace('=', '', $signed_data); $compliant_format = str_replace('=', '', $signed_data);
// decode the data // decode the data
$data = base64url_decode($data); $data = Strings::base64UrlDecode($data);
$author = OStatus::salmonAuthor($data, $importer); $author = OStatus::salmonAuthor($data, $importer);
$author_link = $author["author-link"]; $author_link = $author["author-link"];
@ -106,8 +106,8 @@ function salmon_post(App $a, $xml = '') {
$key_info = explode('.',$key); $key_info = explode('.',$key);
$m = base64url_decode($key_info[1]); $m = Strings::base64UrlDecode($key_info[1]);
$e = base64url_decode($key_info[2]); $e = Strings::base64UrlDecode($key_info[2]);
Logger::log('key details: ' . print_r($key_info,true), Logger::DEBUG); Logger::log('key details: ' . print_r($key_info,true), Logger::DEBUG);

View file

@ -11,12 +11,12 @@ First create a global unique userid
Site userid: Site userid:
https://macgirvin.com/1 https://macgirvin.com/1
$guuid = base64url_encode(hash('whirlpool','https://macgirvin.com/1.' . mt_rand(1000000,9999999),1); $guuid = Strings::base64UrlEncode(hash('whirlpool','https://macgirvin.com/1.' . mt_rand(1000000,9999999),1);
Then create a hashed site destination. Then create a hashed site destination.
$gduid = base64url_encode(hash('whirlpool', $guuid . 'https://macgirvin.com',1); $gduid = Strings::base64UrlEncode(hash('whirlpool', $guuid . 'https://macgirvin.com',1);
These two keys will identify you as a person+site pair in the future. These two keys will identify you as a person+site pair in the future.
You will also obtain a password upon introducing yourself to a site. You will also obtain a password upon introducing yourself to a site.

View file

@ -21,6 +21,7 @@ use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\ParseUrl; use Friendica\Util\ParseUrl;
use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Strings;
require_once 'include/dba.php'; require_once 'include/dba.php';
@ -373,7 +374,7 @@ class OEmbed
} }
$width = '100%'; $width = '100%';
$src = System::baseUrl() . '/oembed/' . base64url_encode($src); $src = System::baseUrl() . '/oembed/' . Strings::base64UrlEncode($src);
return '<iframe onload="resizeIframe(this);" class="embed_rich" height="' . $height . '" width="' . $width . '" src="' . $src . '" allowfullscreen scrolling="no" frameborder="no">' . L10n::t('Embedded content') . '</iframe>'; return '<iframe onload="resizeIframe(this);" class="embed_rich" height="' . $height . '" width="' . $width . '" src="' . $src . '" allowfullscreen scrolling="no" frameborder="no">' . L10n::t('Embedded content') . '</iframe>';
} }

View file

@ -19,6 +19,7 @@ use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Util\Strings;
/** /**
* This class contains functions to handle smiles * This class contains functions to handle smiles
@ -241,7 +242,7 @@ class Smilies
*/ */
private static function encode($m) private static function encode($m)
{ {
return(str_replace($m[1], base64url_encode($m[1]), $m[0])); return(str_replace($m[1], Strings::base64UrlEncode($m[1]), $m[0]));
} }
/** /**
@ -251,7 +252,7 @@ class Smilies
*/ */
private static function decode($m) private static function decode($m)
{ {
return(str_replace($m[1], base64url_decode($m[1]), $m[0])); return(str_replace($m[1], Strings::base64UrlDecode($m[1]), $m[0]));
} }

View file

@ -95,7 +95,7 @@ class Magic extends BaseModule
if ($j['encrypted_token']) { if ($j['encrypted_token']) {
// The token is encrypted. If the local user is really the one the other instance // The token is encrypted. If the local user is really the one the other instance
// thinks he/she is, the token can be decrypted with the local users public key. // thinks he/she is, the token can be decrypted with the local users public key.
openssl_private_decrypt(base64url_decode($j['encrypted_token']), $token, $user['prvkey']); openssl_private_decrypt(Strings::base64UrlDecode($j['encrypted_token']), $token, $user['prvkey']);
} else { } else {
$token = $j['token']; $token = $j['token'];
} }

View file

@ -4,6 +4,7 @@ namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Content; use Friendica\Content;
use Friendica\Util\Strings;
/** /**
* Oembed module * Oembed module
@ -36,7 +37,7 @@ class Oembed extends BaseModule
if ($a->argc == 2) { if ($a->argc == 2) {
echo '<html><body>'; echo '<html><body>';
$url = base64url_decode($a->argv[1]); $url = Strings::base64UrlDecode($a->argv[1]);
$j = Content\OEmbed::fetchURL($url); $j = Content\OEmbed::fetchURL($url);
// workaround for media.ccc.de (and any other endpoint that return size 0) // workaround for media.ccc.de (and any other endpoint that return size 0)

View file

@ -75,7 +75,7 @@ class Owa extends BaseModule
// At a later time, we will compare weather the token we're getting // At a later time, we will compare weather the token we're getting
// is really the same token we have stored in the database. // is really the same token we have stored in the database.
openssl_public_encrypt($token, $result, $contact['pubkey']); openssl_public_encrypt($token, $result, $contact['pubkey']);
$ret['encrypted_token'] = base64url_encode($result); $ret['encrypted_token'] = Strings::base64UrlEncode($result);
} else { } else {
Logger::log('OWA fail: ' . $contact['id'] . ' ' . $contact['addr'] . ' ' . $contact['url'], Logger::DEBUG); Logger::log('OWA fail: ' . $contact['id'] . ' ' . $contact['addr'] . ' ' . $contact['url'], Logger::DEBUG);
} }

View file

@ -1313,8 +1313,8 @@ class Probe
$key = explode(".", $pubkey); $key = explode(".", $pubkey);
if (sizeof($key) >= 3) { if (sizeof($key) >= 3) {
$m = base64url_decode($key[1]); $m = Strings::base64UrlDecode($key[1]);
$e = base64url_decode($key[2]); $e = Strings::base64UrlDecode($key[2]);
$data["pubkey"] = Crypto::meToPem($m, $e); $data["pubkey"] = Crypto::meToPem($m, $e);
} }
} }

View file

@ -1002,7 +1002,7 @@ class DFRN
XML::addElement($doc, $entry, "updated", DateTimeFormat::utc($item["edited"] . "+00:00", DateTimeFormat::ATOM)); XML::addElement($doc, $entry, "updated", DateTimeFormat::utc($item["edited"] . "+00:00", DateTimeFormat::ATOM));
// "dfrn:env" is used to read the content // "dfrn:env" is used to read the content
XML::addElement($doc, $entry, "dfrn:env", base64url_encode($body, true)); XML::addElement($doc, $entry, "dfrn:env", Strings::base64UrlEncode($body, true));
// The "content" field is not read by the receiver. We could remove it when the type is "text" // The "content" field is not read by the receiver. We could remove it when the type is "text"
// We keep it at the moment, maybe there is some old version that doesn't read "dfrn:env" // We keep it at the moment, maybe there is some old version that doesn't read "dfrn:env"
@ -2494,7 +2494,7 @@ class DFRN
$item["body"] = XML::getFirstNodeValue($xpath, "dfrn:env/text()", $entry); $item["body"] = XML::getFirstNodeValue($xpath, "dfrn:env/text()", $entry);
$item["body"] = str_replace([' ',"\t","\r","\n"], ['','','',''], $item["body"]); $item["body"] = str_replace([' ',"\t","\r","\n"], ['','','',''], $item["body"]);
// make sure nobody is trying to sneak some html tags by us // make sure nobody is trying to sneak some html tags by us
$item["body"] = Strings::removeTags(base64url_decode($item["body"])); $item["body"] = Strings::removeTags(Strings::base64UrlDecode($item["body"]));
$item["body"] = BBCode::limitBodySize($item["body"]); $item["body"] = BBCode::limitBodySize($item["body"]);

View file

@ -298,23 +298,23 @@ class Diaspora
$handle = ""; $handle = "";
$data = base64url_decode($children->data); $data = Strings::base64UrlDecode($children->data);
$type = $children->data->attributes()->type[0]; $type = $children->data->attributes()->type[0];
$encoding = $children->encoding; $encoding = $children->encoding;
$alg = $children->alg; $alg = $children->alg;
$sig = base64url_decode($children->sig); $sig = Strings::base64UrlDecode($children->sig);
$key_id = $children->sig->attributes()->key_id[0]; $key_id = $children->sig->attributes()->key_id[0];
if ($key_id != "") { if ($key_id != "") {
$handle = base64url_decode($key_id); $handle = Strings::base64UrlDecode($key_id);
} }
$b64url_data = base64url_encode($data); $b64url_data = Strings::base64UrlEncode($data);
$msg = str_replace(["\n", "\r", " ", "\t"], ["", "", "", ""], $b64url_data); $msg = str_replace(["\n", "\r", " ", "\t"], ["", "", "", ""], $b64url_data);
$signable_data = $msg.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg); $signable_data = $msg.".".Strings::base64UrlEncode($type).".".Strings::base64UrlEncode($encoding).".".Strings::base64UrlEncode($alg);
if ($handle == '') { if ($handle == '') {
Logger::log('No author could be decoded. Discarding. Message: ' . $envelope); Logger::log('No author could be decoded. Discarding. Message: ' . $envelope);
@ -426,10 +426,10 @@ class Diaspora
$type = $base->data[0]->attributes()->type[0]; $type = $base->data[0]->attributes()->type[0];
$encoding = $base->encoding; $encoding = $base->encoding;
$alg = $base->alg; $alg = $base->alg;
$signed_data = $data.'.'.base64url_encode($type).'.'.base64url_encode($encoding).'.'.base64url_encode($alg); $signed_data = $data.'.'.Strings::base64UrlEncode($type).'.'.Strings::base64UrlEncode($encoding).'.'.Strings::base64UrlEncode($alg);
// This is the signature // This is the signature
$signature = base64url_decode($base->sig); $signature = Strings::base64UrlDecode($base->sig);
// Get the senders' public key // Get the senders' public key
$key_id = $base->sig[0]->attributes()->key_id[0]; $key_id = $base->sig[0]->attributes()->key_id[0];
@ -463,7 +463,7 @@ class Diaspora
} }
} }
return ['message' => (string)base64url_decode($base->data), return ['message' => (string)Strings::base64UrlDecode($base->data),
'author' => XML::unescape($author_addr), 'author' => XML::unescape($author_addr),
'key' => (string)$key]; 'key' => (string)$key];
} }
@ -547,7 +547,7 @@ class Diaspora
// Stash the signature away for now. We have to find their key or it won't be good for anything. // Stash the signature away for now. We have to find their key or it won't be good for anything.
$signature = base64url_decode($base->sig); $signature = Strings::base64UrlDecode($base->sig);
// unpack the data // unpack the data
@ -563,11 +563,11 @@ class Diaspora
$alg = $base->alg; $alg = $base->alg;
$signed_data = $data.'.'.base64url_encode($type).'.'.base64url_encode($encoding).'.'.base64url_encode($alg); $signed_data = $data.'.'.Strings::base64UrlEncode($type).'.'.Strings::base64UrlEncode($encoding).'.'.Strings::base64UrlEncode($alg);
// decode the data // decode the data
$data = base64url_decode($data); $data = Strings::base64UrlDecode($data);
if ($public) { if ($public) {
@ -2962,14 +2962,14 @@ class Diaspora
*/ */
public static function buildMagicEnvelope($msg, array $user) public static function buildMagicEnvelope($msg, array $user)
{ {
$b64url_data = base64url_encode($msg); $b64url_data = Strings::base64UrlEncode($msg);
$data = str_replace(["\n", "\r", " ", "\t"], ["", "", "", ""], $b64url_data); $data = str_replace(["\n", "\r", " ", "\t"], ["", "", "", ""], $b64url_data);
$key_id = base64url_encode(self::myHandle($user)); $key_id = Strings::base64UrlEncode(self::myHandle($user));
$type = "application/xml"; $type = "application/xml";
$encoding = "base64url"; $encoding = "base64url";
$alg = "RSA-SHA256"; $alg = "RSA-SHA256";
$signable_data = $data.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg); $signable_data = $data.".".Strings::base64UrlEncode($type).".".Strings::base64UrlEncode($encoding).".".Strings::base64UrlEncode($alg);
// Fallback if the private key wasn't transmitted in the expected field // Fallback if the private key wasn't transmitted in the expected field
if ($user['uprvkey'] == "") { if ($user['uprvkey'] == "") {
@ -2977,7 +2977,7 @@ class Diaspora
} }
$signature = Crypto::rsaSign($signable_data, $user["uprvkey"]); $signature = Crypto::rsaSign($signable_data, $user["uprvkey"]);
$sig = base64url_encode($signature); $sig = Strings::base64UrlEncode($signature);
$xmldata = ["me:env" => ["me:data" => $data, $xmldata = ["me:env" => ["me:data" => $data,
"@attributes" => ["type" => $type], "@attributes" => ["type" => $type],

View file

@ -8,6 +8,7 @@ use Friendica\Core\Logger;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Util\Crypto; use Friendica\Util\Crypto;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Strings;
use Friendica\Util\XML; use Friendica\Util\XML;
/** /**
@ -70,7 +71,7 @@ class Salmon
return $ret[0]; return $ret[0];
} else { } else {
foreach ($ret as $a) { foreach ($ret as $a) {
$hash = base64url_encode(hash('sha256', $a)); $hash = Strings::base64UrlEncode(hash('sha256', $a));
if ($hash == $keyhash) { if ($hash == $keyhash) {
return $a; return $a;
} }
@ -104,22 +105,22 @@ class Salmon
// create a magic envelope // create a magic envelope
$data = base64url_encode($slap); $data = Strings::base64UrlEncode($slap);
$data_type = 'application/atom+xml'; $data_type = 'application/atom+xml';
$encoding = 'base64url'; $encoding = 'base64url';
$algorithm = 'RSA-SHA256'; $algorithm = 'RSA-SHA256';
$keyhash = base64url_encode(hash('sha256', self::salmonKey($owner['spubkey'])), true); $keyhash = Strings::base64UrlEncode(hash('sha256', self::salmonKey($owner['spubkey'])), true);
$precomputed = '.' . base64url_encode($data_type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($algorithm); $precomputed = '.' . Strings::base64UrlEncode($data_type) . '.' . Strings::base64UrlEncode($encoding) . '.' . Strings::base64UrlEncode($algorithm);
// GNU Social format // GNU Social format
$signature = base64url_encode(Crypto::rsaSign($data . $precomputed, $owner['sprvkey'])); $signature = Strings::base64UrlEncode(Crypto::rsaSign($data . $precomputed, $owner['sprvkey']));
// Compliant format // Compliant format
$signature2 = base64url_encode(Crypto::rsaSign(str_replace('=', '', $data . $precomputed), $owner['sprvkey'])); $signature2 = Strings::base64UrlEncode(Crypto::rsaSign(str_replace('=', '', $data . $precomputed), $owner['sprvkey']));
// Old Status.net format // Old Status.net format
$signature3 = base64url_encode(Crypto::rsaSign($data, $owner['sprvkey'])); $signature3 = Strings::base64UrlEncode(Crypto::rsaSign($data, $owner['sprvkey']));
// At first try the non compliant method that works for GNU Social // At first try the non compliant method that works for GNU Social
$xmldata = ["me:env" => ["me:data" => $data, $xmldata = ["me:env" => ["me:data" => $data,
@ -208,6 +209,6 @@ class Salmon
public static function salmonKey($pubkey) public static function salmonKey($pubkey)
{ {
Crypto::pemToMe($pubkey, $m, $e); Crypto::pemToMe($pubkey, $m, $e);
return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true); return 'RSA' . '.' . Strings::base64UrlEncode($m, true) . '.' . Strings::base64UrlEncode($e, true);
} }
} }

View file

@ -7,6 +7,7 @@ namespace Friendica\Util;
use Friendica\Core\Addon; use Friendica\Core\Addon;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Util\Strings;
use ASN_BASE; use ASN_BASE;
use ASNValue; use ASNValue;
@ -159,8 +160,8 @@ class Crypto
$r = ASN_BASE::parseASNString($x); $r = ASN_BASE::parseASNString($x);
$m = base64url_decode($r[0]->asnData[0]->asnData); $m = Strings::base64UrlDecode($r[0]->asnData[0]->asnData);
$e = base64url_decode($r[0]->asnData[1]->asnData); $e = Strings::base64UrlDecode($r[0]->asnData[1]->asnData);
} }
/** /**
@ -198,8 +199,8 @@ class Crypto
$r = ASN_BASE::parseASNString($x); $r = ASN_BASE::parseASNString($x);
$m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData); $m = Strings::base64UrlDecode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData);
$e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData); $e = Strings::base64UrlDecode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);
} }
/** /**
@ -355,7 +356,7 @@ class Crypto
$result = ['encrypted' => true]; $result = ['encrypted' => true];
$key = random_bytes(256); $key = random_bytes(256);
$iv = random_bytes(256); $iv = random_bytes(256);
$result['data'] = base64url_encode(self::$fn($data, $key, $iv), true); $result['data'] = Strings::base64UrlEncode(self::$fn($data, $key, $iv), true);
// log the offending call so we can track it down // log the offending call so we can track it down
if (!openssl_public_encrypt($key, $k, $pubkey)) { if (!openssl_public_encrypt($key, $k, $pubkey)) {
@ -364,9 +365,9 @@ class Crypto
} }
$result['alg'] = $alg; $result['alg'] = $alg;
$result['key'] = base64url_encode($k, true); $result['key'] = Strings::base64UrlEncode($k, true);
openssl_public_encrypt($iv, $i, $pubkey); openssl_public_encrypt($iv, $i, $pubkey);
$result['iv'] = base64url_encode($i, true); $result['iv'] = Strings::base64UrlEncode($i, true);
return $result; return $result;
} else { } else {
@ -395,7 +396,7 @@ class Crypto
$key = random_bytes(32); $key = random_bytes(32);
$iv = random_bytes(16); $iv = random_bytes(16);
$result = ['encrypted' => true]; $result = ['encrypted' => true];
$result['data'] = base64url_encode(self::encryptAES256CBC($data, $key, $iv), true); $result['data'] = Strings::base64UrlEncode(self::encryptAES256CBC($data, $key, $iv), true);
// log the offending call so we can track it down // log the offending call so we can track it down
if (!openssl_public_encrypt($key, $k, $pubkey)) { if (!openssl_public_encrypt($key, $k, $pubkey)) {
@ -404,9 +405,9 @@ class Crypto
} }
$result['alg'] = 'aes256cbc'; $result['alg'] = 'aes256cbc';
$result['key'] = base64url_encode($k, true); $result['key'] = Strings::base64UrlEncode($k, true);
openssl_public_encrypt($iv, $i, $pubkey); openssl_public_encrypt($iv, $i, $pubkey);
$result['iv'] = base64url_encode($i, true); $result['iv'] = Strings::base64UrlEncode($i, true);
return $result; return $result;
} }
@ -448,10 +449,10 @@ class Crypto
$fn = 'decrypt' . strtoupper($alg); $fn = 'decrypt' . strtoupper($alg);
if (method_exists(__CLASS__, $fn)) { if (method_exists(__CLASS__, $fn)) {
openssl_private_decrypt(base64url_decode($data['key']), $k, $prvkey); openssl_private_decrypt(Strings::base64UrlDecode($data['key']), $k, $prvkey);
openssl_private_decrypt(base64url_decode($data['iv']), $i, $prvkey); openssl_private_decrypt(Strings::base64UrlDecode($data['iv']), $i, $prvkey);
return self::$fn(base64url_decode($data['data']), $k, $i); return self::$fn(Strings::base64UrlDecode($data['data']), $k, $i);
} else { } else {
$x = ['data' => $data, 'prvkey' => $prvkey, 'alg' => $alg, 'result' => $data]; $x = ['data' => $data, 'prvkey' => $prvkey, 'alg' => $alg, 'result' => $data];
Addon::callHooks('other_unencapsulate', $x); Addon::callHooks('other_unencapsulate', $x);
@ -471,10 +472,10 @@ class Crypto
*/ */
private static function unencapsulateAes($data, $prvkey) private static function unencapsulateAes($data, $prvkey)
{ {
openssl_private_decrypt(base64url_decode($data['key']), $k, $prvkey); openssl_private_decrypt(Strings::base64UrlDecode($data['key']), $k, $prvkey);
openssl_private_decrypt(base64url_decode($data['iv']), $i, $prvkey); openssl_private_decrypt(Strings::base64UrlDecode($data['iv']), $i, $prvkey);
return self::decryptAES256CBC(base64url_decode($data['data']), $k, $i); return self::decryptAES256CBC(Strings::base64UrlDecode($data['data']), $k, $i);
} }

View file

@ -220,7 +220,7 @@ class Strings
* *
* @return string Transformed string. * @return string Transformed string.
*/ */
public static function protectSprintf($s) // protect_sprintf() public static function protectSprintf($s)
{ {
return str_replace('%', '%%', $s); return str_replace('%', '%%', $s);
} }
@ -233,7 +233,7 @@ class Strings
* *
* @return string Encoded URL * @return string Encoded URL
*/ */
public static function base64UrlEncode($s, $strip_padding = false) //base64url_encode() public static function base64UrlEncode($s, $strip_padding = false)
{ {
$s = strtr(base64_encode($s), '+/', '-_'); $s = strtr(base64_encode($s), '+/', '-_');
@ -250,7 +250,7 @@ class Strings
* *
* @return string Decoded URL * @return string Decoded URL
*/ */
public static function base64url_decode($s) // base64url_decode() public static function base64UrlDecode($s)
{ {
if (is_array($s)) { if (is_array($s)) {
Logger::log('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true)); Logger::log('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true));