PHP Classes

File: src/Operations/PKE.php

Recommend this page to a friend!
  Classes of Scott Arciszewski   PASERK PHP   src/Operations/PKE.php   Download  
File: src/Operations/PKE.php
Role: Class source
Content type: text/plain
Description: Class source
Class: PASERK PHP
Extend PASETO to wrap and serialize keys
Author: By
Last change:
Date: 2 years ago
Size: 2,720 bytes
 

Contents

Class file image Download
<?php
declare(strict_types=1);
namespace
ParagonIE\Paserk\Operations;

use
ParagonIE\Paserk\Operations\PKE\{
   
PKEv3,
   
PKEv4
};
use
ParagonIE\Paserk\Operations\Key\{
   
SealingPublicKey,
   
SealingSecretKey
};
use
ParagonIE\Paserk\PaserkException;
use
ParagonIE\Paseto\Keys\SymmetricKey;
use
ParagonIE\Paseto\ProtocolInterface;
use function
   
array_pop,
   
count,
   
explode,
   
implode;

/**
 * Class PKE
 * @package ParagonIE\Paserk\Operations
 */
class PKE
{
    const
DOMAIN_SEPARATION_ENCRYPT = "\x01";
    const
DOMAIN_SEPARATION_AUTH = "\x02";

    protected
ProtocolInterface $version;

    public function
__construct(ProtocolInterface $version)
    {
       
$this->version = $version;
    }

   
/**
     * @return PKEInterface
     * @throws PaserkException
     */
   
public function getSealer(): PKEInterface
   
{
        return
match ($this->version::header()) {
           
'v3' => new PKEv3(),
           
'v4' => new PKEv4(),
            default => throw new
PaserkException(
               
'Unknown version: ' . $this->version::header()
            ),
        };
    }

   
/**
     * @param SymmetricKey $ptk Symmetric key to seal with this public key
     * @param SealingPublicKey $pk Wrapping key
     * @return string
     *
     * @throws PaserkException
     */
   
public function seal(SymmetricKey $ptk, SealingPublicKey $pk): string
   
{
        if (!
hash_equals($ptk->getProtocol()::header(), $this->version::header())) {
            throw new
PaserkException('Plaintext key is not intended for this version');
        }
        if (!
hash_equals($pk->getProtocol()::header(), $this->version::header())) {
            throw new
PaserkException('Wrapping key is not intended for this version');
        }
       
/// @SPEC DETAIL: Algorithm Lucidity enforcement.

       
$sealer = $this->getSealer();
        return
$sealer::header() . $sealer->seal($ptk, $pk);
    }

   
/**
     * @param string $paserk
     * @param SealingSecretKey $sk Unwrapping key
     * @return SymmetricKey
     *
     * @throws PaserkException
     */
   
public function unseal(string $paserk, SealingSecretKey $sk): SymmetricKey
   
{
       
// Step 1:
       
if (!hash_equals($sk->getProtocol()::header(), $this->version::header())) {
            throw new
PaserkException('Unwrapping key is not intended for this version');
        }
       
$pieces = explode('.', $paserk);
        if (
count($pieces) !== 3) {
            throw new
PaserkException('Invalid PASERK');
        }
       
$payload = array_pop($pieces);
       
$header = implode('.', $pieces) . '.'; // Recreate header
       
$sealer = $this->getSealer();
        return
$sealer->unseal($header, $payload, $sk);
    }
}