did_crypto/crypto/ecdsa/
_256.rs1use 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 p256::{
11 ecdsa::{signature::Signer, signature::Verifier, Signature, SigningKey, VerifyingKey},
12 NistP256,
13};
14
15pub struct P256SigningKey {
16 key: SigningKey,
17}
18
19impl SignFromKey for P256SigningKey {
20 fn sign(&self, content: String, _alg: Algorithm) -> Result<String, Error> {
21 let sig_result: Result<Signature, p256::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 P256SigningKey {
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<NistP256> =
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<NistP256> =
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(P256SigningKey { key: ec_key })
77 }
78}
79
80pub struct P256VerifyingKey {
81 key: VerifyingKey,
82}
83
84impl VerifyFromKey for P256VerifyingKey {
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<(), p256::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 P256VerifyingKey {
119 pub fn from_pem(key_str: &str) -> Result<Self, Error> {
120 let key_scalar: elliptic_curve::PublicKey<NistP256> =
121 match elliptic_curve::PublicKey::from_public_key_pem(key_str) {
122 Ok(val) => val,
123 Err(error) => {
124 println!("{}", key_str);
125 log::error(error.to_string().as_str());
126 return Err(Error::EC_PEM_ERROR);
127 }
128 };
129
130 let ec_key = match VerifyingKey::from_sec1_bytes(&key_scalar.to_sec1_bytes()) {
131 Ok(val) => val,
132 Err(error) => {
133 log::error(error.to_string().as_str());
134 return Err(Error::PUBLIC_KEY_IDENTIFICATION_ERROR);
135 }
136 };
137 Ok(P256VerifyingKey { key: ec_key })
138 }
139}
140
141pub fn ec_256_sign(message: String, key: impl SignFromKey) -> Result<String, Error> {
142 key.sign(message, Algorithm::ES256)
143}
144
145pub fn ec_256_verify(message: String, sig: String, key: impl VerifyFromKey) -> Result<bool, Error> {
146 key.verify(message, sig, Algorithm::ES256)
147}