Пример #1
0
 protected function initAes($key, $iv, $keySize)
 {
     $this->aes = new \Crypt_AES();
     $this->aes->setKeyLength($keySize);
     $this->aesKey = $key;
     $this->aesIV = $iv;
     $this->aes->setKey($this->aesKey);
     $this->aes->setIV($this->aesIV);
 }
 public static function decrypt($secret, $password, ApiKeyEncryptionOptions $options)
 {
     $decodedSecret = self::base64url_decode($secret);
     $salt = self::base64url_decode($options->getEncryptionKeySalt());
     $iterations = $options->getEncryptionKeyIterations();
     $keyLengthBits = $options->getEncryptionKeySize();
     $iv = substr($decodedSecret, 0, 16);
     $aes = new \Crypt_AES();
     $aes->setPassword($password, 'pbkdf2', 'sha1', $salt, $iterations, $keyLengthBits / 8);
     $aes->setKeyLength($keyLengthBits);
     $aes->setIV($iv);
     return $aes->decrypt(substr($decodedSecret, 16));
 }
Пример #3
0
/**
 * Checks whether a user has the right to enter on the platform or not
 * @param string The username, as provided in form
 * @param string The cleartext password, as provided in form
 * @param string The WS URL, as provided at the beginning of this script
 */
function loginWSAuthenticate($username, $password, $wsUrl)
{
    // check params
    if (empty($username) or empty($password) or empty($wsUrl)) {
        return false;
    }
    // Create new SOAP client instance
    $client = new SoapClient($wsUrl);
    if (!$client) {
        return false;
    }
    // Include phpseclib methods, because of a bug with AES/CFB in mcrypt
    include_once api_get_path(LIBRARY_PATH) . 'phpseclib/Crypt/AES.php';
    // Define all elements necessary to the encryption
    $key = '-+*%$({[]})$%*+-';
    // Complete password con PKCS7-specific padding
    $blockSize = 16;
    $padding = $blockSize - strlen($password) % $blockSize;
    $password .= str_repeat(chr($padding), $padding);
    $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
    $cipher->setKeyLength(128);
    $cipher->setKey($key);
    $cipher->setIV($key);
    $cipheredPass = $cipher->encrypt($password);
    // Mcrypt call left for documentation purposes - broken, see https://bugs.php.net/bug.php?id=51146
    //$cipheredPass = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $password,  MCRYPT_MODE_CFB, $key);
    // Following lines present for debug purposes only
    /*
    $arr = preg_split('//', $cipheredPass, -1, PREG_SPLIT_NO_EMPTY);
    foreach ($arr as $char) {
        error_log(ord($char));
    }
    */
    // Change to base64 to avoid communication alteration
    $passCrypted = base64_encode($cipheredPass);
    // The call to the webservice will change depending on your definition
    try {
        $response = $client->validateUser(array('user' => $username, 'pass' => $passCrypted, 'system' => 'chamilo'));
    } catch (SoapFault $fault) {
        error_log('Caught something');
        if ($fault->faultstring != 'Could not connect to host') {
            error_log('Not a connection problem');
            throw $fault;
        } else {
            error_log('Could not connect to WS host');
        }
        return 0;
    }
    return $response->validateUserResult;
}
Пример #4
0
 /**
  * Initializes AES instance using either provided $options or session values
  * @param array $options Array of options, containing 'key' and 'iv' values
  * @return mixed|void
  * @throws Exception
  */
 public function initSymmetric($options = array())
 {
     if (empty($options) && Session::has('aes_key') && Session::has('aes_iv')) {
         $options = array('key' => Session::get('aes_key'), 'iv' => Session::get('aes_iv'));
     }
     if (!(isset($options['key']) && isset($options['iv']))) {
         \Log::error("Either key or iv not set");
         throw new \Exception("Either key or iv not set");
     }
     Session::put('aes_key', $options['key']);
     Session::put('aes_iv', $options['iv']);
     $aes = new \Crypt_AES(CRYPT_AES_MODE_CBC);
     $aes->setKeyLength(256);
     $aes->setKey(Base64::UrlDecode($options['key']));
     $aes->setIV(Base64::UrlDecode($options['iv']));
     $aes->enablePadding();
     $this->aes = $aes;
     $this->isAesInitialized = true;
 }
