mirror of
https://github.com/zerotier/identity.git
synced 2026-05-22 16:29:03 -07:00
Add domain restricted signature API to identities.
This commit is contained in:
@@ -52,6 +52,9 @@ pub trait Identity:
|
||||
|
||||
/// Verify a signature made by this identity's corresponding secret.
|
||||
fn verify_signature(&self, data: &[u8], signature: &[u8]) -> bool;
|
||||
|
||||
/// Verify a signature with a domain restriction parameter.
|
||||
fn verify_domain_restricted_signature(&self, domain: &[u8], data: &[u8], signature: &[u8]) -> bool;
|
||||
}
|
||||
|
||||
/// Secret keys that correspond to a public Identity.
|
||||
@@ -71,6 +74,10 @@ pub trait IdentitySecret: Sync + Send + Clone + PartialEq + Eq + Serialize + Des
|
||||
|
||||
/// Cryptographically sign a message with this identity.
|
||||
fn sign(&self, data: &[u8]) -> Self::Signature;
|
||||
|
||||
/// Cryptographically sign a message with this identity.
|
||||
/// This version takes a domain parameter that helps defend against signature misuse
|
||||
fn sign_domain_restricted(&self, domain: &[u8], data: &[u8]) -> Self::Signature;
|
||||
}
|
||||
|
||||
mod base24;
|
||||
|
||||
+14
@@ -611,6 +611,15 @@ impl crate::Identity for Identity {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn verify_domain_restricted_signature(&self, domain: &[u8], data: &[u8], signature: &[u8]) -> bool {
|
||||
if let Ok(sig) = signature.try_into() {
|
||||
self.ecdsa.verify(domain, data, sig)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Secret NIST P-384 identity (also contains public).
|
||||
@@ -777,6 +786,11 @@ impl crate::IdentitySecret for IdentitySecret {
|
||||
fn sign(&self, data: &[u8]) -> Self::Signature {
|
||||
self.ecdsa.sign_raw(data)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sign_domain_restricted(&self, domain: &[u8], data: &[u8]) -> Self::Signature {
|
||||
self.ecdsa.sign(domain, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToFromBytes for IdentitySecret {
|
||||
|
||||
@@ -292,6 +292,11 @@ impl crate::Identity for Identity {
|
||||
fn verify_signature(&self, data: &[u8], signature: &[u8]) -> bool {
|
||||
ed25519_verify(&self.eddsa, signature, data)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn verify_domain_restricted_signature(&self, domain: &[u8], data: &[u8], signature: &[u8]) -> bool {
|
||||
ed25519_verify_domain_restricted(&self.eddsa, signature, domain, data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Identity {
|
||||
@@ -424,6 +429,16 @@ impl crate::IdentitySecret for IdentitySecret {
|
||||
fn sign(&self, data: &[u8]) -> Self::Signature {
|
||||
self.eddsa.sign_zt(data)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sign_domain_restricted(&self, domain: &[u8], data: &[u8]) -> Self::Signature {
|
||||
// Note: this identity type returns a 96-byte signature for backward compatibility with old ZT, but
|
||||
// the last 32 bytes of this signature aren't actually used. Since the domain restricted version is
|
||||
// not used with old ZT, just leave these bytes zero. Only the first 64 bytes matter.
|
||||
let mut tmp = [0u8; 96];
|
||||
tmp[..64].copy_from_slice(&self.eddsa.sign_domain_restricted(domain, data));
|
||||
tmp
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Zeroize, ZeroizeOnDrop)]
|
||||
|
||||
Reference in New Issue
Block a user