jsonprooftoken/jwk/
alg_parameters.rs

1// Copyright 2023 Fondazione LINKS
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7//     http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::{encoding::base64url_encode, jpa::algs::ProofAlgorithm};
16use serde::{Deserialize, Serialize};
17use std::fmt;
18
19use super::{curves::EllipticCurveTypes, types::KeyType};
20
21#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
22#[serde(untagged)]
23pub enum Algorithm {
24    Proof(ProofAlgorithm),
25    // These are defined in the JWA rfc
26
27    // Signature(SignatureAlgorithm), https://datatracker.ietf.org/doc/html/rfc7518#section-3
28    // KeyManagement(KeyManagementAlgorithm), https://datatracker.ietf.org/doc/html/rfc7518#section-4
29    // Encryption(EncryptionAlgorithm), https://datatracker.ietf.org/doc/html/rfc7518#section-5
30}
31
32impl fmt::Display for Algorithm {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        match self {
35            Algorithm::Proof(proof_algorithm) => write!(f, "{}", proof_algorithm),
36        }
37    }
38}
39
40#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
41#[serde(untagged)]
42pub enum JwkAlgorithmParameters {
43    EllipticCurve(JwkEllipticCurveKeyParameters),
44    OctetKeyPair(JwkOctetKeyPairParameters),
45}
46
47impl JwkAlgorithmParameters {
48    pub fn to_public(&self) -> Option<Self> {
49        match self {
50            Self::OctetKeyPair(inner) => Some(Self::OctetKeyPair(inner.to_public())),
51            Self::EllipticCurve(value) => Some(Self::EllipticCurve(value.to_public())),
52        }
53    }
54
55    pub fn is_public(&self) -> bool {
56        match self {
57            Self::OctetKeyPair(value) => value.is_public(),
58            Self::EllipticCurve(value) => value.is_public(),
59        }
60    }
61
62    pub fn is_private(&self) -> bool {
63        match self {
64            Self::OctetKeyPair(value) => value.is_private(),
65            Self::EllipticCurve(value) => value.is_private(),
66        }
67    }
68}
69
70/// Octect Key Pair representation of BLS keys
71///
72/// For now using this representation https://www.rfc-editor.org/rfc/rfc8037
73///
74/// Maybe in future change to [this](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-03)
75#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
76pub struct JwkOctetKeyPairParameters {
77    pub kty: KeyType,
78    /// The "crv" (curve) parameter identifies the cryptographic curve used
79    /// with the key.
80    ///
81    /// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-03#curve-parameter-registration)
82    pub crv: EllipticCurveTypes,
83    /// Represents the base64url encoded public key
84    ///
85    /// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-03#section-2.2.1)
86    pub x: String, // Public Key
87    /// The "d" parameter contains the base64url encoded private key
88    ///
89    /// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-03#section-2.2.1)
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub d: Option<String>,
92}
93
94impl JwkOctetKeyPairParameters {
95    pub fn new<T: AsRef<[u8]>>(crv: EllipticCurveTypes, x: T, d: Option<T>) -> Self {
96        Self {
97            kty: KeyType::OctetKeyPair,
98            crv: crv,
99            x: base64url_encode(x),
100            d: match d {
101                Some(d) => Some(base64url_encode(d)),
102                None => None,
103            },
104        }
105    }
106
107    /// Returns a clone without private key.
108    pub fn to_public(&self) -> Self {
109        Self {
110            kty: KeyType::OctetKeyPair,
111            crv: self.crv.clone(),
112            x: self.x.clone(),
113            d: None,
114        }
115    }
116
117    /// Returns `true` if _all_ private key components of the key are unset, `false` otherwise.
118    pub fn is_public(&self) -> bool {
119        self.d.is_none()
120    }
121
122    /// Returns `true` if _all_ private key components of the key are set, `false` otherwise.
123    pub fn is_private(&self) -> bool {
124        self.d.is_some()
125    }
126}
127
128/// EC representation of BLS keys
129///
130/// Barreto-Lynn-Scott Elliptic Curve Key Representations for JOSE and COSE
131/// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-05)
132#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
133pub struct JwkEllipticCurveKeyParameters {
134    pub kty: KeyType,
135    /// The "crv" (curve) parameter identifies the cryptographic curve used
136    /// with the key.
137    ///
138    /// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-05#curve-parameter-registration)
139    pub crv: EllipticCurveTypes,
140    /// Represents the base64url encoded x coordinate of the curve point for the public key
141    ///
142    /// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-05#name-json-web-key-representation)
143    pub x: String, // Public Key's x-coordinate
144    /// Represents the base64url encoded y coordinate of the curve point for the public key
145    ///
146    /// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-05#name-json-web-key-representation)
147    pub y: String, // Public Key's y-coordinate
148    /// The "d" parameter contains the base64url encoded private key
149    ///
150    /// [More Info](https://datatracker.ietf.org/doc/html/draft-ietf-cose-bls-key-representations-05#name-json-web-key-representation)
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub d: Option<String>,
153}
154
155impl JwkEllipticCurveKeyParameters {
156    pub fn new(crv: EllipticCurveTypes, x: &[u8], y: &[u8], d: Option<&[u8]>) -> Self {
157        Self {
158            kty: KeyType::EllipticCurve,
159            crv: crv,
160            x: base64url_encode(x),
161            y: base64url_encode(y),
162            d: match d {
163                Some(d) => Some(base64url_encode(d)),
164                None => None,
165            },
166        }
167    }
168
169    /// Returns a clone without private key.
170    pub fn to_public(&self) -> Self {
171        Self {
172            kty: KeyType::OctetKeyPair,
173            crv: self.crv.clone(),
174            x: self.x.clone(),
175            y: self.y.clone(),
176            d: None,
177        }
178    }
179
180    /// Returns `true` if _all_ private key components of the key are unset, `false` otherwise.
181    pub fn is_public(&self) -> bool {
182        self.d.is_none()
183    }
184
185    /// Returns `true` if _all_ private key components of the key are set, `false` otherwise.
186    pub fn is_private(&self) -> bool {
187        self.d.is_some()
188    }
189}