Пример #5
0
}
###
$return = 'boxgamefile.php?id=' . urlencode($boxid);
require "../configuration.php";
require "./include.php";
require_once "../includes/func.ssh2.inc.php";
require_once "../libs/phpseclib/Crypt/AES.php";
require_once "../libs/gameinstaller/gameinstaller.php";
$title = T_('Box Game File Repositories');
if (query_numrows("SELECT `name` FROM `" . DBPREFIX . "box` WHERE `boxid` = '" . $boxid . "'") == 0) {
    exit('Error: BoxID is invalid.');
}
$rows = query_fetch_assoc("SELECT * FROM `" . DBPREFIX . "box` WHERE `boxid` = '" . $boxid . "' LIMIT 1");
$games = mysql_query("SELECT * FROM `" . DBPREFIX . "game` ORDER BY `game`");
$aes = new Crypt_AES();
$aes->setKeyLength(256);
$aes->setKey(CRYPT_KEY);
// Get SSH2 Object OR ERROR String
$ssh = newNetSSH2($rows['ip'], $rows['sshport'], $rows['login'], $aes->decrypt($rows['password']));
if (!is_object($ssh)) {
    $_SESSION['msg1'] = T_('Connection Error!');
    $_SESSION['msg2'] = $ssh;
    $_SESSION['msg-type'] = 'error';
}
$gameInstaller = new GameInstaller($ssh);
include "./bootstrap/header.php";
/**
 * Notifications
 */
include "./bootstrap/notifications.php";
?>
 function getPassword($pwd = null, $iv_field = "iv")
 {
     if (is_null($pwd)) {
         $pwd = $this->password;
         if (!$this->password) {
             return "";
         }
     }
     try {
         $master_key_filepath = CAppUI::conf("master_key_filepath");
         $master_key_filepath = rtrim($master_key_filepath, "/");
         if (CExchangeSource::checkMasterKeyFile($master_key_filepath)) {
             CAppUI::requireLibraryFile("phpseclib/phpseclib/Crypt/AES");
             CAppUI::requireLibraryFile("phpseclib/phpseclib/Crypt/Random");
             $cipher = new Crypt_AES(CRYPT_AES_MODE_CTR);
             $cipher->setKeyLength(256);
             $keyAB = file($master_key_filepath . "/.mediboard.key");
             if (count($keyAB) == 2) {
                 $cipher->setKey($keyAB[0] . $keyAB[1]);
                 $ivToUse = $this->{$iv_field};
                 if (!$ivToUse) {
                     $clear = $pwd;
                     $this->store();
                     return $clear;
                 }
                 $cipher->setIV($ivToUse);
                 $decrypted = rtrim(base64_decode($pwd), "");
                 $decrypted = $cipher->decrypt($decrypted);
                 if ($decrypted) {
                     return $decrypted;
                 }
             }
         }
     } catch (Exception $e) {
         return $pwd;
     }
     return $pwd;
 }
Пример #7
0
 /**
  * Decrypt Session Credentials
  *
  * @param none
  * @return array
  * @access private
  */
 private function decryptSessionCredentials()
 {
     if (!empty($this->session) && array_key_exists('CREDENTIALS', $this->session)) {
         switch (CONF_SEC_SESSION_METHOD) {
             case 'aes256':
             default:
                 $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
                 $cipher->setKeyLength(256);
                 $cipher->setKey($this->session_key);
                 $credentials = unserialize($cipher->decrypt($this->session['CREDENTIALS']));
                 break;
         }
         return $credentials;
     }
     return array();
 }
