1
0
mirror of https://github.com/BitskiCo/jwk-rs synced 2024-11-22 03:49:22 +00:00

Debug bytes as base64

This commit is contained in:
Nick Hynes 2021-01-26 14:54:07 +03:00
parent d89eb75794
commit 463e9221ba
No known key found for this signature in database
GPG Key ID: 5B3463E9F1D73C83
5 changed files with 76 additions and 27 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "jsonwebkey" name = "jsonwebkey"
version = "0.3.0" version = "0.3.1"
authors = ["Nick Hynes <nhynes@nhynes.com>"] authors = ["Nick Hynes <nhynes@nhynes.com>"]
description = "JSON Web Key (JWK) (de)serialization, generation, and conversion." description = "JSON Web Key (JWK) (de)serialization, generation, and conversion."
readme = "README.md" readme = "README.md"
@ -11,7 +11,6 @@ edition = "2018"
[dependencies] [dependencies]
base64 = "0.12" base64 = "0.12"
bitflags = "1.2" bitflags = "1.2"
derive_more = "0.99"
generic-array = "0.14" generic-array = "0.14"
jsonwebtoken = { version = "7.2", optional = true } jsonwebtoken = { version = "7.2", optional = true }
num-bigint = { version = "0.2", optional = true } num-bigint = { version = "0.2", optional = true }

View File

@ -1,15 +1,23 @@
use derive_more::{AsRef, Deref};
use generic_array::{ArrayLength, GenericArray}; use generic_array::{ArrayLength, GenericArray};
use serde::de::{self, Deserialize, Deserializer}; use serde::{
de::{self, Deserializer},
Deserialize, Serialize,
};
use zeroize::{Zeroize, Zeroizing}; use zeroize::{Zeroize, Zeroizing};
/// A zeroizing-on-drop container for a `[u8; N]` that deserializes from base64. /// A zeroizing-on-drop container for a `[u8; N]` that deserializes from base64.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deref, AsRef)] #[derive(Clone, PartialEq, Eq, Serialize)]
#[serde(transparent)] #[serde(transparent)]
pub struct ByteArray<N: ArrayLength<u8>>( pub struct ByteArray<N: ArrayLength<u8>>(
#[serde(serialize_with = "crate::utils::serde_base64::serialize")] pub GenericArray<u8, N>, #[serde(serialize_with = "crate::utils::serde_base64::serialize")] GenericArray<u8, N>,
); );
impl<N: ArrayLength<u8>> std::fmt::Debug for ByteArray<N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&crate::utils::base64_encode(&self.0))
}
}
impl<N: ArrayLength<u8>, T: Into<GenericArray<u8, N>>> From<T> for ByteArray<N> { impl<N: ArrayLength<u8>, T: Into<GenericArray<u8, N>>> From<T> for ByteArray<N> {
fn from(arr: T) -> Self { fn from(arr: T) -> Self {
Self(arr.into()) Self(arr.into())
@ -22,6 +30,19 @@ impl<N: ArrayLength<u8>> Drop for ByteArray<N> {
} }
} }
impl<N: ArrayLength<u8>> AsRef<[u8]> for ByteArray<N> {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl<N: ArrayLength<u8>> std::ops::Deref for ByteArray<N> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<N: ArrayLength<u8>> ByteArray<N> { impl<N: ArrayLength<u8>> ByteArray<N> {
/// An unwrapping version of `try_from_slice`. /// An unwrapping version of `try_from_slice`.
pub fn from_slice(bytes: impl AsRef<[u8]>) -> Self { pub fn from_slice(bytes: impl AsRef<[u8]>) -> Self {
@ -73,7 +94,7 @@ mod tests {
let b64 = serde_json::to_string(&arr).unwrap(); let b64 = serde_json::to_string(&arr).unwrap();
assert_eq!(b64, BASE64_JSON); assert_eq!(b64, BASE64_JSON);
let bytes: ByteArray<U7> = serde_json::from_str(&b64).unwrap(); let bytes: ByteArray<U7> = serde_json::from_str(&b64).unwrap();
assert_eq!(bytes.as_slice(), BYTES); assert_eq!(bytes.as_ref(), BYTES);
} }
#[test] #[test]

View File

@ -1,21 +1,34 @@
use std::fmt; use serde::{Deserialize, Serialize};
use derive_more::{AsRef, Deref, From};
use zeroize::Zeroize; use zeroize::Zeroize;
/// A zeroizing-on-drop container for a `Vec<u8>` that deserializes from base64. /// A zeroizing-on-drop container for a `Vec<u8>` that deserializes from base64.
#[derive(Clone, PartialEq, Eq, Zeroize, Serialize, Deserialize, Deref, AsRef, From)] #[derive(Clone, PartialEq, Eq, Zeroize, Serialize, Deserialize)]
#[zeroize(drop)] #[zeroize(drop)]
#[serde(transparent)] #[serde(transparent)]
pub struct ByteVec(#[serde(with = "crate::utils::serde_base64")] pub Vec<u8>); pub struct ByteVec(#[serde(with = "crate::utils::serde_base64")] Vec<u8>);
impl fmt::Debug for ByteVec { impl std::fmt::Debug for ByteVec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if cfg!(debug_assertions) { f.write_str(&crate::utils::base64_encode(&self.0))
write!(f, "{:?}", self.0) }
} else { }
write!(f, "ByteVec")
} impl<T: Into<Vec<u8>>> From<T> for ByteVec {
fn from(into_vec: T) -> Self {
Self(into_vec.into())
}
}
impl AsRef<[u8]> for ByteVec {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl std::ops::Deref for ByteVec {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
} }
} }
@ -31,6 +44,6 @@ mod tests {
let b64 = serde_json::to_string(&ByteVec(BYTES.to_vec())).unwrap(); let b64 = serde_json::to_string(&ByteVec(BYTES.to_vec())).unwrap();
assert_eq!(b64, BASE64_JSON); assert_eq!(b64, BASE64_JSON);
let bytes: ByteVec = serde_json::from_str(&b64).unwrap(); let bytes: ByteVec = serde_json::from_str(&b64).unwrap();
assert_eq!(bytes.as_slice(), BYTES); assert_eq!(bytes.as_ref(), BYTES);
} }
} }

