rustls_mbedcrypto_provider/
signature_verify_algo.rs

1use super::hash::Algorithm as HashAlgorithm;
2use alloc::vec;
3use mbedtls::pk::{EcGroupId, Pk};
4use rustls::pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm};
5use rustls::SignatureScheme;
6use webpki::alg_id;
7
8/// ECDSA signatures using the P-256 curve and SHA-256.
9pub static ECDSA_P256_SHA256: &Algorithm = &Algorithm {
10    signature_scheme: SignatureScheme::ECDSA_NISTP256_SHA256,
11    hash_algo: &super::hash::MBED_SHA_256,
12    public_key_alg_id: alg_id::ECDSA_P256,
13    ec_group_id: Some(EcGroupId::SecP256R1),
14    signature_alg_id: alg_id::ECDSA_SHA256,
15};
16/// ECDSA signatures using the P-384 curve and SHA-256.
17pub static ECDSA_P384_SHA256: &Algorithm = &Algorithm {
18    signature_scheme: SignatureScheme::ECDSA_NISTP256_SHA256,
19    hash_algo: &super::hash::MBED_SHA_256,
20    public_key_alg_id: alg_id::ECDSA_P384,
21    ec_group_id: Some(EcGroupId::SecP384R1),
22    signature_alg_id: alg_id::ECDSA_SHA256,
23};
24/// ECDSA signatures using the P-384 curve and SHA-384.
25pub static ECDSA_P384_SHA384: &Algorithm = &Algorithm {
26    signature_scheme: SignatureScheme::ECDSA_NISTP384_SHA384,
27    hash_algo: &super::hash::MBED_SHA_384,
28    public_key_alg_id: alg_id::ECDSA_P384,
29    ec_group_id: Some(EcGroupId::SecP384R1),
30    signature_alg_id: alg_id::ECDSA_SHA384,
31};
32/// ECDSA signatures using the P-256 curve and SHA-384.
33pub static ECDSA_P256_SHA384: &Algorithm = &Algorithm {
34    signature_scheme: SignatureScheme::ECDSA_NISTP384_SHA384,
35    hash_algo: &super::hash::MBED_SHA_384,
36    public_key_alg_id: alg_id::ECDSA_P256,
37    ec_group_id: Some(EcGroupId::SecP256R1),
38    signature_alg_id: alg_id::ECDSA_SHA384,
39};
40/// ECDSA signatures using the P-512 curve and SHA-512.
41pub static ECDSA_P521_SHA512: &Algorithm = &Algorithm {
42    signature_scheme: SignatureScheme::ECDSA_NISTP521_SHA512,
43    hash_algo: &super::hash::MBED_SHA_512,
44    public_key_alg_id: alg_id::ECDSA_P521,
45    ec_group_id: Some(EcGroupId::SecP521R1),
46    signature_alg_id: alg_id::ECDSA_SHA512,
47};
48/// RSA PKCS#1 1.5 signatures using SHA-256.
49pub static RSA_PKCS1_SHA256: &Algorithm = &Algorithm {
50    signature_scheme: SignatureScheme::RSA_PKCS1_SHA256,
51    hash_algo: &super::hash::MBED_SHA_256,
52    public_key_alg_id: alg_id::RSA_ENCRYPTION,
53    ec_group_id: None,
54    signature_alg_id: alg_id::RSA_PKCS1_SHA256,
55};
56/// RSA PKCS#1 1.5 signatures using SHA-384.
57pub static RSA_PKCS1_SHA384: &Algorithm = &Algorithm {
58    signature_scheme: SignatureScheme::RSA_PKCS1_SHA384,
59    hash_algo: &super::hash::MBED_SHA_384,
60    public_key_alg_id: alg_id::RSA_ENCRYPTION,
61    ec_group_id: None,
62    signature_alg_id: alg_id::RSA_PKCS1_SHA384,
63};
64/// RSA PKCS#1 1.5 signatures using SHA-512.
65pub static RSA_PKCS1_SHA512: &Algorithm = &Algorithm {
66    signature_scheme: SignatureScheme::RSA_PKCS1_SHA512,
67    hash_algo: &super::hash::MBED_SHA_512,
68    public_key_alg_id: alg_id::RSA_ENCRYPTION,
69    ec_group_id: None,
70    signature_alg_id: alg_id::RSA_PKCS1_SHA512,
71};
72/// RSA PSS signatures using SHA-256 and of
73/// type rsaEncryption; see [RFC 4055 Section 1.2].
74///
75/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
76pub static RSA_PSS_SHA256: &Algorithm = &Algorithm {
77    signature_scheme: SignatureScheme::RSA_PSS_SHA256,
78    hash_algo: &super::hash::MBED_SHA_256,
79    public_key_alg_id: alg_id::RSA_ENCRYPTION,
80    ec_group_id: None,
81    signature_alg_id: alg_id::RSA_PSS_SHA256,
82};
83/// RSA PSS signatures using SHA-384 and of
84/// type rsaEncryption; see [RFC 4055 Section 1.2].
85///
86/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
87pub static RSA_PSS_SHA384: &Algorithm = &Algorithm {
88    signature_scheme: SignatureScheme::RSA_PSS_SHA384,
89    hash_algo: &super::hash::MBED_SHA_384,
90    public_key_alg_id: alg_id::RSA_ENCRYPTION,
91    ec_group_id: None,
92    signature_alg_id: alg_id::RSA_PSS_SHA384,
93};
94/// RSA PSS signatures using SHA-512 and of
95/// type rsaEncryption; see [RFC 4055 Section 1.2].
96///
97/// [RFC 4055 Section 1.2]: https://tools.ietf.org/html/rfc4055#section-1.2
98pub static RSA_PSS_SHA512: &Algorithm = &Algorithm {
99    signature_scheme: SignatureScheme::RSA_PSS_SHA512,
100    hash_algo: &super::hash::MBED_SHA_512,
101    public_key_alg_id: alg_id::RSA_ENCRYPTION,
102    ec_group_id: None,
103    signature_alg_id: alg_id::RSA_PSS_SHA512,
104};
105
106/// A signature verify algorithm type
107#[derive(Clone, Debug, PartialEq)]
108pub struct Algorithm {
109    signature_scheme: SignatureScheme,
110    hash_algo: &'static HashAlgorithm,
111    public_key_alg_id: AlgorithmIdentifier,
112    ec_group_id: Option<EcGroupId>,
113    signature_alg_id: AlgorithmIdentifier,
114}
115
116impl SignatureVerificationAlgorithm for Algorithm {
117    fn verify_signature(&self, public_key: &[u8], message: &[u8], signature: &[u8]) -> Result<(), InvalidSignature> {
118        let mut pk = match self.ec_group_id {
119            None => Pk::from_public_key(public_key).map_err(|_| InvalidSignature)?,
120            Some(ec_group_id) => {
121                let spki = yasna::construct_der(|writer| {
122                    writer.write_sequence(|writer| {
123                        writer.next().write_sequence(|w| {
124                            w.next()
125                                .write_der(&self.public_key_alg_id)
126                        });
127                        writer
128                            .next()
129                            .write_bitvec(&bit_vec::BitVec::from_bytes(public_key));
130                    })
131                });
132                let ec_pk = Pk::from_public_key(&spki).map_err(|_| InvalidSignature)?;
133                let curves_match = ec_pk
134                    .curve()
135                    .is_ok_and(|pk_curve| pk_curve == ec_group_id);
136                if !curves_match {
137                    return Err(InvalidSignature);
138                };
139                ec_pk
140            }
141        };
142
143        if let Some(opts) = utils::pk::rustls_signature_scheme_to_mbedtls_pk_options(self.signature_scheme) {
144            pk.set_options(opts);
145        }
146        let mut hash = vec![0u8; self.hash_algo.output_len];
147        mbedtls::hash::Md::hash(self.hash_algo.hash_type, message, &mut hash).map_err(|_| InvalidSignature)?;
148        pk.verify(self.hash_algo.hash_type, &hash, signature)
149            .map_err(|_| InvalidSignature)
150    }
151
152    fn public_key_alg_id(&self) -> AlgorithmIdentifier {
153        self.public_key_alg_id
154    }
155
156    fn signature_alg_id(&self) -> AlgorithmIdentifier {
157        self.signature_alg_id
158    }
159}