V2 network controller now provides a reply that at least parses!

This commit is contained in:
Adam Ierymenko 2022-10-28 16:03:06 -04:00
parent bc31c35ae8
commit bc7a9e41bf
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
5 changed files with 39 additions and 33 deletions

View file

@ -276,14 +276,16 @@ impl Controller {
tags: HashMap::new(),
};
let mut coo = vl2::v1::CertificateOfOwnership::new(network_id, now, source_identity.address);
for ip in nc.static_ips.iter() {
coo.add_ip(ip);
if !nc.static_ips.is_empty() {
let mut coo = vl2::v1::CertificateOfOwnership::new(network_id, now, source_identity.address);
for ip in nc.static_ips.iter() {
coo.add_ip(ip);
}
if !coo.sign(&self.local_identity, &source_identity) {
return Ok((AuthorizationResult::RejectedDueToError, None, None));
}
v1cred.certificates_of_ownership.push(coo);
}
if !coo.sign(&self.local_identity, &source_identity) {
return Ok((AuthorizationResult::RejectedDueToError, None, None));
}
v1cred.certificates_of_ownership.push(coo);
for (id, value) in member.tags.iter() {
let tag = vl2::v1::Tag::new(*id, *value, &self.local_identity, network_id, &source_identity, now);
@ -417,6 +419,7 @@ impl InnerProtocol for Controller {
let (result, config) = match self2.get_network_config(&peer.identity, network_id, now).await {
Result::Ok((result, Some(config), revocations)) => {
dump_network_config(&config);
self2.send_network_config(peer.as_ref(), &config, Some(message_id));
(result, Some(config))
}

View file

@ -113,6 +113,7 @@ pub struct Network {
pub min_supported_version: Option<u32>,
/// MTU inside the virtual network, default of 2800 is used if not set.
#[serde(skip_serializing_if = "Option::is_none")]
pub mtu: Option<u16>,
/// If true the network has access control, which is usually what you want.

View file

@ -122,6 +122,8 @@ impl NetworkConfig {
pub fn v1_proto_to_dictionary(&self, controller_identity: &Identity) -> Option<Dictionary> {
let mut d = Dictionary::new();
d.set_u64(proto_v1_field_name::network_config::VERSION, 6);
d.set_str(
proto_v1_field_name::network_config::NETWORK_ID,
self.network_id.to_string().as_str(),
@ -191,7 +193,11 @@ impl NetworkConfig {
if let Some(v1cred) = self.v1_credentials.as_ref() {
d.set_bytes(
proto_v1_field_name::network_config::CERTIFICATE_OF_MEMBERSHIP,
v1cred.certificate_of_membership.to_bytes()?.as_bytes().to_vec(),
v1cred
.certificate_of_membership
.to_bytes(self.network_id.network_controller())
.as_bytes()
.to_vec(),
);
if !v1cred.certificates_of_ownership.is_empty() {

View file

@ -19,7 +19,7 @@ pub struct CertificateOfMembership {
pub timestamp: i64,
pub max_delta: i64,
pub issued_to: Address,
pub issued_to_fingerprint: Blob<{ Identity::FINGERPRINT_SIZE }>,
pub issued_to_fingerprint: Blob<32>,
pub signature: ArrayVec<u8, { Identity::MAX_SIGNATURE_SIZE }>,
}
@ -36,7 +36,7 @@ impl CertificateOfMembership {
signature: ArrayVec::new(),
};
com.issued_to_fingerprint = Blob::from(Self::v1_proto_issued_to_fingerprint(issued_to, Some(issuer.address)));
com.issued_to_fingerprint = Blob::from(Self::v1_proto_issued_to_fingerprint(issued_to));
if let Some(signature) = issuer.sign(&com.v1_proto_get_qualifier_bytes(), true) {
com.signature = signature;
Some(com)
@ -77,32 +77,25 @@ impl CertificateOfMembership {
*memory::as_byte_array(&q)
}
fn v1_proto_issued_to_fingerprint(issued_to: &Identity, signed_by: Option<Address>) -> [u8; 48] {
/// Get the identity fingerprint used in V1, which only covers the curve25519 keys.
fn v1_proto_issued_to_fingerprint(issued_to: &Identity) -> [u8; 32] {
let mut v1_signee_hasher = SHA384::new();
v1_signee_hasher.update(&issued_to.address.to_bytes());
v1_signee_hasher.update(&issued_to.x25519);
v1_signee_hasher.update(&issued_to.ed25519);
let mut fp = v1_signee_hasher.finish();
fp[32..].fill(0);
if let Some(signed_by) = signed_by {
fp[32..37].copy_from_slice(&signed_by.to_bytes());
}
fp
(&v1_signee_hasher.finish()[..32]).try_into().unwrap()
}
/// Get this certificate of membership in byte encoded format.
pub fn to_bytes(&self) -> Option<ArrayVec<u8, 384>> {
if self.signature.len() == 96 {
let mut v = ArrayVec::new();
v.push(1); // version byte from v1 protocol
v.push(0);
v.push(7); // 7 qualifiers, big-endian 16-bit
let _ = v.write_all(&self.v1_proto_get_qualifier_bytes());
let _ = v.write_all(&self.issued_to_fingerprint.as_bytes()[32..38]); // issuer address
let _ = v.write_all(self.signature.as_bytes());
return Some(v);
}
return None;
pub fn to_bytes(&self, controller_address: Address) -> ArrayVec<u8, 384> {
let mut v = ArrayVec::new();
v.push(1); // version byte from v1 protocol
v.push(0);
v.push(7); // 7 qualifiers, big-endian 16-bit
let _ = v.write_all(&self.v1_proto_get_qualifier_bytes());
let _ = v.write_all(&controller_address.to_bytes());
let _ = v.write_all(self.signature.as_bytes());
v
}
/// Decode a V1 legacy format certificate of membership in byte format.
@ -117,7 +110,7 @@ impl CertificateOfMembership {
return Err(InvalidParameterError("incomplete"));
}
let (mut network_id, mut issued_to, mut timestamp, mut max_delta, mut v1_fingerprint) = (0, 0, 0, 0, [0u8; 48]);
let (mut network_id, mut issued_to, mut timestamp, mut max_delta, mut v1_fingerprint) = (0, 0, 0, 0, [0u8; 32]);
for _ in 0..qualifier_count {
let qt = u64::from_be_bytes(b[..8].try_into().unwrap());
let q: [u8; 8] = b[8..16].try_into().unwrap();
@ -150,8 +143,7 @@ impl CertificateOfMembership {
b = &b[24..];
}
v1_fingerprint[32..38].copy_from_slice(&b[..5]); // issuer address
b = &b[5..];
b = &b[5..]; // skip issuer address which is always the controller
Ok(Self {
network_id: NetworkId::from_u64(network_id).ok_or(InvalidParameterError("invalid network ID"))?,
@ -169,7 +161,7 @@ impl CertificateOfMembership {
/// Verify this certificate of membership.
pub fn verify(self, issuer: &Identity, expect_issued_to: &Identity) -> Option<Verified<Self>> {
if Self::v1_proto_issued_to_fingerprint(expect_issued_to, None).eq(&self.issued_to_fingerprint.as_bytes()[..32]) {
if Self::v1_proto_issued_to_fingerprint(expect_issued_to).eq(&self.issued_to_fingerprint.as_bytes()[..32]) {
if issuer.verify(&self.v1_proto_get_qualifier_bytes(), self.signature.as_bytes()) {
return Some(Verified(self));
}

View file

@ -65,6 +65,7 @@ impl<const L: usize> ToString for Blob<L> {
}
impl<const L: usize> Serialize for Blob<L> {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
@ -82,10 +83,12 @@ struct BlobVisitor<const L: usize>;
impl<'de, const L: usize> serde::de::Visitor<'de> for BlobVisitor<L> {
type Value = Blob<L>;
#[inline]
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str(format!("array of {} bytes", L).as_str())
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
@ -99,6 +102,7 @@ impl<'de, const L: usize> serde::de::Visitor<'de> for BlobVisitor<L> {
}
impl<'de, const L: usize> Deserialize<'de> for Blob<L> {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Blob<L>, D::Error>
where
D: Deserializer<'de>,