1use std::borrow::Cow;
2
3use coset::{
4 iana::{self, EnumI64},
5 Algorithm, CoseKey, KeyType,
6};
7use ssi_crypto::AlgorithmInstance;
8
9use crate::key::{CoseKeyDecode, EC2_CRV};
10
11pub fn instantiate_algorithm(algorithm: &Algorithm) -> Option<AlgorithmInstance> {
13 match algorithm {
14 Algorithm::Assigned(iana::Algorithm::PS256) => Some(AlgorithmInstance::PS256),
15 Algorithm::Assigned(iana::Algorithm::PS384) => Some(AlgorithmInstance::PS384),
16 Algorithm::Assigned(iana::Algorithm::PS512) => Some(AlgorithmInstance::PS512),
17 Algorithm::Assigned(iana::Algorithm::EdDSA) => Some(AlgorithmInstance::EdDSA),
18 Algorithm::Assigned(iana::Algorithm::ES256K) => Some(AlgorithmInstance::ES256K),
19 Algorithm::Assigned(iana::Algorithm::ES256) => Some(AlgorithmInstance::ES256),
20 Algorithm::Assigned(iana::Algorithm::ES384) => Some(AlgorithmInstance::ES384),
21 _ => None,
22 }
23}
24
25pub fn algorithm_name(algorithm: &Algorithm) -> String {
27 match algorithm {
28 Algorithm::Assigned(iana::Algorithm::PS256) => "PS256".to_owned(),
29 Algorithm::Assigned(iana::Algorithm::PS384) => "PS384".to_owned(),
30 Algorithm::Assigned(iana::Algorithm::PS512) => "PS512".to_owned(),
31 Algorithm::Assigned(iana::Algorithm::EdDSA) => "EdDSA".to_owned(),
32 Algorithm::Assigned(iana::Algorithm::ES256K) => "ES256K".to_owned(),
33 Algorithm::Assigned(iana::Algorithm::ES256) => "ES256".to_owned(),
34 Algorithm::Assigned(iana::Algorithm::ES384) => "ES384".to_owned(),
35 Algorithm::Assigned(i) => format!("assigned({})", i.to_i64()),
36 Algorithm::PrivateUse(i) => format!("private_use({i})"),
37 Algorithm::Text(text) => text.to_owned(),
38 }
39}
40
41pub fn preferred_algorithm(key: &'_ CoseKey) -> Option<Cow<'_, Algorithm>> {
43 key.alg
44 .as_ref()
45 .map(Cow::Borrowed)
46 .or_else(|| match key.kty {
47 KeyType::Assigned(iana::KeyType::RSA) => {
48 Some(Cow::Owned(Algorithm::Assigned(iana::Algorithm::PS256)))
49 }
50 KeyType::Assigned(iana::KeyType::OKP) => {
51 let crv = key
52 .parse_required_param(&EC2_CRV, |v| {
53 v.as_integer().and_then(|i| i64::try_from(i).ok())
54 })
55 .ok()?;
56
57 match iana::EllipticCurve::from_i64(crv)? {
58 iana::EllipticCurve::Ed25519 => {
59 Some(Cow::Owned(Algorithm::Assigned(iana::Algorithm::EdDSA)))
60 }
61 _ => None,
62 }
63 }
64 KeyType::Assigned(iana::KeyType::EC2) => {
65 let crv = key
66 .parse_required_param(&EC2_CRV, |v| {
67 v.as_integer().and_then(|i| i64::try_from(i).ok())
68 })
69 .ok()?;
70
71 match iana::EllipticCurve::from_i64(crv)? {
72 iana::EllipticCurve::Secp256k1 => {
73 Some(Cow::Owned(Algorithm::Assigned(iana::Algorithm::ES256K)))
74 }
75 iana::EllipticCurve::P_256 => {
76 Some(Cow::Owned(Algorithm::Assigned(iana::Algorithm::ES256)))
77 }
78 iana::EllipticCurve::P_384 => {
79 Some(Cow::Owned(Algorithm::Assigned(iana::Algorithm::ES384)))
80 }
81 _ => None,
82 }
83 }
84 _ => None,
85 })
86}