debian_packaging/
signing_key.rs1use {
8 pgp::{
9 crypto::{hash::HashAlgorithm, sym::SymmetricKeyAlgorithm},
10 types::{CompressionAlgorithm, SecretKeyTrait},
11 Deserializable, KeyType, SecretKeyParams, SecretKeyParamsBuilder, SignedPublicKey,
12 SignedSecretKey,
13 },
14 smallvec::smallvec,
15 std::io::Cursor,
16 strum::EnumIter,
17};
18
19pub const DEBIAN_8_RELEASE_KEY: &str = include_str!("keys/debian-8-release.asc");
21
22pub const DEBIAN_8_ARCHIVE_KEY: &str = include_str!("keys/debian-8-archive.asc");
24
25pub const DEBIAN_8_SECURITY_ARCHIVE_KEY: &str = include_str!("keys/debian-8-security.asc");
27
28pub const DEBIAN_9_RELEASE_KEY: &str = include_str!("keys/debian-9-release.asc");
30
31pub const DEBIAN_9_ARCHIVE_KEY: &str = include_str!("keys/debian-9-archive.asc");
33
34pub const DEBIAN_9_SECURITY_ARCHIVE_KEY: &str = include_str!("keys/debian-9-security.asc");
36
37pub const DEBIAN_10_RELEASE_KEY: &str = include_str!("keys/debian-10-release.asc");
39
40pub const DEBIAN_10_ARCHIVE_KEY: &str = include_str!("keys/debian-10-archive.asc");
42
43pub const DEBIAN_10_SECURITY_ARCHIVE_KEY: &str = include_str!("keys/debian-10-security.asc");
45
46pub const DEBIAN_11_RELEASE_KEY: &str = include_str!("keys/debian-11-release.asc");
48
49pub const DEBIAN_11_ARCHIVE_KEY: &str = include_str!("keys/debian-11-archive.asc");
51
52pub const DEBIAN_11_SECURITY_ARCHIVE_KEY: &str = include_str!("keys/debian-11-security.asc");
54
55#[derive(Clone, Copy, Debug, EnumIter)]
57pub enum DistroSigningKey {
58 Debian8Release,
60 Debian8Archive,
62 Debian8SecurityArchive,
64 Debian9Release,
66 Debian9Archive,
68 Debian9SecurityArchive,
70 Debian10Release,
72 Debian10Archive,
74 Debian10SecurityArchive,
76 Debian11Release,
78 Debian11Archive,
80 Debian11SecurityArchive,
82}
83
84impl DistroSigningKey {
85 pub fn armored_public_key(&self) -> &'static str {
87 match self {
88 Self::Debian8Release => DEBIAN_8_RELEASE_KEY,
89 Self::Debian8Archive => DEBIAN_8_ARCHIVE_KEY,
90 Self::Debian8SecurityArchive => DEBIAN_8_SECURITY_ARCHIVE_KEY,
91 Self::Debian9Release => DEBIAN_9_RELEASE_KEY,
92 Self::Debian9Archive => DEBIAN_9_ARCHIVE_KEY,
93 Self::Debian9SecurityArchive => DEBIAN_9_SECURITY_ARCHIVE_KEY,
94 Self::Debian10Release => DEBIAN_10_RELEASE_KEY,
95 Self::Debian10Archive => DEBIAN_10_ARCHIVE_KEY,
96 Self::Debian10SecurityArchive => DEBIAN_10_SECURITY_ARCHIVE_KEY,
97 Self::Debian11Release => DEBIAN_11_RELEASE_KEY,
98 Self::Debian11Archive => DEBIAN_11_ARCHIVE_KEY,
99 Self::Debian11SecurityArchive => DEBIAN_11_SECURITY_ARCHIVE_KEY,
100 }
101 }
102
103 pub fn public_key(&self) -> SignedPublicKey {
105 SignedPublicKey::from_armor_single(Cursor::new(self.armored_public_key().as_bytes()))
106 .expect("built-in signing keys should parse")
107 .0
108 }
109}
110
111pub fn signing_secret_key_params_builder(primary_user_id: impl ToString) -> SecretKeyParamsBuilder {
117 let mut key_params = SecretKeyParamsBuilder::default();
118 key_params
119 .key_type(KeyType::Rsa(2048))
120 .preferred_symmetric_algorithms(smallvec![SymmetricKeyAlgorithm::AES256])
121 .preferred_hash_algorithms(smallvec![
122 HashAlgorithm::SHA2_256,
123 HashAlgorithm::SHA2_384,
124 HashAlgorithm::SHA2_512
125 ])
126 .preferred_compression_algorithms(smallvec![CompressionAlgorithm::ZLIB])
127 .can_sign(true)
128 .primary_user_id(primary_user_id.to_string());
129
130 key_params
131}
132
133pub fn create_self_signed_key<PW>(
174 params: SecretKeyParams,
175 key_passphrase: PW,
176) -> pgp::errors::Result<(SignedSecretKey, SignedPublicKey)>
177where
178 PW: (FnOnce() -> String) + Clone,
179{
180 let mut rng = rand::thread_rng();
181 let secret_key = params.generate(&mut rng)?;
182 let secret_key_signed = secret_key.sign(&mut rng, key_passphrase.clone())?;
183
184 let public_key = secret_key_signed.public_key();
185 let public_key_signed = public_key.sign(&mut rng, &secret_key_signed, key_passphrase)?;
186
187 Ok((secret_key_signed, public_key_signed))
188}
189
190#[cfg(test)]
191mod test {
192 use {super::*, strum::IntoEnumIterator};
193
194 #[test]
195 fn all_distro_signing_keys() {
196 for key in DistroSigningKey::iter() {
197 key.public_key();
198 }
199 }
200
201 #[test]
202 fn key_creation() -> pgp::errors::Result<()> {
203 let builder = signing_secret_key_params_builder("Me <someone@example.com>");
204 let params = builder.build().unwrap();
205 let (private, public) = create_self_signed_key(params, || "passphrase".to_string())?;
206
207 assert!(private
208 .to_armored_string(Default::default())?
209 .starts_with("-----BEGIN PGP PRIVATE KEY BLOCK-----"));
210 assert!(public
211 .to_armored_string(Default::default())?
212 .starts_with("-----BEGIN PGP PUBLIC KEY BLOCK-----"));
213
214 Ok(())
215 }
216}