Add RINO version 3 encrypt/decrypt

- Add legacy decrypt of RINO2
- Add fallback to RINO1 to encrypt
This commit is contained in:
Hypolite Petovan 2018-01-18 20:15:26 -05:00
parent 6857392067
commit 7af6cc8454
2 changed files with 47 additions and 22 deletions

View file

@ -6,6 +6,10 @@
* @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf * @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf
*/ */
use Defuse\Crypto\Crypto;
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
use Defuse\Crypto\Key;
use Friendica\App; use Friendica\App;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Database\DBM; use Friendica\Database\DBM;
@ -179,8 +183,8 @@ function dfrn_notify_post(App $a) {
break; break;
case 2: case 2:
try { try {
$data = \Crypto::decrypt(hex2bin($data), $final_key); $data = Crypto::legacyDecrypt(hex2bin($data), $final_key);
} catch (\InvalidCiphertextException $ex) { // VERY IMPORTANT } catch (WrongKeyOrModifiedCiphertextException $ex) { // VERY IMPORTANT
/* /*
* Either: * Either:
* 1. The ciphertext was modified by the attacker, * 1. The ciphertext was modified by the attacker,
@ -190,12 +194,28 @@ function dfrn_notify_post(App $a) {
*/ */
logger('The ciphertext has been tampered with!'); logger('The ciphertext has been tampered with!');
xml_status(0, 'The ciphertext has been tampered with!'); xml_status(0, 'The ciphertext has been tampered with!');
} catch (\CryptoTestFailedException $ex) { } catch (EnvironmentIsBrokenException $ex) {
logger('Cannot safely perform dencryption');
xml_status(0, 'CryptoTestFailed');
} catch (\CannotPerformOperationException $ex) {
logger('Cannot safely perform decryption'); logger('Cannot safely perform decryption');
xml_status(0, 'Cannot safely perform decryption'); xml_status(0, 'Environment is broken');
}
break;
case 3:
$KeyObject = Key::loadFromAsciiSafeString($final_key);
try {
$data = Crypto::decrypt(hex2bin($data), $KeyObject);
} catch (WrongKeyOrModifiedCiphertextException $ex) { // VERY IMPORTANT
/*
* Either:
* 1. The ciphertext was modified by the attacker,
* 2. The key is wrong, or
* 3. $ciphertext is not a valid ciphertext or was corrupted.
* Assume the worst.
*/
logger('The ciphertext has been tampered with!');
xml_status(0, 'The ciphertext has been tampered with!');
} catch (EnvironmentIsBrokenException $ex) {
logger('Cannot safely perform decryption');
xml_status(0, 'Environment is broken');
} }
break; break;
default: default:

View file

@ -8,6 +8,9 @@
*/ */
namespace Friendica\Protocol; namespace Friendica\Protocol;
use Defuse\Crypto\Crypto;
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use Defuse\Crypto\Key;
use Friendica\App; use Friendica\App;
use Friendica\Content\OEmbed; use Friendica\Content\OEmbed;
use Friendica\Core\Config; use Friendica\Core\Config;
@ -22,11 +25,14 @@ use Friendica\Model\Term;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Object\Image; use Friendica\Object\Image;
use Friendica\Protocol\OStatus; use Friendica\Protocol\OStatus;
use Friendica\Util\Crypto as FriendicaCrypto;
use Friendica\Util\XML; use Friendica\Util\XML;
use dba; use dba;
use DOMDocument; use DOMDocument;
use DOMXPath; use DOMXPath;
use HTMLPurifier;
use HTMLPurifier_Config;
require_once 'boot.php'; require_once 'boot.php';
require_once 'include/dba.php'; require_once 'include/dba.php';
@ -465,7 +471,7 @@ class DFRN
/* get site pubkey. this could be a new installation with no site keys*/ /* get site pubkey. this could be a new installation with no site keys*/
$pubkey = Config::get('system', 'site_pubkey'); $pubkey = Config::get('system', 'site_pubkey');
if (! $pubkey) { if (! $pubkey) {
$res = Crypto::newKeypair(1024); $res = FriendicaCrypto::newKeypair(1024);
Config::set('system', 'site_prvkey', $res['prvkey']); Config::set('system', 'site_prvkey', $res['prvkey']);
Config::set('system', 'site_pubkey', $res['pubkey']); Config::set('system', 'site_pubkey', $res['pubkey']);
} }
@ -1291,30 +1297,29 @@ class DFRN
switch ($rino_remote_version) { switch ($rino_remote_version) {
case 1: case 1:
case 2:
$rino = 1;
$rino_remote_version = 1;
// Deprecated rino version! // Deprecated rino version!
$key = openssl_random_pseudo_bytes(16); $key = openssl_random_pseudo_bytes(16);
$data = self::aesEncrypt($postvars['data'], $key); $data = self::aesEncrypt($postvars['data'], $key);
break; break;
case 2: case 3:
// RINO 2 based on php-encryption
try { try {
$key = \Crypto::CreateNewRandomKey(); $KeyObject = Key::createNewRandomKey();
} catch (\CryptoTestFailedException $ex) { } catch (EnvironmentIsBrokenException $ex) {
logger('Cannot safely create a key'); logger('Cannot safely create a key');
return -4; return -4;
} catch (\CannotPerformOperationException $ex) {
logger('Cannot safely create a key');
return -5;
} }
try { try {
$data = \Crypto::Encrypt($postvars['data'], $key); $data = Crypto::encrypt($postvars['data'], $key);
} catch (\CryptoTestFailedException $ex) { } catch (EnvironmentIsBrokenException $ex) {
logger('Cannot safely perform encryption'); logger('Cannot safely perform encryption');
return -6; return -6;
} catch (\CannotPerformOperationException $ex) {
logger('Cannot safely perform encryption');
return -7;
} }
$key = $KeyObject->saveToAsciiSafeString();
break; break;
default: default:
logger("rino: invalid requested version '$rino_remote_version'"); logger("rino: invalid requested version '$rino_remote_version'");
@ -2489,13 +2494,13 @@ class DFRN
$item['body'] = OEmbed::HTML2BBCode($item['body']); $item['body'] = OEmbed::HTML2BBCode($item['body']);
$config = \HTMLPurifier_Config::createDefault(); $config = HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null); $config->set('Cache.DefinitionImpl', null);
// we shouldn't need a whitelist, because the bbcode converter // we shouldn't need a whitelist, because the bbcode converter
// will strip out any unsupported tags. // will strip out any unsupported tags.
$purifier = new \HTMLPurifier($config); $purifier = new HTMLPurifier($config);
$item['body'] = $purifier->purify($item['body']); $item['body'] = $purifier->purify($item['body']);
$item['body'] = @html2bbcode($item['body']); $item['body'] = @html2bbcode($item['body']);