openmls_basic_credential/
lib.rs1use std::fmt::Debug;
8
9use openmls_traits::{
10 signatures::{Signer, SignerError},
11 storage::{self, StorageProvider, CURRENT_VERSION},
12 types::{CryptoError, SignatureScheme},
13};
14
15use p256::ecdsa::{signature::Signer as P256Signer, Signature, SigningKey};
16
17use rand::rngs::OsRng;
18use serde::{Deserialize, Serialize};
19use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize};
20
21#[derive(
26 TlsSerialize, TlsSize, TlsDeserialize, TlsDeserializeBytes, serde::Serialize, serde::Deserialize,
27)]
28#[cfg_attr(feature = "clonable", derive(Clone))]
29pub struct SignatureKeyPair {
30 private: Vec<u8>,
31 public: Vec<u8>,
32 signature_scheme: SignatureScheme,
33}
34
35impl Debug for SignatureKeyPair {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 f.debug_struct("SignatureKeyPair")
38 .field("private", &"***".to_string())
39 .field("public", &self.public)
40 .field("signature_scheme", &self.signature_scheme)
41 .finish()
42 }
43}
44
45impl Signer for SignatureKeyPair {
46 fn sign(&self, payload: &[u8]) -> Result<Vec<u8>, SignerError> {
47 match self.signature_scheme {
48 SignatureScheme::ECDSA_SECP256R1_SHA256 => {
49 let k = SigningKey::from_bytes(self.private.as_slice().into())
50 .map_err(|_| SignerError::SigningError)?;
51 let signature: Signature = k.sign(payload);
52 Ok(signature.to_der().to_bytes().into())
53 }
54 SignatureScheme::ED25519 => {
55 let k = ed25519_dalek::SigningKey::try_from(self.private.as_slice())
56 .map_err(|_| SignerError::SigningError)?;
57 let signature = k.sign(payload);
58 Ok(signature.to_bytes().into())
59 }
60 _ => Err(SignerError::SigningError),
61 }
62 }
63
64 fn signature_scheme(&self) -> SignatureScheme {
65 self.signature_scheme
66 }
67}
68
69fn id(public_key: &[u8], signature_scheme: SignatureScheme) -> Vec<u8> {
71 const LABEL: &[u8; 22] = b"RustCryptoSignatureKey";
72 let mut id = public_key.to_vec();
73 id.extend_from_slice(LABEL);
74 let signature_scheme = (signature_scheme as u16).to_be_bytes();
75 id.extend_from_slice(&signature_scheme);
76 id
77}
78
79impl SignatureKeyPair {
80 pub fn new(signature_scheme: SignatureScheme) -> Result<Self, CryptoError> {
82 let (private, public) = match signature_scheme {
83 SignatureScheme::ECDSA_SECP256R1_SHA256 => {
84 let k = SigningKey::random(&mut OsRng);
85 let pk = k.verifying_key().to_encoded_point(false).as_bytes().into();
86 (k.to_bytes().as_slice().into(), pk)
87 }
88 SignatureScheme::ED25519 => {
89 let sk = ed25519_dalek::SigningKey::generate(&mut OsRng);
90 let pk = sk.verifying_key().to_bytes().into();
91 (sk.to_bytes().into(), pk)
92 }
93 _ => return Err(CryptoError::UnsupportedSignatureScheme),
94 };
95
96 Ok(Self {
97 private,
98 public,
99 signature_scheme,
100 })
101 }
102
103 pub fn from_raw(signature_scheme: SignatureScheme, private: Vec<u8>, public: Vec<u8>) -> Self {
105 Self {
106 private,
107 public,
108 signature_scheme,
109 }
110 }
111
112 pub fn id(&self) -> StorageId {
113 StorageId {
114 value: id(&self.public, self.signature_scheme),
115 }
116 }
117
118 pub fn store<T>(&self, store: &T) -> Result<(), T::Error>
120 where
121 T: StorageProvider<CURRENT_VERSION>,
122 {
123 store.write_signature_key_pair(&self.id(), self)
124 }
125
126 pub fn read(
128 store: &impl StorageProvider<CURRENT_VERSION>,
129 public_key: &[u8],
130 signature_scheme: SignatureScheme,
131 ) -> Option<Self> {
132 store
133 .signature_key_pair(&StorageId {
134 value: id(public_key, signature_scheme),
135 })
136 .ok()
137 .flatten()
138 }
139
140 pub fn delete<T: StorageProvider<CURRENT_VERSION>>(
142 store: &T,
143 public_key: &[u8],
144 signature_scheme: SignatureScheme,
145 ) -> Result<(), T::Error> {
146 let id = StorageId {
147 value: id(public_key, signature_scheme),
148 };
149 store.delete_signature_key_pair(&id)
150 }
151
152 pub fn public(&self) -> &[u8] {
154 self.public.as_ref()
155 }
156
157 pub fn to_public_vec(&self) -> Vec<u8> {
159 self.public.clone()
160 }
161
162 pub fn signature_scheme(&self) -> SignatureScheme {
164 self.signature_scheme
165 }
166
167 #[cfg(feature = "test-utils")]
168 pub fn private(&self) -> &[u8] {
169 &self.private
170 }
171}
172
173#[derive(Debug, Serialize, Deserialize)]
176pub struct StorageId {
177 value: Vec<u8>,
178}
179
180impl From<Vec<u8>> for StorageId {
181 fn from(vec: Vec<u8>) -> Self {
182 StorageId { value: vec }
183 }
184}
185
186impl storage::Key<CURRENT_VERSION> for StorageId {}
188impl storage::traits::SignaturePublicKey<CURRENT_VERSION> for StorageId {}
189
190impl storage::Entity<CURRENT_VERSION> for SignatureKeyPair {}
192impl storage::traits::SignatureKeyPair<CURRENT_VERSION> for SignatureKeyPair {}