diff --git a/build/nextcloud.php b/build/nextcloud.php index 9970cd0f5..a87a97cf6 100755 --- a/build/nextcloud.php +++ b/build/nextcloud.php @@ -1,7 +1,7 @@ version}-nextcloud.tar"; diff --git a/build/plugins.php b/build/plugins.php index 9cb4d9c1e..ce1addbad 100755 --- a/build/plugins.php +++ b/build/plugins.php @@ -104,6 +104,14 @@ foreach (glob(ROOT_DIR . '/plugins/*', GLOB_NOSORT | GLOB_ONLYDIR) as $dir) { $tar = new PharData($tar_destination); $tar->buildFromDirectory('./plugins/', '/' . \preg_quote("./plugins/{$name}/", '/') . '((?!\.bak).)*$/'); $tar->compress(Phar::GZ); +/* + $private = \openssl_get_privatekey(\file_get_contents('private.pem')); + $pkey = ''; + \openssl_pkey_export($private, $pkey); + $tar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + $tar->setSignatureAlgorithm(Phar::Phar::PGP, file_get_contents($private_key)); + $signature = $tar->getSignature(); +*/ unlink($tar_destination); rename("{$tar_destination}.gz", $tgz_destination); /* @@ -116,10 +124,18 @@ foreach (glob(ROOT_DIR . '/plugins/*', GLOB_NOSORT | GLOB_ONLYDIR) as $dir) { unlink($phar_destination); rename("{$phar_destination}.gz", $phar_destination); } + */ if (isset($options['sign'])) { - passthru('gpg --local-user 1016E47079145542F8BA133548208BA13290F3EB --armor --detach-sign '.escapeshellarg($tgz_destination), $return_var); + $arg = escapeshellarg($tgz_destination); + passthru('gpg --local-user 1016E47079145542F8BA133548208BA13290F3EB --armor --detach-sign '.$arg, $return_var); $manifest_item['pgp_sig'] = trim(preg_replace('/-----(BEGIN|END) PGP SIGNATURE-----/', '', file_get_contents($tgz_destination.'.asc'))); + + $cert_dir = $_SERVER['HOME'].'/.snappymail/certificates'; + $out = escapeshellarg($tgz_destination . '.sig'); + passthru("openssl dgst -sha256 -sign {$cert_dir}/sign_releases.key -out {$out} {$arg}", $return_var); +// passthru("openssl dgst -sha512 -sign {$cert_dir}/sign_releases.key -out {$out} {$arg}", $return_var); +// $manifest_item['ssl_sig'] = base64_encode(file_get_contents($tgz_destination.'.sig')); } ksort($manifest_item); $manifest[$name] = $manifest_item; diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/repository.php b/snappymail/v/0.0.0/app/libraries/snappymail/repository.php index 07151ad78..d2ac31ecc 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/repository.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/repository.php @@ -7,8 +7,12 @@ abstract class Repository // snappyMailRepo const BASE_URL = 'https://snappymail.eu/repository/v2/'; - const KEY = 'https://snappymail.eu/repository/releases.asc'; - const KEY_FINGERPRINT = '1016 E470 7914 5542 F8BA 1335 4820 8BA1 3290 F3EB'; + const KEY_ARMOR_URL = 'https://snappymail.eu/repository/releases.asc'; +// const KEY_RAW_URL = 'https://snappymail.eu/.well-known/openpgpkey/hu/i4cdqgcarfjdjnba6y4jnf498asg8c6p'; + // Long Key ID is the last 16 bytes of the fingerprint + const KEY_FINGERPRINT = '1016E47079145542F8BA133548208BA13290F3EB'; + + const X509_PUB = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAOtwedIGp7T+3q5Hx+Gf/MoUqU6Ac3AHoI6KWlNaJH2g=\n-----END PUBLIC KEY-----"; private static function get(string $path) : string { @@ -281,36 +285,70 @@ abstract class Repository $sTmp = static::download($aList[$sId]['file']); // https://github.com/the-djmaze/snappymail/security/advisories/GHSA-j9c4-gf64-rph2 + // Verify PGP signature $sTmpSignature = static::download($aList[$sId]['file'] . '.asc'); if (!$sTmpSignature) { - throw new \Exception('PGP signature is missing'); + throw new \Exception('Plugin PGP signature is missing'); } /* if ($aList[$sId]['pgp_sig'] !== \trim(\preg_replace('/-----(BEGIN|END) PGP SIGNATURE-----/', '', $sTmpSignature))) { - throw new \Exception('PGP signature invalid'); + throw new \Exception('Plugin PGP signature invalid'); } */ /* - // TODO: verify signature + // Like: gpg --no-default-keyring --keyring /path/to/pubkey.gpg --verify /path/to/file.txt.gpg $gnupg = PGP\GnuPG::getInstance(''); - $sKey = ''; // static::KEY; - if (!$sKey) { - $sKey = PGP\Keyservers::get('4820 8BA1 3290 F3EB'); + if (!\count($gnupg->keyinfo(static::KEY_FINGERPRINT))) { + $sKey = null; + $file = __DIR__ . '/repository/releases.asc'; + if (\is_readable($file)) { + if ('bfa5df5ab2e782940f6b2eede9e62b5b7a44415b' !== \sha1_file($file)) { + throw new \Exception('Repository invalid public key'); + } + $sKey = \file_get_contents($file); + } if (!$sKey) { - $aKeys = PGP\Keyservers::index('releases@snappymail.eu'); - if ($aKeys) { - $sKey = PGP\Keyservers::get($aKeys[0]['keyid']); + $sKey = PGP\Keyservers::get(static::KEY_FINGERPRINT); + if (!$sKey) { + $aKeys = PGP\Keyservers::index('releases@snappymail.eu'); + if ($aKeys) { + $sKey = PGP\Keyservers::get($aKeys[0]['keyid']); + } } } + if (!$sKey) { + throw new \Exception('Repository public key is missing'); + } + $gnupg->import($sKey); + if (!\count($gnupg->keyinfo(static::KEY_FINGERPRINT))) { + throw new \Exception('Repository public key not imported'); + } } - if (!$sKey) { - throw new \Exception('PGP public key is missing'); + $result = $gnupg->verifyFile($sTmp, $sTmpSignature); + if (!empty($result[0]['keyid'])) { + throw new \Exception("Plugin PGP signature wrong key: {$result[0]['keyid']}"); + } + if (empty($result[0]['fingerprint'])) { + throw new \Exception('Plugin PGP signature invalid'); + } + if (static::KEY_FINGERPRINT !== $result[0]['fingerprint']) { + throw new \Exception("Plugin PGP signature wrong key: {$result[0]['fingerprint']}"); } - $gnupg->import($sKey); - // TODO: check KEY_FINGERPRINT ? - // Verify signature - $gnupg->verify($sTmp, $sTmpSignature); + // Verify x509 signature +/* + // openssl rsautl -verify -inkey my-pub.pem -in in.txt.rsa -pubin + $sTmpSignature = static::download($aList[$sId]['file'] . '.sig'); + if (!$sTmpSignature) { + throw new \Exception('Plugin x509 signature is missing'); + } + openssl_verify( + \file_get_contents($sTmp), + \file_get_contents($sTmpSignature), + static::X509_PUB, + \OPENSSL_ALGO_SHA256, + 0 + ): int|false */ } } diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/repository/releases.asc b/snappymail/v/0.0.0/app/libraries/snappymail/repository/releases.asc new file mode 100644 index 000000000..39afe03b7 --- /dev/null +++ b/snappymail/v/0.0.0/app/libraries/snappymail/repository/releases.asc @@ -0,0 +1,9 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEYg0atBYJKwYBBAHaRw8BAQdA2S2tvGavChACjtBastsKRThD3rsBW1LUZLmN +Zbs4uaG0I1NuYXBweU1haWwgPHJlbGVhc2VzQHNuYXBweW1haWwuZXU+iJQEExYK +ADwWIQQQFuRweRRVQvi6EzVIIIuhMpDz6wUCYg0atAIbAwULCQgHAgMiAgEGFQoJ +CAsCBBYCAwECHgcCF4AACgkQSCCLoTKQ8+u9SAD/Q/IoAwjUkKDJBPq0RGwCFnl6 +FG/VHB97CvBSpGOxtIsBAMCwMhWlsaBHAEqbzxiN+cdlMYwV23+SWLUJ/XMFgukE +=5ZwF +-----END PGP PUBLIC KEY BLOCK----- diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/repository/releases.gpg b/snappymail/v/0.0.0/app/libraries/snappymail/repository/releases.gpg new file mode 100644 index 000000000..4f830265c Binary files /dev/null and b/snappymail/v/0.0.0/app/libraries/snappymail/repository/releases.gpg differ