Identity hashes really just need to be SHA384, good enough for top secret.

This commit is contained in:
Adam Ierymenko 2022-06-23 17:41:34 -04:00
parent 9cbbcb4495
commit 1df6843e94
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
3 changed files with 15 additions and 13 deletions

View file

@ -6,12 +6,11 @@ use std::str::FromStr;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use zerotier_core_crypto::hash::SHA512_HASH_SIZE;
use crate::error::InvalidFormatError;
use crate::util::buffer::Buffer;
use crate::util::marshalable::Marshalable;
use crate::vl1::inetaddress::InetAddress;
use crate::vl1::protocol::IDENTITY_FINGERPRINT_SIZE;
use crate::vl1::{Address, MAC};
pub const TYPE_NIL: u8 = 0;
@ -38,7 +37,7 @@ pub enum Endpoint {
/// Via another node using unencapsulated relaying (e.g. via a root)
/// This is the address and the full identity fingerprint.
ZeroTier(Address, [u8; SHA512_HASH_SIZE]),
ZeroTier(Address, [u8; IDENTITY_FINGERPRINT_SIZE]),
/// Direct L2 Ethernet
Ethernet(MAC),
@ -66,7 +65,7 @@ pub enum Endpoint {
/// Via another node using inner encapsulation via VERB_ENCAP.
/// This is the address and the full identity fingerprint.
ZeroTierEncap(Address, [u8; SHA512_HASH_SIZE]),
ZeroTierEncap(Address, [u8; IDENTITY_FINGERPRINT_SIZE]),
}
impl Default for Endpoint {
@ -203,7 +202,7 @@ impl Marshalable for Endpoint {
TYPE_NIL => Ok(Endpoint::Nil),
TYPE_ZEROTIER => {
let zt = Address::unmarshal(buf, cursor)?;
Ok(Endpoint::ZeroTier(zt, buf.read_bytes_fixed::<SHA512_HASH_SIZE>(cursor)?.clone()))
Ok(Endpoint::ZeroTier(zt, buf.read_bytes_fixed::<IDENTITY_FINGERPRINT_SIZE>(cursor)?.clone()))
}
TYPE_ETHERNET => Ok(Endpoint::Ethernet(MAC::unmarshal(buf, cursor)?)),
TYPE_WIFIDIRECT => Ok(Endpoint::WifiDirect(MAC::unmarshal(buf, cursor)?)),
@ -215,7 +214,7 @@ impl Marshalable for Endpoint {
TYPE_WEBRTC => Ok(Endpoint::WebRTC(buf.read_bytes(buf.read_varint(cursor)? as usize, cursor)?.to_vec())),
TYPE_ZEROTIER_ENCAP => {
let zt = Address::unmarshal(buf, cursor)?;
Ok(Endpoint::ZeroTierEncap(zt, buf.read_bytes_fixed::<SHA512_HASH_SIZE>(cursor)?.clone()))
Ok(Endpoint::ZeroTierEncap(zt, buf.read_bytes_fixed(cursor)?.clone()))
}
_ => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "unrecognized endpoint type in stream")),
}
@ -339,7 +338,7 @@ impl FromStr for Endpoint {
let hash = base64::decode_config(hash, base64::URL_SAFE_NO_PAD);
if hash.is_ok() {
let hash = hash.unwrap();
if hash.len() == SHA512_HASH_SIZE {
if hash.len() == IDENTITY_FINGERPRINT_SIZE {
if endpoint_type == "zt" {
return Ok(Endpoint::ZeroTier(Address::from_str(address)?, hash.as_slice().try_into().unwrap()));
} else {

View file

@ -23,7 +23,7 @@ use crate::error::{InvalidFormatError, InvalidParameterError};
use crate::util::buffer::Buffer;
use crate::util::marshalable::Marshalable;
use crate::util::pool::{Pool, PoolFactory, Pooled};
use crate::vl1::protocol::{ADDRESS_SIZE, ADDRESS_SIZE_STRING, IDENTITY_POW_THRESHOLD};
use crate::vl1::protocol::{ADDRESS_SIZE, ADDRESS_SIZE_STRING, IDENTITY_FINGERPRINT_SIZE, IDENTITY_POW_THRESHOLD};
use crate::vl1::Address;
/// Secret keys associated with NIST P-384 public keys.
@ -67,7 +67,7 @@ pub struct Identity {
pub ed25519: [u8; ED25519_PUBLIC_KEY_SIZE],
pub p384: Option<IdentityP384Public>,
pub secret: Option<IdentitySecret>,
pub fingerprint: [u8; SHA512_HASH_SIZE],
pub fingerprint: [u8; IDENTITY_FINGERPRINT_SIZE],
}
#[inline(always)]
@ -136,7 +136,7 @@ impl Identity {
ed25519: ed25519_pub,
p384: None,
secret: Some(IdentitySecret { c25519, ed25519, p384: None }),
fingerprint: [0_u8; 64], // replaced in upgrade()
fingerprint: [0_u8; IDENTITY_FINGERPRINT_SIZE], // replaced in upgrade()
};
// Then "upgrade" to add NIST P-384 keys and compute fingerprint.
@ -174,7 +174,7 @@ impl Identity {
let _ = self_sign_buf.write_all(p384_ecdsa.public_key_bytes());
// Fingerprint includes only the above fields, so calc before appending the ECDSA signature.
self.fingerprint = SHA512::hash(self_sign_buf.as_slice());
self.fingerprint = SHA384::hash(self_sign_buf.as_slice());
// Sign all keys including the x25519 ones with the new P-384 keys.
let ecdsa_self_signature = p384_ecdsa.sign(self_sign_buf.as_slice());
@ -505,7 +505,7 @@ impl FromStr for Identity {
return Err(InvalidFormatError);
}
let mut sha = SHA512::new();
let mut sha = SHA384::new();
sha.update(&address.to_bytes());
sha.update(&keys[0].as_slice()[0..64]);
if !keys[2].is_empty() {
@ -675,7 +675,7 @@ impl Marshalable for Identity {
}
let x25519_public = x25519_public.unwrap();
let mut sha = SHA512::new();
let mut sha = SHA384::new();
sha.update(&address.to_bytes());
sha.update(x25519_public.0);
sha.update(x25519_public.1);

View file

@ -107,6 +107,9 @@ pub const ADDRESS_SIZE_STRING: usize = 10;
/// Prefix indicating reserved addresses (that can't actually be addresses).
pub const ADDRESS_RESERVED_PREFIX: u8 = 0xff;
/// Size of an identity fingerprint (SHA384)
pub const IDENTITY_FINGERPRINT_SIZE: usize = 48;
pub mod packet_constants {
/// Size of packet header that lies outside the encryption envelope.
pub const HEADER_SIZE: usize = 27;