Skip to main content

crypto/
p256.rs

1// SPDX-License-Identifier: Apache-2.0
2//! P-256 (ECDSA) signature implementation.
3
4use p256::{
5    SecretKey,
6    ecdsa::{
7        Signature, SigningKey, VerifyingKey,
8        signature::{Signer as SignatureSigner, Verifier as SignatureVerifier},
9    },
10};
11use pkcs8::DecodePrivateKey;
12use rsa::{pkcs1::DecodeRsaPrivateKey, rand_core::OsRng};
13
14use crate::{Signer, SignerError};
15
16/// P-256 (ECDSA) signer.
17pub struct P256Signer {
18    signing_key: SigningKey,
19}
20
21impl P256Signer {
22    pub fn generate() -> Result<Self, SignerError> {
23        Ok(Self {
24            signing_key: SigningKey::random(&mut OsRng),
25        })
26    }
27
28    pub fn from_pem(pem: &str) -> Result<Self, SignerError> {
29        if let Ok(signing_key) = SigningKey::from_pkcs8_pem(pem) {
30            return Ok(Self { signing_key });
31        }
32
33        if let Ok(signing_key) = SigningKey::from_pkcs1_pem(pem) {
34            return Ok(Self { signing_key });
35        }
36
37        if let Ok(ec_sk) = SecretKey::from_sec1_pem(pem) {
38            // Convert curve SecretKey -> ECDSA SigningKey
39            let signing_key = SigningKey::from(ec_sk);
40            return Ok(Self { signing_key });
41        }
42
43        Err(SignerError::UnknownKeyFormat)
44    }
45
46    pub fn to_pem(&self) -> Result<String, SignerError> {
47        use pkcs8::EncodePrivateKey;
48
49        self.signing_key
50            .to_pkcs8_pem(pkcs8::LineEnding::LF)
51            .map(|pem| pem.to_string())
52            .map_err(|e| SignerError::Pkcs8(e.to_string()))
53    }
54
55    pub fn verify_with_public_key(
56        data: &[u8],
57        public_key: &[u8],
58        signature: &[u8],
59    ) -> Result<(), SignerError> {
60        let verifying_key = VerifyingKey::from_sec1_bytes(public_key)
61            .map_err(|e| SignerError::InvalidPublicKey(e.to_string()))?;
62        if let Ok(signature) = Signature::from_slice(signature) {
63            return verifying_key
64                .verify(data, &signature)
65                .map_err(|_| SignerError::VerificationFailed);
66        }
67        let signature = Signature::from_der(signature)
68            .map_err(|e| SignerError::InvalidSignature(e.to_string()))?;
69        verifying_key
70            .verify(data, &signature)
71            .map_err(|_| SignerError::VerificationFailed)
72    }
73}
74
75impl Signer for P256Signer {
76    fn algorithm(&self) -> &'static str {
77        "p256"
78    }
79
80    fn public_key(&self) -> Vec<u8> {
81        self.signing_key
82            .verifying_key()
83            .to_encoded_point(false)
84            .as_bytes()
85            .to_vec()
86    }
87
88    fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SignerError> {
89        let signature: Signature = self.signing_key.sign(data);
90        Ok(signature.to_bytes().to_vec())
91    }
92
93    fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), SignerError> {
94        Self::verify_with_public_key(data, &self.public_key(), signature)
95    }
96}