From 1bfe1283aa38454369f29883411a6c012c88df59 Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 9 Aug 2011 18:55:46 -0700 Subject: crypto stuff --- include/certfns.php | 130 ------------------------------------ include/crypto.php | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/diaspora.php | 25 ++----- include/network.php | 14 ++++ include/salmon.php | 31 ++------- include/text.php | 6 +- 6 files changed, 212 insertions(+), 178 deletions(-) delete mode 100644 include/certfns.php create mode 100644 include/crypto.php (limited to 'include') diff --git a/include/certfns.php b/include/certfns.php deleted file mode 100644 index aa84cfeb6..000000000 --- a/include/certfns.php +++ /dev/null @@ -1,130 +0,0 @@ -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'); - require_once('include/salmon.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) { - require_once('include/salmon.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[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; -} - diff --git a/include/crypto.php b/include/crypto.php new file mode 100644 index 000000000..1ab9e7b25 --- /dev/null +++ b/include/crypto.php @@ -0,0 +1,184 @@ +=')) { + 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) +{ + //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, 65); + $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'); + require_once('include/salmon.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) { + require_once('include/salmon.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[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) ; +} diff --git a/include/diaspora.php b/include/diaspora.php index d25137bf3..e39617aa3 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 48e830e84..ddfc34977 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 3ccae2756..4043b4f1d 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 adc94b458..7b43cd340 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); }} -- cgit v1.2.3