1
1
//! "Big" ASN.1 `INTEGER` types.
2
2
3
- use super :: uint;
3
+ use super :: { int , uint} ;
4
4
use crate :: {
5
5
asn1:: AnyRef , ord:: OrdIsValueOrd , ByteSlice , DecodeValue , EncodeValue , Error , ErrorKind ,
6
6
FixedTag , Header , Length , Reader , Result , Tag , Writer ,
7
7
} ;
8
8
9
+ /// "Big" signed ASN.1 `INTEGER` type.
10
+ ///
11
+ /// Provides direct access to the underlying big endian bytes which comprise
12
+ /// an signed integer value.
13
+ ///
14
+ /// Intended for use cases like very large integers that are used in
15
+ /// cryptographic applications (e.g. keys, signatures).
16
+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
17
+ pub struct IntRef < ' a > {
18
+ /// Inner value
19
+ inner : ByteSlice < ' a > ,
20
+ }
21
+
22
+ impl < ' a > IntRef < ' a > {
23
+ /// Create a new [`IntRef`] from a byte slice.
24
+ pub fn new ( bytes : & ' a [ u8 ] ) -> Result < Self > {
25
+ let inner = ByteSlice :: new ( int:: strip_leading_ones ( bytes) )
26
+ . map_err ( |_| ErrorKind :: Length { tag : Self :: TAG } ) ?;
27
+
28
+ Ok ( Self { inner } )
29
+ }
30
+
31
+ /// Borrow the inner byte slice which contains the least significant bytes
32
+ /// of a big endian integer value with all leading ones stripped.
33
+ pub fn as_bytes ( & self ) -> & ' a [ u8 ] {
34
+ self . inner . as_slice ( )
35
+ }
36
+
37
+ /// Get the length of this [`IntRef`] in bytes.
38
+ pub fn len ( & self ) -> Length {
39
+ self . inner . len ( )
40
+ }
41
+
42
+ /// Is the inner byte slice empty?
43
+ pub fn is_empty ( & self ) -> bool {
44
+ self . inner . is_empty ( )
45
+ }
46
+ }
47
+
48
+ impl < ' a > DecodeValue < ' a > for IntRef < ' a > {
49
+ fn decode_value < R : Reader < ' a > > ( reader : & mut R , header : Header ) -> Result < Self > {
50
+ let bytes = ByteSlice :: decode_value ( reader, header) ?. as_slice ( ) ;
51
+ let result = Self :: new ( int:: decode_to_slice ( bytes) ?) ?;
52
+
53
+ // Ensure we compute the same encoded length as the original any value.
54
+ if result. value_len ( ) ? != header. length {
55
+ return Err ( Self :: TAG . non_canonical_error ( ) ) ;
56
+ }
57
+
58
+ Ok ( result)
59
+ }
60
+ }
61
+
62
+ impl < ' a > EncodeValue for IntRef < ' a > {
63
+ fn value_len ( & self ) -> Result < Length > {
64
+ int:: encoded_len ( self . inner . as_slice ( ) )
65
+ }
66
+
67
+ fn encode_value ( & self , writer : & mut dyn Writer ) -> Result < ( ) > {
68
+ writer. write ( self . as_bytes ( ) )
69
+ }
70
+ }
71
+
72
+ impl < ' a > From < & IntRef < ' a > > for IntRef < ' a > {
73
+ fn from ( value : & IntRef < ' a > ) -> IntRef < ' a > {
74
+ * value
75
+ }
76
+ }
77
+
78
+ impl < ' a > TryFrom < AnyRef < ' a > > for IntRef < ' a > {
79
+ type Error = Error ;
80
+
81
+ fn try_from ( any : AnyRef < ' a > ) -> Result < IntRef < ' a > > {
82
+ any. decode_into ( )
83
+ }
84
+ }
85
+
86
+ impl < ' a > FixedTag for IntRef < ' a > {
87
+ const TAG : Tag = Tag :: Integer ;
88
+ }
89
+
90
+ impl < ' a > OrdIsValueOrd for IntRef < ' a > { }
91
+
9
92
/// "Big" unsigned ASN.1 `INTEGER` type.
10
93
///
11
94
/// Provides direct access to the underlying big endian bytes which comprise an
@@ -95,11 +178,11 @@ impl<'a> FixedTag for UintRef<'a> {
95
178
impl < ' a > OrdIsValueOrd for UintRef < ' a > { }
96
179
97
180
#[ cfg( feature = "alloc" ) ]
98
- pub use self :: allocating:: Uint ;
181
+ pub use self :: allocating:: { Int , Uint } ;
99
182
100
183
#[ cfg( feature = "alloc" ) ]
101
184
mod allocating {
102
- use super :: { super :: uint, UintRef } ;
185
+ use super :: { super :: int , super :: uint, IntRef , UintRef } ;
103
186
use crate :: {
104
187
asn1:: AnyRef ,
105
188
ord:: OrdIsValueOrd ,
@@ -108,6 +191,108 @@ mod allocating {
108
191
Result , Tag , Writer ,
109
192
} ;
110
193
194
+ /// "Big" signed ASN.1 `INTEGER` type.
195
+ ///
196
+ /// Provides direct storage for the big endian bytes which comprise an
197
+ /// signed integer value.
198
+ ///
199
+ /// Intended for use cases like very large integers that are used in
200
+ /// cryptographic applications (e.g. keys, signatures).
201
+ #[ derive( Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
202
+ pub struct Int {
203
+ /// Inner value
204
+ inner : Bytes ,
205
+ }
206
+
207
+ impl Int {
208
+ /// Create a new [`Int`] from a byte slice.
209
+ pub fn new ( bytes : & [ u8 ] ) -> Result < Self > {
210
+ let inner = Bytes :: new ( int:: strip_leading_ones ( bytes) )
211
+ . map_err ( |_| ErrorKind :: Length { tag : Self :: TAG } ) ?;
212
+
213
+ Ok ( Self { inner } )
214
+ }
215
+
216
+ /// Borrow the inner byte slice which contains the least significant bytes
217
+ /// of a big endian integer value with all leading ones stripped.
218
+ pub fn as_bytes ( & self ) -> & [ u8 ] {
219
+ self . inner . as_slice ( )
220
+ }
221
+
222
+ /// Get the length of this [`Int`] in bytes.
223
+ pub fn len ( & self ) -> Length {
224
+ self . inner . len ( )
225
+ }
226
+
227
+ /// Is the inner byte slice empty?
228
+ pub fn is_empty ( & self ) -> bool {
229
+ self . inner . is_empty ( )
230
+ }
231
+ }
232
+
233
+ impl < ' a > DecodeValue < ' a > for Int {
234
+ fn decode_value < R : Reader < ' a > > ( reader : & mut R , header : Header ) -> Result < Self > {
235
+ let bytes = Bytes :: decode_value ( reader, header) ?;
236
+ let result = Self :: new ( int:: decode_to_slice ( bytes. as_slice ( ) ) ?) ?;
237
+
238
+ // Ensure we compute the same encoded length as the original any value.
239
+ if result. value_len ( ) ? != header. length {
240
+ return Err ( Self :: TAG . non_canonical_error ( ) ) ;
241
+ }
242
+
243
+ Ok ( result)
244
+ }
245
+ }
246
+
247
+ impl EncodeValue for Int {
248
+ fn value_len ( & self ) -> Result < Length > {
249
+ int:: encoded_len ( self . inner . as_slice ( ) )
250
+ }
251
+
252
+ fn encode_value ( & self , writer : & mut dyn Writer ) -> Result < ( ) > {
253
+ writer. write ( self . as_bytes ( ) )
254
+ }
255
+ }
256
+
257
+ impl < ' a > From < & IntRef < ' a > > for Int {
258
+ fn from ( value : & IntRef < ' a > ) -> Int {
259
+ let inner = Bytes :: new ( value. as_bytes ( ) ) . expect ( "Invalid Int" ) ;
260
+ Int { inner }
261
+ }
262
+ }
263
+
264
+ impl < ' a > TryFrom < AnyRef < ' a > > for Int {
265
+ type Error = Error ;
266
+
267
+ fn try_from ( any : AnyRef < ' a > ) -> Result < Int > {
268
+ any. decode_into ( )
269
+ }
270
+ }
271
+
272
+ impl FixedTag for Int {
273
+ const TAG : Tag = Tag :: Integer ;
274
+ }
275
+
276
+ impl OrdIsValueOrd for Int { }
277
+
278
+ impl < ' a > RefToOwned < ' a > for IntRef < ' a > {
279
+ type Owned = Int ;
280
+ fn to_owned ( & self ) -> Self :: Owned {
281
+ let inner = self . inner . to_owned ( ) ;
282
+
283
+ Int { inner }
284
+ }
285
+ }
286
+
287
+ impl OwnedToRef for Int {
288
+ type Borrowed < ' a > = IntRef < ' a > ;
289
+ fn to_ref ( & self ) -> Self :: Borrowed < ' _ > {
290
+ let inner = self . inner . to_ref ( ) ;
291
+
292
+ IntRef { inner }
293
+ }
294
+ }
295
+
111
296
/// "Big" unsigned ASN.1 `INTEGER` type.
112
297
///
113
298
/// Provides direct storage for the big endian bytes which comprise an
@@ -220,10 +405,73 @@ mod allocating {
220
405
mod tests {
221
406
use super :: UintRef ;
222
407
use crate :: {
223
- asn1:: { integer:: tests:: * , AnyRef } ,
408
+ asn1:: { integer:: tests:: * , AnyRef , IntRef } ,
224
409
Decode , Encode , ErrorKind , SliceWriter , Tag ,
225
410
} ;
226
411
412
+ #[ test]
413
+ fn decode_int_bytes ( ) {
414
+ // Positive numbers decode, but have zero extensions as necessary
415
+ // (to distinguish them from negative representations).
416
+ assert_eq ! ( & [ 0 ] , IntRef :: from_der( I0_BYTES ) . unwrap( ) . as_bytes( ) ) ;
417
+ assert_eq ! ( & [ 127 ] , IntRef :: from_der( I127_BYTES ) . unwrap( ) . as_bytes( ) ) ;
418
+ assert_eq ! ( & [ 0 , 128 ] , IntRef :: from_der( I128_BYTES ) . unwrap( ) . as_bytes( ) ) ;
419
+ assert_eq ! ( & [ 0 , 255 ] , IntRef :: from_der( I255_BYTES ) . unwrap( ) . as_bytes( ) ) ;
420
+
421
+ assert_eq ! (
422
+ & [ 0x01 , 0x00 ] ,
423
+ IntRef :: from_der( I256_BYTES ) . unwrap( ) . as_bytes( )
424
+ ) ;
425
+
426
+ assert_eq ! (
427
+ & [ 0x7F , 0xFF ] ,
428
+ IntRef :: from_der( I32767_BYTES ) . unwrap( ) . as_bytes( )
429
+ ) ;
430
+
431
+ // Negative integers decode.
432
+ assert_eq ! ( & [ 128 ] , IntRef :: from_der( INEG128_BYTES ) . unwrap( ) . as_bytes( ) ) ;
433
+ assert_eq ! (
434
+ & [ 255 , 127 ] ,
435
+ IntRef :: from_der( INEG129_BYTES ) . unwrap( ) . as_bytes( )
436
+ ) ;
437
+ assert_eq ! (
438
+ & [ 128 , 0 ] ,
439
+ IntRef :: from_der( INEG32768_BYTES ) . unwrap( ) . as_bytes( )
440
+ ) ;
441
+ }
442
+
443
+ #[ test]
444
+ fn encode_int_bytes ( ) {
445
+ for & example in & [
446
+ I0_BYTES ,
447
+ I127_BYTES ,
448
+ I128_BYTES ,
449
+ I255_BYTES ,
450
+ I256_BYTES ,
451
+ I32767_BYTES ,
452
+ ] {
453
+ let uint = IntRef :: from_der ( example) . unwrap ( ) ;
454
+
455
+ let mut buf = [ 0u8 ; 128 ] ;
456
+ let mut encoder = SliceWriter :: new ( & mut buf) ;
457
+ uint. encode ( & mut encoder) . unwrap ( ) ;
458
+
459
+ let result = encoder. finish ( ) . unwrap ( ) ;
460
+ assert_eq ! ( example, result) ;
461
+ }
462
+
463
+ for & example in & [ INEG128_BYTES , INEG129_BYTES , INEG32768_BYTES ] {
464
+ let uint = IntRef :: from_der ( example) . unwrap ( ) ;
465
+
466
+ let mut buf = [ 0u8 ; 128 ] ;
467
+ let mut encoder = SliceWriter :: new ( & mut buf) ;
468
+ uint. encode ( & mut encoder) . unwrap ( ) ;
469
+
470
+ let result = encoder. finish ( ) . unwrap ( ) ;
471
+ assert_eq ! ( example, result) ;
472
+ }
473
+ }
474
+
227
475
#[ test]
228
476
fn decode_uint_bytes ( ) {
229
477
assert_eq ! ( & [ 0 ] , UintRef :: from_der( I0_BYTES ) . unwrap( ) . as_bytes( ) ) ;
0 commit comments