Пример #8
0
 public static function getCipher($algo)
 {
     $cipher = null;
     switch ($algo) {
         case 2:
             if (class_exists('Crypt_TripleDES')) {
                 $cipher = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
                 $key_bytes = 24;
                 $key_block_bytes = 8;
             }
             break;
         case 3:
             if (defined('MCRYPT_CAST_128')) {
                 $cipher = new MCryptWrapper(MCRYPT_CAST_128);
             }
             break;
         case 7:
             if (class_exists('Crypt_AES')) {
                 $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
                 $cipher->setKeyLength(128);
             }
             break;
         case 8:
             if (class_exists('Crypt_AES')) {
                 $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
                 $cipher->setKeyLength(192);
             }
             break;
         case 9:
             if (class_exists('Crypt_AES')) {
                 $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
                 $cipher->setKeyLength(256);
             }
             break;
     }
     if (!$cipher) {
         return array(null, null, null);
         // Unsupported cipher
     }
     if (!isset($key_bytes)) {
         $key_bytes = $cipher->key_size;
     }
     if (!isset($key_block_bytes)) {
         $key_block_bytes = $cipher->block_size;
     }
     return array($cipher, $key_bytes, $key_block_bytes);
 }
Пример #9
0
 /**
  * Validate the signature and date of the message, then
  * decrypt it.
  *
  * @param string $secret
  * @param string $body
  * @param string $signature
  * @return string
  *   Plain text.
  * @throws InvalidMessageException
  */
 public static function authenticateThenDecrypt($secret, $body, $signature)
 {
     $keys = self::deriveAesKeys($secret);
     $localHmac = hash_hmac('sha256', $body, $keys['auth']);
     if (!self::hash_compare($signature, $localHmac)) {
         throw new InvalidMessageException("Incorrect hash");
     }
     list($jsonEnvelope, $jsonEncrypted) = explode(Constants::PROTOCOL_DELIM, $body, 2);
     if (strlen($jsonEnvelope) > Constants::MAX_ENVELOPE_BYTES) {
         throw new InvalidMessageException("Oversized envelope");
     }
     $envelope = json_decode($jsonEnvelope, TRUE);
     if (!$envelope) {
         throw new InvalidMessageException("Malformed envelope");
     }
     if (!is_numeric($envelope['ttl']) || Time::getTime() > $envelope['ttl']) {
         throw new InvalidMessageException("Invalid TTL");
     }
     if (!is_string($envelope['iv']) || strlen($envelope['iv']) !== Constants::AES_BYTES * 2 || !preg_match('/^[a-f0-9]+$/', $envelope['iv'])) {
         // AES_BYTES (32) ==> bin2hex ==> 2 hex digits (4-bit) per byte (8-bit)
         throw new InvalidMessageException("Malformed initialization vector");
     }
     $jsonPlaintext = UserError::adapt('Civi\\Cxn\\Rpc\\Exception\\InvalidMessageException', function () use($jsonEncrypted, $envelope, $keys) {
         $cipher = new \Crypt_AES(CRYPT_AES_MODE_CBC);
         $cipher->setKeyLength(Constants::AES_BYTES);
         $cipher->setKey($keys['enc']);
         $cipher->setIV(BinHex::hex2bin($envelope['iv']));
         return $cipher->decrypt($jsonEncrypted);
     });
     return $jsonPlaintext;
 }
