1use super::{
4 der::{self, Tag},
5 Error, SignatureScheme,
6};
7
8use ring::signature;
9
10#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub enum Restrictions {
13 None,
15 TLSv12,
18 TLSv13,
21}
22
23impl Default for Restrictions {
24 fn default() -> Self { Self::None }
25}
26
27#[derive(Debug, Copy, Clone)]
29pub struct SubjectPublicKeyInfo<'a> {
30 spki: &'a [u8],
31 algorithm: &'a [u8],
32 key: &'a [u8],
33}
34
35impl<'a> SubjectPublicKeyInfo<'a> {
36 pub fn spki(&self) -> &'a [u8] { self.spki }
38 pub fn algorithm(&self) -> &'a [u8] { self.algorithm }
40 pub fn key(&self) -> &'a [u8] { self.key }
42 pub fn read(input: &mut untrusted::Reader<'a>) -> Result<Self, Error> {
44 let (spki, (algorithm, key)) = input.read_partial(|input| {
45 der::nested(input, Tag::Sequence, Error::BadDER, |input| {
46 let algorithm = der::expect_tag_and_get_value(input, Tag::Sequence)
47 .map_err(|_| Error::BadDER)?;
48 let key = der::bit_string_with_no_unused_bits(input).map_err(|_| Error::BadDER)?;
49 Ok((algorithm.as_slice_less_safe(), key.as_slice_less_safe()))
50 })
51 })?;
52 Ok(Self {
53 spki: spki.as_slice_less_safe(),
54 algorithm,
55 key,
56 })
57 }
58
59 pub fn check_signature(
63 &self, algorithm: SignatureScheme, message: &[u8], signature: &[u8],
64 restrictions: Restrictions,
65 ) -> Result<(), Error> {
66 self.public_key(algorithm, restrictions)?
67 .verify(message, signature)
68 .map_err(|_| Error::InvalidSignatureForPublicKey)
69 }
70
71 pub fn public_key(
75 &self, algorithm: SignatureScheme, restrictions: Restrictions,
76 ) -> Result<signature::UnparsedPublicKey<&'a [u8]>, Error> {
77 use signature as s;
78 #[cfg(feature = "rsa")]
79 use Restrictions::TLSv12;
80 use Restrictions::TLSv13;
81 let algorithm: &'static dyn s::VerificationAlgorithm = match algorithm {
82 #[cfg(feature = "rsa")]
83 SignatureScheme::RSA_PKCS1_SHA256 if restrictions != TLSv13 => match self.algorithm {
84 include_bytes!("data/alg-rsa-encryption.der") => (&s::RSA_PKCS1_2048_8192_SHA256),
85 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
86 },
87 #[cfg(feature = "rsa")]
88 SignatureScheme::RSA_PKCS1_SHA384 if restrictions != TLSv13 => match self.algorithm {
89 include_bytes!("data/alg-rsa-encryption.der") => (&s::RSA_PKCS1_2048_8192_SHA384),
90 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
91 },
92 #[cfg(feature = "rsa")]
93 SignatureScheme::RSA_PKCS1_SHA512 if restrictions != TLSv13 => match self.algorithm {
94 include_bytes!("data/alg-rsa-encryption.der") => &s::RSA_PKCS1_2048_8192_SHA512,
95 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
96 },
97 SignatureScheme::ECDSA_NISTP256_SHA256 => match self.algorithm {
98 include_bytes!("data/alg-ecdsa-p256.der") => &s::ECDSA_P256_SHA256_ASN1,
99 include_bytes!("data/alg-ecdsa-p384.der") if restrictions != TLSv13 =>
100 &s::ECDSA_P384_SHA256_ASN1,
101 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
102 },
103 SignatureScheme::ECDSA_NISTP384_SHA384 => match self.algorithm {
104 include_bytes!("data/alg-ecdsa-p384.der") => &s::ECDSA_P384_SHA384_ASN1,
105 include_bytes!("data/alg-ecdsa-p256.der") if restrictions != TLSv13 =>
106 &s::ECDSA_P256_SHA384_ASN1,
107 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
108 },
109 SignatureScheme::ED25519 => match self.algorithm {
110 include_bytes!("data/alg-ed25519.der") => &s::ED25519,
111 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
112 },
113 #[cfg(feature = "rsa")]
114 SignatureScheme::RSA_PSS_SHA256 if restrictions != TLSv12 => match self.algorithm {
115 include_bytes!("data/alg-rsa-encryption.der") => &s::RSA_PSS_2048_8192_SHA256,
116 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
117 },
118 #[cfg(feature = "rsa")]
119 SignatureScheme::RSA_PSS_SHA384 if restrictions != TLSv12 => match self.algorithm {
120 include_bytes!("data/alg-rsa-encryption.der") => &s::RSA_PSS_2048_8192_SHA384,
121 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
122 },
123 #[cfg(feature = "rsa")]
124 SignatureScheme::RSA_PSS_SHA512 if restrictions != TLSv12 => match self.algorithm {
125 include_bytes!("data/alg-rsa-encryption.der") => &s::RSA_PSS_2048_8192_SHA512,
126 _ => return Err(Error::UnsupportedSignatureAlgorithmForPublicKey),
127 },
128 _ => return Err(Error::UnsupportedSignatureAlgorithm),
129 };
130 Ok(s::UnparsedPublicKey::new(algorithm, self.key))
131 }
132
133 pub fn get_public_key_x509(
135 &self, algorithm_id: &[u8],
136 ) -> Result<ring::signature::UnparsedPublicKey<&'a [u8]>, Error> {
137 self.public_key(parse_algorithmid(algorithm_id)?, Restrictions::None)
138 }
139}
140
141const RSASSA_PSS_PREFIX: &[u8; 11] = include_bytes!("data/alg-rsa-pss.der");
142
143pub fn parse_algorithmid(asn1: &[u8]) -> Result<SignatureScheme, Error> {
146 match asn1 {
147 include_bytes!("data/alg-rsa-pkcs1-sha256.der") => Ok(SignatureScheme::RSA_PKCS1_SHA256),
148 include_bytes!("data/alg-rsa-pkcs1-sha384.der") => Ok(SignatureScheme::RSA_PKCS1_SHA384),
149 include_bytes!("data/alg-rsa-pkcs1-sha512.der") => Ok(SignatureScheme::RSA_PKCS1_SHA512),
150 include_bytes!("data/alg-ecdsa-sha256.der") => Ok(SignatureScheme::ECDSA_NISTP256_SHA256),
151 include_bytes!("data/alg-ecdsa-sha384.der") => Ok(SignatureScheme::ECDSA_NISTP384_SHA384),
152 include_bytes!("data/alg-ed25519.der") => Ok(SignatureScheme::ED25519),
153 e if e.starts_with(&RSASSA_PSS_PREFIX[..]) => match &e[RSASSA_PSS_PREFIX.len()..] {
154 include_bytes!("data/alg-rsa-pss-sha256-v0.der")
155 | include_bytes!("data/alg-rsa-pss-sha256-v1.der")
156 | include_bytes!("data/alg-rsa-pss-sha256-v2.der")
157 | include_bytes!("data/alg-rsa-pss-sha256-v3.der") =>
158 Ok(SignatureScheme::RSA_PSS_SHA256),
159
160 include_bytes!("data/alg-rsa-pss-sha384-v0.der")
161 | include_bytes!("data/alg-rsa-pss-sha384-v1.der")
162 | include_bytes!("data/alg-rsa-pss-sha384-v2.der")
163 | include_bytes!("data/alg-rsa-pss-sha384-v3.der") =>
164 Ok(SignatureScheme::RSA_PSS_SHA384),
165
166 include_bytes!("data/alg-rsa-pss-sha512-v0.der")
167 | include_bytes!("data/alg-rsa-pss-sha512-v1.der")
168 | include_bytes!("data/alg-rsa-pss-sha512-v2.der")
169 | include_bytes!("data/alg-rsa-pss-sha512-v3.der") =>
170 Ok(SignatureScheme::RSA_PSS_SHA512),
171 _ => Err(Error::UnsupportedSignatureAlgorithm),
172 },
173 _ => Err(Error::UnsupportedSignatureAlgorithm),
174 }
175}