From 1bfe1283aa38454369f29883411a6c012c88df59 Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 9 Aug 2011 18:55:46 -0700 Subject: [PATCH] crypto stuff --- boot.php | 2 +- images/friendika-16.png | Bin 770 -> 756 bytes include/{certfns.php => crypto.php} | 54 ++++++++++++++++++++++++++++ include/diaspora.php | 25 ++++--------- include/network.php | 14 ++++++++ include/salmon.php | 31 +++------------- include/text.php | 6 ++-- mod/receive.php | 2 +- mod/salmon.php | 44 +++++++---------------- mod/xrd.php | 14 +++----- 10 files changed, 102 insertions(+), 90 deletions(-) rename include/{certfns.php => crypto.php} (68%) diff --git a/boot.php b/boot.php index b5768c79..3b8c27f6 100644 --- a/boot.php +++ b/boot.php @@ -7,7 +7,7 @@ require_once('include/text.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 ( 'DB_UPDATE_VERSION', 1079 ); diff --git a/images/friendika-16.png b/images/friendika-16.png index 3793508fb2b39c060fd83cb788d3135fd6cd7f9e..745b7ac6c5ab5c611182478b8de48950d125d4cd 100644 GIT binary patch delta 702 zcmV;v0zv(P2J{7xLVp6BNkl`y=!D;7{!0*-uKRjlMiQhvq3N`ezBDz>Q)P4 zBVwg?wzl^E5&i*of+&k1g4n892!f)8i;Y3!Cb|K4<8ES-ncTVezVCZ1W;P-|#q%`h z91g!nA6~z{{_Nw$yAQ79H*hR-is0y+J2^+362o4{mp>KkG=E!8qlscWr#U{{n{I!5 zH9R)n|M>E1@zSuLMdrn4Tq)4o?$1x28V2b5}(v zaAI{O^5geo_J3BdKyQmQpDM>hoHh>A!(Z^Fk;nz~VDILP_rD(M*YG@LcM3NBD)V!* z?vu5VinF;K6Hdvg>l8#bxfU)Ul)ig#s2}#9X8VP=DemnWgpH~zR#jl-7K&2FvP1v` z<>DYoq6`IPs9aW+mH{ry3?%SED%*ep=cDtTa>=Y4sDElJ0AuJExTgj=N)lcg!hig; z%(bf*`Qn*Q&YaIa5qtAZ748gB^{sEV zCo~s^pntqXDS-$Da>^(rQ4YlJ-WeZ!zUl1?uZ!7%7F11tW5uh(u|ljNCpkqYtT1n+ zrYkKKJWv)mnT@RtO<#Nk{q@`ZpFzrU*Vy$bl5mPj&6IFs$G>k*v^80ix+G>zAhwZw zbQ>Mt!+@Qa=!|XK$n%-gpF1(U^U>)OpTTbJtVz;0@K3vSUzx_EpHQB%R#CkCp4U(OragrQmM{tB3sm76}3G6qIDb_=$ zUi6yO&4p*43zO>ZXpoXa7jcS`B9sY=Re&N4B7YxM?4CSH;tHv2+;@G^rtvV$556Oh zhNiYe(&1@h=YRK^kM7-9Q3{+`UyJst59!|7Bl6Th_lvVc6b|K8H-#%4SRRy zeDL*1zlK*R`%|zPRGDAei$1w9R&lnFW5Ovp^}T|~CO5(bgwpp94)w$S3v9pkF2#dg zgRoI`)v5}t+(A*wSe6KYpj;j#NtB_W43*2O(kj4ZnSX%Nc{I~!m+G4H&;&Zo0Cl^=hZGB)Oa0S0Fn zR$^3T@EJ(U%5^5>TFUvM^nAj5js=$mHC`qF8->>{LYSLmkS&W91HqDqDTf8y zI}1MhM1SlpHdVMcKsB(w*`Cr~8iDc(r34}r$SI?gL^%|@duM$3`KGroy)EVkT2eKG zjWw^2CJM2Eoa7Xpu)?C1+P<_@@JLzUWHz=oG<*FG^w)0>e+DVbeQP(TNWv*9wKKx4 z9k-iPRnrSnpTxWk#4eJL?xN!d7_jpSow02jc||dI`g13S_dY(o9SWYk{(L>yoR*w4 yk*@39&yPiOy5!@PF=rv=')) { + 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) { @@ -128,3 +178,7 @@ function metorsa($m,$e) { return $key; } +function salmon_key($pubkey) { + pemtome($pubkey,$m,$e); + return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ; +} diff --git a/include/diaspora.php b/include/diaspora.php index d25137bf..e39617aa 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -1,6 +1,6 @@ =')) { - $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); - } + $verify = rsa_verify($signed_data,$signature,$key); if(! $verify) { logger('mod-diaspora: Message did not verify. Discarding.'); - receive_return(400); + http_status_exit(400); } logger('mod-diaspora: Message verified.'); diff --git a/include/network.php b/include/network.php index 48e830e8..ddfc3497 100644 --- a/include/network.php +++ b/include/network.php @@ -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 // used by webfinger diff --git a/include/salmon.php b/include/salmon.php index 3ccae275..4043b4f1 100644 --- a/include/salmon.php +++ b/include/salmon.php @@ -1,21 +1,7 @@ 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) { @@ -112,24 +98,15 @@ EOT; $algorithm = 'RSA-SHA256'; $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 = '.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'); diff --git a/include/text.php b/include/text.php index adc94b45..7b43cd34 100644 --- a/include/text.php +++ b/include/text.php @@ -671,7 +671,7 @@ function smilies($s) { $a = get_app(); 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( '<3', '</3', @@ -688,7 +688,9 @@ function smilies($s) { ':-X', ':-D', '8-|', - '8-O' + '8-O', + '~friendika ~friendika', + ), $s); }} diff --git a/mod/receive.php b/mod/receive.php index 85143712..e2c11020 100644 --- a/mod/receive.php +++ b/mod/receive.php @@ -6,7 +6,7 @@ require_once('include/salmon.php'); -require_once('include/certfns.php'); +require_once('include/crypto.php'); require_once('include/diaspora.php'); diff --git a/mod/salmon.php b/mod/salmon.php index 514653be..0264e820 100644 --- a/mod/salmon.php +++ b/mod/salmon.php @@ -5,6 +5,7 @@ // complicated process to try and sort out. require_once('include/salmon.php'); +require_once('include/crypto.php'); require_once('library/simplepie/simplepie.inc'); function salmon_return($val) { @@ -33,7 +34,7 @@ function salmon_post(&$a) { dbesc($nick) ); if(! count($r)) - salmon_return(500); + http_status_exit(500); $importer = $r[0]; @@ -52,7 +53,7 @@ function salmon_post(&$a) { if(! $base) { 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. @@ -117,7 +118,7 @@ function salmon_post(&$a) { if(! $author_link) { 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 @@ -129,54 +130,35 @@ function salmon_post(&$a) { if(! $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); $m = base64url_decode($key_info[1]); $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(); - $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); + $pubkey = metopem($m,$e); // 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) { 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) { 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) { logger('mod-salmon: Message did not verify. Discarding.'); - salmon_return(400); + http_status_exit(400); } 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']))) { logger('mod-salmon: Ignoring this author.'); - salmon_return(202); + http_status_exit(202); // NOTREACHED } @@ -225,7 +207,7 @@ function salmon_post(&$a) { consume_feed($feedxml,$importer,$contact_rec,$hub); - salmon_return(200); + http_status_exit(200); } diff --git a/mod/xrd.php b/mod/xrd.php index 9021222b..fcec7433 100644 --- a/mod/xrd.php +++ b/mod/xrd.php @@ -1,9 +1,8 @@ $a->get_baseurl(), @@ -41,7 +38,6 @@ function xrd_content(&$a) { else $dspr = ''; - $tpl = file_get_contents('view/xrd_person.tpl'); $o = replace_macros($tpl, array( @@ -60,7 +56,7 @@ function xrd_content(&$a) { $arr = array('user' => $r[0], 'xml' => $o); call_hooks('personal_xrd', $arr); - echo $o; + echo $arr['xml']; killme(); }