added identifier

This commit is contained in:
Monica Moniot
2024-02-26 12:28:44 -05:00
parent 83778c3ebc
commit b123891bd8
7 changed files with 195 additions and 16 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ authors = ["ZeroTier, Inc. <contact@zerotier.com>"]
edition = "2021"
license = "MPL-2.0"
name = "zerotier-identity"
version = "0.1.1"
version = "0.1.2"
[dependencies]
serde = { version = "1.0.183", features = ["derive"], default-features = false }
-13
View File
@@ -5,20 +5,7 @@
* (c) ZeroTier, Inc.
* https://www.zerotier.com/
*/
use std::fmt::Debug;
use std::hash::Hash;
use std::mem::{size_of, transmute};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::p384::*;
use zerotier_common_utils::blob::Blob;
use zerotier_common_utils::error::InvalidParameterError;
use zerotier_common_utils::tofrombytes::ToFromBytes;
use crate::base62;
use crate::ADDRESS_ERR;
// Implementation note: the addresses use u64 arrays that are actually treated as flat byte
// array memory arenas in order to optimize for fast lookup when these are used as map keys.
+170
View File
@@ -0,0 +1,170 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* (c) ZeroTier, Inc.
* https://www.zerotier.com/
*/
use crate::p384::*;
#[derive(Debug, Clone, Hash)]
pub enum PeerIdentifier {
Identity(Identity),
Address(Address),
Short(ShortAddress),
}
#[derive(Debug, Clone, Hash)]
pub enum PeerIdentifierRef<'a> {
Identity(&'a Identity),
Address(&'a Address),
Short(ShortAddress),
}
impl PeerIdentifier {
pub fn matches(&self, identity: &Identity) -> bool {
match self {
PeerIdentifier::Identity(id) => id.eq(identity),
PeerIdentifier::Address(id) => identity.address.eq(id),
PeerIdentifier::Short(id) => identity.address.prefix().eq(id),
}
}
pub fn prefix(&self) -> &ShortAddress {
match self {
PeerIdentifier::Identity(id) => id.address.prefix(),
PeerIdentifier::Address(id) => id.prefix(),
PeerIdentifier::Short(id) => id,
}
}
pub fn address(&self) -> AnyAddress {
match self {
PeerIdentifier::Identity(id) => id.address.into(),
PeerIdentifier::Address(id) => id.into(),
PeerIdentifier::Short(id) => id.into(),
}
}
/// Returns `true` if `other` contains the most complete version of the identity between
/// `self` and `other`.
/// Otherwise returns `false`.
/// This function will debug panic if `self` and `other` are not identifiers for the same peer.
/// The caller must check for equality before calling this function.
/// TODO: make this function take into account identity lifetime.
pub fn upgrade_check(&self, other: &Self) -> bool {
debug_assert_eq!(self, other);
use PeerIdentifier::*;
match (self, other) {
(Identity(_), _) => false,
(_, Identity(_)) => true,
(Short(_), Address(_)) => true,
_ => false,
}
}
}
/// Does not preserve transitivity.
impl std::cmp::PartialEq for PeerIdentifier {
fn eq(&self, other: &Self) -> bool {
use PeerIdentifier::*;
match (self, other) {
(Identity(identity), id) | (id, Identity(identity)) => id.matches(identity),
(Address(addr0), Address(addr1)) => addr0.eq(addr1),
(Address(addr0), Short(addr1)) => addr0.prefix().eq(addr1),
(Short(addr0), Address(addr1)) => addr0.eq(addr1.prefix()),
(Short(addr0), Short(addr1)) => addr0.eq(addr1),
}
}
}
impl From<Address> for PeerIdentifier {
fn from(value: Address) -> Self {
Self::Address(value)
}
}
impl From<ShortAddress> for PeerIdentifier {
fn from(value: ShortAddress) -> Self {
Self::Short(value)
}
}
impl From<&Address> for PeerIdentifier {
fn from(value: &Address) -> Self {
Self::Address(*value)
}
}
impl From<&ShortAddress> for PeerIdentifier {
fn from(value: &ShortAddress) -> Self {
Self::Short(*value)
}
}
impl From<Identity> for PeerIdentifier {
fn from(value: Identity) -> Self {
Self::Identity(value)
}
}
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy, Hash)]
pub enum AnyAddress {
Address(Address),
Short(ShortAddress),
}
impl AnyAddress {
pub fn matches(&self, identity: &Identity) -> bool {
match self {
AnyAddress::Address(id) => identity.address.eq(id),
AnyAddress::Short(id) => identity.address.prefix().eq(id),
}
}
pub fn prefix(&self) -> &ShortAddress {
match self {
AnyAddress::Address(id) => id.prefix(),
AnyAddress::Short(id) => id,
}
}
/// Returns `true` if `other` contains the most complete version of the identity between
/// `self` and `other`.
/// Otherwise returns `false`.
/// This function will debug panic if `self` and `other` are not identifiers for the same peer.
/// The caller must check for equality before calling this function.
/// TODO: make this function take into account identity lifetime.
pub fn upgrade_check(&self, other: &Self) -> bool {
debug_assert_eq!(self, other);
use AnyAddress::*;
match (self, other) {
(Short(_), Address(_)) => true,
_ => false,
}
}
}
/// Does not preserve transitivity.
impl std::cmp::PartialEq for AnyAddress {
fn eq(&self, other: &Self) -> bool {
use AnyAddress::*;
match (self, other) {
(Address(addr0), Address(addr1)) => addr0.eq(addr1),
(Address(addr0), Short(addr1)) => addr0.prefix().eq(addr1),
(Short(addr0), Address(addr1)) => addr0.eq(addr1.prefix()),
(Short(addr0), Short(addr1)) => addr0.eq(addr1),
}
}
}
impl From<Address> for AnyAddress {
fn from(value: Address) -> Self {
Self::Address(value)
}
}
impl From<ShortAddress> for AnyAddress {
fn from(value: ShortAddress) -> Self {
Self::Short(value)
}
}
impl From<&Address> for AnyAddress {
fn from(value: &Address) -> Self {
Self::Address(*value)
}
}
impl From<&ShortAddress> for AnyAddress {
fn from(value: &ShortAddress) -> Self {
Self::Short(*value)
}
}
+7
View File
@@ -1,3 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* (c) ZeroTier, Inc.
* https://www.zerotier.com/
*/
use crate::p384::*;
const TIMESTAMP_START: usize = P384_PUBLIC_KEY_SIZE;
+7
View File
@@ -1,3 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* (c) ZeroTier, Inc.
* https://www.zerotier.com/
*/
use crate::p384::*;
/// Secret NIST P-384 identity (also contains public).
+3 -2
View File
@@ -5,7 +5,6 @@
* (c) ZeroTier, Inc.
* https://www.zerotier.com/
*/
use std::fmt::Debug;
use std::hash::Hash;
use std::io::Write;
@@ -18,15 +17,17 @@ use crate::zeroize::{Zeroize, ZeroizeOnDrop};
use zerotier_common_utils::{base64, blob::Blob, error::InvalidParameterError, tofrombytes::ToFromBytes};
use zerotier_crypto_glue::{hash::SHA384, p384::*};
use crate::base24;
use crate::{base24, base62};
use crate::{ADDRESS_ERR, IDENTITY_ERR};
mod address;
mod identifier;
mod identity;
mod identity_secret;
mod short_address;
pub use address::*;
pub use identifier::*;
pub use identity::*;
pub use identity_secret::*;
pub use short_address::*;
+7
View File
@@ -1,3 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* (c) ZeroTier, Inc.
* https://www.zerotier.com/
*/
use crate::p384::*;
/// 128-bit short address prefix.