View File

@ -58,9 +58,6 @@
//! This pulls in the [p256](https://crates.io/crates/p256) and [rand](https://crates.io/crates/rand) crates. //! This pulls in the [p256](https://crates.io/crates/p256) and [rand](https://crates.io/crates/rand) crates.
//! * `jsonwebtoken` - enables conversions to types in the [jsonwebtoken](https://crates.io/crates/jsonwebtoken) crate. //! * `jsonwebtoken` - enables conversions to types in the [jsonwebtoken](https://crates.io/crates/jsonwebtoken) crate.
#[macro_use]
extern crate serde;
mod byte_array; mod byte_array;
mod byte_vec; mod byte_vec;
mod key_ops; mod key_ops;
@ -69,6 +66,7 @@ mod tests;
mod utils; mod utils;
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt;
use generic_array::typenum::U32; use generic_array::typenum::U32;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -308,7 +306,7 @@ impl Key {
]); ]);
let oids = &[Some(&rsa_encryption_oid), None]; let oids = &[Some(&rsa_encryption_oid), None];
let write_bytevec = |writer: DERWriter<'_>, vec: &ByteVec| { let write_bytevec = |writer: DERWriter<'_>, vec: &ByteVec| {
let bigint = BigUint::from_bytes_be(vec.as_slice()); let bigint = BigUint::from_bytes_be(&vec);
writer.write_biguint(&bigint); writer.write_biguint(&bigint);
}; };
@ -435,7 +433,7 @@ impl Key {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "crv")] #[serde(tag = "crv")]
pub enum Curve { pub enum Curve {
/// Parameters of the prime256v1 (P256) curve. /// Parameters of the prime256v1 (P256) curve.
@ -451,6 +449,18 @@ pub enum Curve {
}, },
} }
impl fmt::Debug for Curve {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::P256 { x, y, .. } => f
.debug_struct("Curve:P256")
.field("x", x)
.field("y", y)
.finish(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct RsaPublic { pub struct RsaPublic {
/// The standard public exponent, 65537. /// The standard public exponent, 65537.
@ -487,7 +497,7 @@ impl<'de> Deserialize<'de> for PublicExponent {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RsaPrivate { pub struct RsaPrivate {
/// Private exponent. /// Private exponent.
pub d: ByteVec, pub d: ByteVec,
@ -508,6 +518,12 @@ pub struct RsaPrivate {
pub qi: Option<ByteVec>, pub qi: Option<ByteVec>,
} }
impl fmt::Debug for RsaPrivate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("RsaPrivate")
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum KeyUse { pub enum KeyUse {
#[serde(rename = "sig")] #[serde(rename = "sig")]

View File

@ -8,7 +8,7 @@ fn base64_config() -> base64::Config {
base64::Config::new(base64::CharacterSet::UrlSafe, false /* pad */) base64::Config::new(base64::CharacterSet::UrlSafe, false /* pad */)
} }
fn base64_encode(bytes: impl AsRef<[u8]>) -> String { pub(crate) fn base64_encode(bytes: impl AsRef<[u8]>) -> String {
base64::encode_config(bytes, base64_config()) base64::encode_config(bytes, base64_config())
} }