1use std::ops::Deref;
6
7use mls_rs_core::crypto::{CipherSuite, SignaturePublicKey, SignatureSecretKey};
8use mls_rs_crypto_traits::Curve;
9use openssl::hash::MessageDigest;
10
11#[cfg(feature = "x509")]
12use openssl::pkey::{PKey, Private, Public};
13
14use thiserror::Error;
15
16use crate::ec::{
17 curve_from_private_key, curve_from_public_key, generate_keypair, private_key_bytes_to_public,
18 private_key_from_bytes, private_key_from_der, private_key_to_bytes, pub_key_from_uncompressed,
19 pub_key_to_uncompressed, public_key_from_der, EcError,
20};
21
22#[derive(Debug, Error)]
23pub enum EcSignerError {
24 #[error(transparent)]
25 OpensslError(#[from] openssl::error::ErrorStack),
26 #[error(transparent)]
27 EcError(#[from] EcError),
28 #[error("invalid signature")]
29 InvalidSignature,
30}
31
32#[derive(Clone, Debug, Copy, PartialEq, Eq)]
33pub struct EcSigner(Curve);
34
35impl Deref for EcSigner {
36 type Target = Curve;
37
38 fn deref(&self) -> &Self::Target {
39 &self.0
40 }
41}
42
43impl EcSigner {
44 pub fn new(cipher_suite: CipherSuite) -> Option<Self> {
45 Curve::from_ciphersuite(cipher_suite, true).map(Self)
46 }
47
48 pub fn signature_key_generate(
49 &self,
50 ) -> Result<(SignatureSecretKey, SignaturePublicKey), EcSignerError> {
51 let key_pair = generate_keypair(self.0)?;
52 Ok((key_pair.secret.into(), key_pair.public.into()))
53 }
54
55 pub fn signature_key_import_der_public(
56 &self,
57 der_data: &[u8],
58 ) -> Result<SignaturePublicKey, EcError> {
59 let key = public_key_from_der(der_data)?;
60
61 curve_from_public_key(&key)
62 .filter(|&c| c == self.0)
63 .ok_or(EcError::InvalidKeyBytes)?;
64
65 Ok(pub_key_to_uncompressed(&key)?.into())
66 }
67
68 pub fn signature_key_import_der_private(
69 &self,
70 der_data: &[u8],
71 ) -> Result<SignatureSecretKey, EcError> {
72 let key = private_key_from_der(der_data)?;
73
74 curve_from_private_key(&key)
75 .filter(|&c| c == self.0)
76 .ok_or(EcError::InvalidKeyBytes)?;
77
78 Ok(private_key_to_bytes(&key)?.into())
79 }
80
81 pub fn signature_key_derive_public(
82 &self,
83 secret_key: &SignatureSecretKey,
84 ) -> Result<SignaturePublicKey, EcSignerError> {
85 Ok(private_key_bytes_to_public(secret_key, self.0)?.into())
86 }
87
88 #[cfg(feature = "x509")]
89 pub(crate) fn pkey_from_secret_key(
90 &self,
91 key: &SignatureSecretKey,
92 ) -> Result<PKey<Private>, EcSignerError> {
93 private_key_from_bytes(key, self.0, true).map_err(Into::into)
94 }
95
96 #[cfg(feature = "x509")]
97 pub(crate) fn pkey_from_public_key(
98 &self,
99 key: &SignaturePublicKey,
100 ) -> Result<PKey<Public>, EcSignerError> {
101 pub_key_from_uncompressed(key, self.0).map_err(Into::into)
102 }
103
104 pub fn sign(
105 &self,
106 secret_key: &SignatureSecretKey,
107 data: &[u8],
108 ) -> Result<Vec<u8>, EcSignerError> {
109 let secret_key = private_key_from_bytes(secret_key, self.0, false)?;
110
111 let mut signer = match self.message_digest() {
112 Some(md) => openssl::sign::Signer::new(md, &secret_key),
113 None => openssl::sign::Signer::new_without_digest(&secret_key),
114 }?;
115
116 Ok(signer.sign_oneshot_to_vec(data)?)
117 }
118
119 pub fn verify(
120 &self,
121 public_key: &SignaturePublicKey,
122 signature: &[u8],
123 data: &[u8],
124 ) -> Result<(), EcSignerError> {
125 let public_key = pub_key_from_uncompressed(public_key, self.0)?;
126
127 let mut verifier = match self.message_digest() {
128 Some(md) => openssl::sign::Verifier::new(md, &public_key),
129 None => openssl::sign::Verifier::new_without_digest(&public_key),
130 }?;
131
132 verifier
133 .verify_oneshot(signature, data)?
134 .then_some(())
135 .ok_or(EcSignerError::InvalidSignature)
136 }
137
138 pub(crate) fn message_digest(&self) -> Option<MessageDigest> {
139 match self.0 {
140 Curve::P256 => Some(MessageDigest::sha256()),
141 Curve::P384 => Some(MessageDigest::sha384()),
142 Curve::P521 => Some(MessageDigest::sha512()),
143 _ => None,
144 }
145 }
146}
147
148#[cfg(test)]
149mod test {
150 use mls_rs_crypto_traits::Curve;
151
152 use crate::{
153 ec::test_utils::{
154 get_test_public_keys, get_test_public_keys_der, get_test_secret_keys,
155 get_test_secret_keys_der, TestKeys,
156 },
157 ec_signer::EcSigner,
158 };
159
160 #[test]
161 fn import_der_public() {
162 let keys = get_test_public_keys();
163 let der_keys = get_test_public_keys_der();
164
165 let convert = |keys: &TestKeys, curve: Curve| {
166 EcSigner(curve)
167 .signature_key_import_der_public(&keys.get_key_from_curve(curve))
168 .unwrap()
169 };
170
171 let converted = TestKeys {
172 p256: convert(&der_keys, Curve::P256).to_vec(),
173 p384: convert(&der_keys, Curve::P384).to_vec(),
174 p521: convert(&der_keys, Curve::P521).to_vec(),
175 x25519: convert(&der_keys, Curve::X25519).to_vec(),
176 ed25519: convert(&der_keys, Curve::Ed25519).to_vec(),
177 x448: convert(&der_keys, Curve::X448).to_vec(),
178 ed448: convert(&der_keys, Curve::Ed448).to_vec(),
179 };
180
181 assert_eq!(keys, converted);
182 }
183
184 #[test]
185 fn import_der_private() {
186 let keys = get_test_secret_keys();
187 let der_keys = get_test_secret_keys_der();
188
189 let convert = |keys: &TestKeys, curve: Curve| {
190 EcSigner(curve)
191 .signature_key_import_der_private(&keys.get_key_from_curve(curve))
192 .unwrap()
193 };
194
195 let converted = TestKeys {
196 p256: convert(&der_keys, Curve::P256).to_vec(),
197 p384: convert(&der_keys, Curve::P384).to_vec(),
198 p521: convert(&der_keys, Curve::P521).to_vec(),
199 x25519: convert(&der_keys, Curve::X25519).to_vec(),
200 ed25519: convert(&der_keys, Curve::Ed25519).to_vec(),
201 x448: convert(&der_keys, Curve::X448).to_vec(),
202 ed448: convert(&der_keys, Curve::Ed448).to_vec(),
203 };
204
205 assert_eq!(keys, converted);
206 }
207}