1#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
2#![forbid(unsafe_code)]
3#![allow(unknown_lints)]
4#![warn(absolute_paths_not_starting_with_crate)]
5#![warn(elided_lifetimes_in_paths)]
6#![warn(explicit_outlives_requirements)]
7#![warn(meta_variable_misuse)]
8#![warn(missing_copy_implementations)]
9#![warn(missing_debug_implementations)]
10#![warn(missing_docs)]
11#![warn(non_ascii_idents)]
12#![warn(noop_method_call)]
13#![warn(rust_2021_idioms)]
14#![warn(single_use_lifetimes)]
15#![warn(trivial_casts)]
16#![warn(unreachable_pub)]
17#![warn(unused_crate_dependencies)]
18#![warn(unused_extern_crates)]
19#![warn(unused_lifetimes)]
20#![warn(unused_results)]
21#![allow(clippy::enum_variant_names)]
22#![doc = include_str!("../README.md")]
23
24mod constants;
25pub mod sign;
26#[cfg(any(feature = "sign-zip", feature = "unsign-zip"))]
27mod sign_unsign_zip;
28pub mod unsign;
29pub mod verify;
30#[cfg(any(feature = "verify-tar", feature = "unsign-tar"))]
31mod verify_unsign_tar;
32
33use std::fmt;
34use std::io::{self, Read};
35
36#[doc(no_inline)]
37pub use ed25519_dalek::{
38 KEYPAIR_LENGTH, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH, Signature, SignatureError, SigningKey,
39 VerifyingKey,
40};
41
42#[derive(Clone, Default)]
46pub struct Prehash(ed25519_dalek::Sha512);
47
48impl fmt::Debug for Prehash {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("Prehash").finish_non_exhaustive()
51 }
52}
53
54impl Prehash {
55 pub fn new() -> Self {
57 Self(ed25519_dalek::Sha512::default())
58 }
59
60 pub fn calculate<I>(input: &mut I) -> io::Result<Self>
62 where
63 I: ?Sized + Read,
64 {
65 let mut this = Self::new();
66 let _: u64 = io::copy(input, &mut this.0)?;
67 Ok(this)
68 }
69}
70
71impl io::Write for Prehash {
72 #[inline]
73 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
74 self.0.write(buf)
75 }
76
77 #[inline]
78 fn flush(&mut self) -> io::Result<()> {
79 self.0.flush()
80 }
81}
82
83#[non_exhaustive]
85#[derive(Debug, thiserror::Error)]
86#[error(transparent)]
87pub enum ZipsignError {
88 GatherSignatureData(#[from] self::sign::GatherSignatureDataError),
90 ReadSigningKeys(#[from] self::sign::ReadSigningKeysError),
92 #[cfg(feature = "sign-tar")]
94 #[cfg_attr(docsrs, doc(cfg(feature = "sign-tar")))]
95 SignTar(#[from] self::sign::SignTarError),
96 #[cfg(feature = "sign-zip")]
98 #[cfg_attr(docsrs, doc(cfg(feature = "sign-zip")))]
99 SignZip(#[from] self::sign::SignZipError),
100
101 NoMatch(#[from] self::verify::NoMatch),
103 CollectKeys(#[from] self::verify::CollectKeysError),
105 ReadSignatures(#[from] self::verify::ReadSignaturesError),
107 #[cfg(feature = "verify-tar")]
109 #[cfg_attr(docsrs, doc(cfg(feature = "verify-tar")))]
110 VerifyTar(#[from] self::verify::VerifyTarError),
111 #[cfg(feature = "verify-zip")]
113 #[cfg_attr(docsrs, doc(cfg(feature = "verify-zip")))]
114 VerifyZip(#[from] self::verify::VerifyZipError),
115
116 #[cfg(feature = "unsign-tar")]
118 #[cfg_attr(docsrs, doc(cfg(feature = "unsign-tar")))]
119 UnsignTar(#[from] self::unsign::UnsignTarError),
120 #[cfg(feature = "unsign-zip")]
122 #[cfg_attr(docsrs, doc(cfg(feature = "unsign-zip")))]
123 UnsignZip(#[from] self::unsign::UnsignZipError),
124
125 Io(#[from] io::Error),
127}
128
129macro_rules! Error {
130 (
131 $(#[$meta:meta])+
132 $vis:vis struct $outer:ident($inner:ident) { $(
133 $(#[$field_meta:meta])+
134 $field:ident $(( $(
135 $(#[$ty_meta:meta])*
136 $field_type:ty
137 ),+ $(,)? ))?
138 ),+ $(,)? }
139 ) => {
140 $(#[$meta])+
141 $vis struct $outer(Box<$inner>);
142
143 #[derive(Debug, thiserror::Error)]
144 enum $inner { $(
145 $(#[$field_meta])+
146 $field $(( $(
147 $(#[$ty_meta])* $field_type,
148 )+ ))?,
149 )+ }
150
151 const _: () = {
152 impl std::fmt::Debug for $outer {
153 #[inline]
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155 std::fmt::Debug::fmt(&*self.0, f)
156 }
157 }
158
159 impl std::fmt::Display for $outer {
160 #[inline]
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 std::fmt::Display::fmt(&*self.0, f)
163 }
164 }
165
166 impl From<$inner> for $outer {
167 #[inline]
168 fn from(value: $inner) -> Self {
169 Self(Box::new(value))
170 }
171 }
172
173 impl std::error::Error for $outer {
174 #[inline]
175 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
176 self.0.source()
177 }
178 }
179 };
180 };
181}
182
183pub(crate) use Error;