public function isAuthenticated($request) { $currentTime = time(); if (isset($request[$this->cookieName])) { $connection = $request[$this->cookieName]['CON']; $timestamp = $request[$this->cookieName]['TM']; if ($connection && $timestamp) { if ($currentTime - $timestamp < $this->cookieExpireTime) { $temp = Crypto::decrypt($connection, _Key_New); list($username) = explode("|Z|1|Z|", $temp); if ($username) { $connection = Crypto::encrypt(implode("|Z|1|Z|", array($username, time())), _Key_New); $this->setAuthenticated($connection); return true; } } else { // Timed-out return false; } } else { // Not Authenticated return false; } } }
/** * Check if a user is logged in */ public static function isLoggedIn() { if (empty($_COOKIE['s'])) { return false; } else { $str = Crypto::decrypt($_COOKIE['s'], $_SERVER['ENCRYPTION_KEY']); $fields = explode(':', $str); return $fields[1]; // return the userid } }
function testSimple() { $tests = array_merge(array($this->test_data), $this->passwords); foreach ($tests as $subject) { $enc = Crypto::encrypt($subject, $this->master, 'simple'); $dec = Crypto::decrypt($enc, $this->master, 'simple'); $this->assertEqual($dec, $subject, "{$subject}: Encryption failed closed loop"); $this->assertNotEqual($enc, $subject, 'Data was not encrypted'); $this->assertNotEqual($enc, false, 'Encryption failed'); $this->assertNotEqual($dec, false, 'Decryption failed'); $dec = Crypto::decrypt($enc, $this->master, 'wrong'); $this->assertNotEqual($dec, $this->test_data, 'Subkeys are broken'); } }
/** * Decrypt then verify a password * * @param string $password - The user-provided password * @param string $stored - The encrypted password hash * @param EncryptionKey $secret_key - The master key for all passwords * @return boolean */ public static function verify(string $password, string $stored, EncryptionKey $secret_key) : bool { // First let's decrypt the hash $hash_str = Crypto::decrypt($stored, $secret_key); // Upon successful decryption, verify the password is correct $isArgon2 = \hash_equals(CryptoUtil::safeSubstr($hash_str, 0, 9), \Sodium\CRYPTO_PWHASH_STRPREFIX); $isScrypt = \hash_equals(CryptoUtil::safeSubstr($hash_str, 0, 3), \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX); if ($isArgon2) { return \Sodium\crypto_pwhash_str_verify($hash_str, $password); } elseif ($isScrypt) { return \Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify($hash_str, $password); } return false; }
/** * Store a value in an encrypted cookie * * @param string $name * @return mixed (typically an array) */ public function fetch(string $name) { if (!isset($_COOKIE[$name])) { return null; } try { $decrypted = Crypto::decrypt($_COOKIE[$name], $this->key); if (empty($decrypted)) { return null; } return \json_decode($decrypted, true); } catch (InvalidMessage $e) { return null; } }
public function KeyGet($master, $password, $key) { if ($this->MasterExists($master)) { require_once APP_DIR . "/src/Inc/Crypto.php"; $items = getData("master_" . $master . "_items"); $pass_salt = getData("master_" . $master . "_password_salt"); $encrypt_key = $this->master_salt . $password . $pass_salt; Crypto::$KEY_BYTE_SIZE = mb_strlen($encrypt_key, '8bit'); $items = base64_decode(Crypto::decrypt(base64_decode($items), $encrypt_key)); $items = str_replace(""", "'", $items); $items = $items == null ? array() : json_decode($items, true); return isset($items[$key]) ? $items[$key] : null; } else { return false; } }
/** * Store a value in an encrypted cookie * * @param string $name * @return mixed (typically an array) */ public function fetch(string $name) { if (!isset($_COOKIE[$name])) { return null; } try { $stored = $_COOKIE[$name]; $config = self::getConfig($stored); $decrypted = Crypto::decrypt($stored, $this->key, $config->ENCODING); if (empty($decrypted)) { return null; } return \json_decode($decrypted->getString(), true); } catch (InvalidMessage $e) { return null; } }
function search($query) { $c = $this->getConnection(); // TODO: Include bind information $users = array(); if ($dn = $this->getConfig()->get('bind_dn')) { $pw = Crypto::decrypt($this->getConfig()->get('bind_pw'), SECRET_SALT, $this->getConfig()->getNamespace()); $r = $c->bind($dn, $pw); unset($pw); if (PEAR::isError($r)) { return $users; } } $schema = static::$schemas[$this->getSchema($c)]; $schema = $schema['user']; $r = $c->search($this->getSearchBase(), str_replace('{q}', $query, $schema['search']), array('attributes' => array_filter(flatten(array($schema['first'], $schema['last'], $schema['full'], $schema['phone'], $schema['mobile'], $schema['email'], $schema['username']))))); // XXX: Log or return some kind of error? if (PEAR::isError($r)) { return $users; } foreach ($r as $e) { // Detect first and last name if only full name is given if (!($first = $e->getValue($schema['first'])) || !($last = $e->getValue($schema['last']))) { $name = new PersonsName($this->_getValue($e, $schema['full'])); $first = $name->getFirst(); $last = $name->getLast(); } $users[] = array('username' => $this->_getValue($e, $schema['username']), 'first' => $first, 'last' => $last, 'email' => $this->_getValue($e, $schema['email']), 'phone' => $this->_getValue($e, $schema['phone']), 'mobile' => $this->_getValue($e, $schema['mobile']), 'backend' => static::$id); } return $users; }
function to_php($value) { return Crypto::decrypt($value, SECRET_SALT, $this->getFormName()); }
function to_php($value) { return Crypto::decrypt($value, SECRET_SALT, 'pwfield'); }
function pre_save(&$config, &$errors) { require_once 'include/Net/LDAP2.php'; global $ost; if ($ost && !extension_loaded('ldap')) { $ost->setWarning('LDAP extension is not available'); return; } if ($config['domain'] && !$config['servers']) { if (!($servers = LDAPAuthentication::autodiscover($config['domain'], preg_split('/,?\\s+/', $config['dns'])))) { $this->getForm()->getField('servers')->addError("Unable to find LDAP servers for this domain. Try giving\n an address of one of the DNS servers or manually specify\n the LDAP servers for this domain below."); } } else { if (!$config['servers']) { $this->getForm()->getField('servers')->addError("No servers specified. Either specify a Active Directory\n domain or a list of servers"); } else { $servers = array(); foreach (preg_split('/\\s+/', $config['servers']) as $host) { $servers[] = array('host' => $host); } } } $connection_error = false; foreach ($servers as $info) { // Assume MSAD $info['options']['LDAP_OPT_REFERRALS'] = 0; if ($config['tls']) { $info['starttls'] = true; // Don't require a certificate here putenv('LDAPTLS_REQCERT=never'); } if ($config['bind_dn']) { $info['binddn'] = $config['bind_dn']; $info['bindpw'] = $config['bind_pw'] ? $config['bind_pw'] : Crypto::decrypt($this->get('bind_pw'), SECRET_SALT, $this->getNamespace()); } // Set reasonable timeouts so we dont exceed max_execution_time $info['options'] = array('LDAP_OPT_TIMELIMIT' => 5, 'LDAP_OPT_NETWORK_TIMEOUT' => 5); $c = new Net_LDAP2($info); $r = $c->bind(); if (PEAR::isError($r)) { $connection_error = $r->getMessage() . ': Unable to bind to ' . $info['host']; } else { $connection_error = false; break; } } if ($connection_error) { $this->getForm()->getField('servers')->addError($connection_error); $errors['err'] = 'Unable to connect any listed LDAP servers'; } if (!$errors && $config['bind_pw']) { $config['bind_pw'] = Crypto::encrypt($config['bind_pw'], SECRET_SALT, $this->getNamespace()); } else { $config['bind_pw'] = $this->get('bind_pw'); } global $msg; if (!$errors) { $msg = 'LDAP configuration updated successfully'; } return !$errors; }
/** * Decrypt then verify a password * * @param HiddenString $password The user's password * @param string $stored The encrypted password hash * @param EncryptionKey $secretKey The master key for all passwords * @return bool Is this password valid? * @throws InvalidMessage */ public static function verify(HiddenString $password, string $stored, EncryptionKey $secretKey) : bool { $config = self::getConfig($stored); // Base64-urlsafe encoded, so 4/3 the size of raw binary if (Util::safeStrlen($stored) < $config->SHORTEST_CIPHERTEXT_LENGTH * 4 / 3) { throw new InvalidMessage('Encrypted password hash is too short.'); } // First let's decrypt the hash $hash_str = Crypto::decrypt($stored, $secretKey, $config->ENCODING); // Upon successful decryption, verify the password is correct return \Sodium\crypto_pwhash_str_verify($hash_str->getString(), $password->getString()); }
function getSMTPInfo() { $info = array('host' => $this->ht['smtp_host'], 'port' => $this->ht['smtp_port'], 'auth' => (bool) $this->ht['smtp_auth'], 'username' => $this->ht['userid'], 'password' => Crypto::decrypt($this->ht['userpass'], SECRET_SALT, $this->ht['userid'])); return $info; }
public function testEncryptWithFileDecryptWithCrypto() { $ciphertext_path = self::$TEMP_DIR . '/ciphertext'; $plaintext_path = self::$TEMP_DIR . '/plaintext'; $key = Key::createNewRandomKey(); $plaintext = 'Plaintext!'; file_put_contents($plaintext_path, $plaintext); File::encryptFile($plaintext_path, $ciphertext_path, $key); $ciphertext = file_get_contents($ciphertext_path); $plaintext_decrypted = Crypto::decrypt($ciphertext, $key, true); $this->assertSame($plaintext, $plaintext_decrypted); }
function dfrn_notify_post(&$a) { logger(__FUNCTION__, LOGGER_TRACE); $dfrn_id = x($_POST, 'dfrn_id') ? notags(trim($_POST['dfrn_id'])) : ''; $dfrn_version = x($_POST, 'dfrn_version') ? (double) $_POST['dfrn_version'] : 2.0; $challenge = x($_POST, 'challenge') ? notags(trim($_POST['challenge'])) : ''; $data = x($_POST, 'data') ? $_POST['data'] : ''; $key = x($_POST, 'key') ? $_POST['key'] : ''; $rino_remote = x($_POST, 'rino') ? intval($_POST['rino']) : 0; $dissolve = x($_POST, 'dissolve') ? intval($_POST['dissolve']) : 0; $perm = x($_POST, 'perm') ? notags(trim($_POST['perm'])) : 'r'; $ssl_policy = x($_POST, 'ssl_policy') ? notags(trim($_POST['ssl_policy'])) : 'none'; $page = x($_POST, 'page') ? intval($_POST['page']) : 0; $forum = $page == 1 ? 1 : 0; $prv = $page == 2 ? 1 : 0; $writable = -1; if ($dfrn_version >= 2.21) { $writable = $perm === 'rw' ? 1 : 0; } $direction = -1; if (strpos($dfrn_id, ':') == 1) { $direction = intval(substr($dfrn_id, 0, 1)); $dfrn_id = substr($dfrn_id, 2); } $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge)); if (!count($r)) { logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge); xml_status(3); } $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s'", dbesc($dfrn_id), dbesc($challenge)); // find the local user who owns this relationship. $sql_extra = ''; switch ($direction) { case -1: $sql_extra = sprintf(" AND ( `issued-id` = '%s' OR `dfrn-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id)); break; case 0: $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id)); break; case 1: $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id)); break; default: xml_status(3); break; // NOTREACHED } // be careful - $importer will contain both the contact information for the contact // sending us the post, and also the user information for the person receiving it. // since they are mixed together, it is easy to get them confused. $r = q("SELECT\t`contact`.*, `contact`.`uid` AS `importer_uid`,\n\t\t\t\t\t`contact`.`pubkey` AS `cpubkey`,\n\t\t\t\t\t`contact`.`prvkey` AS `cprvkey`,\n\t\t\t\t\t`contact`.`thumb` AS `thumb`,\n\t\t\t\t\t`contact`.`url` as `url`,\n\t\t\t\t\t`contact`.`name` as `senderName`,\n\t\t\t\t\t`user`.*\n\t\t\tFROM `contact`\n\t\t\tLEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\t\tWHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `user`.`nickname` = '%s' AND `user`.`account_expired` = 0 AND `user`.`account_removed` = 0 {$sql_extra} LIMIT 1", dbesc($a->argv[1])); if (!count($r)) { logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id); xml_status(3); //NOTREACHED } // $importer in this case contains the contact record for the remote contact joined with the user record of our user. $importer = $r[0]; logger("Remote rino version: " . $rino_remote . " for " . $importer["url"], LOGGER_DEBUG); if ($writable != -1 && $writable != $importer['writable'] || $importer['forum'] != $forum || $importer['prv'] != $prv) { q("UPDATE `contact` SET `writable` = %d, forum = %d, prv = %d WHERE `id` = %d", intval($writable == -1 ? $importer['writable'] : $writable), intval($forum), intval($prv), intval($importer['id'])); if ($writable != -1) { $importer['writable'] = $writable; } $importer['forum'] = $page; } // if contact's ssl policy changed, update our links fix_contact_ssl_policy($importer, $ssl_policy); logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']); logger('dfrn_notify: data: ' . $data, LOGGER_DATA); if ($dissolve == 1) { /** * Relationship is dissolved permanently */ require_once 'include/Contact.php'; contact_remove($importer['id']); logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']); xml_status(0); } // If we are setup as a soapbox we aren't accepting input from this person // This behaviour is deactivated since it really doesn't make sense to even disallow comments // The check if someone is a friend or simply a follower is done in a later place so it needn't to be done here //if($importer['page-flags'] == PAGE_SOAPBOX) // xml_status(0); $rino = get_config('system', 'rino_encrypt'); $rino = intval($rino); // use RINO1 if mcrypt isn't installed and RINO2 was selected if ($rino == 2 and !function_exists('mcrypt_create_iv')) { $rino = 1; } logger("Local rino version: " . $rino, LOGGER_DEBUG); if (strlen($key)) { // if local rino is lower than remote rino, abort: should not happen! // but only for $remote_rino > 1, because old code did't send rino version if ($rino_remote_version > 1 && $rino < $rino_remote) { logger("rino version '{$rino_remote}' is lower than supported '{$rino}'"); xml_status(0, "rino version '{$rino_remote}' is lower than supported '{$rino}'"); } $rawkey = hex2bin(trim($key)); logger('rino: md5 raw key: ' . md5($rawkey)); $final_key = ''; if ($dfrn_version >= 2.1) { if ($importer['duplex'] && strlen($importer['cprvkey']) || !strlen($importer['cpubkey'])) { openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']); } else { openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']); } } else { if ($importer['duplex'] && strlen($importer['cpubkey']) || !strlen($importer['cprvkey'])) { openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']); } else { openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']); } } #logger('rino: received key : ' . $final_key); switch ($rino_remote) { case 0: case 1: // we got a key. old code send only the key, without RINO version. // we assume RINO 1 if key and no RINO version $data = aes_decrypt(hex2bin($data), $final_key); break; case 2: try { $data = Crypto::decrypt(hex2bin($data), $final_key); } catch (InvalidCiphertext $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 (Ex\CryptoTestFailed $ex) { logger('Cannot safely perform dencryption'); xml_status(0, 'CryptoTestFailed'); } catch (Ex\CannotPerformOperation $ex) { logger('Cannot safely perform decryption'); xml_status(0, 'Cannot safely perform decryption'); } break; default: logger("rino: invalid sent verision '{$rino_remote}'"); xml_status(0); } logger('rino: decrypted data: ' . $data, LOGGER_DATA); } $ret = local_delivery($importer, $data); xml_status($ret); // NOTREACHED }
/** * Decryption of encoded data for all of the versions * * @dataProvider dataDecrypt */ public function testDecrypt($expected, $encrypted, $key, $cipher = null, $mode = null) { $crypto = new Crypto($key, $cipher, $mode); $decrypted = $crypto->decrypt($encrypted); $this->assertEquals($expected, $decrypted); }