\Drupal\strata\Crypto RotatingCipher

Seals with the active key and opens with whichever key on the ring works.

A drop-in CipherInterface, so nothing in the pipeline knows a rotation is in progress. The object store, the segment writer and the verifier all take a cipher and this is one.

Sealing only ever uses the active key. A rotation is only finished when nothing is left sealed under a retired key, and sealing with anything but the newest key would mean the rotation could never finish.

The last key that opened something is remembered, because that is the only way to tell a frame that is up to date from one that predates the rotation. There is no key fingerprint in the frame format, so the fact that a retired key was the one that worked IS the signal, and KeyRotation reads it to measure how much of the store still needs the old key.

That memory is per-instance and not thread-safe in any sense; it describes the most recent open() on this object and is meaningless after any other call. Read it immediately or not at all.

A failure to open reports the cipher's own error, not a guess about the key. A wrong key and a corrupt byte both fail the Poly1305 tag identically, so claiming the key is at fault would be a conclusion drawn from an observation that does not support it.

Summary

Methods
Properties
Constants
__construct
id
isAvailable
unavailableReason
seal
open
openedWith
openedWithActiveKey
ring
No public properties found
No public constants found
No protected methods found
No protected properties found
No protected constants found
No private methods found
ciphers
openedWith
ring
No private constants found

Properties

$ciphers

$ciphers : list<\Drupal\strata\Crypto\CipherInterface>

The ciphers, in the order they are tried.

Type

array<int, CipherInterface> —

$openedWith

$openedWith : ?string

Fingerprint of the key that opened the most recent value.

Type

string|null

$ring

$ring : \Drupal\strata\Crypto\KeyRing

Type

KeyRing

Methods

__construct()

__construct(\Drupal\strata\Crypto\KeyRing  $ring) : mixed

Constructs a rotating cipher.

Parameters

\Drupal\strata\Crypto\KeyRing $ring

The keys, active first.

Returns

mixed —

id()

id() : string

The stable identifier recorded in a frame header.

Returns

string —

A short lowercase token such as "xchacha20poly1305" or "none".

isAvailable()

isAvailable() : bool

Whether this cipher can run on this host.

Returns

bool —

TRUE when every extension it needs is present.

unavailableReason()

unavailableReason() : string|null

Why the cipher is unavailable, for the settings form and hook_requirements().

Returns

string|null —

A short human-readable reason, or NULL when the cipher is available.

seal()

seal(string  $plain, string  $associated = '') : string

Seals a frame.

Parameters

string $plain

The bytes to seal. An empty string seals to an empty string, so an absent payload never becomes a non-empty frame.

string $associated

Additional authenticated data - bound to the ciphertext but not encrypted. Strata passes the frame's own digest, which is what makes a frame moved to a different key in the bucket fail to open rather than open as the wrong content.

Returns

string —

The sealed bytes, including whatever nonce and tag the implementation needs to open them.

open()

open(string  $sealed, string  $associated = '') : string

Opens a sealed frame.

Parameters

string $sealed

The sealed bytes.

string $associated

The same additional authenticated data used to seal.

Throws

\Drupal\strata\Crypto\AuthenticationFailure

When no key on the ring opens the value, which cannot be told apart from corruption.

Returns

string —

The original bytes.

openedWith()

openedWith() : string|null

The fingerprint of the key that opened the most recent value.

Returns

string|null —

The fingerprint, or NULL when nothing has been opened or the last open failed.

openedWithActiveKey()

openedWithActiveKey() : bool

Whether the most recent value was opened by the active key.

FALSE means the value predates the rotation and would be re-sealed by finishing it.

Returns

bool —

TRUE when the active key opened it.

ring()

ring() : \Drupal\strata\Crypto\KeyRing

The ring this cipher draws on.

Returns

\Drupal\strata\Crypto\KeyRing —

The ring.