1 use crate::crypto; 2 use crate::packet; 3 use crate::Packet; 4 5 /// Holds an MDC packet. 6 /// 7 /// A modification detection code packet. This packet appears after a 8 /// SEIP packet. See [Section 5.14 of RFC 4880] for details. 9 /// 10 /// [Section 5.14 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.14 11 /// 12 /// # A note on equality 13 /// 14 /// Two `MDC` packets are considered equal if their serialized form is 15 /// equal. This excludes the computed digest. 16 #[derive(Clone, Debug)] 17 pub struct MDC { 18 /// CTB packet header fields. 19 pub(crate) common: packet::Common, 20 /// Our SHA-1 hash. 21 computed_digest: [u8; 20], 22 /// A 20-octet SHA-1 hash of the preceding plaintext data. 23 digest: [u8; 20], 24 } 25 26 impl PartialEq for MDC { eq(&self, other: &MDC) -> bool27 fn eq(&self, other: &MDC) -> bool { 28 self.common == other.common 29 && self.digest == other.digest 30 } 31 } 32 33 impl Eq for MDC {} 34 35 impl std::hash::Hash for MDC { hash<H: std::hash::Hasher>(&self, state: &mut H)36 fn hash<H: std::hash::Hasher>(&self, state: &mut H) { 37 std::hash::Hash::hash(&self.common, state); 38 std::hash::Hash::hash(&self.digest, state); 39 } 40 } 41 42 impl MDC { 43 /// Creates an MDC packet. new(digest: [u8; 20], computed_digest: [u8; 20]) -> Self44 pub fn new(digest: [u8; 20], computed_digest: [u8; 20]) -> Self { 45 MDC { 46 common: Default::default(), 47 computed_digest, 48 digest, 49 } 50 } 51 52 /// Gets the packet's hash value. digest(&self) -> &[u8]53 pub fn digest(&self) -> &[u8] { 54 &self.digest[..] 55 } 56 57 /// Gets the computed hash value. computed_digest(&self) -> &[u8]58 pub fn computed_digest(&self) -> &[u8] { 59 &self.computed_digest[..] 60 } 61 62 /// Returns whether the data protected by the MDC is valid. valid(&self) -> bool63 pub fn valid(&self) -> bool { 64 if self.digest == [ 0; 20 ] { 65 // If the computed_digest and digest are uninitialized, then 66 // return false. 67 false 68 } else { 69 self.computed_digest == self.digest 70 } 71 } 72 } 73 74 impl From<MDC> for Packet { from(s: MDC) -> Self75 fn from(s: MDC) -> Self { 76 Packet::MDC(s) 77 } 78 } 79 80 impl From<[u8; 20]> for MDC { from(digest: [u8; 20]) -> Self81 fn from(digest: [u8; 20]) -> Self { 82 MDC { 83 common: Default::default(), 84 // All 0s. 85 computed_digest: Default::default(), 86 digest, 87 } 88 } 89 } 90 91 impl From<crypto::hash::Context> for MDC { from(mut hash: crypto::hash::Context) -> Self92 fn from(mut hash: crypto::hash::Context) -> Self { 93 let mut value : [u8; 20] = Default::default(); 94 hash.digest(&mut value[..]); 95 value.into() 96 } 97 } 98