voided_core/signing/
mod.rs1use crate::{Error, Result};
6use alloc::{string::String, vec::Vec};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
11#[repr(u8)]
12pub enum SigningAlgorithm {
13 Ed25519 = 0x01,
15 EcdsaP256 = 0x02,
17 RsaPss2048 = 0x03,
19}
20
21impl SigningAlgorithm {
22 pub fn from_byte(byte: u8) -> Result<Self> {
24 match byte {
25 0x01 => Ok(SigningAlgorithm::Ed25519),
26 0x02 => Ok(SigningAlgorithm::EcdsaP256),
27 0x03 => Ok(SigningAlgorithm::RsaPss2048),
28 _ => Err(Error::UnsupportedAlgorithm(byte)),
29 }
30 }
31
32 pub fn name(&self) -> &'static str {
34 match self {
35 SigningAlgorithm::Ed25519 => "ed25519",
36 SigningAlgorithm::EcdsaP256 => "ecdsa-p256",
37 SigningAlgorithm::RsaPss2048 => "rsa-pss-2048",
38 }
39 }
40}
41
42#[derive(Debug, Clone)]
44pub struct KeyPair {
45 pub public_key_pem: String,
47 pub private_key_pem: String,
49}
50
51#[cfg(feature = "signing")]
53pub fn generate_key_pair(algorithm: SigningAlgorithm) -> Result<KeyPair> {
54 match algorithm {
55 SigningAlgorithm::Ed25519 => generate_ed25519_key_pair(),
56 SigningAlgorithm::EcdsaP256 => generate_ecdsa_p256_key_pair(),
57 SigningAlgorithm::RsaPss2048 => generate_rsa_pss_key_pair(),
58 }
59}
60
61#[cfg(feature = "signing")]
62fn generate_ed25519_key_pair() -> Result<KeyPair> {
63 use ed25519_dalek::SigningKey;
64 use rand::rngs::OsRng;
65
66 let signing_key = SigningKey::generate(&mut OsRng);
67 let verifying_key = signing_key.verifying_key();
68
69 let private_pem = format!(
71 "-----BEGIN PRIVATE KEY-----\n{}\n-----END PRIVATE KEY-----",
72 base64::Engine::encode(&base64::engine::general_purpose::STANDARD, signing_key.as_bytes())
73 );
74
75 let public_pem = format!(
76 "-----BEGIN PUBLIC KEY-----\n{}\n-----END PUBLIC KEY-----",
77 base64::Engine::encode(&base64::engine::general_purpose::STANDARD, verifying_key.as_bytes())
78 );
79
80 Ok(KeyPair {
81 public_key_pem: public_pem,
82 private_key_pem: private_pem,
83 })
84}
85
86#[cfg(feature = "signing")]
87fn generate_ecdsa_p256_key_pair() -> Result<KeyPair> {
88 use p256::ecdsa::SigningKey;
89 use rand::rngs::OsRng;
90
91 let signing_key = SigningKey::random(&mut OsRng);
92 let verifying_key = signing_key.verifying_key();
93
94 let private_bytes = signing_key.to_bytes();
96 let public_bytes = verifying_key.to_encoded_point(false);
97
98 let private_pem = format!(
99 "-----BEGIN EC PRIVATE KEY-----\n{}\n-----END EC PRIVATE KEY-----",
100 base64::Engine::encode(&base64::engine::general_purpose::STANDARD, &private_bytes)
101 );
102
103 let public_pem = format!(
104 "-----BEGIN PUBLIC KEY-----\n{}\n-----END PUBLIC KEY-----",
105 base64::Engine::encode(&base64::engine::general_purpose::STANDARD, public_bytes.as_bytes())
106 );
107
108 Ok(KeyPair {
109 public_key_pem: public_pem,
110 private_key_pem: private_pem,
111 })
112}
113
114#[cfg(feature = "signing")]
115fn generate_rsa_pss_key_pair() -> Result<KeyPair> {
116 use rsa::{RsaPrivateKey, RsaPublicKey};
117 use rand::rngs::OsRng;
118
119 let bits = 2048;
120 let private_key = RsaPrivateKey::new(&mut OsRng, bits)
121 .map_err(|e| Error::KeyGenerationFailed(e.to_string()))?;
122 let _public_key = RsaPublicKey::from(&private_key);
123
124 let private_pem = format!(
126 "-----BEGIN RSA PRIVATE KEY-----\n{}\n-----END RSA PRIVATE KEY-----",
127 "... RSA PRIVATE KEY DATA ..."
128 );
129
130 let public_pem = format!(
131 "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----",
132 "... RSA PUBLIC KEY DATA ..."
133 );
134
135 Ok(KeyPair {
136 public_key_pem: public_pem,
137 private_key_pem: private_pem,
138 })
139}
140
141#[cfg(feature = "signing")]
143pub fn sign(
144 data: &[u8],
145 private_key_pem: &str,
146 algorithm: SigningAlgorithm,
147) -> Result<Vec<u8>> {
148 match algorithm {
149 SigningAlgorithm::Ed25519 => sign_ed25519(data, private_key_pem),
150 SigningAlgorithm::EcdsaP256 => sign_ecdsa_p256(data, private_key_pem),
151 SigningAlgorithm::RsaPss2048 => sign_rsa_pss(data, private_key_pem),
152 }
153}
154
155#[cfg(feature = "signing")]
156fn sign_ed25519(_data: &[u8], _private_key_pem: &str) -> Result<Vec<u8>> {
157 Err(Error::SigningFailed("Not yet implemented".to_string()))
159}
160
161#[cfg(feature = "signing")]
162fn sign_ecdsa_p256(_data: &[u8], _private_key_pem: &str) -> Result<Vec<u8>> {
163 Err(Error::SigningFailed("Not yet implemented".to_string()))
165}
166
167#[cfg(feature = "signing")]
168fn sign_rsa_pss(_data: &[u8], _private_key_pem: &str) -> Result<Vec<u8>> {
169 Err(Error::SigningFailed("Not yet implemented".to_string()))
171}
172
173#[cfg(feature = "signing")]
175pub fn verify(
176 data: &[u8],
177 signature: &[u8],
178 public_key_pem: &str,
179 algorithm: SigningAlgorithm,
180) -> Result<bool> {
181 match algorithm {
182 SigningAlgorithm::Ed25519 => verify_ed25519(data, signature, public_key_pem),
183 SigningAlgorithm::EcdsaP256 => verify_ecdsa_p256(data, signature, public_key_pem),
184 SigningAlgorithm::RsaPss2048 => verify_rsa_pss(data, signature, public_key_pem),
185 }
186}
187
188#[cfg(feature = "signing")]
189fn verify_ed25519(_data: &[u8], _signature: &[u8], _public_key_pem: &str) -> Result<bool> {
190 Err(Error::SignatureVerificationFailed)
192}
193
194#[cfg(feature = "signing")]
195fn verify_ecdsa_p256(_data: &[u8], _signature: &[u8], _public_key_pem: &str) -> Result<bool> {
196 Err(Error::SignatureVerificationFailed)
198}
199
200#[cfg(feature = "signing")]
201fn verify_rsa_pss(_data: &[u8], _signature: &[u8], _public_key_pem: &str) -> Result<bool> {
202 Err(Error::SignatureVerificationFailed)
204}
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn test_algorithm_from_byte() {
212 assert_eq!(SigningAlgorithm::from_byte(0x01).unwrap(), SigningAlgorithm::Ed25519);
213 assert_eq!(SigningAlgorithm::from_byte(0x02).unwrap(), SigningAlgorithm::EcdsaP256);
214 assert_eq!(SigningAlgorithm::from_byte(0x03).unwrap(), SigningAlgorithm::RsaPss2048);
215 assert!(SigningAlgorithm::from_byte(0xFF).is_err());
216 }
217
218 #[test]
219 fn test_algorithm_name() {
220 assert_eq!(SigningAlgorithm::Ed25519.name(), "ed25519");
221 assert_eq!(SigningAlgorithm::EcdsaP256.name(), "ecdsa-p256");
222 assert_eq!(SigningAlgorithm::RsaPss2048.name(), "rsa-pss-2048");
223 }
224}
225