Пример #10
0
function SendEncryptedResponse($message)
{
    $aes = new Crypt_AES(CRYPT_AES_MODE_CBC);
    $aes->setKeyLength(256);
    $aes->setKey(Base64UrlDecode($_SESSION['key']));
    $aes->setIV(Base64UrlDecode($_SESSION['iv']));
    $aes->enablePadding();
    // This is PKCS
    echo Base64UrlEncode($aes->encrypt($message));
    exit;
}
Пример #11
0
 /**
  * Add a New Box To The Collection
  *
  * @http_method POST
  * @resource box/
  *
  * @param string $name query
  * @param string $os query
  * @param string $ip query
  * @param string $port query
  * @param string $login query
  * @param string $password query
  * @param optional string $userPath
  * @param optional string $steamPath
  * @param optional string $notes
  *
  * @return application/json
  *
  * @author Nikita Rousseau
  */
 function postBox($name, $os, $ip, $port, $login, $password, $userPath = '', $steamPath = '', $notes = '')
 {
     $args = array('name' => $name, 'os' => $os, 'ip' => $ip, 'port' => $port, 'login' => $login, 'password' => $password, 'userPath' => $userPath, 'steamPath' => $steamPath, 'notes' => $notes);
     $errors = array();
     // array to hold validation errors
     $data = array();
     // array to pass back data
     $dbh = Core_DBH::getDBH();
     // Get Database Handle
     // validate the variables ======================================================
     $v = new Valitron\Validator($args);
     $rules = ['required' => [['name'], ['os'], ['ip'], ['port'], ['login'], ['password']], 'regex' => [['name', "/^([-a-z0-9_ -])+\$/i"]], 'integer' => [['os'], ['port']], 'ip' => [['ip']], 'alphaNum' => [['login']]];
     $labels = array('name' => T_('Remote Machine Name'), 'os' => T_('Operating System'), 'ip' => T_('IP Address'), 'port' => T_('Port'), 'login' => T_('Login'), 'password' => T_('Password'));
     $v->rules($rules);
     $v->labels($labels);
     $v->validate();
     $errors = $v->errors();
     // validate the variables phase 2 ==============================================
     if (empty($errors)) {
         // Verify OS ID
         try {
             $sth = $dbh->prepare("\n\t\t\t\t\tSELECT operating_system\n\t\t\t\t\tFROM " . DB_PREFIX . "os\n\t\t\t\t\tWHERE\n\t\t\t\t\t\tos_id = :os_id\n\t\t\t\t\t;");
             $sth->bindParam(':os_id', $args['os']);
             $sth->execute();
             $result = $sth->fetchAll(PDO::FETCH_ASSOC);
         } catch (PDOException $e) {
             echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
             die;
         }
         if (empty($result[0])) {
             $errors['os'] = 'Bad Identifier';
         }
         // Verify Communication
         $socket = @fsockopen($args['ip'], $args['port'], $errno, $errstr, 3);
         if ($socket === FALSE) {
             $errors['com'] = "Unable to connect to " . $args['ip'] . " on port " . $args['port'] . ". " . utf8_encode($errstr) . " ( {$errno} )";
             unset($socket);
         } else {
             unset($socket);
             $ssh = new Net_SSH2($args['ip'], $args['port']);
             if (!$ssh->login($args['login'], $args['password'])) {
                 $errors['com'] = 'Login failed';
             } else {
                 // Verify Remote Paths
                 if (!empty($args['userPath'])) {
                     if (boolval(trim($ssh->exec('test -d ' . escapeshellcmd($args['userPath']) . " && echo '1' || echo '0'"))) === FALSE) {
                         $errors['remoteUserHome'] = 'Invalid path. Must be an absolute or full path';
                     }
                 }
                 if (!empty($args['steamPath'])) {
                     if (boolval(trim($ssh->exec('test -f ' . escapeshellcmd($args['steamPath']) . " && echo '1' || echo '0'"))) === FALSE) {
                         $errors['steamcmd'] = 'SteamCMD not found. Must be an absolute or full path';
                     }
                 }
             }
             $ssh->disconnect();
         }
     }
     // Apply =======================================================================
     if (empty($errors)) {
         //
         // Database update
         //
         // Vars Init
         if (empty($args['userPath'])) {
             $home = "~";
             $args['userPath'] = $home;
         } else {
             $home = escapeshellcmd(normalizePath($args['userPath']));
             $args['userPath'] = $home;
         }
         $config = parse_ini_file(CONF_SECRET_INI);
         // BOX
         try {
             $sth = $dbh->prepare("\n\t\t\t\t\tINSERT INTO " . DB_PREFIX . "box\n\t\t\t\t\tSET\n\t\t\t\t\t\tos_id \t\t\t= :os,\n\t\t\t\t\t\tname \t\t\t= :name,\n\t\t\t\t\t\tsteam_lib_path \t= :steamcmd,\n\t\t\t\t\t\tnotes \t\t\t= :notes\n\t\t\t\t\t;");
             $sth->bindParam(':os', $args['os']);
             $sth->bindParam(':name', $args['name']);
             $sth->bindParam(':steamcmd', $args['steamPath']);
             $sth->bindParam(':notes', $args['notes']);
             $sth->execute();
             $box_id = $dbh->lastInsertId();
         } catch (PDOException $e) {
             echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
             die;
         }
         // IP
         try {
             $sth = $dbh->prepare("\n\t\t\t\t\tINSERT INTO " . DB_PREFIX . "box_ip\n\t\t\t\t\tSET\n\t\t\t\t\t\tbox_id = :box_id,\n\t\t\t\t\t\tip = :ip,\n\t\t\t\t\t\tis_default = 1\n\t\t\t\t\t;");
             $sth->bindParam(':box_id', $box_id);
             $sth->bindParam(':ip', $args['ip']);
             $sth->execute();
         } catch (PDOException $e) {
             echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
             die;
         }
         // CREDENTIALS
         // Phase 1
         // Connect to the remote host
         // Try to append our public key to authorized_keys
         $ssh = new Net_SSH2($args['ip'], $args['port']);
         $ssh->login($args['login'], $args['password']);
         $remote_keys = $ssh->exec('cat ' . $home . '/.ssh/authorized_keys');
         // Check if the public key already exists
         if (strpos($remote_keys, file_get_contents(RSA_PUBLIC_KEY_FILE)) === FALSE) {
             // Otherwise, append it
             $ssh->exec("echo '" . file_get_contents(RSA_PUBLIC_KEY_FILE) . "' >> " . $home . "/.ssh/authorized_keys");
         }
         // Phase 2
         // Verify that the public key is allowed on the remote host
         $isUsingSSHPubKey = TRUE;
         // By default, we use the SSH authentication keys method
         $remote_keys = $ssh->exec('cat ' . $home . '/.ssh/authorized_keys');
         $ssh->disconnect();
         if (strpos($remote_keys, file_get_contents(RSA_PUBLIC_KEY_FILE)) === FALSE) {
             // authorized_keys is not writable
             // Use compatibility mode
             // Store the password in DB
             $isUsingSSHPubKey = FALSE;
         } else {
             // Phase 3
             // Try to connect with our private key on the remote host
             $ssh = new Net_SSH2($args['ip'], $args['port']);
             $key = new Crypt_RSA();
             $key->loadKey(file_get_contents(RSA_PRIVATE_KEY_FILE));
             if (!$ssh->login($args['login'], $key)) {
                 // Authentication failed
                 // Use compatibility mode
                 // Store the password in DB
                 $isUsingSSHPubKey = FALSE;
             }
             $ssh->disconnect();
         }
         // SSH CREDENTIALS
         $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
         $cipher->setKeyLength(256);
         $cipher->setKey($config['APP_SSH_KEY']);
         if ($isUsingSSHPubKey) {
             try {
                 $sth = $dbh->prepare("\n\t\t\t\t\t\tINSERT INTO " . DB_PREFIX . "box_credential\n\t\t\t\t\t\tSET\n\t\t\t\t\t\t\tlogin = :login,\n\t\t\t\t\t\t\tremote_user_home = :home,\n\t\t\t\t\t\t\tcom_protocol = 'ssh2',\n\t\t\t\t\t\t\tcom_port = :com_port\n\t\t\t\t\t\t;");
                 $login = $cipher->encrypt($args['login']);
                 $sth->bindParam(':login', $login);
                 $sth->bindParam(':home', $args['userPath']);
                 $sth->bindParam(':com_port', $args['port']);
                 $sth->execute();
                 $credential_id = $dbh->lastInsertId();
             } catch (PDOException $e) {
                 echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
                 die;
             }
         } else {
             try {
                 $sth = $dbh->prepare("\n\t\t\t\t\t\tINSERT INTO " . DB_PREFIX . "box_credential\n\t\t\t\t\t\tSET\n\t\t\t\t\t\t\tlogin = :login,\n\t\t\t\t\t\t\tpassword = :password,\n\t\t\t\t\t\t\tremote_user_home = :home,\n\t\t\t\t\t\t\tcom_protocol = 'ssh2',\n\t\t\t\t\t\t\tcom_port = :port\n\t\t\t\t\t\t;");
                 $login = $cipher->encrypt($args['login']);
                 $password = $cipher->encrypt($args['password']);
                 $sth->bindParam(':login', $login);
                 $sth->bindParam(':password', $password);
                 $sth->bindParam(':home', $args['userPath']);
                 $sth->bindParam(':com_port', $args['port']);
                 $sth->execute();
                 $credential_id = $dbh->lastInsertId();
             } catch (PDOException $e) {
                 echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
                 die;
             }
         }
         // UPDATE BOX
         try {
             $sth = $dbh->prepare("\n\t\t\t\t\tUPDATE " . DB_PREFIX . "box\n\t\t\t\t\tSET\n\t\t\t\t\t\tbox_credential_id = :box_credential_id\n\t\t\t\t\tWHERE box_id = :box_id\n\t\t\t\t\t;");
             $sth->bindParam(':box_credential_id', $credential_id);
             $sth->bindParam(':box_id', $box_id);
             $sth->execute();
         } catch (PDOException $e) {
             echo $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine();
             die;
         }
     }
     // return a response and log ===================================================
     $logger = self::getLogger();
     $data['errors'] = $errors;
     if (!empty($data['errors'])) {
         $data['success'] = false;
         $logger->info('Failed to add box.');
     } else {
         $data['success'] = true;
         $logger->info('Box added.');
     }
     return array('response' => 'application/json', 'data' => json_encode($data));
 }
