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