rust_pdf_box/crypto/
asn1.rs1#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum DerElement {
5 Boolean(bool),
6 Integer(Vec<u8>), BitString(Vec<u8>, u8), OctetString(Vec<u8>),
9 Null,
10 ObjectIdentifier(Vec<u64>),
11 Utf8String(String),
12 PrintableString(String),
13 UtcTime(String), GeneralizedTime(String), Sequence(Vec<DerElement>),
16 Set(Vec<DerElement>),
17 ContextSpecific(u8, Box<DerElement>, bool), }
19
20impl DerElement {
21 pub fn integer_from_u64(val: u64) -> Self {
22 let bytes = val.to_be_bytes();
23 let mut start = 0;
24 while start < bytes.len() - 1 && bytes[start] == 0 {
25 start += 1;
26 }
27 let mut slice = bytes[start..].to_vec();
28 if (slice[0] & 0x80) != 0 {
30 slice.insert(0, 0x00);
31 }
32 Self::Integer(slice)
33 }
34
35 pub fn integer_from_bytes(bytes: &[u8]) -> Self {
36 let mut v = bytes.to_vec();
37 if v.is_empty() {
38 v.push(0);
39 } else if (v[0] & 0x80) != 0 {
40 v.insert(0, 0x00);
41 }
42 Self::Integer(v)
43 }
44
45 pub fn to_der(&self) -> Vec<u8> {
46 let mut out = Vec::new();
47 match self {
48 Self::Boolean(b) => {
49 out.push(0x01);
50 out.push(0x01);
51 out.push(if *b { 0xFF } else { 0x00 });
52 }
53 Self::Integer(bytes) => {
54 out.push(0x02);
55 encode_length(&mut out, bytes.len());
56 out.extend_from_slice(bytes);
57 }
58 Self::BitString(bytes, unused_bits) => {
59 out.push(0x03);
60 encode_length(&mut out, bytes.len() + 1);
61 out.push(*unused_bits);
62 out.extend_from_slice(bytes);
63 }
64 Self::OctetString(bytes) => {
65 out.push(0x04);
66 encode_length(&mut out, bytes.len());
67 out.extend_from_slice(bytes);
68 }
69 Self::Null => {
70 out.push(0x05);
71 out.push(0x00);
72 }
73 Self::ObjectIdentifier(arcs) => {
74 out.push(0x06);
75 let mut body = Vec::new();
76 if arcs.len() >= 2 {
77 body.push((arcs[0] * 40 + arcs[1]) as u8);
78 for &arc in &arcs[2..] {
79 encode_oid_arc(&mut body, arc);
80 }
81 }
82 encode_length(&mut out, body.len());
83 out.extend_from_slice(&body);
84 }
85 Self::Utf8String(s) => {
86 out.push(0x0C);
87 encode_length(&mut out, s.len());
88 out.extend_from_slice(s.as_bytes());
89 }
90 Self::PrintableString(s) => {
91 out.push(0x13);
92 encode_length(&mut out, s.len());
93 out.extend_from_slice(s.as_bytes());
94 }
95 Self::UtcTime(s) => {
96 out.push(0x17);
97 encode_length(&mut out, s.len());
98 out.extend_from_slice(s.as_bytes());
99 }
100 Self::GeneralizedTime(s) => {
101 out.push(0x18);
102 encode_length(&mut out, s.len());
103 out.extend_from_slice(s.as_bytes());
104 }
105 Self::Sequence(elements) => {
106 let mut body = Vec::new();
107 for el in elements {
108 body.extend_from_slice(&el.to_der());
109 }
110 out.push(0x30); encode_length(&mut out, body.len());
112 out.extend_from_slice(&body);
113 }
114 Self::Set(elements) => {
115 let mut body = Vec::new();
116 for el in elements {
117 body.extend_from_slice(&el.to_der());
118 }
119 out.push(0x31); encode_length(&mut out, body.len());
121 out.extend_from_slice(&body);
122 }
123 Self::ContextSpecific(tag, inner, is_constructed) => {
124 let body = inner.to_der();
125 let tag_byte = 0x80 | (if *is_constructed { 0x20 } else { 0x00 }) | (tag & 0x1F);
126 out.push(tag_byte);
127 encode_length(&mut out, body.len());
129 out.extend_from_slice(&body);
130 }
131 }
132 out
133 }
134}
135
136fn encode_length(out: &mut Vec<u8>, len: usize) {
137 if len < 128 {
138 out.push(len as u8);
139 } else {
140 let mut len_bytes = Vec::new();
141 let mut temp = len;
142 while temp > 0 {
143 len_bytes.push((temp & 0xFF) as u8);
144 temp >>= 8;
145 }
146 len_bytes.reverse();
147 out.push(0x80 | (len_bytes.len() as u8));
148 out.extend_from_slice(&len_bytes);
149 }
150}
151
152fn encode_oid_arc(out: &mut Vec<u8>, mut arc: u64) {
153 let mut chunks = Vec::new();
154 chunks.push((arc & 0x7F) as u8);
155 arc >>= 7;
156 while arc > 0 {
157 chunks.push(0x80 | ((arc & 0x7F) as u8));
158 arc >>= 7;
159 }
160 chunks.reverse();
161 out.extend_from_slice(&chunks);
162}