did_crypto/crypto/ecdsa/
_256k.rs

1use std::str::FromStr;
2
3use crate::{
4    algorithms::Algorithm,
5    crypto::{SignFromKey, VerifyFromKey},
6    errors::Error,
7    log,
8};
9use elliptic_curve::pkcs8::DecodePublicKey;
10use k256::{
11    ecdsa::{signature::Signer, signature::Verifier, Signature, SigningKey, VerifyingKey},
12    Secp256k1,
13};
14
15pub struct P256kSigningKey {
16    key: SigningKey,
17}
18
19impl SignFromKey for P256kSigningKey {
20    fn sign(&self, content: String, _alg: Algorithm) -> Result<String, Error> {
21        let sig_result: Result<Signature, k256::ecdsa::Error> =
22            self.key.try_sign(content.as_bytes());
23        let signature = match sig_result {
24            Ok(val) => val,
25            Err(error) => {
26                log::error(error.to_string().as_str());
27                return Err(Error::SIGNING_FAILED);
28            }
29        };
30
31        Ok(base64_url::encode(signature.to_bytes().as_slice()))
32    }
33}
34
35impl P256kSigningKey {
36    pub fn from_pem(key_str: &str) -> Result<Self, Error> {
37        let ec_key = match key_str.starts_with("-----BEGIN EC PRIVATE KEY-----") {
38            true => {
39                let key_scalar: elliptic_curve::SecretKey<Secp256k1> =
40                    match elliptic_curve::SecretKey::from_sec1_pem(key_str) {
41                        Ok(val) => val,
42                        Err(error) => {
43                            log::error(error.to_string().as_str());
44                            return Err(Error::EC_PEM_ERROR);
45                        }
46                    };
47
48                match SigningKey::from_bytes(&key_scalar.as_scalar_primitive().to_bytes()) {
49                    Ok(val) => val,
50                    Err(error) => {
51                        log::error(error.to_string().as_str());
52                        return Err(Error::PRIVATE_KEY_IDENTIFICATION_ERROR);
53                    }
54                }
55            }
56            false => {
57                let key_scalar: elliptic_curve::SecretKey<Secp256k1> =
58                    match elliptic_curve::SecretKey::from_str(key_str) {
59                        Ok(val) => val,
60                        Err(error) => {
61                            log::error(error.to_string().as_str());
62                            return Err(Error::EC_PEM_ERROR);
63                        }
64                    };
65
66                match SigningKey::from_bytes(&key_scalar.as_scalar_primitive().to_bytes()) {
67                    Ok(val) => val,
68                    Err(error) => {
69                        log::error(error.to_string().as_str());
70                        return Err(Error::PRIVATE_KEY_IDENTIFICATION_ERROR);
71                    }
72                }
73            }
74        };
75
76        Ok(P256kSigningKey { key: ec_key })
77    }
78}
79
80pub struct P256kVerifyingKey {
81    key: VerifyingKey,
82}
83
84impl VerifyFromKey for P256kVerifyingKey {
85    fn verify(&self, content: String, signature: String, _alg: Algorithm) -> Result<bool, Error> {
86        let decoded_sig = match base64_url::decode(signature.as_bytes()) {
87            Ok(val) => val,
88            Err(error) => {
89                log::error(error.to_string().as_str());
90                return Err(Error::DECODING_ERROR);
91            }
92        };
93
94        let sig = match Signature::from_slice(&decoded_sig) {
95            Ok(val) => val,
96            Err(error) => {
97                log::error(error.to_string().as_str());
98                return Err(Error::SIGNATURE_IDENTIFICATION_FAILED);
99            }
100        };
101
102        let verify_result: Result<(), k256::ecdsa::Error> =
103            self.key.verify(content.as_bytes(), &sig);
104        if verify_result.is_ok() {
105            return Ok(true);
106        } else {
107            match verify_result.err() {
108                Some(error) => {
109                    log::error(error.to_string().as_str());
110                }
111                None => {}
112            };
113            return Ok(false);
114        }
115    }
116}
117
118impl P256kVerifyingKey {
119    pub fn from_pem(key_str: &str) -> Result<Self, Error> {
120        let key_scalar: elliptic_curve::PublicKey<Secp256k1> =
121            match elliptic_curve::PublicKey::from_public_key_pem(key_str) {
122                Ok(val) => val,
123                Err(error) => {
124                    log::error(error.to_string().as_str());
125                    return Err(Error::EC_PEM_ERROR);
126                }
127            };
128        let ec_key = match VerifyingKey::from_sec1_bytes(&key_scalar.to_sec1_bytes()) {
129            Ok(val) => val,
130            Err(error) => {
131                log::error(error.to_string().as_str());
132                return Err(Error::PUBLIC_KEY_IDENTIFICATION_ERROR);
133            }
134        };
135
136        Ok(P256kVerifyingKey { key: ec_key })
137    }
138}
139
140pub fn ec_256k_sign(message: String, key: impl SignFromKey) -> Result<String, Error> {
141    key.sign(message, Algorithm::ES256K)
142}
143
144pub fn ec_256k_verify(
145    message: String,
146    sig: String,
147    key: impl VerifyFromKey,
148) -> Result<bool, Error> {
149    key.verify(message, sig, Algorithm::ES256K)
150}