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    cached_public_key: Vec<u8>,
20}
21
22impl P256Signer {
23    fn from_signing_key(signing_key: SigningKey) -> Self {
24        let cached_public_key = signing_key
25            .verifying_key()
26            .to_encoded_point(false)
27            .as_bytes()
28            .to_vec();
29        Self {
30            signing_key,
31            cached_public_key,
32        }
33    }
34
35    pub fn generate() -> Result<Self, SignerError> {
36        Ok(Self::from_signing_key(SigningKey::random(&mut OsRng)))
37    }
38
39    pub fn from_pem(pem: &str) -> Result<Self, SignerError> {
40        if let Ok(signing_key) = SigningKey::from_pkcs8_pem(pem) {
41            return Ok(Self::from_signing_key(signing_key));
42        }
43
44        if let Ok(signing_key) = SigningKey::from_pkcs1_pem(pem) {
45            return Ok(Self::from_signing_key(signing_key));
46        }
47
48        if let Ok(ec_sk) = SecretKey::from_sec1_pem(pem) {
49            return Ok(Self::from_signing_key(SigningKey::from(ec_sk)));
50        }
51
52        Err(SignerError::UnknownKeyFormat)
53    }
54
55    pub fn to_pem(&self) -> Result<String, SignerError> {
56        use pkcs8::EncodePrivateKey;
57
58        self.signing_key
59            .to_pkcs8_pem(pkcs8::LineEnding::LF)
60            .map(|pem| pem.to_string())
61            .map_err(|e| SignerError::Pkcs8(e.to_string()))
62    }
63
64    pub fn verify_with_public_key(
65        data: &[u8],
66        public_key: &[u8],
67        signature: &[u8],
68    ) -> Result<(), SignerError> {
69        let verifying_key = VerifyingKey::from_sec1_bytes(public_key)
70            .map_err(|e| SignerError::InvalidPublicKey(e.to_string()))?;
71        if let Ok(signature) = Signature::from_slice(signature) {
72            return verifying_key
73                .verify(data, &signature)
74                .map_err(|_| SignerError::VerificationFailed);
75        }
76        let signature = Signature::from_der(signature)
77            .map_err(|e| SignerError::InvalidSignature(e.to_string()))?;
78        verifying_key
79            .verify(data, &signature)
80            .map_err(|_| SignerError::VerificationFailed)
81    }
82}
83
84impl Signer for P256Signer {
85    fn algorithm(&self) -> &'static str {
86        "p256"
87    }
88
89    fn public_key(&self) -> &[u8] {
90        &self.cached_public_key
91    }
92
93    fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SignerError> {
94        let signature: Signature = self.signing_key.sign(data);
95        Ok(signature.to_bytes().to_vec())
96    }
97
98    fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), SignerError> {
99        Self::verify_with_public_key(data, self.public_key(), signature)
100    }
101}