Implement Clone
and PartialEq
for all types.
See https://github.com/briansmith/ring/issues/859 for background.
This commit is contained in:
parent
aa9d546b1b
commit
c0d10881a2
74
src/lib.rs
74
src/lib.rs
@ -1,4 +1,4 @@
|
|||||||
//! Crate **ruma_signatures** implements digital signatures according to the
|
//! Crate `ruma_signatures` implements digital signatures according to the
|
||||||
//! [Matrix](https://matrix.org/) specification.
|
//! [Matrix](https://matrix.org/) specification.
|
||||||
//!
|
//!
|
||||||
//! Digital signatures are used by Matrix homeservers to verify the authenticity of events in the
|
//! Digital signatures are used by Matrix homeservers to verify the authenticity of events in the
|
||||||
@ -27,13 +27,16 @@
|
|||||||
//! "1".to_string(), // The "version" of the key.
|
//! "1".to_string(), // The "version" of the key.
|
||||||
//! ).expect("the provided keys should be suitable for Ed25519");
|
//! ).expect("the provided keys should be suitable for Ed25519");
|
||||||
//! let value = serde_json::from_str("{}").expect("an empty JSON object should deserialize");
|
//! let value = serde_json::from_str("{}").expect("an empty JSON object should deserialize");
|
||||||
//! ruma_signatures::sign_json(&key_pair, &value).expect("value is a a JSON object"); // `Signature`
|
//! let signature = ruma_signatures::sign_json(
|
||||||
|
//! &key_pair,
|
||||||
|
//! &value,
|
||||||
|
//! ).expect("`value` must be a JSON object");
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! # Signing Matrix events
|
//! # Signing Matrix events
|
||||||
//!
|
//!
|
||||||
//! Signing an event uses a more involved process than signing arbitrary JSON.
|
//! Signing an event uses a more involved process than signing arbitrary JSON.
|
||||||
//! Event signing is not yet implemented by ruma_signatures.
|
//! Event signing is not yet implemented by ruma-signatures.
|
||||||
//!
|
//!
|
||||||
//! # Verifying signatures
|
//! # Verifying signatures
|
||||||
//!
|
//!
|
||||||
@ -52,7 +55,7 @@
|
|||||||
//! assert!(ruma_signatures::verify_json(&verifier, &public_key, &signature, &value).is_ok());
|
//! assert!(ruma_signatures::verify_json(&verifier, &public_key, &signature, &value).is_ok());
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Verifying signatures of Matrix events is not yet implemented by ruma_signatures.
|
//! Verifying signatures of Matrix events is not yet implemented by ruma-signatures.
|
||||||
//!
|
//!
|
||||||
//! # Signature sets
|
//! # Signature sets
|
||||||
//!
|
//!
|
||||||
@ -142,7 +145,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
error::Error as StdError,
|
error::Error as StdError,
|
||||||
fmt::{Display, Formatter, Result as FmtResult},
|
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
use base64::{decode_config, encode_config, CharacterSet, Config};
|
use base64::{decode_config, encode_config, CharacterSet, Config};
|
||||||
@ -234,7 +237,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An error when trying to extract the algorithm and version from a key identifier.
|
/// An error when trying to extract the algorithm and version from a key identifier.
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum SplitError<'a> {
|
enum SplitError<'a> {
|
||||||
/// The signature's ID has an invalid length.
|
/// The signature's ID has an invalid length.
|
||||||
InvalidLength(usize),
|
InvalidLength(usize),
|
||||||
@ -273,20 +276,24 @@ pub enum Algorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An Ed25519 key pair.
|
/// An Ed25519 key pair.
|
||||||
#[derive(Debug)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct Ed25519KeyPair {
|
pub struct Ed25519KeyPair {
|
||||||
/// The *ring* key pair.
|
/// The public key.
|
||||||
ring_key_pair: RingEd25519KeyPair,
|
public_key: Vec<u8>,
|
||||||
|
|
||||||
|
/// The private key.
|
||||||
|
private_key: Vec<u8>,
|
||||||
|
|
||||||
/// The version of the key pair.
|
/// The version of the key pair.
|
||||||
version: String,
|
version: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A verifier for Ed25519 digital signatures.
|
/// A verifier for Ed25519 digital signatures.
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||||
pub struct Ed25519Verifier;
|
pub struct Ed25519Verifier;
|
||||||
|
|
||||||
/// An error produced when `ruma_signatures` operations fail.
|
/// An error produced when ruma-signatures operations fail.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
/// A human-readable description of the error.
|
/// A human-readable description of the error.
|
||||||
message: String,
|
message: String,
|
||||||
@ -330,7 +337,7 @@ pub struct Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A map of server names to sets of digital signatures created by that server.
|
/// A map of server names to sets of digital signatures created by that server.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct Signatures {
|
pub struct Signatures {
|
||||||
/// A map of homeservers to sets of signatures for the homeserver.
|
/// A map of homeservers to sets of signatures for the homeserver.
|
||||||
map: HashMap<Host, SignatureSet>,
|
map: HashMap<Host, SignatureSet>,
|
||||||
@ -340,7 +347,7 @@ pub struct Signatures {
|
|||||||
struct SignaturesVisitor;
|
struct SignaturesVisitor;
|
||||||
|
|
||||||
/// A set of digital signatures created by a single homeserver.
|
/// A set of digital signatures created by a single homeserver.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub struct SignatureSet {
|
pub struct SignatureSet {
|
||||||
/// A set of signatures for a homeserver.
|
/// A set of signatures for a homeserver.
|
||||||
set: HashSet<Signature>,
|
set: HashSet<Signature>,
|
||||||
@ -372,25 +379,46 @@ pub trait Verifier {
|
|||||||
|
|
||||||
impl KeyPair for Ed25519KeyPair {
|
impl KeyPair for Ed25519KeyPair {
|
||||||
fn new(public_key: &[u8], private_key: &[u8], version: String) -> Result<Self, Error> {
|
fn new(public_key: &[u8], private_key: &[u8], version: String) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
if let Err(error) = RingEd25519KeyPair::from_seed_and_public_key(
|
||||||
ring_key_pair: RingEd25519KeyPair::from_seed_and_public_key(
|
|
||||||
Input::from(private_key),
|
Input::from(private_key),
|
||||||
Input::from(public_key),
|
Input::from(public_key),
|
||||||
)
|
) {
|
||||||
.map_err(|_| Error::new("invalid key pair"))?,
|
return Err(Error::new(error.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
public_key: public_key.to_owned(),
|
||||||
|
private_key: private_key.to_owned(),
|
||||||
version,
|
version,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(&self, message: &[u8]) -> Signature {
|
fn sign(&self, message: &[u8]) -> Signature {
|
||||||
|
// Okay to unwrap because we verified the input in the `new`.
|
||||||
|
let ring_key_pair = RingEd25519KeyPair::from_seed_and_public_key(
|
||||||
|
Input::from(&self.private_key),
|
||||||
|
Input::from(&self.public_key),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Signature {
|
Signature {
|
||||||
algorithm: Algorithm::Ed25519,
|
algorithm: Algorithm::Ed25519,
|
||||||
signature: self.ring_key_pair.sign(message).as_ref().to_vec(),
|
signature: ring_key_pair.sign(message).as_ref().to_vec(),
|
||||||
version: self.version.clone(),
|
version: self.version.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for Ed25519KeyPair {
|
||||||
|
fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
|
||||||
|
formatter
|
||||||
|
.debug_struct("Ed25519KeyPair")
|
||||||
|
.field("public_key", &self.public_key)
|
||||||
|
.field("version", &self.version)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Ed25519Verifier {
|
impl Ed25519Verifier {
|
||||||
/// Creates a new `Ed25519Verifier`.
|
/// Creates a new `Ed25519Verifier`.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -745,12 +773,12 @@ mod test {
|
|||||||
Signatures, BASE64_CONFIG,
|
Signatures, BASE64_CONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PUBLIC_KEY: &'static str = "XGX0JRS2Af3be3knz2fBiRbApjm2Dh61gXDJA8kcJNI";
|
const PUBLIC_KEY: &str = "XGX0JRS2Af3be3knz2fBiRbApjm2Dh61gXDJA8kcJNI";
|
||||||
const PRIVATE_KEY: &'static str = "YJDBA9Xnr2sVqXD9Vj7XVUnmFZcZrlw8Md7kMW+3XA0";
|
const PRIVATE_KEY: &str = "YJDBA9Xnr2sVqXD9Vj7XVUnmFZcZrlw8Md7kMW+3XA0";
|
||||||
|
|
||||||
const EMPTY_JSON_SIGNATURE: &'static str =
|
const EMPTY_JSON_SIGNATURE: &str =
|
||||||
"K8280/U9SSy9IVtjBuVeLr+HpOB4BQFWbg+UZaADMtTdGYI7Geitb76LTrr5QV/7Xg4ahLwYGYZzuHGZKM5ZAQ";
|
"K8280/U9SSy9IVtjBuVeLr+HpOB4BQFWbg+UZaADMtTdGYI7Geitb76LTrr5QV/7Xg4ahLwYGYZzuHGZKM5ZAQ";
|
||||||
const MINIMAL_JSON_SIGNATURE: &'static str =
|
const MINIMAL_JSON_SIGNATURE: &str =
|
||||||
"KqmLSbO39/Bzb0QIYE82zqLwsA+PDzYIpIRA2sRQ4sL53+sN6/fpNSoqE7BP7vBZhG6kYdD13EIMJpvhJI+6Bw";
|
"KqmLSbO39/Bzb0QIYE82zqLwsA+PDzYIpIRA2sRQ4sL53+sN6/fpNSoqE7BP7vBZhG6kYdD13EIMJpvhJI+6Bw";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user