Public API (non-internal, non-plugin implementations)#
// Structure of documents
└── src/
└── Encryption/
├── EncryptedValue.php
├── EncryptionException.php
├── EncryptionKeyId.php
├── EncryptorInterface.php
└── KeyManagement/
├── KeyActivatorException.php
├── KeyActivatorInterface.php
├── KeyGeneratorException.php
├── KeyGeneratorInterface.php
├── KeyPrunePlan.php
├── KeyPruneResult.php
├── KeyPrunerException.php
├── KeyPrunerInterface.php
├── KeyRotationException.php
├── KeyRotationOptions.php
├── KeyRotationPlan.php
├── KeyRotationResult.php
├── KeyRotatorInterface.php
├── KeyUsageTrackerInterface.php
├── Observers/
│ ├── KeyActivatedObserverInterface.php
│ ├── KeyDeletedObserverInterface.php
├── Port/
│ └── KeyRegistryException.php
│ └── KeyRegistryInterface.php
│ └── KeyUsageMapping.php
│ └── KeyUsageProviderInterface.php
│ └── MutableKeyRegistryInterface.php
└── KeyTransfer/
├── KeyTransferException.php
├── KeyTransferInterface.php
├── Port/
│ └── KeyPackageCodecException.php
│ └── KeyPackageCodecInterface.php
│ └── KeyTransferPayloadHandlerException.php
│ └── KeyTransferPayloadHandlerInterface.php
└── Sodium/
└── Exception/
├── SodiumKeyPairException.php
├── SodiumKeyPairNotFoundException.php
├── SodiumKeyPairOperationException.php
└── SodiumKeyPairReadRepositoryInterface.php
└── SodiumKeyPairWriteRepositoryInterface.php
Path: /src/Encryption/EncryptedValue.php#
namespace Drupal\easy_encryption\Encryption;
/**
* Immutable value object representing encrypted data with key metadata.
*
* The ciphertext is stored internally as raw binary data. Use
* getCiphertextHex() for storage in configuration, databases, or files that
* expect string data.
*
* @immutable
*/
final class EncryptedValue
{
public function __construct(
private readonly string $ciphertext,
public readonly EncryptionKeyId $keyId,
) {
/* ... */
}
/**
* Returns the raw binary ciphertext.
*
* @return string
* The binary ciphertext.
*/
public function getCiphertext(): string
{
/* ... */
}
/**
* Returns hex-encoded ciphertext for storage.
*
* Use this method when persisting encrypted data to configuration, databases,
* or files. To reconstruct the object from stored hex, use
* EncryptedValue::fromHex().
*
* @return string
* The hex-encoded ciphertext.
*/
public function getCiphertextHex(): string
{
/* ... */
}
/**
* Creates an EncryptedValue from hex-encoded ciphertext.
*
* Use this factory method when reading encrypted data from storage that was
* previously encoded with getCiphertextHex().
*
* @param string $hex
* The hex-encoded ciphertext.
* @param string $keyId
* The key pair identifier.
*
* @return static
* A new EncryptedValue instance.
*
* @throws \InvalidArgumentException
* If the ciphertext is empty or invalid, or the key ID is empty.
*/
public static function fromHex(string $hex, string $keyId): self
{
/* ... */
}
}
Path: /src/Encryption/EncryptionException.php#
namespace Drupal\easy_encryption\Encryption;
/**
* Thrown when an encryption or decryption operation fails.
*/
class EncryptionException extends \RuntimeException
{
}
Path: /src/Encryption/EncryptionKeyId.php#
namespace Drupal\easy_encryption\Encryption;
/**
* Value object representing an Encryption key identifier.
*
* Instances are immutable and always contain a safe, normalized identifier
* consisting only of lowercase letters, digits, and underscores.
*
* This is a shared domain concept used by both key management (generation,
* rotation, transfer) and encryption (encryptors/ciphertexts). It is not the
* same as a Key module Key entity ID.
*/
final class EncryptionKeyId implements \Stringable
{
private const NORMALIZED_PATTERN = '/^[a-z0-9_]+$/';
/**
* Creates a EncryptionKeyId from arbitrary input by normalizing it.
*
* Normalization rules:
* - lowercases
* - replaces any run of characters not in [a-z0-9_] with a single underscore
* - trims leading/trailing underscores.
*/
public static function fromUserInput(string $keyId): self
{
/* ... */
}
/**
* Creates a EncryptionKeyId from an already-normalized value.
*/
public static function fromNormalized(string $keyId): self
{
/* ... */
}
/**
* {@inheritdoc}
*/
public function __toString(): string
{
/* ... */
}
}
Path: /src/Encryption/EncryptorInterface.php#
namespace Drupal\easy_encryption\Encryption;
/**
* Defines an interface for encrypting and decrypting sensitive data.
*/
interface EncryptorInterface
{
/**
* Encrypts a value.
*
* @param string $value
* The plaintext value to encrypt.
*
* @return \Drupal\easy_encryption\Encryption\EncryptedValue
* The encrypted value with metadata.
*
* @throws \InvalidArgumentException
* If the value is empty.
* @throws \Drupal\easy_encryption\Encryption\EncryptionException
* If encryption fails.
*/
public function encrypt(
#[\SensitiveParameter]
string $value,
): EncryptedValue;
/**
* Decrypts a value.
*
* @param \Drupal\easy_encryption\Encryption\EncryptedValue $value
* The encrypted value to decrypt.
*
* @return string
* The decrypted plaintext.
*
* @throws \Drupal\easy_encryption\Encryption\EncryptionException
* If decryption fails.
*/
public function decrypt(EncryptedValue $value): string;
/**
* Validates that encryption and decryption work correctly.
*
* Implementations may skip this test silently if the environment does not
* support decryption (for example, when only a public key is available).
*
* @throws \Drupal\easy_encryption\Encryption\EncryptionException
* If the self-test fails.
*/
public function selfTest(): void;
}
Path: /src/KeyManagement/KeyActivatorException.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Thrown when key activation fails.
*
* This exception is intended to be thrown by the KeyActivator application
* service, so callers do not need to depend on the underlying repository
* exception hierarchy.
*/
final class KeyActivatorException extends \RuntimeException
{
/**
* Creates an exception for a failed encryption key activation.
*
* @param string $keyId
* The key identifier that could not be activated.
* @param \Throwable|null $previous
* (optional) The underlying exception that caused activation to fail.
*
* @return self
* The exception instance.
*/
public static function activationFailed(string $keyId, ?\Throwable $previous = null): self
{
/* ... */
}
}
Path: /src/KeyManagement/KeyActivatorInterface.php#
namespace Drupal\easy_encryption\KeyManagement;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Application service for activating an encryption key.
*
* Activation sets which encryption key ID is considered active for new
* encryption operations on the site.
*/
interface KeyActivatorInterface
{
/**
* Activates an existing encryption key by ID.
*
* Activation MUST be allowed when private key is missing, as long as a public
* key exists (encrypt-only environments).
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId $keyId
* The encryption key identifier.
*
* @throws \Drupal\easy_encryption\KeyManagement\KeyActivatorException
* Thrown when activation fails.
*/
public function activate(EncryptionKeyId $keyId): void;
}
Path: /src/KeyManagement/KeyGeneratorException.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Thrown when key generation or activation fails.
*/
final class KeyGeneratorException extends \RuntimeException
{
/**
* Creates an exception for a failed encryption key generation.
*
* @param string|null $keyId
* The key identifier, if one was known at the time of failure.
* @param \Throwable|null $previous
* (optional) The underlying exception that caused generation to fail.
*
* @return self
* The exception instance.
*/
public static function generationFailed(?string $keyId = null, ?\Throwable $previous = null): self
{
/* ... */
}
}
Path: /src/KeyManagement/KeyGeneratorInterface.php#
namespace Drupal\easy_encryption\KeyManagement;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Application service for generating and activating encryption keys.
*
* This service returns key identifiers, not key material, to keep the
* application layer decoupled from the underlying cryptographic library.
*/
interface KeyGeneratorInterface
{
/**
* Generates and persists an encryption key.
*
* If no ID is provided, the generator MUST create a new identifier.
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId|null $keyId
* (optional) The encryption key identifier to use.
*
* @return \Drupal\easy_encryption\Encryption\EncryptionKeyId
* The encryption key identifier that was generated.
*
* @throws \Drupal\easy_encryption\KeyManagement\KeyGeneratorException
* Thrown when the encryption key generation fails.
*/
public function generate(?EncryptionKeyId $keyId = null): EncryptionKeyId;
}
Path: /src/KeyManagement/KeyPrunePlan.php#
namespace Drupal\easy_encryption\KeyManagement;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Describes what would be pruned without performing changes.
*
* @immutable
*/
final class KeyPrunePlan
{
/**
* Construct a KeyPrunePlan.
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId|null $activeKeyId
* The active encryption key ID, if any.
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId[] $toDelete
* Encryption key IDs that would be deleted.
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId[] $referenced
* Encryption key IDs referenced, in use.
*/
public function __construct(
public readonly ?EncryptionKeyId $activeKeyId,
public readonly array $toDelete = [],
public readonly array $referenced = [],
) {
/* ... */
}
}
Path: /src/KeyManagement/KeyPruneResult.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Result of pruning unused encryption keys.
*
* @immutable
*/
final class KeyPruneResult
{
/**
* Construct a KeyPruneResult.
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId[] $deleted
* Deleted encryption key IDs.
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId[] $failed
* Encryption key IDs that failed deletion.
*/
public function __construct(
public readonly array $deleted = [],
public readonly array $failed = [],
) {
/* ... */
}
}
Path: /src/KeyManagement/KeyPrunerException.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Thrown when pruning unused encryption keys cannot be planned or started.
*/
final class KeyPrunerException extends \RuntimeException
{
/**
* Creates an exception for failures while building a prune plan.
*
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function planFailed(?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for failures that prevent pruning from running at all.
*
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function pruneFailed(?\Throwable $previous = null): self
{
/* ... */
}
}
Path: /src/KeyManagement/KeyPrunerInterface.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Application service for pruning unused encryption keys.
*/
interface KeyPrunerInterface
{
/**
* Builds a non-mutating plan describing what would be pruned.
*
* @throws \Drupal\easy_encryption\KeyManagement\KeyPrunerException
* Thrown when the plan cannot be computed.
*/
public function planPruning(): KeyPrunePlan;
/**
* Deletes unused encryption keys.
*
* This operation returns partial results: failures are reported in the result
* object rather than aborting the whole run.
*
* @return \Drupal\easy_encryption\KeyManagement\KeyPruneResult
* The prune result.
*
* @throws \Drupal\easy_encryption\KeyManagement\KeyPrunerException
* Thrown when the prune operation cannot start
* (for example, planning fails).
*/
public function pruneUnused(): KeyPruneResult;
}
Path: /src/KeyManagement/KeyRotationException.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Exception is thrown by key rotation workflows.
*/
final class KeyRotationException extends \RuntimeException
{
/**
* Creates an exception for failures while building a rotation plan.
*
* Planning is a non-mutating operation (used for dry-run previews). This
* exception indicates that the system could not compute a plan, typically due
* to storage access errors or unexpected runtime issues.
*
* @param \Throwable|null $previous
* (optional) The underlying exception that caused planning to fail.
*
* @return self
* The exception instance.
*/
public static function planFailed(?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for failures while rotating the active enc. keys.
*
* This exception indicates that generating or activating a new encryption key
* failed.
*
* @param \Throwable|null $previous
* (optional) The underlying exception that caused rotation to fail.
*
* @return self
* The exception instance.
*/
public static function rotateFailed(?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception when re-encryption cannot be performed.
*
* This is used when the operation is not possible in the current environment,
* for example because the private key is not available and existing encrypted
* values therefore cannot be decrypted for re-encryption.
*
* @param string $reason
* A human-readable explanation of why re-encryption cannot be performed.
* @param \Throwable|null $previous
* (optional) The underlying exception, if any.
*
* @return self
* The exception instance.
*/
public static function reencryptNotPossible(string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception when one or more credentials fail to re-encrypt.
*
* @param int $failedCount
* The number of credentials that failed to re-encrypt.
* @param \Throwable|null $previous
* (optional) The underlying exception, if any.
*
* @return self
* The exception instance.
*/
public static function reencryptFailed(int $failedCount, ?\Throwable $previous = null): self
{
/* ... */
}
}
Path: /src/KeyManagement/KeyRotationOptions.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Options for the rotation operation.
*/
final class KeyRotationOptions
{
public function __construct(
public readonly bool $reencryptKeys = false,
public readonly bool $failOnReencryptErrors = true,
) {
/* ... */
}
}
Path: /src/KeyManagement/KeyRotationPlan.php#
namespace Drupal\easy_encryption\KeyManagement;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Describes what would be re-encrypted without performing changes.
*
* @immutable
*/
final class KeyRotationPlan
{
public function __construct(
public readonly ?EncryptionKeyId $activeKeyId,
public readonly int $total = 0,
public readonly int $toUpdate = 0,
public readonly int $toSkip = 0,
) {
/* ... */
}
}
Path: /src/KeyManagement/KeyRotationResult.php#
namespace Drupal\easy_encryption\KeyManagement;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Result of rotating the active encryption key and optionally re-encrypting.
*
* @immutable
*/
final class KeyRotationResult
{
public function __construct(
public readonly ?EncryptionKeyId $oldActiveKeyId,
public readonly EncryptionKeyId $newActiveKeyId,
public readonly int $updated = 0,
public readonly int $skipped = 0,
public readonly int $failed = 0,
) {
/* ... */
}
}
Path: /src/KeyManagement/KeyRotatorInterface.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Application service for planning and performing encryption key rotation.
*/
interface KeyRotatorInterface
{
/**
* Builds a non-mutating plan describing what would change.
*
* @throws \Drupal\easy_encryption\KeyManagement\KeyRotationException
* If the plan cannot be computed.
*/
public function plan(bool $includeReencryptCounts = true): KeyRotationPlan;
/**
* Rotates the active encryption key and optionally re-encrypts credentials.
*
* @throws \Drupal\easy_encryption\KeyManagement\KeyRotationException
* If rotation fails, or re-encryption fails and failOnReencryptErrors
* is TRUE.
*/
public function rotate(KeyRotationOptions $options): KeyRotationResult;
}
Path: /src/KeyManagement/KeyUsageTrackerInterface.php#
namespace Drupal\easy_encryption\KeyManagement;
/**
* Public API for tracking encryption key usage across the entire system.
*/
interface KeyUsageTrackerInterface
{
/**
* Returns the aggregated mapping of all consumers and their encryption keys.
*
* @return array{result: array<string, \Drupal\easy_encryption\KeyManagement\Port\KeyUsageMapping>, cacheability: \Drupal\Core\Cache\CacheableDependencyInterface}
* The 'result' is keyed by consumer ID.
* 'cacheability' applies to the entire set.
*/
public function getKeyUsageMapping(): array;
}
Path: /src/KeyManagement/Observers/KeyActivatedObserverInterface.php#
namespace Drupal\easy_encryption\KeyManagement\Observers;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Contract for encryption key activation observers.
*/
interface KeyActivatedObserverInterface
{
/**
* Act when an encryption key gets activated.
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId $activeKeyId
* The ID of the activated encryption key.
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId|null $previousKeyId
* The ID of the previously active key if there was any.
*/
public function onKeyActivation(EncryptionKeyId $activeKeyId, ?EncryptionKeyId $previousKeyId): void;
}
Path: /src/KeyManagement/Observers/KeyDeletedObserverInterface.php#
namespace Drupal\easy_encryption\KeyManagement\Observers;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Contract for encryption key deletion observers.
*/
interface KeyDeletedObserverInterface
{
/**
* Act when an encryption key gets deleted.
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId $keyId
* The ID of the activated encryption key.
*/
public function onKeyDeletion(EncryptionKeyId $keyId): void;
}
Path: /src/KeyManagement/Port/KeyRegistryException.php#
namespace Drupal\easy_encryption\KeyManagement\Port;
/**
* Thrown when the encryption key registry cannot be read or written.
*
* This exception is intended to be thrown by KeyRegistryInterface
* implementations, so callers do not need to depend on underlying storage
* exceptions (config, database, etc.).
*/
final class KeyRegistryException extends \RuntimeException
{
/**
* Creates an exception for failures while reading registry data.
*
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function readFailed(?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for failures while registering a key id.
*
* @param string $keyId
* The encryption key identifier that could not be registered.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function registerFailed(string $keyId, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for failures while unregistering a key id.
*
* @param string $keyId
* The encryption key identifier that could not be registered.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function unregisterFailed(string $keyId, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for failures while setting the active key id.
*
* @param string $keyId
* The encryption key identifier that could not be activated.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function setActiveFailed(string $keyId, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception when attempting to set an active key that is unknown.
*
* @param string $keyId
* The encryption key identifier.
*/
public static function unknownKey(string $keyId): self
{
/* ... */
}
}
Path: /src/KeyManagement/Port/KeyRegistryInterface.php#
namespace Drupal\easy_encryption\KeyManagement\Port;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Read-only registry of known encryption keys and the active key.
*/
interface KeyRegistryInterface
{
/**
* Lists encryption key IDs known to this site.
*
* @return array{result: \Drupal\easy_encryption\Encryption\EncryptionKeyId[], cacheability: \Drupal\Core\Cache\CacheableDependencyInterface}
* Known key ids plus cacheability metadata.
*
* @throws \Drupal\easy_encryption\KeyManagement\Port\KeyRegistryException
* When registry storage cannot be read.
*/
public function listKnownKeyIds(): array;
/**
* Returns the active encryption key id, if any.
*
* @return array{result: \Drupal\easy_encryption\Encryption\EncryptionKeyId|null, cacheability: \Drupal\Core\Cache\CacheableDependencyInterface}
* Active key id plus cacheability metadata.
*
* @throws \Drupal\easy_encryption\KeyManagement\Port\KeyRegistryException
* When registry storage cannot be read.
*/
public function getActiveKeyId(): array;
/**
* Checks whether a key id is known to the registry.
*
* @return array{result: bool, cacheability: \Drupal\Core\Cache\CacheableDependencyInterface}
* TRUE if known plus cacheability metadata.
*
* @throws \Drupal\easy_encryption\KeyManagement\Port\KeyRegistryException
* When registry storage cannot be read.
*/
public function isKnown(EncryptionKeyId $key_id): array;
}
Path: /src/KeyManagement/Port/KeyUsageMapping.php#
namespace Drupal\easy_encryption\KeyManagement\Port;
use Drupal\Core\Cache\CacheBackendInterface as CacheBackendInterface;
use Drupal\Core\Cache\CacheableDependencyInterface as CacheableDependencyInterface;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Represents an encryption key used by a specific consumer with cacheability.
*/
final class KeyUsageMapping implements CacheableDependencyInterface
{
/**
* Constructs a new object.
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId $keyId
* The encryption key being used.
* @param \Drupal\Core\Cache\CacheableDependencyInterface|null $cacheability
* Optional cacheability metadata for this specific mapping.
*/
public function __construct(
public readonly EncryptionKeyId $keyId,
private readonly ?CacheableDependencyInterface $cacheability = null,
) {
/* ... */
}
/**
* {@inheritdoc}
*/
public function getCacheContexts(): array
{
/* ... */
}
/**
* {@inheritdoc}
*/
public function getCacheTags(): array
{
/* ... */
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge(): int
{
/* ... */
}
}
Path: /src/KeyManagement/Port/KeyUsageProviderInterface.php#
namespace Drupal\easy_encryption\KeyManagement\Port;
/**
* Interface for reporters that identify encryption key dependencies.
*/
interface KeyUsageProviderInterface
{
/**
* Returns a mapping of consumers.
*
* @return array{result: array<string, \Drupal\easy_encryption\KeyManagement\Port\KeyUsageMapping>, cacheability: \Drupal\Core\Cache\CacheableDependencyInterface}
* The 'result' is keyed by consumer ID. 'cacheability' applies to the
* entire set.
*/
public function getKeyUsageMapping(): array;
}
Path: /src/KeyManagement/Port/MutableKeyRegistryInterface.php#
namespace Drupal\easy_encryption\KeyManagement\Port;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Mutable registry of known encryption keys and the active key.
*/
interface MutableKeyRegistryInterface
{
/**
* Registers a key id as known.
*
* Implementations must be idempotent.
*
* @throws \Drupal\easy_encryption\KeyManagement\Port\KeyRegistryException
* When the registry cannot be written.
*/
public function register(EncryptionKeyId $key_id): void;
/**
* Unregisters a key id from the known list.
*
* @throws \Drupal\easy_encryption\KeyManagement\Port\KeyRegistryException
* When the registry cannot be written.
*/
public function unregister(EncryptionKeyId $key_id): void;
/**
* Sets the active encryption key id.
*
* Implementations should either:
* - implicitly register the key id if missing, or
* - throw unknownKey() if the key id is not registered.
*
* Pick one policy and keep it consistent. For export/import and for
* predictable behavior, I recommend: throw if unknown.
*
* @throws \Drupal\easy_encryption\KeyManagement\Port\KeyRegistryException
* When the registry cannot be written or the key is unknown.
*/
public function setActive(EncryptionKeyId $key_id): void;
}
Path: /src/KeyTransfer/KeyTransferException.php#
namespace Drupal\easy_encryption\KeyTransfer;
/**
* Thrown when key transfer operations fail at the application layer.
*/
final class KeyTransferException extends \RuntimeException
{
/**
* Creates an exception for an invalid package.
*
* @param string $reason
* Human-readable validation error.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function invalidPackage(string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception when no payload handler supports the package payload.
*
* @param string $reason
* Human-readable explanation, for example "Unsupported format foo".
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function unsupportedPayload(string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for export failures.
*
* @param string $keyId
* The key id that was being exported.
* @param string $reason
* Human-readable explanation of the failure.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function exportFailed(string $keyId, string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for import failures.
*
* @param string $reason
* Human-readable explanation of the failure.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function importFailed(string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for failures while activating a key after import.
*
* @param string $keyId
* The imported key id that could not be activated.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function activationFailed(string $keyId, ?\Throwable $previous = null): self
{
/* ... */
}
}
Path: /src/KeyTransfer/KeyTransferInterface.php#
namespace Drupal\easy_encryption\KeyTransfer;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Application service for importing/exporting keys as portable packages.
*/
interface KeyTransferInterface
{
/**
* Exports a known key as a portable package string.
*
* @throws \Drupal\easy_encryption\KeyTransfer\KeyTransferException
* When export fails or cannot be performed.
*/
public function exportKey(EncryptionKeyId $keyId): string;
/**
* Imports a portable package string & optionally activates the imported key.
*
* @return array{key_id: \Drupal\easy_encryption\Encryption\EncryptionKeyId, activated: bool}
* The imported key id and whether activation was requested/performed.
*
* @throws \Drupal\easy_encryption\KeyTransfer\KeyTransferException
* When import fails or the package is invalid/unsupported.
*/
public function importKey(string $package, bool $activate = false): array;
}
Path: /src/KeyTransfer/Port/KeyPackageCodecException.php#
namespace Drupal\easy_encryption\KeyTransfer\Port;
/**
* Thrown when a key package cannot be encoded or decoded.
*/
final class KeyPackageCodecException extends \RuntimeException
{
/**
* Creates an exception for failures while encoding a key package.
*
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function encodeFailed(?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for failures while decoding a key package.
*
* @param string $reason
* Human-readable error describing what part of decoding failed.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function decodeFailed(string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
}
Path: /src/KeyTransfer/Port/KeyPackageCodecInterface.php#
namespace Drupal\easy_encryption\KeyTransfer\Port;
/**
* Encodes/decodes key transfer packages (envelope only).
*
* The codec is format-agnostic: algorithm-specific data is carried in the
* payload structure and interpreted by payload handlers.
*/
interface KeyPackageCodecInterface
{
/**
* Encodes the package structure into a portable string.
*
* @param array<string,mixed> $data
* Package data, typically with keys like 'key_id' and 'payload'.
*
* @throws \Drupal\easy_encryption\KeyTransfer\Port\KeyPackageCodecException
* When the package cannot be encoded.
*/
public function encode(array $data): string;
/**
* Decodes a portable string into the package structure.
*
* @return array<string,mixed>
* Package data.
*
* @throws \Drupal\easy_encryption\KeyTransfer\Port\KeyPackageCodecException
* When the package cannot be decoded.
*/
public function decode(string $text): array;
}
Path: /src/KeyTransfer/Port/KeyTransferPayloadHandlerException.php#
namespace Drupal\easy_encryption\KeyTransfer\Port;
/**
* Thrown when a key transfer payload handler cannot import or export a payload.
*/
final class KeyTransferPayloadHandlerException extends \RuntimeException
{
/**
* Creates an exception for invalid payload content.
*
* @param string $reason
* Human-readable validation error.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function invalidPayload(string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception when exporting a key is not possible.
*
* @param string $keyId
* The key id that could not be exported.
* @param string $reason
* Human-readable explanation.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function exportNotPossible(string $keyId, string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception when importing a key is not possible.
*
* @param string $keyId
* The key id that could not be imported.
* @param string $reason
* Human-readable explanation.
* @param \Throwable|null $previous
* (optional) The underlying exception.
*/
public static function importNotPossible(string $keyId, string $reason, ?\Throwable $previous = null): self
{
/* ... */
}
}
Path: /src/KeyTransfer/Port/KeyTransferPayloadHandlerInterface.php#
namespace Drupal\easy_encryption\KeyTransfer\Port;
use Drupal\easy_encryption\Encryption\EncryptionKeyId as EncryptionKeyId;
/**
* Port for handling algorithm-specific key transfer payloads.
*
* Implementations are discovered via tagged services.
*
* @template TPayload of array
*/
interface KeyTransferPayloadHandlerInterface
{
/**
* Returns TRUE if this handler supports importing the given payload.
*
* This method must be defensive: it can receive any decoded payload data.
*
* @param array $payload
* Payload data.
*
* @phpstan-assert-if-true TPayload $payload
*/
public function applies(array $payload): bool;
/**
* Exports key material as payload data.
*
* @return TPayload
* Payload data for this handler.
*
* @throws \Drupal\easy_encryption\KeyTransfer\Port\KeyTransferPayloadHandlerException
* When export cannot be performed.
*/
public function exportPayload(EncryptionKeyId $keyId): array;
/**
* Imports key material from payload data for the provided key id.
*
* This method must not activate the key. Activation is application logic.
*
* @param \Drupal\easy_encryption\Encryption\EncryptionKeyId $keyId
* Key identifier from the package envelope.
* @param TPayload $payload
* Payload data for this handler.
*
* @throws \Drupal\easy_encryption\KeyTransfer\Port\KeyTransferPayloadHandlerException
* When import cannot be performed.
*/
public function importPayload(EncryptionKeyId $keyId, array $payload): void;
}
Path: /src/Sodium/Exception/SodiumKeyPairException.php#
namespace Drupal\easy_encryption\Sodium\Exception;
/**
* Base exception for sodium key pair repository failures.
*
* All exceptions thrown by Sodium repositories
* implementations SHOULD extend this class so that callers can
* catch and handle repository errors in a generic way.
*/
class SodiumKeyPairException extends \RuntimeException
{
/**
* Creates an exception for a key pair that was not found.
*
* @param string $id
* The key pair identifier.
*
* @return self
* The exception instance.
*/
public static function notFound(string $id): self
{
/* ... */
}
}
Path: /src/Sodium/Exception/SodiumKeyPairNotFoundException.php#
namespace Drupal\easy_encryption\Sodium\Exception;
/**
* Thrown when a requested key pair cannot be found.
*/
final class SodiumKeyPairNotFoundException extends SodiumKeyPairException
{
/**
* Creates an exception for a missing key pair identifier.
*
* @param string $id
* The missing key pair identifier.
* @param \Throwable|null $previous
* (optional) The previous throwable.
*
* @return static
* The exception instance.
*/
public static function forId(string $id, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for a missing active key pair.
*
* @return self
* The exception instance.
*/
public static function forActive(): self
{
/* ... */
}
}
Path: /src/Sodium/Exception/SodiumKeyPairOperationException.php#
namespace Drupal\easy_encryption\Sodium\Exception;
/**
* Thrown when a key pair operation fails.
*
* This exception covers failures related to key pair generation, storage,
* retrieval, deletion, and cryptographic operations that depend on key
* availability or validity.
*/
final class SodiumKeyPairOperationException extends SodiumKeyPairException
{
/**
* Creates an exception for a failed generation or activation.
*
* @param \Throwable|null $previous
* (optional) The previous throwable.
*
* @return self
* The exception instance.
*/
public static function generationFailed(?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for a failed load of an existing key pair.
*
* @param string $id
* The key pair identifier.
* @param \Throwable|null $previous
* (optional) The previous throwable.
*
* @return self
* The exception instance.
*/
public static function loadFailed(string $id, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for an attempt to delete the active key pair.
*
* @param string $id
* The key pair identifier.
*
* @return self
* The exception instance.
*/
public static function cannotDeleteActive(string $id): self
{
/* ... */
}
/**
* Creates an exception for a failed deletion operation.
*
* @param string $id
* The key pair identifier.
* @param \Throwable|null $previous
* (optional) The previous throwable.
*
* @return self
* The exception instance.
*/
public static function deleteFailed(string $id, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception for a failed decryption operation.
*
* @param string $keyId
* The key pair identifier.
* @param \Throwable|null $previous
* (optional) The previous throwable.
*
* @return self
* The exception instance.
*/
public static function decryptionFailed(string $keyId, ?\Throwable $previous = null): self
{
/* ... */
}
/**
* Creates an exception when the private key is not available.
*
* This typically occurs in encrypt-only environments where the private key
* has been intentionally excluded for security reasons.
*
* @param string $keyId
* The key pair identifier.
*
* @return self
* The exception instance.
*/
public static function privateKeyNotAvailable(string $keyId): self
{
/* ... */
}
/**
* Creates an exception when the public key is not available.
*
* @param string $keyId
* The key pair identifier.
*
* @return self
* The exception instance.
*/
public static function publicKeyNotAvailable(string $keyId): self
{
/* ... */
}
/**
* Creates an exception when keypair construction fails.
*
* This occurs when sodium_crypto_box_keypair_from_secretkey_and_publickey()
* throws an exception, typically indicating key corruption or mismatch.
*
* @param string $keyId
* The key pair identifier.
* @param \Throwable $previous
* The previous throwable from the Sodium operation.
*
* @return self
* The exception instance.
*/
public static function keypairConstructionFailed(string $keyId, \Throwable $previous): self
{
/* ... */
}
}
Path: /src/Sodium/SodiumKeyPairReadRepositoryInterface.php#
namespace Drupal\easy_encryption\Sodium;
/**
* Read-only repository for sodium key pairs.
*/
interface SodiumKeyPairReadRepositoryInterface
{
/**
* Returns a key pair by its identifier.
*
* Implementations MAY omit the private key when the current environment is
* not allowed to perform decryption.
*
* @throws \Drupal\easy_encryption\Sodium\Exception\SodiumKeyPairNotFoundException
* @throws \Drupal\easy_encryption\Sodium\Exception\SodiumKeyPairOperationException
*/
public function getKeyPairById(string $id): SodiumKeyPair;
/**
* Returns identifiers for all stored key pairs.
*
* Implementations MUST return identifiers for all key pairs known to
* the repository, regardless of whether the corresponding private
* keys are available in the current environment.
*
* @return string[]
* An array of key pair identifiers.
*/
public function listKeyPairIds(): array;
}
Path: /src/Sodium/SodiumKeyPairWriteRepositoryInterface.php#
namespace Drupal\easy_encryption\Sodium;
/**
* Write repository for sodium key pairs.
*/
interface SodiumKeyPairWriteRepositoryInterface
{
/**
* Generates and persists a new key pair with the given id.
*
* @throws \Drupal\easy_encryption\Sodium\Exception\SodiumKeyPairOperationException
* If generation or persistence fails.
*/
public function generateKeyPair(string $id): void;
/**
* Deletes persisted key material for the given id.
*
* @throws \Drupal\easy_encryption\Sodium\Exception\SodiumKeyPairOperationException
* If deletion fails.
*/
public function deleteKeyPair(string $id): void;
/**
* Writes/updates public key material.
*
* @throws \Drupal\easy_encryption\Sodium\Exception\SodiumKeyPairOperationException
* If persistence fails.
*/
public function upsertPublicKey(string $id, string $publicKeyBin): void;
/**
* Writes/updates private key material.
*
* @throws \Drupal\easy_encryption\Sodium\Exception\SodiumKeyPairOperationException
* If persistence fails.
*/
public function upsertPrivateKey(string $id, string $privateKeyBin): void;
}
File Statistics
- Size: 40.72 KB
- Lines: 1672
File: core/api.md