1#[cfg(feature = "sign-tar")]
4mod tar;
5#[cfg(feature = "sign-zip")]
6mod zip;
7
8use std::io::Read;
9
10#[cfg(feature = "sign-tar")]
11pub use self::tar::{SignTarError, copy_and_sign_tar};
12#[cfg(feature = "sign-zip")]
13pub use self::zip::{SignZipError, copy_and_sign_zip};
14use crate::constants::{BUF_LIMIT, HEADER_SIZE, MAGIC_HEADER, SignatureCountLeInt};
15use crate::{KEYPAIR_LENGTH, Prehash, SIGNATURE_LENGTH, SignatureError, SigningKey};
16
17crate::Error! {
18 pub struct ReadSigningKeysError(KeysError) {
20 #[error("input #{1} did not contain a valid key")]
21 Construct(#[source] ed25519_dalek::ed25519::Error, usize),
22 #[error("no signing keys provided")]
23 Empty,
24 #[error("could not read key in file #{1}")]
25 Read(#[source] std::io::Error, usize),
26 }
27}
28
29pub fn read_signing_keys<I, R>(inputs: I) -> Result<Vec<SigningKey>, ReadSigningKeysError>
31where
32 I: IntoIterator<Item = std::io::Result<R>>,
33 R: Read,
34{
35 let mut keys = inputs
37 .into_iter()
38 .enumerate()
39 .map(|(key_index, input)| {
40 let mut key = [0; KEYPAIR_LENGTH];
41 input
42 .and_then(|mut input| input.read_exact(&mut key))
43 .map_err(|err| KeysError::Read(err, key_index))?;
44 SigningKey::from_keypair_bytes(&key).map_err(|err| KeysError::Construct(err, key_index))
45 })
46 .collect::<Result<Vec<_>, _>>()?;
47 if keys.is_empty() {
48 return Err(KeysError::Empty.into());
49 }
50 keys.sort_by(|l, r| {
51 l.verifying_key()
52 .as_bytes()
53 .cmp(r.verifying_key().as_bytes())
54 });
55 Ok(keys)
56}
57
58crate::Error! {
59 pub struct GatherSignatureDataError(SignaturesError) {
61 #[error("no signing keys provided")]
62 Empty,
63 #[error("could not sign data with key #{1}")]
64 Signature(#[source] SignatureError, usize),
65 #[error("too many signing keys provided")]
66 TooManyKeys,
67 }
68}
69
70pub fn gather_signature_data(
73 keys: &[SigningKey],
74 prehashed_message: &Prehash,
75 context: Option<&[u8]>,
76) -> Result<Vec<u8>, GatherSignatureDataError> {
77 if keys.is_empty() {
78 return Err(SignaturesError::Empty.into());
79 }
80
81 let signature_bytes = HEADER_SIZE + keys.len() * SIGNATURE_LENGTH;
82 if signature_bytes > BUF_LIMIT {
83 return Err(SignaturesError::TooManyKeys.into());
84 }
85
86 let mut header = [0; HEADER_SIZE];
87 header[..MAGIC_HEADER.len()].copy_from_slice(MAGIC_HEADER);
88 header[MAGIC_HEADER.len()..]
89 .copy_from_slice(&(keys.len() as SignatureCountLeInt).to_le_bytes());
90
91 let mut buf = Vec::with_capacity(signature_bytes);
92 buf.extend(header);
93 for (idx, key) in keys.iter().enumerate() {
94 let signature = key
95 .sign_prehashed(prehashed_message.0.clone(), context)
96 .map_err(|err| SignaturesError::Signature(err, idx))?;
97 buf.extend(signature.to_bytes());
98 }
99 Ok(buf)
100}