x509_parser/
public_key.rs1use crate::error::*;
2use asn1_rs::FromDer;
3use der_parser::{
4 der::{parse_der_integer, parse_der_sequence_defined_g},
5 error::BerResult,
6};
7
8#[derive(Debug, PartialEq, Eq)]
10pub enum PublicKey<'a> {
11 RSA(RSAPublicKey<'a>),
12 EC(ECPoint<'a>),
13 DSA(&'a [u8]),
15 GostR3410(&'a [u8]),
17 GostR3410_2012(&'a [u8]),
20
21 Unknown(&'a [u8]),
22}
23
24impl PublicKey<'_> {
25 pub fn key_size(&self) -> usize {
27 match self {
28 Self::EC(ec) => ec.key_size(),
29 Self::RSA(rsa) => rsa.key_size(),
30 Self::DSA(y) | Self::GostR3410(y) => y.len() * 8,
31 _ => 0,
32 }
33 }
34}
35
36#[derive(Debug, PartialEq, Eq)]
38pub struct RSAPublicKey<'a> {
39 pub modulus: &'a [u8],
43 pub exponent: &'a [u8],
47}
48
49impl RSAPublicKey<'_> {
50 pub fn try_exponent(&self) -> Result<u64, X509Error> {
54 let mut buf = [0u8; 8];
55 if self.exponent.is_empty() || self.exponent[0] & 0x80 != 0 || self.exponent.len() > 8 {
56 return Err(X509Error::InvalidNumber);
57 }
58 buf[8_usize.saturating_sub(self.exponent.len())..].copy_from_slice(self.exponent);
59 let int = <u64>::from_be_bytes(buf);
60 Ok(int)
61 }
62
63 pub fn key_size(&self) -> usize {
65 if !self.modulus.is_empty() && self.modulus[0] & 0x80 == 0 {
66 let modulus = &self.modulus[1..];
68 8 * modulus.len()
69 } else {
70 0
71 }
72 }
73}
74
75fn parse_rsa_key(bytes: &[u8]) -> BerResult<RSAPublicKey> {
77 parse_der_sequence_defined_g(move |i, _| {
78 let (i, obj_modulus) = parse_der_integer(i)?;
79 let (i, obj_exponent) = parse_der_integer(i)?;
80 let modulus = obj_modulus.as_slice()?;
81 let exponent = obj_exponent.as_slice()?;
82 let key = RSAPublicKey { modulus, exponent };
83 Ok((i, key))
84 })(bytes)
85}
86
87impl<'a> FromDer<'a, X509Error> for RSAPublicKey<'a> {
88 fn from_der(bytes: &'a [u8]) -> X509Result<'a, Self> {
89 parse_rsa_key(bytes).map_err(|_| nom::Err::Error(X509Error::InvalidSPKI))
90 }
91}
92
93#[derive(Debug, PartialEq, Eq)]
95pub struct ECPoint<'a> {
96 data: &'a [u8],
97}
98
99impl<'a> ECPoint<'a> {
100 pub fn data(&'a self) -> &'a [u8] {
102 self.data
103 }
104
105 pub fn key_size(&self) -> usize {
107 match self.data {
108 [] => {
109 0
111 }
112 [4, rem @ ..] => {
113 rem.len() * 8 / 2
115 }
116 [2..=3, rem @ ..] => {
117 rem.len() * 8
119 }
120 _ => {
121 0
123 }
124 }
125 }
126}
127
128impl<'a> From<&'a [u8]> for ECPoint<'a> {
129 fn from(data: &'a [u8]) -> Self {
130 ECPoint { data }
131 }
132}