From b4ea243fbedc56813c74ba5b00bf8c69c6892a80 Mon Sep 17 00:00:00 2001 From: Niklas Keller Date: Wed, 27 Jan 2016 09:46:30 +0100 Subject: [PATCH] New InvalidCertificateException and more tests --- lib/Certificate.php | 16 +++++++++---- lib/InvalidCertificateException.php | 7 ++++++ test/CertificateTest.php | 36 +++++++++++++++++++++++----- test/data/localhost.der | Bin 0 -> 767 bytes 4 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 lib/InvalidCertificateException.php create mode 100644 test/data/localhost.der diff --git a/lib/Certificate.php b/lib/Certificate.php index d29308d..ca9ed2f 100644 --- a/lib/Certificate.php +++ b/lib/Certificate.php @@ -14,13 +14,13 @@ public function __construct($pem) { } if (!$cert = @openssl_x509_read($pem)) { - throw new \InvalidArgumentException("Invalid PEM encoded certificate!"); + throw new InvalidCertificateException("Invalid PEM encoded certificate!"); } $this->pem = $pem; if (!$this->info = openssl_x509_parse($cert)) { - throw new \InvalidArgumentException("Invalid PEM encoded certificate!"); + throw new InvalidCertificateException("Invalid PEM encoded certificate!"); } } @@ -116,17 +116,25 @@ public function __debugInfo() { } public static function derToPem($der) { + if (!is_string($der)) { + throw new \InvalidArgumentException("\$der must be a string, " . gettype($der) . " given."); + } + return sprintf( - "-----BEGIN CERTIFICATE-----\n%s-----END CERTIFICATE-----", + "-----BEGIN CERTIFICATE-----\n%s-----END CERTIFICATE-----\n", chunk_split(base64_encode($der), 64, "\n") ); } public static function pemToDer($pem) { + if (!is_string($pem)) { + throw new \InvalidArgumentException("\$pem must be a string, " . gettype($pem) . " given."); + } + $pattern = "@-----BEGIN CERTIFICATE-----\n([a-zA-Z0-9+/=\n]+)-----END CERTIFICATE-----@"; if (!preg_match($pattern, $pem, $match)) { - throw new \RuntimeException("Invalid PEM could not be converted to DER format."); + throw new InvalidCertificateException("Invalid PEM could not be converted to DER format."); } return base64_decode(str_replace(["\n", "\r"], "", trim($match[1]))); diff --git a/lib/InvalidCertificateException.php b/lib/InvalidCertificateException.php new file mode 100644 index 0000000..6d2d368 --- /dev/null +++ b/lib/InvalidCertificateException.php @@ -0,0 +1,7 @@ +assertSame("Let's Encrypt", $cert->getIssuer()->getOrganizationName()); $this->assertSame("Let's Encrypt Authority X1", $cert->getIssuer()->getCommonName()); $this->assertFalse($cert->isSelfSigned()); - $this->assertSame($raw, (string) $cert); + $this->assertSame(trim($raw), trim((string) $cert)); + $this->assertSame(trim($raw), trim($cert->toPem())); + $this->assertSame(trim($raw), trim(Certificate::derToPem($cert->toDer()))); $this->assertSame([ "commonName" => "www.kelunik.com", "names" => ["kelunik.com", "www.kelunik.com"], @@ -43,23 +45,45 @@ public function testSignature() { } public function testDerToPem() { - $raw = file_get_contents(__DIR__ . "/data/localhost.pem"); - $transformed = Certificate::pemToDer(Certificate::derToPem($raw)); + $pem = file_get_contents(__DIR__ . "/data/localhost.pem"); + $der = file_get_contents(__DIR__ . "/data/localhost.der"); - $this->assertSame($raw, $transformed); + $this->assertSame($der, Certificate::pemToDer($pem)); + $this->assertSame($pem, Certificate::derToPem($der)); } /** * @expectedException \InvalidArgumentException */ - public function testNonString() { - new Certificate(0); + public function testInvalidDerType() { + Certificate::derToPem(0); } /** * @expectedException \InvalidArgumentException */ + public function testInvalidPemType() { + Certificate::pemToDer(0); + } + + /** + * @expectedException \Kelunik\Certificate\InvalidCertificateException + */ public function testInvalidPem() { + Certificate::pemToDer(""); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testNonString() { + new Certificate(0); + } + + /** + * @expectedException \Kelunik\Certificate\InvalidCertificateException + */ + public function testInvalidPemConstruct() { new Certificate(""); } } diff --git a/test/data/localhost.der b/test/data/localhost.der new file mode 100644 index 0000000000000000000000000000000000000000..c165ac7c3027459fdb0ca9c9f1d4d4dcbd7f3f7b GIT binary patch literal 767 zcmXqLV)|{+#Q1mtGZP~d6DPx`1>Zuy$$K#v@Un4gwRyCC=VfH%W@RuCF%&WoU}Fwt zVdmk?$xlwq$;dA*F_07IH8eFeG%__ZG%+)^jDm74pj;ffni!Rkjb~(KU~XdMX8<~b zi>Zl`k>Pp;`<6e~aEv!A7_e{L(j(U^VjRQwD-e_=t^D^H5whS>;QS=VTwaw>AG z+^-8pVvD~A2gVnx9{>OM*P4tNlWjY^OBzm{?>}()U00sN{U_C(9n2eaDi6$Jh?{pT zZuQ#*S&<=Y&zmqlo3Q@!Z$H!f0Xeo?=FZn}v;P*fF=5v(W|?B)c|XpJ>iu~?XGPrZ zB!kl0@N2hDoMQI+trmK_m-V+VWTz|TMy7~-;gEMhDo=R#OK?r!V*UH7Fv|3M!6 zK9d~J=?3y3X=N4(1F;6|3V1*YgjrY(m>C)WBZoOKN`Ya{$l%r%^SO$>ZgF<>!nk$4 z<-QL0RD<$C*5}owUbx4;Me{av+}rT zTXuilMD?T9j;?QS6#3|#jVLPEx8nx8duG};yLlR$`Q87`IUZ=UuUB_+PLz!Q&!XK8 zWxiieg&NK}uxQ1k@8;n}Icc&+WiQzC&lYIB)yxPwe(imnn#|StGsDF8{ywmD+LGwy z6LkZdMK4K<+s