mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
More Rust tests, fixes, implementation of boilerplate like PartialEq...
This commit is contained in:
parent
d97643a390
commit
6221d8e84c
9 changed files with 145 additions and 16 deletions
|
@ -32,6 +32,15 @@ impl From<&str> for Address {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Address {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Address {}
|
||||
|
||||
impl serde::Serialize for Address {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
|
|
|
@ -25,7 +25,6 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
use crate::bindings::capi::ZT_CertificateError;
|
||||
|
||||
/// Maximum length of a string in a certificate (mostly for the certificate name fields).
|
||||
pub const CERTIFICATE_MAX_STRING_LENGTH: isize = ztcore::ZT_CERTIFICATE_MAX_STRING_LENGTH as isize;
|
||||
|
@ -44,6 +43,7 @@ pub const CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE: u32 = ztcore::ZT_C
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct CertificateSerialNo(pub [u8; 48]);
|
||||
|
||||
impl CertificateSerialNo {
|
||||
|
@ -128,7 +128,7 @@ impl<'de> serde::Deserialize<'de> for CertificateSerialNo {
|
|||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Type of certificate subject unique ID
|
||||
#[derive(FromPrimitive, ToPrimitive)]
|
||||
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
pub enum CertificateUniqueIdType {
|
||||
NistP384 = ztcore::ZT_CertificateUniqueIdType_ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384 as isize
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ impl<'de> serde::Deserialize<'de> for CertificateUniqueIdType {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct CertificateSubjectUniqueIdSecret {
|
||||
pub public: Vec<u8>,
|
||||
pub private: Vec<u8>,
|
||||
|
@ -293,7 +293,7 @@ impl<'de> serde::Deserialize<'de> for CertificateError {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct CertificateName {
|
||||
#[serde(rename = "serialNo")]
|
||||
pub serial_no: String,
|
||||
|
@ -383,7 +383,7 @@ impl CertificateName {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct CertificateNetwork {
|
||||
pub id: NetworkId,
|
||||
pub controller: Fingerprint,
|
||||
|
@ -413,7 +413,7 @@ impl CertificateNetwork {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct CertificateIdentity {
|
||||
pub identity: Identity,
|
||||
pub locator: Option<Locator>,
|
||||
|
@ -440,7 +440,7 @@ impl CertificateIdentity {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct CertificateSubject {
|
||||
pub timestamp: i64,
|
||||
pub identities: Vec<CertificateIdentity>,
|
||||
|
@ -614,7 +614,7 @@ impl CertificateSubject {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Certificate {
|
||||
#[serde(rename = "serialNo")]
|
||||
pub serial_no: CertificateSerialNo,
|
||||
|
@ -745,6 +745,8 @@ impl Certificate {
|
|||
}
|
||||
}
|
||||
|
||||
implement_to_from_json!(Certificate);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -765,9 +767,11 @@ mod tests {
|
|||
println!("certificate unique ID private: {}", hex::encode(uid.private).as_str());
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn cert_encoding_decoding() {
|
||||
fn cert_encode_decode() {
|
||||
let uid = CertificateSubjectUniqueIdSecret::new(CertificateUniqueIdType::NistP384);
|
||||
let id0 = Identity::new_generate(IdentityType::NistP384).ok().unwrap();
|
||||
|
||||
let mut cert = Certificate{
|
||||
serial_no: CertificateSerialNo::new(),
|
||||
flags: 1,
|
||||
|
@ -780,8 +784,46 @@ mod tests {
|
|||
max_path_length: 123,
|
||||
signature: Vec::new()
|
||||
};
|
||||
cert.serial_no.0[1] = 2;
|
||||
cert.serial_no.0[1] = 99;
|
||||
cert.subject.timestamp = 5;
|
||||
cert.subject.identities.push(CertificateIdentity{
|
||||
identity: id0.clone(),
|
||||
locator: None
|
||||
});
|
||||
cert.subject.networks.push(CertificateNetwork{
|
||||
id: NetworkId(0xdeadbeef),
|
||||
controller: id0.fingerprint()
|
||||
});
|
||||
cert.subject.certificates.push(CertificateSerialNo::new());
|
||||
cert.subject.update_urls.push(String::from("http://foo.bar"));
|
||||
cert.subject.name = CertificateName{
|
||||
serial_no: String::from("12345"),
|
||||
common_name: String::from("foo"),
|
||||
country: String::from("bar"),
|
||||
organization: String::from("baz"),
|
||||
unit: String::from("asdf"),
|
||||
locality: String::from("qwerty"),
|
||||
province: String::from("province"),
|
||||
street_address: String::from("street address"),
|
||||
postal_code: String::from("postal code"),
|
||||
email: String::from("nobody@nowhere.org"),
|
||||
url: String::from("https://www.zerotier.com/"),
|
||||
host: String::from("zerotier.com")
|
||||
};
|
||||
|
||||
//println!("{}", cert.to_json().as_str());
|
||||
|
||||
unsafe {
|
||||
let cert_capi = cert.to_capi();
|
||||
let cert2 = Certificate::new_from_capi(&cert_capi.certificate);
|
||||
assert!(cert == cert2);
|
||||
//println!("{}", cert2.to_json().as_str());
|
||||
}
|
||||
|
||||
{
|
||||
let cert2 = Certificate::new_from_json(cert.to_json().as_str());
|
||||
assert!(cert2.is_ok());
|
||||
assert!(cert2.ok().unwrap() == cert);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -92,6 +92,14 @@ impl ToString for Endpoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Endpoint {
|
||||
fn eq(&self, other: &Endpoint) -> bool {
|
||||
self.to_string() == other.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Endpoint {}
|
||||
|
||||
impl serde::Serialize for Endpoint {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
|
|
|
@ -18,6 +18,7 @@ use std::os::raw::{c_char, c_int};
|
|||
use crate::*;
|
||||
use crate::bindings::capi as ztcore;
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct Fingerprint {
|
||||
pub address: Address,
|
||||
pub hash: [u8; 48]
|
||||
|
|
|
@ -87,7 +87,7 @@ impl Identity {
|
|||
|
||||
/// Convert to a string and include the private key if present.
|
||||
/// If the private key is not present this is the same as to_string().
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn to_secret_string(&self) -> String {
|
||||
self.intl_to_string(true)
|
||||
}
|
||||
|
@ -150,6 +150,14 @@ impl Identity {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Identity {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.intl_to_string(false) == other.intl_to_string(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Identity {}
|
||||
|
||||
impl Clone for Identity {
|
||||
fn clone(&self) -> Identity {
|
||||
unsafe {
|
||||
|
@ -169,7 +177,7 @@ impl Drop for Identity {
|
|||
}
|
||||
|
||||
impl ToString for Identity {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn to_string(&self) -> String {
|
||||
self.intl_to_string(false)
|
||||
}
|
||||
|
@ -208,12 +216,14 @@ impl<'de> serde::Deserialize<'de> for Identity {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::*;
|
||||
use crate::StateObjectType::IdentitySecret;
|
||||
|
||||
#[test]
|
||||
fn identity() {
|
||||
let test1 = Identity::new_generate(IdentityType::Curve25519);
|
||||
assert!(test1.is_ok());
|
||||
let test1 = test1.ok().unwrap();
|
||||
assert!(test1.has_private());
|
||||
|
||||
let test2 = Identity::new_generate(IdentityType::NistP384);
|
||||
assert!(test2.is_ok());
|
||||
|
@ -221,5 +231,40 @@ mod tests {
|
|||
|
||||
println!("test type 0: {}", test1.to_secret_string());
|
||||
println!("test type 1: {}", test2.to_secret_string());
|
||||
|
||||
assert!(test1.clone() == test1);
|
||||
|
||||
let test12 = Identity::new_from_string(test1.to_string().as_str());
|
||||
assert!(test12.is_ok());
|
||||
let test12 = test12.ok().unwrap();
|
||||
assert!(!test12.has_private());
|
||||
let test22 = Identity::new_from_string(test2.to_string().as_str());
|
||||
assert!(test22.is_ok());
|
||||
let test22 = test22.ok().unwrap();
|
||||
assert!(test1 == test12);
|
||||
assert!(test2 == test22);
|
||||
|
||||
println!("test type 0, from string: {}", test12.to_string());
|
||||
println!("test type 1, from string: {}", test22.to_string());
|
||||
|
||||
let from_str_fail = Identity::new_from_string("asdf:foo:invalid");
|
||||
assert!(from_str_fail.is_err());
|
||||
|
||||
let mut to_sign: [u8; 4] = [ 1,2,3,4 ];
|
||||
|
||||
let signed = test1.sign(&to_sign);
|
||||
assert!(signed.is_ok());
|
||||
let signed = signed.ok().unwrap();
|
||||
assert!(test1.verify(&to_sign, signed.as_ref()));
|
||||
to_sign[0] = 2;
|
||||
assert!(!test1.verify(&to_sign, signed.as_ref()));
|
||||
to_sign[0] = 1;
|
||||
|
||||
let signed = test2.sign(&to_sign);
|
||||
assert!(signed.is_ok());
|
||||
let signed = signed.ok().unwrap();
|
||||
assert!(test2.verify(&to_sign, signed.as_ref()));
|
||||
to_sign[0] = 2;
|
||||
assert!(!test2.verify(&to_sign, signed.as_ref()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,7 +183,6 @@ pub unsafe fn cstr_to_string(cstr: *const c_char, max_len: isize) -> String {
|
|||
String::new()
|
||||
}
|
||||
|
||||
/*
|
||||
#[macro_export(crate)]
|
||||
macro_rules! implement_to_from_json {
|
||||
($struct_name:ident) => {
|
||||
|
@ -206,4 +205,3 @@ macro_rules! implement_to_from_json {
|
|||
}
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -96,6 +96,14 @@ impl ToString for Locator {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Locator {
|
||||
fn eq(&self, other: &Locator) -> bool {
|
||||
self.to_string() == other.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Locator {}
|
||||
|
||||
impl serde::Serialize for Locator {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
|
|
|
@ -38,6 +38,15 @@ impl serde::Serialize for MAC {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for MAC {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for MAC {}
|
||||
|
||||
struct AddressVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for AddressVisitor {
|
||||
|
|
|
@ -41,6 +41,15 @@ impl From<&str> for NetworkId {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for NetworkId {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for NetworkId {}
|
||||
|
||||
impl serde::Serialize for NetworkId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
|
|
Loading…
Add table
Reference in a new issue