pub struct Witness {
pub key_id: String,
pub signature: Vec<u8>,
pub scheme: Option<u16>,
pub authenticator_data: Option<Vec<u8>>,
pub client_data_json: Option<Vec<u8>>,
pub credential_key: Option<Vec<u8>>,
}Expand description
A cosignature: a witness cosignature (never populated here, D67) or,
in OpEntry::author_sig, the author’s own. Present in the format
from the first persisted byte so adding witnessing never rewrites
history.
The scheme and WebAuthn fields are additive (serde(default) plus
skip_serializing_if), so a signature written before D39 serializes
to exactly the bytes it always did and every entry hash containing
one is unchanged.
Fields§
§key_id: StringIdentifier of the witness key that produced Witness::signature.
signature: Vec<u8>Signature over the entry’s content hash.
scheme: Option<u16>Which scheme produced Witness::signature, from scheme.
Absent means scheme::ED25519: entries written before D39
carry no tag, and giving them one would change their bytes and
therefore their hash. An unrecognised value decodes fine on
purpose — an old reader must be able to replay a log containing
a scheme it cannot verify, so the refusal belongs at
verification rather than at decode.
authenticator_data: Option<Vec<u8>>WebAuthn authenticator data, the first half of what a
scheme::WEBAUTHN_ES256 signature covers. Absent for every
other scheme.
client_data_json: Option<Vec<u8>>WebAuthn client data JSON, whose challenge member carries the
OpEntry::signing_hash the human approved. Absent for every
other scheme.
credential_key: Option<Vec<u8>>The credential’s public key as SubjectPublicKeyInfo DER, so a
scheme::WEBAUTHN_ES256 signature can be checked by someone
holding nothing but the log (D45). Absent for every other scheme,
and absent from entries written before D45.
The other two WebAuthn fields are inside what the authenticator
signed, so altering them breaks the signature. This one is the key
the signature is checked against, so altering it forges
nothing — it stops a good entry from verifying. It is covered by
OpEntry::content_hash and therefore by the chain, which is
what makes that substitution detectable; it is not covered by
OpEntry::signing_hash, and calling it signed would be wrong.
Written by the node from the credential it just verified against,
never by the client: getPublicKey() exists on a WebAuthn
registration response only, so a browser holding an assertion
does not have this value to send.
Implementations§
Source§impl Witness
impl Witness
Sourcepub fn ed25519(key_id: impl Into<String>, signature: Vec<u8>) -> Self
pub fn ed25519(key_id: impl Into<String>, signature: Vec<u8>) -> Self
An ed25519 cosignature, the shape every caller before D39 wrote as a struct literal.
Sourcepub fn webauthn_es256(
key_id: impl Into<String>,
signature: Vec<u8>,
authenticator_data: Vec<u8>,
client_data_json: Vec<u8>,
) -> Self
pub fn webauthn_es256( key_id: impl Into<String>, signature: Vec<u8>, authenticator_data: Vec<u8>, client_data_json: Vec<u8>, ) -> Self
A WebAuthn ES256 cosignature (D39), carrying the two byte strings
a verifier needs and cannot reconstruct: the authenticator data,
and the client data JSON whose challenge binds the signature to
one OpEntry::signing_hash.
Sourcepub fn with_credential_key(self, spki_der: Vec<u8>) -> Self
pub fn with_credential_key(self, spki_der: Vec<u8>) -> Self
Attaches the credential public key a verifier needs (D45).
A builder rather than a fifth argument to
Witness::webauthn_es256, because the two values arrive at
different moments: the browser sends the assertion, and the node
adds the key after looking it up to verify against.
Sourcepub fn scheme_id(&self) -> u16
pub fn scheme_id(&self) -> u16
The scheme this signature claims, resolving the pre-D39 absence
to scheme::ED25519. Verifiers should match on this rather
than on Witness::scheme directly, so the two spellings of
ed25519 never diverge.