Пример #12
0
 public function onStartMagicEnvelopeToXML(MagicEnvelope $magic_env, XMLStringer $xs, $flavour = null, Profile $target = null)
 {
     // Since Diaspora doesn't use a separate namespace for their "extended"
     // salmon slap, we'll have to resort to this workaround hack.
     if ($flavour !== 'diaspora') {
         return true;
     }
     // WARNING: This changes the $magic_env contents! Be aware of it.
     /**
      * https://wiki.diasporafoundation.org/Federation_protocol_overview
      * http://www.rubydoc.info/github/Raven24/diaspora-federation/master/DiasporaFederation/Salmon/EncryptedSlap
      *
      * Constructing the encryption header
      */
     // For some reason diaspora wants the salmon slap in a <diaspora> header.
     $xs->elementStart('diaspora', array('xmlns' => 'https://joindiaspora.com/protocol'));
     /**
      * Choose an AES key and initialization vector, suitable for the
      * aes-256-cbc cipher. I shall refer to this as the “inner key”
      * and the “inner initialization vector (iv)”.
      */
     $inner_key = new Crypt_AES(CRYPT_AES_MODE_CBC);
     $inner_key->setKeyLength(256);
     // set length to 256 bits (could be calculated, but let's be sure)
     $inner_key->setKey(common_random_rawstr(32));
     // 32 bytes from a (pseudo) random source
     $inner_key->setIV(common_random_rawstr(16));
     // 16 bytes is the block length
     /**
      * Construct the following XML snippet:
      *  <decrypted_header>
      *      <iv>((base64-encoded inner iv))</iv>
      *      <aes_key>((base64-encoded inner key))</aes_key>
      *      <author>
      *          <name>Alice Exampleman</name>
      *          <uri>acct:user@sender.example</uri>
      *      </author>
      *  </decrypted_header>
      */
     $decrypted_header = sprintf('<decrypted_header><iv>%1$s</iv><aes_key>%2$s</aes_key><author_id>%3$s</author_id></decrypted_header>', base64_encode($inner_key->iv), base64_encode($inner_key->key), $magic_env->getActor()->getAcctUri());
     /**
      * Construct another AES key and initialization vector suitable
      * for the aes-256-cbc cipher. I shall refer to this as the
      * “outer key” and the “outer initialization vector (iv)”.
      */
     $outer_key = new Crypt_AES(CRYPT_AES_MODE_CBC);
     $outer_key->setKeyLength(256);
     // set length to 256 bits (could be calculated, but let's be sure)
     $outer_key->setKey(common_random_rawstr(32));
     // 32 bytes from a (pseudo) random source
     $outer_key->setIV(common_random_rawstr(16));
     // 16 bytes is the block length
     /**
      * Encrypt your <decrypted_header> XML snippet using the “outer key”
      * and “outer iv” (using the aes-256-cbc cipher). This encrypted
      * blob shall be referred to as “the ciphertext”. 
      */
     $ciphertext = $outer_key->encrypt($decrypted_header);
     /**
      * Construct the following JSON object, which shall be referred to
      * as “the outer aes key bundle”:
      *  {
      *      "iv": ((base64-encoded AES outer iv)),
      *      "key": ((base64-encoded AES outer key))
      *  }
      */
     $outer_bundle = json_encode(array('iv' => base64_encode($outer_key->iv), 'key' => base64_encode($outer_key->key)));
     /**
      * Encrypt the “outer aes key bundle” with Bob’s RSA public key.
      * I shall refer to this as the “encrypted outer aes key bundle”.
      */
     common_debug('Diaspora creating "outer aes key bundle", will require magic-public-key');
     $key_fetcher = new MagicEnvelope();
     $remote_keys = $key_fetcher->getKeyPair($target, true);
     // actually just gets the public key
     $enc_outer = $remote_keys->publicKey->encrypt($outer_bundle);
     /**
      * Construct the following JSON object, which I shall refer to as
      * the “encrypted header json object”:
      *  {
      *      "aes_key": ((base64-encoded encrypted outer aes key bundle)),
      *      "ciphertext": ((base64-encoded ciphertextm from above))
      *  }
      */
     $enc_header = json_encode(array('aes_key' => base64_encode($enc_outer), 'ciphertext' => base64_encode($ciphertext)));
     /**
      * Construct the xml snippet:
      *  <encrypted_header>((base64-encoded encrypted header json object))</encrypted_header>
      */
     $xs->element('encrypted_header', null, base64_encode($enc_header));
     /**
      * In order to prepare the payload message for inclusion in your
      * salmon slap, you will:
      *
      * 1. Encrypt the payload message using the aes-256-cbc cipher and
      *      the “inner encryption key” and “inner encryption iv” you
      *      chose earlier.
      * 2. Base64-encode the encrypted payload message.
      */
     $payload = $inner_key->encrypt($magic_env->getData());
     //FIXME: This means we don't actually put an <atom:entry> in the payload,
     // since Diaspora has its own update method! Silly me. Read up on:
     // https://wiki.diasporafoundation.org/Federation_Message_Semantics
     $magic_env->signMessage(base64_encode($payload), 'application/xml');
     // Since we have to change the content of me:data we'll just write the
     // whole thing from scratch. We _could_ otherwise have just manipulated
     // that element and added the encrypted_header in the EndMagicEnvelopeToXML event.
     $xs->elementStart('me:env', array('xmlns:me' => MagicEnvelope::NS));
     $xs->element('me:data', array('type' => $magic_env->getDataType()), $magic_env->getData());
     $xs->element('me:encoding', null, $magic_env->getEncoding());
     $xs->element('me:alg', null, $magic_env->getSignatureAlgorithm());
     $xs->element('me:sig', null, $magic_env->getSignature());
     $xs->elementEnd('me:env');
     $xs->elementEnd('entry');
     return false;
 }
