1
+ use std:: mem:: MaybeUninit ;
2
+
1
3
use ffi:: {
2
4
ASIdOrRange_id , ASIdOrRange_range , ASIdentifierChoice_asIdsOrRanges ,
3
- ASIdentifierChoice_inherit , ASN1_INTEGER ,
5
+ ASIdentifierChoice_inherit , IPAddressChoice_addressesOrRanges , X509v3_addr_get_afi ,
6
+ X509v3_addr_get_range , ASN1_INTEGER , IANA_AFI_IPV4 , IANA_AFI_IPV6 ,
4
7
} ;
5
8
use foreign_types:: { ForeignType , ForeignTypeRef } ;
6
9
7
10
use crate :: {
8
11
asn1:: Asn1IntegerRef ,
9
- stack:: { StackRef , Stackable } ,
12
+ stack:: { Stack , StackRef , Stackable } ,
10
13
util:: { ForeignTypeExt , ForeignTypeRefExt } ,
11
14
} ;
12
15
@@ -47,25 +50,27 @@ impl ASIdentifiers {
47
50
48
51
pub fn ranges ( & self ) -> Option < Vec < ( u32 , u32 ) > > {
49
52
let mut r = Vec :: new ( ) ;
53
+ let asptr = self . 0 ;
50
54
unsafe {
51
- let asptr = self . 0 ;
52
55
let asnum = ( * asptr) . asnum ;
53
- if ( * asnum) . type_ = = ASIdentifierChoice_asIdsOrRanges {
54
- if let Some ( s ) = StackRef :: < ASIdOrRange > :: from_const_ptr_opt ( ( * asnum ) . asIdsOrRanges )
55
- {
56
- for a_ptr in s {
57
- let a = a_ptr . as_ptr ( ) ;
58
- if ( * a ) . type_ == ASIdOrRange_id {
59
- let asn = Self :: parse_asn1_integer ( ( * a) . u . id ) ? ;
60
- r . push ( ( asn , asn ) ) ;
61
- } else if ( * a ) . type_ == ASIdOrRange_range {
62
- let range = ( * a) . u . range ;
63
- let asn1 = Self :: parse_asn1_integer ( ( * range ) . min ) ? ;
64
- let asn2 = Self :: parse_asn1_integer ( ( * range) . max ) ?;
65
- r . push ( ( asn1 , asn2 ) ) ;
66
- }
56
+ if ( * asnum) . type_ ! = ASIdentifierChoice_asIdsOrRanges {
57
+ return None ;
58
+ }
59
+ if let Some ( s ) = StackRef :: < ASIdOrRange > :: from_const_ptr_opt ( ( * asnum ) . asIdsOrRanges ) {
60
+ for a_ptr in s {
61
+ let a = a_ptr . as_ptr ( ) ;
62
+ if ( * a) . type_ == ASIdOrRange_id {
63
+ let asn = Self :: parse_asn1_integer ( ( * a ) . u . id ) ? ;
64
+ r . push ( ( asn , asn ) ) ;
65
+ } else if ( * a) . type_ == ASIdOrRange_range {
66
+ let range = ( * a ) . u . range ;
67
+ let asn1 = Self :: parse_asn1_integer ( ( * range) . min ) ?;
68
+ let asn2 = Self :: parse_asn1_integer ( ( * range ) . max ) ? ;
69
+ r . push ( ( asn1 , asn2 ) ) ;
67
70
}
68
71
}
72
+ } else {
73
+ return None ;
69
74
}
70
75
}
71
76
Some ( r)
@@ -80,11 +85,105 @@ impl ASIdentifiers {
80
85
}
81
86
}
82
87
83
- pub trait ExtractASN {
88
+ foreign_type_and_impl_send_sync ! {
89
+ type CType = ffi:: _IPAddressOrRange;
90
+ fn drop = ffi:: IPAddressOrRange_free ;
91
+
92
+ /// The AS number extension of an `X509` certificate.
93
+ pub struct IPAddressOrRange ;
94
+ /// Reference to `IPAddressOrRange`.
95
+ pub struct IPAddressOrRangeRef ;
96
+ }
97
+
98
+ impl Stackable for IPAddressOrRange {
99
+ type StackType = ffi:: stack_st_IPAddressOrRange ;
100
+ }
101
+
102
+ foreign_type_and_impl_send_sync ! {
103
+ type CType = ffi:: _IPAddressFamily;
104
+ fn drop = ffi:: IPAddressFamily_free ;
105
+
106
+ /// The AS number extension of an `X509` certificate.
107
+ pub struct IPAddressFamily ;
108
+ /// Reference to `IPAddressFamily`.
109
+ pub struct IPAddressFamilyRef ;
110
+ }
111
+
112
+ impl Stackable for IPAddressFamily {
113
+ type StackType = ffi:: stack_st_IPAddressFamily ;
114
+ }
115
+
116
+ #[ derive( PartialEq , Eq , Debug ) ]
117
+ pub enum IPVersion {
118
+ V4 ,
119
+ V6 ,
120
+ }
121
+
122
+ impl IPAddressFamily {
123
+ pub fn fam ( & self ) -> Option < IPVersion > {
124
+ let ptr = self . 0 ;
125
+ match X509v3_addr_get_afi ( ptr) {
126
+ IANA_AFI_IPV4 => Some ( IPVersion :: V4 ) ,
127
+ IANA_AFI_IPV6 => Some ( IPVersion :: V6 ) ,
128
+ _ => None ,
129
+ }
130
+ }
131
+
132
+ pub fn range ( & self ) -> Option < Vec < ( std:: net:: IpAddr , std:: net:: IpAddr ) > > {
133
+ let ptr = self . 0 ;
134
+ let mut r = Vec :: new ( ) ;
135
+ unsafe {
136
+ let choice = ( * ptr) . ipAddressChoice ;
137
+ if ( * choice) . type_ != IPAddressChoice_addressesOrRanges {
138
+ return None ;
139
+ }
140
+ let stack =
141
+ StackRef :: < IPAddressOrRange > :: from_const_ptr_opt ( ( * choice) . addressesOrRanges ) ?;
142
+ for e in stack {
143
+ let mut min = MaybeUninit :: < [ u8 ; 16 ] > :: uninit ( ) ;
144
+ let mut max = MaybeUninit :: < [ u8 ; 16 ] > :: uninit ( ) ;
145
+ let size = X509v3_addr_get_range (
146
+ e. as_ptr ( ) ,
147
+ X509v3_addr_get_afi ( ptr) ,
148
+ min. as_mut_ptr ( ) as * mut u8 ,
149
+ max. as_mut_ptr ( ) as * mut u8 ,
150
+ 16 ,
151
+ ) ;
152
+ r. push ( (
153
+ Self :: data_to_ip_addr ( min. assume_init ( ) , size) ?,
154
+ Self :: data_to_ip_addr ( max. assume_init ( ) , size) ?,
155
+ ) )
156
+ }
157
+ }
158
+ Some ( r)
159
+ }
160
+
161
+ fn data_to_ip_addr ( data : [ u8 ; 16 ] , len : isize ) -> Option < std:: net:: IpAddr > {
162
+ match len {
163
+ 4 => Some ( std:: net:: IpAddr :: V4 ( std:: net:: Ipv4Addr :: new (
164
+ data[ 0 ] , data[ 1 ] , data[ 2 ] , data[ 3 ] ,
165
+ ) ) ) ,
166
+ 16 => Some ( std:: net:: IpAddr :: V6 ( std:: net:: Ipv6Addr :: new (
167
+ ( data[ 0 ] as u16 ) << 8 | data[ 1 ] as u16 ,
168
+ ( data[ 2 ] as u16 ) << 8 | data[ 3 ] as u16 ,
169
+ ( data[ 4 ] as u16 ) << 8 | data[ 5 ] as u16 ,
170
+ ( data[ 6 ] as u16 ) << 8 | data[ 7 ] as u16 ,
171
+ ( data[ 8 ] as u16 ) << 8 | data[ 9 ] as u16 ,
172
+ ( data[ 10 ] as u16 ) << 8 | data[ 11 ] as u16 ,
173
+ ( data[ 12 ] as u16 ) << 8 | data[ 13 ] as u16 ,
174
+ ( data[ 14 ] as u16 ) << 8 | data[ 15 ] as u16 ,
175
+ ) ) ) ,
176
+ _ => None ,
177
+ }
178
+ }
179
+ }
180
+
181
+ pub trait ExtractSBGPInfo {
84
182
fn asn ( & self ) -> Option < ASIdentifiers > ;
183
+ fn ip_addresses ( & self ) -> Option < Stack < IPAddressFamily > > ;
85
184
}
86
185
87
- impl ExtractASN for X509 {
186
+ impl ExtractSBGPInfo for X509 {
88
187
fn asn ( & self ) -> Option < ASIdentifiers > {
89
188
unsafe {
90
189
let asn = ffi:: X509_get_ext_d2i (
@@ -96,4 +195,16 @@ impl ExtractASN for X509 {
96
195
ASIdentifiers :: from_ptr_opt ( asn as * mut _ )
97
196
}
98
197
}
198
+
199
+ fn ip_addresses ( & self ) -> Option < Stack < IPAddressFamily > > {
200
+ unsafe {
201
+ let asn = ffi:: X509_get_ext_d2i (
202
+ self . as_ptr ( ) ,
203
+ ffi:: NID_sbgp_ipAddrBlock ,
204
+ std:: ptr:: null_mut ( ) ,
205
+ std:: ptr:: null_mut ( ) ,
206
+ ) ;
207
+ Stack :: from_ptr_opt ( asn as * mut _ )
208
+ }
209
+ }
99
210
}
0 commit comments