1#[cfg(not(feature = "std"))]
2use alloc::sync::Arc;
3#[cfg(feature = "std")]
4use std::sync::Arc;
5
6use bytes::Bytes;
7
8use crate::{Name, PacketError, tlv_type};
9use ndn_tlv::TlvReader;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13pub enum SignatureType {
14 DigestSha256,
15 SignatureSha256WithRsa,
16 SignatureSha256WithEcdsa,
17 SignatureHmacWithSha256,
18 SignatureEd25519,
19 Other(u64),
20}
21
22impl SignatureType {
23 pub fn code(&self) -> u64 {
24 match self {
25 SignatureType::DigestSha256 => 0,
26 SignatureType::SignatureSha256WithRsa => 1,
27 SignatureType::SignatureSha256WithEcdsa => 3,
28 SignatureType::SignatureHmacWithSha256 => 4,
29 SignatureType::SignatureEd25519 => 5,
30 SignatureType::Other(c) => *c,
31 }
32 }
33
34 pub fn from_code(code: u64) -> Self {
35 match code {
36 0 => SignatureType::DigestSha256,
37 1 => SignatureType::SignatureSha256WithRsa,
38 3 => SignatureType::SignatureSha256WithEcdsa,
39 4 => SignatureType::SignatureHmacWithSha256,
40 5 => SignatureType::SignatureEd25519,
41 c => SignatureType::Other(c),
42 }
43 }
44}
45
46#[derive(Clone, Debug)]
56pub struct SignatureInfo {
57 pub sig_type: SignatureType,
58 pub key_locator: Option<Arc<Name>>,
60 pub key_digest: Option<Bytes>,
63 pub sig_nonce: Option<Bytes>,
65 pub sig_time: Option<u64>,
67 pub sig_seq_num: Option<u64>,
69}
70
71impl SignatureInfo {
72 pub fn decode(value: Bytes) -> Result<Self, PacketError> {
73 let mut reader = TlvReader::new(value);
74 let mut sig_type = SignatureType::Other(0);
75 let mut key_locator = None;
76 let mut key_digest = None;
77 let mut sig_nonce = None;
78 let mut sig_time = None;
79 let mut sig_seq_num = None;
80
81 while !reader.is_empty() {
82 let (typ, val) = reader.read_tlv()?;
83 match typ {
84 t if t == tlv_type::SIGNATURE_TYPE => {
85 let mut code = 0u64;
86 for &b in val.iter() {
87 code = (code << 8) | b as u64;
88 }
89 sig_type = SignatureType::from_code(code);
90 }
91 t if t == tlv_type::KEY_LOCATOR => {
92 let mut inner = TlvReader::new(val);
95 if !inner.is_empty() {
96 let (kt, kv) = inner.read_tlv()?;
97 if kt == tlv_type::NAME {
98 let name = Name::decode(kv)?;
99 key_locator = Some(Arc::new(name));
100 } else if kt == tlv_type::KEY_DIGEST {
101 key_digest = Some(kv);
102 }
103 }
104 }
105 t if t == tlv_type::SIGNATURE_NONCE => {
106 sig_nonce = Some(val);
107 }
108 t if t == tlv_type::SIGNATURE_TIME => {
109 let mut ms = 0u64;
110 for &b in val.iter() {
111 ms = (ms << 8) | b as u64;
112 }
113 sig_time = Some(ms);
114 }
115 t if t == tlv_type::SIGNATURE_SEQ_NUM => {
116 let mut n = 0u64;
117 for &b in val.iter() {
118 n = (n << 8) | b as u64;
119 }
120 sig_seq_num = Some(n);
121 }
122 _ => {}
123 }
124 }
125 Ok(Self {
126 sig_type,
127 key_locator,
128 key_digest,
129 sig_nonce,
130 sig_time,
131 sig_seq_num,
132 })
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139 use crate::name::build_name_value;
140 use ndn_tlv::TlvWriter;
141
142 fn build_sig_info(sig_type_code: u8, key_name_components: Option<&[&[u8]]>) -> bytes::Bytes {
143 let mut w = TlvWriter::new();
144 w.write_tlv(crate::tlv_type::SIGNATURE_TYPE, &[sig_type_code]);
145 if let Some(comps) = key_name_components {
146 w.write_nested(crate::tlv_type::KEY_LOCATOR, |w| {
147 let name_val = build_name_value(comps);
148 w.write_tlv(crate::tlv_type::NAME, &name_val);
149 });
150 }
151 w.finish()
152 }
153
154 #[test]
157 fn sig_type_known_codes() {
158 let cases = [
159 (SignatureType::DigestSha256, 0u64),
160 (SignatureType::SignatureSha256WithRsa, 1),
161 (SignatureType::SignatureSha256WithEcdsa, 3),
162 (SignatureType::SignatureHmacWithSha256, 4),
163 (SignatureType::SignatureEd25519, 5),
164 ];
165 for (sig_type, code) in cases {
166 assert_eq!(sig_type.code(), code, "{sig_type:?}");
167 assert_eq!(SignatureType::from_code(code), sig_type);
168 }
169 }
170
171 #[test]
172 fn sig_type_other_code_roundtrip() {
173 let t = SignatureType::Other(99);
174 assert_eq!(t.code(), 99);
175 assert_eq!(SignatureType::from_code(99), SignatureType::Other(99));
176 }
177
178 #[test]
181 fn decode_sig_type_only() {
182 let raw = build_sig_info(5, None);
183 let si = SignatureInfo::decode(raw).unwrap();
184 assert_eq!(si.sig_type, SignatureType::SignatureEd25519);
185 assert!(si.key_locator.is_none());
186 }
187
188 #[test]
189 fn decode_all_known_sig_types() {
190 for code in [0u8, 1, 3, 4, 5] {
191 let raw = build_sig_info(code, None);
192 let si = SignatureInfo::decode(raw).unwrap();
193 assert_eq!(si.sig_type.code(), code as u64);
194 }
195 }
196
197 #[test]
198 fn decode_with_key_locator() {
199 let raw = build_sig_info(5, Some(&[b"sensor", b"node1", b"KEY", b"abc"]));
200 let si = SignatureInfo::decode(raw).unwrap();
201 assert_eq!(si.sig_type, SignatureType::SignatureEd25519);
202 let kl = si.key_locator.expect("key_locator present");
203 assert_eq!(kl.len(), 4);
204 assert_eq!(kl.components()[0].value.as_ref(), b"sensor");
205 assert_eq!(kl.components()[3].value.as_ref(), b"abc");
206 assert!(
207 si.key_digest.is_none(),
208 "Name-form locator must not populate key_digest"
209 );
210 }
211
212 #[test]
213 fn decode_with_key_digest_locator() {
214 let digest = [0xABu8; 32];
216 let mut w = TlvWriter::new();
217 w.write_tlv(crate::tlv_type::SIGNATURE_TYPE, &[5]);
218 w.write_nested(crate::tlv_type::KEY_LOCATOR, |w| {
219 w.write_tlv(crate::tlv_type::KEY_DIGEST, &digest);
220 });
221 let si = SignatureInfo::decode(w.finish()).unwrap();
222 assert_eq!(si.sig_type, SignatureType::SignatureEd25519);
223 assert!(
224 si.key_locator.is_none(),
225 "KeyDigest form must not populate key_locator"
226 );
227 let kd = si.key_digest.expect("key_digest present");
228 assert_eq!(kd.len(), 32);
229 assert!(kd.iter().all(|&b| b == 0xAB));
230 }
231
232 #[test]
233 fn decode_empty_is_other_zero() {
234 let si = SignatureInfo::decode(bytes::Bytes::new()).unwrap();
236 assert_eq!(si.sig_type, SignatureType::Other(0));
237 assert!(si.key_locator.is_none());
238 }
239
240 #[test]
243 fn decode_sig_nonce() {
244 let mut w = TlvWriter::new();
245 w.write_tlv(crate::tlv_type::SIGNATURE_TYPE, &[5]);
246 w.write_tlv(crate::tlv_type::SIGNATURE_NONCE, &[0xDE, 0xAD, 0xBE, 0xEF]);
247 let si = SignatureInfo::decode(w.finish()).unwrap();
248 assert_eq!(si.sig_nonce.as_deref(), Some(&[0xDE, 0xAD, 0xBE, 0xEF][..]));
249 }
250
251 #[test]
252 fn decode_sig_time() {
253 let mut w = TlvWriter::new();
254 w.write_tlv(crate::tlv_type::SIGNATURE_TYPE, &[5]);
255 let ts: u64 = 1_700_000_000_000; w.write_tlv(crate::tlv_type::SIGNATURE_TIME, &ts.to_be_bytes());
257 let si = SignatureInfo::decode(w.finish()).unwrap();
258 assert_eq!(si.sig_time, Some(ts));
259 }
260
261 #[test]
262 fn decode_sig_seq_num() {
263 let mut w = TlvWriter::new();
264 w.write_tlv(crate::tlv_type::SIGNATURE_TYPE, &[5]);
265 w.write_tlv(crate::tlv_type::SIGNATURE_SEQ_NUM, &42u64.to_be_bytes());
266 let si = SignatureInfo::decode(w.finish()).unwrap();
267 assert_eq!(si.sig_seq_num, Some(42));
268 }
269
270 #[test]
271 fn decode_all_anti_replay_fields() {
272 let mut w = TlvWriter::new();
273 w.write_tlv(crate::tlv_type::SIGNATURE_TYPE, &[5]);
274 w.write_tlv(crate::tlv_type::SIGNATURE_NONCE, &[0x01, 0x02]);
275 w.write_tlv(crate::tlv_type::SIGNATURE_TIME, &500u64.to_be_bytes());
276 w.write_tlv(crate::tlv_type::SIGNATURE_SEQ_NUM, &7u64.to_be_bytes());
277 let si = SignatureInfo::decode(w.finish()).unwrap();
278 assert_eq!(si.sig_nonce.as_deref(), Some(&[0x01, 0x02][..]));
279 assert_eq!(si.sig_time, Some(500));
280 assert_eq!(si.sig_seq_num, Some(7));
281 }
282
283 #[test]
284 fn decode_no_anti_replay_fields() {
285 let raw = build_sig_info(5, None);
286 let si = SignatureInfo::decode(raw).unwrap();
287 assert!(si.sig_nonce.is_none());
288 assert!(si.sig_time.is_none());
289 assert!(si.sig_seq_num.is_none());
290 }
291}