Пример #13
0
 public static function getCipher($algo)
 {
     $cipher = NULL;
     switch ($algo) {
         case 2:
             if (class_exists('Crypt_TripleDES')) {
                 $cipher = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
                 $key_bytes = 24;
                 $key_block_bytes = 8;
             }
             break;
         case 3:
             if (defined('MCRYPT_CAST_128')) {
                 $cipher = new MCryptWrapper(MCRYPT_CAST_128);
             } else {
                 $cipher = new Horde_Pgp_Crypt_Cast128();
             }
             /* End Horde Change */
             break;
             /* Horde change */
         /* Horde change */
         case 4:
             $cipher = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CFB);
             $key_bytes = 16;
             break;
             /* End Horde Change */
         /* End Horde Change */
         case 7:
             if (class_exists('Crypt_AES')) {
                 $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
                 $cipher->setKeyLength(128);
             }
             break;
         case 8:
             if (class_exists('Crypt_AES')) {
                 $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
                 $cipher->setKeyLength(192);
             }
             break;
         case 9:
             if (class_exists('Crypt_AES')) {
                 $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
                 $cipher->setKeyLength(256);
             }
             break;
             /* Horde change */
         /* Horde change */
         case 10:
             $cipher = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CFB);
             $key_bytes = 32;
             break;
             /* End Horde Change */
     }
     if (!$cipher) {
         return array(NULL, NULL, NULL);
     }
     // Unsupported cipher
     if (!isset($key_bytes)) {
         $key_bytes = $cipher->key_size;
     }
     if (!isset($key_block_bytes)) {
         $key_block_bytes = $cipher->block_size;
     }
     return array($cipher, $key_bytes, $key_block_bytes);
 }
