mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-02 22:41:47 -06:00
* M9: more signature validation algorithms Validation now reads what real signers write, and says when it is weak: - Digests SHA-224, SHA-512/224, SHA-512/256, SHA3-224/256/384/512 and RIPEMD-160, beside SHA-1 and SHA-2. - RSA PKCS#1 v1.5 for every digest, in `rsa_pad`: the one expected encoding is built and compared byte for byte, with or without the DigestInfo's NULL (RFC 8017 App. B.1). A signature over the bare digest, which doesn't say which hash it uses, is refused. The signature value must be below the modulus (RFC 8017 §5.2.2); s and s + n both verified before. - RSA-PSS with the hash, MGF1 hash and salt length the signature declares. - ECDSA as DER, non-minimal DER or raw r||s on P-256, P-384, P-521 and brainpoolP256r1/P384r1/P512r1 (BSI "plain" ECDSA OIDs too); brainpoolP512r1 is hand-written on crypto-bigint because no RustCrypto crate has it. - Ed25519 (RFC 8419), and the legacy adbe.x509.rsa_sha1 format. - An algorithm PdfCraft can't check is Unknown, never Invalid. - SHA-1 and RIPEMD-160 signatures validate, but the signature's details say the algorithm is weak (wording pinned by tests). - Encoding irregularities that were tolerated are listed in the details (`verify_noting`; `verify` keeps its signature). Found while testing, each with a regression test that failed before the fix: a brainpoolP512r1 public key with a coordinate >= p panicked inside crypto-bigint's `sub_mod` (the certificate comes from the PDF); it is refused now, and the point at infinity is an invalid signature, not an error. Vectors were made with OpenSSL (tests/data/README.md has the commands). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * Update comment to clarify MAC digest restrictions Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * M9: a legacy x509.rsa_sha1 signature whose key the verifier rejects is Invalid; only unsupported keys are "can't check yet" Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
51 lines
1.6 KiB
Rust
51 lines
1.6 KiB
Rust
//! Digital signatures (execution plan M9; ISO 32000-2 §12.8; ETSI EN 319 142 PAdES).
|
|
//!
|
|
//! - [`der`], [`x509`], [`cms`], [`pkcs12`], [`keys`]: the cryptographic formats, on RustCrypto
|
|
//! primitives (RSA private-key operations use aws-lc-rs on native targets, ADR-0009).
|
|
//! - [`pdf`]: signature fields in a document — listing and validating them, and signing
|
|
//! (PAdES B-B, `ETSI.CAdES.detached`) with an incremental save.
|
|
|
|
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
|
|
|
pub mod cms;
|
|
pub mod der;
|
|
pub mod dss;
|
|
mod ec512;
|
|
#[cfg(target_os = "macos")]
|
|
pub mod keychain;
|
|
pub mod keys;
|
|
pub mod pdf;
|
|
pub mod pkcs12;
|
|
pub mod revocation;
|
|
mod rsa_pad;
|
|
pub mod timestamp;
|
|
#[cfg(target_os = "windows")]
|
|
pub mod windows;
|
|
pub mod x509;
|
|
|
|
pub use der::Time;
|
|
pub use keys::{DigestAlg, PrivateKey, PublicKey};
|
|
pub use pdf::{
|
|
Appearance, DigestCache, Modification, SignOptions, SignatureInfo, Status, TrustStore, list as signatures, sign, sign_with_timestamp,
|
|
timestamp_document, validate,
|
|
};
|
|
pub use pkcs12::DigitalId;
|
|
pub use timestamp::{TimestampAuthority, TimestampQuery, TimestampToken};
|
|
pub use x509::{Certificate, Name};
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum SignError {
|
|
#[error("malformed data: {0}")]
|
|
Malformed(String),
|
|
#[error("not supported: {0}")]
|
|
Unsupported(String),
|
|
#[error("the password is incorrect")]
|
|
WrongPassword,
|
|
#[error("{0}")]
|
|
Crypto(String),
|
|
#[error("{0}")]
|
|
Pdf(String),
|
|
#[error(transparent)]
|
|
Cos(#[from] pdfcraft_cos::CosError),
|
|
}
|