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}