mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-04-25 11:02:12 +00:00
97 lines
3.6 KiB
Rust
97 lines
3.6 KiB
Rust
// Copyright 2017 Parity Technologies (UK) Ltd.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
// to deal in the Software without restriction, including without limitation
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
//! This module contains some utilities for algorithm support exchange.
|
|
//!
|
|
//! One important part of the SECIO handshake is negotiating algorithms. This is what this module
|
|
//! helps you with.
|
|
|
|
macro_rules! supported_impl {
|
|
($mod_name:ident: $ty:ty, $($name:expr => $val:expr),*,) => (
|
|
pub mod $mod_name {
|
|
use std::cmp::Ordering;
|
|
#[allow(unused_imports)]
|
|
use stream_cipher::Cipher;
|
|
#[allow(unused_imports)]
|
|
use ring::{agreement, digest};
|
|
use error::SecioError;
|
|
|
|
/// String to advertise to the remote.
|
|
pub const PROPOSITION_STRING: &'static str = concat_comma!($($name),*);
|
|
|
|
/// Choose which algorithm to use based on the remote's advertised list.
|
|
pub fn select_best(hashes_ordering: Ordering, input: &str) -> Result<$ty, SecioError> {
|
|
match hashes_ordering {
|
|
Ordering::Less | Ordering::Equal => {
|
|
for second_elem in input.split(',') {
|
|
$(
|
|
if $name == second_elem {
|
|
return Ok($val);
|
|
}
|
|
)+
|
|
}
|
|
},
|
|
Ordering::Greater => {
|
|
$(
|
|
for second_elem in input.split(',') {
|
|
if $name == second_elem {
|
|
return Ok($val);
|
|
}
|
|
}
|
|
)+
|
|
},
|
|
};
|
|
|
|
Err(SecioError::NoSupportIntersection(PROPOSITION_STRING, input.to_owned()))
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
// Concatenates several strings with commas.
|
|
macro_rules! concat_comma {
|
|
($first:expr, $($rest:expr),*) => (
|
|
concat!($first $(, ',', $rest)*)
|
|
);
|
|
}
|
|
|
|
// TODO: there's no library in the Rust ecosystem that supports P-521, but the Go & JS
|
|
// implementations advertise it
|
|
supported_impl!(
|
|
exchanges: &'static agreement::Algorithm,
|
|
"P-256" => &agreement::ECDH_P256,
|
|
"P-384" => &agreement::ECDH_P384,
|
|
);
|
|
|
|
// TODO: the Go & JS implementations advertise Blowfish ; however doing so in Rust leads to
|
|
// runtime errors
|
|
supported_impl!(
|
|
ciphers: Cipher,
|
|
"AES-128" => Cipher::Aes128,
|
|
"AES-256" => Cipher::Aes256,
|
|
"TwofishCTR" => Cipher::Twofish,
|
|
);
|
|
|
|
supported_impl!(
|
|
hashes: &'static digest::Algorithm,
|
|
"SHA256" => &digest::SHA256,
|
|
"SHA512" => &digest::SHA512,
|
|
);
|