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