1
1
//! X.509 serial number
2
2
3
- use core:: fmt:: Display ;
3
+ use core:: { fmt:: Display , marker :: PhantomData } ;
4
4
5
5
use der:: {
6
6
asn1:: { self , Int } ,
7
7
DecodeValue , EncodeValue , ErrorKind , FixedTag , Header , Length , Reader , Result , Tag , ValueOrd ,
8
8
Writer ,
9
9
} ;
10
10
11
+ use crate :: certificate:: { Profile , Rfc5280 } ;
12
+
11
13
/// [RFC 5280 Section 4.1.2.2.] Serial Number
12
14
///
13
15
/// The serial number MUST be a positive integer assigned by the CA to
@@ -25,16 +27,18 @@ use der::{
25
27
/// that are negative or zero. Certificate users SHOULD be prepared to
26
28
/// gracefully handle such certificates.
27
29
#[ derive( Clone , Debug , Eq , PartialEq , ValueOrd , PartialOrd , Ord ) ]
28
- pub struct SerialNumber {
29
- inner : Int ,
30
+ pub struct SerialNumber < P : Profile = Rfc5280 > {
31
+ pub ( crate ) inner : Int ,
32
+ #[ asn1( skipped = "Default::default" ) ]
33
+ _profile : PhantomData < P > ,
30
34
}
31
35
32
- impl SerialNumber {
36
+ impl < P : Profile > SerialNumber < P > {
33
37
/// Maximum length in bytes for a [`SerialNumber`]
34
38
pub const MAX_LEN : Length = Length :: new ( 20 ) ;
35
39
36
40
/// See notes in `SerialNumber::new` and `SerialNumber::decode_value`.
37
- const MAX_DECODE_LEN : Length = Length :: new ( 21 ) ;
41
+ pub ( crate ) const MAX_DECODE_LEN : Length = Length :: new ( 21 ) ;
38
42
39
43
/// Create a new [`SerialNumber`] from a byte slice.
40
44
///
@@ -47,12 +51,13 @@ impl SerialNumber {
47
51
// RFC 5280 is ambiguous about whether this is valid, so we limit
48
52
// `SerialNumber` *encodings* to 20 bytes or fewer while permitting
49
53
// `SerialNumber` *decodings* to have up to 21 bytes below.
50
- if inner. value_len ( ) ? > SerialNumber :: MAX_LEN {
54
+ if inner. value_len ( ) ? > Self :: MAX_LEN {
51
55
return Err ( ErrorKind :: Overlength . into ( ) ) ;
52
56
}
53
57
54
58
Ok ( Self {
55
59
inner : inner. into ( ) ,
60
+ _profile : PhantomData ,
56
61
} )
57
62
}
58
63
@@ -63,7 +68,7 @@ impl SerialNumber {
63
68
}
64
69
}
65
70
66
- impl EncodeValue for SerialNumber {
71
+ impl < P : Profile > EncodeValue for SerialNumber < P > {
67
72
fn value_len ( & self ) -> Result < Length > {
68
73
self . inner . value_len ( )
69
74
}
@@ -73,22 +78,21 @@ impl EncodeValue for SerialNumber {
73
78
}
74
79
}
75
80
76
- impl < ' a > DecodeValue < ' a > for SerialNumber {
81
+ impl < ' a , P : Profile > DecodeValue < ' a > for SerialNumber < P > {
77
82
fn decode_value < R : Reader < ' a > > ( reader : & mut R , header : Header ) -> Result < Self > {
78
83
let inner = Int :: decode_value ( reader, header) ?;
84
+ let serial = Self {
85
+ inner,
86
+ _profile : PhantomData ,
87
+ } ;
79
88
80
- // See the note in `SerialNumber::new`: we permit lengths of 21 bytes here,
81
- // since some X.509 implementations interpret the limit of 20 bytes to refer
82
- // to the pre-encoded value.
83
- if inner. len ( ) > SerialNumber :: MAX_DECODE_LEN {
84
- return Err ( Tag :: Integer . value_error ( ) ) ;
85
- }
89
+ P :: check_serial_number ( & serial) ?;
86
90
87
- Ok ( Self { inner } )
91
+ Ok ( serial )
88
92
}
89
93
}
90
94
91
- impl FixedTag for SerialNumber {
95
+ impl < P : Profile > FixedTag for SerialNumber < P > {
92
96
const TAG : Tag = <Int as FixedTag >:: TAG ;
93
97
}
94
98
@@ -131,7 +135,7 @@ impl_from!(usize);
131
135
// Implement by hand because the derive would create invalid values.
132
136
// Use the constructor to create a valid value.
133
137
#[ cfg( feature = "arbitrary" ) ]
134
- impl < ' a > arbitrary:: Arbitrary < ' a > for SerialNumber {
138
+ impl < ' a , P : Profile > arbitrary:: Arbitrary < ' a > for SerialNumber < P > {
135
139
fn arbitrary ( u : & mut arbitrary:: Unstructured < ' a > ) -> arbitrary:: Result < Self > {
136
140
let len = u. int_in_range ( 0u32 ..=Self :: MAX_LEN . into ( ) ) ?;
137
141
@@ -154,7 +158,7 @@ mod tests {
154
158
// Creating a new serial with an oversized encoding (due to high MSB) fails.
155
159
{
156
160
let too_big = [ 0x80 ; 20 ] ;
157
- assert ! ( SerialNumber :: new( & too_big) . is_err( ) ) ;
161
+ assert ! ( SerialNumber :: < Rfc5280 > :: new( & too_big) . is_err( ) ) ;
158
162
}
159
163
160
164
// Creating a new serial with the maximum encoding succeeds.
@@ -163,7 +167,7 @@ mod tests {
163
167
0x7F , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
164
168
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
165
169
] ;
166
- assert ! ( SerialNumber :: new( & just_enough) . is_ok( ) ) ;
170
+ assert ! ( SerialNumber :: < Rfc5280 > :: new( & just_enough) . is_ok( ) ) ;
167
171
}
168
172
}
169
173
0 commit comments