Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

- added phar-verify script

- added new tests
- RemotePharVerifier will abort on openssl files in no pubkey mode
- RemotePharVerifier will check other signature methods in no pubkey
mode
  • Loading branch information...
commit c8c675f7b84be8b081e5ed210d1f4cd5f995c011 1 parent 5bb567f
@koto authored
View
15 PharUtil/RemotePharVerifier.php
@@ -160,13 +160,14 @@ protected function assertVerified($local_path) {
if (!copy($this->pub_key_file, $this->getPubkeyFilename($local_path))) {
throw new RuntimeException("Error copying public key file!");
}
- try {
- $this->verifyPharSignature($local_path);
- } catch (Exception $e) {
- $this->doDelete($local_path); // delete offending files
- throw $e;
- }
}
+ try {
+ $this->verifyPharSignature($local_path);
+ } catch (Exception $e) {
+ $this->doDelete($local_path); // delete offending files
+ throw $e;
+ }
+
return true;
}
@@ -228,7 +229,7 @@ protected function verifyPharSignature($local_path) {
$sig = $phar->getSignature();
unset($phar);
- if ($sig['hash_type'] !== 'OpenSSL') {
+ if ($this->pub_key_file && $sig['hash_type'] !== 'OpenSSL') {
throw new PharUtil_SignatureVerificationException("This phar is not signed with OpenSSL!");
}
} catch (UnexpectedValueException $e) {
View
29 package.xml
@@ -16,7 +16,7 @@
<date>2010-08-06</date>
<time>15:20:37</time>
<version>
- <release>0.2.0</release>
+ <release>0.3.0</release>
<api>0.1</api>
</version>
<stability>
@@ -49,6 +49,7 @@
<dir name="phar">
<file name="modified.phar" role="test" />
<file name="nosig.phar" role="test" />
+ <file name="nosigmodified.phar" role="test" />
<file name="test.phar" role="test" />
<file name="test.phar.gz" role="test" />
<file name="wrongsig.phar" role="test" />
@@ -95,6 +96,15 @@
<tasks:replace from="@php_bin@" to="php_bin" type="pear-config" />
<tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" />
</file>
+ <file name="phar-verify.php" role="script">
+ <tasks:replace from="/usr/bin/env php" to="php_bin" type="pear-config"/>
+ <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" />
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="phar-verify.bat" role="script">
+ <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" />
+ <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" />
+ </file>
<file name="phar-generate-cert" role="script" />
</dir>
</contents>
@@ -132,18 +142,35 @@
<install as="phar-build.bat" name="phar-build.bat" />
<install as="phar-extract" name="phar-extract.php" />
<install as="phar-extract.bat" name="phar-extract.bat" />
+ <install as="phar-verify" name="phar-verify.php" />
+ <install as="phar-verify.bat" name="phar-verify.bat" />
</filelist>
</phprelease>
<phprelease>
<filelist>
<install as="phar-build" name="phar-build.php" />
<install as="phar-extract" name="phar-extract.php" />
+ <install as="phar-verify" name="phar-verify.php" />
<ignore name="phar-build.bat" />
<ignore name="phar-extract.bat" />
+ <ignore name="phar-verify.bat" />
</filelist>
</phprelease>
<changelog>
<release>
+ <release>
+ <version>
+ <release>0.3</release>
+ <api>0.1</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <date>2010-08-06</date>
+ <license uri="http://www.opensource.org/licenses/mit-license.html">MIT</license>
+ <notes>Added phar-verify toolset, small changes</notes>
+ </release>
<version>
<release>0.2</release>
<api>0.1</api>
View
1  phar-build.php
@@ -20,7 +20,6 @@
'name' => 'phar-build',
));
-// add an option to make the program verbose
$parser->addOption('src', array(
'short_name' => '-s',
'long_name' => '--src',
View
3  phar-extract.php
@@ -38,7 +38,6 @@
'description' => "Input Phar archive filename e.g. phar.phar",
));
-// add an option to make the program verbose
$parser->addArgument('destination', array(
'action' => 'StoreString',
'description' => "Destination directory"
@@ -104,7 +103,7 @@
throw new Exception("Phar writing support is disabled in this PHP installation, set phar.readonly=0 in php.ini!");
}
echo "Extracting {$files_count} file(s) to: {$args['destination']}..." . PHP_EOL;
- $phar->ExtractTo($args['destination'], null, true);
+ $phar->extractTo($args['destination'], null, true);
}
if ($options['public']) {
View
8 phar-verify.bat
@@ -0,0 +1,8 @@
+@ECHO OFF
+if "%PHPBIN%" == "" set PHPBIN="@php_bin@"
+if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
+GOTO RUN
+:USE_PEAR_PATH
+set PHPBIN="%PHP_PEAR_PHP_BIN%"
+:RUN
+%PHPBIN% "@bin_dir@\phar-verify" %*
View
94 phar-verify.php
@@ -0,0 +1,94 @@
+#!/usr/bin/env php
+<?php
+/**
+ * Verify Phar archive signature using a public key file
+ *
+ * This file is part of the PharUtil library.
+ * @author Krzysztof Kotowicz <kkotowicz at gmail dot com>
+ * @package PharUtil
+ */
+
+// Include the Console_CommandLine package.
+require_once 'Console/CommandLine.php';
+require_once 'PharUtil/RemotePharVerifier.php';
+
+// create the parser
+$parser = new Console_CommandLine(array(
+ 'description' => 'Verify Phar archive signature using a public key file',
+ 'version' => '@package_version@',
+ 'name' => 'phar-verify',
+));
+
+$parser->addOption('public', array(
+ 'short_name' => '-P',
+ 'long_name' => '--public',
+ 'action' => 'StoreString',
+ 'default' => './cert/pub.pem',
+ 'description' => "Public key file (PEM) to verify signature\n(./cert/pub.pem by default)"
+));
+
+$parser->addOption('nosign', array(
+ 'short_name' => '-n',
+ 'long_name' => '--ns',
+ 'action' => 'StoreTrue',
+ 'description' => 'Archive is not signed, don\'t require an OpenSSL signature'
+));
+
+$parser->addOption('temp', array(
+ 'short_name' => '-t',
+ 'long_name' => '--temp',
+ 'action' => 'StoreString',
+ 'description' => 'Temporary directory (' . sys_get_temp_dir() . ' by default)',
+));
+
+$parser->addArgument('phar', array(
+ 'action' => 'StoreString',
+ 'description' => "Input Phar archive URI e.g.\n/path/to/local/phar.phar or http://path/to/remote/phar.phar",
+));
+
+// run the parser
+try {
+ $result = $parser->parse();
+} catch (Exception $exc) {
+ $parser->displayError($exc->getMessage());
+}
+
+$options = $result->options;
+$args = $result->args;
+
+echo $parser->name . ' ' . $parser->version . PHP_EOL . PHP_EOL;
+
+// validate parameters
+if (substr($args['phar'], -5) !== '.phar') {
+ $parser->displayError("Input Phar must have .phar extension, {$args['phar']} given.", 2);
+}
+
+if ($options['nosign']) {
+ $options['public'] = null; // no public key
+}
+
+if ($options['public']) {
+ if (!file_exists($options['public']) || !is_readable($options['public'])) {
+ $parser->displayError("Public key in '{$options['public']}' does not exist or is not readable.", 4);
+ }
+}
+
+if (!$options['temp']) {
+ $options['temp'] = sys_get_temp_dir();
+}
+
+try {
+ echo "Verifying Phar archive: {$args['phar']}..." . PHP_EOL;
+
+ $v = new PharUtil_RemotePharVerifier($options['temp'], $options['temp'], $options['public']);
+
+ $v->verify($args['phar']);
+
+ echo "Phar archive successfully verified." . PHP_EOL;
+} catch (Exception $e) {
+ echo "Error: " . $e->getMessage() . PHP_EOL;
+ exit(1);
+}
+
+
+echo PHP_EOL . "All done, exiting." . PHP_EOL;
View
41 test/PharUtil/RemotePharVerifierTest.php
@@ -104,10 +104,12 @@ public function testFetchCleansUpOnFailure($file) {
}
$this->fail("PharUtil_SignatureVerificationException was not thrown");
}
+
public function invalidFiles() {
return array(
array('wrongsig.phar'),
array('nosig.phar'),
+ array('nosigmodified.phar'),
array('modified.phar'),
array('test.phar.gz'),
);
@@ -120,7 +122,7 @@ public function testModifiedPharsAreInvalid() {
$v->fetch($this->remote_dir . 'modified.phar');
}
- public function testNoPubkeyChecking() {
+ public function testNoPubkeyWillPassNotSignedPhars() {
// no public key given
$v = new PharUtil_RemotePharVerifier($this->fetch_dir, $this->verified_dir, null);
@@ -128,14 +130,6 @@ public function testNoPubkeyChecking() {
$this->assertFileExists($ok);
$this->assertFileEquals($this->remote_dir . 'nosig.phar', $ok);
- $ok = $v->fetch($this->remote_dir . 'wrongsig.phar');
- $this->assertFileExists($ok);
- $this->assertFileEquals($this->remote_dir . 'wrongsig.phar', $ok);
-
- $ok = $v->fetch($this->remote_dir . 'modified.phar');
- $this->assertFileExists($ok);
- $this->assertFileEquals($this->remote_dir . 'modified.phar', $ok);
-
// gzips are ok withot pubkey verification
$ok = $v->fetch($this->remote_dir . 'test.phar.gz');
$this->assertFileExists($ok);
@@ -143,6 +137,35 @@ public function testNoPubkeyChecking() {
}
/**
+ * @dataProvider openSslFiles
+ */
+ public function testNoPubkeyWillErrorOnAllSignedPhars($file) {
+ // no public key given
+ $v = new PharUtil_RemotePharVerifier($this->fetch_dir, $this->verified_dir, null);
+
+ // this will pass (thankyou Phar :( )
+ $this->setExpectedException('PharUtil_SignatureVerificationException');
+ $ok = $v->fetch($this->remote_dir . $file);
+ }
+
+ public function openSslFiles() {
+ return array(
+ array('wrongsig.phar'),
+ array('modified.phar'),
+ array('test.phar'),
+ );
+ }
+
+ public function testNoPubkeyWillCheckOtherChecksums() {
+ // no public key given
+ $v = new PharUtil_RemotePharVerifier($this->fetch_dir, $this->verified_dir, null);
+
+ // simulate transfer error (SHA-1 checksum, but file is modified)
+ $this->setExpectedException('PharUtil_SignatureVerificationException');
+ $ok = $v->fetch($this->remote_dir . 'nosigmodified.phar');
+ }
+
+ /**
* @dataProvider invalidFilenames
*/
public function testFilenameChecking($filename) {
View
BIN  test/PharUtil/data/phar/nosigmodified.phar
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.