Merge branch 'hex_decode' into 'main'

Speed up RsaIdentity decoding

Closes #377

See merge request tpo/core/arti!381
This commit is contained in:
Ian Jackson 2022-03-04 17:22:52 +00:00
commit 952aef1be3
8 changed files with 38 additions and 27 deletions

View File

@ -59,9 +59,8 @@ impl Authority {
pub(crate) fn default_authorities() -> Vec<Authority> {
/// Build an authority; panic if input is bad.
fn auth(name: &str, key: &str) -> Authority {
let v3ident = hex::decode(key).expect("Built-in authority identity had bad hex!?");
let v3ident = RsaIdentity::from_bytes(&v3ident)
.expect("Built-in authority identity had wrong length!?");
let v3ident =
RsaIdentity::from_hex(key).expect("Built-in authority identity had bad hex!?");
AuthorityBuilder::new()
.name(name)
.v3ident(v3ident)

View File

@ -331,9 +331,7 @@ mod fallbacks {
pub(crate) fn default_fallbacks() -> Vec<super::FallbackDir> {
/// Build a fallback directory; panic if input is bad.
fn fallback(rsa: &str, ed: &str, ports: &[&str]) -> FallbackDir {
let rsa = hex::decode(rsa).expect("Bad hex in built-in fallback list");
let rsa =
RsaIdentity::from_bytes(&rsa).expect("Wrong length in built-in fallback list");
let rsa = RsaIdentity::from_hex(rsa).expect("Bad hex in built-in fallback list");
let ed = base64::decode_config(ed, base64::STANDARD_NO_PAD)
.expect("Bad hex in built-in fallback list");
let ed =

View File

@ -1005,8 +1005,7 @@ mod test {
datetime!(2020-08-07 12:42:45 UTC).into()
}
fn rsa(s: &str) -> RsaIdentity {
let k = hex::decode(s).unwrap();
RsaIdentity::from_bytes(&k[..]).unwrap()
RsaIdentity::from_hex(s).unwrap()
}
fn test_authorities() -> Vec<Authority> {
fn a(s: &str) -> Authority {

View File

@ -608,20 +608,16 @@ impl Drop for Unlinker {
/// Convert a hexadecimal sha3-256 digest from the database into an array.
fn digest_from_hex(s: &str) -> Result<[u8; 32]> {
hex::decode(s)
.map_err(Error::BadHexInCache)?
.try_into()
.map_err(|_| Error::CacheCorruption("Invalid digest in database"))
let mut bytes = [0_u8; 32];
hex::decode_to_slice(s, &mut bytes[..]).map_err(Error::BadHexInCache)?;
Ok(bytes)
}
/// Convert a hexadecimal sha3-256 "digest string" as used in the
/// digest column from the database into an array.
fn digest_from_dstr(s: &str) -> Result<[u8; 32]> {
if let Some(stripped) = s.strip_prefix("sha3-256-") {
hex::decode(stripped)
.map_err(Error::BadHexInCache)?
.try_into()
.map_err(|_| Error::CacheCorruption("Invalid digest in database"))
digest_from_hex(stripped)
} else {
Err(Error::CacheCorruption("Invalid digest in database"))
}

View File

@ -94,9 +94,8 @@ impl<'de> serde::Deserialize<'de> for RsaIdentity {
where
E: serde::de::Error,
{
let bytes = hex::decode(s).map_err(E::custom)?;
RsaIdentity::from_bytes(&bytes)
.ok_or_else(|| E::custom("wrong length for RSA identity"))
RsaIdentity::from_hex(s)
.ok_or_else(|| E::custom("wrong encoding for RSA identity"))
}
}
@ -151,6 +150,16 @@ impl RsaIdentity {
None
}
}
/// Decode an `RsaIdentity` from a hexadecimal string.
///
/// The string must have no spaces, or any extra characters.
pub fn from_hex(s: &str) -> Option<Self> {
let mut array = [0_u8; 20];
match hex::decode_to_slice(s, &mut array) {
Err(_) => None,
Ok(()) => Some(RsaIdentity::from(array)),
}
}
}
impl From<[u8; 20]> for RsaIdentity {

View File

@ -41,8 +41,7 @@ fn test_ed25519_identity() {
fn test_rsa_formatting() {
use ll::pk::rsa::RsaIdentity;
let id = hex::decode("5696ab38cb3852afa476a5c07b2d4788963d5567").unwrap();
let id = RsaIdentity::from_bytes(&id).unwrap();
let id = RsaIdentity::from_hex("5696ab38cb3852afa476a5c07b2d4788963d5567").unwrap();
assert_eq!(
format!("<<{}>>", id),
@ -54,6 +53,18 @@ fn test_rsa_formatting() {
);
}
#[test]
fn test_wrong_hex_rsa_ids() {
use ll::pk::rsa::RsaIdentity;
assert!(RsaIdentity::from_hex("5696ab38cb3852afa476a5c07b2d4788963d5567").is_some());
assert!(RsaIdentity::from_hex("5696AB38CB3852AFA476A5C07b2d4788963d5567").is_some());
assert!(RsaIdentity::from_hex("5696ab38cb3852afa476a5c07b2d4788963d").is_none());
assert!(RsaIdentity::from_hex("5696ab38cb3852afa476a5c07b2d4788963d5567A").is_none());
assert!(RsaIdentity::from_hex("5696ab38cb3852afa476a5c07b2d4788963d5567AB").is_none());
assert!(RsaIdentity::from_hex("").is_none());
assert!(RsaIdentity::from_hex("listen carefully, spider of destiny -FZ").is_none());
}
// TODO: Proper tests for RSA keys
#[test]

View File

@ -353,12 +353,7 @@ mod fingerprint {
/// Helper: parse an identity from a hexadecimal string
fn parse_hex_ident(s: &str) -> Result<RsaIdentity> {
let bytes = hex::decode(s).map_err(|_| {
EK::BadArgument
.at_pos(Pos::at(s))
.with_msg("invalid hexadecimal in fingerprint")
})?;
RsaIdentity::from_bytes(&bytes).ok_or_else(|| {
RsaIdentity::from_hex(s).ok_or_else(|| {
EK::BadArgument
.at_pos(Pos::at(s))
.with_msg("wrong length on fingerprint")

View File

@ -19,6 +19,10 @@ We can delete older sections here after we bump the releases.
## Since Arti 0.1.0
tor-llcrypto:
new-api: Added RsaIdentity::from_hex().
arti-client:
api-break (experimental only): changed circmgr() and dirmgr() to return