/** * Get an array of keys to install automatically with this repo. * * @return array */ public function getKeys(){ if($this->_keys !== null){ // Cache! return $this->_keys; } $gpg = new \Core\GPG\GPG(); $this->_keys = []; foreach($this->getElements('keys/key') as $k){ $id = $k->getAttribute('id'); $key = null; $local = true; // Try to find more info about this key! // First step is to assign the key from local data. // If that fails, gracefully search remote servers for it. if(($key = $gpg->getKey($id)) === null){ $remoteKeys = $gpg->searchRemoteKeys($id); foreach($remoteKeys as $k){ /** @var \Core\GPG\PublicKey $k */ if($k->id == $id || $k->id_short == $id){ $key = $k; $local = false; break; } } } if($key !== null){ $dat = [ 'key' => $id, 'available' => true, 'installed' => $local, 'fingerprint' => \Core\GPG\GPG::FormatFingerprint($key->fingerprint, false, true), 'uids' => [], ]; foreach($key->uids as $uid){ /** @var \Core\GPG\UID $uid */ if($uid->isValid()){ $dat['uids'][] = ['name' => $uid->fullname, 'email' => $uid->email]; } } } else{ $dat = [ 'key' => $id, 'available' => false, 'installed' => false, 'fingerprint' => '', 'uids' => [], ]; } $this->_keys[] = $dat; } return $this->_keys; }
/** * Validate the verification email, part 2 of confirmation. * * @param string $nonce * @param string $signature * * @return bool|string */ public static function ValidateVerificationResponse($nonce, $signature) { /** @var \NonceModel $nonce */ $nonce = \NonceModel::Construct($nonce); if(!$nonce->isValid()){ \SystemLogModel::LogSecurityEvent('/user/gpg/verified', 'FAILED to verify key (Invalid NONCE)', null); return 'Invalid nonce provided!'; } // Now is where the real fun begins. $nonce->decryptData(); $data = $nonce->get('data'); /** @var \UserModel $user */ $user = \UserModel::Construct($data['user']); $gpg = new \Core\GPG\GPG(); $key = $data['key']; $pubKey = $gpg->getKey($key); try{ $sig = $gpg->verifyDataSignature($signature, $data['sentence']); } catch(\Exception $e){ \SystemLogModel::LogSecurityEvent('/user/gpg/verified', 'FAILED to verify key ' . $key, null, $user->get('id')); return 'Invalid signature'; } $fpr = str_replace(' ', '', $sig->fingerprint); // Trim spaces. if($key != $fpr && $key != $sig->keyID){ // They must match! \SystemLogModel::LogSecurityEvent('/user/gpg/verified', 'FAILED to verify key ' . $key, null, $user->get('id')); return 'Invalid signature'; } // Otherwise? $user->enableAuthDriver('gpg'); $user->set('gpgauth_pubkey', $fpr); // Was there a photo attached to this public key? if(sizeof($pubKey->getPhotos()) > 0){ $p = $pubKey->getPhotos(); // I just want the first. /** @var \Core\Filestore\File $p */ $p = $p[0]; $localFile = \Core\Filestore\Factory::File('public/user/avatar/' . $pubKey->fingerprint . '.' . $p->getExtension()); $p->copyTo($localFile); $user->set('avatar', $localFile->getFilename(false)); } $user->save(); $nonce->markUsed(); \SystemLogModel::LogSecurityEvent('/user/gpg/verified', 'Verified key ' . $fpr, null, $user->get('id')); return true; }