crypto stuff
This commit is contained in:
parent
49be394182
commit
1bfe1283aa
10 changed files with 102 additions and 90 deletions
2
boot.php
2
boot.php
|
@ -7,7 +7,7 @@ require_once('include/text.php');
|
||||||
require_once("include/pgettext.php");
|
require_once("include/pgettext.php");
|
||||||
|
|
||||||
|
|
||||||
define ( 'FRIENDIKA_VERSION', '2.2.1066' );
|
define ( 'FRIENDIKA_VERSION', '2.2.1067' );
|
||||||
define ( 'DFRN_PROTOCOL_VERSION', '2.21' );
|
define ( 'DFRN_PROTOCOL_VERSION', '2.21' );
|
||||||
define ( 'DB_UPDATE_VERSION', 1079 );
|
define ( 'DB_UPDATE_VERSION', 1079 );
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 770 B After Width: | Height: | Size: 756 B |
|
@ -1,6 +1,56 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once('library/ASNValue.class.php');
|
require_once('library/ASNValue.class.php');
|
||||||
|
require_once('library/asn1.php');
|
||||||
|
|
||||||
|
|
||||||
|
function rsa_sign($data,$key) {
|
||||||
|
|
||||||
|
$sig = '';
|
||||||
|
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||||
|
openssl_sign($data,$sig,$key,'sha256');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(strlen($key) < 1024 || extension_loaded('gmp')) {
|
||||||
|
require_once('library/phpsec/Crypt/RSA.php');
|
||||||
|
$rsa = new CRYPT_RSA();
|
||||||
|
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
||||||
|
$rsa->setHash('sha256');
|
||||||
|
$rsa->loadKey($key);
|
||||||
|
$sig = $rsa->sign($data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger('rsa_sign: insecure algorithm used. Please upgrade PHP to 5.3');
|
||||||
|
openssl_private_encrypt(hex2bin('3031300d060960864801650304020105000420') . hash('sha256',$data,true), $sig, $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rsa_verify($data,$sig,$key) {
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||||
|
$verify = openssl_verify($data,$sig,$key,'sha256');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(strlen($key) <= 300 || extension_loaded('gmp')) {
|
||||||
|
require_once('library/phpsec/Crypt/RSA.php');
|
||||||
|
$rsa = new CRYPT_RSA();
|
||||||
|
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
||||||
|
$rsa->setHash('sha256');
|
||||||
|
$rsa->loadKey($key);
|
||||||
|
$verify = $rsa->verify($data,$sig);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// fallback sha256 verify for PHP < 5.3 and large key lengths
|
||||||
|
$rawsig = '';
|
||||||
|
openssl_public_decrypt($sig,$rawsig,$key);
|
||||||
|
$verify = (($rawsig && substr($rawsig,-32) === hash('sha256',$data,true)) ? true : false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $verify;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function DerToPem($Der, $Private=false)
|
function DerToPem($Der, $Private=false)
|
||||||
{
|
{
|
||||||
|
@ -128,3 +178,7 @@ function metorsa($m,$e) {
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function salmon_key($pubkey) {
|
||||||
|
pemtome($pubkey,$m,$e);
|
||||||
|
return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once('include/certfns.php');
|
require_once('include/crypto.php');
|
||||||
|
|
||||||
function receive_return($val) {
|
function receive_return($val) {
|
||||||
|
|
||||||
|
@ -83,9 +83,7 @@ function diaspora_msg_build($msg,$user,$contact,$prvkey,$pubkey) {
|
||||||
$signable_data = $data . '.' . base64url_encode($type) . "\n" . '.'
|
$signable_data = $data . '.' . base64url_encode($type) . "\n" . '.'
|
||||||
. base64url_encode($encoding) . "\n" . '.' . base64url_encode($alg) . "\n";
|
. base64url_encode($encoding) . "\n" . '.' . base64url_encode($alg) . "\n";
|
||||||
|
|
||||||
$signature = '';
|
$signature = rsa_sign($signable_data,$prvkey);
|
||||||
$result = openssl_sign($signable_data,$signature,$prvkey,'SHA256');
|
|
||||||
|
|
||||||
$sig = base64url_encode($signature);
|
$sig = base64url_encode($signature);
|
||||||
|
|
||||||
$decrypted_header = <<< EOT
|
$decrypted_header = <<< EOT
|
||||||
|
@ -226,7 +224,7 @@ function diaspora_decode($importer,$xml) {
|
||||||
|
|
||||||
if(! $author_link) {
|
if(! $author_link) {
|
||||||
logger('mod-diaspora: Could not retrieve author URI.');
|
logger('mod-diaspora: Could not retrieve author URI.');
|
||||||
receive_return(400);
|
http_status_exit(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once we have the author URI, go to the web and try to find their public key
|
// Once we have the author URI, go to the web and try to find their public key
|
||||||
|
@ -239,25 +237,14 @@ function diaspora_decode($importer,$xml) {
|
||||||
|
|
||||||
if(! $key) {
|
if(! $key) {
|
||||||
logger('mod-diaspora: Could not retrieve author key.');
|
logger('mod-diaspora: Could not retrieve author key.');
|
||||||
receive_return(400);
|
http_status_exit(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$verify = false;
|
$verify = rsa_verify($signed_data,$signature,$key);
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
|
||||||
$verify = openssl_verify($signed_data,$signature,$key,'sha256');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// fallback sha256 verify for PHP < 5.3
|
|
||||||
$rawsig = '';
|
|
||||||
$hash = hash('sha256',$signed_data,true);
|
|
||||||
openssl_public_decrypt($signature,$rawsig,$key);
|
|
||||||
$verify = (($rawsig && substr($rawsig,-32) === $hash) ? true : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(! $verify) {
|
if(! $verify) {
|
||||||
logger('mod-diaspora: Message did not verify. Discarding.');
|
logger('mod-diaspora: Message did not verify. Discarding.');
|
||||||
receive_return(400);
|
http_status_exit(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger('mod-diaspora: Message verified.');
|
logger('mod-diaspora: Message verified.');
|
||||||
|
|
|
@ -181,6 +181,20 @@ function xml_status($st, $message = '') {
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
if(! function_exists('http_status_exit')) {
|
||||||
|
function http_status_exit($val) {
|
||||||
|
|
||||||
|
if($val >= 400)
|
||||||
|
$err = 'Error';
|
||||||
|
if($val >= 200 && $val < 300)
|
||||||
|
$err = 'OK';
|
||||||
|
|
||||||
|
logger('http_status_exit ' . $val);
|
||||||
|
header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $err);
|
||||||
|
killme();
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
// convert an XML document to a normalised, case-corrected array
|
// convert an XML document to a normalised, case-corrected array
|
||||||
// used by webfinger
|
// used by webfinger
|
||||||
|
|
|
@ -1,21 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once('library/asn1.php');
|
require_once('include/crypto.php');
|
||||||
|
|
||||||
function salmon_key($pubkey) {
|
|
||||||
$lines = explode("\n",$pubkey);
|
|
||||||
unset($lines[0]);
|
|
||||||
unset($lines[count($lines)]);
|
|
||||||
$x = base64_decode(implode('',$lines));
|
|
||||||
|
|
||||||
$r = ASN_BASE::parseASNString($x);
|
|
||||||
|
|
||||||
$m = $r[0]->asnData[1]->asnData[0]->asnData[0]->asnData;
|
|
||||||
$e = $r[0]->asnData[1]->asnData[0]->asnData[1]->asnData;
|
|
||||||
|
|
||||||
|
|
||||||
return 'RSA' . '.' . $m . '.' . $e ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function get_salmon_key($uri,$keyhash) {
|
function get_salmon_key($uri,$keyhash) {
|
||||||
|
@ -112,24 +98,15 @@ EOT;
|
||||||
$algorithm = 'RSA-SHA256';
|
$algorithm = 'RSA-SHA256';
|
||||||
$keyhash = base64url_encode(hash('sha256',salmon_key($owner['spubkey'])),true);
|
$keyhash = base64url_encode(hash('sha256',salmon_key($owner['spubkey'])),true);
|
||||||
|
|
||||||
// Setup RSA stuff to PKCS#1 sign the data
|
|
||||||
|
|
||||||
require_once('library/phpsec/Crypt/RSA.php');
|
|
||||||
|
|
||||||
$rsa = new CRYPT_RSA();
|
|
||||||
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
|
||||||
$rsa->setHash('sha256');
|
|
||||||
$rsa->loadKey($owner['sprvkey']);
|
|
||||||
|
|
||||||
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
|
||||||
|
|
||||||
$precomputed = '.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
|
$precomputed = '.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
|
||||||
|
|
||||||
$signature = base64url_encode($rsa->sign(str_replace('=','',$data . $precomputed),true));
|
$signature = base64url_encode(rsa_sign(str_replace('=','',$data . $precomputed),true),$owner['sprvkey']);
|
||||||
|
|
||||||
$signature2 = base64url_encode($rsa->sign($data . $precomputed));
|
$signature2 = base64url_encode(rsa_sign($data . $precomputed),$owner['sprvkey']);
|
||||||
|
|
||||||
$signature3 = base64url_encode($rsa->sign($data));
|
$signature3 = base64url_encode(rsa_sign($data),$owner['sprvkey']);
|
||||||
|
|
||||||
$salmon_tpl = get_markup_template('magicsig.tpl');
|
$salmon_tpl = get_markup_template('magicsig.tpl');
|
||||||
|
|
||||||
|
|
|
@ -671,7 +671,7 @@ function smilies($s) {
|
||||||
$a = get_app();
|
$a = get_app();
|
||||||
|
|
||||||
return str_replace(
|
return str_replace(
|
||||||
array( '<3', '</3', '<\\3', ':-)', ':)', ';-)', ':-(', ':(', ':-P', ':P', ':-"', ':-x', ':-X', ':-D', '8-|', '8-O'),
|
array( '<3', '</3', '<\\3', ':-)', ':)', ';-)', ':-(', ':(', ':-P', ':P', ':-"', ':-x', ':-X', ':-D', '8-|', '8-O', '~friendika' ),
|
||||||
array(
|
array(
|
||||||
'<img src="' . $a->get_baseurl() . '/images/smiley-heart.gif" alt="<3" />',
|
'<img src="' . $a->get_baseurl() . '/images/smiley-heart.gif" alt="<3" />',
|
||||||
'<img src="' . $a->get_baseurl() . '/images/smiley-brokenheart.gif" alt="</3" />',
|
'<img src="' . $a->get_baseurl() . '/images/smiley-brokenheart.gif" alt="</3" />',
|
||||||
|
@ -688,7 +688,9 @@ function smilies($s) {
|
||||||
'<img src="' . $a->get_baseurl() . '/images/smiley-kiss.gif" alt=":-X" />',
|
'<img src="' . $a->get_baseurl() . '/images/smiley-kiss.gif" alt=":-X" />',
|
||||||
'<img src="' . $a->get_baseurl() . '/images/smiley-laughing.gif" alt=":-D" />',
|
'<img src="' . $a->get_baseurl() . '/images/smiley-laughing.gif" alt=":-D" />',
|
||||||
'<img src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-|" />',
|
'<img src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-|" />',
|
||||||
'<img src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-O" />'
|
'<img src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-O" />',
|
||||||
|
'<a href="http://project.friendika.com">~friendika <img src="' . $a->get_baseurl() . '/images/friendika-16.png" alt="~friendika" /></a>',
|
||||||
|
|
||||||
), $s);
|
), $s);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
require_once('include/salmon.php');
|
require_once('include/salmon.php');
|
||||||
require_once('include/certfns.php');
|
require_once('include/crypto.php');
|
||||||
require_once('include/diaspora.php');
|
require_once('include/diaspora.php');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// complicated process to try and sort out.
|
// complicated process to try and sort out.
|
||||||
|
|
||||||
require_once('include/salmon.php');
|
require_once('include/salmon.php');
|
||||||
|
require_once('include/crypto.php');
|
||||||
require_once('library/simplepie/simplepie.inc');
|
require_once('library/simplepie/simplepie.inc');
|
||||||
|
|
||||||
function salmon_return($val) {
|
function salmon_return($val) {
|
||||||
|
@ -33,7 +34,7 @@ function salmon_post(&$a) {
|
||||||
dbesc($nick)
|
dbesc($nick)
|
||||||
);
|
);
|
||||||
if(! count($r))
|
if(! count($r))
|
||||||
salmon_return(500);
|
http_status_exit(500);
|
||||||
|
|
||||||
$importer = $r[0];
|
$importer = $r[0];
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ function salmon_post(&$a) {
|
||||||
|
|
||||||
if(! $base) {
|
if(! $base) {
|
||||||
logger('mod-salmon: unable to locate salmon data in xml ');
|
logger('mod-salmon: unable to locate salmon data in xml ');
|
||||||
salmon_return(400);
|
http_status_exit(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -117,7 +118,7 @@ function salmon_post(&$a) {
|
||||||
|
|
||||||
if(! $author_link) {
|
if(! $author_link) {
|
||||||
logger('mod-salmon: Could not retrieve author URI.');
|
logger('mod-salmon: Could not retrieve author URI.');
|
||||||
salmon_return(400);
|
http_status_exit(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once we have the author URI, go to the web and try to find their public key
|
// Once we have the author URI, go to the web and try to find their public key
|
||||||
|
@ -129,54 +130,35 @@ function salmon_post(&$a) {
|
||||||
|
|
||||||
if(! $key) {
|
if(! $key) {
|
||||||
logger('mod-salmon: Could not retrieve author key.');
|
logger('mod-salmon: Could not retrieve author key.');
|
||||||
salmon_return(400);
|
http_status_exit(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup RSA stuff to verify the signature
|
|
||||||
|
|
||||||
require_once('library/phpsec/Crypt/RSA.php');
|
|
||||||
|
|
||||||
$rsa = new CRYPT_RSA();
|
|
||||||
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
|
||||||
$rsa->setHash('sha256');
|
|
||||||
$rsa->loadKey($prvkey);
|
|
||||||
|
|
||||||
$sig = $rsa->sign($data);
|
|
||||||
|
|
||||||
require_once('library/phpsec/Crypt/RSA.php');
|
|
||||||
|
|
||||||
$key_info = explode('.',$key);
|
$key_info = explode('.',$key);
|
||||||
|
|
||||||
$m = base64url_decode($key_info[1]);
|
$m = base64url_decode($key_info[1]);
|
||||||
$e = base64url_decode($key_info[2]);
|
$e = base64url_decode($key_info[2]);
|
||||||
|
|
||||||
logger('mod-salmon: key details: ' . print_r($key_info,true));
|
logger('mod-salmon: key details: ' . print_r($key_info,true), LOGGER_DEBUG);
|
||||||
|
|
||||||
$rsa = new CRYPT_RSA();
|
$pubkey = metopem($m,$e);
|
||||||
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
|
||||||
$rsa->setHash('sha256');
|
|
||||||
|
|
||||||
$rsa->modulus = new Math_BigInteger($m, 256);
|
|
||||||
$rsa->k = strlen($rsa->modulus->toBytes());
|
|
||||||
$rsa->exponent = new Math_BigInteger($e, 256);
|
|
||||||
|
|
||||||
// We should have everything we need now. Let's see if it verifies.
|
// We should have everything we need now. Let's see if it verifies.
|
||||||
|
|
||||||
$verify = $rsa->verify($compliant_format,$signature);
|
$verify = rsa_verify($compliant_format,$signature,$pubkey);
|
||||||
|
|
||||||
if(! $verify) {
|
if(! $verify) {
|
||||||
logger('mod-salmon: message did not verify using protocol. Trying padding hack.');
|
logger('mod-salmon: message did not verify using protocol. Trying padding hack.');
|
||||||
$verify = $rsa->verify($signed_data,$signature);
|
$verify = rsa_verify($signed_data,$signature,$pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! $verify) {
|
if(! $verify) {
|
||||||
logger('mod-salmon: message did not verify using padding. Trying old statusnet hack.');
|
logger('mod-salmon: message did not verify using padding. Trying old statusnet hack.');
|
||||||
$verify = $rsa->verify($stnet_signed_data,$signature);
|
$verify = rsa_verify($stnet_signed_data,$signature,$pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! $verify) {
|
if(! $verify) {
|
||||||
logger('mod-salmon: Message did not verify. Discarding.');
|
logger('mod-salmon: Message did not verify. Discarding.');
|
||||||
salmon_return(400);
|
http_status_exit(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger('mod-salmon: Message verified.');
|
logger('mod-salmon: Message verified.');
|
||||||
|
@ -203,7 +185,7 @@ function salmon_post(&$a) {
|
||||||
|
|
||||||
if((count($r)) && (($r[0]['readonly']) || ($r[0]['rel'] == CONTACT_IS_FOLLOWER) || ($r[0]['blocked']))) {
|
if((count($r)) && (($r[0]['readonly']) || ($r[0]['rel'] == CONTACT_IS_FOLLOWER) || ($r[0]['blocked']))) {
|
||||||
logger('mod-salmon: Ignoring this author.');
|
logger('mod-salmon: Ignoring this author.');
|
||||||
salmon_return(202);
|
http_status_exit(202);
|
||||||
// NOTREACHED
|
// NOTREACHED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +207,7 @@ function salmon_post(&$a) {
|
||||||
|
|
||||||
consume_feed($feedxml,$importer,$contact_rec,$hub);
|
consume_feed($feedxml,$importer,$contact_rec,$hub);
|
||||||
|
|
||||||
salmon_return(200);
|
http_status_exit(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
14
mod/xrd.php
14
mod/xrd.php
|
@ -1,9 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once('salmon.php');
|
require_once('include/crypto.php');
|
||||||
require_once('certfns.php');
|
|
||||||
|
|
||||||
function xrd_content(&$a) {
|
function xrd_init(&$a) {
|
||||||
|
|
||||||
$uri = urldecode(notags(trim($_GET['uri'])));
|
$uri = urldecode(notags(trim($_GET['uri'])));
|
||||||
|
|
||||||
|
@ -23,14 +22,12 @@ function xrd_content(&$a) {
|
||||||
if(! count($r))
|
if(! count($r))
|
||||||
killme();
|
killme();
|
||||||
|
|
||||||
$salmon_key = str_replace('=','',salmon_key($r[0]['spubkey']));
|
$salmon_key = salmon_key($r[0]['spubkey']);
|
||||||
|
|
||||||
header('Access-Control-Allow-Origin: *');
|
header('Access-Control-Allow-Origin: *');
|
||||||
header("Content-type: text/xml");
|
header("Content-type: text/xml");
|
||||||
|
|
||||||
$dspr_enabled = get_config('system','diaspora_enabled');
|
if(get_config('system','diaspora_enabled')) {
|
||||||
|
|
||||||
if($dspr_enabled) {
|
|
||||||
$tpl = file_get_contents('view/xrd_diaspora.tpl');
|
$tpl = file_get_contents('view/xrd_diaspora.tpl');
|
||||||
$dspr = replace_macros($tpl,array(
|
$dspr = replace_macros($tpl,array(
|
||||||
'$baseurl' => $a->get_baseurl(),
|
'$baseurl' => $a->get_baseurl(),
|
||||||
|
@ -41,7 +38,6 @@ function xrd_content(&$a) {
|
||||||
else
|
else
|
||||||
$dspr = '';
|
$dspr = '';
|
||||||
|
|
||||||
|
|
||||||
$tpl = file_get_contents('view/xrd_person.tpl');
|
$tpl = file_get_contents('view/xrd_person.tpl');
|
||||||
|
|
||||||
$o = replace_macros($tpl, array(
|
$o = replace_macros($tpl, array(
|
||||||
|
@ -60,7 +56,7 @@ function xrd_content(&$a) {
|
||||||
$arr = array('user' => $r[0], 'xml' => $o);
|
$arr = array('user' => $r[0], 'xml' => $o);
|
||||||
call_hooks('personal_xrd', $arr);
|
call_hooks('personal_xrd', $arr);
|
||||||
|
|
||||||
echo $o;
|
echo $arr['xml'];
|
||||||
killme();
|
killme();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue