//! Pure signing and public-key export over decrypted field values. No storage or grant policy. use super::keys; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Error { pub kind: &'static str, pub message: &'static str, } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(self.message) } } impl std::error::Error for Error {} pub type Result = std::result::Result; pub(super) fn error(kind: &'static str, message: &'static str) -> Error { Error { kind, message } } pub(super) fn invalid_key() -> Error { error("invalid_key", "invalid signing key encoding or length") } #[derive(Debug, serde::Serialize)] pub struct SignResult { pub signature: String, #[serde(skip_serializing_if = "Option::is_none")] pub bytes: Option>, } /// Sign bytes. RSA requires explicit, matching padding and digest parameters. pub fn sign( value: &str, passphrase: Option<&str>, format: &str, payload: &[u8], output: &str, padding: Option<&str>, hash: Option<&str>, ) -> Result { keys::check(format, padding, hash)?; let key = keys::read(value, format, passphrase)?; keys::output(format, output, keys::sign_key(&key, format, payload)?) } /// Export only the public part of an asymmetric key. pub fn public_key( value: &str, passphrase: Option<&str>, format: &str, output: &str, ) -> Result { keys::public(&keys::read(value, format, passphrase)?, output) } /// Generate a P-256 private key in PKCS#8 PEM format for ES256. pub fn generate_es256() -> Result> { use p256::pkcs8::EncodePrivateKey; p256::SecretKey::random(&mut rsa::rand_core::OsRng) .to_pkcs8_pem(Default::default()) .map_err(|_| invalid_key()) }