Skip to content

Commit

Permalink
Switch from base64 to base64ct
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Nov 4, 2023
1 parent 6524683 commit 379a49e
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 26 deletions.
17 changes: 10 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ name = "clevis"
path = "src/main.rs"

[dependencies]
base64 = "0.21.0"
clap = { version = "4.2.1", features = ["derive"] }
clap = { version = "4.4.7", features = ["derive"] }
env_logger = "0.10.0"
josekit = "0.8.2"
josekit = "0.8.4"
log = "0.4.20"
serde = "1.0.160"
sha2 = "0.10.6"
serde_json = { version = "1.0.95", features = ["preserve_order"] }
ureq = { version = "2.6.2", features = ["json"] }
serde = "1.0.190"
sha2 = "0.10.8"
serde_json = { version = "1.0.108", features = ["preserve_order"] }
ureq = { version = "2.8.0", features = ["json"] }
sha1 = "0.10.6"
hex = "0.4.3"
p521 = { git = "https://github.com/RustCrypto/elliptic-curves.git" }
p256 = { git = "https://github.com/RustCrypto/elliptic-curves.git" }
base64ct = { version = "1.6.0", features = ["alloc"] }

# vsss-rs = "2.7.1"

[features]
Expand Down
6 changes: 3 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub enum Error {
JsonMissingKey(Box<str>),
JsonKeyType(Box<str>),
Utf8(Utf8Error),
Base64(base64::DecodeError),
Base64(base64ct::Error),
Json(serde_json::Error),
Jose(josekit::JoseError),
VerifyKey,
Expand Down Expand Up @@ -49,8 +49,8 @@ impl From<Utf8Error> for Error {
}
}

impl From<base64::DecodeError> for Error {
fn from(value: base64::DecodeError) -> Self {
impl From<base64ct::Error> for Error {
fn from(value: base64ct::Error) -> Self {
Self::Base64(value)
}
}
Expand Down
34 changes: 24 additions & 10 deletions src/jose.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::key_exchange::create_encryption_key;
use crate::util::{b64_to_bytes, b64_to_str};
use crate::{Error, Result};
use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine};
use base64ct::{Base64UrlUnpadded, Encoding};
use josekit::jwe::alg::ecdh_es::EcdhEsJweAlgorithm;
use josekit::jwe::{self, JweHeader};
use josekit::jwk::Jwk;
Expand All @@ -17,6 +17,8 @@ use std::ops::Deref;
use std::{sync::OnceLock, time::Duration};

/// Representation of a tang advertisment response which is a JWS of available keys.
///
/// This is what is produced when you GET `tang_url/adv`.
#[derive(Deserialize)]
pub struct Advertisment {
#[serde(deserialize_with = "b64_to_str")]
Expand All @@ -34,16 +36,25 @@ impl Advertisment {
let verifier = get_verifier(verify_jwk)?;

// B64 is 4/3 data length, plus a `.`
let verify_len = ((self.payload.len() + self.protected.len()) * 4 / 3) + 1;
let mut to_verify = String::with_capacity(verify_len);
let payload_b64_len = Base64UrlUnpadded::encoded_len(self.payload.as_bytes());
let protected_b64_len = Base64UrlUnpadded::encoded_len(self.protected.as_bytes());
let mut to_verify = vec![b'.'; payload_b64_len + 1 + protected_b64_len];
dbg!(payload_b64_len, protected_b64_len);

// The format `b64(HEADER).b64(PAYLOAD)` is used for validation
BASE64_URL_SAFE_NO_PAD.encode_string(&self.protected, &mut to_verify);
to_verify.push('.');
BASE64_URL_SAFE_NO_PAD.encode_string(&self.payload, &mut to_verify);
Base64UrlUnpadded::encode(
&self.protected.as_bytes(),
&mut to_verify[..protected_b64_len],
)
.unwrap();
Base64UrlUnpadded::encode(
&self.payload.as_bytes(),
&mut to_verify[(protected_b64_len + 1)..],
)
.unwrap();

verifier
.verify(to_verify.as_bytes(), &self.signature)
.verify(&to_verify, &self.signature)
.map_err(Into::into)
}

Expand All @@ -67,7 +78,10 @@ impl fmt::Debug for Advertisment {
f.debug_struct("Advertisment")
.field("payload", &json_field(&self.payload))
.field("protected", &json_field(&self.protected))
.field("signature", &BASE64_URL_SAFE_NO_PAD.encode(&self.signature))
.field(
"signature",
&Base64UrlUnpadded::encode_string(&self.signature),
)
.finish()
}
}
Expand Down Expand Up @@ -220,12 +234,12 @@ fn make_thumbprint(jwk: &Jwk, alg: ThpHashAlg) -> Result<String> {
ThpHashAlg::Sha1 => {
let mut hasher = sha1::Sha1::new();
hasher.update(to_hash.as_bytes());
Ok(BASE64_URL_SAFE_NO_PAD.encode(hasher.finalize()))
Ok(Base64UrlUnpadded::encode_string(&hasher.finalize()))
}
ThpHashAlg::Sha256 => {
let mut hasher = Sha256::new();
hasher.update(to_hash.as_bytes());
Ok(BASE64_URL_SAFE_NO_PAD.encode(hasher.finalize()))
Ok(Base64UrlUnpadded::encode_string(&hasher.finalize()))
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/tang_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{sync::OnceLock, time::Duration};
use crate::jose::{Advertisment, JwkSet};
use crate::util::{b64_to_bytes, b64_to_str};
use crate::{Error, Result};
use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine};
use base64ct::{Base64UrlUnpadded, Encoding};
use josekit::jwk::Jwk;
use josekit::jws::alg::ecdsa::EcdsaJwsAlgorithm;
use josekit::jws::alg::eddsa::EddsaJwsAlgorithm;
Expand All @@ -16,6 +16,7 @@ use serde_json::{json, Value};
const DEFAULT_URL: &str = "http://tang.local";
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(120);

/// A tang server connection specification
#[derive(Clone, Debug)]
pub struct TangClient {
url: String,
Expand Down
7 changes: 2 additions & 5 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::BTreeMap;

use base64::prelude::BASE64_URL_SAFE_NO_PAD;
use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine};
use base64ct::{Base64UrlUnpadded, Encoding};
use serde::de::Error as DeError;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::{Map, Value as JsonValue};
Expand All @@ -20,8 +19,6 @@ where
D: Deserializer<'de>,
{
String::deserialize(deserializer).and_then(|string| {
BASE64_URL_SAFE_NO_PAD
.decode(&string)
.map_err(|err| DeError::custom(dbg!(err.to_string())))
Base64UrlUnpadded::decode_vec(&string).map_err(|err| DeError::custom(err.to_string()))
})
}

0 comments on commit 379a49e

Please sign in to comment.