PHP Classes

File: src/Types/Seal.php

Recommend this page to a friend!
  Classes of Scott Arciszewski   PASERK PHP   src/Types/Seal.php   Download  
File: src/Types/Seal.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: 1 year ago
Size: 3,380 bytes
 

Contents

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

use
ParagonIE\Paserk\{
   
ConstraintTrait,
   
PaserkException,
   
PaserkTypeInterface
};
use
ParagonIE\Paserk\Operations\{
   
PKE,
   
Key\SealingPublicKey,
   
Key\SealingSecretKey
};
use
ParagonIE\Paseto\{
   
Exception\InvalidVersionException,
   
KeyInterface,
   
Keys\SymmetricKey
};
use
SodiumException;
use
Throwable;
use function
   
array_key_exists,
   
is_null;

/**
 * Class Seal
 * @package ParagonIE\Paserk\Types
 */
class Seal implements PaserkTypeInterface
{
    use
ConstraintTrait;

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

   
/** @var SealingSecretKey|null $sk */
   
protected ?SealingSecretKey $sk = null;

   
/** @var array<string, string> */
   
protected array $localCache = [];

   
/**
     * Seal constructor.
     *
     * @param SealingPublicKey $pk
     * @param SealingSecretKey|null $sk
     */
   
public function __construct(SealingPublicKey $pk, ?SealingSecretKey $sk = null)
    {
       
$this->pk = $pk;
        if (
$sk) {
           
$this->sk = $sk;
        }
       
$this->localCache = [];
    }

   
/**
     * @param SealingSecretKey $sk
     * @return self
     *
     * @throws PaserkException
     */
   
public static function fromSecretKey(SealingSecretKey $sk): self
   
{
        try {
           
$pk = new SealingPublicKey($sk->getPublicKey()->raw(), $sk->getProtocol());
            return new
self($pk, $sk);
        } catch (
Throwable $ex) {
            throw new
PaserkException("Could not load public key", 0, $ex);
        }
    }

   
/**
     * @param string $paserk
     * @return KeyInterface
     *
     * @throws PaserkException
     */
   
public function decode(string $paserk): KeyInterface
   
{
        if (
is_null($this->sk)) {
            throw new
PaserkException('No secret key was provided; cannot unseal');
        }
       
$unsealed = (new PKE($this->sk->getProtocol()))
            ->
unseal($paserk, $this->sk);
       
$this->throwIfInvalidProtocol($unsealed->getProtocol());
       
/// @SPEC DETAIL: Algorithm Lucidity

       
return $unsealed;
    }

   
/**
     * @param KeyInterface $key
     * @return string
     *
     * @throws PaserkException
     * @throws InvalidVersionException
     */
   
public function encode(KeyInterface $key): string
   
{
        if (!(
$key instanceof SymmetricKey)) {
            throw new
PaserkException('Only symmetric keys are allowed here');
        }
       
$this->throwIfInvalidProtocol($key->getProtocol());
       
/// @SPEC DETAIL: Algorithm Lucidity

       
$localId = (new Local($this->pk->getProtocol()))->encode($key);
        if (!
array_key_exists($localId, $this->localCache)) {
           
$pke = new PKE($this->pk->getProtocol());
           
$this->localCache[$localId] = $pke->seal($key, $this->pk);
        }
        return
$this->localCache[$localId];
    }

   
/**
     * @return string
     */
   
public static function getTypeLabel(): string
   
{
        return
'seal';
    }

   
/**
     * @param KeyInterface $key
     * @return string
     *
     * @throws InvalidVersionException
     * @throws PaserkException
     * @throws SodiumException
     */
   
public function id(KeyInterface $key): string
   
{
        return
Lid::encode(
           
$key->getProtocol(),
           
$this->encode($key)
        );
    }
}