From 0567d5a967edb5fe4dac23bc2336d4e2496819cc Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Mon, 8 Aug 2016 18:19:57 +0100 Subject: [PATCH 01/10] Pass instance of GuzzleHttp\Psr7\Request so that we can get more from it Updated tests to pass with the new changes --- src/ComodoDecodeCSR.php | 24 +++++++++++++++--------- tests/Xigen/ComodoDecodeCSRTest.php | 20 ++++++++++---------- tests/Xigen/DiffrentTextfileCSRTest.php | 5 +++++ 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/ComodoDecodeCSR.php b/src/ComodoDecodeCSR.php index b557b22..f2de05b 100644 --- a/src/ComodoDecodeCSR.php +++ b/src/ComodoDecodeCSR.php @@ -64,8 +64,7 @@ public function checkInstalled() return false; } - $response = "" . $request->getBody(); - return $this->checkDVC($response); + return $this->checkDVC($request); } public function generateDVC() @@ -76,28 +75,35 @@ public function generateDVC() return $DVC; } - public function checkDVC($response) + /** + * + * @param GuzzleHttp\Psr7\Request $request + * @return bool + */ + public function checkDVC($request) { + $body = $request->getBody() . ''; + $DVC = $this->generateDVC(); //If the response matches the DVC value return true - if ($response === $DVC) { + if ($body === $DVC) { return true; } //Check if last 2 characters are new lines - if (substr($response, -2) === "\n\n") { - $response = substr($response, 0, -2) . "\n"; + if (substr($body, -2) === "\n\n") { + $body = substr($body, 0, -2) . "\n"; } //Check if last character is not a new line - if (substr($response, -1) !== "\n") { + if (substr($body, -1) !== "\n") { //Add said new line - $response = $response . "\n"; + $body = $body . "\n"; } //Check it again - if ($response === $DVC) { + if ($body === $DVC) { return true; } diff --git a/tests/Xigen/ComodoDecodeCSRTest.php b/tests/Xigen/ComodoDecodeCSRTest.php index 9a3c7cc..bee19a5 100644 --- a/tests/Xigen/ComodoDecodeCSRTest.php +++ b/tests/Xigen/ComodoDecodeCSRTest.php @@ -54,21 +54,21 @@ public function testSettingCSR() public function testGettingHashes() { $this->ComodoDecodeCSR->setCSR($this->loadTestCSR()); - $Hashes = $this->ComodoDecodeCSR->fetchHashes(); + $hashes = $this->ComodoDecodeCSR->fetchHashes(); - $this->assertSame($this->validMD5, $Hashes["md5"], "md5 didn't match the correct value"); + $this->assertSame($this->validMD5, $hashes["md5"], "md5 didn't match the correct value"); $this->assertSame($this->validMD5, $this->ComodoDecodeCSR->getMD5(), "md5 didn't match the correct value"); - $this->assertSame($this->validSHA1, $Hashes["sha1"], "sha1 didn't match the correct value"); + $this->assertSame($this->validSHA1, $hashes["sha1"], "sha1 didn't match the correct value"); $this->assertSame($this->validSHA1, $this->ComodoDecodeCSR->getSHA1(), "sha1 didn't match the correct value"); } public function testGettingHashesFromInvalidCSR() { - $Hashes = $this->ComodoDecodeCSR->fetchHashes(); + $hashes = $this->ComodoDecodeCSR->fetchHashes(); - $this->assertSame($Hashes["md5"], '', "a md5 was set"); - $this->assertSame($Hashes["sha1"], '', "a sha1 was set"); + $this->assertSame($hashes["md5"], '', "a md5 was set"); + $this->assertSame($hashes["sha1"], '', "a sha1 was set"); } public function testCheckingInstalled() @@ -76,9 +76,9 @@ public function testCheckingInstalled() $csr = $this->loadTestCSR(); $this->ComodoDecodeCSR->setCSR($csr); $this->ComodoDecodeCSR->fetchHashes(); - $Installed = $this->ComodoDecodeCSR->checkInstalled(); + $installed = $this->ComodoDecodeCSR->checkInstalled(); - $this->assertTrue($Installed); + $this->assertTrue($installed); } public function testCheckInstalledFail() @@ -86,8 +86,8 @@ public function testCheckInstalledFail() $csr = $this->createFakeCSR(); $this->ComodoDecodeCSR->setCSR($csr); $this->ComodoDecodeCSR->fetchHashes(); - $Installed = $this->ComodoDecodeCSR->checkInstalled(); + $installed = $this->ComodoDecodeCSR->checkInstalled(); - $this->assertFalse($Installed); + $this->assertFalse($installed); } } diff --git a/tests/Xigen/DiffrentTextfileCSRTest.php b/tests/Xigen/DiffrentTextfileCSRTest.php index 2e3334b..915c872 100644 --- a/tests/Xigen/DiffrentTextfileCSRTest.php +++ b/tests/Xigen/DiffrentTextfileCSRTest.php @@ -9,6 +9,9 @@ namespace Xigen\Tests; +use GuzzleHttp\Psr7; +use GuzzleHttp\Psr7\Response; + use Xigen\ComodoDecodeCSR; class DiffrentTextfileCSRTest extends XigenUnit @@ -25,6 +28,8 @@ public function setUp() private function checkresponse($response) { + $stream = Psr7\stream_for($response); + $response = new Response(200, [], $stream); return $this->ComodoDecodeCSR->checkDVC($response); } From db8650ea2e1509aaec039d90df0be0d0b2c7547b Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Mon, 8 Aug 2016 18:33:45 +0100 Subject: [PATCH 02/10] GuzzleHttp\Psr7\Request should be GuzzleHttp\Psr7\Response --- src/ComodoDecodeCSR.php | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/ComodoDecodeCSR.php b/src/ComodoDecodeCSR.php index f2de05b..3b8562a 100644 --- a/src/ComodoDecodeCSR.php +++ b/src/ComodoDecodeCSR.php @@ -11,6 +11,7 @@ use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Psr7\Response; class ComodoDecodeCSR { @@ -21,6 +22,11 @@ class ComodoDecodeCSR protected $SHA1; protected $Endpoint = "https://secure.comodo.net/products/!decodeCSR"; protected $CSR; + /** + * An array of warnings that can be show after the test + * @var array + */ + protected $warnings = []; protected $Form = [ 'responseFormat' => 'N', 'showErrorCodes' => 'N', @@ -40,6 +46,15 @@ class ComodoDecodeCSR ]; private $request; + protected function addWarning($code, $message) + { + $this->warnings[] = [ + $code => $message + ]; + + return $this; + } + public function fetchHashes() { $client = new Client(); @@ -56,15 +71,15 @@ public function checkInstalled() $domain = $this->getCN(); $URL = 'http://' . $domain . "/" . $this->getmd5() . '.txt'; - $client = new Client(); + $client = new Client(['allow_redirects' => false]); try { - $request = $client->request('GET', $URL); + $response = $client->request('GET', $URL); } catch (ClientException $e) { return false; } - return $this->checkDVC($request); + return $this->checkDVC($response); } public function generateDVC() @@ -77,13 +92,12 @@ public function generateDVC() /** * - * @param GuzzleHttp\Psr7\Request $request + * @param GuzzleHttp\Psr7\Response $response * @return bool */ - public function checkDVC($request) + public function checkDVC(Response $response) { - $body = $request->getBody() . ''; - + $body = $response->getBody() . ''; $DVC = $this->generateDVC(); //If the response matches the DVC value return true From 5e7cf8c18e27bbbf4ac2a1a92eef94b11bd7442f Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Tue, 9 Aug 2016 12:22:22 +0100 Subject: [PATCH 03/10] Add two new Console Commands, Hashes and CreateFile --- ComodoDecodeCSR | 4 +++ src/Console/Check.php | 6 ++-- src/Console/CreateFile.php | 62 ++++++++++++++++++++++++++++++++++++++ src/Console/Hashes.php | 60 ++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/Console/CreateFile.php create mode 100644 src/Console/Hashes.php diff --git a/ComodoDecodeCSR b/ComodoDecodeCSR index afe38fd..790c3c0 100755 --- a/ComodoDecodeCSR +++ b/ComodoDecodeCSR @@ -18,5 +18,9 @@ use Symfony\Component\Console\Application; use Xigen\Console; $application = new Application('ComodoDecodeCSR', '0.4'); + $application->add(new Console\Check()); +$application->add(new Console\Hashes()); +$application->add(new Console\CreateFile()); + $application->run(); diff --git a/src/Console/Check.php b/src/Console/Check.php index 01f6250..ad2b9c9 100644 --- a/src/Console/Check.php +++ b/src/Console/Check.php @@ -45,14 +45,12 @@ protected function execute(InputInterface $input, OutputInterface $output) $ComodoDecodeCSR->fetchHashes(); if ($ComodoDecodeCSR->checkInstalled()) { - $output->writeln('Success!'); - $output->writeln('This domain should pass DVC'); + $output->writeln('Success! This domain should pass DVC'); return true; } - $output->writeln('Fail!'); - $output->writeln('There is something wrong with the validation file'); + $output->writeln('Fail! There is something wrong with the validation file'); return false; } diff --git a/src/Console/CreateFile.php b/src/Console/CreateFile.php new file mode 100644 index 0000000..fd804b6 --- /dev/null +++ b/src/Console/CreateFile.php @@ -0,0 +1,62 @@ + + * @package ComodoDecodeCSR + * @copyright 2016 Xigen + * @license GNU General Public License v3 + * @link https://github.com/XigenChris/ComodoDecodeCSR + */ + +namespace Xigen\Console; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Output\OutputInterface; +use Xigen\ComodoDecodeCSR; + +class CreateFile extends BaseCommand +{ + protected function configure() + { + $this + ->setName("createfile") + ->setDescription("Creates the file needed for DVC") + ->addArgument( + 'csr', + InputArgument::REQUIRED, + 'Location of csr file' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $csrFile = $input->getArgument('csr'); + if (!file_exists($csrFile)) { + $output->writeln('Unable to load '. $csrFile .''); + $output->writeln('Please check the path and try again'); + + return 1; + } + + $csr = file_get_contents($csrFile); + + $comodoDecodeCSR = new ComodoDecodeCSR(); + $comodoDecodeCSR->setCSR($csr); + $hashes = $comodoDecodeCSR->fetchHashes(); + + if (!$hashes) { + $output->writeln('Fail!'); + $output->writeln('Unable to fetch hashes'); + + return 2; + } + + $output->writeln('Filename: ' . $hashes['md5'] . '.txt'); + $output->writeln('Contents:'); + $output->writeln($comodoDecodeCSR->generateDVC()); + $output->writeln('URL: http://' . $comodoDecodeCSR->getCN() . '/' . $hashes['md5'] . '.txt'); + + return 0; + } +} diff --git a/src/Console/Hashes.php b/src/Console/Hashes.php new file mode 100644 index 0000000..f4f247d --- /dev/null +++ b/src/Console/Hashes.php @@ -0,0 +1,60 @@ + + * @package ComodoDecodeCSR + * @copyright 2016 Xigen + * @license GNU General Public License v3 + * @link https://github.com/XigenChris/ComodoDecodeCSR + */ + +namespace Xigen\Console; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Output\OutputInterface; +use Xigen\ComodoDecodeCSR; + +class Hashes extends BaseCommand +{ + protected function configure() + { + $this + ->setName("hashes") + ->setDescription("Get hashes from a CSR file") + ->addArgument( + 'csr', + InputArgument::REQUIRED, + 'Location of csr file' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $csrFile = $input->getArgument('csr'); + if (!file_exists($csrFile)) { + $output->writeln('Unable to load '. $csrFile .''); + $output->writeln('Please check the path and try again'); + + return 1; + } + + $csr = file_get_contents($csrFile); + + $comodoDecodeCSR = new ComodoDecodeCSR(); + $comodoDecodeCSR->setCSR($csr); + $hashes = $comodoDecodeCSR->fetchHashes(); + + if ($hashes) { + $output->writeln('MD5 ' . $hashes['md5']); + $output->writeln('SHA1 ' . $hashes['sha1']); + + return 0; + } + + $output->writeln('Fail!'); + $output->writeln('Unable to fetch hashes'); + + return 2; + } +} From 3b8721f9ddc0a28d6304177ea1d74db9fca8f1e6 Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Tue, 9 Aug 2016 12:39:50 +0100 Subject: [PATCH 04/10] Put loading CSR into its own function --- src/Console/BaseCommand.php | 19 +++++++++++++++++++ src/Console/Check.php | 17 ++++------------- src/Console/CreateFile.php | 12 +----------- src/Console/Hashes.php | 14 ++------------ 4 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/Console/BaseCommand.php b/src/Console/BaseCommand.php index ecdb666..be7eac1 100644 --- a/src/Console/BaseCommand.php +++ b/src/Console/BaseCommand.php @@ -10,9 +10,28 @@ namespace Xigen\Console; use Xigen\Application; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command; abstract class BaseCommand extends Command { + /** + * Load a .csr file via an CLI argument + * @param Symfony\Component\Console\Input\InputInterface $input + * @param Symfony\Component\Console\Output\OutputInterface $output + * @return bool|void + */ + public function loadCSR(InputInterface $input, OutputInterface $output) + { + $csrFile = $input->getArgument('csr'); + if (!file_exists($csrFile)) { + $output->writeln('Unable to load '. $csrFile .''); + $output->writeln('Please check the path and try again'); + exit(); + } + + return file_get_contents($csrFile); + } } diff --git a/src/Console/Check.php b/src/Console/Check.php index ad2b9c9..52eb7ed 100644 --- a/src/Console/Check.php +++ b/src/Console/Check.php @@ -31,20 +31,11 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { - $csrFile = $input->getArgument('csr'); - if (!file_exists($csrFile)) { - $output->writeln('Unable to load '. $csrFile .''); - $output->writeln('Please check the path and try again'); - return false; - } - - $csr = file_get_contents($csrFile); - - $ComodoDecodeCSR = new ComodoDecodeCSR(); - $ComodoDecodeCSR->setCSR($csr); - $ComodoDecodeCSR->fetchHashes(); + $comodoDecodeCSR = new ComodoDecodeCSR(); + $comodoDecodeCSR->setCSR($this->loadCSR($input, $output)); + $comodoDecodeCSR->fetchHashes(); - if ($ComodoDecodeCSR->checkInstalled()) { + if ($comodoDecodeCSR->checkInstalled()) { $output->writeln('Success! This domain should pass DVC'); return true; diff --git a/src/Console/CreateFile.php b/src/Console/CreateFile.php index fd804b6..2a69808 100644 --- a/src/Console/CreateFile.php +++ b/src/Console/CreateFile.php @@ -31,18 +31,8 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { - $csrFile = $input->getArgument('csr'); - if (!file_exists($csrFile)) { - $output->writeln('Unable to load '. $csrFile .''); - $output->writeln('Please check the path and try again'); - - return 1; - } - - $csr = file_get_contents($csrFile); - $comodoDecodeCSR = new ComodoDecodeCSR(); - $comodoDecodeCSR->setCSR($csr); + $comodoDecodeCSR->setCSR($this->loadCSR($input, $output)); $hashes = $comodoDecodeCSR->fetchHashes(); if (!$hashes) { diff --git a/src/Console/Hashes.php b/src/Console/Hashes.php index f4f247d..641d0ad 100644 --- a/src/Console/Hashes.php +++ b/src/Console/Hashes.php @@ -31,24 +31,14 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { - $csrFile = $input->getArgument('csr'); - if (!file_exists($csrFile)) { - $output->writeln('Unable to load '. $csrFile .''); - $output->writeln('Please check the path and try again'); - - return 1; - } - - $csr = file_get_contents($csrFile); - $comodoDecodeCSR = new ComodoDecodeCSR(); - $comodoDecodeCSR->setCSR($csr); + $comodoDecodeCSR->setCSR($this->loadCSR($input, $output)); $hashes = $comodoDecodeCSR->fetchHashes(); if ($hashes) { $output->writeln('MD5 ' . $hashes['md5']); $output->writeln('SHA1 ' . $hashes['sha1']); - + return 0; } From 9b63580a575450a089bf73422cba3d1734170e04 Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Tue, 9 Aug 2016 13:19:41 +0100 Subject: [PATCH 05/10] Remove getter and setter traits Added 'magic' getter and setter --- src/ComodoDecodeCSR.php | 18 ++++++++++-- src/Traits/ComodoDecodeCSR/Getters.php | 39 -------------------------- src/Traits/ComodoDecodeCSR/Setters.php | 30 -------------------- src/Traits/GetSetUnset.php | 31 ++++++++++++++++++++ 4 files changed, 46 insertions(+), 72 deletions(-) delete mode 100644 src/Traits/ComodoDecodeCSR/Getters.php delete mode 100644 src/Traits/ComodoDecodeCSR/Setters.php create mode 100644 src/Traits/GetSetUnset.php diff --git a/src/ComodoDecodeCSR.php b/src/ComodoDecodeCSR.php index b557b22..baa4e80 100644 --- a/src/ComodoDecodeCSR.php +++ b/src/ComodoDecodeCSR.php @@ -14,8 +14,7 @@ class ComodoDecodeCSR { - use Traits\ComodoDecodeCSR\Getters; - use Traits\ComodoDecodeCSR\Setters; + use Traits\GetSetUnset; protected $MD5; protected $SHA1; @@ -40,6 +39,19 @@ class ComodoDecodeCSR ]; private $request; + public function getCN() + { + $CSRInfo = $this->decodeCSR(); + return $CSRInfo['subject']['CN']; + } + + public function setCSR($CSR) + { + //TODO Check that this is a valid CSR + $this->CSR = $CSR; + $this->Form['csr'] = $CSR; + } + public function fetchHashes() { $client = new Client(); @@ -54,7 +66,7 @@ public function fetchHashes() public function checkInstalled() { $domain = $this->getCN(); - $URL = 'http://' . $domain . "/" . $this->getmd5() . '.txt'; + $URL = 'http://' . $domain . "/" . $this->getMD5() . '.txt'; $client = new Client(); diff --git a/src/Traits/ComodoDecodeCSR/Getters.php b/src/Traits/ComodoDecodeCSR/Getters.php deleted file mode 100644 index 400d9fc..0000000 --- a/src/Traits/ComodoDecodeCSR/Getters.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @package ComodoDecodeCSR - * @copyright 2016 Xigen - * @license GNU General Public License v3 - * @link https://github.com/XigenChris/ComodoDecodeCSR - */ - -namespace Xigen\Traits\ComodoDecodeCSR; - -trait Getters -{ - public function getMD5() - { - return $this->MD5; - } - - public function getSHA1() - { - return $this->SHA1; - } - - public function getEndpoint() - { - return $this->Endpoint; - } - - public function getCN() - { - $CSRInfo = $this->decodeCSR(); - return $CSRInfo['subject']['CN']; - } - - public function getCSR() - { - return $this->CSR; - } -} diff --git a/src/Traits/ComodoDecodeCSR/Setters.php b/src/Traits/ComodoDecodeCSR/Setters.php deleted file mode 100644 index 1e89b19..0000000 --- a/src/Traits/ComodoDecodeCSR/Setters.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @package ComodoDecodeCSR - * @copyright 2016 Xigen - * @license GNU General Public License v3 - * @link https://github.com/XigenChris/ComodoDecodeCSR - */ - -namespace Xigen\Traits\ComodoDecodeCSR; - -trait Setters -{ - public function setMD5($MD5) - { - return $this->MD5 = $MD5; - } - - public function setSHA1($SHA1) - { - return $this->SHA1 = $SHA1; - } - - public function setCSR($CSR) - { - //TODO Check that this is a valid CSR - $this->CSR = $CSR; - $this->Form['csr'] = $CSR; - } -} diff --git a/src/Traits/GetSetUnset.php b/src/Traits/GetSetUnset.php new file mode 100644 index 0000000..a540fdc --- /dev/null +++ b/src/Traits/GetSetUnset.php @@ -0,0 +1,31 @@ + + * @package ComodoDecodeCSR + * @copyright 2016 Xigen + * @license GNU General Public License v3 + * @link https://github.com/XigenChris/ComodoDecodeCSR + */ + +namespace Xigen\Traits; + +trait GetSetUnset +{ + public function __call($method, $args) + { + $data = false; + switch (substr($method, 0, 3)) { + case 'get': + $get = substr($method, 3); + $data = $this->$get; + break; + case 'set': + $set = substr($method, 3); + $data = $args[0]; + $this->$set = $data; + break; + } + + return $data; + } +} From 146f3eae07a0b2356cde67c9c3342b1af2dd8499 Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Tue, 9 Aug 2016 13:27:33 +0100 Subject: [PATCH 06/10] Small fix for scrutinizer --- src/Console/Check.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Console/Check.php b/src/Console/Check.php index 52eb7ed..ca9d79f 100644 --- a/src/Console/Check.php +++ b/src/Console/Check.php @@ -38,11 +38,11 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($comodoDecodeCSR->checkInstalled()) { $output->writeln('Success! This domain should pass DVC'); - return true; + return 2; } $output->writeln('Fail! There is something wrong with the validation file'); - return false; + return 0; } } From 4fda6fed2073cb7aaeb9b3d59f773377d028e8b1 Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Wed, 17 Aug 2016 13:48:13 +0100 Subject: [PATCH 07/10] Added some logic to catch 301 and 302 redirects --- src/ComodoDecodeCSR.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ComodoDecodeCSR.php b/src/ComodoDecodeCSR.php index 3b8562a..8e7bc2f 100644 --- a/src/ComodoDecodeCSR.php +++ b/src/ComodoDecodeCSR.php @@ -51,8 +51,6 @@ protected function addWarning($code, $message) $this->warnings[] = [ $code => $message ]; - - return $this; } public function fetchHashes() @@ -69,9 +67,10 @@ public function fetchHashes() public function checkInstalled() { $domain = $this->getCN(); + //We do most of our DVC over http:// unless the site is fully SSL $URL = 'http://' . $domain . "/" . $this->getmd5() . '.txt'; - $client = new Client(['allow_redirects' => false]); + $client = new Client(['allow_redirects' => false, 'verify' => false]); try { $response = $client->request('GET', $URL); @@ -100,6 +99,14 @@ public function checkDVC(Response $response) $body = $response->getBody() . ''; $DVC = $this->generateDVC(); + //Check if we received a 301 or 302 redirect + if ($response->getStatusCode() === 301 || $response->getStatusCode() == 301) { + $message = 'There is a redirect inplace. Make sure that its not redirecting to https://'; + $this->addWarning(301, $message); + + return false; + } + //If the response matches the DVC value return true if ($body === $DVC) { return true; From 2ab5f70e2bee77601e408bf97f56dbe2b051063f Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Wed, 17 Aug 2016 13:48:49 +0100 Subject: [PATCH 08/10] [Tests] Added some tests for the redirect checks --- tests/Xigen/RedirectTest.php | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/Xigen/RedirectTest.php diff --git a/tests/Xigen/RedirectTest.php b/tests/Xigen/RedirectTest.php new file mode 100644 index 0000000..6e97d27 --- /dev/null +++ b/tests/Xigen/RedirectTest.php @@ -0,0 +1,42 @@ + + * @package ComodoDecodeCSR + * @copyright 2016 Xigen + * @license GNU General Public License v3 + * @link https://github.com/XigenChris/ComodoDecodeCSR + */ + +namespace Xigen\Tests; + +use GuzzleHttp\Psr7; +use GuzzleHttp\Psr7\Response; +use Xigen\ComodoDecodeCSR; + +class RedirectTest extends XigenUnit +{ + protected $ComodoDecodeCSR; + + public function setUp() + { + $this->ComodoDecodeCSR = new ComodoDecodeCSR(); + } + + public function test301Redirect() + { + $stream = Psr7\stream_for('{"data" : "test"}'); + $response = new Response(301, ['Location' => 'https://comododecodecsr.tk'], $stream); + + $test = $this->ComodoDecodeCSR->checkDVC($response); + $this->assertFalse($test, "Failed to check 301 redirect"); + } + + public function test302Redirect() + { + $stream = Psr7\stream_for('{"data" : "test"}'); + $response = new Response(302, ['Location' => 'https://comododecodecsr.tk'], $stream); + + $test = $this->ComodoDecodeCSR->checkDVC($response); + $this->assertFalse($test, "Failed to check 302 redirect"); + } +} From e30e33f83ef053f12cfebcc9e4417c348799a759 Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Tue, 23 Aug 2016 13:27:08 +0100 Subject: [PATCH 09/10] [Tests] Starting working on tests for the console app --- src/ComodoDecodeCSR.php | 31 ++++++---- src/Console/Check.php | 17 +++-- src/Console/CreateFile.php | 12 +++- src/Exception.php | 15 +++++ tests/Xigen/ComodoDecodeCSRTest.php | 19 ------ tests/Xigen/Console/CheckTest.php | 86 ++++++++++++++++++++++++++ tests/Xigen/Console/CreateFileTest.php | 76 +++++++++++++++++++++++ tests/Xigen/XigenUnit.php | 25 ++++++++ 8 files changed, 246 insertions(+), 35 deletions(-) create mode 100644 src/Exception.php create mode 100644 tests/Xigen/Console/CheckTest.php create mode 100644 tests/Xigen/Console/CreateFileTest.php diff --git a/src/ComodoDecodeCSR.php b/src/ComodoDecodeCSR.php index 6ab6e4c..09d33c1 100644 --- a/src/ComodoDecodeCSR.php +++ b/src/ComodoDecodeCSR.php @@ -51,11 +51,12 @@ public function getCN() return $CSRInfo['subject']['CN']; } - public function setCSR($CSR) + public function setCSR($csr) { - //TODO Check that this is a valid CSR - $this->CSR = $CSR; - $this->Form['csr'] = $CSR; + $this->CSR = $csr; + //Check that this is a valid CSR + $this->decodeCSR(); + $this->Form['csr'] = $csr; } protected function addWarning($code, $message) @@ -78,14 +79,18 @@ public function fetchHashes() public function checkInstalled() { - $domain = $this->getCN(); + try { + $domain = $this->getCN(); + } catch (\Exception $e) { + return false; + } //We do most of our DVC over http:// unless the site is fully SSL - $URL = 'http://' . $domain . "/" . $this->getMD5() . '.txt'; + $url = 'http://' . $domain . "/" . $this->getMD5() . '.txt'; $client = new Client(['allow_redirects' => false, 'verify' => false]); try { - $response = $client->request('GET', $URL); + $response = $client->request('GET', $url); } catch (ClientException $e) { return false; } @@ -145,10 +150,14 @@ public function checkDVC(Response $response) private function decodeCSR() { - $data = openssl_csr_get_public_key($this->getCSR()); - $details = openssl_pkey_get_details($data); - $key = $details['key']; - $subject = openssl_csr_get_subject($this->getCSR()); + try { + $data = openssl_csr_get_public_key($this->getCSR()); + $details = openssl_pkey_get_details($data); + $key = $details['key']; + $subject = openssl_csr_get_subject($this->getCSR()); + } catch (\Exception $e) { + throw new Exception("Invalid CSR"); + } return array( "subject" => $subject, diff --git a/src/Console/Check.php b/src/Console/Check.php index ca9d79f..d95b238 100644 --- a/src/Console/Check.php +++ b/src/Console/Check.php @@ -13,6 +13,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; use Xigen\ComodoDecodeCSR; +use Xigen\Exception; class Check extends BaseCommand { @@ -32,17 +33,25 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { $comodoDecodeCSR = new ComodoDecodeCSR(); - $comodoDecodeCSR->setCSR($this->loadCSR($input, $output)); - $comodoDecodeCSR->fetchHashes(); + + try { + $comodoDecodeCSR->setCSR($this->loadCSR($input, $output)); + $comodoDecodeCSR->fetchHashes(); + } catch (Exception $e) { + $output->writeln('Error!'); + $output->writeln('Invalid CSR'); + + return 3; + } if ($comodoDecodeCSR->checkInstalled()) { $output->writeln('Success! This domain should pass DVC'); - return 2; + return 0; } $output->writeln('Fail! There is something wrong with the validation file'); - return 0; + return 2; } } diff --git a/src/Console/CreateFile.php b/src/Console/CreateFile.php index 2a69808..f0ddf9f 100644 --- a/src/Console/CreateFile.php +++ b/src/Console/CreateFile.php @@ -13,6 +13,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; use Xigen\ComodoDecodeCSR; +use Xigen\Exception; class CreateFile extends BaseCommand { @@ -32,7 +33,16 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { $comodoDecodeCSR = new ComodoDecodeCSR(); - $comodoDecodeCSR->setCSR($this->loadCSR($input, $output)); + + try { + $comodoDecodeCSR->setCSR($this->loadCSR($input, $output)); + } catch (Exception $e) { + $output->writeln('Error!'); + $output->writeln('Invalid CSR'); + + return 3; + } + $hashes = $comodoDecodeCSR->fetchHashes(); if (!$hashes) { diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 0000000..b4348cb --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,15 @@ + + * @package ComodoDecodeCSR + * @copyright 2016 Xigen + * @license GNU General Public License v3 + * @link https://github.com/XigenChris/ComodoDecodeCSR + */ + +namespace Xigen; + +class Exception extends \Exception +{ + +} \ No newline at end of file diff --git a/tests/Xigen/ComodoDecodeCSRTest.php b/tests/Xigen/ComodoDecodeCSRTest.php index bee19a5..8bea285 100644 --- a/tests/Xigen/ComodoDecodeCSRTest.php +++ b/tests/Xigen/ComodoDecodeCSRTest.php @@ -20,25 +20,6 @@ public function setUp() $this->ComodoDecodeCSR = new ComodoDecodeCSR(); } - private function createFakeCSR() - { - $dn = array( - "countryName" => "NA", - "stateOrProvinceName" => "NA", - "localityName" => "NA", - "organizationName" => "NA", - "organizationalUnitName" => "NA", - "commonName" => "httpbin.org", - "emailAddress" => "NA" - ); - - // Generate a new private (and public) key pair - $privkey = openssl_pkey_new(); - - // Generate a certificate signing request - return openssl_csr_new($dn, $privkey); - } - public function testSettingCSR() { //Load the test CSR diff --git a/tests/Xigen/Console/CheckTest.php b/tests/Xigen/Console/CheckTest.php new file mode 100644 index 0000000..f827384 --- /dev/null +++ b/tests/Xigen/Console/CheckTest.php @@ -0,0 +1,86 @@ + + * @package ComodoDecodeCSR + * @copyright 2016 Xigen + * @license GNU General Public License v3 + * @link https://github.com/XigenChris/ComodoDecodeCSR + */ + +namespace Xigen\Tests\Console; + +use Xigen\ComodoDecodeCSR; +use Xigen\Tests\XigenUnit; +use Xigen\Console\Check; +use Symfony\Component\Console\Tester\CommandTester; + +class CheckTest extends XigenUnit +{ + protected $ComodoDecodeCSR; + + public function setUp() + { + register_shutdown_function(function () { + if (file_exists('test.csr')) { + unlink('test.csr'); + } + }); + } + + public function testNoCSR() + { + $command = new Check(); + $tester = new CommandTester($command); + + try { + $tester->execute([]); + } catch (\Exception $e) { + $this->assertEmpty($tester->getDisplay(), "Message wan't empty"); + $this->assertSame($e->getMessage(), 'Not enough arguments (missing: "csr").'); + } + } + + public function testWithInvalidCSR() + { + $command = new Check(); + $tester = new CommandTester($command); + + //Create an empty + file_put_contents('test.csr', '', FILE_APPEND | LOCK_EX); + + $tester->execute([ + 'csr' => 'test.csr' + ]); + + $this->assertSame($tester->getStatusCode(), (int) 3); + $this->assertRegExp('/Error!/', $tester->getDisplay()); + } + + public function testWithBadCSR() + { + $command = new Check(); + $tester = new CommandTester($command); + + //Create an empty + file_put_contents('test.csr', ' ' . $this->createFakeCSR(), FILE_APPEND | LOCK_EX); + + $tester->execute([ + 'csr' => 'test.csr' + ]); + + $this->assertSame($tester->getStatusCode(), (int) 3); + $this->assertRegExp('/Error!/', $tester->getDisplay()); + } + + public function testWithCorrectCSR() + { + $command = new Check(); + $tester = new CommandTester($command); + $tester->execute([ + 'csr' => 'certificate/test.csr' + ]); + + $this->assertSame($tester->getStatusCode(), (int) 0); + $this->assertRegExp('/Success!/', $tester->getDisplay()); + } +} diff --git a/tests/Xigen/Console/CreateFileTest.php b/tests/Xigen/Console/CreateFileTest.php new file mode 100644 index 0000000..a144e91 --- /dev/null +++ b/tests/Xigen/Console/CreateFileTest.php @@ -0,0 +1,76 @@ + + * @package ComodoDecodeCSR + * @copyright 2016 Xigen + * @license GNU General Public License v3 + * @link https://github.com/XigenChris/ComodoDecodeCSR + */ + +namespace Xigen\Tests\Console; + +use Xigen\ComodoDecodeCSR; +use Xigen\Tests\XigenUnit; +use Xigen\Console\CreateFile; +use Symfony\Component\Console\Tester\CommandTester; + +class CreateFileTest extends XigenUnit +{ + protected $ComodoDecodeCSR; + + public function setUp() + { + register_shutdown_function(function () { + if (file_exists('test.csr')) { + unlink('test.csr'); + } + }); + } + + public function testNoCSR() + { + $command = new CreateFile(); + $tester = new CommandTester($command); + + try { + $tester->execute([]); + } catch (\Exception $e) { + $this->assertEmpty($tester->getDisplay(), "Message wan't empty"); + $this->assertSame($e->getMessage(), 'Not enough arguments (missing: "csr").'); + } + } + + public function testWithBadCSR() + { + $command = new CreateFile(); + $tester = new CommandTester($command); + + //Create an empty + file_put_contents('test.csr', '', FILE_APPEND | LOCK_EX); + + $tester->execute([ + 'csr' => 'test.csr' + ]); + + $this->assertSame($tester->getStatusCode(), (int) 3); + $this->assertRegExp('/Error!/', $tester->getDisplay()); + } + + public function testWithCorrectCSR() + { + $command = new CreateFile(); + $tester = new CommandTester($command); + $tester->execute([ + 'csr' => 'certificate/test.csr' + ]); + + $this->assertSame($tester->getStatusCode(), (int) 0); + $lines = $this->getOutputLines($tester->getDisplay()); + + $this->assertRegExp('/Filename: [a-f0-9]{32}.txt/i', $lines[0]); + $this->assertSame('Contents:', $lines[1]); + $this->assertRegExp('/[0-9a-f]{5,40}/i', $lines[2]); + $this->assertSame('comodoca.com', $lines[3]); + $this->assertRegExp('/URL: http:\/\/comododecodecsr.tk\/[a-f0-9]{32}.txt/i', $lines[5]); + } +} diff --git a/tests/Xigen/XigenUnit.php b/tests/Xigen/XigenUnit.php index de300e4..6fbc2da 100644 --- a/tests/Xigen/XigenUnit.php +++ b/tests/Xigen/XigenUnit.php @@ -14,8 +14,33 @@ abstract class XigenUnit extends \PHPUnit_Framework_TestCase public $validMD5 = "98EB197EF83F7A9EB736ED7CEBD413CE"; public $validSHA1 = "DA9C72B6F6BCB05772BF8543E19D1A41B0210E84"; + public function createFakeCSR() + { + $dn = array( + "countryName" => "NA", + "stateOrProvinceName" => "NA", + "localityName" => "NA", + "organizationName" => "NA", + "organizationalUnitName" => "NA", + "commonName" => "httpbin.org", + "emailAddress" => "NA" + ); + + // Generate a new private (and public) key pair + $privkey = openssl_pkey_new(); + + // Generate a certificate signing request + return openssl_csr_new($dn, $privkey); + } + public function loadTestCSR() { return file_get_contents('certificate/test.csr'); } + + public function getOutputLines($display) + { + return preg_split("/((\r?\n)|(\r\n?))/", $display); + } + } From f509d5f3c0286f2479f28dc5491fb74416d2b4ca Mon Sep 17 00:00:00 2001 From: Chris Hilsdon Date: Tue, 13 Sep 2016 12:23:43 +0100 Subject: [PATCH 10/10] Check again using https:// before saying a it will fail --- src/ComodoDecodeCSR.php | 62 +++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/ComodoDecodeCSR.php b/src/ComodoDecodeCSR.php index 09d33c1..5877fcf 100644 --- a/src/ComodoDecodeCSR.php +++ b/src/ComodoDecodeCSR.php @@ -45,6 +45,8 @@ class ComodoDecodeCSR ]; private $request; + private $forceSSL = false; + public function getCN() { $CSRInfo = $this->decodeCSR(); @@ -79,23 +81,39 @@ public function fetchHashes() public function checkInstalled() { + try { $domain = $this->getCN(); } catch (\Exception $e) { return false; } - //We do most of our DVC over http:// unless the site is fully SSL - $url = 'http://' . $domain . "/" . $this->getMD5() . '.txt'; - $client = new Client(['allow_redirects' => false, 'verify' => false]); + $response = $this->fetchDVCFile($domain); + if ($response == false) { + return false; + } - try { - $response = $client->request('GET', $url); - } catch (ClientException $e) { + $check = $this->checkDVC($response); + if ($check === true) { + return $check; + } + + //Try again but this time use https:// + $this->forceSSL = true; + + $response = $this->fetchDVCFile($domain); + if ($response == false) { return false; } - return $this->checkDVC($response); + $check = $this->checkDVC($response); + if ($check === true) { + //TODO Add a message to say then you will need to select 'HTTPS CSR + //Hash' + return $check; + } + + return false; } public function generateDVC() @@ -117,10 +135,7 @@ public function checkDVC(Response $response) $DVC = $this->generateDVC(); //Check if we received a 301 or 302 redirect - if ($response->getStatusCode() === 301 || $response->getStatusCode() == 301) { - $message = 'There is a redirect inplace. Make sure that its not redirecting to https://'; - $this->addWarning(301, $message); - + if ($response->getStatusCode() === 301 || $response->getStatusCode() == 302) { return false; } @@ -140,6 +155,8 @@ public function checkDVC(Response $response) $body = $body . "\n"; } + var_dump($body, $DVC); + //Check it again if ($body === $DVC) { return true; @@ -186,4 +203,27 @@ private function processResponse() return $data ? $data : false; } + + private function fetchDVCFile($domain) + { + //We do most of our DVC over http:// unless the site is fully SSL + $protocol = 'http://'; + + if ($this->forceSSL) { + $protocol = 'https://'; + } + + $url = $protocol . $domain . "/" . $this->getMD5() . '.txt'; + + $client = new Client(['allow_redirects' => false, 'verify' => false]); + + try { + $response = $client->request('GET', $url); + } catch (ClientException $e) { + var_dump('te', $e); + return false; + } + + return $response; + } }