Upgrade base64 to 0.20
This commit is contained in:
parent
e4678284ca
commit
536341ca7e
@ -7,7 +7,7 @@ resolver = "2"
|
||||
[workspace.dependencies]
|
||||
assert_matches = "1.5.0"
|
||||
assign = "1.1.1"
|
||||
base64 = "0.13.1"
|
||||
base64 = "0.20.0"
|
||||
criterion = "0.4.0"
|
||||
http = "0.2.8"
|
||||
js_int = "0.2.2"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use std::{fmt, marker::PhantomData};
|
||||
|
||||
use base64::engine::fast_portable::{self, FastPortable, FastPortableConfig};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// A wrapper around `B` (usually `Vec<u8>`) that (de)serializes from / to a base64 string.
|
||||
@ -25,7 +26,7 @@ pub trait Base64Config {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct Conf(base64::Config);
|
||||
pub struct Conf(base64::alphabet::Alphabet);
|
||||
|
||||
/// Standard base64 character set without padding.
|
||||
///
|
||||
@ -36,8 +37,7 @@ pub struct Conf(base64::Config);
|
||||
pub struct Standard;
|
||||
|
||||
impl Base64Config for Standard {
|
||||
// See https://github.com/matrix-org/matrix-spec/issues/838
|
||||
const CONF: Conf = Conf(base64::STANDARD_NO_PAD.decode_allow_trailing_bits(true));
|
||||
const CONF: Conf = Conf(base64::alphabet::STANDARD);
|
||||
}
|
||||
|
||||
/// Url-safe base64 character set without padding.
|
||||
@ -49,7 +49,13 @@ impl Base64Config for Standard {
|
||||
pub struct UrlSafe;
|
||||
|
||||
impl Base64Config for UrlSafe {
|
||||
const CONF: Conf = Conf(base64::URL_SAFE_NO_PAD.decode_allow_trailing_bits(true));
|
||||
const CONF: Conf = Conf(base64::alphabet::URL_SAFE);
|
||||
}
|
||||
|
||||
impl<C: Base64Config, B> Base64<C, B> {
|
||||
// See https://github.com/matrix-org/matrix-spec/issues/838
|
||||
const CONFIG: FastPortableConfig = fast_portable::NO_PAD.with_decode_allow_trailing_bits(true);
|
||||
const ENGINE: FastPortable = FastPortable::from(&C::CONF.0, Self::CONFIG);
|
||||
}
|
||||
|
||||
impl<C: Base64Config, B: AsRef<[u8]>> Base64<C, B> {
|
||||
@ -65,7 +71,7 @@ impl<C: Base64Config, B: AsRef<[u8]>> Base64<C, B> {
|
||||
|
||||
/// Encode the bytes contained in this `Base64` instance to unpadded base64.
|
||||
pub fn encode(&self) -> String {
|
||||
base64::encode_config(&self.bytes, C::CONF.0)
|
||||
base64::encode_engine(self.as_bytes(), &Self::ENGINE)
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +90,7 @@ impl<C: Base64Config> Base64<C> {
|
||||
|
||||
/// Parse some base64-encoded data to create a `Base64` instance.
|
||||
pub fn parse(encoded: impl AsRef<[u8]>) -> Result<Self, Base64DecodeError> {
|
||||
base64::decode_config(encoded, C::CONF.0).map(Self::new).map_err(Base64DecodeError)
|
||||
base64::decode_engine(encoded, &Self::ENGINE).map(Self::new).map_err(Base64DecodeError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use std::{
|
||||
mem,
|
||||
};
|
||||
|
||||
use base64::{encode_config, STANDARD_NO_PAD, URL_SAFE_NO_PAD};
|
||||
use base64::{alphabet, encode_engine};
|
||||
use ruma_common::{
|
||||
canonical_json::{redact, JsonType},
|
||||
serde::{base64::Standard, Base64},
|
||||
@ -55,16 +55,18 @@ static REFERENCE_HASH_FIELDS_TO_REMOVE: &[&str] = &["age_ts", "signatures", "uns
|
||||
/// A homeserver signs JSON with a key pair:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ruma_common::serde::base64::Base64;
|
||||
/// #
|
||||
/// const PKCS8: &str = "\
|
||||
/// MFECAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
|
||||
/// tA0T+6tgSEA3TPraTczVkDPTRaX4K+AfUuyx7Mzq1UafTXypnl0t2k=\
|
||||
/// tA0T+6tgSEA3TPraTczVkDPTRaX4K+AfUuyx7Mzq1UafTXypnl0t2k\
|
||||
/// ";
|
||||
///
|
||||
/// let document = base64::decode_config(&PKCS8, base64::STANDARD_NO_PAD).unwrap();
|
||||
/// let document: Base64 = Base64::parse(PKCS8).unwrap();
|
||||
///
|
||||
/// // Create an Ed25519 key pair.
|
||||
/// let key_pair = ruma_signatures::Ed25519KeyPair::from_der(
|
||||
/// &document,
|
||||
/// document.as_bytes(),
|
||||
/// "1".into(), // The "version" of the key.
|
||||
/// )
|
||||
/// .unwrap();
|
||||
@ -331,14 +333,17 @@ pub fn reference_hash(
|
||||
|
||||
let hash = Sha256::digest(json.as_bytes());
|
||||
|
||||
Ok(encode_config(
|
||||
hash,
|
||||
match version {
|
||||
RoomVersionId::V1 | RoomVersionId::V2 | RoomVersionId::V3 => STANDARD_NO_PAD,
|
||||
// Room versions higher than version 3 are url safe base64 encoded
|
||||
_ => URL_SAFE_NO_PAD,
|
||||
},
|
||||
))
|
||||
let base64_alphabet = match version {
|
||||
RoomVersionId::V1 | RoomVersionId::V2 | RoomVersionId::V3 => alphabet::STANDARD,
|
||||
// Room versions higher than version 3 are url safe base64 encoded
|
||||
_ => alphabet::URL_SAFE,
|
||||
};
|
||||
let base64_engine = base64::engine::fast_portable::FastPortable::from(
|
||||
&base64_alphabet,
|
||||
base64::engine::fast_portable::NO_PAD,
|
||||
);
|
||||
|
||||
Ok(encode_engine(hash, &base64_engine))
|
||||
}
|
||||
|
||||
/// Hashes and signs an event and adds the hash and signature to objects under the keys `hashes` and
|
||||
@ -366,19 +371,19 @@ pub fn reference_hash(
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ruma_common::RoomVersionId;
|
||||
/// # use ruma_common::{RoomVersionId, serde::base64::Base64};
|
||||
/// # use ruma_signatures::{hash_and_sign_event, Ed25519KeyPair};
|
||||
/// #
|
||||
/// const PKCS8: &str = "\
|
||||
/// MFECAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
|
||||
/// tA0T+6tgSEA3TPraTczVkDPTRaX4K+AfUuyx7Mzq1UafTXypnl0t2k=\
|
||||
/// tA0T+6tgSEA3TPraTczVkDPTRaX4K+AfUuyx7Mzq1UafTXypnl0t2k\
|
||||
/// ";
|
||||
///
|
||||
/// let document = base64::decode_config(&PKCS8, base64::STANDARD_NO_PAD).unwrap();
|
||||
/// let document: Base64 = Base64::parse(PKCS8).unwrap();
|
||||
///
|
||||
/// // Create an Ed25519 key pair.
|
||||
/// let key_pair = Ed25519KeyPair::from_der(
|
||||
/// &document,
|
||||
/// document.as_bytes(),
|
||||
/// "1".into(), // The "version" of the key.
|
||||
/// )
|
||||
/// .unwrap();
|
||||
|
@ -103,29 +103,29 @@ fn split_id(id: &str) -> Result<(Algorithm, String), Error> {
|
||||
mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use base64::{decode_config, STANDARD_NO_PAD};
|
||||
use pkcs8::{der::Decode, PrivateKeyInfo};
|
||||
use ruma_common::{serde::Base64, RoomVersionId};
|
||||
use ruma_common::{
|
||||
serde::{base64::Standard, Base64},
|
||||
RoomVersionId,
|
||||
};
|
||||
use serde_json::{from_str as from_json_str, to_string as to_json_string};
|
||||
|
||||
use super::{
|
||||
canonical_json, hash_and_sign_event, sign_json, verify_event, verify_json, Ed25519KeyPair,
|
||||
};
|
||||
|
||||
const PKCS8: &str = "\
|
||||
MFECAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
|
||||
tA0T+6tgSEA3TPraTczVkDPTRaX4K+AfUuyx7Mzq1UafTXypnl0t2k=\
|
||||
";
|
||||
fn pkcs8() -> Vec<u8> {
|
||||
const ENCODED: &str = "\
|
||||
MFECAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
|
||||
tA0T+6tgSEA3TPraTczVkDPTRaX4K+AfUuyx7Mzq1UafTXypnl0t2k\
|
||||
";
|
||||
|
||||
Base64::<Standard>::parse(ENCODED).unwrap().into_inner()
|
||||
}
|
||||
|
||||
/// Convenience method for getting the public key as a string
|
||||
fn public_key_string() -> Base64 {
|
||||
Base64::new(
|
||||
PrivateKeyInfo::from_der(&decode_config(PKCS8, STANDARD_NO_PAD).unwrap())
|
||||
.unwrap()
|
||||
.public_key
|
||||
.unwrap()
|
||||
.to_owned(),
|
||||
)
|
||||
Base64::new(PrivateKeyInfo::from_der(&pkcs8()).unwrap().public_key.unwrap().to_owned())
|
||||
}
|
||||
|
||||
/// Convenience for converting a string of JSON into its canonical form.
|
||||
@ -225,11 +225,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn sign_empty_json() {
|
||||
let key_pair = Ed25519KeyPair::from_der(
|
||||
decode_config(PKCS8, STANDARD_NO_PAD).unwrap().as_slice(),
|
||||
"1".into(),
|
||||
)
|
||||
.unwrap();
|
||||
let key_pair = Ed25519KeyPair::from_der(&pkcs8(), "1".into()).unwrap();
|
||||
|
||||
let mut value = from_json_str("{}").unwrap();
|
||||
|
||||
@ -256,11 +252,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn sign_minimal_json() {
|
||||
let key_pair = Ed25519KeyPair::from_der(
|
||||
decode_config(PKCS8, STANDARD_NO_PAD).unwrap().as_slice(),
|
||||
"1".into(),
|
||||
)
|
||||
.unwrap();
|
||||
let key_pair = Ed25519KeyPair::from_der(&pkcs8(), "1".into()).unwrap();
|
||||
|
||||
let mut alpha_object = from_json_str(r#"{ "one": 1, "two": "Two" }"#).unwrap();
|
||||
sign_json("domain", &key_pair, &mut alpha_object).unwrap();
|
||||
@ -316,11 +308,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn sign_minimal_event() {
|
||||
let key_pair = Ed25519KeyPair::from_der(
|
||||
decode_config(PKCS8, STANDARD_NO_PAD).unwrap().as_slice(),
|
||||
"1".into(),
|
||||
)
|
||||
.unwrap();
|
||||
let key_pair = Ed25519KeyPair::from_der(&pkcs8(), "1".into()).unwrap();
|
||||
|
||||
let json = r#"{
|
||||
"room_id": "!x:domain",
|
||||
@ -350,11 +338,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn sign_redacted_event() {
|
||||
let key_pair = Ed25519KeyPair::from_der(
|
||||
decode_config(PKCS8, STANDARD_NO_PAD).unwrap().as_slice(),
|
||||
"1".into(),
|
||||
)
|
||||
.unwrap();
|
||||
let key_pair = Ed25519KeyPair::from_der(&pkcs8(), "1".into()).unwrap();
|
||||
|
||||
let json = r#"{
|
||||
"content": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Digital signatures and collections of signatures.
|
||||
|
||||
use base64::{encode_config, STANDARD_NO_PAD};
|
||||
use ruma_common::serde::{base64::Standard, Base64};
|
||||
|
||||
use crate::{split_id, Algorithm, Error};
|
||||
|
||||
@ -61,7 +61,7 @@ impl Signature {
|
||||
///
|
||||
/// Uses the standard character set with no padding.
|
||||
pub fn base64(&self) -> String {
|
||||
encode_config(self.signature.as_slice(), STANDARD_NO_PAD)
|
||||
Base64::<Standard, _>::new(self.signature.as_slice()).encode()
|
||||
}
|
||||
|
||||
/// The key identifier, a string containing the signature algorithm and the key "version"
|
||||
|
Loading…
x
Reference in New Issue
Block a user