PHP Classes

File: tests/SapientSealTest.php

Recommend this page to a friend!
  Classes of Scott Arciszewski   sapient   tests/SapientSealTest.php   Download  
File: tests/SapientSealTest.php
Role: Class source
Content type: text/plain
Description: Class source
Class: sapient
Add a security layer to server to server requests
Author: By
Last change: Proposal: Inject adapters, punt to adapter where appropriate.
Merge remote-tracking branch 'origin/master'
Date: 6 years ago
Size: 9,322 bytes
 

Contents

Class file image Download
<?php
namespace ParagonIE\Sapient\UnitTests;

use
GuzzleHttp\Psr7\Request;
use
GuzzleHttp\Psr7\Response;
use
ParagonIE\ConstantTime\Base64UrlSafe;
use
ParagonIE\Sapient\Adapter\Guzzle;
use
ParagonIE\Sapient\CryptographyKeys\{
   
SealingPublicKey,
   
SealingSecretKey
};
use
ParagonIE\Sapient\Sapient;
use
PHPUnit\Framework\TestCase;

/**
 * Class SapientTest
 * @package ParagonIE\Sapient\UnitTests
 */
class SapientSealTest extends TestCase
{
   
/** @var Sapient */
   
protected $sapient;

   
/** @var SealingSecretKey */
   
protected $clientSealSecret;

   
/** @var SealingPublicKey */
   
protected $clientSealPublic;

   
/** @var SealingSecretKey */
   
protected $serverSealSecret;

   
/** @var SealingPublicKey */
   
protected $serverSealPublic;

   
/**
     * Setup the class properties
     */
   
public function setUp()
    {
       
$this->sapient = new Sapient(new Guzzle());

       
$this->clientSealSecret = SealingSecretKey::generate();
       
$this->clientSealPublic = $this->clientSealSecret->getPublickey();

       
$this->serverSealSecret = SealingSecretKey::generate();
       
$this->serverSealPublic = $this->serverSealSecret->getPublickey();
    }

