1use crate::public_key::bigint::BigUint;
13use crate::public_key::io::{pem_unwrap, pem_wrap, xml_unwrap, xml_wrap};
14use crate::public_key::rsa::{Rsa, RsaPrivateKey, RsaPublicKey};
15
16const RSA_ENCRYPTION_OID: &[u8] = &[0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01];
17
18impl RsaPublicKey {
19 #[must_use]
21 pub fn to_pkcs1_der(&self) -> Vec<u8> {
22 let mut body = Vec::new();
23 body.extend(der_integer_biguint(self.modulus()));
24 body.extend(der_integer_biguint(self.exponent()));
25 der_sequence(&body)
26 }
27
28 #[must_use]
30 pub fn to_spki_der(&self) -> Vec<u8> {
31 let pkcs1 = self.to_pkcs1_der();
32 let mut alg = Vec::new();
33 alg.extend(der_oid(RSA_ENCRYPTION_OID));
34 alg.extend(der_null());
35
36 let mut body = Vec::new();
37 body.extend(der_sequence(&alg));
38 body.extend(der_bit_string(&pkcs1));
39 der_sequence(&body)
40 }
41
42 #[must_use]
44 pub fn to_pkcs1_pem(&self) -> String {
45 pem_wrap("RSA PUBLIC KEY", &self.to_pkcs1_der())
46 }
47
48 #[must_use]
50 pub fn to_spki_pem(&self) -> String {
51 pem_wrap("PUBLIC KEY", &self.to_spki_der())
52 }
53
54 #[must_use]
60 pub fn to_xml(&self) -> String {
61 xml_wrap(
62 "RsaPublicKey",
63 &[("e", self.exponent()), ("n", self.modulus())],
64 )
65 }
66
67 #[must_use]
69 pub fn from_pkcs1_der(der: &[u8]) -> Option<Self> {
70 let mut outer = DerReader::new(der);
71 let seq = outer.read_tlv(0x30)?;
72 if !outer.is_finished() {
73 return None;
74 }
75
76 let mut reader = DerReader::new(seq);
77 let modulus = reader.read_integer_biguint()?;
78 let public_exponent = reader.read_integer_biguint()?;
79 if !reader.is_finished() || public_exponent <= BigUint::one() {
80 return None;
81 }
82
83 Some(Self::from_components(public_exponent, modulus))
84 }
85
86 #[must_use]
88 pub fn from_spki_der(der: &[u8]) -> Option<Self> {
89 let mut outer = DerReader::new(der);
90 let seq = outer.read_tlv(0x30)?;
91 if !outer.is_finished() {
92 return None;
93 }
94
95 let mut reader = DerReader::new(seq);
96 let alg_seq = reader.read_tlv(0x30)?;
97 let bit_string = reader.read_tlv(0x03)?;
98 if !reader.is_finished() || bit_string.is_empty() || bit_string[0] != 0 {
99 return None;
100 }
101
102 let mut alg_reader = DerReader::new(alg_seq);
103 let oid = alg_reader.read_tlv(0x06)?;
104 let _null = alg_reader.read_tlv(0x05)?;
105 if !alg_reader.is_finished() || oid != RSA_ENCRYPTION_OID {
106 return None;
107 }
108
109 Self::from_pkcs1_der(&bit_string[1..])
110 }
111
112 #[must_use]
114 pub fn from_pkcs1_pem(pem: &str) -> Option<Self> {
115 let der = pem_unwrap("RSA PUBLIC KEY", pem)?;
116 Self::from_pkcs1_der(&der)
117 }
118
119 #[must_use]
121 pub fn from_spki_pem(pem: &str) -> Option<Self> {
122 let der = pem_unwrap("PUBLIC KEY", pem)?;
123 Self::from_spki_der(&der)
124 }
125
126 #[must_use]
128 pub fn from_xml(xml: &str) -> Option<Self> {
129 let mut fields = xml_unwrap("RsaPublicKey", &["e", "n"], xml)?.into_iter();
130 let public_exponent = fields.next()?;
131 let modulus = fields.next()?;
132 if fields.next().is_some() || public_exponent <= BigUint::one() || modulus <= BigUint::one()
133 {
134 return None;
135 }
136 Some(Self::from_components(public_exponent, modulus))
137 }
138}
139
140impl RsaPrivateKey {
141 #[must_use]
147 pub fn to_pkcs1_der(&self) -> Vec<u8> {
148 let mut body = Vec::new();
149 body.extend(der_integer_u8(0));
150 body.extend(der_integer_biguint(self.modulus()));
151 body.extend(der_integer_biguint(self.public_exponent()));
152 body.extend(der_integer_biguint(self.exponent()));
153 body.extend(der_integer_biguint(self.prime1()));
154 body.extend(der_integer_biguint(self.prime2()));
155 body.extend(der_integer_biguint(self.crt_exponent1()));
156 body.extend(der_integer_biguint(self.crt_exponent2()));
157 body.extend(der_integer_biguint(self.crt_coefficient()));
158 der_sequence(&body)
159 }
160
161 #[must_use]
163 pub fn to_pkcs8_der(&self) -> Vec<u8> {
164 let pkcs1 = self.to_pkcs1_der();
165
166 let mut alg = Vec::new();
167 alg.extend(der_oid(RSA_ENCRYPTION_OID));
168 alg.extend(der_null());
169
170 let mut body = Vec::new();
171 body.extend(der_integer_u8(0));
172 body.extend(der_sequence(&alg));
173 body.extend(der_octet_string(&pkcs1));
174 der_sequence(&body)
175 }
176
177 #[must_use]
179 pub fn to_pkcs1_pem(&self) -> String {
180 pem_wrap("RSA PRIVATE KEY", &self.to_pkcs1_der())
181 }
182
183 #[must_use]
185 pub fn to_pkcs8_pem(&self) -> String {
186 pem_wrap("PRIVATE KEY", &self.to_pkcs8_der())
187 }
188
189 #[must_use]
194 pub fn to_xml(&self) -> String {
195 xml_wrap(
196 "RsaPrivateKey",
197 &[
198 ("e", self.public_exponent()),
199 ("d", self.exponent()),
200 ("n", self.modulus()),
201 ("p", self.prime1()),
202 ("q", self.prime2()),
203 ],
204 )
205 }
206
207 #[must_use]
209 pub fn from_pkcs1_der(der: &[u8]) -> Option<Self> {
210 let mut outer = DerReader::new(der);
211 let seq = outer.read_tlv(0x30)?;
212 if !outer.is_finished() {
213 return None;
214 }
215
216 let mut reader = DerReader::new(seq);
217 let version = reader.read_integer_small()?;
218 if version != 0 {
219 return None;
220 }
221
222 let modulus = reader.read_integer_biguint()?;
223 let public_exponent = reader.read_integer_biguint()?;
224 let private_exponent = reader.read_integer_biguint()?;
225 let prime1 = reader.read_integer_biguint()?;
226 let prime2 = reader.read_integer_biguint()?;
227 let exponent1 = reader.read_integer_biguint()?;
228 let exponent2 = reader.read_integer_biguint()?;
229 let coefficient = reader.read_integer_biguint()?;
230 if !reader.is_finished() {
231 return None;
232 }
233
234 let (public, private) = Rsa::from_primes_with_exponent(&prime1, &prime2, &public_exponent)?;
235 if public.modulus() != &modulus || private.exponent() != &private_exponent {
236 return None;
237 }
238
239 if exponent1 != *private.crt_exponent1() || exponent2 != *private.crt_exponent2() {
240 return None;
241 }
242 if coefficient != *private.crt_coefficient() {
243 return None;
244 }
245
246 Some(private)
247 }
248
249 #[must_use]
251 pub fn from_pkcs8_der(der: &[u8]) -> Option<Self> {
252 let mut outer = DerReader::new(der);
253 let seq = outer.read_tlv(0x30)?;
254 if !outer.is_finished() {
255 return None;
256 }
257
258 let mut reader = DerReader::new(seq);
259 let version = reader.read_integer_small()?;
260 if version != 0 {
261 return None;
262 }
263
264 let alg_seq = reader.read_tlv(0x30)?;
265 let inner = reader.read_tlv(0x04)?;
266 if !reader.is_finished() {
267 return None;
268 }
269
270 let mut alg_reader = DerReader::new(alg_seq);
271 let oid = alg_reader.read_tlv(0x06)?;
272 let _null = alg_reader.read_tlv(0x05)?;
273 if !alg_reader.is_finished() || oid != RSA_ENCRYPTION_OID {
274 return None;
275 }
276
277 Self::from_pkcs1_der(inner)
278 }
279
280 #[must_use]
282 pub fn from_pkcs1_pem(pem: &str) -> Option<Self> {
283 let der = pem_unwrap("RSA PRIVATE KEY", pem)?;
284 Self::from_pkcs1_der(&der)
285 }
286
287 #[must_use]
289 pub fn from_pkcs8_pem(pem: &str) -> Option<Self> {
290 let der = pem_unwrap("PRIVATE KEY", pem)?;
291 Self::from_pkcs8_der(&der)
292 }
293
294 #[must_use]
296 pub fn from_xml(xml: &str) -> Option<Self> {
297 let mut fields = xml_unwrap("RsaPrivateKey", &["e", "d", "n", "p", "q"], xml)?.into_iter();
298 let public_exponent = fields.next()?;
299 let private_exponent = fields.next()?;
300 let modulus = fields.next()?;
301 let prime1 = fields.next()?;
302 let prime2 = fields.next()?;
303 if fields.next().is_some() {
304 return None;
305 }
306
307 let (public, private) = Rsa::from_primes_with_exponent(&prime1, &prime2, &public_exponent)?;
308 if public.modulus() != &modulus || private.exponent() != &private_exponent {
309 return None;
310 }
311 Some(private)
312 }
313}
314
315fn der_tlv(tag: u8, content: &[u8]) -> Vec<u8> {
316 let mut out = Vec::with_capacity(2 + content.len() + 5);
317 out.push(tag);
318 out.extend(der_len(content.len()));
319 out.extend_from_slice(content);
320 out
321}
322
323fn der_len(len: usize) -> Vec<u8> {
324 if len < 128 {
325 return vec![u8::try_from(len).expect("short DER length fits in u8")];
327 }
328
329 let bytes = len.to_be_bytes();
330 let first_nonzero = bytes
331 .iter()
332 .position(|&byte| byte != 0)
333 .expect("non-zero long DER length has a significant byte");
334 let len_bytes = &bytes[first_nonzero..];
335
336 let mut out = Vec::with_capacity(1 + len_bytes.len());
337 out.push(0x80 | u8::try_from(len_bytes.len()).expect("usize length-of-length fits in u8"));
338 out.extend_from_slice(len_bytes);
339 out
340}
341
342fn der_sequence(content: &[u8]) -> Vec<u8> {
343 der_tlv(0x30, content)
344}
345
346fn der_octet_string(content: &[u8]) -> Vec<u8> {
347 der_tlv(0x04, content)
348}
349
350fn der_bit_string(content: &[u8]) -> Vec<u8> {
351 let mut body = Vec::with_capacity(1 + content.len());
352 body.push(0);
355 body.extend_from_slice(content);
356 der_tlv(0x03, &body)
357}
358
359fn der_null() -> Vec<u8> {
360 der_tlv(0x05, &[])
361}
362
363fn der_oid(content: &[u8]) -> Vec<u8> {
364 der_tlv(0x06, content)
365}
366
367fn der_integer_u8(value: u8) -> Vec<u8> {
368 der_integer_bytes(&[value])
369}
370
371fn der_integer_biguint(value: &BigUint) -> Vec<u8> {
372 let bytes = value.to_be_bytes();
373 der_integer_bytes(&bytes)
374}
375
376fn der_integer_bytes(bytes: &[u8]) -> Vec<u8> {
377 let mut body = if let Some(first_nonzero) = bytes.iter().position(|&byte| byte != 0) {
378 bytes[first_nonzero..].to_vec()
379 } else {
380 vec![0]
381 };
382
383 if body[0] & 0x80 != 0 {
386 body.insert(0, 0);
387 }
388
389 der_tlv(0x02, &body)
390}
391
392struct DerReader<'a> {
393 data: &'a [u8],
394 pos: usize,
395}
396
397impl<'a> DerReader<'a> {
398 fn new(data: &'a [u8]) -> Self {
399 Self { data, pos: 0 }
400 }
401
402 fn is_finished(&self) -> bool {
403 self.pos == self.data.len()
404 }
405
406 fn read_tlv(&mut self, expected_tag: u8) -> Option<&'a [u8]> {
407 let tag = *self.data.get(self.pos)?;
408 self.pos += 1;
409 if tag != expected_tag {
410 return None;
411 }
412
413 let first = *self.data.get(self.pos)?;
414 self.pos += 1;
415 let len = if first & 0x80 == 0 {
416 usize::from(first)
418 } else {
419 let count = usize::from(first & 0x7f);
422 if count == 0 || count > core::mem::size_of::<usize>() {
423 return None;
424 }
425 let mut len = 0usize;
426 for _ in 0..count {
427 len = (len << 8) | usize::from(*self.data.get(self.pos)?);
428 self.pos += 1;
429 }
430 len
431 };
432
433 let end = self.pos.checked_add(len)?;
434 let content = self.data.get(self.pos..end)?;
435 self.pos = end;
436 Some(content)
437 }
438
439 fn read_integer_biguint(&mut self) -> Option<BigUint> {
440 let content = self.read_tlv(0x02)?;
441 if content.is_empty() {
442 return None;
443 }
444 if content[0] & 0x80 != 0 {
446 return None;
447 }
448
449 let body = if content.len() > 1 && content[0] == 0 {
450 &content[1..]
453 } else {
454 content
455 };
456 Some(BigUint::from_be_bytes(body))
457 }
458
459 fn read_integer_small(&mut self) -> Option<u8> {
460 let value = self.read_integer_biguint()?;
461 let bytes = value.to_be_bytes();
462 if bytes.len() != 1 {
463 return None;
464 }
465 Some(bytes[0])
466 }
467}
468
469#[cfg(test)]
470mod tests {
471 use super::{RsaPrivateKey, RsaPublicKey};
472 use crate::public_key::rsa::Rsa;
473 use crate::vt::BigUint;
474
475 #[test]
476 fn spki_roundtrip() {
477 let p = BigUint::from_u64(61);
478 let q = BigUint::from_u64(53);
479 let (public, _) = Rsa::from_primes(&p, &q).expect("valid RSA key");
480
481 let der = public.to_spki_der();
482 let parsed = RsaPublicKey::from_spki_der(&der).expect("parse SPKI");
483 assert_eq!(parsed, public);
484
485 let pem = public.to_spki_pem();
486 let parsed = RsaPublicKey::from_spki_pem(&pem).expect("parse SPKI PEM");
487 assert_eq!(parsed, public);
488 }
489
490 #[test]
491 fn pkcs8_roundtrip() {
492 let p = BigUint::from_u64(61);
493 let q = BigUint::from_u64(53);
494 let (_, private) = Rsa::from_primes(&p, &q).expect("valid RSA key");
495
496 let der = private.to_pkcs8_der();
497 let parsed = RsaPrivateKey::from_pkcs8_der(&der).expect("parse PKCS#8");
498 assert_eq!(parsed, private);
499
500 let pem = private.to_pkcs8_pem();
501 let parsed = RsaPrivateKey::from_pkcs8_pem(&pem).expect("parse PKCS#8 PEM");
502 assert_eq!(parsed, private);
503 }
504
505 #[test]
506 fn xml_roundtrip() {
507 let p = BigUint::from_u64(61);
508 let q = BigUint::from_u64(53);
509 let (public, private) = Rsa::from_primes(&p, &q).expect("valid RSA key");
510
511 let public_xml = public.to_xml();
512 let private_xml = private.to_xml();
513 assert_eq!(RsaPublicKey::from_xml(&public_xml), Some(public));
514 assert_eq!(RsaPrivateKey::from_xml(&private_xml), Some(private));
515 }
516
517 #[test]
518 fn generated_key_xml_roundtrip() {
519 let mut drbg = crate::CtrDrbgAes256::new(&[0xc1; 48]);
520 let (public, private) = Rsa::generate(&mut drbg, 64).expect("generated RSA key");
521
522 let public_der = public.to_spki_der();
523 let public_xml = public.to_xml();
524 let private_xml = private.to_xml();
525
526 assert_eq!(
527 RsaPublicKey::from_spki_der(&public_der),
528 Some(public.clone())
529 );
530 assert_eq!(RsaPublicKey::from_xml(&public_xml), Some(public));
531 assert_eq!(RsaPrivateKey::from_xml(&private_xml), Some(private));
532 }
533
534 #[test]
535 fn openssl_accepts_spki_pem() {
536 let p = BigUint::from_u64(61);
537 let q = BigUint::from_u64(53);
538 let (public, _) = Rsa::from_primes(&p, &q).expect("valid RSA key");
539
540 let Some(expected) = crate::test_utils::run_openssl(
541 &[
542 "pkey", "-pubin", "-inform", "PEM", "-pubout", "-outform", "DER",
543 ],
544 public.to_spki_pem().as_bytes(),
545 ) else {
546 return;
547 };
548
549 assert_eq!(expected, public.to_spki_der());
550 }
551
552 #[test]
553 fn openssl_accepts_pkcs8_pem() {
554 let p = BigUint::from_u64(61);
555 let q = BigUint::from_u64(53);
556 let (_, private) = Rsa::from_primes(&p, &q).expect("valid RSA key");
557
558 let Some(expected) = crate::test_utils::run_openssl(
559 &["pkey", "-inform", "PEM", "-outform", "DER"],
560 private.to_pkcs8_pem().as_bytes(),
561 ) else {
562 return;
563 };
564
565 assert_eq!(expected, private.to_pkcs8_der());
566 }
567}