1use crate::Error;
10
11pub mod oid {
13 pub const EC_PUBLIC_KEY: &[u8] = &[0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01];
15 pub const PRIME256V1: &[u8] = &[0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07];
17 pub const SECP384R1: &[u8] = &[0x2b, 0x81, 0x04, 0x00, 0x22];
19 pub const RSA_ENCRYPTION: &[u8] = &[0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01];
21 pub const ED25519: &[u8] = &[0x2b, 0x65, 0x70];
23}
24
25pub fn read_tlv(input: &[u8]) -> Result<(u8, &[u8], &[u8]), Error> {
27 if input.len() < 2 {
28 return Err(Error::InvalidInput);
29 }
30 let tag = input[0];
31 let first = input[1] as usize;
33 let (len, rest_off) = if first < 0x80 {
34 (first, 2)
35 } else {
36 let n = first & 0x7f;
37 if n == 0 || n > 4 || n + 2 > input.len() {
39 return Err(Error::InvalidInput);
40 }
41 let mut len = 0usize;
42 for k in 0..n {
43 len = (len << 8) | input[2 + k] as usize;
44 }
45 if input[2] == 0 || len < 0x80 {
47 return Err(Error::InvalidInput);
48 }
49 (len, 2 + n)
50 };
51 if rest_off + len > input.len() {
52 return Err(Error::InvalidInput);
53 }
54 Ok((
55 tag,
56 &input[rest_off..rest_off + len],
57 &input[rest_off + len..],
58 ))
59}
60
61pub fn expect(tag: u8, input: &[u8]) -> Result<(&[u8], &[u8]), Error> {
63 let (t, content, rest) = read_tlv(input)?;
64 if t != tag {
65 return Err(Error::InvalidInput);
66 }
67 Ok((content, rest))
68}
69
70pub fn sequence(input: &[u8]) -> Result<(&[u8], &[u8]), Error> {
72 expect(0x30, input)
73}
74
75pub fn octet_string(input: &[u8]) -> Result<(&[u8], &[u8]), Error> {
77 expect(0x04, input)
78}
79
80pub fn bit_string(input: &[u8]) -> Result<(&[u8], &[u8]), Error> {
82 let (content, rest) = expect(0x03, input)?;
83 if content.is_empty() || content[0] != 0 {
84 return Err(Error::InvalidInput);
85 }
86 Ok((&content[1..], rest))
87}
88
89pub fn object_identifier(input: &[u8]) -> Result<(&[u8], &[u8]), Error> {
91 expect(0x06, input)
92}
93
94pub fn integer(input: &[u8]) -> Result<(&[u8], &[u8]), Error> {
97 let (content, rest) = expect(0x02, input)?;
98 if content.is_empty() {
99 return Err(Error::InvalidInput);
100 }
101 if content[0] & 0x80 != 0 {
103 return Err(Error::InvalidInput);
104 }
105 if content.len() >= 2 && content[0] == 0 && content[1] & 0x80 == 0 {
108 return Err(Error::InvalidInput);
109 }
110 let mut s = 0;
112 while s + 1 < content.len() && content[s] == 0 {
113 s += 1;
114 }
115 Ok((&content[s..], rest))
116}
117
118#[derive(Debug)]
120pub enum ParsedPrivateKey {
121 P256 {
123 scalar: [u8; 32],
125 public_sec1: Option<Vec<u8>>,
127 },
128 P384 {
130 scalar: [u8; 48],
132 public_sec1: Option<Vec<u8>>,
134 },
135 RsaPkcs1(Vec<u8>),
137 Ed25519(Vec<u8>),
139}
140
141pub fn parse_pkcs8_private_key(der: &[u8]) -> Result<ParsedPrivateKey, Error> {
149 let (seq, rest) = sequence(der)?;
150 if !rest.is_empty() {
152 return Err(Error::InvalidInput);
153 }
154 let (version, rest) = integer(seq)?;
155 if version.len() != 1 || version[0] != 0 {
156 return Err(Error::InvalidInput);
157 }
158 let (alg_seq, rest) = sequence(rest)?;
160 let (oid, alg_rest) = object_identifier(alg_seq)?;
161 let (_ptag, _params, _alg_rest_rest) = match read_tlv(alg_rest) {
162 Ok(x) => x,
163 Err(_) => return Err(Error::InvalidInput),
164 };
165 let (key_bytes, rest) = octet_string(rest)?;
166 if !rest.is_empty() && rest[0] != 0xa0 {
168 return Err(Error::InvalidInput);
169 }
170
171 if oid == oid::ED25519 {
172 let (seed, inner_rest) = octet_string(key_bytes)?;
174 if !inner_rest.is_empty() || seed.len() != 32 {
175 return Err(Error::InvalidInput);
176 }
177 return Ok(ParsedPrivateKey::Ed25519(seed.to_vec()));
178 }
179 if oid == oid::RSA_ENCRYPTION {
180 return Ok(ParsedPrivateKey::RsaPkcs1(key_bytes.to_vec()));
183 }
184 if oid == oid::EC_PUBLIC_KEY {
185 let (ptag, params, _alg_rest_rest) = read_tlv(alg_rest)?;
187 if ptag != 0x06 {
188 return Err(Error::InvalidInput);
189 }
190 let curve_oid = params;
191 let curve = if curve_oid == oid::PRIME256V1 {
192 32usize
193 } else if curve_oid == oid::SECP384R1 {
194 48usize
195 } else {
196 return Err(Error::InvalidInput);
197 };
198 let (sec1, sec1_rest) = sequence(key_bytes)?;
201 if !sec1_rest.is_empty() {
202 return Err(Error::InvalidInput);
203 }
204 let (sec_ver, sec1_rest) = integer(sec1)?;
205 if sec_ver.len() != 1 || sec_ver[0] != 1 {
206 return Err(Error::InvalidInput);
207 }
208 let (priv_key, sec1_rest) = octet_string(sec1_rest)?;
209 if priv_key.len() != curve || !sec1_rest.is_empty() && sec1_rest[0] != 0xa1 {
210 return Err(Error::InvalidInput);
211 }
212 let mut public_sec1 = None;
216 if !sec1_rest.is_empty() {
217 let (ptag, content, pub_rest) = read_tlv(sec1_rest)?;
218 if ptag != 0xa1 || !pub_rest.is_empty() || content.is_empty() {
219 return Err(Error::InvalidInput);
220 }
221 let point: &[u8] = if content[0] == 0x03 {
222 let (itag, bits, rest2) = read_tlv(content)?;
223 if itag != 0x03 || !rest2.is_empty() || bits.is_empty() || bits[0] != 0 {
224 return Err(Error::InvalidInput);
225 }
226 &bits[1..]
227 } else if content[0] == 0x00 {
228 &content[1..]
229 } else {
230 return Err(Error::InvalidInput);
231 };
232 if point.len() != 1 + 2 * curve || point[0] != 0x04 {
233 return Err(Error::InvalidInput);
234 }
235 public_sec1 = Some(point.to_vec());
236 }
237 let mut scalar = [0u8; 48];
238 scalar[..curve].copy_from_slice(priv_key);
239 return if curve == 32 {
240 let mut s256 = [0u8; 32];
241 s256.copy_from_slice(&scalar[..32]);
242 Ok(ParsedPrivateKey::P256 {
243 scalar: s256,
244 public_sec1,
245 })
246 } else {
247 Ok(ParsedPrivateKey::P384 {
248 scalar,
249 public_sec1,
250 })
251 };
252 }
253 Err(Error::InvalidInput)
254}