-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes to support ACME, including JWS #359
base: master
Are you sure you want to change the base?
Changes from all commits
fd60bf2
b6ef547
7904bb1
b0072fd
5a3b07f
c64cbe2
dbc9dbd
f2f070b
a1cf7b7
8ae98dc
dd34b25
b8cf8b2
f7b51d2
0cfda16
d61c791
4f57bea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,109 @@ | ||
use std::result; | ||
|
||
use base64::{engine::general_purpose::STANDARD, Engine}; | ||
use serde::{Deserialize, Serialize}; | ||
use serde::{Deserialize, Deserializer, Serialize, Serializer}; | ||
|
||
use crate::algorithms::Algorithm; | ||
use crate::errors::Result; | ||
use crate::jwk::Jwk; | ||
use crate::serialization::b64_decode; | ||
|
||
const ZIP_SERIAL_DEFLATE: &str = "DEF"; | ||
const ENC_A128CBC_HS256: &str = "A128CBC-HS256"; | ||
const ENC_A192CBC_HS384: &str = "A192CBC-HS384"; | ||
const ENC_A256CBC_HS512: &str = "A256CBC-HS512"; | ||
const ENC_A128GCM: &str = "A128GCM"; | ||
const ENC_A192GCM: &str = "A192GCM"; | ||
const ENC_A256GCM: &str = "A256GCM"; | ||
|
||
/// Encryption algorithm for encrypted payloads. | ||
/// | ||
/// Defined in [RFC7516#4.1.2](https://datatracker.ietf.org/doc/html/rfc7516#section-4.1.2). | ||
/// | ||
/// Values defined in [RFC7518#5.1](https://datatracker.ietf.org/doc/html/rfc7518#section-5.1). | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
#[allow(clippy::upper_case_acronyms, non_camel_case_types)] | ||
pub enum Enc { | ||
A128CBC_HS256, | ||
A192CBC_HS384, | ||
A256CBC_HS512, | ||
A128GCM, | ||
A192GCM, | ||
A256GCM, | ||
Other(String), | ||
} | ||
|
||
impl Serialize for Enc { | ||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> | ||
where | ||
S: Serializer, | ||
{ | ||
match self { | ||
Enc::A128CBC_HS256 => ENC_A128CBC_HS256, | ||
Enc::A192CBC_HS384 => ENC_A192CBC_HS384, | ||
Enc::A256CBC_HS512 => ENC_A256CBC_HS512, | ||
Enc::A128GCM => ENC_A128GCM, | ||
Enc::A192GCM => ENC_A192GCM, | ||
Enc::A256GCM => ENC_A256GCM, | ||
Enc::Other(v) => v, | ||
} | ||
.serialize(serializer) | ||
} | ||
} | ||
|
||
impl<'de> Deserialize<'de> for Enc { | ||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
let s = String::deserialize(deserializer)?; | ||
match s.as_str() { | ||
ENC_A128CBC_HS256 => return Ok(Enc::A128CBC_HS256), | ||
ENC_A192CBC_HS384 => return Ok(Enc::A192CBC_HS384), | ||
ENC_A256CBC_HS512 => return Ok(Enc::A256CBC_HS512), | ||
ENC_A128GCM => return Ok(Enc::A128GCM), | ||
ENC_A192GCM => return Ok(Enc::A192GCM), | ||
ENC_A256GCM => return Ok(Enc::A256GCM), | ||
_ => (), | ||
} | ||
Ok(Enc::Other(s)) | ||
} | ||
} | ||
/// Compression applied to plaintext. | ||
/// | ||
/// Defined in [RFC7516#4.1.3](https://datatracker.ietf.org/doc/html/rfc7516#section-4.1.3). | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
pub enum Zip { | ||
Deflate, | ||
Other(String), | ||
} | ||
|
||
impl Serialize for Zip { | ||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> | ||
where | ||
S: Serializer, | ||
{ | ||
match self { | ||
Zip::Deflate => ZIP_SERIAL_DEFLATE, | ||
Zip::Other(v) => v, | ||
} | ||
.serialize(serializer) | ||
} | ||
} | ||
|
||
impl<'de> Deserialize<'de> for Zip { | ||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
let s = String::deserialize(deserializer)?; | ||
match s.as_str() { | ||
ZIP_SERIAL_DEFLATE => Ok(Zip::Deflate), | ||
_ => Ok(Zip::Other(s)), | ||
} | ||
} | ||
} | ||
|
||
/// A basic JWT header, the alg defaults to HS256 and typ is automatically | ||
/// set to `JWT`. All the other fields are optional. | ||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)] | ||
|
@@ -64,6 +160,27 @@ pub struct Header { | |
#[serde(skip_serializing_if = "Option::is_none")] | ||
#[serde(rename = "x5t#S256")] | ||
pub x5t_s256: Option<String>, | ||
/// Critical - indicates header fields that must be understood by the receiver. | ||
/// | ||
/// Defined in [RFC7515#4.1.6](https://tools.ietf.org/html/rfc7515#section-4.1.6). | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub crit: Option<Vec<String>>, | ||
/// See `Enc` for description. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub enc: Option<Enc>, | ||
/// See `Zip` for description. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub zip: Option<Zip>, | ||
/// ACME: The URL to which this JWS object is directed | ||
/// | ||
/// Defined in [RFC8555#6.4](https://datatracker.ietf.org/doc/html/rfc8555#section-6.4). | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub url: Option<String>, | ||
/// ACME: Random data for preventing replay attacks. | ||
/// | ||
/// Defined in [RFC8555#6.5.2](https://datatracker.ietf.org/doc/html/rfc8555#section-6.5.2). | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub nonce: Option<String>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add #347 (comment) while you're there? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added crit, enc, and zip -- I think I have the values there right, but I'm not familiar with their use so double checking it would probably be good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. @inferiorhumanorgans can you have a look? |
||
} | ||
|
||
impl Header { | ||
|
@@ -80,6 +197,11 @@ impl Header { | |
x5c: None, | ||
x5t: None, | ||
x5t_s256: None, | ||
crit: None, | ||
enc: None, | ||
zip: None, | ||
url: None, | ||
nonce: None, | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can probably macro it out to avoid duplicating the code from
verify_signature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried factoring out a function, let me know if this works for you.