1use crate::{
24 crypto::{
25 base64_decode, base64_encode, sha256::Sha256, PrivateKeyKind, SigningKeyKind,
26 SigningPublicKey,
27 },
28 error::parser::DestinationParseError,
29 runtime::Runtime,
30};
31
32use bytes::{BufMut, Bytes, BytesMut};
33use nom::{
34 bytes::complete::take,
35 number::complete::{be_u16, be_u8},
36 sequence::tuple,
37 Err, IResult,
38};
39use rand_core::RngCore;
40
41use alloc::{string::String, sync::Arc, vec::Vec};
42use core::fmt;
43
44const NULL_CERTIFICATE: u8 = 0x00;
46
47const KEY_CERTIFICATE: u8 = 0x05;
49
50const KEY_CERTIFICATE_LEN: u16 = 0x04;
52
53const PADDING_LEN: usize = 320usize + 32usize;
57
58const KEY_KIND_EDDSA_SHA512_ED25519: u16 = 0x0007;
62
63const DESTINATION_WITH_KEY_CERT_LEN: usize = 391usize;
65
66const DESTINATION_WITH_NULL_CERT_LEN: usize = 387usize;
68
69const DESTINATION_MINIMUM_LEN: usize = 387usize;
71
72const DESTINATION_LEN_NO_CERTIFICATE: usize = 384usize;
74
75#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
77pub struct DestinationId(Arc<String>);
78
79impl DestinationId {
80 #[cfg(test)]
81 pub fn random() -> DestinationId {
82 use rand::Rng;
83
84 DestinationId::from(rand::thread_rng().gen::<[u8; 32]>())
85 }
86
87 pub fn to_vec(&self) -> Vec<u8> {
89 base64_decode(self.0.as_bytes()).expect("to succeed")
90 }
91}
92
93impl fmt::Display for DestinationId {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 write!(f, "{}", &self.0[..8])
96 }
97}
98
99impl<T: AsRef<[u8]>> From<T> for DestinationId {
100 fn from(value: T) -> Self {
101 DestinationId(Arc::new(base64_encode(value)))
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct Destination {
108 destination_id: DestinationId,
110
111 identity_hash: Bytes,
113
114 private_key_len: usize,
116
117 serialized: Bytes,
119
120 signing_key_len: usize,
122
123 verifying_key: SigningPublicKey,
125}
126
127impl Destination {
128 pub fn new<R: Runtime>(verifying_key: SigningPublicKey) -> Self {
130 let serialized = {
131 let serialized_len = PADDING_LEN
132 .saturating_add(32usize) .saturating_add(1usize) .saturating_add(2usize) .saturating_add(4usize); let mut out = BytesMut::with_capacity(serialized_len);
138 let mut padding = [0u8; PADDING_LEN];
139 R::rng().fill_bytes(&mut padding);
140
141 out.put_slice(&padding);
142 out.put_slice(verifying_key.as_ref());
143 out.put_u8(KEY_CERTIFICATE);
144 out.put_u16(KEY_CERTIFICATE_LEN);
145 out.put_u16(KEY_KIND_EDDSA_SHA512_ED25519);
146
147 out.put_u16(0u16);
153
154 out.freeze()
155 };
156 let identity_hash = Sha256::new().update(&serialized).finalize();
157
158 Self {
159 destination_id: DestinationId::from(identity_hash.clone()),
160 identity_hash: Bytes::from(identity_hash),
161 private_key_len: 32, serialized,
163 signing_key_len: 32, verifying_key,
165 }
166 }
167
168 pub fn parse_frame(input: &[u8]) -> IResult<&[u8], Destination, DestinationParseError> {
170 if input.len() < DESTINATION_MINIMUM_LEN {
171 return Err(Err::Error(DestinationParseError::InvalidLength));
172 }
173
174 let (_, (initial_bytes, rest)) = tuple((
175 take(DESTINATION_LEN_NO_CERTIFICATE),
176 take(input.len() - DESTINATION_LEN_NO_CERTIFICATE),
177 ))(input)?;
178
179 let (rest, certificate_kind) = be_u8(rest)?;
180 let (rest, certificate_len) = be_u16(rest)?;
181
182 let (rest, verifying_key, signing_key_len, private_key_len, destination_len) =
183 match (certificate_kind, certificate_len) {
184 (NULL_CERTIFICATE, _) => (
185 rest,
186 SigningPublicKey::dsa_sha1(&initial_bytes[384 - 128..384])
187 .ok_or(Err::Error(DestinationParseError::InvalidBitstream))?,
188 256, 128, DESTINATION_WITH_NULL_CERT_LEN,
191 ),
192 (KEY_CERTIFICATE, KEY_CERTIFICATE_LEN) => {
193 let (rest, signing_key_kind) = be_u16(rest)?;
194 let (rest, private_key_kind) = be_u16(rest)?;
195
196 let (verifying_key, signing_key_len) =
197 match SigningKeyKind::try_from(signing_key_kind) {
198 Ok(SigningKeyKind::DsaSha1(_)) =>
199 return Err(Err::Error(DestinationParseError::NotANullCertificate)),
200 Ok(SigningKeyKind::EcDsaSha256P256(size)) => (
201 SigningPublicKey::p256(&initial_bytes[384 - 64..384])
202 .ok_or(Err::Error(DestinationParseError::InvalidBitstream))?,
203 size,
204 ),
205 Ok(SigningKeyKind::EdDsaSha512Ed25519(size)) => {
206 let public_key = TryInto::<[u8; 32]>::try_into(
209 initial_bytes[384 - 32..384].to_vec(),
210 )
211 .expect("to succeed");
212
213 (
214 SigningPublicKey::from_bytes(&public_key).ok_or({
215 Err::Error(DestinationParseError::InvalidBitstream)
216 })?,
217 size,
218 )
219 }
220 Err(()) =>
221 return Err(Err::Error(
222 DestinationParseError::UnsupportedSigningKey(signing_key_kind),
223 )),
224 };
225
226 let public_key_len = match PrivateKeyKind::try_from(private_key_kind) {
227 Ok(PrivateKeyKind::ElGamal(size)) => size,
228 Ok(PrivateKeyKind::P256(size)) => size,
229 Ok(PrivateKeyKind::X25519(size)) => size,
230 Err(()) =>
231 return Err(Err::Error(DestinationParseError::UnsupportedPrivateKey(
232 private_key_kind,
233 ))),
234 };
235
236 (
237 rest,
238 verifying_key,
239 signing_key_len,
240 public_key_len,
241 DESTINATION_WITH_KEY_CERT_LEN,
242 )
243 }
244 (certificate_kind, _certificate_len) =>
245 return Err(Err::Error(DestinationParseError::UnsupportedCertificate(
246 certificate_kind,
247 ))),
248 };
249
250 let identity_hash = Bytes::from(Sha256::new().update(&input[..destination_len]).finalize());
251 let serialized = Bytes::from(input[..destination_len].to_vec());
252
253 Ok((
254 rest,
255 Destination {
256 destination_id: DestinationId::from(identity_hash.clone()),
257 identity_hash,
258 serialized,
259 verifying_key,
260 private_key_len,
261 signing_key_len,
262 },
263 ))
264 }
265
266 pub fn parse(input: impl AsRef<[u8]>) -> Result<Self, DestinationParseError> {
268 Ok(Self::parse_frame(input.as_ref())?.1)
269 }
270
271 pub fn serialize(&self) -> Bytes {
273 self.serialized.clone()
274 }
275
276 pub fn serialized_len(&self) -> usize {
278 let certificate_payload_len = match self.verifying_key {
279 SigningPublicKey::DsaSha1(_) => 0usize,
280 _ => 4usize,
281 };
282
283 32usize .saturating_add(320usize) .saturating_add(32usize) .saturating_add(1usize) .saturating_add(2usize) .saturating_add(certificate_payload_len)
289 }
290
291 pub fn id(&self) -> DestinationId {
293 self.destination_id.clone()
294 }
295
296 pub fn verifying_key(&self) -> &SigningPublicKey {
298 &self.verifying_key
299 }
300
301 pub fn private_key_length(&self) -> usize {
303 self.private_key_len
304 }
305
306 pub fn signing_key_length(&self) -> usize {
308 self.signing_key_len
309 }
310
311 pub fn serialized(&self) -> &Bytes {
313 &self.serialized
314 }
315
316 #[cfg(test)]
318 pub fn random() -> (Self, crate::crypto::SigningPrivateKey) {
319 let signing_key = crate::crypto::SigningPrivateKey::random(rand::thread_rng());
320 (
321 Self::new::<crate::runtime::mock::MockRuntime>(signing_key.public()),
322 signing_key,
323 )
324 }
325}
326
327impl core::ops::Deref for Destination {
328 type Target = [u8];
329
330 fn deref(&self) -> &Self::Target {
331 &self.serialized
332 }
333}
334
335#[cfg(test)]
336mod tests {
337 use super::*;
338 use crate::{crypto::SigningPrivateKey, runtime::mock::MockRuntime};
339
340 #[test]
341 fn serialize_and_parse_destination() {
342 let signing_key = SigningPrivateKey::from_bytes(&[0xa; 32]).unwrap().public();
343 let destination = Destination::new::<MockRuntime>(signing_key.clone());
344
345 let serialized = destination.clone().serialize();
346 let parsed = Destination::parse(&serialized).unwrap();
347
348 assert_eq!(parsed.destination_id, destination.destination_id);
349 assert_eq!(
350 parsed.verifying_key.as_ref(),
351 destination.verifying_key.as_ref()
352 );
353 }
354
355 #[test]
356 fn too_small_input() {
357 assert_eq!(
358 Destination::parse(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).unwrap_err(),
359 DestinationParseError::InvalidLength
360 );
361 }
362
363 #[test]
364 fn deserialize_valid_destination() {
365 let input = vec![
366 216, 194, 83, 151, 200, 24, 84, 242, 184, 222, 34, 89, 37, 175, 254, 228, 173, 78, 114,
367 24, 15, 104, 241, 215, 166, 166, 102, 40, 136, 138, 22, 252, 114, 203, 192, 101, 32,
368 156, 212, 74, 177, 120, 153, 172, 221, 181, 175, 190, 178, 17, 71, 33, 39, 211, 208,
369 241, 30, 35, 222, 99, 215, 32, 242, 40, 202, 70, 197, 171, 84, 202, 52, 173, 221, 153,
370 242, 77, 240, 30, 133, 4, 126, 31, 105, 24, 87, 209, 111, 140, 122, 58, 242, 224, 61,
371 95, 144, 26, 25, 129, 202, 69, 130, 238, 88, 201, 34, 132, 197, 242, 129, 223, 50, 194,
372 130, 227, 102, 209, 79, 209, 70, 202, 48, 248, 32, 124, 230, 90, 90, 104, 199, 23, 141,
373 60, 213, 122, 20, 94, 223, 251, 48, 64, 30, 97, 36, 40, 194, 119, 98, 83, 29, 0, 31,
374 113, 241, 52, 72, 175, 208, 221, 251, 220, 146, 82, 235, 83, 172, 33, 118, 249, 114,
375 218, 149, 42, 76, 8, 137, 125, 81, 209, 156, 68, 75, 58, 79, 245, 124, 41, 243, 228,
376 244, 162, 239, 31, 176, 185, 44, 202, 6, 202, 200, 127, 247, 43, 80, 178, 76, 120, 211,
377 75, 157, 84, 199, 229, 62, 10, 51, 143, 31, 218, 237, 8, 232, 227, 1, 168, 159, 119,
378 35, 41, 43, 67, 241, 91, 87, 213, 118, 129, 172, 192, 92, 176, 79, 63, 80, 251, 160,
379 212, 50, 194, 46, 229, 59, 15, 48, 93, 62, 80, 237, 86, 159, 203, 194, 165, 80, 22,
380 108, 18, 64, 58, 210, 130, 124, 26, 198, 206, 159, 132, 252, 96, 155, 124, 35, 108,
381 231, 22, 53, 246, 114, 232, 108, 192, 249, 122, 24, 236, 5, 210, 53, 149, 124, 6, 12,
382 36, 59, 144, 19, 176, 11, 159, 46, 184, 45, 193, 58, 134, 179, 130, 176, 122, 34, 177,
383 172, 147, 35, 19, 123, 22, 176, 182, 216, 78, 246, 104, 110, 62, 111, 117, 110, 174,
384 49, 132, 214, 130, 96, 112, 30, 211, 159, 113, 131, 151, 166, 156, 206, 227, 20, 21,
385 115, 66, 8, 218, 103, 153, 78, 46, 127, 199, 169, 197, 168, 124, 158, 232, 115, 71,
386 104, 19, 165, 200, 234, 67, 168, 253, 137, 220, 5, 0, 4, 0, 7, 0, 0,
387 ];
388
389 let destination = Destination::parse(&input).unwrap();
390 let serialized = destination.serialize();
391
392 assert_eq!(input, *serialized);
393 }
394
395 #[test]
396 fn null_certificate_works() {
397 let input = vec![
398 89, 215, 97, 216, 78, 133, 203, 37, 193, 23, 180, 175, 81, 129, 202, 116, 223, 175,
399 141, 253, 255, 55, 171, 170, 65, 99, 94, 4, 52, 204, 208, 253, 247, 98, 56, 144, 8,
400 235, 50, 121, 218, 227, 152, 54, 102, 88, 90, 215, 80, 151, 201, 45, 105, 194, 111,
401 150, 231, 41, 236, 223, 147, 139, 131, 104, 204, 163, 254, 235, 195, 27, 252, 175, 45,
402 87, 5, 129, 195, 214, 73, 71, 123, 5, 241, 160, 202, 111, 179, 169, 193, 181, 171, 80,
403 220, 51, 203, 223, 186, 127, 148, 75, 182, 26, 152, 25, 102, 180, 46, 140, 103, 104,
404 254, 252, 136, 42, 206, 104, 44, 134, 43, 90, 241, 162, 207, 9, 243, 64, 3, 164, 186,
405 123, 101, 12, 142, 59, 70, 237, 2, 23, 151, 26, 76, 121, 206, 249, 118, 65, 221, 38,
406 85, 86, 111, 58, 228, 247, 63, 16, 130, 187, 183, 96, 137, 52, 83, 59, 88, 128, 76, 3,
407 52, 22, 230, 247, 2, 39, 177, 177, 225, 175, 113, 237, 1, 246, 180, 217, 7, 32, 69, 90,
408 145, 55, 99, 231, 65, 123, 170, 80, 155, 59, 71, 191, 244, 244, 86, 79, 18, 248, 162,
409 33, 197, 41, 145, 141, 197, 123, 34, 229, 95, 91, 32, 64, 80, 94, 25, 224, 61, 233,
410 185, 90, 62, 246, 77, 25, 222, 138, 156, 215, 96, 124, 184, 12, 121, 188, 121, 73, 44,
411 66, 248, 222, 10, 100, 196, 140, 7, 62, 92, 130, 137, 208, 23, 127, 230, 216, 113, 197,
412 69, 34, 60, 231, 58, 153, 52, 110, 87, 245, 178, 77, 243, 155, 124, 210, 91, 98, 191,
413 85, 181, 122, 207, 25, 157, 5, 184, 122, 205, 117, 175, 179, 43, 188, 147, 87, 207,
414 150, 230, 72, 126, 184, 215, 34, 72, 189, 46, 170, 35, 195, 137, 36, 218, 69, 84, 18,
415 16, 73, 114, 195, 251, 222, 147, 107, 42, 203, 64, 246, 152, 195, 251, 141, 103, 231,
416 151, 104, 78, 134, 229, 214, 33, 138, 227, 124, 196, 123, 5, 35, 84, 36, 117, 165, 26,
417 85, 153, 239, 12, 103, 236, 69, 186, 82, 228, 107, 105, 81, 176, 67, 111, 34, 228, 116,
418 251, 171, 27, 72, 187, 116, 221, 112, 0, 0, 0, 0, 0, 2, 6, 31, 139, 8, 0, 0, 1, 0, 0,
419 2, 17, 1, 239, 1, 16, 254, 186, 2, 0, 215, 250, 169, 148, 79, 97,
420 ];
421
422 let destination = Destination::parse(&input[..387]).unwrap();
423 let serialized = destination.serialize();
424
425 assert_eq!(&input[..387], &*serialized);
426 }
427}