From c160383170c7853e1702504de55bd38330694fbb Mon Sep 17 00:00:00 2001 From: Michael Rossberg Date: Sat, 15 Apr 2023 18:24:35 +0200 Subject: [PATCH 01/29] read AS numbers --- openssl-sys/src/handwritten/mod.rs | 2 + openssl-sys/src/handwritten/x509_sbgp.rs | 39 ++++++++++ openssl-sys/src/lib.rs | 2 + openssl-sys/src/x509_sbgp.rs | 9 +++ openssl/src/x509/mod.rs | 2 + openssl/src/x509/sbgp.rs | 99 ++++++++++++++++++++++++ systest/build.rs | 1 + 7 files changed, 154 insertions(+) create mode 100644 openssl-sys/src/handwritten/x509_sbgp.rs create mode 100644 openssl-sys/src/x509_sbgp.rs create mode 100644 openssl/src/x509/sbgp.rs diff --git a/openssl-sys/src/handwritten/mod.rs b/openssl-sys/src/handwritten/mod.rs index d3adfa5a13..292c0ecaa8 100644 --- a/openssl-sys/src/handwritten/mod.rs +++ b/openssl-sys/src/handwritten/mod.rs @@ -31,6 +31,7 @@ pub use self::stack::*; pub use self::tls1::*; pub use self::types::*; pub use self::x509::*; +pub use self::x509_sbgp::*; pub use self::x509_vfy::*; pub use self::x509v3::*; @@ -67,5 +68,6 @@ mod stack; mod tls1; mod types; mod x509; +mod x509_sbgp; mod x509_vfy; mod x509v3; diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs new file mode 100644 index 0000000000..ee709b90eb --- /dev/null +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -0,0 +1,39 @@ +use super::super::*; +use libc::*; + +#[repr(C)] +pub struct ASRange { + pub min: *mut ASN1_INTEGER, + pub max: *mut ASN1_INTEGER, +} + +#[repr(C)] +pub struct _ASIdOrRange { + pub type_: c_int, + pub u: ASIdOrRange_st_anon_union, +} + +#[repr(C)] +pub union ASIdOrRange_st_anon_union { + pub id: *mut ASN1_INTEGER, + pub range: *mut ASRange, +} + +stack!(stack_st_ASIdOrRange); + +#[repr(C)] +pub struct ASIdentifierChoice { + pub type_: c_int, + pub asIdsOrRanges: *mut stack_st_ASIdOrRange, +} + +#[repr(C)] +pub struct _ASIdentifiers { + pub asnum: *mut ASIdentifierChoice, + pub rdi: *mut ASIdentifierChoice, +} + +extern "C" { + pub fn ASIdentifiers_free(asi: *mut _ASIdentifiers); + pub fn ASIdOrRange_free(asi: *mut _ASIdOrRange); +} diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 0e23386fd3..0eacff2d30 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -64,6 +64,7 @@ mod openssl { pub use self::tls1::*; pub use self::types::*; pub use self::x509::*; + pub use self::x509_sbgp::*; pub use self::x509_vfy::*; pub use self::x509v3::*; @@ -94,6 +95,7 @@ mod openssl { mod tls1; mod types; mod x509; + mod x509_sbgp; mod x509_vfy; mod x509v3; diff --git a/openssl-sys/src/x509_sbgp.rs b/openssl-sys/src/x509_sbgp.rs new file mode 100644 index 0000000000..6f627c634b --- /dev/null +++ b/openssl-sys/src/x509_sbgp.rs @@ -0,0 +1,9 @@ +use libc::*; + +use super::*; + +pub const ASIdOrRange_id: c_int = 0; +pub const ASIdOrRange_range: c_int = 1; + +pub const ASIdentifierChoice_inherit: c_int = 0; +pub const ASIdentifierChoice_asIdsOrRanges: c_int = 1; diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 97242ff4d8..0a2a726bf7 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -44,6 +44,8 @@ use openssl_macros::corresponds; #[cfg(any(ossl102, libressl261))] pub mod verify; +pub mod sbgp; + pub mod extension; pub mod store; diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs new file mode 100644 index 0000000000..f105ab427b --- /dev/null +++ b/openssl/src/x509/sbgp.rs @@ -0,0 +1,99 @@ +use ffi::{ + ASIdOrRange_id, ASIdOrRange_range, ASIdentifierChoice_asIdsOrRanges, + ASIdentifierChoice_inherit, ASN1_INTEGER, +}; +use foreign_types::{ForeignType, ForeignTypeRef}; + +use crate::{ + asn1::Asn1IntegerRef, + stack::{StackRef, Stackable}, + util::{ForeignTypeExt, ForeignTypeRefExt}, +}; + +use super::X509; + +foreign_type_and_impl_send_sync! { + type CType = ffi::_ASIdOrRange; + fn drop = ffi::ASIdOrRange_free; + + /// The AS number extension of an `X509` certificate. + pub struct ASIdOrRange; + /// Reference to `ASIdOrRange`. + pub struct ASIdOrRangeRef; +} + +impl Stackable for ASIdOrRange { + type StackType = ffi::stack_st_ASIdOrRange; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::_ASIdentifiers; + fn drop = ffi::ASIdentifiers_free; + + /// The AS number extension of an `X509` certificate. + pub struct ASIdentifiers; + /// Reference to `ASIdentifiers`. + pub struct ASIdentifiersRef; +} + +impl ASIdentifiers { + pub fn inherited(&self) -> bool { + unsafe { + let asptr = self.0; + let asnum = (*asptr).asnum; + (*asnum).type_ == ASIdentifierChoice_inherit + } + } + + pub fn ranges(&self) -> Option> { + let mut r = Vec::new(); + unsafe { + let asptr = self.0; + let asnum = (*asptr).asnum; + if (*asnum).type_ == ASIdentifierChoice_asIdsOrRanges { + if let Some(s) = StackRef::::from_const_ptr_opt((*asnum).asIdsOrRanges) + { + for a_ptr in s { + let a = a_ptr.as_ptr(); + if (*a).type_ == ASIdOrRange_id { + let asn = Self::parse_asn1_integer((*a).u.id)?; + r.push((asn, asn)); + } else if (*a).type_ == ASIdOrRange_range { + let range = (*a).u.range; + let asn1 = Self::parse_asn1_integer((*range).min)?; + let asn2 = Self::parse_asn1_integer((*range).max)?; + r.push((asn1, asn2)); + } + } + } + } + } + Some(r) + } + + fn parse_asn1_integer(v: *mut ASN1_INTEGER) -> Option { + let v_parsed; + unsafe { + v_parsed = Asn1IntegerRef::from_ptr(v); + } + v_parsed.to_bn().ok()?.to_dec_str().ok()?.parse().ok() + } +} + +pub trait ExtractASN { + fn asn(&self) -> Option; +} + +impl ExtractASN for X509 { + fn asn(&self) -> Option { + unsafe { + let asn = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_sbgp_autonomousSysNum, + std::ptr::null_mut(), + std::ptr::null_mut(), + ); + ASIdentifiers::from_ptr_opt(asn as *mut _) + } + } +} diff --git a/systest/build.rs b/systest/build.rs index 53407eafad..ad41ca798e 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -118,6 +118,7 @@ fn main() { s == "ProbeResult" || s == "X509_OBJECT_data" || // inline union s == "DIST_POINT_NAME_st_anon_union" || // inline union + s == "_ASIdOrRange_st_anon_union" || // inline union s == "PKCS7_data" || s == "ASN1_TYPE_value" }); From 525dcbb40bf5ae91de2d45f502e982269fcd3a2d Mon Sep 17 00:00:00 2001 From: Michael Rossberg Date: Mon, 17 Apr 2023 16:58:22 +0200 Subject: [PATCH 02/29] IP address range parsing --- openssl-sys/src/handwritten/x509_sbgp.rs | 148 ++++++++++++++++++++++ openssl-sys/src/x509_sbgp.rs | 9 ++ openssl/src/x509/sbgp.rs | 149 ++++++++++++++++++++--- 3 files changed, 287 insertions(+), 19 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index ee709b90eb..e4aab2c780 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -33,7 +33,155 @@ pub struct _ASIdentifiers { pub rdi: *mut ASIdentifierChoice, } +#[repr(C)] +pub struct IPAddressRange { + pub min: *mut ASN1_BIT_STRING, + pub max: *mut ASN1_BIT_STRING, +} + +#[repr(C)] +pub struct _IPAddressOrRange { + pub type_: c_int, + pub u: IPAddressOrRange_st_anon_union, +} +#[repr(C)] +pub union IPAddressOrRange_st_anon_union { + pub addressPrefix: *mut ASN1_BIT_STRING, + pub addressRange: *mut IPAddressRange, +} + +stack!(stack_st_IPAddressOrRange); +type IPAddressOrRanges = stack_st_IPAddressOrRange; + +#[repr(C)] +pub struct IPAddressChoice { + pub type_: c_int, + pub addressesOrRanges: *mut IPAddressOrRanges, +} + +#[repr(C)] +pub struct _IPAddressFamily { + pub addressFamily: *mut ASN1_OCTET_STRING, + pub ipAddressChoice: *mut IPAddressChoice, +} + +stack!(stack_st_IPAddressFamily); +type IPAddrBlocks = stack_st_IPAddressFamily; + extern "C" { pub fn ASIdentifiers_free(asi: *mut _ASIdentifiers); pub fn ASIdOrRange_free(asi: *mut _ASIdOrRange); + pub fn IPAddressFamily_free(asi: *mut _IPAddressFamily); + pub fn IPAddressOrRange_free(asi: *mut _IPAddressOrRange); +} + +pub fn X509v3_addr_get_afi(f: *mut _IPAddressFamily) -> c_int { + unsafe { + if f.is_null() { + 0 + } else { + let d = (*f).addressFamily as *mut ASN1_STRING; + if d.is_null() || ASN1_STRING_length(d) < 2 || ASN1_STRING_get0_data(d).is_null() { + 0 + } else { + let raw = ASN1_STRING_get0_data(d); + ((*raw.offset(0) as i32) << 8) | *raw.offset(1) as i32 + } + } + } +} + +fn length_from_afi(afi: c_int) -> isize { + match afi { + IANA_AFI_IPV4 => 4, + IANA_AFI_IPV6 => 16, + _ => 0, + } +} + +struct ASN1_STRING_internal { + length: c_int, + type_: c_int, + data: *mut u8, + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + flags: c_int, +} +/* + * Expand the bitstring form of an address into a raw byte array. + * At the moment this is coded for simplicity, not speed. + */ +fn addr_expand(addr: *mut u8, bs: *const ASN1_BIT_STRING, length: isize, fill: u8) -> bool { + unsafe { + let str = bs as *mut ASN1_STRING; + let str_len = ASN1_STRING_length(str); + if str_len < 0 || str_len as isize > length { + return false; + } + + if str_len > 0 { + // copy bytes + let d = ASN1_STRING_get0_data(str); + for i in 0..(str_len as isize) { + *addr.offset(i) = *d.offset(i); + } + + let internal_str = bs as *mut ASN1_STRING_internal; + if ((*internal_str).flags & 7) != 0 { + let mask = 0xFF >> (8 - ((*internal_str).flags & 7)); + let val = if fill == 0 { + *d.offset(str_len as isize - 1) & !mask + } else { + *d.offset(str_len as isize - 1) | mask + }; + *addr.offset(str_len as isize - 1) = val; + } + } + + // fill up bytes + for i in (str_len as isize)..(length as isize) { + *addr.offset(i) = fill; + } + } + + true +} + +/* + * Extract min and max values from an IPAddressOrRange. + */ +fn extract_min_max(aor: *mut _IPAddressOrRange, min: *mut u8, max: *mut u8, length: isize) -> bool { + unsafe { + match (*aor).type_ { + IPAddressOrRange_addressPrefix => { + return addr_expand(min, (*aor).u.addressPrefix, length, 0x00) + && addr_expand(max, (*aor).u.addressPrefix, length, 0xFF) + } + IPAddressOrRange_addressRange => { + return addr_expand(min, (*(*aor).u.addressRange).min, length, 0x00) + && addr_expand(max, (*(*aor).u.addressRange).max, length, 0xFF) + } + _ => false, + } + } +} + +pub fn X509v3_addr_get_range( + aor: *mut _IPAddressOrRange, + afi: c_int, + min: *mut u8, + max: *mut u8, + length: isize, +) -> isize { + let afi_length = length_from_afi(afi); + if aor.is_null() || min.is_null() || max.is_null() || afi_length == 0 || length < afi_length { + return 0; + } + if !extract_min_max(aor, min, max, afi_length) { + return 0; + } + afi_length } diff --git a/openssl-sys/src/x509_sbgp.rs b/openssl-sys/src/x509_sbgp.rs index 6f627c634b..8bfcf6d81f 100644 --- a/openssl-sys/src/x509_sbgp.rs +++ b/openssl-sys/src/x509_sbgp.rs @@ -7,3 +7,12 @@ pub const ASIdOrRange_range: c_int = 1; pub const ASIdentifierChoice_inherit: c_int = 0; pub const ASIdentifierChoice_asIdsOrRanges: c_int = 1; + +pub const IPAddressOrRange_addressPrefix: c_int = 0; +pub const IPAddressOrRange_addressRange: c_int = 1; + +pub const IPAddressChoice_inherit: c_int = 0; +pub const IPAddressChoice_addressesOrRanges: c_int = 1; + +pub const IANA_AFI_IPV4: c_int = 1; +pub const IANA_AFI_IPV6: c_int = 2; diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index f105ab427b..e0a60b7b34 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -1,12 +1,15 @@ +use std::mem::MaybeUninit; + use ffi::{ ASIdOrRange_id, ASIdOrRange_range, ASIdentifierChoice_asIdsOrRanges, - ASIdentifierChoice_inherit, ASN1_INTEGER, + ASIdentifierChoice_inherit, IPAddressChoice_addressesOrRanges, X509v3_addr_get_afi, + X509v3_addr_get_range, ASN1_INTEGER, IANA_AFI_IPV4, IANA_AFI_IPV6, }; use foreign_types::{ForeignType, ForeignTypeRef}; use crate::{ asn1::Asn1IntegerRef, - stack::{StackRef, Stackable}, + stack::{Stack, StackRef, Stackable}, util::{ForeignTypeExt, ForeignTypeRefExt}, }; @@ -47,25 +50,27 @@ impl ASIdentifiers { pub fn ranges(&self) -> Option> { let mut r = Vec::new(); + let asptr = self.0; unsafe { - let asptr = self.0; let asnum = (*asptr).asnum; - if (*asnum).type_ == ASIdentifierChoice_asIdsOrRanges { - if let Some(s) = StackRef::::from_const_ptr_opt((*asnum).asIdsOrRanges) - { - for a_ptr in s { - let a = a_ptr.as_ptr(); - if (*a).type_ == ASIdOrRange_id { - let asn = Self::parse_asn1_integer((*a).u.id)?; - r.push((asn, asn)); - } else if (*a).type_ == ASIdOrRange_range { - let range = (*a).u.range; - let asn1 = Self::parse_asn1_integer((*range).min)?; - let asn2 = Self::parse_asn1_integer((*range).max)?; - r.push((asn1, asn2)); - } + if (*asnum).type_ != ASIdentifierChoice_asIdsOrRanges { + return None; + } + if let Some(s) = StackRef::::from_const_ptr_opt((*asnum).asIdsOrRanges) { + for a_ptr in s { + let a = a_ptr.as_ptr(); + if (*a).type_ == ASIdOrRange_id { + let asn = Self::parse_asn1_integer((*a).u.id)?; + r.push((asn, asn)); + } else if (*a).type_ == ASIdOrRange_range { + let range = (*a).u.range; + let asn1 = Self::parse_asn1_integer((*range).min)?; + let asn2 = Self::parse_asn1_integer((*range).max)?; + r.push((asn1, asn2)); } } + } else { + return None; } } Some(r) @@ -80,11 +85,105 @@ impl ASIdentifiers { } } -pub trait ExtractASN { +foreign_type_and_impl_send_sync! { + type CType = ffi::_IPAddressOrRange; + fn drop = ffi::IPAddressOrRange_free; + + /// The AS number extension of an `X509` certificate. + pub struct IPAddressOrRange; + /// Reference to `IPAddressOrRange`. + pub struct IPAddressOrRangeRef; +} + +impl Stackable for IPAddressOrRange { + type StackType = ffi::stack_st_IPAddressOrRange; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::_IPAddressFamily; + fn drop = ffi::IPAddressFamily_free; + + /// The AS number extension of an `X509` certificate. + pub struct IPAddressFamily; + /// Reference to `IPAddressFamily`. + pub struct IPAddressFamilyRef; +} + +impl Stackable for IPAddressFamily { + type StackType = ffi::stack_st_IPAddressFamily; +} + +#[derive(PartialEq, Eq, Debug)] +pub enum IPVersion { + V4, + V6, +} + +impl IPAddressFamily { + pub fn fam(&self) -> Option { + let ptr = self.0; + match X509v3_addr_get_afi(ptr) { + IANA_AFI_IPV4 => Some(IPVersion::V4), + IANA_AFI_IPV6 => Some(IPVersion::V6), + _ => None, + } + } + + pub fn range(&self) -> Option> { + let ptr = self.0; + let mut r = Vec::new(); + unsafe { + let choice = (*ptr).ipAddressChoice; + if (*choice).type_ != IPAddressChoice_addressesOrRanges { + return None; + } + let stack = + StackRef::::from_const_ptr_opt((*choice).addressesOrRanges)?; + for e in stack { + let mut min = MaybeUninit::<[u8; 16]>::uninit(); + let mut max = MaybeUninit::<[u8; 16]>::uninit(); + let size = X509v3_addr_get_range( + e.as_ptr(), + X509v3_addr_get_afi(ptr), + min.as_mut_ptr() as *mut u8, + max.as_mut_ptr() as *mut u8, + 16, + ); + r.push(( + Self::data_to_ip_addr(min.assume_init(), size)?, + Self::data_to_ip_addr(max.assume_init(), size)?, + )) + } + } + Some(r) + } + + fn data_to_ip_addr(data: [u8; 16], len: isize) -> Option { + match len { + 4 => Some(std::net::IpAddr::V4(std::net::Ipv4Addr::new( + data[0], data[1], data[2], data[3], + ))), + 16 => Some(std::net::IpAddr::V6(std::net::Ipv6Addr::new( + (data[0] as u16) << 8 | data[1] as u16, + (data[2] as u16) << 8 | data[3] as u16, + (data[4] as u16) << 8 | data[5] as u16, + (data[6] as u16) << 8 | data[7] as u16, + (data[8] as u16) << 8 | data[9] as u16, + (data[10] as u16) << 8 | data[11] as u16, + (data[12] as u16) << 8 | data[13] as u16, + (data[14] as u16) << 8 | data[15] as u16, + ))), + _ => None, + } + } +} + +pub trait ExtractSBGPInfo { fn asn(&self) -> Option; + fn ip_addresses(&self) -> Option>; } -impl ExtractASN for X509 { +impl ExtractSBGPInfo for X509 { fn asn(&self) -> Option { unsafe { let asn = ffi::X509_get_ext_d2i( @@ -96,4 +195,16 @@ impl ExtractASN for X509 { ASIdentifiers::from_ptr_opt(asn as *mut _) } } + + fn ip_addresses(&self) -> Option> { + unsafe { + let asn = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_sbgp_ipAddrBlock, + std::ptr::null_mut(), + std::ptr::null_mut(), + ); + Stack::from_ptr_opt(asn as *mut _) + } + } } From a7dc9935ccc86e436479befce2aacb90b4005137 Mon Sep 17 00:00:00 2001 From: Michael Rossberg Date: Tue, 18 Apr 2023 08:43:41 +0200 Subject: [PATCH 03/29] add possibility to define sbgp extensions --- openssl/src/x509/extension.rs | 131 ++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 11e0151530..b778c4ddef 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -428,6 +428,137 @@ impl AuthorityKeyIdentifier { } } +pub struct SbgpAsIdentifier { + critical: bool, + asn: Vec<(u32, u32)>, +} + +impl Default for SbgpAsIdentifier { + fn default() -> SbgpAsIdentifier { + SbgpAsIdentifier::new() + } +} + +impl SbgpAsIdentifier { + /// Construct a new `SbgpAsIdentifier` extension. + pub fn new() -> SbgpAsIdentifier { + SbgpAsIdentifier { + critical: false, + asn: Vec::new(), + } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut SbgpAsIdentifier { + self.critical = true; + self + } + + /// Adds an AS number. + pub fn add_asn(&mut self, asn: u32) -> &mut SbgpAsIdentifier { + self.asn.push((asn, asn)); + self + } + + /// Adds a range of AS numbers. + pub fn add_asn_range(&mut self, asn_min: u32, asn_max: u32) -> &mut SbgpAsIdentifier { + self.asn.push((asn_min, asn_max)); + self + } + + /// Return a `SbgpAsIdentifier` extension as an `X509Extension`. + pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { + let mut value = String::new(); + let mut first = true; + append(&mut value, &mut first, self.critical, "critical"); + for (asn_min, asn_max) in &self.asn { + let asn_format = if asn_min == asn_max { + format!("AS:{asn_min}") + } else { + format!("AS:{asn_min}-{asn_max}") + }; + append(&mut value, &mut first, true, &asn_format); + } + X509Extension::new_nid(None, Some(ctx), Nid::SBGP_AUTONOMOUSSYSNUM, &value) + } +} + +pub struct SbgpIpAddressIdentifier { + critical: bool, + ip_ranges: Vec<(std::net::IpAddr, std::net::IpAddr)>, +} + +impl Default for SbgpIpAddressIdentifier { + fn default() -> SbgpIpAddressIdentifier { + SbgpIpAddressIdentifier::new() + } +} + +impl SbgpIpAddressIdentifier { + /// Construct a new `SbgpIpAddressIdentifier` extension. + pub fn new() -> SbgpIpAddressIdentifier { + SbgpIpAddressIdentifier { + critical: false, + ip_ranges: Vec::new(), + } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut SbgpIpAddressIdentifier { + self.critical = true; + self + } + + /// Adds an IP adress. + pub fn add_ip_addr(&mut self, ip_addr: std::net::IpAddr) -> &mut SbgpIpAddressIdentifier { + self.ip_ranges.push((ip_addr, ip_addr)); + self + } + + /// Adds a range of IPv4 adresses. + pub fn add_ipv4_addr_range( + &mut self, + ip_addr_min: std::net::Ipv4Addr, + ip_addr_max: std::net::Ipv4Addr, + ) -> &mut SbgpIpAddressIdentifier { + self.ip_ranges.push(( + std::net::IpAddr::V4(ip_addr_min), + std::net::IpAddr::V4(ip_addr_max), + )); + self + } + + /// Adds a range of IPv6 adresses. + pub fn add_ipv6_addr_range( + &mut self, + ip_addr_min: std::net::Ipv6Addr, + ip_addr_max: std::net::Ipv6Addr, + ) -> &mut SbgpIpAddressIdentifier { + self.ip_ranges.push(( + std::net::IpAddr::V6(ip_addr_min), + std::net::IpAddr::V6(ip_addr_max), + )); + self + } + + /// Return a `SbgpIpAddressIdentifier` extension as an `X509Extension`. + pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { + let mut value = String::new(); + let mut first = true; + append(&mut value, &mut first, self.critical, "critical"); + for (ip_addr_min, ip_addr_max) in &self.ip_ranges { + let version = if ip_addr_min.is_ipv4() { 4 } else { 6 }; + let ip_addr_format = if ip_addr_min == ip_addr_max { + format!("IPv{version}:{ip_addr_min}") + } else { + format!("IPv{version}:{ip_addr_min}-{ip_addr_max}") + }; + append(&mut value, &mut first, true, &ip_addr_format); + } + X509Extension::new_nid(None, Some(ctx), Nid::SBGP_IPADDRBLOCK, &value) + } +} + enum RustGeneralName { Dns(String), Email(String), From 187ee6d37cd2d6e972fc8c5041143d8f626cdb32 Mon Sep 17 00:00:00 2001 From: Michael Rossberg Date: Tue, 18 Jul 2023 08:43:47 +0200 Subject: [PATCH 04/29] some style fixes --- openssl-sys/src/handwritten/x509_sbgp.rs | 24 +++++++++++------------- openssl/src/x509/sbgp.rs | 10 ++++++---- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index e4aab2c780..83edf9f521 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -75,18 +75,16 @@ extern "C" { pub fn IPAddressOrRange_free(asi: *mut _IPAddressOrRange); } -pub fn X509v3_addr_get_afi(f: *mut _IPAddressFamily) -> c_int { - unsafe { - if f.is_null() { +pub unsafe fn X509v3_addr_get_afi(f: *mut _IPAddressFamily) -> c_int { + if f.is_null() { + 0 + } else { + let d = (*f).addressFamily as *mut ASN1_STRING; + if d.is_null() || ASN1_STRING_length(d) < 2 || ASN1_STRING_get0_data(d).is_null() { 0 } else { - let d = (*f).addressFamily as *mut ASN1_STRING; - if d.is_null() || ASN1_STRING_length(d) < 2 || ASN1_STRING_get0_data(d).is_null() { - 0 - } else { - let raw = ASN1_STRING_get0_data(d); - ((*raw.offset(0) as i32) << 8) | *raw.offset(1) as i32 - } + let raw = ASN1_STRING_get0_data(d); + ((*raw.offset(0) as i32) << 8) | *raw.offset(1) as i32 } } } @@ -142,7 +140,7 @@ fn addr_expand(addr: *mut u8, bs: *const ASN1_BIT_STRING, length: isize, fill: u } // fill up bytes - for i in (str_len as isize)..(length as isize) { + for i in (str_len as isize)..length { *addr.offset(i) = fill; } } @@ -157,11 +155,11 @@ fn extract_min_max(aor: *mut _IPAddressOrRange, min: *mut u8, max: *mut u8, leng unsafe { match (*aor).type_ { IPAddressOrRange_addressPrefix => { - return addr_expand(min, (*aor).u.addressPrefix, length, 0x00) + addr_expand(min, (*aor).u.addressPrefix, length, 0x00) && addr_expand(max, (*aor).u.addressPrefix, length, 0xFF) } IPAddressOrRange_addressRange => { - return addr_expand(min, (*(*aor).u.addressRange).min, length, 0x00) + addr_expand(min, (*(*aor).u.addressRange).min, length, 0x00) && addr_expand(max, (*(*aor).u.addressRange).max, length, 0xFF) } _ => false, diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index e0a60b7b34..2e25b6598f 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -122,10 +122,12 @@ pub enum IPVersion { impl IPAddressFamily { pub fn fam(&self) -> Option { let ptr = self.0; - match X509v3_addr_get_afi(ptr) { - IANA_AFI_IPV4 => Some(IPVersion::V4), - IANA_AFI_IPV6 => Some(IPVersion::V6), - _ => None, + unsafe { + match X509v3_addr_get_afi(ptr) { + IANA_AFI_IPV4 => Some(IPVersion::V4), + IANA_AFI_IPV6 => Some(IPVersion::V6), + _ => None, + } } } From d27ac33fed826dec9a4c0a99749beae27501d6ef Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Fri, 11 Aug 2023 13:36:45 +0200 Subject: [PATCH 05/29] fixes for current master and OpenSSL 3 Signed-off-by: Markus Theil --- openssl-sys/src/handwritten/x509_sbgp.rs | 22 +++++++++++----------- openssl/src/x509/extension.rs | 2 ++ openssl/src/x509/sbgp.rs | 8 ++++---- systest/build.rs | 7 ++++++- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index 83edf9f521..1b32fc46e4 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -8,7 +8,7 @@ pub struct ASRange { } #[repr(C)] -pub struct _ASIdOrRange { +pub struct ASIdOrRange { pub type_: c_int, pub u: ASIdOrRange_st_anon_union, } @@ -28,7 +28,7 @@ pub struct ASIdentifierChoice { } #[repr(C)] -pub struct _ASIdentifiers { +pub struct ASIdentifiers { pub asnum: *mut ASIdentifierChoice, pub rdi: *mut ASIdentifierChoice, } @@ -40,7 +40,7 @@ pub struct IPAddressRange { } #[repr(C)] -pub struct _IPAddressOrRange { +pub struct IPAddressOrRange { pub type_: c_int, pub u: IPAddressOrRange_st_anon_union, } @@ -60,7 +60,7 @@ pub struct IPAddressChoice { } #[repr(C)] -pub struct _IPAddressFamily { +pub struct IPAddressFamily { pub addressFamily: *mut ASN1_OCTET_STRING, pub ipAddressChoice: *mut IPAddressChoice, } @@ -69,13 +69,13 @@ stack!(stack_st_IPAddressFamily); type IPAddrBlocks = stack_st_IPAddressFamily; extern "C" { - pub fn ASIdentifiers_free(asi: *mut _ASIdentifiers); - pub fn ASIdOrRange_free(asi: *mut _ASIdOrRange); - pub fn IPAddressFamily_free(asi: *mut _IPAddressFamily); - pub fn IPAddressOrRange_free(asi: *mut _IPAddressOrRange); + pub fn ASIdentifiers_free(asi: *mut ASIdentifiers); + pub fn ASIdOrRange_free(asi: *mut ASIdOrRange); + pub fn IPAddressFamily_free(asi: *mut IPAddressFamily); + pub fn IPAddressOrRange_free(asi: *mut IPAddressOrRange); } -pub unsafe fn X509v3_addr_get_afi(f: *mut _IPAddressFamily) -> c_int { +pub unsafe fn X509v3_addr_get_afi(f: *mut IPAddressFamily) -> c_int { if f.is_null() { 0 } else { @@ -151,7 +151,7 @@ fn addr_expand(addr: *mut u8, bs: *const ASN1_BIT_STRING, length: isize, fill: u /* * Extract min and max values from an IPAddressOrRange. */ -fn extract_min_max(aor: *mut _IPAddressOrRange, min: *mut u8, max: *mut u8, length: isize) -> bool { +fn extract_min_max(aor: *mut IPAddressOrRange, min: *mut u8, max: *mut u8, length: isize) -> bool { unsafe { match (*aor).type_ { IPAddressOrRange_addressPrefix => { @@ -168,7 +168,7 @@ fn extract_min_max(aor: *mut _IPAddressOrRange, min: *mut u8, max: *mut u8, leng } pub fn X509v3_addr_get_range( - aor: *mut _IPAddressOrRange, + aor: *mut IPAddressOrRange, afi: c_int, min: *mut u8, max: *mut u8, diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index b778c4ddef..62a8e93de9 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -467,6 +467,7 @@ impl SbgpAsIdentifier { } /// Return a `SbgpAsIdentifier` extension as an `X509Extension`. + #[allow(deprecated)] pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { let mut value = String::new(); let mut first = true; @@ -542,6 +543,7 @@ impl SbgpIpAddressIdentifier { } /// Return a `SbgpIpAddressIdentifier` extension as an `X509Extension`. + #[allow(deprecated)] pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { let mut value = String::new(); let mut first = true; diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index 2e25b6598f..7175979d95 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -16,7 +16,7 @@ use crate::{ use super::X509; foreign_type_and_impl_send_sync! { - type CType = ffi::_ASIdOrRange; + type CType = ffi::ASIdOrRange; fn drop = ffi::ASIdOrRange_free; /// The AS number extension of an `X509` certificate. @@ -30,7 +30,7 @@ impl Stackable for ASIdOrRange { } foreign_type_and_impl_send_sync! { - type CType = ffi::_ASIdentifiers; + type CType = ffi::ASIdentifiers; fn drop = ffi::ASIdentifiers_free; /// The AS number extension of an `X509` certificate. @@ -86,7 +86,7 @@ impl ASIdentifiers { } foreign_type_and_impl_send_sync! { - type CType = ffi::_IPAddressOrRange; + type CType = ffi::IPAddressOrRange; fn drop = ffi::IPAddressOrRange_free; /// The AS number extension of an `X509` certificate. @@ -100,7 +100,7 @@ impl Stackable for IPAddressOrRange { } foreign_type_and_impl_send_sync! { - type CType = ffi::_IPAddressFamily; + type CType = ffi::IPAddressFamily; fn drop = ffi::IPAddressFamily_free; /// The AS number extension of an `X509` certificate. diff --git a/systest/build.rs b/systest/build.rs index ad41ca798e..295122e1b3 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -118,7 +118,12 @@ fn main() { s == "ProbeResult" || s == "X509_OBJECT_data" || // inline union s == "DIST_POINT_NAME_st_anon_union" || // inline union - s == "_ASIdOrRange_st_anon_union" || // inline union + s == "ASIdOrRange_st_anon_union" || // inline union + s == "ASIdOrRange" || + s == "ASIdentifierChoice" || + s == "IPAddressOrRange_st_anon_union" || // inline union + s == "IPAddressOrRange" || + s == "IPAddressChoice" || s == "PKCS7_data" || s == "ASN1_TYPE_value" }); From e93ab39ae93330affd45ac7f02c67d20865db622 Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Fri, 11 Aug 2023 15:01:26 +0200 Subject: [PATCH 06/29] add test for SBGP extension Signed-off-by: Markus Theil --- openssl/src/x509/tests.rs | 48 ++++++++++++++++++++++++++++++++++++++- openssl/test/rfc3779.pem | 31 +++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 openssl/test/rfc3779.pem diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index a4a3de970c..b29a8ba5cc 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1,4 +1,6 @@ use std::cmp::Ordering; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::str::FromStr; use crate::asn1::{Asn1Object, Asn1OctetString, Asn1Time}; use crate::bn::{BigNum, MsbOption}; @@ -11,7 +13,7 @@ use crate::ssl::SslFiletype; use crate::stack::Stack; use crate::x509::extension::{ AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName, - SubjectKeyIdentifier, + SubjectKeyIdentifier, SbgpAsIdentifier, SbgpIpAddressIdentifier }; #[cfg(not(boringssl))] use crate::x509::store::X509Lookup; @@ -27,6 +29,7 @@ use crate::x509::{CrlReason, X509Builder}; use crate::x509::{ CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509, }; +use crate::x509::sbgp::ExtractSBGPInfo; #[cfg(ossl110)] use foreign_types::ForeignType; @@ -1177,3 +1180,46 @@ fn test_dist_point_null() { let cert = X509::from_pem(cert).unwrap(); assert!(cert.crl_distribution_points().is_none()); } + +#[test] +fn test_sbgp_extensions_parsing() { + let cert = include_bytes!("../../test/rfc3779.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let asn_ranges = cert.asn().unwrap().ranges().unwrap(); + assert_eq!(asn_ranges[0], (10,18)); + assert_eq!(asn_ranges[1], (20,20)); + + let families = cert.ip_addresses().unwrap(); + for family in families { + let ranges = family.range().unwrap(); + for (ip_min, ip_max) in ranges { + if let (IpAddr::V6(a_v6_min), IpAddr::V6(a_v6_max)) = (ip_min, ip_max) { + assert_eq!(a_v6_min, Ipv6Addr::from_str("fd00::").unwrap()); + assert_eq!(a_v6_max, Ipv6Addr::from_str("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap()); + } + if let (IpAddr::V4(a_v4_min), IpAddr::V4(a_v4_max)) = (ip_min, ip_max) { + assert_eq!(a_v4_min, Ipv4Addr::from_str("10.0.0.0").unwrap()); + assert_eq!(a_v4_max, Ipv4Addr::from_str("10.0.0.255").unwrap()); + } + } + } +} + +#[test] +fn test_sbgp_extensions_builder() { + let mut builder = X509Builder::new().unwrap(); + let asn_ext = SbgpAsIdentifier::new() + .critical() + .add_asn(32) + .add_asn_range(10,20) + .build(&builder.x509v3_context(None, None)).unwrap(); + builder.append_extension(asn_ext).unwrap(); + + let mut ip_addr_ext = SbgpIpAddressIdentifier::new(); + ip_addr_ext.critical(); + ip_addr_ext.add_ipv6_addr_range(Ipv6Addr::from_str("fd00::").unwrap(), Ipv6Addr::from_str("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap()); + ip_addr_ext.add_ipv4_addr_range(Ipv4Addr::from_str("10.0.0.0").unwrap(), Ipv4Addr::from_str("10.0.0.255").unwrap()); + let build_ext = ip_addr_ext.build(&builder.x509v3_context(None, None)).unwrap(); + builder.append_extension(build_ext).unwrap(); +} \ No newline at end of file diff --git a/openssl/test/rfc3779.pem b/openssl/test/rfc3779.pem new file mode 100644 index 0000000000..04083c7e36 --- /dev/null +++ b/openssl/test/rfc3779.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUdvq+8DcTNlDrHkAryL2UdkvghPcwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMUkZDMzc3OS1UZXN0MB4XDTIzMDgxMTEyMTkyN1oXDTMz +MDgwODEyMTkyN1owFzEVMBMGA1UEAwwMUkZDMzc3OS1UZXN0MIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxkHmL2WyQn/wd0xh05YfBvZt93h9LcijUNPR +9ALora5Z72yJcN2mf0umufJLhNi6oneJPpBx7kd07kksiqffjTu5DobnxwKt9yKh +b3JqYFVhxkdqlTmf7G4k0aVAD2COgv9oEwTgrClU55cOLUEAZ1WZRjeeZvFYKQdP +oT0Fp2aWH+NTqjPC/GUggnBTs+oUd5S2xyqhajSQNdF7rHspXcvW5a8e8Za8pJ51 +3wwSLGYatK8KJQrvPsW+RYxtTCKHps9TVFJxNm4IPiIdbKwvFETqmx0TDPpbE+Uj +izBnNYGo94HVWuzHrfWyh95fXwo11YDYoQvLghXgv0xC0nWNFtnZkQunnyhhTZMk +K+2N3NN8kMqD6B05LDeGOd5tT2t5iVot4b8Umem0G3XhqWdwKc2/uso86ld4v1wM +Ce4VADl9dilJsmJzmoDuHxB1YH8bZk3/ugo31fRnaTlJ7OPK8+jpzHgMFEan6igh +ZJI/FKjdzujXShdD6UsVh4UV34g0Uyv2PwCf3ProLojpaNfl+KRZ+axdwnhhdYNr +Zh7npYZlePSzwZmwuLKBBFtSsxo6Ru9JamDmV/NnQQ2tuuv/AByzGsprlDC9NRIq +aABHueqqMxccqpaqrmPKD4qhFZRUX4hDCWbXyqsADrKQXjont2Vta9vaVAlXa/xF +I5AlRzUCAwEAAaOBozCBoDAdBgNVHQ4EFgQUzQnLoR8Fe8Nh7dtLa5M+IVNcnScw +HwYDVR0jBBgwFoAUzQnLoR8Fe8Nh7dtLa5M+IVNcnScwDwYDVR0TAQH/BAUwAwEB +/zArBggrBgEFBQcBBwEB/wQcMBowDAQCAAEwBgMEAAoAADAKBAIAAjAEAwIA/TAg +BggrBgEFBQcBCAEB/wQRMA+gDTALMAYCAQoCARICARQwDQYJKoZIhvcNAQELBQAD +ggIBAKz3jRS9Dq1pfW/lY2ChAG+tPaNH79f2pzsc+SieTVJ3tbCaAA///V7nzgyZ +Yi3QjJVg8P+Ek0KnM3ScRLuiarWM/Vp9uXVdXZGMWJw+G5OJTFhDEXees6WxO/+8 +6u9OHp/nIai/w/FFjjw51mVAFcKm9W/izfDKT2HuZNQhCSDBXaVmqjfbBYHBopEn +LUqUb6s3S0SM74NaSstff3W836n+iX3dy1SmmVnaA6tu7oIZKmwBTO6yZYc6FOX8 +BUSJzgoCWZLwTlV13G1WtpIG8ap4lEEMilSjU8LwOcfC/3GrWtXIiQp3+1iYaKmO +zfU1axY+Vj2KerXbNOcTUQRazctKMvmd87Y2zuTnaQgwzs52257GlmVQj/K01w62 +UT4g84RZ+DvT74f534HK4Ik7lhQbgJO+HlmuED+2I/VPg0k1lpSkvY4zhne62P+l +VAYFq7tOzZSFllZVdAi9UFZkt7s9zPkpU2ed9wNz34DExLWJFXWkgjPWZzRchlUj +t69fpUcqe4is1wNEeOfVnKjyDfkVXBNqSvwkU/WMwazPjx+xV3qdi8rReDQmNx5L +gbv30P1MGeCftOaab2rFvUDlcUE1iClWT8THAUj6E2kaHtP5VA2PKuJHhqsPLIG/ +a2o0h6q0lNq4WHZhNzHBa+wc0uPtNRdBgClD/fsgoRK/pAZQ +-----END CERTIFICATE----- From 815a9516296095f3568d812ee11fd1cc2b9c9019 Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Thu, 12 Oct 2023 16:19:41 +0200 Subject: [PATCH 07/29] mark supported OpenSSL version range, make CI happy Signed-off-by: Markus Theil --- openssl-sys/src/handwritten/x509_sbgp.rs | 43 ++++++++++++++++++++++-- openssl-sys/src/x509_sbgp.rs | 12 +++++++ openssl/src/x509/extension.rs | 6 ++++ openssl/src/x509/sbgp.rs | 32 ++++++++++++++---- openssl/src/x509/tests.rs | 41 ++++++++++++++++------ systest/build.rs | 2 ++ 6 files changed, 116 insertions(+), 20 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index 1b32fc46e4..1adf4dc0ae 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -1,73 +1,103 @@ +#[cfg(ossl110)] use super::super::*; +#[cfg(ossl110)] use libc::*; #[repr(C)] +#[cfg(ossl110)] pub struct ASRange { pub min: *mut ASN1_INTEGER, pub max: *mut ASN1_INTEGER, } #[repr(C)] +#[cfg(ossl110)] pub struct ASIdOrRange { pub type_: c_int, pub u: ASIdOrRange_st_anon_union, } #[repr(C)] +#[cfg(ossl110)] pub union ASIdOrRange_st_anon_union { pub id: *mut ASN1_INTEGER, pub range: *mut ASRange, } +#[cfg(ossl110)] stack!(stack_st_ASIdOrRange); #[repr(C)] +#[cfg(ossl110)] +pub union ASIdentifierChoice_st_anon_union { + pub asIdsOrRanges: *mut stack_st_ASIdOrRange, +} + +#[repr(C)] +#[cfg(ossl110)] pub struct ASIdentifierChoice { pub type_: c_int, - pub asIdsOrRanges: *mut stack_st_ASIdOrRange, + pub u: ASIdentifierChoice_st_anon_union, } #[repr(C)] +#[cfg(ossl110)] pub struct ASIdentifiers { pub asnum: *mut ASIdentifierChoice, pub rdi: *mut ASIdentifierChoice, } #[repr(C)] +#[cfg(ossl110)] pub struct IPAddressRange { pub min: *mut ASN1_BIT_STRING, pub max: *mut ASN1_BIT_STRING, } #[repr(C)] +#[cfg(ossl110)] pub struct IPAddressOrRange { pub type_: c_int, pub u: IPAddressOrRange_st_anon_union, } #[repr(C)] +#[cfg(ossl110)] pub union IPAddressOrRange_st_anon_union { pub addressPrefix: *mut ASN1_BIT_STRING, pub addressRange: *mut IPAddressRange, } +#[cfg(ossl110)] stack!(stack_st_IPAddressOrRange); +#[cfg(ossl110)] type IPAddressOrRanges = stack_st_IPAddressOrRange; #[repr(C)] +#[cfg(ossl110)] +pub union IPAddressChoice_st_anon_union { + pub addressesOrRanges: *mut IPAddressOrRanges, +} + +#[repr(C)] +#[cfg(ossl110)] pub struct IPAddressChoice { pub type_: c_int, - pub addressesOrRanges: *mut IPAddressOrRanges, + pub u: IPAddressChoice_st_anon_union, } #[repr(C)] +#[cfg(ossl110)] pub struct IPAddressFamily { pub addressFamily: *mut ASN1_OCTET_STRING, pub ipAddressChoice: *mut IPAddressChoice, } +#[cfg(ossl110)] stack!(stack_st_IPAddressFamily); +#[cfg(ossl110)] type IPAddrBlocks = stack_st_IPAddressFamily; +#[cfg(ossl110)] extern "C" { pub fn ASIdentifiers_free(asi: *mut ASIdentifiers); pub fn ASIdOrRange_free(asi: *mut ASIdOrRange); @@ -75,6 +105,7 @@ extern "C" { pub fn IPAddressOrRange_free(asi: *mut IPAddressOrRange); } +#[cfg(ossl110)] pub unsafe fn X509v3_addr_get_afi(f: *mut IPAddressFamily) -> c_int { if f.is_null() { 0 @@ -84,11 +115,12 @@ pub unsafe fn X509v3_addr_get_afi(f: *mut IPAddressFamily) -> c_int { 0 } else { let raw = ASN1_STRING_get0_data(d); - ((*raw.offset(0) as i32) << 8) | *raw.offset(1) as i32 + ((*raw.offset(0) as c_int) << 8) | *raw.offset(1) as c_int } } } +#[cfg(ossl110)] fn length_from_afi(afi: c_int) -> isize { match afi { IANA_AFI_IPV4 => 4, @@ -97,6 +129,7 @@ fn length_from_afi(afi: c_int) -> isize { } } +#[cfg(ossl110)] struct ASN1_STRING_internal { length: c_int, type_: c_int, @@ -108,10 +141,12 @@ struct ASN1_STRING_internal { */ flags: c_int, } + /* * Expand the bitstring form of an address into a raw byte array. * At the moment this is coded for simplicity, not speed. */ +#[cfg(ossl110)] fn addr_expand(addr: *mut u8, bs: *const ASN1_BIT_STRING, length: isize, fill: u8) -> bool { unsafe { let str = bs as *mut ASN1_STRING; @@ -151,6 +186,7 @@ fn addr_expand(addr: *mut u8, bs: *const ASN1_BIT_STRING, length: isize, fill: u /* * Extract min and max values from an IPAddressOrRange. */ +#[cfg(ossl110)] fn extract_min_max(aor: *mut IPAddressOrRange, min: *mut u8, max: *mut u8, length: isize) -> bool { unsafe { match (*aor).type_ { @@ -167,6 +203,7 @@ fn extract_min_max(aor: *mut IPAddressOrRange, min: *mut u8, max: *mut u8, lengt } } +#[cfg(ossl110)] pub fn X509v3_addr_get_range( aor: *mut IPAddressOrRange, afi: c_int, diff --git a/openssl-sys/src/x509_sbgp.rs b/openssl-sys/src/x509_sbgp.rs index 8bfcf6d81f..02278a0001 100644 --- a/openssl-sys/src/x509_sbgp.rs +++ b/openssl-sys/src/x509_sbgp.rs @@ -1,18 +1,30 @@ +#[cfg(ossl110)] use libc::*; +#[cfg(ossl110)] use super::*; +#[cfg(ossl110)] pub const ASIdOrRange_id: c_int = 0; +#[cfg(ossl110)] pub const ASIdOrRange_range: c_int = 1; +#[cfg(ossl110)] pub const ASIdentifierChoice_inherit: c_int = 0; +#[cfg(ossl110)] pub const ASIdentifierChoice_asIdsOrRanges: c_int = 1; +#[cfg(ossl110)] pub const IPAddressOrRange_addressPrefix: c_int = 0; +#[cfg(ossl110)] pub const IPAddressOrRange_addressRange: c_int = 1; +#[cfg(ossl110)] pub const IPAddressChoice_inherit: c_int = 0; +#[cfg(ossl110)] pub const IPAddressChoice_addressesOrRanges: c_int = 1; +#[cfg(ossl110)] pub const IANA_AFI_IPV4: c_int = 1; +#[cfg(ossl110)] pub const IANA_AFI_IPV6: c_int = 2; diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 62a8e93de9..fd164e827e 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -428,17 +428,20 @@ impl AuthorityKeyIdentifier { } } +#[cfg(ossl110)] pub struct SbgpAsIdentifier { critical: bool, asn: Vec<(u32, u32)>, } +#[cfg(ossl110)] impl Default for SbgpAsIdentifier { fn default() -> SbgpAsIdentifier { SbgpAsIdentifier::new() } } +#[cfg(ossl110)] impl SbgpAsIdentifier { /// Construct a new `SbgpAsIdentifier` extension. pub fn new() -> SbgpAsIdentifier { @@ -484,17 +487,20 @@ impl SbgpAsIdentifier { } } +#[cfg(ossl110)] pub struct SbgpIpAddressIdentifier { critical: bool, ip_ranges: Vec<(std::net::IpAddr, std::net::IpAddr)>, } +#[cfg(ossl110)] impl Default for SbgpIpAddressIdentifier { fn default() -> SbgpIpAddressIdentifier { SbgpIpAddressIdentifier::new() } } +#[cfg(ossl110)] impl SbgpIpAddressIdentifier { /// Construct a new `SbgpIpAddressIdentifier` extension. pub fn new() -> SbgpIpAddressIdentifier { diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index 7175979d95..3a6aa04fc4 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -1,20 +1,28 @@ +#[cfg(ossl110)] +use std::convert::TryInto; +#[cfg(ossl110)] use std::mem::MaybeUninit; +#[cfg(ossl110)] use ffi::{ ASIdOrRange_id, ASIdOrRange_range, ASIdentifierChoice_asIdsOrRanges, ASIdentifierChoice_inherit, IPAddressChoice_addressesOrRanges, X509v3_addr_get_afi, X509v3_addr_get_range, ASN1_INTEGER, IANA_AFI_IPV4, IANA_AFI_IPV6, }; +#[cfg(ossl110)] use foreign_types::{ForeignType, ForeignTypeRef}; +#[cfg(ossl110)] use crate::{ asn1::Asn1IntegerRef, stack::{Stack, StackRef, Stackable}, util::{ForeignTypeExt, ForeignTypeRefExt}, }; +#[cfg(ossl110)] use super::X509; +#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::ASIdOrRange; fn drop = ffi::ASIdOrRange_free; @@ -24,11 +32,12 @@ foreign_type_and_impl_send_sync! { /// Reference to `ASIdOrRange`. pub struct ASIdOrRangeRef; } - +#[cfg(ossl110)] impl Stackable for ASIdOrRange { type StackType = ffi::stack_st_ASIdOrRange; } +#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::ASIdentifiers; fn drop = ffi::ASIdentifiers_free; @@ -39,6 +48,7 @@ foreign_type_and_impl_send_sync! { pub struct ASIdentifiersRef; } +#[cfg(ossl110)] impl ASIdentifiers { pub fn inherited(&self) -> bool { unsafe { @@ -56,7 +66,7 @@ impl ASIdentifiers { if (*asnum).type_ != ASIdentifierChoice_asIdsOrRanges { return None; } - if let Some(s) = StackRef::::from_const_ptr_opt((*asnum).asIdsOrRanges) { + if let Some(s) = StackRef::::from_const_ptr_opt((*asnum).u.asIdsOrRanges) { for a_ptr in s { let a = a_ptr.as_ptr(); if (*a).type_ == ASIdOrRange_id { @@ -85,6 +95,7 @@ impl ASIdentifiers { } } +#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::IPAddressOrRange; fn drop = ffi::IPAddressOrRange_free; @@ -95,10 +106,12 @@ foreign_type_and_impl_send_sync! { pub struct IPAddressOrRangeRef; } +#[cfg(ossl110)] impl Stackable for IPAddressOrRange { type StackType = ffi::stack_st_IPAddressOrRange; } +#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::IPAddressFamily; fn drop = ffi::IPAddressFamily_free; @@ -109,21 +122,24 @@ foreign_type_and_impl_send_sync! { pub struct IPAddressFamilyRef; } +#[cfg(ossl110)] impl Stackable for IPAddressFamily { type StackType = ffi::stack_st_IPAddressFamily; } #[derive(PartialEq, Eq, Debug)] +#[cfg(ossl110)] pub enum IPVersion { V4, V6, } +#[cfg(ossl110)] impl IPAddressFamily { pub fn fam(&self) -> Option { let ptr = self.0; unsafe { - match X509v3_addr_get_afi(ptr) { + match X509v3_addr_get_afi(ptr) as libc::c_int { IANA_AFI_IPV4 => Some(IPVersion::V4), IANA_AFI_IPV6 => Some(IPVersion::V6), _ => None, @@ -140,7 +156,7 @@ impl IPAddressFamily { return None; } let stack = - StackRef::::from_const_ptr_opt((*choice).addressesOrRanges)?; + StackRef::::from_const_ptr_opt((*choice).u.addressesOrRanges)?; for e in stack { let mut min = MaybeUninit::<[u8; 16]>::uninit(); let mut max = MaybeUninit::<[u8; 16]>::uninit(); @@ -152,8 +168,10 @@ impl IPAddressFamily { 16, ); r.push(( - Self::data_to_ip_addr(min.assume_init(), size)?, - Self::data_to_ip_addr(max.assume_init(), size)?, + #[allow(clippy::useless_conversion)] + Self::data_to_ip_addr(min.assume_init(), size.try_into().unwrap())?, + #[allow(clippy::useless_conversion)] + Self::data_to_ip_addr(max.assume_init(), size.try_into().unwrap())?, )) } } @@ -180,11 +198,13 @@ impl IPAddressFamily { } } +#[cfg(ossl110)] pub trait ExtractSBGPInfo { fn asn(&self) -> Option; fn ip_addresses(&self) -> Option>; } +#[cfg(ossl110)] impl ExtractSBGPInfo for X509 { fn asn(&self) -> Option { unsafe { diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index b29a8ba5cc..9adc7450df 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1,5 +1,7 @@ use std::cmp::Ordering; +#[cfg(ossl110)] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +#[cfg(ossl110)] use std::str::FromStr; use crate::asn1::{Asn1Object, Asn1OctetString, Asn1Time}; @@ -13,8 +15,12 @@ use crate::ssl::SslFiletype; use crate::stack::Stack; use crate::x509::extension::{ AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName, - SubjectKeyIdentifier, SbgpAsIdentifier, SbgpIpAddressIdentifier + SubjectKeyIdentifier, }; +#[cfg(ossl110)] +use crate::x509::extension::{SbgpAsIdentifier, SbgpIpAddressIdentifier}; +#[cfg(ossl110)] +use crate::x509::sbgp::ExtractSBGPInfo; #[cfg(not(boringssl))] use crate::x509::store::X509Lookup; use crate::x509::store::X509StoreBuilder; @@ -29,7 +35,6 @@ use crate::x509::{CrlReason, X509Builder}; use crate::x509::{ CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509, }; -use crate::x509::sbgp::ExtractSBGPInfo; #[cfg(ossl110)] use foreign_types::ForeignType; @@ -1182,13 +1187,14 @@ fn test_dist_point_null() { } #[test] +#[cfg(ossl110)] fn test_sbgp_extensions_parsing() { let cert = include_bytes!("../../test/rfc3779.pem"); let cert = X509::from_pem(cert).unwrap(); let asn_ranges = cert.asn().unwrap().ranges().unwrap(); - assert_eq!(asn_ranges[0], (10,18)); - assert_eq!(asn_ranges[1], (20,20)); + assert_eq!(asn_ranges[0], (10, 18)); + assert_eq!(asn_ranges[1], (20, 20)); let families = cert.ip_addresses().unwrap(); for family in families { @@ -1196,7 +1202,10 @@ fn test_sbgp_extensions_parsing() { for (ip_min, ip_max) in ranges { if let (IpAddr::V6(a_v6_min), IpAddr::V6(a_v6_max)) = (ip_min, ip_max) { assert_eq!(a_v6_min, Ipv6Addr::from_str("fd00::").unwrap()); - assert_eq!(a_v6_max, Ipv6Addr::from_str("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap()); + assert_eq!( + a_v6_max, + Ipv6Addr::from_str("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap() + ); } if let (IpAddr::V4(a_v4_min), IpAddr::V4(a_v4_max)) = (ip_min, ip_max) { assert_eq!(a_v4_min, Ipv4Addr::from_str("10.0.0.0").unwrap()); @@ -1207,19 +1216,29 @@ fn test_sbgp_extensions_parsing() { } #[test] +#[cfg(ossl110)] fn test_sbgp_extensions_builder() { let mut builder = X509Builder::new().unwrap(); let asn_ext = SbgpAsIdentifier::new() .critical() .add_asn(32) - .add_asn_range(10,20) - .build(&builder.x509v3_context(None, None)).unwrap(); + .add_asn_range(10, 20) + .build(&builder.x509v3_context(None, None)) + .unwrap(); builder.append_extension(asn_ext).unwrap(); let mut ip_addr_ext = SbgpIpAddressIdentifier::new(); ip_addr_ext.critical(); - ip_addr_ext.add_ipv6_addr_range(Ipv6Addr::from_str("fd00::").unwrap(), Ipv6Addr::from_str("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap()); - ip_addr_ext.add_ipv4_addr_range(Ipv4Addr::from_str("10.0.0.0").unwrap(), Ipv4Addr::from_str("10.0.0.255").unwrap()); - let build_ext = ip_addr_ext.build(&builder.x509v3_context(None, None)).unwrap(); + ip_addr_ext.add_ipv6_addr_range( + Ipv6Addr::from_str("fd00::").unwrap(), + Ipv6Addr::from_str("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), + ); + ip_addr_ext.add_ipv4_addr_range( + Ipv4Addr::from_str("10.0.0.0").unwrap(), + Ipv4Addr::from_str("10.0.0.255").unwrap(), + ); + let build_ext = ip_addr_ext + .build(&builder.x509v3_context(None, None)) + .unwrap(); builder.append_extension(build_ext).unwrap(); -} \ No newline at end of file +} diff --git a/systest/build.rs b/systest/build.rs index 295122e1b3..a4da53d422 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -120,9 +120,11 @@ fn main() { s == "DIST_POINT_NAME_st_anon_union" || // inline union s == "ASIdOrRange_st_anon_union" || // inline union s == "ASIdOrRange" || + s == "ASIdentifierChoice_st_anon_union" || // inline union s == "ASIdentifierChoice" || s == "IPAddressOrRange_st_anon_union" || // inline union s == "IPAddressOrRange" || + s == "IPAddressChoice_st_anon_union" || // inline union s == "IPAddressChoice" || s == "PKCS7_data" || s == "ASN1_TYPE_value" From df85aef26b666962467bc428fd499fe77ba0435d Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Sat, 14 Oct 2023 12:37:32 +0200 Subject: [PATCH 08/29] fix formatting for older rust versions Signed-off-by: Markus Theil --- openssl/src/x509/extension.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index fd164e827e..d7c372ce78 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -477,9 +477,9 @@ impl SbgpAsIdentifier { append(&mut value, &mut first, self.critical, "critical"); for (asn_min, asn_max) in &self.asn { let asn_format = if asn_min == asn_max { - format!("AS:{asn_min}") + format!("AS:{}", asn_min) } else { - format!("AS:{asn_min}-{asn_max}") + format!("AS:{}-{}", asn_min, asn_max) }; append(&mut value, &mut first, true, &asn_format); } @@ -557,9 +557,9 @@ impl SbgpIpAddressIdentifier { for (ip_addr_min, ip_addr_max) in &self.ip_ranges { let version = if ip_addr_min.is_ipv4() { 4 } else { 6 }; let ip_addr_format = if ip_addr_min == ip_addr_max { - format!("IPv{version}:{ip_addr_min}") + format!("IPv{}:{}", version, ip_addr_min) } else { - format!("IPv{version}:{ip_addr_min}-{ip_addr_max}") + format!("IPv{}:{}-{}", version, ip_addr_min, ip_addr_max) }; append(&mut value, &mut first, true, &ip_addr_format); } From 78c4b4ef6309ab872ca104a0c6e01cea058ef47b Mon Sep 17 00:00:00 2001 From: Petrichor Date: Wed, 25 Oct 2023 16:40:35 +0200 Subject: [PATCH 09/29] removed local reimpls of ossl functions - X509v3_addr_get_range - X509v3_addr_get_afi --- openssl-sys/src/handwritten/x509_sbgp.rs | 124 ++--------------------- openssl/src/x509/sbgp.rs | 4 +- systest/build.rs | 2 +- 3 files changed, 11 insertions(+), 119 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index 1adf4dc0ae..fc1e08510d 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -103,120 +103,12 @@ extern "C" { pub fn ASIdOrRange_free(asi: *mut ASIdOrRange); pub fn IPAddressFamily_free(asi: *mut IPAddressFamily); pub fn IPAddressOrRange_free(asi: *mut IPAddressOrRange); -} - -#[cfg(ossl110)] -pub unsafe fn X509v3_addr_get_afi(f: *mut IPAddressFamily) -> c_int { - if f.is_null() { - 0 - } else { - let d = (*f).addressFamily as *mut ASN1_STRING; - if d.is_null() || ASN1_STRING_length(d) < 2 || ASN1_STRING_get0_data(d).is_null() { - 0 - } else { - let raw = ASN1_STRING_get0_data(d); - ((*raw.offset(0) as c_int) << 8) | *raw.offset(1) as c_int - } - } -} - -#[cfg(ossl110)] -fn length_from_afi(afi: c_int) -> isize { - match afi { - IANA_AFI_IPV4 => 4, - IANA_AFI_IPV6 => 16, - _ => 0, - } -} - -#[cfg(ossl110)] -struct ASN1_STRING_internal { - length: c_int, - type_: c_int, - data: *mut u8, - /* - * The value of the following field depends on the type being held. It - * is mostly being used for BIT_STRING so if the input data has a - * non-zero 'unused bits' value, it will be handled correctly - */ - flags: c_int, -} - -/* - * Expand the bitstring form of an address into a raw byte array. - * At the moment this is coded for simplicity, not speed. - */ -#[cfg(ossl110)] -fn addr_expand(addr: *mut u8, bs: *const ASN1_BIT_STRING, length: isize, fill: u8) -> bool { - unsafe { - let str = bs as *mut ASN1_STRING; - let str_len = ASN1_STRING_length(str); - if str_len < 0 || str_len as isize > length { - return false; - } - - if str_len > 0 { - // copy bytes - let d = ASN1_STRING_get0_data(str); - for i in 0..(str_len as isize) { - *addr.offset(i) = *d.offset(i); - } - - let internal_str = bs as *mut ASN1_STRING_internal; - if ((*internal_str).flags & 7) != 0 { - let mask = 0xFF >> (8 - ((*internal_str).flags & 7)); - let val = if fill == 0 { - *d.offset(str_len as isize - 1) & !mask - } else { - *d.offset(str_len as isize - 1) | mask - }; - *addr.offset(str_len as isize - 1) = val; - } - } - - // fill up bytes - for i in (str_len as isize)..length { - *addr.offset(i) = fill; - } - } - - true -} - -/* - * Extract min and max values from an IPAddressOrRange. - */ -#[cfg(ossl110)] -fn extract_min_max(aor: *mut IPAddressOrRange, min: *mut u8, max: *mut u8, length: isize) -> bool { - unsafe { - match (*aor).type_ { - IPAddressOrRange_addressPrefix => { - addr_expand(min, (*aor).u.addressPrefix, length, 0x00) - && addr_expand(max, (*aor).u.addressPrefix, length, 0xFF) - } - IPAddressOrRange_addressRange => { - addr_expand(min, (*(*aor).u.addressRange).min, length, 0x00) - && addr_expand(max, (*(*aor).u.addressRange).max, length, 0xFF) - } - _ => false, - } - } -} - -#[cfg(ossl110)] -pub fn X509v3_addr_get_range( - aor: *mut IPAddressOrRange, - afi: c_int, - min: *mut u8, - max: *mut u8, - length: isize, -) -> isize { - let afi_length = length_from_afi(afi); - if aor.is_null() || min.is_null() || max.is_null() || afi_length == 0 || length < afi_length { - return 0; - } - if !extract_min_max(aor, min, max, afi_length) { - return 0; - } - afi_length + pub fn X509v3_addr_get_range( + aor: *mut IPAddressOrRange, + afi: c_uint, + min: *mut c_uchar, + max: *mut c_uchar, + length: c_int, + ) -> c_int; + pub fn X509v3_addr_get_afi(f: *const IPAddressFamily) -> c_uint; } diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index 3a6aa04fc4..c45f121bbc 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -7,7 +7,7 @@ use std::mem::MaybeUninit; use ffi::{ ASIdOrRange_id, ASIdOrRange_range, ASIdentifierChoice_asIdsOrRanges, ASIdentifierChoice_inherit, IPAddressChoice_addressesOrRanges, X509v3_addr_get_afi, - X509v3_addr_get_range, ASN1_INTEGER, IANA_AFI_IPV4, IANA_AFI_IPV6, + ASN1_INTEGER, IANA_AFI_IPV4, IANA_AFI_IPV6, }; #[cfg(ossl110)] use foreign_types::{ForeignType, ForeignTypeRef}; @@ -160,7 +160,7 @@ impl IPAddressFamily { for e in stack { let mut min = MaybeUninit::<[u8; 16]>::uninit(); let mut max = MaybeUninit::<[u8; 16]>::uninit(); - let size = X509v3_addr_get_range( + let size = ffi::X509v3_addr_get_range( e.as_ptr(), X509v3_addr_get_afi(ptr), min.as_mut_ptr() as *mut u8, diff --git a/systest/build.rs b/systest/build.rs index a4da53d422..fc8e12323f 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -141,7 +141,7 @@ fn main() { s == "i2d_PKCS8PrivateKey_bio" || s == "SSL_get_ex_new_index" || s == "SSL_CTX_get_ex_new_index" || - s == "CRYPTO_get_ex_new_index" + s == "CRYPTO_get_ex_new_index" }) }); cfg.skip_field_type(|s, field| { From 95f97b38c30530944d516b0de96aece92a233913 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 26 Oct 2023 18:13:30 +0200 Subject: [PATCH 10/29] API refactoring, removed unessecary components --- openssl/src/x509/sbgp.rs | 97 +++++++++++++++++---------------------- openssl/src/x509/tests.rs | 6 +-- 2 files changed, 43 insertions(+), 60 deletions(-) diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index c45f121bbc..e3ad19edd6 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -1,7 +1,7 @@ #[cfg(ossl110)] -use std::convert::TryInto; -#[cfg(ossl110)] use std::mem::MaybeUninit; +#[cfg(ossl110)] +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; #[cfg(ossl110)] use ffi::{ @@ -10,7 +10,9 @@ use ffi::{ ASN1_INTEGER, IANA_AFI_IPV4, IANA_AFI_IPV6, }; #[cfg(ossl110)] -use foreign_types::{ForeignType, ForeignTypeRef}; +use foreign_types::ForeignTypeRef; +#[cfg(ossl110)] +use openssl_macros::corresponds; #[cfg(ossl110)] use crate::{ @@ -20,7 +22,7 @@ use crate::{ }; #[cfg(ossl110)] -use super::X509; +use super::X509Ref; #[cfg(ossl110)] foreign_type_and_impl_send_sync! { @@ -59,39 +61,36 @@ impl ASIdentifiers { } pub fn ranges(&self) -> Option> { - let mut r = Vec::new(); - let asptr = self.0; unsafe { - let asnum = (*asptr).asnum; - if (*asnum).type_ != ASIdentifierChoice_asIdsOrRanges { + let mut result = Vec::new(); + let as_num = (*self.0).asnum; + if (*as_num).type_ != ASIdentifierChoice_asIdsOrRanges { return None; } - if let Some(s) = StackRef::::from_const_ptr_opt((*asnum).u.asIdsOrRanges) { - for a_ptr in s { - let a = a_ptr.as_ptr(); - if (*a).type_ == ASIdOrRange_id { - let asn = Self::parse_asn1_integer((*a).u.id)?; - r.push((asn, asn)); - } else if (*a).type_ == ASIdOrRange_range { - let range = (*a).u.range; - let asn1 = Self::parse_asn1_integer((*range).min)?; - let asn2 = Self::parse_asn1_integer((*range).max)?; - r.push((asn1, asn2)); - } + + let stack = StackRef::::from_const_ptr_opt((*as_num).u.asIdsOrRanges)?; + for asi_ref in stack { + let asi = asi_ref.as_ptr(); + if (*asi).type_ == ASIdOrRange_id { + let asn = Self::parse_asn1_integer((*asi).u.id)?; + result.push((asn, asn)); + } else if (*asi).type_ == ASIdOrRange_range { + let range = (*asi).u.range; + let min = Self::parse_asn1_integer((*range).min)?; + let max = Self::parse_asn1_integer((*range).max)?; + result.push((min, max)); } - } else { - return None; } + + Some(result) } - Some(r) } fn parse_asn1_integer(v: *mut ASN1_INTEGER) -> Option { - let v_parsed; unsafe { - v_parsed = Asn1IntegerRef::from_ptr(v); + let v_ref = Asn1IntegerRef::from_ptr(v); + v_ref.to_bn().ok()?.to_dec_str().ok()?.parse().ok() } - v_parsed.to_bn().ok()?.to_dec_str().ok()?.parse().ok() } } @@ -136,9 +135,10 @@ pub enum IPVersion { #[cfg(ossl110)] impl IPAddressFamily { + #[corresponds(X509v3_addr_get_afi)] pub fn fam(&self) -> Option { - let ptr = self.0; unsafe { + let ptr = self.0; match X509v3_addr_get_afi(ptr) as libc::c_int { IANA_AFI_IPV4 => Some(IPVersion::V4), IANA_AFI_IPV6 => Some(IPVersion::V6), @@ -147,10 +147,10 @@ impl IPAddressFamily { } } - pub fn range(&self) -> Option> { - let ptr = self.0; - let mut r = Vec::new(); + pub fn range(&self) -> Option> { unsafe { + let ptr = self.0; + let mut r = Vec::new(); let choice = (*ptr).ipAddressChoice; if (*choice).type_ != IPAddressChoice_addressesOrRanges { return None; @@ -168,45 +168,29 @@ impl IPAddressFamily { 16, ); r.push(( - #[allow(clippy::useless_conversion)] - Self::data_to_ip_addr(min.assume_init(), size.try_into().unwrap())?, - #[allow(clippy::useless_conversion)] - Self::data_to_ip_addr(max.assume_init(), size.try_into().unwrap())?, + Self::data_to_ip_addr(min.assume_init(), size)?, + Self::data_to_ip_addr(max.assume_init(), size)?, )) } + Some(r) } - Some(r) } - fn data_to_ip_addr(data: [u8; 16], len: isize) -> Option { + fn data_to_ip_addr(data: [u8; 16], len: i32) -> Option { match len { - 4 => Some(std::net::IpAddr::V4(std::net::Ipv4Addr::new( + 4 => Some(IpAddr::V4(Ipv4Addr::new( data[0], data[1], data[2], data[3], ))), - 16 => Some(std::net::IpAddr::V6(std::net::Ipv6Addr::new( - (data[0] as u16) << 8 | data[1] as u16, - (data[2] as u16) << 8 | data[3] as u16, - (data[4] as u16) << 8 | data[5] as u16, - (data[6] as u16) << 8 | data[7] as u16, - (data[8] as u16) << 8 | data[9] as u16, - (data[10] as u16) << 8 | data[11] as u16, - (data[12] as u16) << 8 | data[13] as u16, - (data[14] as u16) << 8 | data[15] as u16, - ))), + 16 => Some(IpAddr::V6(Ipv6Addr::from(data))), _ => None, } } } #[cfg(ossl110)] -pub trait ExtractSBGPInfo { - fn asn(&self) -> Option; - fn ip_addresses(&self) -> Option>; -} - -#[cfg(ossl110)] -impl ExtractSBGPInfo for X509 { - fn asn(&self) -> Option { +impl X509Ref { + #[corresponds(X509_get_ext_d2i)] + pub fn sbgp_asn(&self) -> Option { unsafe { let asn = ffi::X509_get_ext_d2i( self.as_ptr(), @@ -218,7 +202,8 @@ impl ExtractSBGPInfo for X509 { } } - fn ip_addresses(&self) -> Option> { + #[corresponds(X509_get_ext_d2i)] + pub fn sbgp_ip_addresses(&self) -> Option> { unsafe { let asn = ffi::X509_get_ext_d2i( self.as_ptr(), diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 9adc7450df..7b55763079 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -19,8 +19,6 @@ use crate::x509::extension::{ }; #[cfg(ossl110)] use crate::x509::extension::{SbgpAsIdentifier, SbgpIpAddressIdentifier}; -#[cfg(ossl110)] -use crate::x509::sbgp::ExtractSBGPInfo; #[cfg(not(boringssl))] use crate::x509::store::X509Lookup; use crate::x509::store::X509StoreBuilder; @@ -1192,11 +1190,11 @@ fn test_sbgp_extensions_parsing() { let cert = include_bytes!("../../test/rfc3779.pem"); let cert = X509::from_pem(cert).unwrap(); - let asn_ranges = cert.asn().unwrap().ranges().unwrap(); + let asn_ranges = cert.sbgp_asn().unwrap().ranges().unwrap(); assert_eq!(asn_ranges[0], (10, 18)); assert_eq!(asn_ranges[1], (20, 20)); - let families = cert.ip_addresses().unwrap(); + let families = cert.sbgp_ip_addresses().unwrap(); for family in families { let ranges = family.range().unwrap(); for (ip_min, ip_max) in ranges { From 98bff2f7598350d5d9907efa67b8dab0b4954922 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 2 Nov 2023 18:32:02 +0100 Subject: [PATCH 11/29] switched to internal types for sbgp extension building --- openssl-sys/src/handwritten/x509_sbgp.rs | 33 ++++++ openssl/src/x509/extension.rs | 134 ++++++++++++++++------- openssl/src/x509/sbgp.rs | 51 +++++---- openssl/src/x509/tests.rs | 6 +- 4 files changed, 156 insertions(+), 68 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index fc1e08510d..2d1973a230 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -26,6 +26,8 @@ pub union ASIdOrRange_st_anon_union { #[cfg(ossl110)] stack!(stack_st_ASIdOrRange); +#[cfg(ossl110)] +type ASIdOrRanges = stack_st_ASIdOrRange; #[repr(C)] #[cfg(ossl110)] @@ -99,10 +101,34 @@ type IPAddrBlocks = stack_st_IPAddressFamily; #[cfg(ossl110)] extern "C" { + /* + * Constructors / Destructors for SBGP autonomousSysNum + */ + pub fn ASIdentifiers_new() -> *mut ASIdentifiers; pub fn ASIdentifiers_free(asi: *mut ASIdentifiers); pub fn ASIdOrRange_free(asi: *mut ASIdOrRange); + + /* + * Constructors / Destructors for SBGP ipAddrBlock + */ pub fn IPAddressFamily_free(asi: *mut IPAddressFamily); pub fn IPAddressOrRange_free(asi: *mut IPAddressOrRange); + + /* + * Utility functions for working with RFC 3779 values, + * since their encodings are a bit tedious. + * + * Not yet used: + * - X509v3_asid_add_inherit + * - X509v3_addr_add_inherit + * - X509v3_addr_add_prefix + */ + pub fn X509v3_asid_add_id_or_range( + asid: *mut ASIdentifiers, + which: c_int, + min: *mut ASN1_INTEGER, + max: *mut ASN1_INTEGER, + ) -> c_int; pub fn X509v3_addr_get_range( aor: *mut IPAddressOrRange, afi: c_uint, @@ -111,4 +137,11 @@ extern "C" { length: c_int, ) -> c_int; pub fn X509v3_addr_get_afi(f: *const IPAddressFamily) -> c_uint; + pub fn X509v3_addr_add_range( + addr: *mut IPAddrBlocks, + afi: c_uint, + safi: *const c_uint, + min: *mut c_uchar, + max: *mut c_uchar, + ) -> c_int; } diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index d7c372ce78..5154e48067 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -17,13 +17,18 @@ //! let extension: X509Extension = bc.build().unwrap(); //! ``` use std::fmt::Write; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use crate::asn1::Asn1Object; +use crate::bn::BigNum; use crate::error::ErrorStack; use crate::nid::Nid; use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; +use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; use foreign_types::ForeignType; +use super::sbgp::IPAddressFamily; + /// An extension which indicates whether a certificate is a CA certificate. pub struct BasicConstraints { critical: bool, @@ -470,27 +475,32 @@ impl SbgpAsIdentifier { } /// Return a `SbgpAsIdentifier` extension as an `X509Extension`. - #[allow(deprecated)] - pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { - let mut value = String::new(); - let mut first = true; - append(&mut value, &mut first, self.critical, "critical"); - for (asn_min, asn_max) in &self.asn { - let asn_format = if asn_min == asn_max { - format!("AS:{}", asn_min) - } else { - format!("AS:{}-{}", asn_min, asn_max) - }; - append(&mut value, &mut first, true, &asn_format); + pub fn build(&self) -> Result { + unsafe { + let asid = ffi::ASIdentifiers_new(); + for (min, max) in &self.asn { + let min = BigNum::from_u32(*min)?.to_asn1_integer()?; + let max = BigNum::from_u32(*max)?.to_asn1_integer()?; + + if min == max { + ffi::X509v3_asid_add_id_or_range(asid, 0, min.as_ptr(), std::ptr::null_mut()); + } else { + ffi::X509v3_asid_add_id_or_range(asid, 0, min.as_ptr(), max.as_ptr()); + } + + std::mem::forget(min); + std::mem::forget(max); + } + + X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, self.critical, asid as *mut _) } - X509Extension::new_nid(None, Some(ctx), Nid::SBGP_AUTONOMOUSSYSNUM, &value) } } #[cfg(ossl110)] pub struct SbgpIpAddressIdentifier { critical: bool, - ip_ranges: Vec<(std::net::IpAddr, std::net::IpAddr)>, + ip_ranges: Vec<(IpAddr, IpAddr)>, } #[cfg(ossl110)] @@ -517,7 +527,7 @@ impl SbgpIpAddressIdentifier { } /// Adds an IP adress. - pub fn add_ip_addr(&mut self, ip_addr: std::net::IpAddr) -> &mut SbgpIpAddressIdentifier { + pub fn add_ip_addr(&mut self, ip_addr: IpAddr) -> &mut SbgpIpAddressIdentifier { self.ip_ranges.push((ip_addr, ip_addr)); self } @@ -525,45 +535,87 @@ impl SbgpIpAddressIdentifier { /// Adds a range of IPv4 adresses. pub fn add_ipv4_addr_range( &mut self, - ip_addr_min: std::net::Ipv4Addr, - ip_addr_max: std::net::Ipv4Addr, + ip_addr_min: Ipv4Addr, + ip_addr_max: Ipv4Addr, ) -> &mut SbgpIpAddressIdentifier { - self.ip_ranges.push(( - std::net::IpAddr::V4(ip_addr_min), - std::net::IpAddr::V4(ip_addr_max), - )); + self.ip_ranges + .push((IpAddr::V4(ip_addr_min), IpAddr::V4(ip_addr_max))); self } /// Adds a range of IPv6 adresses. pub fn add_ipv6_addr_range( &mut self, - ip_addr_min: std::net::Ipv6Addr, - ip_addr_max: std::net::Ipv6Addr, + ip_addr_min: Ipv6Addr, + ip_addr_max: Ipv6Addr, + ) -> &mut SbgpIpAddressIdentifier { + self.ip_ranges + .push((IpAddr::V6(ip_addr_min), IpAddr::V6(ip_addr_max))); + self + } + + /// Adds a ip prefix + pub fn add_ip_prefix( + &mut self, + prefix: IpAddr, + prefixlen: usize, ) -> &mut SbgpIpAddressIdentifier { - self.ip_ranges.push(( - std::net::IpAddr::V6(ip_addr_min), - std::net::IpAddr::V6(ip_addr_max), - )); + match prefix { + IpAddr::V4(prefix) => { + let mask = !(u32::MAX >> prefixlen); + let min = mask & u32::from(prefix); + let max = min | !mask; + self.ip_ranges + .push((Ipv4Addr::from(min).into(), Ipv4Addr::from(max).into())); + } + IpAddr::V6(prefix) => { + let mask = !(u128::MAX >> prefixlen); + let min = mask & u128::from(prefix); + let max = min | !mask; + self.ip_ranges + .push((Ipv6Addr::from(min).into(), Ipv6Addr::from(max).into())); + } + } self } /// Return a `SbgpIpAddressIdentifier` extension as an `X509Extension`. - #[allow(deprecated)] - pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { - let mut value = String::new(); - let mut first = true; - append(&mut value, &mut first, self.critical, "critical"); - for (ip_addr_min, ip_addr_max) in &self.ip_ranges { - let version = if ip_addr_min.is_ipv4() { 4 } else { 6 }; - let ip_addr_format = if ip_addr_min == ip_addr_max { - format!("IPv{}:{}", version, ip_addr_min) - } else { - format!("IPv{}:{}-{}", version, ip_addr_min, ip_addr_max) - }; - append(&mut value, &mut first, true, &ip_addr_format); + pub fn build(&self) -> Result { + unsafe { + let stack = Stack::::new()?; + macro_rules! cast_ptr { + ($e:expr) => {{ + let ptr: *mut _ = &mut ($e); + ptr as *mut u8 + }}; + } + + for (min, max) in &self.ip_ranges { + let (min, max, afi) = match (*min, *max) { + (IpAddr::V4(mut min), IpAddr::V4(mut max)) => { + (cast_ptr!(min), cast_ptr!(max), IANA_AFI_IPV4 as u32) + } + (IpAddr::V6(mut min), IpAddr::V6(mut max)) => { + (cast_ptr!(min), cast_ptr!(max), IANA_AFI_IPV6 as u32) + } + _ => unreachable!(), + }; + + ffi::X509v3_addr_add_range( + stack.as_ptr().cast(), + afi, + std::ptr::null_mut(), + min, + max, + ); + } + + X509Extension::new_internal( + Nid::SBGP_IPADDRBLOCK, + self.critical, + stack.as_ptr() as *mut _, + ) } - X509Extension::new_nid(None, Some(ctx), Nid::SBGP_IPADDRBLOCK, &value) } } diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index e3ad19edd6..1bf04cebdf 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -135,6 +135,7 @@ pub enum IPVersion { #[cfg(ossl110)] impl IPAddressFamily { + /// Returns the IP version of this record. #[corresponds(X509v3_addr_get_afi)] pub fn fam(&self) -> Option { unsafe { @@ -147,43 +148,47 @@ impl IPAddressFamily { } } + /// Returns the list of IP ranges contained in this IP family. + #[corresponds(X509v3_addr_get_range)] pub fn range(&self) -> Option> { unsafe { + let fam = self.fam()?; let ptr = self.0; - let mut r = Vec::new(); let choice = (*ptr).ipAddressChoice; if (*choice).type_ != IPAddressChoice_addressesOrRanges { return None; } let stack = StackRef::::from_const_ptr_opt((*choice).u.addressesOrRanges)?; - for e in stack { - let mut min = MaybeUninit::<[u8; 16]>::uninit(); - let mut max = MaybeUninit::<[u8; 16]>::uninit(); - let size = ffi::X509v3_addr_get_range( - e.as_ptr(), - X509v3_addr_get_afi(ptr), - min.as_mut_ptr() as *mut u8, - max.as_mut_ptr() as *mut u8, - 16, - ); - r.push(( - Self::data_to_ip_addr(min.assume_init(), size)?, - Self::data_to_ip_addr(max.assume_init(), size)?, - )) + match fam { + IPVersion::V4 => Self::addr_get_range::(stack, 4, IANA_AFI_IPV4 as u32), + IPVersion::V6 => Self::addr_get_range::(stack, 16, IANA_AFI_IPV6 as u32), } - Some(r) } } - fn data_to_ip_addr(data: [u8; 16], len: i32) -> Option { - match len { - 4 => Some(IpAddr::V4(Ipv4Addr::new( - data[0], data[1], data[2], data[3], - ))), - 16 => Some(IpAddr::V6(Ipv6Addr::from(data))), - _ => None, + unsafe fn addr_get_range>( + stack: &StackRef, + len: i32, + afi: u32, + ) -> Option> { + let mut r = Vec::new(); + for val in stack { + let mut min = MaybeUninit::::uninit(); + let mut max = MaybeUninit::::uninit(); + let size = ffi::X509v3_addr_get_range( + val.as_ptr(), + afi, + min.as_mut_ptr() as *mut _, + max.as_mut_ptr() as *mut _, + len, + ); + if size != len { + return None; + } + r.push((min.assume_init().into(), max.assume_init().into())) } + Some(r) } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 7b55763079..1d4516e383 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1221,7 +1221,7 @@ fn test_sbgp_extensions_builder() { .critical() .add_asn(32) .add_asn_range(10, 20) - .build(&builder.x509v3_context(None, None)) + .build() .unwrap(); builder.append_extension(asn_ext).unwrap(); @@ -1235,8 +1235,6 @@ fn test_sbgp_extensions_builder() { Ipv4Addr::from_str("10.0.0.0").unwrap(), Ipv4Addr::from_str("10.0.0.255").unwrap(), ); - let build_ext = ip_addr_ext - .build(&builder.x509v3_context(None, None)) - .unwrap(); + let build_ext = ip_addr_ext.build().unwrap(); builder.append_extension(build_ext).unwrap(); } From a24c404e11326b589b881cad492533a834e17dc9 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 9 Nov 2023 13:11:50 +0100 Subject: [PATCH 12/29] simplified builder, added more tests --- openssl/src/x509/extension.rs | 53 +++++++++++---------- openssl/src/x509/tests.rs | 88 +++++++++++++++++++++++++++++------ 2 files changed, 101 insertions(+), 40 deletions(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 5154e48067..93088d8236 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -26,6 +26,7 @@ use crate::nid::Nid; use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; use foreign_types::ForeignType; +use openssl_macros::corresponds; use super::sbgp::IPAddressFamily; @@ -582,32 +583,9 @@ impl SbgpIpAddressIdentifier { /// Return a `SbgpIpAddressIdentifier` extension as an `X509Extension`. pub fn build(&self) -> Result { unsafe { - let stack = Stack::::new()?; - macro_rules! cast_ptr { - ($e:expr) => {{ - let ptr: *mut _ = &mut ($e); - ptr as *mut u8 - }}; - } - + let mut stack = Stack::::new()?; for (min, max) in &self.ip_ranges { - let (min, max, afi) = match (*min, *max) { - (IpAddr::V4(mut min), IpAddr::V4(mut max)) => { - (cast_ptr!(min), cast_ptr!(max), IANA_AFI_IPV4 as u32) - } - (IpAddr::V6(mut min), IpAddr::V6(mut max)) => { - (cast_ptr!(min), cast_ptr!(max), IANA_AFI_IPV6 as u32) - } - _ => unreachable!(), - }; - - ffi::X509v3_addr_add_range( - stack.as_ptr().cast(), - afi, - std::ptr::null_mut(), - min, - max, - ); + stack.sbgp_add_addr_range(*min, *max) } X509Extension::new_internal( @@ -619,6 +597,31 @@ impl SbgpIpAddressIdentifier { } } +impl Stack { + /// Adds an address range to the stack + /// This helper exists as a utility function, because RFC 3779 types are hard to deal with. + #[corresponds(X509v3_addr_add_range)] + pub fn sbgp_add_addr_range(&mut self, min: IpAddr, max: IpAddr) { + unsafe { + let (min, max, afi) = match (min, max) { + (IpAddr::V4(mut min), IpAddr::V4(mut max)) => ( + &mut min as *mut _ as *mut u8, + &mut max as *mut _ as *mut u8, + IANA_AFI_IPV4 as u32, + ), + (IpAddr::V6(mut min), IpAddr::V6(mut max)) => ( + &mut min as *mut _ as *mut u8, + &mut max as *mut _ as *mut u8, + IANA_AFI_IPV6 as u32, + ), + _ => unreachable!(), + }; + + ffi::X509v3_addr_add_range(self.as_ptr().cast(), afi, std::ptr::null_mut(), min, max); + } + } +} + enum RustGeneralName { Dns(String), Email(String), diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 1d4516e383..33ed6155e3 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1215,26 +1215,84 @@ fn test_sbgp_extensions_parsing() { #[test] #[cfg(ossl110)] -fn test_sbgp_extensions_builder() { +fn test_sbgp_as_identifier_builder() { let mut builder = X509Builder::new().unwrap(); - let asn_ext = SbgpAsIdentifier::new() + let as_id_ext = SbgpAsIdentifier::new() .critical() - .add_asn(32) - .add_asn_range(10, 20) + .add_asn(1000) + .add_asn_range(2500, 2700) + .add_asn(9000) .build() .unwrap(); - builder.append_extension(asn_ext).unwrap(); - let mut ip_addr_ext = SbgpIpAddressIdentifier::new(); - ip_addr_ext.critical(); - ip_addr_ext.add_ipv6_addr_range( - Ipv6Addr::from_str("fd00::").unwrap(), - Ipv6Addr::from_str("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), + builder.append_extension(as_id_ext).unwrap(); + let cert = builder.build(); + + let asn = cert.sbgp_asn().unwrap(); + assert_eq!(asn.inherited(), false); + assert_eq!( + asn.ranges(), + Some(vec![(1000, 1000), (2500, 2700), (9000, 9000)]) ); - ip_addr_ext.add_ipv4_addr_range( - Ipv4Addr::from_str("10.0.0.0").unwrap(), - Ipv4Addr::from_str("10.0.0.255").unwrap(), +} + +#[test] +#[cfg(ossl110)] +fn test_sbgp_ip_addr_ranges_builder() { + use crate::x509::sbgp::IPVersion; + + let mut builder = X509Builder::new().unwrap(); + let ip_addr_ext = SbgpIpAddressIdentifier::new() + .critical() + .add_ip_addr(IpAddr::from_str("10.0.0.0").unwrap()) + .add_ip_prefix(IpAddr::from_str("20.0.0.0").unwrap(), 16) + .add_ipv6_addr_range( + Ipv6Addr::from_str("fc00::200").unwrap(), + Ipv6Addr::from_str("fc00::400").unwrap(), + ) + .add_ipv4_addr_range( + Ipv4Addr::from_str("30.0.0.0").unwrap(), + Ipv4Addr::from_str("30.0.0.100").unwrap(), + ) + .build() + .unwrap(); + + builder.append_extension(ip_addr_ext).unwrap(); + let cert = builder.build(); + + let ranges = cert + .sbgp_ip_addresses() + .unwrap() + .into_iter() + .collect::>(); + + assert_eq!(ranges.len(), 2); + + assert_eq!(ranges[0].fam(), Some(IPVersion::V4)); + assert_eq!( + ranges[0].range(), + Some(vec![ + ( + IpAddr::from_str("10.0.0.0").unwrap(), + IpAddr::from_str("10.0.0.0").unwrap() + ), + ( + IpAddr::from_str("20.0.0.0").unwrap(), + IpAddr::from_str("20.0.255.255").unwrap() + ), + ( + IpAddr::from_str("30.0.0.0").unwrap(), + IpAddr::from_str("30.0.0.100").unwrap() + ) + ]) + ); + + assert_eq!(ranges[1].fam(), Some(IPVersion::V6)); + assert_eq!( + ranges[1].range(), + Some(vec![( + IpAddr::from_str("fc00::200").unwrap(), + IpAddr::from_str("fc00::400").unwrap(), + )]) ); - let build_ext = ip_addr_ext.build().unwrap(); - builder.append_extension(build_ext).unwrap(); } From c4a61d1c2c82b6ce06c335eb15776cae357b94db Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 9 Nov 2023 13:17:37 +0100 Subject: [PATCH 13/29] removed random whitespace change in systest/build --- systest/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/systest/build.rs b/systest/build.rs index fc8e12323f..a4da53d422 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -141,7 +141,7 @@ fn main() { s == "i2d_PKCS8PrivateKey_bio" || s == "SSL_get_ex_new_index" || s == "SSL_CTX_get_ex_new_index" || - s == "CRYPTO_get_ex_new_index" + s == "CRYPTO_get_ex_new_index" }) }); cfg.skip_field_type(|s, field| { From 54c6e48f9ebdd64b951f5f4815e904fe3ed41b4c Mon Sep 17 00:00:00 2001 From: Petrichor Date: Wed, 15 Nov 2023 13:28:23 +0100 Subject: [PATCH 14/29] appeased clippy & added missing cfg(ossl110) --- openssl/src/x509/extension.rs | 13 +++++++++---- openssl/src/x509/tests.rs | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 93088d8236..825a4074db 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -17,19 +17,23 @@ //! let extension: X509Extension = bc.build().unwrap(); //! ``` use std::fmt::Write; -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use crate::asn1::Asn1Object; -use crate::bn::BigNum; use crate::error::ErrorStack; use crate::nid::Nid; use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; -use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; + use foreign_types::ForeignType; use openssl_macros::corresponds; +#[cfg(ossl110)] use super::sbgp::IPAddressFamily; - +#[cfg(ossl110)] +use crate::bn::BigNum; +#[cfg(ossl110)] +use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; +#[cfg(ossl110)] +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// An extension which indicates whether a certificate is a CA certificate. pub struct BasicConstraints { critical: bool, @@ -597,6 +601,7 @@ impl SbgpIpAddressIdentifier { } } +#[cfg(ossl110)] impl Stack { /// Adds an address range to the stack /// This helper exists as a utility function, because RFC 3779 types are hard to deal with. diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 33ed6155e3..2f543f4804 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1229,7 +1229,7 @@ fn test_sbgp_as_identifier_builder() { let cert = builder.build(); let asn = cert.sbgp_asn().unwrap(); - assert_eq!(asn.inherited(), false); + assert!(!asn.inherited()); assert_eq!( asn.ranges(), Some(vec![(1000, 1000), (2500, 2700), (9000, 9000)]) From 938a715a4156d1ac6007fa4b10abeb5774964241 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Wed, 15 Nov 2023 13:33:05 +0100 Subject: [PATCH 15/29] fix unused import --- openssl/src/x509/extension.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 825a4074db..dc9122fdb8 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -24,7 +24,6 @@ use crate::nid::Nid; use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; use foreign_types::ForeignType; -use openssl_macros::corresponds; #[cfg(ossl110)] use super::sbgp::IPAddressFamily; @@ -33,7 +32,10 @@ use crate::bn::BigNum; #[cfg(ossl110)] use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; #[cfg(ossl110)] +use openssl_macros::corresponds; +#[cfg(ossl110)] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + /// An extension which indicates whether a certificate is a CA certificate. pub struct BasicConstraints { critical: bool, From c5cad36ac55a5fe90d1c0c26818b747ca3b2b783 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Mon, 27 Nov 2023 13:34:01 +0100 Subject: [PATCH 16/29] fixed inherit & critical defaults & canonical --- openssl-sys/src/handwritten/x509_sbgp.rs | 12 ++- openssl-sys/src/x509_sbgp.rs | 5 ++ openssl/src/x509/extension.rs | 99 ++++++++++++++++++++---- openssl/src/x509/tests.rs | 22 +++++- 4 files changed, 118 insertions(+), 20 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index 2d1973a230..246d39ef99 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -119,7 +119,6 @@ extern "C" { * since their encodings are a bit tedious. * * Not yet used: - * - X509v3_asid_add_inherit * - X509v3_addr_add_inherit * - X509v3_addr_add_prefix */ @@ -129,6 +128,10 @@ extern "C" { min: *mut ASN1_INTEGER, max: *mut ASN1_INTEGER, ) -> c_int; + pub fn X509v3_asid_add_inherit(asid: *mut ASIdentifiers, which: c_int) -> c_int; + pub fn X509v3_asid_canonize(asid: *mut ASIdentifiers) -> c_int; + pub fn X509v3_asid_is_canonical(asid: *mut ASIdentifiers) -> c_int; + pub fn X509v3_addr_get_range( aor: *mut IPAddressOrRange, afi: c_uint, @@ -144,4 +147,11 @@ extern "C" { min: *mut c_uchar, max: *mut c_uchar, ) -> c_int; + pub fn X509v3_addr_add_inherit( + addr: *mut IPAddrBlocks, + afi: c_uint, + safi: *const c_uint, + ) -> c_int; + pub fn X509v3_addr_canonize(addr: *mut IPAddrBlocks) -> c_int; + pub fn X509v3_addr_is_canonical(addr: *mut IPAddrBlocks) -> c_int; } diff --git a/openssl-sys/src/x509_sbgp.rs b/openssl-sys/src/x509_sbgp.rs index 02278a0001..3177839764 100644 --- a/openssl-sys/src/x509_sbgp.rs +++ b/openssl-sys/src/x509_sbgp.rs @@ -28,3 +28,8 @@ pub const IPAddressChoice_addressesOrRanges: c_int = 1; pub const IANA_AFI_IPV4: c_int = 1; #[cfg(ossl110)] pub const IANA_AFI_IPV6: c_int = 2; + +#[cfg(ossl110)] +pub const V3_ASID_ASNUM: c_int = 0; +#[cfg(ossl110)] +pub const V3_ASID_RDI: c_int = 1; diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index dc9122fdb8..504e9eb6c9 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -25,11 +25,14 @@ use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; use foreign_types::ForeignType; +use super::sbgp::ASIdentifiers; #[cfg(ossl110)] -use super::sbgp::IPAddressFamily; +use super::sbgp::{IPAddressFamily, IPVersion}; #[cfg(ossl110)] use crate::bn::BigNum; #[cfg(ossl110)] +use crate::cvt; +#[cfg(ossl110)] use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; #[cfg(ossl110)] use openssl_macros::corresponds; @@ -444,6 +447,7 @@ impl AuthorityKeyIdentifier { pub struct SbgpAsIdentifier { critical: bool, asn: Vec<(u32, u32)>, + inherit: bool, } #[cfg(ossl110)] @@ -458,14 +462,21 @@ impl SbgpAsIdentifier { /// Construct a new `SbgpAsIdentifier` extension. pub fn new() -> SbgpAsIdentifier { SbgpAsIdentifier { - critical: false, + critical: true, asn: Vec::new(), + inherit: false, } } - /// Sets the `critical` flag to `true`. The extension will be critical. - pub fn critical(&mut self) -> &mut SbgpAsIdentifier { - self.critical = true; + /// Sets the `critical` flag. The extension will be critical. + pub fn critical(&mut self, value: bool) -> &mut SbgpAsIdentifier { + self.critical = value; + self + } + + /// Sets the `inherit`` flag to `true`. + pub fn add_inherit(&mut self) -> &mut SbgpAsIdentifier { + self.inherit = true; self } @@ -484,22 +495,46 @@ impl SbgpAsIdentifier { /// Return a `SbgpAsIdentifier` extension as an `X509Extension`. pub fn build(&self) -> Result { unsafe { - let asid = ffi::ASIdentifiers_new(); + let asid = ASIdentifiers::from_ptr(ffi::ASIdentifiers_new()); + if self.inherit { + cvt(ffi::X509v3_asid_add_inherit( + asid.as_ptr(), + ffi::V3_ASID_ASNUM, + ))?; + } + for (min, max) in &self.asn { let min = BigNum::from_u32(*min)?.to_asn1_integer()?; let max = BigNum::from_u32(*max)?.to_asn1_integer()?; if min == max { - ffi::X509v3_asid_add_id_or_range(asid, 0, min.as_ptr(), std::ptr::null_mut()); + cvt(ffi::X509v3_asid_add_id_or_range( + asid.as_ptr(), + 0, + min.as_ptr(), + std::ptr::null_mut(), + ))?; } else { - ffi::X509v3_asid_add_id_or_range(asid, 0, min.as_ptr(), max.as_ptr()); - } + cvt(ffi::X509v3_asid_add_id_or_range( + asid.as_ptr(), + 0, + min.as_ptr(), + max.as_ptr(), + ))?; + }; std::mem::forget(min); std::mem::forget(max); } - X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, self.critical, asid as *mut _) + if ffi::X509v3_asid_is_canonical(asid.as_ptr()) != 1 { + cvt(ffi::X509v3_asid_canonize(asid.as_ptr()))?; + } + + let ptr = asid.as_ptr(); + std::mem::forget(asid); + + X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, self.critical, ptr as *mut _) } } } @@ -508,6 +543,7 @@ impl SbgpAsIdentifier { pub struct SbgpIpAddressIdentifier { critical: bool, ip_ranges: Vec<(IpAddr, IpAddr)>, + inherit: Option, } #[cfg(ossl110)] @@ -522,14 +558,21 @@ impl SbgpIpAddressIdentifier { /// Construct a new `SbgpIpAddressIdentifier` extension. pub fn new() -> SbgpIpAddressIdentifier { SbgpIpAddressIdentifier { - critical: false, + critical: true, ip_ranges: Vec::new(), + inherit: None, } } - /// Sets the `critical` flag to `true`. The extension will be critical. - pub fn critical(&mut self) -> &mut SbgpIpAddressIdentifier { - self.critical = true; + /// Sets the `critical` flag. The extension will be critical. + pub fn critical(&mut self, value: bool) -> &mut SbgpIpAddressIdentifier { + self.critical = value; + self + } + + /// Sets the `inherit` flag in the list corresponding to the ip version. + pub fn add_inherit(&mut self, afi: IPVersion) -> &mut SbgpIpAddressIdentifier { + self.inherit = Some(afi); self } @@ -590,8 +633,23 @@ impl SbgpIpAddressIdentifier { pub fn build(&self) -> Result { unsafe { let mut stack = Stack::::new()?; + if let Some(ref inherit) = self.inherit { + cvt(ffi::X509v3_addr_add_inherit( + stack.as_ptr(), + match inherit { + IPVersion::V4 => IANA_AFI_IPV4 as u32, + IPVersion::V6 => IANA_AFI_IPV6 as u32, + }, + std::ptr::null(), + ))?; + } + for (min, max) in &self.ip_ranges { - stack.sbgp_add_addr_range(*min, *max) + stack.sbgp_add_addr_range(*min, *max)?; + } + + if ffi::X509v3_addr_is_canonical(stack.as_ptr()) != 1 { + cvt(ffi::X509v3_addr_canonize(stack.as_ptr()))?; } X509Extension::new_internal( @@ -608,7 +666,7 @@ impl Stack { /// Adds an address range to the stack /// This helper exists as a utility function, because RFC 3779 types are hard to deal with. #[corresponds(X509v3_addr_add_range)] - pub fn sbgp_add_addr_range(&mut self, min: IpAddr, max: IpAddr) { + pub fn sbgp_add_addr_range(&mut self, min: IpAddr, max: IpAddr) -> Result<(), ErrorStack> { unsafe { let (min, max, afi) = match (min, max) { (IpAddr::V4(mut min), IpAddr::V4(mut max)) => ( @@ -624,7 +682,14 @@ impl Stack { _ => unreachable!(), }; - ffi::X509v3_addr_add_range(self.as_ptr().cast(), afi, std::ptr::null_mut(), min, max); + cvt(ffi::X509v3_addr_add_range( + self.as_ptr().cast(), + afi, + std::ptr::null_mut(), + min, + max, + )) + .map(|_| ()) } } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 2f543f4804..2f661f1490 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1218,7 +1218,6 @@ fn test_sbgp_extensions_parsing() { fn test_sbgp_as_identifier_builder() { let mut builder = X509Builder::new().unwrap(); let as_id_ext = SbgpAsIdentifier::new() - .critical() .add_asn(1000) .add_asn_range(2500, 2700) .add_asn(9000) @@ -1236,6 +1235,26 @@ fn test_sbgp_as_identifier_builder() { ); } +#[test] +#[cfg(ossl110)] +fn test_sbgp_as_identifier_builder_inherit() { + let mut builder = X509Builder::new().unwrap(); + let as_id_ext = SbgpAsIdentifier::new().add_inherit().build().unwrap(); + + builder.append_extension(as_id_ext).unwrap(); + let cert = builder.build(); + + let asn = cert.sbgp_asn().unwrap(); + assert!(asn.inherited()); + assert_eq!(asn.ranges(), None); + + assert!(SbgpAsIdentifier::new() + .add_inherit() + .add_asn(123) + .build() + .is_err()); +} + #[test] #[cfg(ossl110)] fn test_sbgp_ip_addr_ranges_builder() { @@ -1243,7 +1262,6 @@ fn test_sbgp_ip_addr_ranges_builder() { let mut builder = X509Builder::new().unwrap(); let ip_addr_ext = SbgpIpAddressIdentifier::new() - .critical() .add_ip_addr(IpAddr::from_str("10.0.0.0").unwrap()) .add_ip_prefix(IpAddr::from_str("20.0.0.0").unwrap(), 16) .add_ipv6_addr_range( From 0dd8c8daddc0fd52ce4319683051a1a9ba1df7a0 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Wed, 29 Nov 2023 15:51:54 +0100 Subject: [PATCH 17/29] fix leak, deferred allocation of max --- openssl/src/x509/extension.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 504e9eb6c9..1e6c656d42 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -504,27 +504,28 @@ impl SbgpAsIdentifier { } for (min, max) in &self.asn { - let min = BigNum::from_u32(*min)?.to_asn1_integer()?; - let max = BigNum::from_u32(*max)?.to_asn1_integer()?; - + let asn_min = BigNum::from_u32(*min)?.to_asn1_integer()?; if min == max { cvt(ffi::X509v3_asid_add_id_or_range( asid.as_ptr(), 0, - min.as_ptr(), + asn_min.as_ptr(), std::ptr::null_mut(), + ))?; } else { + let asn_max = BigNum::from_u32(*max)?.to_asn1_integer()?; cvt(ffi::X509v3_asid_add_id_or_range( asid.as_ptr(), 0, - min.as_ptr(), - max.as_ptr(), + asn_min.as_ptr(), + asn_max.as_ptr(), ))?; + std::mem::forget(asn_max); }; - - std::mem::forget(min); - std::mem::forget(max); + // On success ownership of min and max was moved, so forget + // On failure the fn early returned, thus the Rust types will free min and max + std::mem::forget(asn_min); } if ffi::X509v3_asid_is_canonical(asid.as_ptr()) != 1 { From e4c23d1698a409a214b50993bbf50569d2fdda63 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Mon, 4 Dec 2023 11:42:50 +0100 Subject: [PATCH 18/29] simplified builder, removed nonrepr states --- openssl-sys/src/handwritten/x509_sbgp.rs | 9 +- openssl/src/x509/extension.rs | 223 +++++++++++++---------- openssl/src/x509/sbgp.rs | 44 ++--- openssl/src/x509/tests.rs | 33 +++- 4 files changed, 175 insertions(+), 134 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index 246d39ef99..aa6156a567 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -117,10 +117,6 @@ extern "C" { /* * Utility functions for working with RFC 3779 values, * since their encodings are a bit tedious. - * - * Not yet used: - * - X509v3_addr_add_inherit - * - X509v3_addr_add_prefix */ pub fn X509v3_asid_add_id_or_range( asid: *mut ASIdentifiers, @@ -131,6 +127,11 @@ extern "C" { pub fn X509v3_asid_add_inherit(asid: *mut ASIdentifiers, which: c_int) -> c_int; pub fn X509v3_asid_canonize(asid: *mut ASIdentifiers) -> c_int; pub fn X509v3_asid_is_canonical(asid: *mut ASIdentifiers) -> c_int; + pub fn X509v3_asid_inherits(asid: *mut ASIdentifiers) -> c_int; + pub fn X509v3_asid_subset(child: *mut ASIdentifiers, parent: *mut ASIdentifiers) -> c_int; + pub fn X509v3_asid_validate_path(ctx: *mut X509_STORE_CTX) -> c_int; + pub fn X509v3_asid_validate_resource_set(chain: *mut stack_st_X509, ext: *mut ASIdentifiers, allow_inheritence: c_int) -> c_int; + pub fn X509v3_addr_get_range( aor: *mut IPAddressOrRange, diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 1e6c656d42..34e74caa4e 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -444,51 +444,52 @@ impl AuthorityKeyIdentifier { } #[cfg(ossl110)] -pub struct SbgpAsIdentifier { - critical: bool, - asn: Vec<(u32, u32)>, - inherit: bool, +#[cfg(not(OPENSSL_NO_RFC3779))] +pub struct SbgpAsIdentifier(SbgpAsIdentifierOrInherit); + +#[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] +enum SbgpAsIdentifierOrInherit { + Inherit, + Local(Vec<(u32, u32)>) } #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] impl Default for SbgpAsIdentifier { fn default() -> SbgpAsIdentifier { SbgpAsIdentifier::new() } } + #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] impl SbgpAsIdentifier { /// Construct a new `SbgpAsIdentifier` extension. pub fn new() -> SbgpAsIdentifier { - SbgpAsIdentifier { - critical: true, - asn: Vec::new(), - inherit: false, - } - } - - /// Sets the `critical` flag. The extension will be critical. - pub fn critical(&mut self, value: bool) -> &mut SbgpAsIdentifier { - self.critical = value; - self + Self(SbgpAsIdentifierOrInherit::Local(Vec::new())) } /// Sets the `inherit`` flag to `true`. pub fn add_inherit(&mut self) -> &mut SbgpAsIdentifier { - self.inherit = true; + self.0 = SbgpAsIdentifierOrInherit::Inherit; self } /// Adds an AS number. pub fn add_asn(&mut self, asn: u32) -> &mut SbgpAsIdentifier { - self.asn.push((asn, asn)); + if let SbgpAsIdentifierOrInherit::Local(ref mut asns) = self.0 { + asns.push((asn, asn)) + } self } /// Adds a range of AS numbers. pub fn add_asn_range(&mut self, asn_min: u32, asn_max: u32) -> &mut SbgpAsIdentifier { - self.asn.push((asn_min, asn_max)); + if let SbgpAsIdentifierOrInherit::Local(ref mut asns) = self.0 { + asns.push((asn_min, asn_max)) + } self } @@ -496,58 +497,74 @@ impl SbgpAsIdentifier { pub fn build(&self) -> Result { unsafe { let asid = ASIdentifiers::from_ptr(ffi::ASIdentifiers_new()); - if self.inherit { - cvt(ffi::X509v3_asid_add_inherit( - asid.as_ptr(), - ffi::V3_ASID_ASNUM, - ))?; - } - - for (min, max) in &self.asn { - let asn_min = BigNum::from_u32(*min)?.to_asn1_integer()?; - if min == max { - cvt(ffi::X509v3_asid_add_id_or_range( - asid.as_ptr(), - 0, - asn_min.as_ptr(), - std::ptr::null_mut(), - - ))?; - } else { - let asn_max = BigNum::from_u32(*max)?.to_asn1_integer()?; - cvt(ffi::X509v3_asid_add_id_or_range( + match self.0 { + SbgpAsIdentifierOrInherit::Inherit => { + cvt(ffi::X509v3_asid_add_inherit( asid.as_ptr(), - 0, - asn_min.as_ptr(), - asn_max.as_ptr(), + ffi::V3_ASID_ASNUM, ))?; - std::mem::forget(asn_max); - }; - // On success ownership of min and max was moved, so forget - // On failure the fn early returned, thus the Rust types will free min and max - std::mem::forget(asn_min); - } - - if ffi::X509v3_asid_is_canonical(asid.as_ptr()) != 1 { - cvt(ffi::X509v3_asid_canonize(asid.as_ptr()))?; - } + }, + SbgpAsIdentifierOrInherit::Local(ref asns) => { + assert!(!asns.is_empty(), "cannot create empty extension"); + + for (min, max) in asns { + let asn_min = BigNum::from_u32(*min)?.to_asn1_integer()?; + if min == max { + cvt(ffi::X509v3_asid_add_id_or_range( + asid.as_ptr(), + 0, + asn_min.as_ptr(), + std::ptr::null_mut(), + + ))?; + } else { + let asn_max = BigNum::from_u32(*max)?.to_asn1_integer()?; + cvt(ffi::X509v3_asid_add_id_or_range( + asid.as_ptr(), + 0, + asn_min.as_ptr(), + asn_max.as_ptr(), + ))?; + std::mem::forget(asn_max); + }; + // On success ownership of min and max was moved, so forget + // On failure the fn early returned, thus the Rust types will free min and max + std::mem::forget(asn_min); + } + + // canonize must only be performed on this branch, since an inherit + // ext is automatically canoical + if ffi::X509v3_asid_is_canonical(asid.as_ptr()) != 1 { + cvt(ffi::X509v3_asid_canonize(asid.as_ptr()))?; + } + } + } let ptr = asid.as_ptr(); std::mem::forget(asid); - X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, self.critical, ptr as *mut _) + X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, true, ptr as *mut _) } } } #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] pub struct SbgpIpAddressIdentifier { - critical: bool, - ip_ranges: Vec<(IpAddr, IpAddr)>, - inherit: Option, + v4: SbgpIpAddressIdentifierOrInherit, + v6: SbgpIpAddressIdentifierOrInherit, +} + +#[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] +enum SbgpIpAddressIdentifierOrInherit { + Inherit, + Local(Vec<(Addr, Addr)>) } + #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] impl Default for SbgpIpAddressIdentifier { fn default() -> SbgpIpAddressIdentifier { SbgpIpAddressIdentifier::new() @@ -555,32 +572,31 @@ impl Default for SbgpIpAddressIdentifier { } #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] impl SbgpIpAddressIdentifier { /// Construct a new `SbgpIpAddressIdentifier` extension. pub fn new() -> SbgpIpAddressIdentifier { SbgpIpAddressIdentifier { - critical: true, - ip_ranges: Vec::new(), - inherit: None, + v4: SbgpIpAddressIdentifierOrInherit::Local(Vec::new()), + v6: SbgpIpAddressIdentifierOrInherit::Local(Vec::new()), } } - /// Sets the `critical` flag. The extension will be critical. - pub fn critical(&mut self, value: bool) -> &mut SbgpIpAddressIdentifier { - self.critical = value; - self - } - /// Sets the `inherit` flag in the list corresponding to the ip version. pub fn add_inherit(&mut self, afi: IPVersion) -> &mut SbgpIpAddressIdentifier { - self.inherit = Some(afi); + match afi { + IPVersion::V4 => self.v4 = SbgpIpAddressIdentifierOrInherit::Inherit, + IPVersion::V6 => self.v6 = SbgpIpAddressIdentifierOrInherit::Inherit, + } self } /// Adds an IP adress. pub fn add_ip_addr(&mut self, ip_addr: IpAddr) -> &mut SbgpIpAddressIdentifier { - self.ip_ranges.push((ip_addr, ip_addr)); - self + match ip_addr { + IpAddr::V4(addr) => self.add_ipv4_addr_range(addr, addr), + IpAddr::V6(addr)=> self.add_ipv6_addr_range(addr, addr), + } } /// Adds a range of IPv4 adresses. @@ -589,8 +605,9 @@ impl SbgpIpAddressIdentifier { ip_addr_min: Ipv4Addr, ip_addr_max: Ipv4Addr, ) -> &mut SbgpIpAddressIdentifier { - self.ip_ranges - .push((IpAddr::V4(ip_addr_min), IpAddr::V4(ip_addr_max))); + if let SbgpIpAddressIdentifierOrInherit::Local(ref mut ips) = self.v4 { + ips.push((ip_addr_min, ip_addr_max)); + } self } @@ -600,8 +617,9 @@ impl SbgpIpAddressIdentifier { ip_addr_min: Ipv6Addr, ip_addr_max: Ipv6Addr, ) -> &mut SbgpIpAddressIdentifier { - self.ip_ranges - .push((IpAddr::V6(ip_addr_min), IpAddr::V6(ip_addr_max))); + if let SbgpIpAddressIdentifierOrInherit::Local(ref mut ips) = self.v6 { + ips.push((ip_addr_min, ip_addr_max)); + } self } @@ -616,15 +634,13 @@ impl SbgpIpAddressIdentifier { let mask = !(u32::MAX >> prefixlen); let min = mask & u32::from(prefix); let max = min | !mask; - self.ip_ranges - .push((Ipv4Addr::from(min).into(), Ipv4Addr::from(max).into())); + self.add_ipv4_addr_range(min.into(), max.into()); } IpAddr::V6(prefix) => { let mask = !(u128::MAX >> prefixlen); let min = mask & u128::from(prefix); let max = min | !mask; - self.ip_ranges - .push((Ipv6Addr::from(min).into(), Ipv6Addr::from(max).into())); + self.add_ipv6_addr_range(min.into(), max.into()); } } self @@ -634,28 +650,43 @@ impl SbgpIpAddressIdentifier { pub fn build(&self) -> Result { unsafe { let mut stack = Stack::::new()?; - if let Some(ref inherit) = self.inherit { - cvt(ffi::X509v3_addr_add_inherit( + + match self.v4 { + SbgpIpAddressIdentifierOrInherit::Inherit => { + cvt(ffi::X509v3_addr_add_inherit( stack.as_ptr(), - match inherit { - IPVersion::V4 => IANA_AFI_IPV4 as u32, - IPVersion::V6 => IANA_AFI_IPV6 as u32, - }, + IANA_AFI_IPV4 as u32, std::ptr::null(), - ))?; + ))?; + }, + SbgpIpAddressIdentifierOrInherit::Local(ref ips) => { + for (min, max) in ips { + stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV4 as u32)?; + } + }, } - - for (min, max) in &self.ip_ranges { - stack.sbgp_add_addr_range(*min, *max)?; + match self.v6 { + SbgpIpAddressIdentifierOrInherit::Inherit => { + cvt(ffi::X509v3_addr_add_inherit( + stack.as_ptr(), + IANA_AFI_IPV6 as u32, + std::ptr::null(), + ))?; + }, + SbgpIpAddressIdentifierOrInherit::Local(ref ips) => { + for (min, max) in ips { + stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV6 as u32)?; + } + }, } - + if ffi::X509v3_addr_is_canonical(stack.as_ptr()) != 1 { cvt(ffi::X509v3_addr_canonize(stack.as_ptr()))?; } X509Extension::new_internal( Nid::SBGP_IPADDRBLOCK, - self.critical, + true, stack.as_ptr() as *mut _, ) } @@ -663,25 +694,15 @@ impl SbgpIpAddressIdentifier { } #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] impl Stack { /// Adds an address range to the stack /// This helper exists as a utility function, because RFC 3779 types are hard to deal with. #[corresponds(X509v3_addr_add_range)] - pub fn sbgp_add_addr_range(&mut self, min: IpAddr, max: IpAddr) -> Result<(), ErrorStack> { + pub fn sbgp_add_addr_range(&mut self, mut min: Addr, mut max: Addr, afi: u32) -> Result<(), ErrorStack> { unsafe { - let (min, max, afi) = match (min, max) { - (IpAddr::V4(mut min), IpAddr::V4(mut max)) => ( - &mut min as *mut _ as *mut u8, - &mut max as *mut _ as *mut u8, - IANA_AFI_IPV4 as u32, - ), - (IpAddr::V6(mut min), IpAddr::V6(mut max)) => ( - &mut min as *mut _ as *mut u8, - &mut max as *mut _ as *mut u8, - IANA_AFI_IPV6 as u32, - ), - _ => unreachable!(), - }; + let min = &mut min as *mut _ as *mut u8; + let max = &mut max as *mut _ as *mut u8; cvt(ffi::X509v3_addr_add_range( self.as_ptr().cast(), diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index 1bf04cebdf..07f16ab7c7 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -1,30 +1,25 @@ -#[cfg(ossl110)] +#![cfg(ossl110)] +#![cfg(not(OPENSSL_NO_RFC3779))] + use std::mem::MaybeUninit; -#[cfg(ossl110)] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -#[cfg(ossl110)] use ffi::{ ASIdOrRange_id, ASIdOrRange_range, ASIdentifierChoice_asIdsOrRanges, - ASIdentifierChoice_inherit, IPAddressChoice_addressesOrRanges, X509v3_addr_get_afi, + IPAddressChoice_addressesOrRanges, X509v3_addr_get_afi, ASN1_INTEGER, IANA_AFI_IPV4, IANA_AFI_IPV6, }; -#[cfg(ossl110)] use foreign_types::ForeignTypeRef; -#[cfg(ossl110)] use openssl_macros::corresponds; -#[cfg(ossl110)] use crate::{ asn1::Asn1IntegerRef, stack::{Stack, StackRef, Stackable}, util::{ForeignTypeExt, ForeignTypeRefExt}, }; -#[cfg(ossl110)] use super::X509Ref; -#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::ASIdOrRange; fn drop = ffi::ASIdOrRange_free; @@ -34,12 +29,10 @@ foreign_type_and_impl_send_sync! { /// Reference to `ASIdOrRange`. pub struct ASIdOrRangeRef; } -#[cfg(ossl110)] impl Stackable for ASIdOrRange { type StackType = ffi::stack_st_ASIdOrRange; } -#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::ASIdentifiers; fn drop = ffi::ASIdentifiers_free; @@ -50,13 +43,27 @@ foreign_type_and_impl_send_sync! { pub struct ASIdentifiersRef; } -#[cfg(ossl110)] impl ASIdentifiers { + #[corresponds(X509v3_asid_inherits)] pub fn inherited(&self) -> bool { unsafe { - let asptr = self.0; - let asnum = (*asptr).asnum; - (*asnum).type_ == ASIdentifierChoice_inherit + ffi::X509v3_asid_inherits(self.as_ptr()) == 1 + } + } + + #[corresponds(X509v3_asid_subset)] + pub fn contains(&self, parent: &ASIdentifiers) -> bool { + unsafe { + assert!(self.is_canonical()); + assert!(parent.is_canonical()); + ffi::X509v3_asid_subset(self.as_ptr(), parent.as_ptr()) == 1 + } + } + + #[corresponds(X509v3_asid_is_canonical)] + pub fn is_canonical(&self) -> bool { + unsafe { + ffi::X509v3_asid_is_canonical(self.as_ptr()) == 1 } } @@ -94,7 +101,6 @@ impl ASIdentifiers { } } -#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::IPAddressOrRange; fn drop = ffi::IPAddressOrRange_free; @@ -105,12 +111,10 @@ foreign_type_and_impl_send_sync! { pub struct IPAddressOrRangeRef; } -#[cfg(ossl110)] impl Stackable for IPAddressOrRange { type StackType = ffi::stack_st_IPAddressOrRange; } -#[cfg(ossl110)] foreign_type_and_impl_send_sync! { type CType = ffi::IPAddressFamily; fn drop = ffi::IPAddressFamily_free; @@ -121,19 +125,16 @@ foreign_type_and_impl_send_sync! { pub struct IPAddressFamilyRef; } -#[cfg(ossl110)] impl Stackable for IPAddressFamily { type StackType = ffi::stack_st_IPAddressFamily; } #[derive(PartialEq, Eq, Debug)] -#[cfg(ossl110)] pub enum IPVersion { V4, V6, } -#[cfg(ossl110)] impl IPAddressFamily { /// Returns the IP version of this record. #[corresponds(X509v3_addr_get_afi)] @@ -192,7 +193,6 @@ impl IPAddressFamily { } } -#[cfg(ossl110)] impl X509Ref { #[corresponds(X509_get_ext_d2i)] pub fn sbgp_asn(&self) -> Option { diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 2f661f1490..7c675c97ac 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1187,13 +1187,22 @@ fn test_dist_point_null() { #[test] #[cfg(ossl110)] fn test_sbgp_extensions_parsing() { - let cert = include_bytes!("../../test/rfc3779.pem"); - let cert = X509::from_pem(cert).unwrap(); + let cert_bytes = include_bytes!("../../test/rfc3779.pem"); + let cert = X509::from_pem(cert_bytes).unwrap(); + + let asn = cert.sbgp_asn().unwrap(); + assert!(!asn.inherited()); + assert!(asn.is_canonical()); - let asn_ranges = cert.sbgp_asn().unwrap().ranges().unwrap(); + let cert1 = X509::from_pem(cert_bytes).unwrap(); + let prnt = cert1.sbgp_asn().unwrap(); + assert!(asn.contains(&prnt)); + + let asn_ranges = asn.ranges().unwrap(); assert_eq!(asn_ranges[0], (10, 18)); assert_eq!(asn_ranges[1], (20, 20)); + let families = cert.sbgp_ip_addresses().unwrap(); for family in families { let ranges = family.range().unwrap(); @@ -1239,20 +1248,30 @@ fn test_sbgp_as_identifier_builder() { #[cfg(ossl110)] fn test_sbgp_as_identifier_builder_inherit() { let mut builder = X509Builder::new().unwrap(); - let as_id_ext = SbgpAsIdentifier::new().add_inherit().build().unwrap(); + let ext = SbgpAsIdentifier::new().add_inherit().build().unwrap(); - builder.append_extension(as_id_ext).unwrap(); + builder.append_extension(ext).unwrap(); let cert = builder.build(); let asn = cert.sbgp_asn().unwrap(); assert!(asn.inherited()); assert_eq!(asn.ranges(), None); - assert!(SbgpAsIdentifier::new() + // + + let mut builder = X509Builder::new().unwrap(); + let ext = SbgpAsIdentifier::new() .add_inherit() .add_asn(123) .build() - .is_err()); + .unwrap(); + + builder.append_extension(ext).unwrap(); + let cert = builder.build(); + + let asn = cert.sbgp_asn().unwrap(); + assert!(asn.inherited()); + assert_eq!(asn.ranges(), None); } #[test] From 2386460fc2fd8d9dd59510230bcd6976bb96aea2 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Mon, 4 Dec 2023 14:22:21 +0100 Subject: [PATCH 19/29] fixed cfg statements --- openssl-sys/src/handwritten/mod.rs | 4 ++++ openssl-sys/src/handwritten/x509_sbgp.rs | 21 --------------------- openssl/src/x509/extension.rs | 8 ++------ 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/openssl-sys/src/handwritten/mod.rs b/openssl-sys/src/handwritten/mod.rs index 292c0ecaa8..a5f75ccf75 100644 --- a/openssl-sys/src/handwritten/mod.rs +++ b/openssl-sys/src/handwritten/mod.rs @@ -31,6 +31,8 @@ pub use self::stack::*; pub use self::tls1::*; pub use self::types::*; pub use self::x509::*; +#[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] pub use self::x509_sbgp::*; pub use self::x509_vfy::*; pub use self::x509v3::*; @@ -68,6 +70,8 @@ mod stack; mod tls1; mod types; mod x509; +#[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] mod x509_sbgp; mod x509_vfy; mod x509v3; diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index aa6156a567..469f3ef801 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -1,105 +1,84 @@ -#[cfg(ossl110)] use super::super::*; -#[cfg(ossl110)] use libc::*; #[repr(C)] -#[cfg(ossl110)] pub struct ASRange { pub min: *mut ASN1_INTEGER, pub max: *mut ASN1_INTEGER, } #[repr(C)] -#[cfg(ossl110)] pub struct ASIdOrRange { pub type_: c_int, pub u: ASIdOrRange_st_anon_union, } #[repr(C)] -#[cfg(ossl110)] pub union ASIdOrRange_st_anon_union { pub id: *mut ASN1_INTEGER, pub range: *mut ASRange, } -#[cfg(ossl110)] stack!(stack_st_ASIdOrRange); -#[cfg(ossl110)] type ASIdOrRanges = stack_st_ASIdOrRange; #[repr(C)] -#[cfg(ossl110)] pub union ASIdentifierChoice_st_anon_union { pub asIdsOrRanges: *mut stack_st_ASIdOrRange, } #[repr(C)] -#[cfg(ossl110)] pub struct ASIdentifierChoice { pub type_: c_int, pub u: ASIdentifierChoice_st_anon_union, } #[repr(C)] -#[cfg(ossl110)] pub struct ASIdentifiers { pub asnum: *mut ASIdentifierChoice, pub rdi: *mut ASIdentifierChoice, } #[repr(C)] -#[cfg(ossl110)] pub struct IPAddressRange { pub min: *mut ASN1_BIT_STRING, pub max: *mut ASN1_BIT_STRING, } #[repr(C)] -#[cfg(ossl110)] pub struct IPAddressOrRange { pub type_: c_int, pub u: IPAddressOrRange_st_anon_union, } #[repr(C)] -#[cfg(ossl110)] pub union IPAddressOrRange_st_anon_union { pub addressPrefix: *mut ASN1_BIT_STRING, pub addressRange: *mut IPAddressRange, } -#[cfg(ossl110)] stack!(stack_st_IPAddressOrRange); -#[cfg(ossl110)] type IPAddressOrRanges = stack_st_IPAddressOrRange; #[repr(C)] -#[cfg(ossl110)] pub union IPAddressChoice_st_anon_union { pub addressesOrRanges: *mut IPAddressOrRanges, } #[repr(C)] -#[cfg(ossl110)] pub struct IPAddressChoice { pub type_: c_int, pub u: IPAddressChoice_st_anon_union, } #[repr(C)] -#[cfg(ossl110)] pub struct IPAddressFamily { pub addressFamily: *mut ASN1_OCTET_STRING, pub ipAddressChoice: *mut IPAddressChoice, } -#[cfg(ossl110)] stack!(stack_st_IPAddressFamily); -#[cfg(ossl110)] type IPAddrBlocks = stack_st_IPAddressFamily; -#[cfg(ossl110)] extern "C" { /* * Constructors / Destructors for SBGP autonomousSysNum diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 34e74caa4e..0a98da811a 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -539,11 +539,7 @@ impl SbgpAsIdentifier { } } } - - let ptr = asid.as_ptr(); - std::mem::forget(asid); - - X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, true, ptr as *mut _) + X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, true, asid.as_ptr().cast()) } } } @@ -687,7 +683,7 @@ impl SbgpIpAddressIdentifier { X509Extension::new_internal( Nid::SBGP_IPADDRBLOCK, true, - stack.as_ptr() as *mut _, + stack.as_ptr().cast(), ) } } From 49fec48bef4d60389de476a5fcfbd0eb9c70b894 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Wed, 6 Dec 2023 15:29:22 +0100 Subject: [PATCH 20/29] added assertions & panics + renamed some types --- openssl/src/x509/extension.rs | 56 +++++++++++++++++++++++++---------- openssl/src/x509/sbgp.rs | 14 ++++----- openssl/src/x509/tests.rs | 7 ++--- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 0a98da811a..def00f31c2 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -27,7 +27,7 @@ use foreign_types::ForeignType; use super::sbgp::ASIdentifiers; #[cfg(ossl110)] -use super::sbgp::{IPAddressFamily, IPVersion}; +use super::sbgp::{IPAddressFamily, IpVersion}; #[cfg(ossl110)] use crate::bn::BigNum; #[cfg(ossl110)] @@ -451,7 +451,7 @@ pub struct SbgpAsIdentifier(SbgpAsIdentifierOrInherit); #[cfg(not(OPENSSL_NO_RFC3779))] enum SbgpAsIdentifierOrInherit { Inherit, - Local(Vec<(u32, u32)>) + List(Vec<(u32, u32)>) } #[cfg(ossl110)] @@ -468,27 +468,37 @@ impl Default for SbgpAsIdentifier { impl SbgpAsIdentifier { /// Construct a new `SbgpAsIdentifier` extension. pub fn new() -> SbgpAsIdentifier { - Self(SbgpAsIdentifierOrInherit::Local(Vec::new())) + Self(SbgpAsIdentifierOrInherit::List(Vec::new())) } /// Sets the `inherit`` flag to `true`. pub fn add_inherit(&mut self) -> &mut SbgpAsIdentifier { + if let SbgpAsIdentifierOrInherit::List(ref l) = self.0 { + if !l.is_empty() { + panic!("cannot set extension to inherit, list allready contains elements"); + } + } + self.0 = SbgpAsIdentifierOrInherit::Inherit; self } /// Adds an AS number. pub fn add_asn(&mut self, asn: u32) -> &mut SbgpAsIdentifier { - if let SbgpAsIdentifierOrInherit::Local(ref mut asns) = self.0 { + if let SbgpAsIdentifierOrInherit::List(ref mut asns) = self.0 { asns.push((asn, asn)) + } else { + panic!("cannot add AS number to extension, extension is set to inherit"); } self } /// Adds a range of AS numbers. pub fn add_asn_range(&mut self, asn_min: u32, asn_max: u32) -> &mut SbgpAsIdentifier { - if let SbgpAsIdentifierOrInherit::Local(ref mut asns) = self.0 { + if let SbgpAsIdentifierOrInherit::List(ref mut asns) = self.0 { asns.push((asn_min, asn_max)) + } else { + panic!("cannot add AS range to extension, extension is set to inherit"); } self } @@ -504,7 +514,7 @@ impl SbgpAsIdentifier { ffi::V3_ASID_ASNUM, ))?; }, - SbgpAsIdentifierOrInherit::Local(ref asns) => { + SbgpAsIdentifierOrInherit::List(ref asns) => { assert!(!asns.is_empty(), "cannot create empty extension"); for (min, max) in asns { @@ -555,7 +565,7 @@ pub struct SbgpIpAddressIdentifier { #[cfg(not(OPENSSL_NO_RFC3779))] enum SbgpIpAddressIdentifierOrInherit { Inherit, - Local(Vec<(Addr, Addr)>) + List(Vec<(Addr, Addr)>) } @@ -573,16 +583,26 @@ impl SbgpIpAddressIdentifier { /// Construct a new `SbgpIpAddressIdentifier` extension. pub fn new() -> SbgpIpAddressIdentifier { SbgpIpAddressIdentifier { - v4: SbgpIpAddressIdentifierOrInherit::Local(Vec::new()), - v6: SbgpIpAddressIdentifierOrInherit::Local(Vec::new()), + v4: SbgpIpAddressIdentifierOrInherit::List(Vec::new()), + v6: SbgpIpAddressIdentifierOrInherit::List(Vec::new()), + } + } + + fn len_of(&self, afi: IpVersion) -> usize { + match (afi, &self.v4, &self.v6) { + (IpVersion::V4, SbgpIpAddressIdentifierOrInherit::List(l), _) => l.len(), + (IpVersion::V6, _, SbgpIpAddressIdentifierOrInherit::List(l)) => l.len(), + _ => 0, } } /// Sets the `inherit` flag in the list corresponding to the ip version. - pub fn add_inherit(&mut self, afi: IPVersion) -> &mut SbgpIpAddressIdentifier { + pub fn add_inherit(&mut self, afi: IpVersion) -> &mut SbgpIpAddressIdentifier { match afi { - IPVersion::V4 => self.v4 = SbgpIpAddressIdentifierOrInherit::Inherit, - IPVersion::V6 => self.v6 = SbgpIpAddressIdentifierOrInherit::Inherit, + IpVersion::V4 if self.len_of(afi) == 0 => self.v4 = SbgpIpAddressIdentifierOrInherit::Inherit, + IpVersion::V4 => panic!("cannot set ipv4 to inherit, list allready contains values"), + IpVersion::V6 if self.len_of(afi) == 0 => self.v6 = SbgpIpAddressIdentifierOrInherit::Inherit, + IpVersion::V6 => panic!("cannot set ipv6 to inherit, list allready contains values"), } self } @@ -601,8 +621,10 @@ impl SbgpIpAddressIdentifier { ip_addr_min: Ipv4Addr, ip_addr_max: Ipv4Addr, ) -> &mut SbgpIpAddressIdentifier { - if let SbgpIpAddressIdentifierOrInherit::Local(ref mut ips) = self.v4 { + if let SbgpIpAddressIdentifierOrInherit::List(ref mut ips) = self.v4 { ips.push((ip_addr_min, ip_addr_max)); + } else { + panic!("cannot add ipv4 address to extension, ipv4 is set to inherit"); } self } @@ -613,8 +635,10 @@ impl SbgpIpAddressIdentifier { ip_addr_min: Ipv6Addr, ip_addr_max: Ipv6Addr, ) -> &mut SbgpIpAddressIdentifier { - if let SbgpIpAddressIdentifierOrInherit::Local(ref mut ips) = self.v6 { + if let SbgpIpAddressIdentifierOrInherit::List(ref mut ips) = self.v6 { ips.push((ip_addr_min, ip_addr_max)); + } else { + panic!("cannot add ipv6 address to extension, ipv6 is set to inherit"); } self } @@ -655,7 +679,7 @@ impl SbgpIpAddressIdentifier { std::ptr::null(), ))?; }, - SbgpIpAddressIdentifierOrInherit::Local(ref ips) => { + SbgpIpAddressIdentifierOrInherit::List(ref ips) => { for (min, max) in ips { stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV4 as u32)?; } @@ -669,7 +693,7 @@ impl SbgpIpAddressIdentifier { std::ptr::null(), ))?; }, - SbgpIpAddressIdentifierOrInherit::Local(ref ips) => { + SbgpIpAddressIdentifierOrInherit::List(ref ips) => { for (min, max) in ips { stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV6 as u32)?; } diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index 07f16ab7c7..d86bd7f6ce 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -129,8 +129,8 @@ impl Stackable for IPAddressFamily { type StackType = ffi::stack_st_IPAddressFamily; } -#[derive(PartialEq, Eq, Debug)] -pub enum IPVersion { +#[derive(PartialEq, Clone, Copy, Eq, Debug)] +pub enum IpVersion { V4, V6, } @@ -138,12 +138,12 @@ pub enum IPVersion { impl IPAddressFamily { /// Returns the IP version of this record. #[corresponds(X509v3_addr_get_afi)] - pub fn fam(&self) -> Option { + pub fn fam(&self) -> Option { unsafe { let ptr = self.0; match X509v3_addr_get_afi(ptr) as libc::c_int { - IANA_AFI_IPV4 => Some(IPVersion::V4), - IANA_AFI_IPV6 => Some(IPVersion::V6), + IANA_AFI_IPV4 => Some(IpVersion::V4), + IANA_AFI_IPV6 => Some(IpVersion::V6), _ => None, } } @@ -162,8 +162,8 @@ impl IPAddressFamily { let stack = StackRef::::from_const_ptr_opt((*choice).u.addressesOrRanges)?; match fam { - IPVersion::V4 => Self::addr_get_range::(stack, 4, IANA_AFI_IPV4 as u32), - IPVersion::V6 => Self::addr_get_range::(stack, 16, IANA_AFI_IPV6 as u32), + IpVersion::V4 => Self::addr_get_range::(stack, 4, IANA_AFI_IPV4 as u32), + IpVersion::V6 => Self::addr_get_range::(stack, 16, IANA_AFI_IPV6 as u32), } } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 7c675c97ac..036fbd8a79 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1262,7 +1262,6 @@ fn test_sbgp_as_identifier_builder_inherit() { let mut builder = X509Builder::new().unwrap(); let ext = SbgpAsIdentifier::new() .add_inherit() - .add_asn(123) .build() .unwrap(); @@ -1277,7 +1276,7 @@ fn test_sbgp_as_identifier_builder_inherit() { #[test] #[cfg(ossl110)] fn test_sbgp_ip_addr_ranges_builder() { - use crate::x509::sbgp::IPVersion; + use crate::x509::sbgp::IpVersion; let mut builder = X509Builder::new().unwrap(); let ip_addr_ext = SbgpIpAddressIdentifier::new() @@ -1305,7 +1304,7 @@ fn test_sbgp_ip_addr_ranges_builder() { assert_eq!(ranges.len(), 2); - assert_eq!(ranges[0].fam(), Some(IPVersion::V4)); + assert_eq!(ranges[0].fam(), Some(IpVersion::V4)); assert_eq!( ranges[0].range(), Some(vec![ @@ -1324,7 +1323,7 @@ fn test_sbgp_ip_addr_ranges_builder() { ]) ); - assert_eq!(ranges[1].fam(), Some(IPVersion::V6)); + assert_eq!(ranges[1].fam(), Some(IpVersion::V6)); assert_eq!( ranges[1].range(), Some(vec![( From cc295b5d8c74ffadbfedd639ff797eddc9ca3911 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Mon, 18 Dec 2023 10:41:58 +0100 Subject: [PATCH 21/29] docs & AS number extension subset_of test --- openssl/src/x509/extension.rs | 16 +++++++++------- openssl/src/x509/sbgp.rs | 12 +++++++++++- openssl/src/x509/tests.rs | 9 +++++++-- openssl/test/rfc3779-parent.pem | 18 ++++++++++++++++++ 4 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 openssl/test/rfc3779-parent.pem diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index def00f31c2..2b5f692c72 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -443,6 +443,7 @@ impl AuthorityKeyIdentifier { } } +/// A constructor for the `X509` AS number extension. #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] pub struct SbgpAsIdentifier(SbgpAsIdentifierOrInherit); @@ -471,7 +472,7 @@ impl SbgpAsIdentifier { Self(SbgpAsIdentifierOrInherit::List(Vec::new())) } - /// Sets the `inherit`` flag to `true`. + /// Sets the `inherit` flag to `true`. pub fn add_inherit(&mut self) -> &mut SbgpAsIdentifier { if let SbgpAsIdentifierOrInherit::List(ref l) = self.0 { if !l.is_empty() { @@ -483,7 +484,7 @@ impl SbgpAsIdentifier { self } - /// Adds an AS number. + /// Adds an AS number to the AS number extension. pub fn add_asn(&mut self, asn: u32) -> &mut SbgpAsIdentifier { if let SbgpAsIdentifierOrInherit::List(ref mut asns) = self.0 { asns.push((asn, asn)) @@ -493,7 +494,7 @@ impl SbgpAsIdentifier { self } - /// Adds a range of AS numbers. + /// Adds a range of AS numbers to the AS number extension. pub fn add_asn_range(&mut self, asn_min: u32, asn_max: u32) -> &mut SbgpAsIdentifier { if let SbgpAsIdentifierOrInherit::List(ref mut asns) = self.0 { asns.push((asn_min, asn_max)) @@ -554,6 +555,7 @@ impl SbgpAsIdentifier { } } +/// The contstructor for a `X509` IP address extension. #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] pub struct SbgpIpAddressIdentifier { @@ -607,7 +609,7 @@ impl SbgpIpAddressIdentifier { self } - /// Adds an IP adress. + /// Adds an IP address to the IP address extension. pub fn add_ip_addr(&mut self, ip_addr: IpAddr) -> &mut SbgpIpAddressIdentifier { match ip_addr { IpAddr::V4(addr) => self.add_ipv4_addr_range(addr, addr), @@ -615,7 +617,7 @@ impl SbgpIpAddressIdentifier { } } - /// Adds a range of IPv4 adresses. + /// Adds a range of IPv4 adresses to the IP address extension. pub fn add_ipv4_addr_range( &mut self, ip_addr_min: Ipv4Addr, @@ -629,7 +631,7 @@ impl SbgpIpAddressIdentifier { self } - /// Adds a range of IPv6 adresses. + /// Adds a range of IPv6 adresses of the IP adress extension. pub fn add_ipv6_addr_range( &mut self, ip_addr_min: Ipv6Addr, @@ -643,7 +645,7 @@ impl SbgpIpAddressIdentifier { self } - /// Adds a ip prefix + /// Adds a IP prefix to the IP address extension. pub fn add_ip_prefix( &mut self, prefix: IpAddr, diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index d86bd7f6ce..ed597b9d7a 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -44,6 +44,8 @@ foreign_type_and_impl_send_sync! { } impl ASIdentifiers { + /// Indicates whether the AS number extension should be inherited from the + /// parent certificate. #[corresponds(X509v3_asid_inherits)] pub fn inherited(&self) -> bool { unsafe { @@ -51,8 +53,10 @@ impl ASIdentifiers { } } + /// Determines whether the contents of the AS number extension are contained + /// in the parent AS number extension. #[corresponds(X509v3_asid_subset)] - pub fn contains(&self, parent: &ASIdentifiers) -> bool { + pub fn subset_of(&self, parent: &ASIdentifiers) -> bool { unsafe { assert!(self.is_canonical()); assert!(parent.is_canonical()); @@ -60,6 +64,7 @@ impl ASIdentifiers { } } + /// Indicates whether the extension is in canonical form. #[corresponds(X509v3_asid_is_canonical)] pub fn is_canonical(&self) -> bool { unsafe { @@ -67,6 +72,9 @@ impl ASIdentifiers { } } + /// Reads the contents of the AS number extension and parses them into a + /// vector of AS number ranges. Returns `None` if the contents + /// should be inherited. pub fn ranges(&self) -> Option> { unsafe { let mut result = Vec::new(); @@ -194,6 +202,7 @@ impl IPAddressFamily { } impl X509Ref { + /// Extracts the SBGP AS number extension from the `X509` certificate. #[corresponds(X509_get_ext_d2i)] pub fn sbgp_asn(&self) -> Option { unsafe { @@ -207,6 +216,7 @@ impl X509Ref { } } + /// Extracts the SBGP IP address extension from the `X509` certificate. #[corresponds(X509_get_ext_d2i)] pub fn sbgp_ip_addresses(&self) -> Option> { unsafe { diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 036fbd8a79..6bd77ccfac 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1190,19 +1190,24 @@ fn test_sbgp_extensions_parsing() { let cert_bytes = include_bytes!("../../test/rfc3779.pem"); let cert = X509::from_pem(cert_bytes).unwrap(); + let parent_cert_bytes = include_bytes!("../../test/rfc3779-parent.pem"); + let parent_cert = X509::from_pem(parent_cert_bytes).unwrap(); + let asn = cert.sbgp_asn().unwrap(); + let pasn = parent_cert.sbgp_asn().unwrap(); assert!(!asn.inherited()); assert!(asn.is_canonical()); + assert!(asn.subset_of(&pasn)); + assert!(!pasn.subset_of(&asn)); let cert1 = X509::from_pem(cert_bytes).unwrap(); let prnt = cert1.sbgp_asn().unwrap(); - assert!(asn.contains(&prnt)); + assert!(asn.subset_of(&prnt)); let asn_ranges = asn.ranges().unwrap(); assert_eq!(asn_ranges[0], (10, 18)); assert_eq!(asn_ranges[1], (20, 20)); - let families = cert.sbgp_ip_addresses().unwrap(); for family in families { let ranges = family.range().unwrap(); diff --git a/openssl/test/rfc3779-parent.pem b/openssl/test/rfc3779-parent.pem new file mode 100644 index 0000000000..f0d621f1bd --- /dev/null +++ b/openssl/test/rfc3779-parent.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIBADANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1SRkMt +Mzc3OS1URVNUMB4XDTIzMTIxODA5MjMxMFoXDTI0MTIxNzA5MjMxMFowADCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJzJiU73oZHrU5g1mBRV+dEAIdZc +TkJMmg/pZZ9qnQoJE10Mf82KrL+Y7Rp8Na7CBIPy7MzMiErdE7thXblVxJ0gdZfe +1pY4oleJ8V1jm+fOKAQ/fj3RYj5IzgDZ88jyFmPsPYs8I79vrzqo5rp/j0ErFlmY +Y8TU0amDDwNYF+4WskGH4rzp+Owmx+mdRCY5+yjh36Vxi5QzYHRwYl0R8EoXI3cN +lHCDf02AHz6xSvsh4Wtb7eYb0Hr3ImlkNWCLfvdMncUj6CGP/e71tB4hFDP5KUIt +aR4hTf1LC1UlclTMxM84NcrE3DTOD9eeWu9FGi1jhZPdM/+k4j11FLz73VUCAwEA +AaNcMFowIQYIKwYBBQUHAQgBAf8EEjAQoA4wDDAGAgEFAgEZAgID6DA1BggrBgEF +BQcBBwEB/wQmMCQwDwQCAAEwCQMDAAEBAwIACjARBAIAAjALAwkA/QAAAAAAAAAw +DQYJKoZIhvcNAQELBQADggEBAFWdo8d/kTgrTafYsrO96w3Wg43v3FApd3qKvPUH +A5CQi3jmkpRxIt6GpR2BcB9bJyhkQLVHgOaD3amEAqJ9ydUmXeJXQ+4c/cWz/Gy0 +rY/s7Bqn+2N2ZO4Vc2uFkmZsdDL09+1rNKIWRrEx/m2UIIyj4oPxy7BroQpi4cRu +FrTyRvbdFj2fxIM9VdgBakjq9DKvwnLxkmETYq4dF8kJFMoeN4s8/V9TdcCrDylv +XcYRTK3gmRKY6f8Xri3yvrp3VPgxn81Jys0LXhRP4yxmdzX/bUaASQm8XxAuLAbs +cg88aHJSQwvvPPg6pdDX+dHqrvK+Vszpk2h+vn8jM8KGHPI= +-----END CERTIFICATE----- From b6f9916cd631814090565f4d2cf1c1e904e53a7a Mon Sep 17 00:00:00 2001 From: Petrichor Date: Wed, 20 Dec 2023 16:38:42 +0100 Subject: [PATCH 22/29] added SBGP IP ext, misssing bindings --- openssl-sys/src/handwritten/x509_sbgp.rs | 4 +++ openssl/src/x509/sbgp.rs | 11 ++++++++ openssl/src/x509/tests.rs | 5 ++++ openssl/test/rfc3779-parent.pem | 32 ++++++++++++------------ 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index 469f3ef801..9a2313b566 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -134,4 +134,8 @@ extern "C" { ) -> c_int; pub fn X509v3_addr_canonize(addr: *mut IPAddrBlocks) -> c_int; pub fn X509v3_addr_is_canonical(addr: *mut IPAddrBlocks) -> c_int; + pub fn X509v3_addr_inherits(addr: *mut IPAddrBlocks) -> c_int; + pub fn X509v3_addr_subset(a: *mut IPAddrBlocks, b: *mut IPAddrBlocks) -> c_int; + pub fn X509v3_addr_validate_path(ctx: *mut X509_STORE_CTX) -> c_int; + pub fn X509v3_addr_validate_resource_set(chain: *mut stack_st_X509, ext: *mut IPAddrBlocks, allow_inheritence: c_int) -> c_int; } diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index ed597b9d7a..bb0e14fa78 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -143,6 +143,17 @@ pub enum IpVersion { V6, } +impl Stack { + /// Determines whether the IP address extension is contained + /// in the parents IP address extension. + #[corresponds(X509v3_addr_subset)] + pub fn subset_of(&self, parent: &Stack) -> bool { + unsafe { + ffi::X509v3_addr_subset(self.as_ptr(), parent.as_ptr()) == 1 + } + } +} + impl IPAddressFamily { /// Returns the IP version of this record. #[corresponds(X509v3_addr_get_afi)] diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 6bd77ccfac..d84b4b010b 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1209,6 +1209,10 @@ fn test_sbgp_extensions_parsing() { assert_eq!(asn_ranges[1], (20, 20)); let families = cert.sbgp_ip_addresses().unwrap(); + let pfamilies = parent_cert.sbgp_ip_addresses().unwrap(); + assert!(families.subset_of(&pfamilies)); + assert!(!pfamilies.subset_of(&families)); + for family in families { let ranges = family.range().unwrap(); for (ip_min, ip_max) in ranges { @@ -1337,3 +1341,4 @@ fn test_sbgp_ip_addr_ranges_builder() { )]) ); } + diff --git a/openssl/test/rfc3779-parent.pem b/openssl/test/rfc3779-parent.pem index f0d621f1bd..7a7ad99f2d 100644 --- a/openssl/test/rfc3779-parent.pem +++ b/openssl/test/rfc3779-parent.pem @@ -1,18 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIC7zCCAdegAwIBAgIBADANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1SRkMt -Mzc3OS1URVNUMB4XDTIzMTIxODA5MjMxMFoXDTI0MTIxNzA5MjMxMFowADCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJzJiU73oZHrU5g1mBRV+dEAIdZc -TkJMmg/pZZ9qnQoJE10Mf82KrL+Y7Rp8Na7CBIPy7MzMiErdE7thXblVxJ0gdZfe -1pY4oleJ8V1jm+fOKAQ/fj3RYj5IzgDZ88jyFmPsPYs8I79vrzqo5rp/j0ErFlmY -Y8TU0amDDwNYF+4WskGH4rzp+Owmx+mdRCY5+yjh36Vxi5QzYHRwYl0R8EoXI3cN -lHCDf02AHz6xSvsh4Wtb7eYb0Hr3ImlkNWCLfvdMncUj6CGP/e71tB4hFDP5KUIt -aR4hTf1LC1UlclTMxM84NcrE3DTOD9eeWu9FGi1jhZPdM/+k4j11FLz73VUCAwEA -AaNcMFowIQYIKwYBBQUHAQgBAf8EEjAQoA4wDDAGAgEFAgEZAgID6DA1BggrBgEF -BQcBBwEB/wQmMCQwDwQCAAEwCQMDAAEBAwIACjARBAIAAjALAwkA/QAAAAAAAAAw -DQYJKoZIhvcNAQELBQADggEBAFWdo8d/kTgrTafYsrO96w3Wg43v3FApd3qKvPUH -A5CQi3jmkpRxIt6GpR2BcB9bJyhkQLVHgOaD3amEAqJ9ydUmXeJXQ+4c/cWz/Gy0 -rY/s7Bqn+2N2ZO4Vc2uFkmZsdDL09+1rNKIWRrEx/m2UIIyj4oPxy7BroQpi4cRu -FrTyRvbdFj2fxIM9VdgBakjq9DKvwnLxkmETYq4dF8kJFMoeN4s8/V9TdcCrDylv -XcYRTK3gmRKY6f8Xri3yvrp3VPgxn81Jys0LXhRP4yxmdzX/bUaASQm8XxAuLAbs -cg88aHJSQwvvPPg6pdDX+dHqrvK+Vszpk2h+vn8jM8KGHPI= +MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxSRkMz +Nzc5LVRlc3QwHhcNMjMxMjE4MDk1NDE1WhcNMjQxMjE3MDk1NDE1WjAAMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn8IyN9ywCv5cStFJzJ0WJhvu5PyC +Hs9sttZjHphALxkTzCRfZ9x0H/78JPRAoFzdX6yX5eKJgvS1HeV+fZe+84IMClXG +WHLzrrkXoeFmSqN7i8Dbfa4/cibbLiTGm21WW02aY/+W4sTTjer7OdAdyBsaH7MV +34gdcCYzB17WjsiPI/cYIAhO641KV265eAQvov7g407cAk/Q7HZnuQND8arL9FDT +CsMiD4c8t2pq5VtCMPehyHXRiepCBxyc6SuZdatyzsMte2yUZlKrPePnZZt9plUq +J96OgH5MIHzPIteMftpk9Jf0FkMbymvT0F+ayWQ6OJlvZMV0tsVfBVWbyQIDAQAB +o1UwUzAhBggrBgEFBQcBCAEB/wQSMBCgDjAMMAYCAQUCARkCAgPoMC4GCCsGAQUF +BwEHAQH/BB8wHTAPBAIAATAJAwMAAQEDAgAKMAoEAgACMAQDAgTwMA0GCSqGSIb3 +DQEBCwUAA4IBAQCcK+udw4SjXor3hbKN5j0HwP41vfifwY1njqPYEnipuMIdGDUs +uGLBZVUcjLtucPDXCXpNG+LcofPpj0pvO9FCOWRd+NUjWkixs8zWINHgY/nv9AQ+ +EcvA6VAQuxWWy6qe93oLhkDP+9W2600leQO/tlc2VxII10HwAlBiNiB4aI2v3wSr +1OUPiBe0CSAzQsISWh2S+mNkKJDaMw+Due8WmMpdd2mgQQZjU1I2z3+ICU+2+ykA +Wi4JnI7Qiki86A3ZKrEFhxHcmFLR9buvb8Y+ZS0MhISHKqyRN0KARf8yy6TgJV4u +6AvcRSx623+3tjBws01ojoNFjB6eBlxx7SdO -----END CERTIFICATE----- From 7949ec499c027705f833155570246cdfb642878f Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 25 Jan 2024 21:48:08 +0100 Subject: [PATCH 23/29] added missing bindings + fixed fmt --- openssl-sys/src/handwritten/x509_sbgp.rs | 13 ++++- openssl/src/x509/extension.rs | 71 ++++++++++++------------ openssl/src/x509/sbgp.rs | 37 ++++++------ openssl/src/x509/tests.rs | 26 +++------ 4 files changed, 75 insertions(+), 72 deletions(-) diff --git a/openssl-sys/src/handwritten/x509_sbgp.rs b/openssl-sys/src/handwritten/x509_sbgp.rs index 9a2313b566..0792042a49 100644 --- a/openssl-sys/src/handwritten/x509_sbgp.rs +++ b/openssl-sys/src/handwritten/x509_sbgp.rs @@ -109,8 +109,11 @@ extern "C" { pub fn X509v3_asid_inherits(asid: *mut ASIdentifiers) -> c_int; pub fn X509v3_asid_subset(child: *mut ASIdentifiers, parent: *mut ASIdentifiers) -> c_int; pub fn X509v3_asid_validate_path(ctx: *mut X509_STORE_CTX) -> c_int; - pub fn X509v3_asid_validate_resource_set(chain: *mut stack_st_X509, ext: *mut ASIdentifiers, allow_inheritence: c_int) -> c_int; - + pub fn X509v3_asid_validate_resource_set( + chain: *mut stack_st_X509, + ext: *mut ASIdentifiers, + allow_inheritence: c_int, + ) -> c_int; pub fn X509v3_addr_get_range( aor: *mut IPAddressOrRange, @@ -137,5 +140,9 @@ extern "C" { pub fn X509v3_addr_inherits(addr: *mut IPAddrBlocks) -> c_int; pub fn X509v3_addr_subset(a: *mut IPAddrBlocks, b: *mut IPAddrBlocks) -> c_int; pub fn X509v3_addr_validate_path(ctx: *mut X509_STORE_CTX) -> c_int; - pub fn X509v3_addr_validate_resource_set(chain: *mut stack_st_X509, ext: *mut IPAddrBlocks, allow_inheritence: c_int) -> c_int; + pub fn X509v3_addr_validate_resource_set( + chain: *mut stack_st_X509, + ext: *mut IPAddrBlocks, + allow_inheritence: c_int, + ) -> c_int; } diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 2b5f692c72..d8e40298db 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -35,8 +35,6 @@ use crate::cvt; #[cfg(ossl110)] use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; #[cfg(ossl110)] -use openssl_macros::corresponds; -#[cfg(ossl110)] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// An extension which indicates whether a certificate is a CA certificate. @@ -452,7 +450,7 @@ pub struct SbgpAsIdentifier(SbgpAsIdentifierOrInherit); #[cfg(not(OPENSSL_NO_RFC3779))] enum SbgpAsIdentifierOrInherit { Inherit, - List(Vec<(u32, u32)>) + List(Vec<(u32, u32)>), } #[cfg(ossl110)] @@ -463,7 +461,6 @@ impl Default for SbgpAsIdentifier { } } - #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] impl SbgpAsIdentifier { @@ -514,7 +511,7 @@ impl SbgpAsIdentifier { asid.as_ptr(), ffi::V3_ASID_ASNUM, ))?; - }, + } SbgpAsIdentifierOrInherit::List(ref asns) => { assert!(!asns.is_empty(), "cannot create empty extension"); @@ -526,7 +523,6 @@ impl SbgpAsIdentifier { 0, asn_min.as_ptr(), std::ptr::null_mut(), - ))?; } else { let asn_max = BigNum::from_u32(*max)?.to_asn1_integer()?; @@ -540,7 +536,7 @@ impl SbgpAsIdentifier { }; // On success ownership of min and max was moved, so forget // On failure the fn early returned, thus the Rust types will free min and max - std::mem::forget(asn_min); + std::mem::forget(asn_min); } // canonize must only be performed on this branch, since an inherit @@ -549,7 +545,7 @@ impl SbgpAsIdentifier { cvt(ffi::X509v3_asid_canonize(asid.as_ptr()))?; } } - } + } X509Extension::new_internal(Nid::SBGP_AUTONOMOUSSYSNUM, true, asid.as_ptr().cast()) } } @@ -559,18 +555,17 @@ impl SbgpAsIdentifier { #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] pub struct SbgpIpAddressIdentifier { - v4: SbgpIpAddressIdentifierOrInherit, - v6: SbgpIpAddressIdentifierOrInherit, + v4: SbgpIpAddressIdentifierOrInherit, + v6: SbgpIpAddressIdentifierOrInherit, } #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] enum SbgpIpAddressIdentifierOrInherit { Inherit, - List(Vec<(Addr, Addr)>) + List(Vec<(Addr, Addr)>), } - #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] impl Default for SbgpIpAddressIdentifier { @@ -601,9 +596,13 @@ impl SbgpIpAddressIdentifier { /// Sets the `inherit` flag in the list corresponding to the ip version. pub fn add_inherit(&mut self, afi: IpVersion) -> &mut SbgpIpAddressIdentifier { match afi { - IpVersion::V4 if self.len_of(afi) == 0 => self.v4 = SbgpIpAddressIdentifierOrInherit::Inherit, + IpVersion::V4 if self.len_of(afi) == 0 => { + self.v4 = SbgpIpAddressIdentifierOrInherit::Inherit + } IpVersion::V4 => panic!("cannot set ipv4 to inherit, list allready contains values"), - IpVersion::V6 if self.len_of(afi) == 0 => self.v6 = SbgpIpAddressIdentifierOrInherit::Inherit, + IpVersion::V6 if self.len_of(afi) == 0 => { + self.v6 = SbgpIpAddressIdentifierOrInherit::Inherit + } IpVersion::V6 => panic!("cannot set ipv6 to inherit, list allready contains values"), } self @@ -613,7 +612,7 @@ impl SbgpIpAddressIdentifier { pub fn add_ip_addr(&mut self, ip_addr: IpAddr) -> &mut SbgpIpAddressIdentifier { match ip_addr { IpAddr::V4(addr) => self.add_ipv4_addr_range(addr, addr), - IpAddr::V6(addr)=> self.add_ipv6_addr_range(addr, addr), + IpAddr::V6(addr) => self.add_ipv6_addr_range(addr, addr), } } @@ -672,45 +671,41 @@ impl SbgpIpAddressIdentifier { pub fn build(&self) -> Result { unsafe { let mut stack = Stack::::new()?; - + match self.v4 { SbgpIpAddressIdentifierOrInherit::Inherit => { cvt(ffi::X509v3_addr_add_inherit( - stack.as_ptr(), - IANA_AFI_IPV4 as u32, - std::ptr::null(), + stack.as_ptr(), + IANA_AFI_IPV4 as u32, + std::ptr::null(), ))?; - }, + } SbgpIpAddressIdentifierOrInherit::List(ref ips) => { for (min, max) in ips { stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV4 as u32)?; } - }, + } } match self.v6 { SbgpIpAddressIdentifierOrInherit::Inherit => { cvt(ffi::X509v3_addr_add_inherit( - stack.as_ptr(), - IANA_AFI_IPV6 as u32, - std::ptr::null(), + stack.as_ptr(), + IANA_AFI_IPV6 as u32, + std::ptr::null(), ))?; - }, + } SbgpIpAddressIdentifierOrInherit::List(ref ips) => { for (min, max) in ips { stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV6 as u32)?; } - }, + } } - + if ffi::X509v3_addr_is_canonical(stack.as_ptr()) != 1 { cvt(ffi::X509v3_addr_canonize(stack.as_ptr()))?; } - X509Extension::new_internal( - Nid::SBGP_IPADDRBLOCK, - true, - stack.as_ptr().cast(), - ) + X509Extension::new_internal(Nid::SBGP_IPADDRBLOCK, true, stack.as_ptr().cast()) } } } @@ -718,10 +713,14 @@ impl SbgpIpAddressIdentifier { #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] impl Stack { - /// Adds an address range to the stack - /// This helper exists as a utility function, because RFC 3779 types are hard to deal with. - #[corresponds(X509v3_addr_add_range)] - pub fn sbgp_add_addr_range(&mut self, mut min: Addr, mut max: Addr, afi: u32) -> Result<(), ErrorStack> { + // No pub, since messing with existing stacks outside build() + // seems like an unnessecary risk. + fn sbgp_add_addr_range( + &mut self, + mut min: Addr, + mut max: Addr, + afi: u32, + ) -> Result<(), ErrorStack> { unsafe { let min = &mut min as *mut _ as *mut u8; let max = &mut max as *mut _ as *mut u8; diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index bb0e14fa78..2dc0b4ea47 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -6,8 +6,8 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use ffi::{ ASIdOrRange_id, ASIdOrRange_range, ASIdentifierChoice_asIdsOrRanges, - IPAddressChoice_addressesOrRanges, X509v3_addr_get_afi, - ASN1_INTEGER, IANA_AFI_IPV4, IANA_AFI_IPV6, + IPAddressChoice_addressesOrRanges, X509v3_addr_get_afi, ASN1_INTEGER, IANA_AFI_IPV4, + IANA_AFI_IPV6, }; use foreign_types::ForeignTypeRef; use openssl_macros::corresponds; @@ -48,9 +48,7 @@ impl ASIdentifiers { /// parent certificate. #[corresponds(X509v3_asid_inherits)] pub fn inherited(&self) -> bool { - unsafe { - ffi::X509v3_asid_inherits(self.as_ptr()) == 1 - } + unsafe { ffi::X509v3_asid_inherits(self.as_ptr()) == 1 } } /// Determines whether the contents of the AS number extension are contained @@ -67,12 +65,10 @@ impl ASIdentifiers { /// Indicates whether the extension is in canonical form. #[corresponds(X509v3_asid_is_canonical)] pub fn is_canonical(&self) -> bool { - unsafe { - ffi::X509v3_asid_is_canonical(self.as_ptr()) == 1 - } + unsafe { ffi::X509v3_asid_is_canonical(self.as_ptr()) == 1 } } - /// Reads the contents of the AS number extension and parses them into a + /// Reads the contents of the AS number extension and parses them into a /// vector of AS number ranges. Returns `None` if the contents /// should be inherited. pub fn ranges(&self) -> Option> { @@ -144,13 +140,24 @@ pub enum IpVersion { } impl Stack { + /// Indicates whether the AS number extension should be inherited from the + /// parent certificate. + pub fn inherited(&self) -> bool { + unsafe { ffi::X509v3_addr_inherits(self.as_ptr()) == 1 } + } + /// Determines whether the IP address extension is contained /// in the parents IP address extension. #[corresponds(X509v3_addr_subset)] pub fn subset_of(&self, parent: &Stack) -> bool { - unsafe { - ffi::X509v3_addr_subset(self.as_ptr(), parent.as_ptr()) == 1 - } + unsafe { ffi::X509v3_addr_subset(self.as_ptr(), parent.as_ptr()) == 1 } + } + + /// Returns whether the IP address extension is in canonical + /// form. + #[corresponds(X509v3_addr_is_canonical)] + pub fn is_canonical(&self) -> bool { + unsafe { ffi::X509v3_addr_is_canonical(self.as_ptr()) == 1 } } } @@ -159,8 +166,7 @@ impl IPAddressFamily { #[corresponds(X509v3_addr_get_afi)] pub fn fam(&self) -> Option { unsafe { - let ptr = self.0; - match X509v3_addr_get_afi(ptr) as libc::c_int { + match X509v3_addr_get_afi(self.as_ptr()) as libc::c_int { IANA_AFI_IPV4 => Some(IpVersion::V4), IANA_AFI_IPV6 => Some(IpVersion::V6), _ => None, @@ -173,8 +179,7 @@ impl IPAddressFamily { pub fn range(&self) -> Option> { unsafe { let fam = self.fam()?; - let ptr = self.0; - let choice = (*ptr).ipAddressChoice; + let choice = (*self.as_ptr()).ipAddressChoice; if (*choice).type_ != IPAddressChoice_addressesOrRanges { return None; } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index d84b4b010b..e8a20d5e3a 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1200,16 +1200,14 @@ fn test_sbgp_extensions_parsing() { assert!(asn.subset_of(&pasn)); assert!(!pasn.subset_of(&asn)); - let cert1 = X509::from_pem(cert_bytes).unwrap(); - let prnt = cert1.sbgp_asn().unwrap(); - assert!(asn.subset_of(&prnt)); - let asn_ranges = asn.ranges().unwrap(); assert_eq!(asn_ranges[0], (10, 18)); assert_eq!(asn_ranges[1], (20, 20)); let families = cert.sbgp_ip_addresses().unwrap(); let pfamilies = parent_cert.sbgp_ip_addresses().unwrap(); + assert!(!families.inherited()); + assert!(families.is_canonical()); assert!(families.subset_of(&pfamilies)); assert!(!pfamilies.subset_of(&families)); @@ -1266,13 +1264,8 @@ fn test_sbgp_as_identifier_builder_inherit() { assert!(asn.inherited()); assert_eq!(asn.ranges(), None); - // - - let mut builder = X509Builder::new().unwrap(); - let ext = SbgpAsIdentifier::new() - .add_inherit() - .build() - .unwrap(); + let mut builder = X509Builder::new().unwrap(); + let ext = SbgpAsIdentifier::new().add_inherit().build().unwrap(); builder.append_extension(ext).unwrap(); let cert = builder.build(); @@ -1305,11 +1298,11 @@ fn test_sbgp_ip_addr_ranges_builder() { builder.append_extension(ip_addr_ext).unwrap(); let cert = builder.build(); - let ranges = cert - .sbgp_ip_addresses() - .unwrap() - .into_iter() - .collect::>(); + let ranges = cert.sbgp_ip_addresses().unwrap(); + assert!(!ranges.inherited()); + assert!(ranges.is_canonical()); + + let ranges = ranges.into_iter().collect::>(); assert_eq!(ranges.len(), 2); @@ -1341,4 +1334,3 @@ fn test_sbgp_ip_addr_ranges_builder() { )]) ); } - From ba3bf9fc0e549991013ae5f53122a0f618a34976 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 25 Jan 2024 21:52:07 +0100 Subject: [PATCH 24/29] added OPENSSL_NO_RFC3779 to tests --- openssl/src/x509/tests.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index e8a20d5e3a..34d5c70fa8 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1186,6 +1186,7 @@ fn test_dist_point_null() { #[test] #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] fn test_sbgp_extensions_parsing() { let cert_bytes = include_bytes!("../../test/rfc3779.pem"); let cert = X509::from_pem(cert_bytes).unwrap(); @@ -1231,6 +1232,7 @@ fn test_sbgp_extensions_parsing() { #[test] #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] fn test_sbgp_as_identifier_builder() { let mut builder = X509Builder::new().unwrap(); let as_id_ext = SbgpAsIdentifier::new() @@ -1253,6 +1255,7 @@ fn test_sbgp_as_identifier_builder() { #[test] #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] fn test_sbgp_as_identifier_builder_inherit() { let mut builder = X509Builder::new().unwrap(); let ext = SbgpAsIdentifier::new().add_inherit().build().unwrap(); @@ -1277,6 +1280,7 @@ fn test_sbgp_as_identifier_builder_inherit() { #[test] #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] fn test_sbgp_ip_addr_ranges_builder() { use crate::x509::sbgp::IpVersion; From fa9e0b3302ac8f61c5016e71e529cf825fa94770 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 25 Jan 2024 22:15:47 +0100 Subject: [PATCH 25/29] tests missing cfg flags + simplified use stmts --- openssl/src/x509/tests.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 34d5c70fa8..8e8f6563be 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1,8 +1,4 @@ use std::cmp::Ordering; -#[cfg(ossl110)] -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -#[cfg(ossl110)] -use std::str::FromStr; use crate::asn1::{Asn1Object, Asn1OctetString, Asn1Time}; use crate::bn::{BigNum, MsbOption}; @@ -18,6 +14,7 @@ use crate::x509::extension::{ SubjectKeyIdentifier, }; #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] use crate::x509::extension::{SbgpAsIdentifier, SbgpIpAddressIdentifier}; #[cfg(not(boringssl))] use crate::x509::store::X509Lookup; @@ -1188,6 +1185,9 @@ fn test_dist_point_null() { #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] fn test_sbgp_extensions_parsing() { + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + use std::str::FromStr; + let cert_bytes = include_bytes!("../../test/rfc3779.pem"); let cert = X509::from_pem(cert_bytes).unwrap(); @@ -1283,6 +1283,8 @@ fn test_sbgp_as_identifier_builder_inherit() { #[cfg(not(OPENSSL_NO_RFC3779))] fn test_sbgp_ip_addr_ranges_builder() { use crate::x509::sbgp::IpVersion; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + use std::str::FromStr; let mut builder = X509Builder::new().unwrap(); let ip_addr_ext = SbgpIpAddressIdentifier::new() From 8f32bb9851b1ec0432e4fbe806bea61b74db91e0 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 25 Jan 2024 22:38:28 +0100 Subject: [PATCH 26/29] fixed missing cfg flags --- openssl/src/x509/extension.rs | 64 ++++++++++++++++------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index d8e40298db..56268d4007 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -25,16 +25,8 @@ use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; use foreign_types::ForeignType; -use super::sbgp::ASIdentifiers; -#[cfg(ossl110)] -use super::sbgp::{IPAddressFamily, IpVersion}; -#[cfg(ossl110)] -use crate::bn::BigNum; -#[cfg(ossl110)] -use crate::cvt; -#[cfg(ossl110)] -use ffi::{IANA_AFI_IPV4, IANA_AFI_IPV6}; #[cfg(ossl110)] +#[cfg(not(OPENSSL_NO_RFC3779))] use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// An extension which indicates whether a certificate is a CA certificate. @@ -504,10 +496,10 @@ impl SbgpAsIdentifier { /// Return a `SbgpAsIdentifier` extension as an `X509Extension`. pub fn build(&self) -> Result { unsafe { - let asid = ASIdentifiers::from_ptr(ffi::ASIdentifiers_new()); + let asid = super::sbgp::ASIdentifiers::from_ptr(ffi::ASIdentifiers_new()); match self.0 { SbgpAsIdentifierOrInherit::Inherit => { - cvt(ffi::X509v3_asid_add_inherit( + crate::cvt(ffi::X509v3_asid_add_inherit( asid.as_ptr(), ffi::V3_ASID_ASNUM, ))?; @@ -516,17 +508,17 @@ impl SbgpAsIdentifier { assert!(!asns.is_empty(), "cannot create empty extension"); for (min, max) in asns { - let asn_min = BigNum::from_u32(*min)?.to_asn1_integer()?; + let asn_min = crate::bn::BigNum::from_u32(*min)?.to_asn1_integer()?; if min == max { - cvt(ffi::X509v3_asid_add_id_or_range( + crate::cvt(ffi::X509v3_asid_add_id_or_range( asid.as_ptr(), 0, asn_min.as_ptr(), std::ptr::null_mut(), ))?; } else { - let asn_max = BigNum::from_u32(*max)?.to_asn1_integer()?; - cvt(ffi::X509v3_asid_add_id_or_range( + let asn_max = crate::bn::BigNum::from_u32(*max)?.to_asn1_integer()?; + crate::cvt(ffi::X509v3_asid_add_id_or_range( asid.as_ptr(), 0, asn_min.as_ptr(), @@ -542,7 +534,7 @@ impl SbgpAsIdentifier { // canonize must only be performed on this branch, since an inherit // ext is automatically canoical if ffi::X509v3_asid_is_canonical(asid.as_ptr()) != 1 { - cvt(ffi::X509v3_asid_canonize(asid.as_ptr()))?; + crate::cvt(ffi::X509v3_asid_canonize(asid.as_ptr()))?; } } } @@ -585,25 +577,29 @@ impl SbgpIpAddressIdentifier { } } - fn len_of(&self, afi: IpVersion) -> usize { + fn len_of(&self, afi: super::sbgp::IpVersion) -> usize { match (afi, &self.v4, &self.v6) { - (IpVersion::V4, SbgpIpAddressIdentifierOrInherit::List(l), _) => l.len(), - (IpVersion::V6, _, SbgpIpAddressIdentifierOrInherit::List(l)) => l.len(), + (super::sbgp::IpVersion::V4, SbgpIpAddressIdentifierOrInherit::List(l), _) => l.len(), + (super::sbgp::IpVersion::V6, _, SbgpIpAddressIdentifierOrInherit::List(l)) => l.len(), _ => 0, } } /// Sets the `inherit` flag in the list corresponding to the ip version. - pub fn add_inherit(&mut self, afi: IpVersion) -> &mut SbgpIpAddressIdentifier { + pub fn add_inherit(&mut self, afi: super::sbgp::IpVersion) -> &mut SbgpIpAddressIdentifier { match afi { - IpVersion::V4 if self.len_of(afi) == 0 => { + super::sbgp::IpVersion::V4 if self.len_of(afi) == 0 => { self.v4 = SbgpIpAddressIdentifierOrInherit::Inherit } - IpVersion::V4 => panic!("cannot set ipv4 to inherit, list allready contains values"), - IpVersion::V6 if self.len_of(afi) == 0 => { + super::sbgp::IpVersion::V4 => { + panic!("cannot set ipv4 to inherit, list allready contains values") + } + super::sbgp::IpVersion::V6 if self.len_of(afi) == 0 => { self.v6 = SbgpIpAddressIdentifierOrInherit::Inherit } - IpVersion::V6 => panic!("cannot set ipv6 to inherit, list allready contains values"), + super::sbgp::IpVersion::V6 => { + panic!("cannot set ipv6 to inherit, list allready contains values") + } } self } @@ -670,39 +666,39 @@ impl SbgpIpAddressIdentifier { /// Return a `SbgpIpAddressIdentifier` extension as an `X509Extension`. pub fn build(&self) -> Result { unsafe { - let mut stack = Stack::::new()?; + let mut stack = Stack::::new()?; match self.v4 { SbgpIpAddressIdentifierOrInherit::Inherit => { - cvt(ffi::X509v3_addr_add_inherit( + crate::cvt(ffi::X509v3_addr_add_inherit( stack.as_ptr(), - IANA_AFI_IPV4 as u32, + ffi::IANA_AFI_IPV4 as u32, std::ptr::null(), ))?; } SbgpIpAddressIdentifierOrInherit::List(ref ips) => { for (min, max) in ips { - stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV4 as u32)?; + stack.sbgp_add_addr_range(*min, *max, ffi::IANA_AFI_IPV4 as u32)?; } } } match self.v6 { SbgpIpAddressIdentifierOrInherit::Inherit => { - cvt(ffi::X509v3_addr_add_inherit( + crate::cvt(ffi::X509v3_addr_add_inherit( stack.as_ptr(), - IANA_AFI_IPV6 as u32, + ffi::IANA_AFI_IPV6 as u32, std::ptr::null(), ))?; } SbgpIpAddressIdentifierOrInherit::List(ref ips) => { for (min, max) in ips { - stack.sbgp_add_addr_range(*min, *max, IANA_AFI_IPV6 as u32)?; + stack.sbgp_add_addr_range(*min, *max, ffi::IANA_AFI_IPV6 as u32)?; } } } if ffi::X509v3_addr_is_canonical(stack.as_ptr()) != 1 { - cvt(ffi::X509v3_addr_canonize(stack.as_ptr()))?; + crate::cvt(ffi::X509v3_addr_canonize(stack.as_ptr()))?; } X509Extension::new_internal(Nid::SBGP_IPADDRBLOCK, true, stack.as_ptr().cast()) @@ -712,7 +708,7 @@ impl SbgpIpAddressIdentifier { #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] -impl Stack { +impl Stack { // No pub, since messing with existing stacks outside build() // seems like an unnessecary risk. fn sbgp_add_addr_range( @@ -725,7 +721,7 @@ impl Stack { let min = &mut min as *mut _ as *mut u8; let max = &mut max as *mut _ as *mut u8; - cvt(ffi::X509v3_addr_add_range( + crate::cvt(ffi::X509v3_addr_add_range( self.as_ptr().cast(), afi, std::ptr::null_mut(), From 6cc634cfcf61dd058bdcd596bf2ef5c12d33cb00 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Wed, 31 Jan 2024 19:27:35 +0100 Subject: [PATCH 27/29] fixed X509V3_asid_subset, no longer available in 1.1.0 --- openssl/src/x509/sbgp.rs | 4 ++++ openssl/src/x509/tests.rs | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index 2dc0b4ea47..41a29cd528 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -53,6 +53,10 @@ impl ASIdentifiers { /// Determines whether the contents of the AS number extension are contained /// in the parent AS number extension. + /// + /// This function is only available as of version 1.1.1, since it + /// implementation in version 1.1.0 is faulty. + #[cfg(ossl111)] #[corresponds(X509v3_asid_subset)] pub fn subset_of(&self, parent: &ASIdentifiers) -> bool { unsafe { diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 3b644cc36c..16da640950 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1195,11 +1195,15 @@ fn test_sbgp_extensions_parsing() { let parent_cert = X509::from_pem(parent_cert_bytes).unwrap(); let asn = cert.sbgp_asn().unwrap(); - let pasn = parent_cert.sbgp_asn().unwrap(); assert!(!asn.inherited()); assert!(asn.is_canonical()); - assert!(asn.subset_of(&pasn)); - assert!(!pasn.subset_of(&asn)); + + #[cfg(ossl111)] + { + let pasn = parent_cert.sbgp_asn().unwrap(); + assert!(asn.subset_of(&pasn)); + assert!(!pasn.subset_of(&asn)); + } let asn_ranges = asn.ranges().unwrap(); assert_eq!(asn_ranges[0], (10, 18)); From 7bce3d5e35f7c81ab916fde6f4e4fa7ddd408713 Mon Sep 17 00:00:00 2001 From: Petrichor Date: Thu, 1 Feb 2024 11:56:51 +0100 Subject: [PATCH 28/29] fixed rustfmt --- openssl/src/x509/sbgp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/x509/sbgp.rs b/openssl/src/x509/sbgp.rs index 41a29cd528..64123602eb 100644 --- a/openssl/src/x509/sbgp.rs +++ b/openssl/src/x509/sbgp.rs @@ -53,7 +53,7 @@ impl ASIdentifiers { /// Determines whether the contents of the AS number extension are contained /// in the parent AS number extension. - /// + /// /// This function is only available as of version 1.1.1, since it /// implementation in version 1.1.0 is faulty. #[cfg(ossl111)] From 6dcf78125cb70a9234188ab10b1727494ed1189b Mon Sep 17 00:00:00 2001 From: Simon Buttgereit Date: Wed, 14 Feb 2024 08:14:26 +0100 Subject: [PATCH 29/29] fix typos & small clippy fix --- openssl/src/x509/extension.rs | 33 ++++++++++++++++----------------- openssl/src/x509/mod.rs | 5 +---- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 56268d4007..cac055d781 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -465,7 +465,7 @@ impl SbgpAsIdentifier { pub fn add_inherit(&mut self) -> &mut SbgpAsIdentifier { if let SbgpAsIdentifierOrInherit::List(ref l) = self.0 { if !l.is_empty() { - panic!("cannot set extension to inherit, list allready contains elements"); + panic!("Cannot set extension to 'inherit': List already contains elements"); } } @@ -478,7 +478,7 @@ impl SbgpAsIdentifier { if let SbgpAsIdentifierOrInherit::List(ref mut asns) = self.0 { asns.push((asn, asn)) } else { - panic!("cannot add AS number to extension, extension is set to inherit"); + panic!("Cannot add AS number to extension: Extension is set to 'inherit'"); } self } @@ -488,7 +488,7 @@ impl SbgpAsIdentifier { if let SbgpAsIdentifierOrInherit::List(ref mut asns) = self.0 { asns.push((asn_min, asn_max)) } else { - panic!("cannot add AS range to extension, extension is set to inherit"); + panic!("Cannot add AS range to extension: Extension is set to 'inherit'"); } self } @@ -505,7 +505,7 @@ impl SbgpAsIdentifier { ))?; } SbgpAsIdentifierOrInherit::List(ref asns) => { - assert!(!asns.is_empty(), "cannot create empty extension"); + assert!(!asns.is_empty(), "Cannot create empty extension"); for (min, max) in asns { let asn_min = crate::bn::BigNum::from_u32(*min)?.to_asn1_integer()?; @@ -531,8 +531,8 @@ impl SbgpAsIdentifier { std::mem::forget(asn_min); } - // canonize must only be performed on this branch, since an inherit - // ext is automatically canoical + // Canonize must only be performed on this branch, since an inherit ext is + // automatically canonical if ffi::X509v3_asid_is_canonical(asid.as_ptr()) != 1 { crate::cvt(ffi::X509v3_asid_canonize(asid.as_ptr()))?; } @@ -591,14 +591,14 @@ impl SbgpIpAddressIdentifier { super::sbgp::IpVersion::V4 if self.len_of(afi) == 0 => { self.v4 = SbgpIpAddressIdentifierOrInherit::Inherit } - super::sbgp::IpVersion::V4 => { - panic!("cannot set ipv4 to inherit, list allready contains values") - } super::sbgp::IpVersion::V6 if self.len_of(afi) == 0 => { self.v6 = SbgpIpAddressIdentifierOrInherit::Inherit } - super::sbgp::IpVersion::V6 => { - panic!("cannot set ipv6 to inherit, list allready contains values") + _ => { + panic!( + "Cannot set IP{:?} to 'inherit': List already contains values", + afi + ); } } self @@ -612,7 +612,7 @@ impl SbgpIpAddressIdentifier { } } - /// Adds a range of IPv4 adresses to the IP address extension. + /// Adds a range of IPv4 addresses to the IP address extension. pub fn add_ipv4_addr_range( &mut self, ip_addr_min: Ipv4Addr, @@ -621,12 +621,12 @@ impl SbgpIpAddressIdentifier { if let SbgpIpAddressIdentifierOrInherit::List(ref mut ips) = self.v4 { ips.push((ip_addr_min, ip_addr_max)); } else { - panic!("cannot add ipv4 address to extension, ipv4 is set to inherit"); + panic!("Cannot add IPv4 address to extension: IPv4 is set to 'inherit'"); } self } - /// Adds a range of IPv6 adresses of the IP adress extension. + /// Adds a range of IPv6 addresses of the IP address extension. pub fn add_ipv6_addr_range( &mut self, ip_addr_min: Ipv6Addr, @@ -635,7 +635,7 @@ impl SbgpIpAddressIdentifier { if let SbgpIpAddressIdentifierOrInherit::List(ref mut ips) = self.v6 { ips.push((ip_addr_min, ip_addr_max)); } else { - panic!("cannot add ipv6 address to extension, ipv6 is set to inherit"); + panic!("Cannot add IPv6 address to extension: IPv6 is set to 'inherit'"); } self } @@ -709,8 +709,7 @@ impl SbgpIpAddressIdentifier { #[cfg(ossl110)] #[cfg(not(OPENSSL_NO_RFC3779))] impl Stack { - // No pub, since messing with existing stacks outside build() - // seems like an unnessecary risk. + // Not public, since messing with existing stacks outside build() seems like an unnecessary risk. fn sbgp_add_addr_range( &mut self, mut min: Addr, diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 453fec5544..cf6d7c6638 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -2096,10 +2096,7 @@ impl GeneralName { } } - pub(crate) fn new_other_name( - oid: Asn1Object, - value: &Vec, - ) -> Result { + pub(crate) fn new_other_name(oid: Asn1Object, value: &[u8]) -> Result { unsafe { ffi::init();