did_crypto/crypto/ecdsa/
_256k.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 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}