#![cfg_attr(not(test), deny(clippy::print_stdout, clippy::print_stderr))]
#![doc = include_str!("../README.md")]
#![forbid(unsafe_code)]
#![allow(clippy::multiple_crate_versions)]
pub mod algorithm;
pub mod envelope;
pub mod jcs;
pub mod pin_provider;
pub mod signer;
#[cfg(feature = "bls-threshold")]
pub mod signer_bls_threshold;
pub mod signer_external;
#[cfg(feature = "algo-secp256k1")]
pub mod signer_k256;
#[cfg(feature = "algo-p256")]
pub mod signer_p256;
#[cfg(feature = "algo-ed25519")]
pub mod signer_repo_key;
pub mod signer_sigstore;
pub mod statement;
pub mod store;
pub mod verify;
#[cfg(feature = "algo-p256")]
pub mod webauthn;
pub use algorithm::Algorithm;
pub use envelope::{Envelope, PAYLOAD_TYPE_IN_TOTO, Sig, attestation_id, pae_of};
pub use pin_provider::{PinPromptInfo, PinProvider, TtyPinProvider};
pub use signer::Signer;
#[cfg(feature = "bls-threshold")]
pub use signer_bls_threshold::{
KEYID_PREFIX as BLS_THRESHOLD_KEYID_PREFIX, NAMESPACE as BLS_THRESHOLD_NAMESPACE,
PUBLIC_KEY_SIZE as BLS_THRESHOLD_PUBLIC_KEY_SIZE, ThresholdSigner,
aggregate as bls_threshold_aggregate, threshold_for as bls_threshold_for,
trusted_dealer as bls_threshold_trusted_dealer, verify as bls_threshold_verify,
};
pub use signer_external::ExternalSigner;
#[cfg(feature = "algo-ed25519")]
pub use signer_repo_key::{KEYID_PREFIX, RepoKeySigner};
pub use signer_sigstore::SigstoreSigner;
pub use statement::{IN_TOTO_TYPE, Statement, Subject};
pub use verify::{
Reason, Registry, SignatureResult, TrustRoot, VerifyResult, verify_envelope, verify_signature,
};
#[cfg(feature = "algo-p256")]
pub use webauthn::{
WebAuthnPolicy, WebAuthnWrapping, build_client_data_json, verify_webauthn_wrapping,
verify_webauthn_wrapping_with_policy,
};
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("JCS object members must be strictly ascending by key")]
JcsObjectKeysUnsorted,
#[error("predicate body must be a JCS-canonical JSON object (start `{{`, end `}}`)")]
PredicateMustBeJsonObject,
#[error("predicate body is not valid UTF-8")]
PredicateNotUtf8,
#[error("predicate body is not parseable as a JSON object")]
PredicateNotJsonObject,
#[error("DSSE envelope needs at least one signature")]
EnvelopeNeedsAtLeastOneSignature,
#[error("DSSE envelope payloadType must be non-empty")]
PayloadTypeEmpty,
#[error("malformed DSSE envelope")]
MalformedEnvelope,
#[error("DSSE envelope payloadType is not `application/vnd.in-toto+json`")]
UnsupportedPayloadType,
#[error("DSSE envelope has zero signatures")]
EmptySignatures,
#[error("malformed in-toto v1 Statement")]
MalformedStatement,
#[error("Statement has no subject entries")]
SubjectMissing,
#[error("Statement subject has no `blake3` digest")]
SubjectDigestMissing,
#[error("Statement subject digest is not 64 hex characters")]
InvalidDigestLength,
#[error("Statement subject digest is not valid hex")]
InvalidDigestHex,
#[error("external signer keyid is unknown until the first sign call")]
KeyIdNotKnownUntilFirstSign,
#[error("external signer spawn failed: {0}")]
ExternalSignerSpawn(String),
#[error("external signer exited non-zero: {0}")]
ExternalSignerFailed(String),
#[error("external signer response could not be parsed: {0}")]
ExternalSignerBadResponse(String),
#[error("external signer binary path must be absolute: {0}")]
ExternalSignerRelativePath(String),
#[error("external signer timed out during {0} phase")]
ExternalSignerTimeout(&'static str),
#[error("sigstore signer is not yet implemented")]
SigstoreNotImplemented,
#[error("signature algorithm {0} is not enabled in this build")]
AlgorithmNotEnabled(Algorithm),
#[error("envelope is {len} bytes, exceeds the {max}-byte cap")]
EnvelopeTooLarge { len: usize, max: usize },
#[error("attestation store I/O: {0}")]
Io(String),
#[error("secp256k1 key bytes are invalid (zero scalar, >= n, or bad PKCS#8)")]
Secp256k1KeyInvalid,
#[error("secp256k1 signature bytes are malformed (wrong length or not a valid (r, s))")]
Secp256k1SignatureInvalid,
#[error("secp256k1 signature did not verify against the given public key and message")]
Secp256k1VerifyFailed,
#[error("P-256 private key is invalid (scalar out of range or malformed PKCS#8)")]
P256KeyInvalid,
#[error("P-256 signature is malformed (wrong length, non-canonical, or high-S)")]
P256SignatureInvalid,
#[error("P-256 signature verification failed")]
P256VerifyFailed,
#[error(
"WebAuthn clientDataJSON.challenge does not match base64url(PAE) — wrapping not bound to this payload"
)]
WebAuthnChallengeMismatch,
#[error(
"WebAuthn clientDataJSON is not a valid UTF-8 JSON object with string `type` + `challenge`, or `type` is not `webauthn.get`"
)]
WebAuthnBadClientDataJson,
#[error("WebAuthn authenticatorData is malformed (less than 37 bytes or bad base64url)")]
WebAuthnBadAuthenticatorData,
#[error(
"WebAuthn signature did not verify against the reconstructed authenticatorData || SHA256(clientDataJSON)"
)]
WebAuthnSignatureFailed,
#[error("WebAuthn authenticatorData rpIdHash does not match the policy's expected RP ID")]
WebAuthnRpIdMismatch,
#[error("WebAuthn clientDataJSON origin is not in the policy's allow-list")]
WebAuthnOriginNotAllowed,
#[error("WebAuthn assertion did not set the User Present (UP) flag, but policy requires it")]
WebAuthnUserPresenceRequired,
#[error("WebAuthn assertion did not set the User Verified (UV) flag, but policy requires it")]
WebAuthnUserVerificationRequired,
#[error("WebAuthn clientDataJSON crossOrigin is true, but policy disallows cross-origin")]
WebAuthnCrossOriginNotAllowed,
#[error(
"WebAuthn assertion signCount is lower than the previously-seen counter (possible cloned authenticator)"
)]
WebAuthnCounterRollback,
#[error("BLS12-381 threshold partial signature is not a valid wire encoding")]
BlsThresholdPartialDecode,
#[error(
"BLS12-381 threshold recovery failed: fewer than `threshold` distinct partials supplied"
)]
BlsThresholdInsufficientPartials,
#[error("BLS12-381 threshold aggregate public key is malformed (bad G2 compressed encoding)")]
BlsThresholdPublicKeyDecode,
#[error("BLS12-381 threshold signature is malformed (wrong length or bad G1 encoding)")]
BlsThresholdSignatureDecode,
#[error("BLS12-381 threshold signature did not verify against the aggregated public key")]
BlsThresholdVerifyFailed,
}