1use crate::multicodec::MultiEncoded;
2use crate::PLCError;
3use ecdsa::elliptic_curve::sec1::ToEncodedPoint;
4use ecdsa::signature::{SignerMut, Verifier};
5use serde::{Deserialize, Serialize};
6#[cfg(feature = "jwt")]
7use jwt::{SigningAlgorithm, VerifyingAlgorithm};
8#[cfg(feature = "jwt")]
9use base64::Engine;
10
11pub enum BlessedAlgorithm {
12 P256,
13 K256,
14}
15
16impl BlessedAlgorithm {
17 pub fn codec(&self) -> u64 {
18 match self {
19 Self::P256 => 0x1200,
20 Self::K256 => 0xe7,
21 }
22 }
23
24 pub fn prefix(&self) -> [u8; 2] {
25 match self {
26 Self::P256 => [0x80, 0x24],
27 Self::K256 => [0xe7, 0x01],
28 }
29 }
30}
31
32impl From<u64> for BlessedAlgorithm {
33 fn from(value: u64) -> Self {
34 match value {
35 0x1200 => Self::P256,
36 0xe7 => Self::K256,
37 _ => panic!("Unknown algorithm"),
38 }
39 }
40}
41
42#[derive(Clone, Serialize, Deserialize)]
43pub struct Keypair {
44 pub public: Option<Vec<u8>>,
45 pub secret: Option<Vec<u8>>,
46 pub codec: u64,
47}
48
49impl Keypair {
50 pub fn generate(algo: BlessedAlgorithm) -> Self {
51 match algo {
52 BlessedAlgorithm::P256 => {
53 let sk = p256::ecdsa::SigningKey::random(&mut rand::thread_rng());
54 let vk = sk.verifying_key();
55 Keypair {
56 public: Some(vk.to_sec1_bytes().to_vec()),
57 secret: Some(sk.to_bytes().to_vec()),
58 codec: algo.codec(),
59 }
60 }
61 BlessedAlgorithm::K256 => {
62 let sk = k256::ecdsa::SigningKey::random(&mut rand::thread_rng());
63 let vk = sk.verifying_key();
64 Keypair {
65 public: Some(vk.to_sec1_bytes().to_vec()),
66 secret: Some(sk.to_bytes().to_vec()),
67 codec: algo.codec(),
68 }
69 }
70 }
71 }
72
73 pub fn from_value(value: serde_json::Value) -> Result<Self, PLCError> {
74 let keypair: Keypair =
75 serde_json::from_value(value).map_err(|e| PLCError::Other(e.into()))?;
76 Ok(keypair)
77 }
78
79 pub fn from_did_key(key: &str) -> Result<Self, PLCError> {
80 if !key.starts_with("did:key:") {
81 return Err(PLCError::InvalidKey);
82 }
83 let key = key.split_at(8).1;
84 let (_base, data) = multibase::decode(key).map_err(|_| PLCError::InvalidKey)?;
85 let decoded_result =
86 MultiEncoded::new(data.as_slice()).map_err(|_| PLCError::InvalidKey)?;
87
88 Ok(Keypair {
89 public: Some(decoded_result.data().to_vec()),
90 secret: None,
91 codec: decoded_result.codec(),
92 })
93 }
94
95 pub fn to_did_key(&self) -> Result<String, PLCError> {
96 if self.public.is_none() {
97 return Err(PLCError::InvalidKey);
98 }
99 let algo = BlessedAlgorithm::from(self.codec);
100
101 match algo {
102 BlessedAlgorithm::P256 => {
103 let pk = p256::PublicKey::from_sec1_bytes(self.public.as_ref().unwrap().as_slice())
104 .map_err(|e| PLCError::Other(e.into()))?;
105 let key = multibase::encode(
106 multibase::Base::Base58Btc,
107 [
108 algo.prefix().to_vec(),
109 pk.to_encoded_point(true).as_bytes().to_vec(),
110 ]
111 .concat(),
112 );
113 Ok(format!("did:key:{}", key))
114 }
115 BlessedAlgorithm::K256 => {
116 let pk = k256::PublicKey::from_sec1_bytes(self.public.as_ref().unwrap().as_slice())
117 .map_err(|e| PLCError::Other(e.into()))?;
118 let vk = k256::ecdsa::VerifyingKey::from(pk);
119 let key = multibase::encode(
120 multibase::Base::Base58Btc,
121 [algo.prefix().to_vec(), vk.to_sec1_bytes().to_vec()].concat(),
122 );
123 Ok(format!("did:key:{}", key))
124 }
125 }
126 }
127
128 pub fn from_private_key(key: &str) -> Result<Self, PLCError> {
129 let (_base, data) = multibase::decode(key).map_err(|e| PLCError::Other(e.into()))?;
130 let decoded_result =
131 MultiEncoded::new(data.as_slice()).map_err(|e| PLCError::Other(e.into()))?;
132
133 match decoded_result.codec() {
134 0xe7 => {
135 let sk = k256::ecdsa::SigningKey::from_bytes(decoded_result.data().into())
137 .map_err(|e| PLCError::Other(e.into()))?;
138 let vk = sk.verifying_key();
139 Ok(Keypair {
140 public: Some(vk.to_sec1_bytes().to_vec()),
141 secret: Some(decoded_result.data().to_vec()),
142 codec: decoded_result.codec(),
143 })
144 }
145 0x1200 => {
146 let sk = p256::ecdsa::SigningKey::from_bytes(decoded_result.data().into())
148 .map_err(|e| PLCError::Other(e.into()))?;
149 let vk = sk.verifying_key();
150 Ok(Keypair {
151 public: Some(vk.to_sec1_bytes().to_vec()),
152 secret: Some(decoded_result.data().to_vec()),
153 codec: decoded_result.codec(),
154 })
155 }
156 _ => Err(PLCError::MalformedKey),
157 }
158 }
159
160 pub fn to_private_key(&self) -> Result<String, PLCError> {
161 if self.secret.is_none() {
162 return Err(PLCError::InvalidKey);
163 }
164 let algo = BlessedAlgorithm::from(self.codec);
165 match algo {
166 BlessedAlgorithm::P256 => {
167 let key = multibase::encode(
168 multibase::Base::Base58Btc,
169 [algo.prefix().to_vec(), self.secret.clone().unwrap()].concat(),
170 );
171 Ok(key)
172 }
173 BlessedAlgorithm::K256 => {
174 let key = multibase::encode(
175 multibase::Base::Base58Btc,
176 [algo.prefix().to_vec(), self.secret.clone().unwrap()].concat(),
177 );
178 Ok(key)
179 }
180 }
181 }
182
183 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<bool, PLCError> {
184 match self.codec {
185 0xe7 => {
186 let vk = k256::ecdsa::VerifyingKey::from_sec1_bytes(
188 self.public.as_ref().unwrap().as_slice(),
189 )
190 .map_err(|_| PLCError::InvalidKey)?;
191 let sig = k256::ecdsa::Signature::from_slice(sig.into())
192 .map_err(|_| PLCError::InvalidSignature)?;
193 if vk.verify(&msg, &sig).is_ok() {
194 return Ok(true);
195 }
196 }
197 0x1200 => {
198 let vk = p256::ecdsa::VerifyingKey::from_sec1_bytes(
200 self.public.as_ref().unwrap().as_slice(),
201 )
202 .map_err(|_| PLCError::InvalidKey)?;
203 let sig = p256::ecdsa::Signature::from_slice(sig.into())
204 .map_err(|_| PLCError::InvalidSignature)?;
205 if vk.verify(&msg, &sig).is_ok() {
206 return Ok(true);
207 }
208 }
209 _ => (),
210 }
211 Ok(false)
212 }
213
214 pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, PLCError> {
215 match self.codec {
216 0xe7 => {
217 let mut sk = k256::ecdsa::SigningKey::from_bytes(
219 self.secret.as_ref().unwrap().as_slice().into(),
220 )
221 .map_err(|e| PLCError::Other(e.into()))?;
222 let sig: k256::ecdsa::Signature = sk.sign(&msg);
223 Ok(sig.to_bytes().to_vec())
224 }
225 0x1200 => {
226 let mut sk = p256::ecdsa::SigningKey::from_bytes(
228 self.secret.as_ref().unwrap().as_slice().into(),
229 )
230 .map_err(|e| PLCError::Other(e.into()))?;
231 let sig: p256::ecdsa::Signature = sk.sign(&msg);
232 match sig.normalize_s() {
233 Some(sig) => Ok(sig.to_bytes().to_vec()),
234 None => {
235 Ok(sig.to_bytes().to_vec())
236 }
237 }
238 }
239 _ => Err(PLCError::InvalidKey),
240 }
241 }
242}
243
244#[cfg(feature = "jwt")]
245impl SigningAlgorithm for Keypair {
246 fn sign(&self, header: &str, claims: &str) -> Result<String, jwt::Error> {
247 let mut msg = vec![];
248 msg.extend_from_slice(header.as_bytes());
249 msg.extend_from_slice(b".");
250 msg.extend_from_slice(claims.as_bytes());
251 let sig = self.sign(msg.as_slice()).map_err(|_| jwt::Error::InvalidSignature)?;
252 let engine = base64::engine::general_purpose::STANDARD;
253 Ok(engine.encode(sig))
254 }
255
256 fn algorithm_type(&self) -> jwt::AlgorithmType {
257 match BlessedAlgorithm::from(self.codec) {
258 BlessedAlgorithm::P256 => jwt::AlgorithmType::Es256,
259 BlessedAlgorithm::K256 => jwt::AlgorithmType::None
260 }
261 }
262}
263
264#[cfg(feature = "jwt")]
265impl VerifyingAlgorithm for Keypair {
266 fn algorithm_type(&self) -> jwt::AlgorithmType {
267 match BlessedAlgorithm::from(self.codec) {
268 BlessedAlgorithm::P256 => jwt::AlgorithmType::Es256,
269 BlessedAlgorithm::K256 => jwt::AlgorithmType::None
270 }
271 }
272
273 fn verify_bytes(&self, header: &str, claims: &str, signature: &[u8]) -> Result<bool, jwt::Error> {
274 let engine = base64::engine::general_purpose::STANDARD;
275 let signature = engine.decode(signature).map_err(|_| jwt::Error::InvalidSignature)?;
276 let mut msg = vec![];
277 msg.extend_from_slice(header.as_bytes());
278 msg.extend_from_slice(b".");
279 msg.extend_from_slice(claims.as_bytes());
280 self.verify(msg.as_slice(), signature.as_slice()).map_err(|_| jwt::Error::InvalidSignature)
281 }
282}
283
284#[cfg(test)]
285mod test {
286 use super::*;
287
288 #[test]
289 fn test_keypair_p256() {
290 let keypair = Keypair::generate(BlessedAlgorithm::P256);
291 assert!(keypair.public.is_some());
292 assert!(keypair.secret.is_some());
293 assert_eq!(keypair.codec, 0x1200);
294 assert!(keypair.to_did_key().unwrap().starts_with("did:key:zDn"));
295 }
296
297 #[test]
298 fn test_keypair_k256() {
299 let keypair = Keypair::generate(BlessedAlgorithm::K256);
300 assert!(keypair.public.is_some());
301 assert!(keypair.secret.is_some());
302 assert_eq!(keypair.codec, 0xe7);
303 assert!(keypair.to_did_key().unwrap().starts_with("did:key:zQ3s"));
304 }
305
306 #[test]
307 fn test_keypair_from_did_key_p256() {
308 let orig_keypair = Keypair::generate(BlessedAlgorithm::P256);
309 let did_key = orig_keypair.to_did_key().unwrap();
310 let keypair = Keypair::from_did_key(&did_key).unwrap();
311 assert_eq!(
312 keypair.to_did_key().unwrap(),
313 orig_keypair.to_did_key().unwrap()
314 );
315 assert_eq!(keypair.codec, orig_keypair.codec);
316 }
317
318 #[test]
319 fn test_keypair_from_did_key_k256() {
320 let orig_keypair = Keypair::generate(BlessedAlgorithm::K256);
321 let did_key = orig_keypair.to_did_key().unwrap();
322 let keypair = Keypair::from_did_key(&did_key).unwrap();
323 assert_eq!(
324 keypair.to_did_key().unwrap(),
325 orig_keypair.to_did_key().unwrap()
326 );
327 assert_eq!(keypair.codec, orig_keypair.codec);
328 }
329
330 #[test]
331 fn test_keypair_to_did_key() {
332 let keypair =
333 Keypair::from_did_key("did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg");
334 assert!(keypair.is_ok());
335 assert_eq!(
336 keypair.unwrap().to_did_key().unwrap(),
337 "did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg"
338 );
339 }
340
341 #[test]
342 fn test_keypair_from_private_key_p256() {
343 let orig_keypair = Keypair::generate(BlessedAlgorithm::P256);
344 let private_key = orig_keypair.to_private_key().unwrap();
345 let keypair = Keypair::from_private_key(&private_key).unwrap();
346 assert_eq!(
347 keypair.to_did_key().unwrap(),
348 orig_keypair.to_did_key().unwrap()
349 );
350 assert_eq!(keypair.codec, orig_keypair.codec);
351 }
352
353 #[test]
354 fn test_keypair_from_private_key_k256() {
355 let orig_keypair = Keypair::generate(BlessedAlgorithm::K256);
356 let private_key = orig_keypair.to_private_key().unwrap();
357 let keypair = Keypair::from_private_key(&private_key).unwrap();
358 assert_eq!(
359 keypair.to_did_key().unwrap(),
360 orig_keypair.to_did_key().unwrap()
361 );
362 assert_eq!(keypair.codec, orig_keypair.codec);
363 }
364
365 #[test]
366 fn test_keypair_to_private_key_p256() {
367 let orig_keypair = Keypair::generate(BlessedAlgorithm::P256);
368 let private_key = orig_keypair.to_private_key().unwrap();
369 let keypair = Keypair::from_private_key(&private_key).unwrap();
370 assert_eq!(orig_keypair.secret.unwrap(), keypair.secret.unwrap());
371 }
372
373 #[test]
374 fn test_keypair_to_private_key_k256() {
375 let orig_keypair = Keypair::generate(BlessedAlgorithm::K256);
376 let private_key = orig_keypair.to_private_key().unwrap();
377 let keypair = Keypair::from_private_key(&private_key).unwrap();
378 assert_eq!(orig_keypair.secret.unwrap(), keypair.secret.unwrap());
379 }
380
381 #[cfg(feature = "jwt")]
382 #[test]
383 fn test_keypair_jwt() {
384 let keypair = Keypair::generate(BlessedAlgorithm::P256);
385 let header = "{\"alg\":\"ES256\",\"typ\":\"JWT\"}";
386 let claims = "{\"iss\":\"me\"}";
387 let sig = SigningAlgorithm::sign(&keypair, header, claims);
388 assert!(sig.is_ok(), "JWT should be signed correctly: {:?}", sig.err().unwrap());
389
390 let sig = sig.unwrap();
391 let res = keypair.verify_bytes(header, claims, sig.as_bytes());
392 assert!(res.is_ok(), "JWT sig should be valid: {:?}", res.err().unwrap());
393 }
394}