1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use ::{ Asn1DerError, types::{ FromDerObject, IntoDerObject }, der::{ DerObject, DerTag } };
macro_rules! impl_conv {
(decl: $uint:ident) => (
fn $uint(self) -> Result<$uint, Asn1DerError>;
);
(impl: $uint:ident) => (
fn $uint(self) -> Result<$uint, Asn1DerError> {
if self > $uint::max_value() as u128 { Err(Asn1DerError::Unsupported) }
else { Ok(self as $uint) }
}
);
}
pub trait U128Ext {
impl_conv!(decl: usize);
impl_conv!(decl: u64);
impl_conv!(decl: u32);
impl_conv!(decl: u16);
impl_conv!(decl: u8);
}
impl U128Ext for u128 {
impl_conv!(impl: usize);
impl_conv!(impl: u64);
impl_conv!(impl: u32);
impl_conv!(impl: u16);
impl_conv!(impl: u8);
}
impl FromDerObject for u128 {
fn from_der_object(der_object: DerObject) -> Result<Self, Asn1DerError> {
if der_object.tag != DerTag::Integer { return Err(Asn1DerError::InvalidTag) }
if der_object.value.data.is_empty() { return Err(Asn1DerError::InvalidEncoding) }
let mut data = der_object.value.data.iter().peekable();
let unsigned = match **data.peek().ok_or(Asn1DerError::InvalidEncoding)? {
b if b > 0x7f => return Err(Asn1DerError::Unsupported),
0x00 => {
data.next().unwrap();
true
},
_ => false
};
if unsigned { match data.peek().and_then(|b| Some(**b)) {
Some(b) if b < 0x80 => return Err(Asn1DerError::InvalidEncoding),
Some(0x00) => return Err(Asn1DerError::InvalidEncoding),
_ => ()
} }
if data.len() > 16 { return Err(Asn1DerError::Unsupported) }
let (mut value, mut shl) = (0u128, data.len() as u128);
while let Some(b) = data.next() {
shl -= 1;
value += (*b as u128) << (shl * 8);
}
Ok(value)
}
}
impl IntoDerObject for u128 {
fn into_der_object(self) -> DerObject {
let num_len = 16 - (self.leading_zeros() as usize / 8);
let push_leading_zero = self.leading_zeros() % 8 == 0;
let mut payload = Vec::new();
for i in (0..num_len).rev() {
payload.push((self >> (i * 8)) as u8);
}
if push_leading_zero { payload.insert(0, 0x00) }
DerObject::new(DerTag::Integer, payload.into())
}
fn serialized_len(&self) -> usize {
let mut num_len = 16 - (self.leading_zeros() as usize / 8);
if self.leading_zeros() % 8 == 0 { num_len += 1 }
DerObject::compute_serialized_len(num_len)
}
}