Пример #14
0
 /**
  */
 public function generateKey($opts)
 {
     $skey = $this->_generateSecretKeyPacket($opts['keylength'], 'OpenPGP_SecretKeyPacket');
     $id = new Horde_Mail_Rfc822_Address($opts['email']);
     if (strlen($opts['comment'])) {
         $id->comment[] = $opts['comment'];
     }
     if (strlen($opts['name'])) {
         $id->personal = $opts['name'];
     }
     /* This is the private key we are creating. */
     $key = new OpenPGP_Message(array($skey, new OpenPGP_UserIDPacket($id->writeAddress(array('comment' => true)))));
     $rsa = OpenPGP_Crypt_RSA::convert_private_key($skey);
     $rsa->setHash(Horde_String::lower($opts['hash']));
     $rsa_sign_func = array('RSA' => array($opts['hash'] => function ($data) use($rsa) {
         return array($rsa->sign($data));
     }));
     /* Create signature packet. */
     $sig = new OpenPGP_SignaturePacket($key, 'RSA', $opts['hash']);
     /* "Generic certification of a User ID and Public-Key packet." */
     $sig->signature_type = 0x10;
     /* Add subpacket information. */
     $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyFlagsPacket(array(0x3));
     $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_PreferredSymmetricAlgorithmsPacket(array(0x9, 0x8, 0x7, 0x2));
     $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_PreferredHashAlgorithmsPacket(array(0x8, 0x9, 0xa, 0xb, 0x2));
     $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_PreferredCompressionAlgorithmsPacket(array(0x2, 0x1));
     $ks_prefs = new OpenPGP_SignaturePacket_KeyServerPreferencesPacket();
     $ks_prefs->no_modify = true;
     $sig->hashed_subpackets[] = $ks_prefs;
     $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_FeaturesPacket(array(0x1));
     if (isset($opts['expire'])) {
         $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyExpirationTimePacket($opts['expire'] - time());
     }
     $sig->unhashed_subpackets[] = new OpenPGP_SignaturePacket_IssuerPacket(substr($skey->fingerprint, -16));
     $key[] = $sig;
     /* Create self-signature. */
     $sig->sign_data($rsa_sign_func);
     /* OpenPGP currently (as of April 2015) encrypts passphrases w/
      * AES-128 & SHA-1, so use this strategy. */
     if (strlen($opts['passphrase'])) {
         $cipher = new Crypt_AES(CRYPT_AES_MODE_CFB);
         $cipher->setKeyLength(128);
         $s2k = new OpenPGP_S2K(crypt_random_string(8), 2);
         $cipher->setKey($s2k->make_key($opts['passphrase'], 16));
         $iv = crypt_random_string(16);
         $this->_encryptPrivateKey($skey, $cipher, $s2k, $iv);
     }
     /* Encryption subkey. See RFC 4880 [5.5.1.2] (by convention, top-level
      * key is used for signing and subkeys are used for encryption) */
     $ekey = $this->_generateSecretKeyPacket($opts['keylength'], 'OpenPGP_SecretSubkeyPacket');
     /* Computing signature: RFC 4880 [5.2.4] */
     $sig = new OpenPGP_SignaturePacket(implode('', $skey->fingerprint_material()) . implode('', $ekey->fingerprint_material()), 'RSA', $opts['hash']);
     /* This is a "Subkey Binding Signature". */
     $sig->signature_type = 0x18;
     $sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyFlagsPacket(array(0xc));
     $sig->unhashed_subpackets[] = new OpenPGP_SignaturePacket_IssuerPacket(substr($skey->fingerprint, -16));
     $sig->sign_data($rsa_sign_func);
     if (strlen($opts['passphrase'])) {
         $this->_encryptPrivateKey($ekey, $cipher, $s2k, $iv);
     }
     $key[] = $ekey;
     $key[] = $sig;
     return new Horde_Pgp_Element_PrivateKey($key);
 }