@@ -12,6 +12,7 @@ use nom::combinator::{all_consuming, complete, map_opt, map_res, opt};
12
12
use nom:: multi:: { many0, many1} ;
13
13
use nom:: { exact, Err } ;
14
14
use oid_registry:: * ;
15
+ use std:: borrow:: Cow ;
15
16
use std:: collections:: HashMap ;
16
17
use std:: fmt;
17
18
@@ -24,7 +25,7 @@ pub struct X509Extension<'a> {
24
25
/// An extension includes the boolean critical, with a default value of FALSE.
25
26
pub critical : bool ,
26
27
/// Raw content of the extension
27
- pub value : & ' a [ u8 ] ,
28
+ pub ( crate ) value : Cow < ' a , [ u8 ] > ,
28
29
pub ( crate ) parsed_extension : ParsedExtension < ' a > ,
29
30
}
30
31
@@ -92,7 +93,7 @@ impl<'a> X509Extension<'a> {
92
93
let ext = X509Extension {
93
94
oid,
94
95
critical,
95
- value,
96
+ value : Cow :: Borrowed ( value ) ,
96
97
parsed_extension,
97
98
} ;
98
99
Ok ( ( i, ext) )
@@ -109,11 +110,16 @@ impl<'a> X509Extension<'a> {
109
110
X509Extension {
110
111
oid,
111
112
critical,
112
- value,
113
+ value : Cow :: Borrowed ( value ) ,
113
114
parsed_extension,
114
115
}
115
116
}
116
117
118
+ /// Return the value bytes
119
+ pub fn value ( & ' a self ) -> & ' a [ u8 ] {
120
+ & self . value
121
+ }
122
+
117
123
/// Return the extension type or `UnsupportedExtension` if the extension is not implemented.
118
124
pub fn parsed_extension ( & self ) -> & ParsedExtension < ' a > {
119
125
& self . parsed_extension
@@ -163,12 +169,12 @@ pub enum ParsedExtension<'a> {
163
169
pub struct AuthorityKeyIdentifier < ' a > {
164
170
pub key_identifier : Option < KeyIdentifier < ' a > > ,
165
171
pub authority_cert_issuer : Option < Vec < GeneralName < ' a > > > ,
166
- pub authority_cert_serial : Option < & ' a [ u8 ] > ,
172
+ pub authority_cert_serial : Option < Cow < ' a , [ u8 ] > > ,
167
173
}
168
174
169
175
#[ derive( Debug , PartialEq ) ]
170
176
pub struct CertificatePolicies < ' a > {
171
- pub policies : HashMap < Oid < ' a > , & ' a [ u8 ] > ,
177
+ pub policies : HashMap < Oid < ' a > , Cow < ' a , [ u8 ] > > ,
172
178
}
173
179
174
180
/// Identifies whether the subject of the certificate is a CA, and the max validation depth.
@@ -179,7 +185,7 @@ pub struct BasicConstraints {
179
185
}
180
186
181
187
#[ derive( Debug , PartialEq ) ]
182
- pub struct KeyIdentifier < ' a > ( pub & ' a [ u8 ] ) ;
188
+ pub struct KeyIdentifier < ' a > ( pub Cow < ' a , [ u8 ] > ) ;
183
189
184
190
#[ derive( Debug , PartialEq ) ]
185
191
pub struct KeyUsage {
@@ -355,20 +361,20 @@ pub struct SubjectAlternativeName<'a> {
355
361
///
356
362
/// String formats are not validated.
357
363
pub enum GeneralName < ' a > {
358
- OtherName ( Oid < ' a > , & ' a [ u8 ] ) ,
364
+ OtherName ( Oid < ' a > , Cow < ' a , [ u8 ] > ) ,
359
365
/// More or less an e-mail, the format is not checked.
360
- RFC822Name ( & ' a str ) ,
366
+ RFC822Name ( Cow < ' a , str > ) ,
361
367
/// A hostname, format is not checked.
362
- DNSName ( & ' a str ) ,
368
+ DNSName ( Cow < ' a , str > ) ,
363
369
// X400Address,
364
370
/// RFC5280 defines several string types, we always try to parse as utf-8
365
371
/// which is more or less a superset of the string types.
366
372
DirectoryName ( X509Name < ' a > ) ,
367
373
// EDIPartyName { name_assigner: Option<&'a str>, party_name: &'a str },
368
374
/// An uniform resource identifier. The format is not checked.
369
- URI ( & ' a str ) ,
375
+ URI ( Cow < ' a , str > ) ,
370
376
/// An ip address, provided as encoded.
371
- IPAddress ( & ' a [ u8 ] ) ,
377
+ IPAddress ( Cow < ' a , [ u8 ] > ) ,
372
378
RegisteredID ( Oid < ' a > ) ,
373
379
}
374
380
@@ -552,19 +558,20 @@ pub(crate) mod parser {
552
558
if len > rest. len ( ) {
553
559
return Err ( nom:: Err :: Failure ( BerError :: ObjectTooShort ) ) ;
554
560
}
555
- fn ia5str < ' a > ( i : & ' a [ u8 ] , hdr : DerObjectHeader ) -> Result < & ' a str , Err < BerError > > {
561
+ fn ia5str < ' a > ( i : & ' a [ u8 ] , hdr : DerObjectHeader ) -> Result < Cow < ' a , str > , Err < BerError > > {
556
562
der_read_element_content_as ( i, DerTag :: Ia5String , hdr. len , hdr. is_constructed ( ) , 0 ) ?
557
563
. 1
558
564
. into_bytes ( )
559
565
. and_then ( |s| std:: str:: from_utf8 ( s) . map_err ( |_| BerError :: BerValueError ) )
566
+ . map ( Cow :: Borrowed )
560
567
. map_err ( nom:: Err :: Failure )
561
568
}
562
569
let name = match hdr. tag . 0 {
563
570
0 => {
564
571
// otherName SEQUENCE { OID, [0] explicit any defined by oid }
565
572
let ( any, oid) = parse_der_oid ( rest) ?;
566
573
let oid = oid. as_oid_val ( ) . map_err ( nom:: Err :: Failure ) ?;
567
- GeneralName :: OtherName ( oid, any)
574
+ GeneralName :: OtherName ( oid, Cow :: Borrowed ( any) )
568
575
}
569
576
1 => GeneralName :: RFC822Name ( ia5str ( rest, hdr) ?) ,
570
577
2 => GeneralName :: DNSName ( ia5str ( rest, hdr) ?) ,
@@ -590,7 +597,7 @@ pub(crate) mod parser {
590
597
. 1
591
598
. into_bytes ( )
592
599
. map_err ( nom:: Err :: Failure ) ?;
593
- GeneralName :: IPAddress ( ip )
600
+ GeneralName :: IPAddress ( Cow :: Borrowed ( ip ) )
594
601
}
595
602
8 => {
596
603
let oid = der_read_element_content_as (
@@ -756,7 +763,7 @@ pub(crate) mod parser {
756
763
_hdr : DerObjectHeader < ' _ > ,
757
764
) -> IResult < & ' a [ u8 ] , AuthorityKeyIdentifier < ' a > , BerError > {
758
765
let ( i, key_identifier) = opt ( complete ( parse_der_tagged_implicit_g ( 0 , |d, _, _| {
759
- Ok ( ( & [ ] , KeyIdentifier ( d ) ) )
766
+ Ok ( ( & [ ] , KeyIdentifier ( Cow :: Borrowed ( d ) ) ) )
760
767
} ) ) ) ( i) ?;
761
768
let ( i, authority_cert_issuer) =
762
769
opt ( complete ( parse_der_tagged_implicit_g ( 1 , |d, _, _| {
@@ -766,7 +773,8 @@ pub(crate) mod parser {
766
773
2 ,
767
774
parse_der_content ( DerTag :: Integer ) ,
768
775
) ) ) ( i) ?;
769
- let authority_cert_serial = authority_cert_serial. and_then ( |o| o. into_bytes ( ) . ok ( ) ) ;
776
+ let authority_cert_serial =
777
+ authority_cert_serial. and_then ( |o| o. into_bytes ( ) . map ( Cow :: Borrowed ) . ok ( ) ) ;
770
778
let aki = AuthorityKeyIdentifier {
771
779
key_identifier,
772
780
authority_cert_issuer,
@@ -804,7 +812,7 @@ pub(crate) mod parser {
804
812
. content
805
813
. into_bytes ( )
806
814
. or ( Err ( Err :: Error ( BerError :: BerTypeError ) ) ) ?;
807
- let ki = KeyIdentifier ( id ) ;
815
+ let ki = KeyIdentifier ( Cow :: Borrowed ( id ) ) ;
808
816
let ret = ParsedExtension :: SubjectKeyIdentifier ( ki) ;
809
817
Ok ( ( rest, ret) )
810
818
}
@@ -855,11 +863,12 @@ pub(crate) mod parser {
855
863
//
856
864
// PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
857
865
fn parse_certificatepolicies ( i : & [ u8 ] ) -> IResult < & [ u8 ] , ParsedExtension , BerError > {
858
- fn parse_policy_information ( i : & [ u8 ] ) -> IResult < & [ u8 ] , ( Oid , & [ u8 ] ) , BerError > {
866
+ type LocalPolicyInfo < ' a > = ( Oid < ' a > , Cow < ' a , [ u8 ] > ) ;
867
+ fn parse_policy_information ( i : & [ u8 ] ) -> IResult < & [ u8 ] , LocalPolicyInfo , BerError > {
859
868
parse_der_sequence_defined_g ( |content, _| {
860
869
let ( qualifier_set, oid) =
861
870
map_res ( parse_der_oid, |x : DerObject | x. as_oid_val ( ) ) ( content) ?;
862
- Ok ( ( & [ ] , ( oid, qualifier_set) ) )
871
+ Ok ( ( & [ ] , ( oid, Cow :: Borrowed ( qualifier_set) ) ) )
863
872
} ) ( i)
864
873
}
865
874
let ( ret, mut policy_list) = parse_der_sequence_of_v ( parse_policy_information) ( i) ?;
@@ -1024,11 +1033,14 @@ mod tests {
1024
1033
) ;
1025
1034
{
1026
1035
let alt_names = & tbs. subject_alternative_name ( ) . unwrap ( ) . 1 . general_names ;
1027
- assert_eq ! ( alt_names
[ 0 ] , GeneralName :: RFC822Name ( "[email protected] " ) ) ;
1028
- assert_eq ! ( alt_names[ 1 ] , GeneralName :: URI ( "http://my.url.here/" ) ) ;
1036
+ assert_eq ! (
1037
+ alt_names[ 0 ] ,
1038
+ GeneralName :: RFC822Name ( "[email protected] " . into
( ) )
1039
+ ) ;
1040
+ assert_eq ! ( alt_names[ 1 ] , GeneralName :: URI ( "http://my.url.here/" . into( ) ) ) ;
1029
1041
assert_eq ! (
1030
1042
alt_names[ 2 ] ,
1031
- GeneralName :: IPAddress ( [ 192 , 168 , 7 , 1 ] . as_ref ( ) )
1043
+ GeneralName :: IPAddress ( Cow :: Borrowed ( & [ 192 , 168 , 7 , 1 ] ) )
1032
1044
) ;
1033
1045
assert_eq ! (
1034
1046
format!(
@@ -1040,11 +1052,14 @@ mod tests {
1040
1052
) ,
1041
1053
"C=UK, O=My Organization, OU=My Unit, CN=My Name"
1042
1054
) ;
1043
- assert_eq ! ( alt_names[ 4 ] , GeneralName :: DNSName ( "localhost" ) ) ;
1055
+ assert_eq ! ( alt_names[ 4 ] , GeneralName :: DNSName ( "localhost" . into ( ) ) ) ;
1044
1056
assert_eq ! ( alt_names[ 5 ] , GeneralName :: RegisteredID ( oid!( 1.2 . 90 . 0 ) ) ) ;
1045
1057
assert_eq ! (
1046
1058
alt_names[ 6 ] ,
1047
- GeneralName :: OtherName ( oid!( 1.2 . 3 . 4 ) , b"\xA0 \x17 \x0C \x15 some other identifier" )
1059
+ GeneralName :: OtherName (
1060
+ oid!( 1.2 . 3 . 4 ) ,
1061
+ Cow :: Borrowed ( b"\xA0 \x17 \x0C \x15 some other identifier" )
1062
+ )
1048
1063
) ;
1049
1064
}
1050
1065
@@ -1055,10 +1070,12 @@ mod tests {
1055
1070
name_constraints. excluded_subtrees,
1056
1071
Some ( vec![
1057
1072
GeneralSubtree {
1058
- base: GeneralName :: IPAddress ( [ 192 , 168 , 0 , 0 , 255 , 255 , 0 , 0 ] . as_ref( ) )
1073
+ base: GeneralName :: IPAddress ( Cow :: Borrowed ( & [
1074
+ 192 , 168 , 0 , 0 , 255 , 255 , 0 , 0
1075
+ ] ) )
1059
1076
} ,
1060
1077
GeneralSubtree {
1061
- base: GeneralName :: RFC822Name ( "foo.com" )
1078
+ base: GeneralName :: RFC822Name ( "foo.com" . into ( ) )
1062
1079
} ,
1063
1080
] )
1064
1081
) ;
0 commit comments