HmacContextTest.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. namespace Tests\Unit\HttpSignatures;
  3. use GuzzleHttp\Psr7\Request;
  4. use App\Util\HttpSignatures\Context;
  5. class HmacContextTest extends \PHPUnit\Framework\TestCase
  6. {
  7. private $context;
  8. public function setUp()
  9. {
  10. $this->noDigestContext = new Context([
  11. 'keys' => ['pda' => 'secret'],
  12. 'algorithm' => 'hmac-sha256',
  13. 'headers' => ['(request-target)', 'date'],
  14. ]);
  15. $this->withDigestContext = new Context([
  16. 'keys' => ['pda' => 'secret'],
  17. 'algorithm' => 'hmac-sha256',
  18. 'headers' => ['(request-target)', 'date', 'digest'],
  19. ]);
  20. }
  21. public function testSignerNoDigestAction()
  22. {
  23. $message = new Request('GET', '/path?query=123', ['date' => 'today', 'accept' => 'llamas']);
  24. $message = $this->noDigestContext->signer()->sign($message);
  25. $expectedString = implode(',', [
  26. 'keyId="pda"',
  27. 'algorithm="hmac-sha256"',
  28. 'headers="(request-target) date"',
  29. 'signature="SFlytCGpsqb/9qYaKCQklGDvwgmrwfIERFnwt+yqPJw="',
  30. ]);
  31. $this->assertEquals(
  32. $expectedString,
  33. $message->getHeader('Signature')[0]
  34. );
  35. $this->assertEquals(
  36. 'Signature '.$expectedString,
  37. $message->getHeader('Authorization')[0]
  38. );
  39. }
  40. public function testSignerAddDigestToHeadersList()
  41. {
  42. $message = new Request(
  43. 'POST', '/path/to/things?query=123',
  44. ['date' => 'today', 'accept' => 'llamas'],
  45. 'Thing to POST');
  46. $message = $this->noDigestContext->signer()->signWithDigest($message);
  47. $expectedString = implode(',', [
  48. 'keyId="pda"',
  49. 'algorithm="hmac-sha256"',
  50. 'headers="(request-target) date digest"',
  51. 'signature="HH6R3OJmJbKUFqqL0tGVIIb7xi1WbbSh/HBXHUtLkUs="', ]);
  52. $expectedDigestHeader =
  53. 'SHA-256=rEcNhYZoBKiR29D30w1JcgArNlF8rXIXf5MnIL/4kcc=';
  54. $this->assertEquals(
  55. $expectedString,
  56. $message->getHeader('Signature')[0]
  57. );
  58. $this->assertEquals(
  59. $expectedDigestHeader,
  60. $message->getHeader('Digest')[0]
  61. );
  62. $this->assertEquals(
  63. 'Signature '.$expectedString,
  64. $message->getHeader('Authorization')[0]
  65. );
  66. }
  67. public function testSignerReplaceDigest()
  68. {
  69. $message = new Request(
  70. 'PUT', '/things/thething?query=123',
  71. ['date' => 'today',
  72. 'accept' => 'llamas',
  73. 'Digest' => 'SHA-256=E/P+4y4x6EySO9qNAjCtQKxVwE1xKsNI/k+cjK+vtLU=', ],
  74. 'Thing to PUT at /things/thething please...');
  75. $message = $this->noDigestContext->signer()->signWithDigest($message);
  76. $expectedString = implode(',', [
  77. 'keyId="pda"',
  78. 'algorithm="hmac-sha256"',
  79. 'headers="(request-target) date digest"',
  80. 'signature="Hyatt1lSR/4XLI9Gcx8XOEKiG8LVktH7Lfr+0tmhwRU="', ]);
  81. $expectedDigestHeader =
  82. 'SHA-256=mulOx+77mQU1EbPET50SCGA4P/4bYxVCJA1pTwJsaMw=';
  83. $this->assertEquals(
  84. $expectedString,
  85. $message->getHeader('Signature')[0]
  86. );
  87. $this->assertEquals(
  88. $expectedDigestHeader,
  89. $message->getHeader('Digest')[0]
  90. );
  91. $this->assertEquals(
  92. 'Signature '.$expectedString,
  93. $message->getHeader('Authorization')[0]
  94. );
  95. }
  96. public function testSignerNewDigestIsInHeaderList()
  97. {
  98. $message = new Request(
  99. 'POST', '/path?query=123',
  100. ['date' => 'today',
  101. 'accept' => 'llamas', ],
  102. 'Stuff that belongs in /path');
  103. $message = $this->withDigestContext->signer()->signWithDigest($message);
  104. $expectedString = implode(',', [
  105. 'keyId="pda"',
  106. 'algorithm="hmac-sha256"',
  107. 'headers="(request-target) date digest"',
  108. 'signature="p8gQHs59X2WzQLUecfmxm1YO0OBTCNKldRZZBQsepfk="', ]);
  109. $expectedDigestHeader =
  110. 'SHA-256=jnSMEfBSum4Rh2k6/IVFyvLuQLmGYwMAGBS9WybyDqQ=';
  111. $this->assertEquals(
  112. $expectedString,
  113. $message->getHeader('Signature')[0]
  114. );
  115. $this->assertEquals(
  116. $expectedDigestHeader,
  117. $message->getHeader('Digest')[0]
  118. );
  119. $this->assertEquals(
  120. 'Signature '.$expectedString,
  121. $message->getHeader('Authorization')[0]
  122. );
  123. }
  124. public function testSignerNewDigestWithoutBody()
  125. {
  126. $message = new Request(
  127. 'GET', '/path?query=123',
  128. ['date' => 'today',
  129. 'accept' => 'llamas', ]);
  130. $message = $this->withDigestContext->signer()->signWithDigest($message);
  131. $expectedString = implode(',', [
  132. 'keyId="pda"',
  133. 'algorithm="hmac-sha256"',
  134. 'headers="(request-target) date digest"',
  135. 'signature="7iFqqryI6I9opV/Zp3eEg6PDY1tKw/3GqioOM7ACHHA="', ]);
  136. $zeroLengthStringDigest =
  137. 'SHA-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=';
  138. $this->assertEquals(
  139. $expectedString,
  140. $message->getHeader('Signature')[0]
  141. );
  142. $this->assertEquals(
  143. $zeroLengthStringDigest,
  144. $message->getHeader('Digest')[0]
  145. );
  146. $this->assertEquals(
  147. 'Signature '.$expectedString,
  148. $message->getHeader('Authorization')[0]
  149. );
  150. }
  151. public function testVerifier()
  152. {
  153. $message = $this->noDigestContext->signer()->sign(new Request('GET', '/path?query=123', [
  154. 'Signature' => 'keyId="pda",algorithm="hmac-sha1",headers="date",signature="x"',
  155. 'Date' => 'x',
  156. ]));
  157. // assert it works without errors; correctness of results tested elsewhere.
  158. $this->assertTrue(is_bool($this->noDigestContext->verifier()->isValid($message)));
  159. }
  160. }