use super::*;
#[derive(
Debug, PartialEq, Clone, Serialize, Deserialize, TlsDeserialize, TlsSerialize, TlsSize,
)]
pub struct Signature {
value: TlsByteVecU16,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(any(feature = "test-utils", test), derive(PartialEq))]
pub struct SignaturePrivateKey {
signature_scheme: SignatureScheme,
value: Vec<u8>,
}
#[derive(Eq, PartialEq, Hash, Debug, Clone, Serialize, Deserialize)]
pub struct SignaturePublicKey {
signature_scheme: SignatureScheme,
pub(in crate::ciphersuite) value: Vec<u8>,
}
#[derive(Debug, Clone)]
pub struct SignatureKeypair {
private_key: SignaturePrivateKey,
public_key: SignaturePublicKey,
}
#[cfg(test)]
impl Signature {
pub(crate) fn modify(&mut self, value: &[u8]) {
self.value = value.to_vec().into();
}
pub(crate) fn as_slice(&self) -> &[u8] {
self.value.as_slice()
}
}
impl<T> SignedStruct<T> for Signature {
fn from_payload(_payload: T, signature: Signature) -> Self {
signature
}
}
impl SignatureKeypair {
#[cfg(feature = "crypto-subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "crypto-subtle")))]
pub fn from_bytes(
signature_scheme: SignatureScheme,
private_key: Vec<u8>,
public_key: Vec<u8>,
) -> Self {
Self {
private_key: SignaturePrivateKey {
signature_scheme,
value: private_key,
},
public_key: SignaturePublicKey {
signature_scheme,
value: public_key,
},
}
}
pub fn into_tuple(self) -> (SignaturePrivateKey, SignaturePublicKey) {
(self.private_key, self.public_key)
}
}
#[cfg(test)]
impl SignatureKeypair {
pub fn sign(
&self,
backend: &impl OpenMlsCryptoProvider,
payload: &[u8],
) -> Result<Signature, CryptoError> {
self.private_key.sign(backend, payload)
}
pub fn verify(
&self,
backend: &impl OpenMlsCryptoProvider,
signature: &Signature,
payload: &[u8],
) -> Result<(), CryptoError> {
self.public_key.verify(backend, signature, payload)
}
}
impl SignatureKeypair {
pub fn new(
signature_scheme: SignatureScheme,
backend: &impl OpenMlsCryptoProvider,
) -> Result<SignatureKeypair, CryptoError> {
let (sk, pk) = backend
.crypto()
.signature_key_gen(signature_scheme)
.map_err(|_| CryptoError::CryptoLibraryError)?;
Ok(SignatureKeypair {
private_key: SignaturePrivateKey {
value: sk,
signature_scheme,
},
public_key: SignaturePublicKey {
value: pk,
signature_scheme,
},
})
}
#[cfg(any(feature = "test-utils", test))]
pub fn from_parts(public_key: SignaturePublicKey, private_key: SignaturePrivateKey) -> Self {
Self {
private_key,
public_key,
}
}
}
impl SignaturePublicKey {
pub fn new(bytes: Vec<u8>, signature_scheme: SignatureScheme) -> Result<Self, CryptoError> {
Ok(Self {
value: bytes,
signature_scheme,
})
}
pub fn verify(
&self,
backend: &impl OpenMlsCryptoProvider,
signature: &Signature,
payload: &[u8],
) -> Result<(), CryptoError> {
backend
.crypto()
.verify_signature(
self.signature_scheme,
payload,
&self.value,
signature.value.as_slice(),
)
.map_err(|_| CryptoError::InvalidSignature)
}
pub fn signature_scheme(&self) -> SignatureScheme {
self.signature_scheme
}
pub fn as_slice(&self) -> &[u8] {
&self.value
}
}
impl SignaturePrivateKey {
pub fn sign(
&self,
backend: &impl OpenMlsCryptoProvider,
payload: &[u8],
) -> Result<Signature, CryptoError> {
match backend
.crypto()
.sign(self.signature_scheme, payload, &self.value)
{
Ok(s) => Ok(Signature { value: s.into() }),
Err(_) => Err(CryptoError::CryptoLibraryError),
}
}
#[cfg(test)]
pub fn signature_scheme(&self) -> SignatureScheme {
self.signature_scheme
}
#[cfg(feature = "crypto-subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "crypto-subtle")))]
pub fn as_slice(&self) -> &[u8] {
&self.value
}
}