You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

134 lines
3.7 KiB

use acme_common::b64_encode;
use acme_common::crypto::{JwsSignatureAlgorithm, KeyPair};
use acme_common::error::Error;
use serde::Serialize;
use serde_json::value::Value;
#[derive(Serialize)]
struct JwsData {
protected: String,
payload: String,
signature: String,
}
#[derive(Serialize)]
struct JwsProtectedHeaderJwk {
alg: String,
jwk: Value,
nonce: String,
url: String,
}
#[derive(Serialize)]
struct JwsProtectedHeaderKid {
alg: String,
kid: String,
nonce: String,
url: String,
}
fn get_data(
key_pair: &KeyPair,
sign_alg: &JwsSignatureAlgorithm,
protected: &str,
payload: &[u8],
) -> Result<String, Error> {
let protected = b64_encode(protected);
let payload = b64_encode(payload);
let signing_input = format!("{}.{}", protected, payload);
let signature = key_pair.sign(sign_alg, signing_input.as_bytes())?;
let signature = b64_encode(&signature);
let data = JwsData {
protected,
payload,
signature,
};
let str_data = serde_json::to_string(&data)?;
Ok(str_data)
}
pub fn encode_jwk(
key_pair: &KeyPair,
sign_alg: &JwsSignatureAlgorithm,
payload: &[u8],
url: &str,
nonce: &str,
) -> Result<String, Error> {
let protected = JwsProtectedHeaderJwk {
alg: sign_alg.to_string(),
jwk: key_pair.jwk_public_key()?,
nonce: nonce.into(),
url: url.into(),
};
let protected = serde_json::to_string(&protected)?;
get_data(key_pair, sign_alg, &protected, payload)
}
pub fn encode_kid(
key_pair: &KeyPair,
sign_alg: &JwsSignatureAlgorithm,
key_id: &str,
payload: &[u8],
url: &str,
nonce: &str,
) -> Result<String, Error> {
let protected = JwsProtectedHeaderKid {
alg: sign_alg.to_string(),
kid: key_id.to_string(),
nonce: nonce.into(),
url: url.into(),
};
let protected = serde_json::to_string(&protected)?;
get_data(key_pair, sign_alg, &protected, payload)
}
#[cfg(test)]
mod tests {
use super::{encode_jwk, encode_kid};
use acme_common::crypto::{gen_keypair, KeyType};
#[test]
fn test_default_jwk() {
let key_pair = gen_keypair(KeyType::EcdsaP256).unwrap();
let payload = "Dummy payload 1";
let payload_b64 = "RHVtbXkgcGF5bG9hZCAx";
let s = encode_jwk(&key_pair, payload.as_bytes(), "", "");
assert!(s.is_ok());
let s = s.unwrap();
assert!(s.contains("\"protected\""));
assert!(s.contains("\"payload\""));
assert!(s.contains("\"signature\""));
assert!(s.contains(payload_b64));
}
#[test]
fn test_default_nopad_jwk() {
let key_pair = gen_keypair(KeyType::EcdsaP256).unwrap();
let payload = "Dummy payload";
let payload_b64 = "RHVtbXkgcGF5bG9hZA";
let payload_b64_pad = "RHVtbXkgcGF5bG9hZA==";
let s = encode_jwk(&key_pair, payload.as_bytes(), "", "");
assert!(s.is_ok());
let s = s.unwrap();
assert!(s.contains("\"protected\""));
assert!(s.contains("\"payload\""));
assert!(s.contains("\"signature\""));
assert!(s.contains(payload_b64));
assert!(!s.contains(payload_b64_pad));
}
#[test]
fn test_default_kid() {
let key_pair = gen_keypair(KeyType::EcdsaP256).unwrap();
let payload = "Dummy payload 1";
let payload_b64 = "RHVtbXkgcGF5bG9hZCAx";
let key_id = "0x2a";
let s = encode_kid(&key_pair, key_id, payload.as_bytes(), "", "");
assert!(s.is_ok());
let s = s.unwrap();
assert!(s.contains("\"protected\""));
assert!(s.contains("\"payload\""));
assert!(s.contains("\"signature\""));
assert!(s.contains(payload_b64));
}
}