Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: lazy_static removed, light parser for address URI added #2250

Merged
merged 32 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5b233fc
crypto: lazy_static removed, light parser added
michalkucharczyk Nov 9, 2023
3ab3733
fuzzer added
michalkucharczyk Nov 9, 2023
7e6bdb3
fix
michalkucharczyk Nov 9, 2023
f92f50f
cleanup
michalkucharczyk Nov 9, 2023
1a52c98
license added
michalkucharczyk Nov 9, 2023
b0167c3
std gate added
michalkucharczyk Nov 9, 2023
b6dbf0d
address uri moved to src/
michalkucharczyk Nov 9, 2023
eaf5de0
Apply suggestions from code review
michalkucharczyk Nov 13, 2023
047eb83
parsing error added
michalkucharczyk Nov 13, 2023
b33de54
fix
michalkucharczyk Nov 13, 2023
ee7f179
Merge remote-tracking branch 'origin/master' into mku-crypto-address-…
michalkucharczyk Nov 13, 2023
a3b9ded
Update substrate/primitives/core/src/address_uri.rs
michalkucharczyk Nov 13, 2023
3aad2c5
Update substrate/primitives/core/src/address_uri.rs
michalkucharczyk Nov 13, 2023
d556091
review suggestions
michalkucharczyk Nov 13, 2023
40486a6
fuzzer fixed
michalkucharczyk Nov 13, 2023
77ad7f1
review suggestion
michalkucharczyk Nov 13, 2023
93bc851
naming
michalkucharczyk Nov 13, 2023
33dd1f3
missed review suggesions + fixes
michalkucharczyk Nov 13, 2023
0476638
Update substrate/primitives/core/src/address_uri.rs
michalkucharczyk Nov 13, 2023
0dddd34
fix
michalkucharczyk Nov 13, 2023
2500fe0
Merge remote-tracking branch 'origin/master' into mku-crypto-address-…
michalkucharczyk Nov 13, 2023
52f8aa2
Merge branch 'master' into mku-crypto-address-uri-parser
michalkucharczyk Nov 13, 2023
abff740
".git/.scripts/commands/update-ui/update-ui.sh"
Nov 13, 2023
b2bb315
test-pallet-ui: trybuild-overwrite
michalkucharczyk Nov 13, 2023
13582d3
Merge branch 'master' into mku-crypto-address-uri-parser
michalkucharczyk Nov 13, 2023
9fa5ff8
better error communication
michalkucharczyk Nov 16, 2023
80532e7
fuzzer added to workspace
michalkucharczyk Nov 16, 2023
69d7c7f
fix
michalkucharczyk Nov 16, 2023
ad71461
fix
michalkucharczyk Nov 16, 2023
ab059c3
fix indexing to be 0-based
michalkucharczyk Nov 16, 2023
f6c7bfd
Merge branch 'master' into mku-crypto-address-uri-parser
michalkucharczyk Nov 16, 2023
06dd2fd
Merge branch 'master' into mku-crypto-address-uri-parser
michalkucharczyk Nov 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions substrate/primitives/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ bs58 = { version = "0.5.0", default-features = false, optional = true }
rand = { version = "0.8.5", features = ["small_rng"], optional = true }
substrate-bip39 = { version = "0.4.4", optional = true }
bip39 = { version = "2.0.0", default-features = false }
regex = { version = "1.6.0", optional = true }
zeroize = { version = "1.4.3", default-features = false }
secrecy = { version = "0.8.0", default-features = false }
lazy_static = { version = "1.4.0", default-features = false, optional = true }
parking_lot = { version = "0.12.1", optional = true }
ss58-registry = { version = "1.34.0", default-features = false }
sp-std = { path = "../std", default-features = false}
Expand Down Expand Up @@ -63,6 +61,8 @@ bandersnatch_vrfs = { git = "https://github.com/w3f/ring-vrf", rev = "cbc342e",
[dev-dependencies]
criterion = "0.4.0"
serde_json = "1.0.108"
lazy_static = "1.4.0"
regex = "1.6.0"
sp-core-hashing-proc-macro = { path = "hashing/proc-macro" }

[[bench]]
Expand Down Expand Up @@ -92,7 +92,6 @@ std = [
"hash256-std-hasher/std",
"impl-serde/std",
"itertools",
"lazy_static",
"libsecp256k1/std",
"log/std",
"merlin/std",
Expand All @@ -102,7 +101,6 @@ std = [
"primitive-types/serde",
"primitive-types/std",
"rand",
"regex",
"scale-info/std",
"schnorrkel/std",
"secp256k1/global-context",
Expand Down
28 changes: 28 additions & 0 deletions substrate/primitives/core/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "sp-core-fuzz"
version = "0.0.0"
publish = false

[package.metadata]
cargo-fuzz = true

[dependencies]
lazy_static = "1.4.0"
libfuzzer-sys = "0.4"
regex = "1.10.2"

[dependencies.sp-core]
path = ".."
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved

# Prevent this from interfering with workspaces
[workspace]
members = ["."]
michalkucharczyk marked this conversation as resolved.
Show resolved Hide resolved

[profile.release]
debug = 1

[[bin]]
name = "fuzz_address_uri"
path = "fuzz_targets/fuzz_address_uri.rs"
test = false
doc = false
50 changes: 50 additions & 0 deletions substrate/primitives/core/fuzz/fuzz_targets/fuzz_address_uri.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![no_main]

extern crate libfuzzer_sys;
extern crate regex;
extern crate sp_core;

use libfuzzer_sys::fuzz_target;
use regex::Regex;
use sp_core::crypto::AddressUri;

lazy_static::lazy_static! {
static ref SECRET_PHRASE_REGEX: Regex = Regex::new(r"^(?P<phrase>[a-zA-Z0-9 ]+)?(?P<path>(//?[^/]+)*)(///(?P<password>.*))?$")
.expect("constructed from known-good static value; qed");
}

fuzz_target!(|input: &str| {
let regex_result = SECRET_PHRASE_REGEX.captures(input);
let manual_result = AddressUri::parse(input);
assert_eq!(regex_result.is_some(), manual_result.is_some());
if let (Some(regex_result), Some(manual_result)) = (regex_result, manual_result) {
assert_eq!(regex_result.name("phrase").map(|ss58| ss58.as_str()), manual_result.ss58);

let mut manual_paths = manual_result
.paths
.iter()
.map(|s| "/".to_string() + s)
.collect::<Vec<_>>()
.join("");

assert_eq!(regex_result.name("path").unwrap().as_str().to_string(), manual_paths);
assert_eq!(regex_result.name("password").map(|ss58| ss58.as_str()), manual_result.pass);
}
});
67 changes: 28 additions & 39 deletions substrate/primitives/core/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ use codec::{Decode, Encode, MaxEncodedLen};
use itertools::Itertools;
#[cfg(feature = "std")]
use rand::{rngs::OsRng, RngCore};
#[cfg(feature = "std")]
use regex::Regex;
use scale_info::TypeInfo;
#[cfg(feature = "std")]
pub use secrecy::{ExposeSecret, SecretString};
Expand All @@ -43,6 +41,11 @@ pub use ss58_registry::{from_known_address_format, Ss58AddressFormat, Ss58Addres
/// Trait to zeroize a memory buffer.
pub use zeroize::Zeroize;

#[cfg(feature = "std")]
mod address_uri;
#[cfg(feature = "std")]
use address_uri::AddressUri;

/// The root phrase for our publicly known keys.
pub const DEV_PHRASE: &str =
"bottom drive obey lake curtain smoke basket hold race lonely fit walk";
Expand Down Expand Up @@ -414,47 +417,40 @@ pub fn set_default_ss58_version(new_default: Ss58AddressFormat) {
DEFAULT_VERSION.store(new_default.into(), core::sync::atomic::Ordering::Relaxed);
}

#[cfg(feature = "std")]
lazy_static::lazy_static! {
static ref SS58_REGEX: Regex = Regex::new(r"^(?P<ss58>[\w\d ]+)?(?P<path>(//?[^/]+)*)$")
.expect("constructed from known-good static value; qed");
static ref SECRET_PHRASE_REGEX: Regex = Regex::new(r"^(?P<phrase>[\d\w ]+)?(?P<path>(//?[^/]+)*)(///(?P<password>.*))?$")
.expect("constructed from known-good static value; qed");
static ref JUNCTION_REGEX: Regex = Regex::new(r"/(/?[^/]+)")
.expect("constructed from known-good static value; qed");
}

#[cfg(feature = "std")]
impl<T: Sized + AsMut<[u8]> + AsRef<[u8]> + Public + Derive> Ss58Codec for T {
fn from_string(s: &str) -> Result<Self, PublicError> {
let cap = SS58_REGEX.captures(s).ok_or(PublicError::InvalidFormat)?;
let s = cap.name("ss58").map(|r| r.as_str()).unwrap_or(DEV_ADDRESS);
let cap = AddressUri::parse(s).ok_or(PublicError::InvalidFormat)?;
if cap.pass.is_some() {
return Err(PublicError::InvalidFormat);
}
let s = cap.ss58.unwrap_or(DEV_ADDRESS);
let addr = if let Some(stripped) = s.strip_prefix("0x") {
let d = array_bytes::hex2bytes(stripped).map_err(|_| PublicError::InvalidFormat)?;
Self::from_slice(&d).map_err(|()| PublicError::BadLength)?
} else {
Self::from_ss58check(s)?
};
if cap["path"].is_empty() {
if cap.paths.is_empty() {
Ok(addr)
} else {
let path =
JUNCTION_REGEX.captures_iter(&cap["path"]).map(|f| DeriveJunction::from(&f[1]));
addr.derive(path).ok_or(PublicError::InvalidPath)
addr.derive(cap.paths.iter().map(DeriveJunction::from))
.ok_or(PublicError::InvalidPath)
}
}

fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
let cap = SS58_REGEX.captures(s).ok_or(PublicError::InvalidFormat)?;
let (addr, v) = Self::from_ss58check_with_version(
cap.name("ss58").map(|r| r.as_str()).unwrap_or(DEV_ADDRESS),
)?;
if cap["path"].is_empty() {
let cap = AddressUri::parse(s).ok_or(PublicError::InvalidFormat)?;
if cap.pass.is_some() {
return Err(PublicError::InvalidFormat);
}
let (addr, v) = Self::from_ss58check_with_version(cap.ss58.unwrap_or(DEV_ADDRESS))?;
if cap.paths.is_empty() {
Ok((addr, v))
} else {
let path =
JUNCTION_REGEX.captures_iter(&cap["path"]).map(|f| DeriveJunction::from(&f[1]));
addr.derive(path).ok_or(PublicError::InvalidPath).map(|a| (a, v))
addr.derive(cap.paths.iter().map(DeriveJunction::from))
.ok_or(PublicError::InvalidPath)
.map(|a| (a, v))
}
}
}
Expand Down Expand Up @@ -817,22 +813,15 @@ impl sp_std::str::FromStr for SecretUri {
type Err = SecretStringError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let cap = SECRET_PHRASE_REGEX.captures(s).ok_or(SecretStringError::InvalidFormat)?;

let junctions = JUNCTION_REGEX
.captures_iter(&cap["path"])
.map(|f| DeriveJunction::from(&f[1]))
.collect::<Vec<_>>();

let phrase = cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE);
let password = cap.name("password");
let cap = AddressUri::parse(s).ok_or(SecretStringError::InvalidFormat)?;
let phrase = cap.ss58.unwrap_or(DEV_PHRASE);

Ok(Self {
phrase: SecretString::from_str(phrase).expect("Returns infallible error; qed"),
password: password.map(|v| {
SecretString::from_str(v.as_str()).expect("Returns infallible error; qed")
}),
junctions,
password: cap
.pass
.map(|v| SecretString::from_str(v).expect("Returns infallible error; qed")),
junctions: cap.paths.iter().map(DeriveJunction::from).collect::<Vec<_>>(),
})
}
}
Expand Down
Loading
Loading