RsaVerifierTest.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. namespace Tests\Unit\HttpSignatures;
  3. use GuzzleHttp\Psr7\Request;
  4. use App\Util\HttpSignatures\KeyStore;
  5. use App\Util\HttpSignatures\Verifier;
  6. use Tests\Unit\HttpSignatures\TestKeys;
  7. class VerifierRsaTest extends \PHPUnit\Framework\TestCase
  8. {
  9. const DATE = 'Fri, 01 Aug 2014 13:44:32 -0700';
  10. const DATE_DIFFERENT = 'Fri, 01 Aug 2014 13:44:33 -0700';
  11. /**
  12. * @var Verifier
  13. */
  14. private $verifier;
  15. /**
  16. * @var Request
  17. */
  18. private $message;
  19. public function setUp()
  20. {
  21. $this->setUpRsaVerifier();
  22. $sha1SignatureHeader =
  23. 'keyId="rsa1",algorithm="rsa-sha1",headers="(request-target) date",'.
  24. 'signature="YIR3DteE3Jmz1VAnUMTgjTn3vTKfQuZl1CJhMBvGOZpnzwKeYBXAH10'.
  25. '8FojnbSeVG/AXq9pcrA6AFK0peg0aueqxpaFlo+4L/q5XzJ+QoryY3dlSrxwVnE5s5'.
  26. 'M19xmFm/6YkZR/KPeANCsG4SPL82Um/PCEMU0tmKd6sSx+IIzAYbXG/VrFMDeQAdXq'.
  27. 'pU1EhgxopKEAapN8rChb49+1JfR/RxlSKiLukJJ6auurm2zMn2D40fR1d2umA5LAO7'.
  28. 'vRt2iQwVbtwiFkVlRqkMvGftCNZByu8jJ6StI5H7EfuANSHAZXKXWNH8yxpBUW/QCH'.
  29. 'CZjPd0ugM0QJJIc7i8JbGlA=="';
  30. $this->sha1Message = new Request('GET', '/path?query=123', [
  31. 'Date' => 'today',
  32. 'Signature' => $sha1SignatureHeader,
  33. ]);
  34. $sha256SignatureHeader =
  35. 'keyId="rsa1",algorithm="rsa-sha256",headers="(request-target) date",'.
  36. 'signature="WGIegQCC3GEwxbkuXtq67CAqeDhkwblxAH2uoDx5kfWurhLRA5WBFDA/a'.
  37. 'ktsZAjuUoimG1w4CGxSecziER1ez44PBlHP2fCW4ArLgnQgcjkdN2cOf/gj0OVL8s2us'.
  38. 'G4o4tud/+jjF3nxTxLl3HC+erBKsJakwXbw9kt4Cr028BToVfNXsWoMFpv0IjcgBH2V4'.
  39. '1AVlX/mYBMMJAihBCIcpgAcGrrxmG2gkfvSn09wtTttkGHftPIp3VpB53zbemlJS9Yw3'.
  40. 'tmmHr6cvWSXqQy/bTsEOoQJ2REfn5eiyzsJu3GiOpiILK67i/WH9moltJtlfV57TV72c'.
  41. 'gYtjWa6yqhtFg=="';
  42. $this->sha256Message = new Request('GET', '/path?query=123', [
  43. 'Date' => 'today',
  44. 'Signature' => $sha256SignatureHeader,
  45. ]);
  46. }
  47. private function setUpRsaVerifier()
  48. {
  49. $keyStore = new KeyStore(['rsa1' => TestKeys::rsaPublicKey]);
  50. $this->verifier = new Verifier($keyStore);
  51. }
  52. public function testVerifyValidRsaMessage()
  53. {
  54. $this->assertTrue($this->verifier->isValid($this->sha1Message));
  55. $this->assertTrue($this->verifier->isValid($this->sha256Message));
  56. }
  57. public function testVerifyValidRsaMessageAuthorizationHeader()
  58. {
  59. $message = $this->sha1Message->withHeader(
  60. 'Authorization',
  61. "Signature {$this->sha1Message->getHeader('Signature')[0]}");
  62. $message = $this->sha1Message->withoutHeader('Signature');
  63. $this->assertTrue($this->verifier->isValid($this->sha1Message));
  64. $message = $this->sha256Message->withHeader(
  65. 'Authorization',
  66. "Signature {$this->sha256Message->getHeader('Signature')[0]}");
  67. $message = $this->sha256Message->withoutHeader('Signature');
  68. $this->assertTrue($this->verifier->isValid($this->sha256Message));
  69. }
  70. public function testRejectTamperedRsaRequestMethod()
  71. {
  72. $message = $this->sha1Message->withMethod('POST');
  73. $this->assertFalse($this->verifier->isValid($message));
  74. $message = $this->sha256Message->withMethod('POST');
  75. $this->assertFalse($this->verifier->isValid($message));
  76. }
  77. public function testRejectTamperedRsaDate()
  78. {
  79. $message = $this->sha1Message->withHeader('Date', self::DATE_DIFFERENT);
  80. $this->assertFalse($this->verifier->isValid($message));
  81. $message = $this->sha256Message->withHeader('Date', self::DATE_DIFFERENT);
  82. $this->assertFalse($this->verifier->isValid($message));
  83. }
  84. public function testRejectTamperedRsaSignature()
  85. {
  86. $message = $this->sha1Message->withHeader(
  87. 'Signature',
  88. preg_replace('/signature="/', 'signature="x', $this->sha1Message->getHeader('Signature')[0])
  89. );
  90. $this->assertFalse($this->verifier->isValid($message));
  91. $message = $this->sha256Message->withHeader(
  92. 'Signature',
  93. preg_replace('/signature="/', 'signature="x', $this->sha256Message->getHeader('Signature')[0])
  94. );
  95. $this->assertFalse($this->verifier->isValid($message));
  96. }
  97. public function testRejectRsaMessageWithoutSignatureHeader()
  98. {
  99. $message = $this->sha1Message->withoutHeader('Signature');
  100. $this->assertFalse($this->verifier->isValid($message));
  101. $message = $this->sha256Message->withoutHeader('Signature');
  102. $this->assertFalse($this->verifier->isValid($message));
  103. }
  104. public function testRejectRsaMessageWithGarbageSignatureHeader()
  105. {
  106. $message = $this->sha1Message->withHeader('Signature', 'not="a",valid="signature"');
  107. $this->assertFalse($this->verifier->isValid($message));
  108. $message = $this->sha256Message->withHeader('Signature', 'not="a",valid="signature"');
  109. $this->assertFalse($this->verifier->isValid($message));
  110. }
  111. public function testRejectRsaMessageWithPartialSignatureHeader()
  112. {
  113. $message = $this->sha1Message->withHeader('Signature', 'keyId="aa",algorithm="bb"');
  114. $this->assertFalse($this->verifier->isValid($message));
  115. $message = $this->sha256Message->withHeader('Signature', 'keyId="aa",algorithm="bb"');
  116. $this->assertFalse($this->verifier->isValid($message));
  117. }
  118. public function testRejectsRsaMessageWithUnknownKeyId()
  119. {
  120. $keyStore = new KeyStore(['nope' => 'secret']);
  121. $verifier = new Verifier($keyStore);
  122. $this->assertFalse($verifier->isValid($this->sha1Message));
  123. $this->assertFalse($verifier->isValid($this->sha256Message));
  124. }
  125. public function testRejectsRsaMessageMissingSignedHeaders()
  126. {
  127. $message = $this->sha1Message->withoutHeader('Date');
  128. $this->assertFalse($this->verifier->isValid($message));
  129. $message = $this->sha256Message->withoutHeader('Date');
  130. $this->assertFalse($this->verifier->isValid($message));
  131. }
  132. }