Make SignatureMap and SignatureSet type aliases for HashMap.
This commit is contained in:
parent
efbea86fe5
commit
e64df47d23
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
use std::{collections::HashMap, hash::BuildHasher};
|
use std::{collections::HashMap, hash::BuildHasher};
|
||||||
|
|
||||||
use base64::{encode_config, STANDARD_NO_PAD};
|
use base64::{decode_config, encode_config, STANDARD_NO_PAD};
|
||||||
use ring::digest::{digest, SHA256};
|
use ring::digest::{digest, SHA256};
|
||||||
use serde_json::{from_str, from_value, map::Map, to_string, to_value, Value};
|
use serde_json::{from_str, from_value, map::Map, to_string, to_value, Value};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
keys::KeyPair,
|
keys::KeyPair,
|
||||||
signatures::{Signature, SignatureMap, SignatureSet},
|
signatures::{Signature, SignatureMap},
|
||||||
verification::Verifier,
|
verification::Verifier,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -128,7 +128,7 @@ where
|
|||||||
Some(signatures) => from_value(Value::Object(signatures.clone()))?,
|
Some(signatures) => from_value(Value::Object(signatures.clone()))?,
|
||||||
None => return Err(Error::new("Field `signatures` must be a JSON object")),
|
None => return Err(Error::new("Field `signatures` must be a JSON object")),
|
||||||
},
|
},
|
||||||
None => SignatureMap::with_capacity(1),
|
None => HashMap::with_capacity(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
maybe_unsigned = map.remove("unsigned");
|
maybe_unsigned = map.remove("unsigned");
|
||||||
@ -142,10 +142,10 @@ where
|
|||||||
|
|
||||||
// Insert the new signature in the map we pulled out (or created) previously.
|
// Insert the new signature in the map we pulled out (or created) previously.
|
||||||
let signature_set = signature_map
|
let signature_set = signature_map
|
||||||
.entry(server_name)?
|
.entry(server_name.to_string())
|
||||||
.or_insert_with(|| SignatureSet::with_capacity(1));
|
.or_insert_with(|| HashMap::with_capacity(1));
|
||||||
|
|
||||||
signature_set.insert(signature);
|
signature_set.insert(signature.id(), signature.base64());
|
||||||
|
|
||||||
// Safe to unwrap because we did this exact check at the beginning of the function.
|
// Safe to unwrap because we did this exact check at the beginning of the function.
|
||||||
let map = value.as_object_mut().unwrap();
|
let map = value.as_object_mut().unwrap();
|
||||||
@ -490,7 +490,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (server_name, verify_keys) in verify_key_map {
|
for (server_name, verify_keys) in verify_key_map {
|
||||||
let signature_set = match signature_map.get(server_name)? {
|
let signature_set = match signature_map.get(server_name) {
|
||||||
Some(set) => set,
|
Some(set) => set,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::new(format!(
|
return Err(Error::new(format!(
|
||||||
@ -532,7 +532,15 @@ where
|
|||||||
|
|
||||||
let canonical_json = from_str(&to_canonical_json(&redacted)?)?;
|
let canonical_json = from_str(&to_canonical_json(&redacted)?)?;
|
||||||
|
|
||||||
verify_json(verifier, verify_key, signature, &canonical_json)?;
|
verify_json(
|
||||||
|
verifier,
|
||||||
|
verify_key,
|
||||||
|
&Signature::new(
|
||||||
|
"ed25519:fixme",
|
||||||
|
&decode_config(signature, STANDARD_NO_PAD).expect("FIXME"),
|
||||||
|
)?,
|
||||||
|
&canonical_json,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,37 +1,36 @@
|
|||||||
//! Digital signatures and collections of signatures.
|
//! Digital signatures and collections of signatures.
|
||||||
|
|
||||||
use std::{
|
use std::collections::HashMap;
|
||||||
collections::{hash_map::Entry, HashMap},
|
|
||||||
error::Error as _,
|
|
||||||
fmt::{Formatter, Result as FmtResult},
|
|
||||||
};
|
|
||||||
|
|
||||||
use base64::{decode_config, encode_config, STANDARD_NO_PAD};
|
use base64::{encode_config, STANDARD_NO_PAD};
|
||||||
use serde::{
|
|
||||||
de::{Error as SerdeError, MapAccess, Unexpected, Visitor},
|
|
||||||
ser::SerializeMap,
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
use url::{Host, Url};
|
|
||||||
|
|
||||||
use crate::{Algorithm, Error};
|
use crate::{Algorithm, Error};
|
||||||
|
|
||||||
/// A digital signature.
|
/// A digital signature.
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
pub struct Signature {
|
pub struct Signature {
|
||||||
/// The cryptographic algorithm to use.
|
/// The cryptographic algorithm that generated this signature.
|
||||||
pub(crate) algorithm: Algorithm,
|
pub algorithm: Algorithm,
|
||||||
|
|
||||||
/// The signature data.
|
/// The signature data.
|
||||||
pub(crate) signature: Vec<u8>,
|
pub signature: Vec<u8>,
|
||||||
|
|
||||||
/// The version of the signature.
|
/// The "version" of the key identifier for the public key used to generate this signature.
|
||||||
pub(crate) version: String,
|
pub version: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Signature {
|
impl Signature {
|
||||||
/// Creates a signature from raw bytes.
|
/// Creates a signature from raw bytes.
|
||||||
///
|
///
|
||||||
|
/// While a signature can be created directly using struct literal syntax, this constructor can
|
||||||
|
/// be used to automatically determine the algorithm and version from a key identifier in the
|
||||||
|
/// form *algorithm:version*, e.g. "ed25519:1".
|
||||||
|
///
|
||||||
|
/// This constructor will ensure that the version does not contain characters that violate the
|
||||||
|
/// guidelines in the specification. Because it may be necessary to represent signatures with
|
||||||
|
/// versions that don't adhere to these guidelines, it's possible to simply use the struct
|
||||||
|
/// literal syntax to construct a `Signature` with an arbitrary key.
|
||||||
|
///
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
///
|
///
|
||||||
/// * id: A key identifier, e.g. "ed25519:1".
|
/// * id: A key identifier, e.g. "ed25519:1".
|
||||||
@ -88,354 +87,15 @@ impl Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A map from server names to sets of digital signatures created by that server.
|
/// A map from entity names to sets of digital signatures created by that entity.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// "Entity" is currently always a homeserver, e.g. "example.com".
|
||||||
///
|
pub type SignatureMap = HashMap<String, SignatureSet>;
|
||||||
/// Creating and serializing a `SignatureMap`:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// const SIGNATURE_BYTES: &str =
|
|
||||||
/// "K8280/U9SSy9IVtjBuVeLr+HpOB4BQFWbg+UZaADMtTdGYI7Geitb76LTrr5QV/7Xg4ahLwYGYZzuHGZKM5ZAQ";
|
|
||||||
///
|
|
||||||
/// // Create a `Signature` from the raw bytes of the signature.
|
|
||||||
/// let signature_bytes = base64::decode_config(&SIGNATURE_BYTES, base64::STANDARD_NO_PAD).unwrap();
|
|
||||||
/// let signature = ruma_signatures::Signature::new("ed25519:1", &signature_bytes).unwrap();
|
|
||||||
///
|
|
||||||
/// // Create a `SignatureSet` and insert the signature into it.
|
|
||||||
/// let mut signature_set = ruma_signatures::SignatureSet::new();
|
|
||||||
/// signature_set.insert(signature);
|
|
||||||
///
|
|
||||||
/// // Create a `SignatureMap` and insert the set into it, keyed by the homeserver name.
|
|
||||||
/// let mut signature_map = ruma_signatures::SignatureMap::new();
|
|
||||||
/// signature_map.insert("example.com", signature_set).unwrap();
|
|
||||||
///
|
|
||||||
/// // Serialize the map to JSON.
|
|
||||||
/// assert!(serde_json::to_string(&signature_map).is_ok());
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
|
||||||
pub struct SignatureMap {
|
|
||||||
/// A map from homeservers to sets of signatures for the homeserver.
|
|
||||||
map: HashMap<Host, SignatureSet>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SignatureMap {
|
|
||||||
/// Initializes a new empty `SignatureMap`.
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
map: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes a new empty `SignatureMap` with room for a specific number of servers.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * capacity: The number of items to allocate memory for.
|
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
map: HashMap::with_capacity(capacity),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a signature set for a server.
|
|
||||||
///
|
|
||||||
/// If no signature set for the given server existed in the collection, `None` is returned.
|
|
||||||
/// Otherwise, the signature set is returned.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * server_name: The hostname or IP of the homeserver, e.g. `example.com`.
|
|
||||||
/// * signature_set: The `SignatureSet` containing the digital signatures made by the server.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns an error if the given server name cannot be parsed as a valid host.
|
|
||||||
pub fn insert(
|
|
||||||
&mut self,
|
|
||||||
server_name: &str,
|
|
||||||
signature_set: SignatureSet,
|
|
||||||
) -> Result<Option<SignatureSet>, Error> {
|
|
||||||
let host = server_name_to_host(server_name)?;
|
|
||||||
|
|
||||||
Ok(self.map.insert(host, signature_set))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the given server's corresponding signature set for in-place manipulation.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * server_name: The hostname or IP of the homeserver, e.g. `example.com`.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns an error if the given server name cannot be parsed as a valid host.
|
|
||||||
pub fn entry(&mut self, server_name: &str) -> Result<Entry<Host, SignatureSet>, Error> {
|
|
||||||
let host = server_name_to_host(server_name)?;
|
|
||||||
|
|
||||||
Ok(self.map.entry(host))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a reference to the signature set for the given server, if any.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * server_name: The hostname or IP of the homeserver, e.g. `example.com`.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns an error if the given server name cannot be parsed as a valid host.
|
|
||||||
pub fn get(&self, server_name: &str) -> Result<Option<&SignatureSet>, Error> {
|
|
||||||
let host = server_name_to_host(server_name)?;
|
|
||||||
|
|
||||||
Ok(self.map.get(&host))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a mutable reference to the signature set for the given server, if any.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * server_name: The hostname or IP of the homeserver, e.g. `example.com`.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns an error if the given server name cannot be parsed as a valid host.
|
|
||||||
pub fn get_mut(&mut self, server_name: &str) -> Result<Option<&mut SignatureSet>, Error> {
|
|
||||||
let host = server_name_to_host(server_name)?;
|
|
||||||
|
|
||||||
Ok(self.map.get_mut(&host))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The number of servers in the collection.
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.map.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether or not the collection of signatures is empty.
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.len() == 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for SignatureMap {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
|
|
||||||
|
|
||||||
for (host, signature_set) in self.map.iter() {
|
|
||||||
map_serializer.serialize_key(&host.to_string())?;
|
|
||||||
map_serializer.serialize_value(signature_set)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
map_serializer.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for SignatureMap {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
deserializer.deserialize_map(SignatureMapVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serde Visitor for deserializing `SignatureMap`.
|
|
||||||
struct SignatureMapVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for SignatureMapVisitor {
|
|
||||||
type Value = SignatureMap;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "digital signatures")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
|
|
||||||
where
|
|
||||||
M: MapAccess<'de>,
|
|
||||||
{
|
|
||||||
let mut signatures = match visitor.size_hint() {
|
|
||||||
Some(capacity) => SignatureMap::with_capacity(capacity),
|
|
||||||
None => SignatureMap::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
while let Some((server_name, signature_set)) =
|
|
||||||
visitor.next_entry::<String, SignatureSet>()?
|
|
||||||
{
|
|
||||||
if signatures.insert(&server_name, signature_set).is_err() {
|
|
||||||
return Err(M::Error::invalid_value(
|
|
||||||
Unexpected::Str(&server_name),
|
|
||||||
&self,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(signatures)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A set of digital signatures created by a single homeserver.
|
/// A set of digital signatures created by a single homeserver.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// This is represented as a map from signing key ID to Base64-encoded signature.
|
||||||
///
|
pub type SignatureSet = HashMap<String, String>;
|
||||||
/// Creating and serializing a `SignatureSet`:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// const SIGNATURE_BYTES: &str =
|
|
||||||
/// "K8280/U9SSy9IVtjBuVeLr+HpOB4BQFWbg+UZaADMtTdGYI7Geitb76LTrr5QV/7Xg4ahLwYGYZzuHGZKM5ZAQ";
|
|
||||||
///
|
|
||||||
/// // Create a `Signature` from the raw bytes of the signature.
|
|
||||||
/// let signature_bytes = base64::decode_config(&SIGNATURE_BYTES, base64::STANDARD_NO_PAD).unwrap();
|
|
||||||
/// let signature = ruma_signatures::Signature::new("ed25519:1", &signature_bytes).unwrap();
|
|
||||||
///
|
|
||||||
/// // Create a `SignatureSet` and insert the signature into it.
|
|
||||||
/// let mut signature_set = ruma_signatures::SignatureSet::new();
|
|
||||||
/// signature_set.insert(signature);
|
|
||||||
///
|
|
||||||
/// // Serialize the set to JSON.
|
|
||||||
/// assert!(serde_json::to_string(&signature_set).is_ok());
|
|
||||||
/// ```
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
|
||||||
pub struct SignatureSet {
|
|
||||||
/// A set of signatures for a homeserver.
|
|
||||||
map: HashMap<String, Signature>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SignatureSet {
|
|
||||||
/// Initializes a new empty SignatureSet.
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
map: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes a new empty SignatureSet with room for a specific number of signatures.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * capacity: The number of items to allocate memory for.
|
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
map: HashMap::with_capacity(capacity),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a signature to the set.
|
|
||||||
///
|
|
||||||
/// If no signature with the given key ID existed in the collection, `None` is returned.
|
|
||||||
/// Otherwise, the signature is returned.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * signature: A `Signature` to insert into the set.
|
|
||||||
pub fn insert(&mut self, signature: Signature) -> Option<Signature> {
|
|
||||||
self.map.insert(signature.id(), signature)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a reference to the signature with the given key ID, if any.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * key_id: The identifier of the public key (e.g. "ed25519:1") for the desired signature.
|
|
||||||
pub fn get(&self, key_id: &str) -> Option<&Signature> {
|
|
||||||
self.map.get(key_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a mutable reference to the signature with the given ID, if any.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * key_id: The identifier of the public key (e.g. "ed25519:1") for the desired signature.
|
|
||||||
pub fn get_mut(&mut self, key_id: &str) -> Option<&mut Signature> {
|
|
||||||
self.map.get_mut(key_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The number of signatures in the set.
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.map.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether or not the set of signatures is empty.
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.len() == 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for SignatureSet {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
|
|
||||||
|
|
||||||
for signature in self.map.values() {
|
|
||||||
map_serializer.serialize_key(&signature.id())?;
|
|
||||||
map_serializer.serialize_value(&signature.base64())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
map_serializer.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for SignatureSet {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
deserializer.deserialize_map(SignatureSetVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serde Visitor for deserializing `SignatureSet`.
|
|
||||||
struct SignatureSetVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for SignatureSetVisitor {
|
|
||||||
type Value = SignatureSet;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter<'_>) -> FmtResult {
|
|
||||||
write!(formatter, "a set of digital signatures")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
|
|
||||||
where
|
|
||||||
M: MapAccess<'de>,
|
|
||||||
{
|
|
||||||
let mut signature_set = match visitor.size_hint() {
|
|
||||||
Some(capacity) => SignatureSet::with_capacity(capacity),
|
|
||||||
None => SignatureSet::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
while let Some((key, value)) = visitor.next_entry::<String, String>()? {
|
|
||||||
let (algorithm, version) = split_id(&key).map_err(|split_error| match split_error {
|
|
||||||
SplitError::InvalidLength(length) => M::Error::invalid_length(length, &self),
|
|
||||||
SplitError::InvalidVersion(version) => {
|
|
||||||
M::Error::invalid_value(Unexpected::Str(version), &self)
|
|
||||||
}
|
|
||||||
SplitError::UnknownAlgorithm(algorithm) => {
|
|
||||||
M::Error::invalid_value(Unexpected::Str(algorithm), &self)
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let signature_bytes: Vec<u8> = match decode_config(&value, STANDARD_NO_PAD) {
|
|
||||||
Ok(raw) => raw,
|
|
||||||
Err(error) => return Err(M::Error::custom(error.description())),
|
|
||||||
};
|
|
||||||
|
|
||||||
let signature = Signature {
|
|
||||||
algorithm,
|
|
||||||
signature: signature_bytes,
|
|
||||||
version,
|
|
||||||
};
|
|
||||||
|
|
||||||
signature_set.insert(signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(signature_set)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
@ -484,18 +144,6 @@ fn split_id(id: &str) -> Result<(Algorithm, String), SplitError<'_>> {
|
|||||||
Ok((algorithm, signature_id[1].to_string()))
|
Ok((algorithm, signature_id[1].to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to convert a server name as a string into a `url::Host`.
|
|
||||||
fn server_name_to_host(server_name: &str) -> Result<Host, Error> {
|
|
||||||
let url_string = format!("https://{}", server_name);
|
|
||||||
let url = Url::parse(&url_string)
|
|
||||||
.map_err(|_| Error::new(format!("invalid server name: {}", server_name)))?;
|
|
||||||
|
|
||||||
match url.host() {
|
|
||||||
Some(host) => Ok(host.to_owned()),
|
|
||||||
None => Err(Error::new(format!("invalid server name: {}", server_name))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Signature;
|
use super::Signature;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user