@@ -17,6 +17,9 @@ use crate::alloc_prelude::*;
17
17
use mbedtls_sys:: types:: raw_types:: c_char;
18
18
use mbedtls_sys:: * ;
19
19
20
+ use yasna:: models:: ObjectIdentifier ;
21
+ use yasna:: { BERDecodable , BERReader , ASN1Result , ASN1Error , ASN1ErrorKind } ;
22
+
20
23
use crate :: pk:: Pk ;
21
24
use crate :: error:: { Error , IntoResult , Result } ;
22
25
use crate :: private:: UnsafeFrom ;
@@ -37,6 +40,24 @@ define!(
37
40
const drop: fn ( & mut Self ) = x509_crt_free;
38
41
) ;
39
42
43
+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
44
+ pub struct Extension {
45
+ pub oid : ObjectIdentifier ,
46
+ pub critical : bool ,
47
+ pub value : Vec < u8 > ,
48
+ }
49
+
50
+ impl BERDecodable for Extension {
51
+ fn decode_ber ( reader : BERReader ) -> ASN1Result < Self > {
52
+ reader. read_sequence ( |reader| {
53
+ let oid = reader. next ( ) . read_oid ( ) ?;
54
+ let critical = reader. read_optional ( |r| r. read_bool ( ) ) ?. unwrap_or ( false ) ;
55
+ let value = reader. next ( ) . read_bytes ( ) ?;
56
+ Ok ( Extension { oid, critical, value } )
57
+ } )
58
+ }
59
+ }
60
+
40
61
impl Certificate {
41
62
pub fn from_der ( der : & [ u8 ] ) -> Result < Certificate > {
42
63
let mut ret = Self :: init ( ) ;
@@ -217,6 +238,25 @@ impl LinkedCertificate {
217
238
Ok ( x509_buf_to_vec ( & self . inner . v3_ext ) )
218
239
}
219
240
241
+ pub fn extensions ( & self ) -> Result < Vec < Extension > > {
242
+ let mut ext = Vec :: new ( ) ;
243
+
244
+ yasna:: parse_der ( & self . extensions_raw ( ) ?, |r| {
245
+ r. read_sequence_of ( |r| {
246
+ if let Ok ( data) = r. read_der ( ) {
247
+ let e: Extension = yasna:: decode_der ( & data) ?;
248
+ ext. push ( e) ;
249
+ return Ok ( ( ) ) ;
250
+ } else {
251
+ return Err ( ASN1Error :: new ( ASN1ErrorKind :: Eof ) ) ;
252
+ }
253
+ } ) ?;
254
+ return Ok ( ( ) ) ;
255
+ } ) . map_err ( |_| Error :: X509InvalidExtensions ) ?;
256
+
257
+ Ok ( ext)
258
+ }
259
+
220
260
pub fn signature ( & self ) -> Result < Vec < u8 > > {
221
261
Ok ( x509_buf_to_vec ( & self . inner . sig ) )
222
262
}
@@ -804,6 +844,35 @@ cYp0bH/RcPTC0Z+ZaqSWMtfxRrk63MJQF9EXpDCdvQRcTMD9D85DJrMKn8aumq0M
804
844
use crate :: x509:: Time ;
805
845
assert_eq ! ( cert. not_before( ) . unwrap( ) , Time :: new( 2019 , 1 , 8 , 0 , 18 , 35 ) . unwrap( ) ) ;
806
846
assert_eq ! ( cert. not_after( ) . unwrap( ) , Time :: new( 2029 , 1 , 5 , 0 , 18 , 35 ) . unwrap( ) ) ;
847
+
848
+ let ext = cert. extensions ( ) . unwrap ( ) ;
849
+ assert_eq ! ( ext. len( ) , 5 ) ;
850
+
851
+ assert_eq ! ( ext[ 0 ] , Extension {
852
+ oid: ObjectIdentifier :: from_slice( & [ 2 , 5 , 29 , 14 ] ) ,
853
+ critical: false ,
854
+ value: hex:: decode( "04186839FAD57E6544121CC6BC421953CC9620655C57CFAC0602" ) . unwrap( ) ,
855
+ } ) ;
856
+ assert_eq ! ( ext[ 1 ] , Extension {
857
+ oid: ObjectIdentifier :: from_slice( & [ 2 , 5 , 29 , 17 ] ) ,
858
+ critical: false ,
859
+ value: hex:: decode( "302981117465737440666f7274616e69782e636f6d82146578616d706c652e666f7274616e69782e636f6d" ) . unwrap( )
860
+ } ) ;
861
+ assert_eq ! ( ext[ 2 ] , Extension {
862
+ oid: ObjectIdentifier :: from_slice( & [ 2 , 5 , 29 , 19 ] ) ,
863
+ critical: true ,
864
+ value: hex:: decode( "3000" ) . unwrap( )
865
+ } ) ;
866
+ assert_eq ! ( ext[ 3 ] , Extension {
867
+ oid: ObjectIdentifier :: from_slice( & [ 2 , 5 , 29 , 35 ] ) ,
868
+ critical: false ,
869
+ value: hex:: decode( "301a801879076BCC8DA0077E4116F84B8E4C9C5C6AF7EC4FA000D987" ) . unwrap( )
870
+ } ) ;
871
+ assert_eq ! ( ext[ 4 ] , Extension {
872
+ oid: ObjectIdentifier :: from_slice( & [ 2 , 5 , 29 , 37 ] ) ,
873
+ critical: false ,
874
+ value: hex:: decode( "300a06082b06010505070302" ) . unwrap( ) ,
875
+ } ) ;
807
876
}
808
877
809
878
#[ test]
0 commit comments