mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 13:27:57 +00:00
Introduce sign_with method in keystore (#4925)
* Add KEY_KIND_ID to the public trait This change is being introduced for the purpose of identifying a public key with it's identifier and algorithm "kind". * Use `sign_with` as implemented in BareCryptoStore * Implement `sign_with` in sc_keystore * Fix inconsistencies, use *_KIND_ID in sp_core testing * Rename KeyKindId to CryptoTypeId * Remove pair-returning functions from BareCryptoStore trait * Define CryptoTypeId in app-crypto macros * Add functions to get keys supported by keystore * Fix sign_with signature to include CryptoTypePublicPair * Add `sign_with_any` and `sign_with_all` * Use keystore.sign_with in auth_discovery * Rename get_supported_keys -> supported_keys * Added headers to function docstrings * Use chain instead of extending a temp vector * Fixed some code formatting * Restrict size of CryptoTypeId This is to be able to use Encode/Decode derives and the overcome having the size being unknown at compile-time. * Implement sign_with in the trait itself * Remove whitespace * Use key_type also as a CryptoTypeId in app_crypto macros * Rename `get_keys` to `keys` in BareCryptoStore * Remove usage of key_pair funcs in tests * Adjust docstring for *_CYPTO_ID constants * Fix failures * Simplify mapping on keys * Remove one let * Fixed typo * PR feedback * remove whitespace * Zip keys and signatures * Use into_iter & remove cloned * Pass index to MissingSignature * Use typed errors instead of strings for BareCryptoStore * Implement Debug for trait error * Use hashsets for better performance for supported_keys * Make sure keys are inserted into the keystore * Make sign_with_all return type consistent with `sign_with` * Rename Error to BareCryptoStoreError * Rename CRYPT_TYPE_ID -> CRYPTO_ID * Remove unnecessary CRYPTO_ID declaration in Public trait * Convert pub key to CryptoTypePublicPair * Fix use * Fix code style * Implement From on CryptoTypePublicPair in app_crypto macros * Change CryptoTypePublicPair to a struct * Implement Display on CryptoTypePublicPair * Pass CryptoTypePublicPair to MissingSignature error * Adjust docs according to function signature * Unify keys implementation * Fix RPC author tests * Fix stackoverflow * Tabify spaces * Pass KeyTypeId to error for easier debugging * Fix asserts * Use ToHex to format public key * Use constants from sp_core * Rename testing KeyTypeId constants * Please compiler * Restore KeyTypeId names apparently, they're not only used in tests * Use BareCryptoStoreError instead of String * Document return value * Fix borrow check * Convert to hashset internally * WIP - iter_keys * Return raw_public_keys * Address PR feedback * Address PR Feedback * Fix hexdisplay import error * Update primitives/core/src/traits.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
@@ -16,10 +16,16 @@
|
||||
|
||||
//! Types that should only be used for testing!
|
||||
|
||||
use crate::crypto::{KeyTypeId, CryptoTypePublicPair};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::{ed25519, sr25519, crypto::{Public, Pair}};
|
||||
use crate::crypto::KeyTypeId;
|
||||
|
||||
use crate::{
|
||||
crypto::{Pair, Public},
|
||||
ed25519, sr25519,
|
||||
traits::BareCryptoStoreError
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use std::collections::HashSet;
|
||||
use codec::Encode;
|
||||
/// Key type for generic Ed25519 key.
|
||||
pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25");
|
||||
/// Key type for generic Sr 25519 key.
|
||||
@@ -39,10 +45,41 @@ impl KeyStore {
|
||||
pub fn new() -> crate::traits::BareCryptoStorePtr {
|
||||
std::sync::Arc::new(parking_lot::RwLock::new(Self::default()))
|
||||
}
|
||||
|
||||
fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option<sr25519::Pair> {
|
||||
self.keys.get(&id)
|
||||
.and_then(|inner|
|
||||
inner.get(pub_key.as_slice())
|
||||
.map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid"))
|
||||
)
|
||||
}
|
||||
|
||||
fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option<ed25519::Pair> {
|
||||
self.keys.get(&id)
|
||||
.and_then(|inner|
|
||||
inner.get(pub_key.as_slice())
|
||||
.map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid"))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl crate::traits::BareCryptoStore for KeyStore {
|
||||
fn keys(&self, id: KeyTypeId) -> Result<Vec<CryptoTypePublicPair>, BareCryptoStoreError> {
|
||||
self.keys
|
||||
.get(&id)
|
||||
.map(|map| {
|
||||
Ok(map.keys()
|
||||
.fold(Vec::new(), |mut v, k| {
|
||||
v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone()));
|
||||
v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone()));
|
||||
v
|
||||
}))
|
||||
})
|
||||
.unwrap_or(Ok(vec![]))
|
||||
}
|
||||
|
||||
fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec<sr25519::Public> {
|
||||
self.keys.get(&id)
|
||||
.map(|keys|
|
||||
@@ -58,10 +95,11 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
&mut self,
|
||||
id: KeyTypeId,
|
||||
seed: Option<&str>,
|
||||
) -> Result<sr25519::Public, String> {
|
||||
) -> Result<sr25519::Public, BareCryptoStoreError> {
|
||||
match seed {
|
||||
Some(seed) => {
|
||||
let pair = sr25519::Pair::from_string(seed, None).expect("Generates an `sr25519` pair.");
|
||||
let pair = sr25519::Pair::from_string(seed, None)
|
||||
.map_err(|_| BareCryptoStoreError::ValidationError("Generates an `sr25519` pair.".to_owned()))?;
|
||||
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
|
||||
Ok(pair.public())
|
||||
},
|
||||
@@ -73,14 +111,6 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option<sr25519::Pair> {
|
||||
self.keys.get(&id)
|
||||
.and_then(|inner|
|
||||
inner.get(pub_key.as_slice())
|
||||
.map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid"))
|
||||
)
|
||||
}
|
||||
|
||||
fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec<ed25519::Public> {
|
||||
self.keys.get(&id)
|
||||
.map(|keys|
|
||||
@@ -96,10 +126,11 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
&mut self,
|
||||
id: KeyTypeId,
|
||||
seed: Option<&str>,
|
||||
) -> Result<ed25519::Public, String> {
|
||||
) -> Result<ed25519::Public, BareCryptoStoreError> {
|
||||
match seed {
|
||||
Some(seed) => {
|
||||
let pair = ed25519::Pair::from_string(seed, None).expect("Generates an `ed25519` pair.");
|
||||
let pair = ed25519::Pair::from_string(seed, None)
|
||||
.map_err(|_| BareCryptoStoreError::ValidationError("Generates an `ed25519` pair.".to_owned()))?;
|
||||
self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
|
||||
Ok(pair.public())
|
||||
},
|
||||
@@ -111,14 +142,6 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option<ed25519::Pair> {
|
||||
self.keys.get(&id)
|
||||
.and_then(|inner|
|
||||
inner.get(pub_key.as_slice())
|
||||
.map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid"))
|
||||
)
|
||||
}
|
||||
|
||||
fn insert_unknown(&mut self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
|
||||
self.keys.entry(id).or_default().insert(public.to_owned(), suri.to_string());
|
||||
Ok(())
|
||||
@@ -131,6 +154,40 @@ impl crate::traits::BareCryptoStore for KeyStore {
|
||||
fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
|
||||
public_keys.iter().all(|(k, t)| self.keys.get(&t).and_then(|s| s.get(k)).is_some())
|
||||
}
|
||||
|
||||
fn supported_keys(
|
||||
&self,
|
||||
id: KeyTypeId,
|
||||
keys: Vec<CryptoTypePublicPair>,
|
||||
) -> std::result::Result<Vec<CryptoTypePublicPair>, BareCryptoStoreError> {
|
||||
let provided_keys = keys.into_iter().collect::<HashSet<_>>();
|
||||
let all_keys = self.keys(id)?.into_iter().collect::<HashSet<_>>();
|
||||
|
||||
Ok(provided_keys.intersection(&all_keys).cloned().collect())
|
||||
}
|
||||
|
||||
fn sign_with(
|
||||
&self,
|
||||
id: KeyTypeId,
|
||||
key: &CryptoTypePublicPair,
|
||||
msg: &[u8],
|
||||
) -> Result<Vec<u8>, BareCryptoStoreError> {
|
||||
match key.0 {
|
||||
ed25519::CRYPTO_ID => {
|
||||
let key_pair: ed25519::Pair = self
|
||||
.ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice()))
|
||||
.ok_or(BareCryptoStoreError::PairNotFound("ed25519".to_owned()))?;
|
||||
return Ok(key_pair.sign(msg).encode());
|
||||
}
|
||||
sr25519::CRYPTO_ID => {
|
||||
let key_pair: sr25519::Pair = self
|
||||
.sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice()))
|
||||
.ok_or(BareCryptoStoreError::PairNotFound("sr25519".to_owned()))?;
|
||||
return Ok(key_pair.sign(msg).encode());
|
||||
}
|
||||
_ => Err(BareCryptoStoreError::KeyNotSupported(id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro for exporting functions from wasm in with the expected signature for using it with the
|
||||
@@ -247,11 +304,9 @@ mod tests {
|
||||
.ed25519_generate_new(ED25519, None)
|
||||
.expect("Generates key");
|
||||
|
||||
let store_key_pair = store.read()
|
||||
.ed25519_key_pair(ED25519, &public)
|
||||
.expect("Key should exists in store");
|
||||
let public_keys = store.read().keys(ED25519).unwrap();
|
||||
|
||||
assert_eq!(public, store_key_pair.public());
|
||||
assert!(public_keys.contains(&public.into()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -267,11 +322,8 @@ mod tests {
|
||||
key_pair.public().as_ref(),
|
||||
).expect("Inserts unknown key");
|
||||
|
||||
let store_key_pair = store.read().sr25519_key_pair(
|
||||
SR25519,
|
||||
&key_pair.public(),
|
||||
).expect("Gets key pair from keystore");
|
||||
let public_keys = store.read().keys(SR25519).unwrap();
|
||||
|
||||
assert_eq!(key_pair.public(), store_key_pair.public());
|
||||
assert!(public_keys.contains(&key_pair.public().into()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user