php-hotfix/src/Hotfix/Loader.php

87 lines
2.3 KiB
PHP

<?php
namespace NoccyLabs\Hotfix\Hotfix;
class Loader
{
protected $signedBy;
protected $loaders = [];
public function __construct()
{
$this->addLoader(new Loader\FileLoader());
$this->addLoader(new Loader\HttpLoader());
$this->addLoader(new Loader\GistLoader());
$this->addLoader(new Loader\PastebinLoader());
}
public function addLoader(Loader\LoaderInterface $loader)
{
$this->loaders[] = $loader;
}
public function getLoaders()
{
return $this->loaders;
}
public function load($fix, $insecure=false)
{
foreach ($this->loaders as $loader) {
$hotfix = $loader->load($fix);
if ($hotfix === false) {
continue;
}
$sigHeader = '-----BEGIN PGP SIGNATURE-----';
if (false === strpos($hotfix, $sigHeader)) {
if (!$insecure) {
throw new \Exception("Hotfix is not signed");
}
$body = $hotfix;
$signer = null;
} else {
list ($body, $signature) = explode($sigHeader, $hotfix);
$signature = $sigHeader.$signature;
if (!$insecure) {
$signer = $this->verifySignature($body, $signature);
} else {
$signer = null;
}
}
return new Hotfix($body, $signer);
}
fprintf(STDERR, "Error: Couldn't load '%s'\n", $fix);
}
protected function verifySignature($body, $signature)
{
$gpg = gnupg_init();
$sigInfo = gnupg_verify($gpg, $body, $signature);
if ($sigInfo === false) {
throw new \Exception("Hotfix signature is not valid!");
}
$fingerprint = $sigInfo[0]['fingerprint'];
$keyInfo = gnupg_keyinfo($gpg, $fingerprint);
if (empty($keyInfo)) {
throw new \Exception("Unknown signer (key id {$sigInfo[0]['fingerprint']})");
}
$subKeys = $keyInfo[0]['subkeys'];
$keyId = null;
foreach ($subKeys as $subKey) {
if ($subKey['fingerprint'] == $fingerprint) {
$keyId = $subKey['keyid'];
break;
}
}
return [ $keyInfo[0], $keyId ];
}
}