3
3
use crate :: { name:: Name , serial_number:: SerialNumber , time:: Validity } ;
4
4
use alloc:: vec:: Vec ;
5
5
use const_oid:: AssociatedOid ;
6
- use core:: cmp:: Ordering ;
6
+ use core:: { cmp:: Ordering , fmt :: Debug , marker :: PhantomData } ;
7
7
use der:: asn1:: BitString ;
8
8
use der:: { Decode , Enumerated , Error , ErrorKind , Sequence , ValueOrd } ;
9
9
use spki:: { AlgorithmIdentifierOwned , SubjectPublicKeyInfoOwned } ;
10
10
11
11
#[ cfg( feature = "pem" ) ]
12
12
use der:: pem:: PemLabel ;
13
13
14
+ pub trait ParsingProfile : PartialEq + Debug + Eq + Clone {
15
+ fn check_serial_number ( serial : & SerialNumber < Self > ) -> der:: Result < ( ) > {
16
+ // See the note in `SerialNumber::new`: we permit lengths of 21 bytes here,
17
+ // since some X.509 implementations interpret the limit of 20 bytes to refer
18
+ // to the pre-encoded value.
19
+ if serial. inner . len ( ) > SerialNumber :: < Self > :: MAX_DECODE_LEN {
20
+ Err ( ErrorKind :: Overlength . into ( ) )
21
+ } else {
22
+ Ok ( ( ) )
23
+ }
24
+ }
25
+ }
26
+
27
+ #[ derive( Debug , PartialEq , Eq , Clone ) ]
28
+ pub struct Rfc5280 ;
29
+
30
+ impl ParsingProfile for Rfc5280 { }
31
+
32
+ #[ cfg( feature = "hazmat" ) ]
33
+ #[ derive( Debug , PartialEq , Eq , Clone ) ]
34
+ pub struct Raw ;
35
+
36
+ #[ cfg( feature = "hazmat" ) ]
37
+ impl ParsingProfile for Raw {
38
+ fn check_serial_number ( serial : & SerialNumber < Self > ) -> der:: Result < ( ) > {
39
+ Ok ( ( ) )
40
+ }
41
+ }
42
+
14
43
/// Certificate `Version` as defined in [RFC 5280 Section 4.1].
15
44
///
16
45
/// ```text
@@ -73,7 +102,7 @@ impl Default for Version {
73
102
#[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
74
103
#[ derive( Clone , Debug , Eq , PartialEq , Sequence , ValueOrd ) ]
75
104
#[ allow( missing_docs) ]
76
- pub struct TbsCertificate {
105
+ pub struct TbsCertificate < PP : ParsingProfile = Rfc5280 > {
77
106
/// The certificate version
78
107
///
79
108
/// Note that this value defaults to Version 1 per the RFC. However,
@@ -83,7 +112,7 @@ pub struct TbsCertificate {
83
112
#[ asn1( context_specific = "0" , default = "Default::default" ) ]
84
113
pub version : Version ,
85
114
86
- pub serial_number : SerialNumber ,
115
+ pub serial_number : SerialNumber < PP > ,
87
116
pub signature : AlgorithmIdentifierOwned ,
88
117
pub issuer : Name ,
89
118
pub validity : Validity ,
@@ -98,6 +127,9 @@ pub struct TbsCertificate {
98
127
99
128
#[ asn1( context_specific = "3" , tag_mode = "EXPLICIT" , optional = "true" ) ]
100
129
pub extensions : Option < crate :: ext:: Extensions > ,
130
+
131
+ #[ asn1( skipped = "Default::default" ) ]
132
+ _profile : PhantomData < PP > ,
101
133
}
102
134
103
135
impl TbsCertificate {
@@ -146,14 +178,14 @@ impl TbsCertificate {
146
178
#[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
147
179
#[ derive( Clone , Debug , Eq , PartialEq , Sequence , ValueOrd ) ]
148
180
#[ allow( missing_docs) ]
149
- pub struct Certificate {
150
- pub tbs_certificate : TbsCertificate ,
181
+ pub struct Certificate < PP : ParsingProfile = Rfc5280 > {
182
+ pub tbs_certificate : TbsCertificate < PP > ,
151
183
pub signature_algorithm : AlgorithmIdentifierOwned ,
152
184
pub signature : BitString ,
153
185
}
154
186
155
187
#[ cfg( feature = "pem" ) ]
156
- impl PemLabel for Certificate {
188
+ impl < PP : ParsingProfile > PemLabel for Certificate < PP > {
157
189
const PEM_LABEL : & ' static str = "CERTIFICATE" ;
158
190
}
159
191
0 commit comments