Reproducible data signatures/certificate parsing
Hi and thanks for a great PGP framework!
The original problem I am trying to solve: verifying in a unit test that a detached signature of a hardcoded text, made with a hardcoded key with a "creation time" set to a hardcoded value doesn't change.
The problem I've faced: every time I parse an armored hardcoded certificate, the resulting Cert
object differs a bit, namely, the secret
parts do not match:
--- cert1 2021-07-09 00:38:49.590574547 +0300
+++ cert2 2021-07-09 00:38:49.590574547 +0300
@@ -15,8 +15,8 @@
Unencrypted(
Unencrypted {
mpis: Encrypted {
- ciphertext: 0x7fa448001e60,
- iv: 0x7fa4480091e0,
+ ciphertext: 0x7fa4480074d0,
+ iv: 0x7fa44800aed0,
},
},
),
@@ -165,8 +165,8 @@
Unencrypted(
Unencrypted {
mpis: Encrypted {
- ciphertext: 0x7fa4480079a0,
- iv: 0x7fa448008350,
+ ciphertext: 0x7fa448019990,
+ iv: 0x7fa448016380,
},
},
),
Full debug output: cert1 and cert2
Here is my function to load the certificate:
fn load_certificate() -> sequoia_openpgp::Cert {
let payload = b"-----BEGIN PGP PRIVATE KEY BLOCK-----
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
=csGp
-----END PGP PRIVATE KEY BLOCK-----
";
let packet = sequoia_openpgp::parse::PacketParser::from_bytes(payload).unwrap();
sequoia_openpgp::cert::CertParser::from(packet)
.next()
.unwrap()
.unwrap()
}
sequoia-openpgp
: v1.3.0
So my questions are..
- Are those differences end up in different signatures?
- If they are, is there a way to make things reproducible?
- If they aren't, what else could go "wrong"?
Thanks!
P.S.
For the record, that's how I generate a signature:
pub fn detached_sign<B: warp::Buf>(
data: B,
key: Key<SecretParts, UnspecifiedRole>,
password: Option<Password>,
creation_time: Option<SystemTime>,
) -> Result<Vec<u8>> {
let mut sink = vec![];
let raw_message = Armorer::new(Message::new(&mut sink))
.build()
.context("Armorer initialization failed")?;
let creation_time = creation_time.unwrap_or_else(SystemTime::now);
let key_pair = if let Some(secret) = password.map(Password::from) {
key.decrypt_secret(&secret)
.context("Key decryption failed")?
.into_keypair()
.expect("Shouldn't fail after decryption")
} else {
key.into_keypair()
.context("Key is encrypted, but no password provided")?
};
let signer = Signer::new(raw_message, key_pair)
.hash_algo(HashAlgorithm::SHA256)
.context("Unable to set hash algorithm")?
.detached()
.creation_time(creation_time);
let mut out = signer.build().context("Unable to build signer")?;
std::io::copy(&mut data.reader(), &mut out).context("Unable to write data to signer")?;
out.finalize()
.context("Unable to finalize signature calculation")?;
Ok(sink)
}
Edited by Denis