added secure_eq to a few places

This commit is contained in:
mamoniot 2022-12-19 11:37:31 -05:00
parent 7da9b6cec5
commit 9c9510ef36
7 changed files with 25 additions and 18 deletions

View file

@ -6,6 +6,7 @@ use std::sync::{Arc, Mutex, RwLock, Weak};
use tokio::time::{Duration, Instant}; use tokio::time::{Duration, Instant};
use zerotier_crypto::secure_eq;
use zerotier_network_hypervisor::protocol; use zerotier_network_hypervisor::protocol;
use zerotier_network_hypervisor::protocol::{PacketBuffer, DEFAULT_MULTICAST_LIMIT, ZEROTIER_VIRTUAL_NETWORK_DEFAULT_MTU}; use zerotier_network_hypervisor::protocol::{PacketBuffer, DEFAULT_MULTICAST_LIMIT, ZEROTIER_VIRTUAL_NETWORK_DEFAULT_MTU};
use zerotier_network_hypervisor::vl1::*; use zerotier_network_hypervisor::vl1::*;
@ -292,7 +293,7 @@ impl Controller {
} }
if let Some(pinned_fingerprint) = member.identity_fingerprint.as_ref() { if let Some(pinned_fingerprint) = member.identity_fingerprint.as_ref() {
if pinned_fingerprint.as_bytes().eq(&source_identity.fingerprint) { if secure_eq(pinned_fingerprint.as_bytes(), &source_identity.fingerprint) {
if member.identity.is_none() { if member.identity.is_none() {
// Learn the FULL identity if the fingerprint is pinned and they match. This // Learn the FULL identity if the fingerprint is pinned and they match. This
// lets us add members by address/fingerprint with full SHA384 identity // lets us add members by address/fingerprint with full SHA384 identity
@ -370,12 +371,12 @@ impl Controller {
// Make sure these agree. It should be impossible to end up with a member that's authorized and // Make sure these agree. It should be impossible to end up with a member that's authorized and
// whose identity and identity fingerprint don't match. // whose identity and identity fingerprint don't match.
if !member if !secure_eq(&member
.identity .identity
.as_ref() .as_ref()
.unwrap() .unwrap()
.fingerprint .fingerprint,
.eq(member.identity_fingerprint.as_ref().unwrap().as_bytes()) member.identity_fingerprint.as_ref().unwrap().as_bytes())
{ {
debug_assert!(false); debug_assert!(false);
return Ok((AuthenticationResult::RejectedDueToError, None)); return Ok((AuthenticationResult::RejectedDueToError, None));

View file

@ -1,5 +1,6 @@
use async_trait::async_trait; use async_trait::async_trait;
use zerotier_crypto::secure_eq;
use zerotier_network_hypervisor::vl1::{Address, InetAddress, NodeStorage}; use zerotier_network_hypervisor::vl1::{Address, InetAddress, NodeStorage};
use zerotier_network_hypervisor::vl2::NetworkId; use zerotier_network_hypervisor::vl2::NetworkId;
@ -70,7 +71,7 @@ pub trait Database: Sync + Send + NodeStorage + 'static {
let members = self.list_members(network_id).await?; let members = self.list_members(network_id).await?;
for a in members.iter() { for a in members.iter() {
if let Some(m) = self.get_member(network_id, *a).await? { if let Some(m) = self.get_member(network_id, *a).await? {
if m.ip_assignments.iter().any(|ip2| ip2.ip_bytes().eq(ip.ip_bytes())) { if m.ip_assignments.iter().any(|ip2| secure_eq(ip2.ip_bytes(), ip.ip_bytes())) {
return Ok(true); return Ok(true);
} }
} }

View file

@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
use tokio_postgres::types::Type; use tokio_postgres::types::Type;
use tokio_postgres::{Client, Statement}; use tokio_postgres::{Client, Statement};
use zerotier_crypto::secure_eq;
use zerotier_crypto::verified::Verified; use zerotier_crypto::verified::Verified;
use zerotier_network_hypervisor::vl1::{Address, Identity, InetAddress, NodeStorage}; use zerotier_network_hypervisor::vl1::{Address, Identity, InetAddress, NodeStorage};
@ -434,7 +435,7 @@ impl Database for PostgresDatabase {
let members = self.list_members(network_id).await?; let members = self.list_members(network_id).await?;
for a in members.iter() { for a in members.iter() {
if let Some(m) = self.get_member(network_id, *a).await? { if let Some(m) = self.get_member(network_id, *a).await? {
if m.ip_assignments.iter().any(|ip2| ip2.ip_bytes().eq(ip.ip_bytes())) { if m.ip_assignments.iter().any(|ip2| secure_eq(ip2.ip_bytes(), ip.ip_bytes())) {
return Ok(true); return Ok(true);
} }
} }

View file

@ -6,6 +6,8 @@ mod fruit_flavored {
use std::os::raw::{c_int, c_void}; use std::os::raw::{c_int, c_void};
use std::ptr::{null, null_mut}; use std::ptr::{null, null_mut};
use crate::secure_eq;
#[allow(non_upper_case_globals, unused)] #[allow(non_upper_case_globals, unused)]
const kCCModeECB: i32 = 1; const kCCModeECB: i32 = 1;
#[allow(non_upper_case_globals, unused)] #[allow(non_upper_case_globals, unused)]
@ -288,7 +290,7 @@ mod fruit_flavored {
#[inline(always)] #[inline(always)]
pub fn finish_decrypt(&mut self, expected_tag: &[u8]) -> bool { pub fn finish_decrypt(&mut self, expected_tag: &[u8]) -> bool {
self.finish_encrypt().eq(expected_tag) secure_eq(&self.finish_encrypt(), expected_tag)
} }
} }

View file

@ -32,6 +32,7 @@ mod openssl_based {
use crate::hash::SHA384; use crate::hash::SHA384;
use crate::secret::Secret; use crate::secret::Secret;
use crate::secure_eq;
use super::{P384_ECDH_SHARED_SECRET_SIZE, P384_ECDSA_SIGNATURE_SIZE, P384_PUBLIC_KEY_SIZE, P384_SECRET_KEY_SIZE}; use super::{P384_ECDH_SHARED_SECRET_SIZE, P384_ECDSA_SIGNATURE_SIZE, P384_PUBLIC_KEY_SIZE, P384_SECRET_KEY_SIZE};
@ -213,7 +214,7 @@ mod openssl_based {
impl PartialEq for P384KeyPair { impl PartialEq for P384KeyPair {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.pair.private_key().eq(other.pair.private_key()) && self.public.bytes.eq(&other.public.bytes) self.pair.private_key().eq(other.pair.private_key()) && secure_eq(&self.public.bytes, &other.public.bytes)
} }
} }
@ -1355,7 +1356,7 @@ pub use openssl_based::*;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::p384::P384KeyPair; use crate::{p384::P384KeyPair, secure_eq};
#[test] #[test]
fn generate_sign_verify_agree() { fn generate_sign_verify_agree() {
@ -1372,7 +1373,7 @@ mod tests {
let sec0 = kp.agree(kp2.public_key()).unwrap(); let sec0 = kp.agree(kp2.public_key()).unwrap();
let sec1 = kp2.agree(kp.public_key()).unwrap(); let sec1 = kp2.agree(kp.public_key()).unwrap();
if !sec0.eq(&sec1) { if !secure_eq(&sec0, &sec1) {
panic!("ECDH secrets do not match"); panic!("ECDH secrets do not match");
} }

View file

@ -9,7 +9,7 @@ use std::str::FromStr;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use zerotier_crypto::hash::*; use zerotier_crypto::{hash::*, secure_eq};
use zerotier_crypto::p384::*; use zerotier_crypto::p384::*;
use zerotier_crypto::salsa::Salsa; use zerotier_crypto::salsa::Salsa;
use zerotier_crypto::secret::Secret; use zerotier_crypto::secret::Secret;
@ -801,7 +801,7 @@ impl Marshalable for Identity {
impl PartialEq for Identity { impl PartialEq for Identity {
#[inline(always)] #[inline(always)]
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.fingerprint.eq(&other.fingerprint) secure_eq(&self.fingerprint, &other.fingerprint)
} }
} }
@ -904,17 +904,17 @@ mod tests {
) )
.unwrap().validate().unwrap(); .unwrap().validate().unwrap();
let self_agree = id.agree(&id).unwrap(); let self_agree = id.agree(&id).unwrap();
assert!(self_agree_expected.as_slice().eq(&self_agree.as_bytes()[..48])); debug_assert!(self_agree_expected.as_slice().eq(&self_agree.as_bytes()[..48]));
// Identity should be upgradable. // Identity should be upgradable.
let mut upgraded = id.clone(); let mut upgraded = id.clone();
assert!(upgraded.upgrade().unwrap()); debug_assert!(upgraded.upgrade().unwrap());
// Upgraded identity should generate the same result when agreeing with the old non-upgraded identity. // Upgraded identity should generate the same result when agreeing with the old non-upgraded identity.
let self_agree = id.agree(&upgraded).unwrap(); let self_agree = id.agree(&upgraded).unwrap();
assert!(self_agree_expected.as_slice().eq(&self_agree.as_bytes()[..48])); debug_assert!(self_agree_expected.as_slice().eq(&self_agree.as_bytes()[..48]));
let self_agree = upgraded.agree(&id).unwrap(); let self_agree = upgraded.agree(&id).unwrap();
assert!(self_agree_expected.as_slice().eq(&self_agree.as_bytes()[..48])); debug_assert!(self_agree_expected.as_slice().eq(&self_agree.as_bytes()[..48]));
} }
const GOOD_V0_IDENTITIES: [&'static str; 4] = [ const GOOD_V0_IDENTITIES: [&'static str; 4] = [
@ -936,7 +936,7 @@ mod tests {
assert!(gen.agree(&gen).is_some()); assert!(gen.agree(&gen).is_some());
let bytes = gen.to_secret_bytes().unwrap(); let bytes = gen.to_secret_bytes().unwrap();
let string = gen.to_secret_string(); let string = gen.to_secret_string();
assert!(Identity::from_str(string.as_str()).unwrap().eq(&gen)); debug_assert!(Identity::from_str(string.as_str()).unwrap().eq(&gen));
let gen_unmarshaled = Identity::from_bytes(bytes.as_bytes()).unwrap(); let gen_unmarshaled = Identity::from_bytes(bytes.as_bytes()).unwrap();
assert!(gen_unmarshaled.secret.is_some()); assert!(gen_unmarshaled.secret.is_some());

View file

@ -7,6 +7,7 @@ use crate::vl2::NetworkId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use zerotier_crypto::hash::SHA384; use zerotier_crypto::hash::SHA384;
use zerotier_crypto::secure_eq;
use zerotier_crypto::verified::Verified; use zerotier_crypto::verified::Verified;
use zerotier_utils::arrayvec::ArrayVec; use zerotier_utils::arrayvec::ArrayVec;
use zerotier_utils::blob::Blob; use zerotier_utils::blob::Blob;
@ -171,7 +172,7 @@ impl CertificateOfMembership {
/// Verify this certificate of membership. /// Verify this certificate of membership.
pub fn verify(self, issuer: &Identity, expect_issued_to: &Identity) -> Option<Verified<Self>> { pub fn verify(self, issuer: &Identity, expect_issued_to: &Identity) -> Option<Verified<Self>> {
if Self::v1_proto_issued_to_fingerprint(expect_issued_to).eq(&self.issued_to_fingerprint.as_bytes()[..32]) { if secure_eq(&Self::v1_proto_issued_to_fingerprint(expect_issued_to), &self.issued_to_fingerprint.as_bytes()[..32]) {
if issuer.verify(&self.v1_proto_get_qualifier_bytes(), self.signature.as_bytes()) { if issuer.verify(&self.v1_proto_get_qualifier_bytes(), self.signature.as_bytes()) {
return Some(Verified::assume_verified(self)); return Some(Verified::assume_verified(self));
} }