Skip to main content

tss_esapi/abstraction/
signatures.rs

1// Copyright 2024 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    structures::{EccSignature, Signature},
6    Error, Result, WrapperErrorKind,
7};
8
9use std::convert::TryFrom;
10
11use ecdsa::SignatureSize;
12use elliptic_curve::{
13    generic_array::{typenum::Unsigned, ArrayLength},
14    FieldBytes, FieldBytesSize, PrimeCurve,
15};
16
17impl<C> TryFrom<&EccSignature> for ecdsa::Signature<C>
18where
19    C: PrimeCurve,
20    SignatureSize<C>: ArrayLength<u8>,
21{
22    type Error = Error;
23
24    fn try_from(signature: &EccSignature) -> Result<Self> {
25        let r = signature.signature_r().as_slice();
26        let s = signature.signature_s().as_slice();
27
28        if r.len() != FieldBytesSize::<C>::USIZE {
29            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
30        }
31        if s.len() != FieldBytesSize::<C>::USIZE {
32            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
33        }
34
35        let signature = ecdsa::Signature::from_scalars(
36            FieldBytes::<C>::clone_from_slice(r),
37            FieldBytes::<C>::clone_from_slice(s),
38        )
39        .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))?;
40        Ok(signature)
41    }
42}
43
44impl<C> TryFrom<&Signature> for ecdsa::Signature<C>
45where
46    C: PrimeCurve,
47    SignatureSize<C>: ArrayLength<u8>,
48{
49    type Error = Error;
50
51    fn try_from(signature: &Signature) -> Result<Self> {
52        let Signature::EcDsa(signature) = signature else {
53            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
54        };
55        Self::try_from(signature)
56    }
57}
58
59// Note: this does not implement `TryFrom<RsaSignature>` because `RsaSignature` does not carry the
60// information whether the signatures was generated using PKCS#1v1.5 or PSS.
61#[cfg(feature = "rsa")]
62impl TryFrom<&Signature> for rsa::pkcs1v15::Signature {
63    type Error = Error;
64
65    fn try_from(signature: &Signature) -> Result<Self> {
66        let Signature::RsaSsa(signature) = signature else {
67            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
68        };
69
70        Self::try_from(signature.signature().as_bytes())
71            .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))
72    }
73}
74
75// Note: this does not implement `TryFrom<RsaSignature>` because `RsaSignature` does not carry the
76// information whether the signatures was generated using PKCS#1v1.5 or PSS.
77#[cfg(feature = "rsa")]
78impl TryFrom<&Signature> for rsa::pss::Signature {
79    type Error = Error;
80
81    fn try_from(signature: &Signature) -> Result<Self> {
82        let Signature::RsaPss(signature) = signature else {
83            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
84        };
85
86        Self::try_from(signature.signature().as_bytes())
87            .map_err(|_| Error::local_error(WrapperErrorKind::InvalidParam))
88    }
89}