    private function
getSampleObjects(): array
    {
        return [
            [],
            [
'test' => 'abcdefg'],
            [
'random' => Base64UrlSafe::encode(
                \
random_bytes(
                    \
random_int(1, 100)
                )
            )
            ],
            [
'structued' => [
               
'abc' => 'def',
               
'o' => null,
               
'ghi' => ['j', 'k', 'l'],
               
'm' => 1234,
               
'n' => 56.78,
               
'p' => ['q' => ['r' => []]]
            ]]
        ];
    }

   
/**
     * @covers Sapient::createSignedJsonRequest()
     * @covers Sapient::verifySignedRequest()
     */
   
public function testSignedJsonRequest()
    {
       
$sampleObjects = $this->getSampleObjects();

        foreach (
$sampleObjects as $obj) {
           
$guzzle = new Guzzle();
           
$request = $guzzle->createSealedJsonRequest(
               
'POST',
               
'/',
               
$obj,
               
$this->clientSealPublic
           
);
           
$decoded = $this->sapient->unsealJsonRequest(
               
$request,
               
$this->clientSealSecret
           
);
           
$this->assertSame($obj, $decoded);

           
/* We expect an exception: */
           
try {
               
$this->sapient->unsealJsonRequest(
                   
$request,
                   
$this->serverSealSecret
               
);
               
$this->fail('Bad message signature');
            } catch (\
Throwable $ex) {
            }

           
$invalid = $request->withBody(
               
$this->sapient->stringToStream(
                   
Base64UrlSafe::encode('invalid message goes here for verifying the failure of crypto_box_seal')
                )
            );
           
/* We expect an exception: */
           
try {
               
$this->sapient->unsealJsonRequest(
                   
$invalid,
                   
$this->clientSealSecret
               
);
               
$this->fail('Bad message accepted');
            } catch (\
Throwable $ex) {
            }
        }
    }

   
/**
     * @covers Sapient::createSignedRequest()
     * @covers Sapient::verifySignedRequest()
     */
   
public function testSignedRequest()
    {
       
$randomMessage = Base64UrlSafe::encode(
            \
random_bytes(
                \
random_int(101, 200)
            )
        );
       
$request = $this->sapient->createSealedRequest(
           
'POST',
           
'/',
           
$randomMessage,
           
$this->clientSealPublic
       
);
       
$decoded = $this->sapient->unsealRequest(
           
$request,
           
$this->clientSealSecret
       
);
       
$this->assertInstanceOf(Request::class, $decoded);
       
$this->assertSame($randomMessage, (string) $decoded->getBody());

       
/* Test bad public key */
       
try {
           
$this->sapient->unsealRequest(
               
$request,
               
$this->serverSealSecret
           
);
           
$this->fail('Bad message signature');
        } catch (\
Throwable $ex) {
        }

       
$invalid = $request->withBody(
           
$this->sapient->stringToStream(
               
Base64UrlSafe::encode('invalid message goes here for verifying the failure of crypto_box_seal')
            )
        );

       
/* Test bad message */
       
try {
           
$this->sapient->unsealRequest(
               
$invalid,
               
$this->serverSealSecret
           
);
           
$this->fail('Bad message accepted');
        } catch (\
Throwable $ex) {
        }
    }
   
/**
     * @covers Sapient::createSignedJsonResponse()
     * @covers Sapient::verifySignedResponse()
     */
   
public function testSignedJsonResponse()
    {
       
$sampleObjects = $this->getSampleObjects();

        foreach (
$sampleObjects as $obj) {
           
$guzzle = new Guzzle();
           
$response = $guzzle->createSealedJsonResponse(
               
200,
               
$obj,
               
$this->serverSealPublic
           
);
           
$responseRaw = $this->sapient->unsealResponse(
               
$response,
               
$this->serverSealSecret
           
);
           
$this->assertInstanceOf(Response::class, $responseRaw);

           
$decoded = $this->sapient->unsealJsonResponse($response, $this->serverSealSecret);
           
$this->assertSame($obj, $decoded);

           
/* Test bad public key */
           
try {
               
$this->sapient->unsealResponse(
                   
$response,
                   
$this->clientSealSecret
               
);
               
$this->fail('Bad message accepted');
            } catch (\
Throwable $ex) {
            }

           
$invalid = $response->withBody(
               
$this->sapient->stringToStream(
                   
Base64UrlSafe::encode('invalid message goes here for verifying the failure of crypto_box_seal')
                )
            );
           
/* Test bad message */
           
try {
               
$this->sapient->unsealResponse(
                   
$invalid,
                   
$this->serverSealSecret
               
);
               
$this->fail('Bad message accepted');
            } catch (\
Throwable $ex) {
            }
        }
    }

   
/**
     * @covers Sapient::createSignedResponse()
     * @covers Sapient::verifySignedResponse()
     */
   
public function testSealedResponse()
    {
       
$randomMessage = Base64UrlSafe::encode(
            \
random_bytes(
                \
random_int(101, 200)
            )
        );
       
$response = $this->sapient->createSealedResponse(
           
200,
           
$randomMessage,
           
$this->serverSealPublic
       
);
       
$responseRaw = $this->sapient->unsealResponse(
           
$response,
           
$this->serverSealSecret
       
);
       
$this->assertInstanceOf(Response::class, $responseRaw);

       
$decoded = $this->sapient->unsealResponse($response, $this->serverSealSecret);
       
$this->assertSame($randomMessage, (string) $decoded->getBody());

       
/* Test bad public key */
       
try {
           
$this->sapient->unsealResponse(
               
$response,
               
$this->clientSealSecret
           
);
           
$this->fail('Bad message accepted');
        } catch (\
Throwable $ex) {
        }

       
$invalid = $response->withBody(
           
$this->sapient->stringToStream(
               
Base64UrlSafe::encode('invalid message goes here for verifying the failure of crypto_box_seal')
            )
        );
       
/* Test bad message */
       
try {
           
$this->sapient->unsealResponse(
               
$invalid,
               
$this->serverSealSecret
           
);
           
$this->fail('Bad message accepted');
        } catch (\
Throwable $ex) {
        }
    }

   
/**
     * @covers Sapient::signRequest()
     * @covers Sapient::signResponse()
     */
   
public function testPsr7()
    {
       
$randomMessage = Base64UrlSafe::encode(
            \
random_bytes(
                \
random_int(101, 200)
            )
        );

       
$request = new Request('POST', '/test', [], $randomMessage);
       
$signedRequest = $this->sapient->sealRequest($request, $this->clientSealPublic);
        try {
           
$unsealed = $this->sapient->unsealRequest(
               
$signedRequest,
               
$this->clientSealSecret
           
);
           
$this->assertSame(
               
$randomMessage,
                (string)
$unsealed->getBody()
            );
        } catch (\
Throwable $ex) {
           
$this->fail('Error decrypting message');
        }

       
$response = new Response(200, [], $randomMessage);
       
$signedResponse = $this->sapient->sealResponse($response, $this->clientSealPublic);
        try {
           
$unsealed = $this->sapient->unsealResponse(
               
$signedResponse,
               
$this->clientSealSecret
           
);
           
$this->assertSame(
               
$randomMessage,
                (string)
$unsealed->getBody()
            );
        } catch (\
Throwable $ex) {
           
$this->fail('Error decrypting message');
        }
    }
}