Skip to content

Commit

Permalink
Fix StrongholdStorage::get_public_key
Browse files Browse the repository at this point in the history
  • Loading branch information
UMR1352 committed Apr 29, 2024
1 parent 096bb30 commit b347a1e
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 179 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ thiserror = { version = "1.0", default-features = false }
strum = { version = "0.25", default-features = false, features = ["std", "derive"] }
serde_json = { version = "1.0", default-features = false }
json-proof-token = { version = "0.3.5" }
zkryptium = { version = "0.2.1", default-features = false, features = ["bbsplus"] }
zkryptium = { version = "0.2.2", default-features = false, features = ["bbsplus"] }

[workspace.package]
authors = ["IOTA Stiftung"]
Expand Down
3 changes: 1 addition & 2 deletions identity_storage/src/key_storage/bls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ fn random_bbs_keypair<S>() -> Result<(BBSplusSecretKey, BBSplusPublicKey), zkryp
where
S: BbsCiphersuite,
{
let key_pair = KeyPair::<BBSplus<S>>::random()?;
Ok((key_pair.private_key().clone(), key_pair.public_key().clone()))
KeyPair::<BBSplus<S>>::random().map(KeyPair::into_parts)
}

/// Generates a new BBS+ keypair using either `BLS12381-SHA256` or `BLS12381-SHAKE256`.
Expand Down
2 changes: 1 addition & 1 deletion identity_stronghold/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
pub(crate) mod ed25519;
mod stronghold_jwk_storage;
#[cfg(any(feature = "bbs-plus", test))]
mod stronghold_jwk_storage_ext;
mod stronghold_jwk_storage_bbs_plus_ext;

Check failure on line 7 in identity_stronghold/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

file not found for module `stronghold_jwk_storage_bbs_plus_ext`

error[E0583]: file not found for module `stronghold_jwk_storage_bbs_plus_ext` --> identity_stronghold/src/lib.rs:7:1 | 7 | mod stronghold_jwk_storage_bbs_plus_ext; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: to create the module `stronghold_jwk_storage_bbs_plus_ext`, create file "identity_stronghold/src/stronghold_jwk_storage_bbs_plus_ext.rs" or "identity_stronghold/src/stronghold_jwk_storage_bbs_plus_ext/mod.rs" = note: if there is a `mod stronghold_jwk_storage_bbs_plus_ext` elsewhere in the crate already, import it with `use crate::...` instead
mod stronghold_key_id;
pub(crate) mod stronghold_key_type;
#[cfg(test)]
Expand Down
75 changes: 73 additions & 2 deletions identity_stronghold/src/stronghold_jwk_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! Wrapper around [`StrongholdSecretManager`](StrongholdSecretManager).
use async_trait::async_trait;
use identity_storage::key_storage::bls::encode_bls_jwk;
use identity_storage::key_storage::JwkStorage;
use identity_storage::JwkGenOutput;
use identity_storage::KeyId;
Expand All @@ -19,14 +20,19 @@ use identity_verification::jwu;
use iota_sdk::client::secret::stronghold::StrongholdSecretManager;
use iota_sdk::client::secret::SecretManager;
use iota_stronghold::procedures::Ed25519Sign;
use iota_stronghold::procedures::FatalProcedureError;
use iota_stronghold::procedures::GenerateKey;
use iota_stronghold::procedures::KeyType as ProceduresKeyType;
use iota_stronghold::procedures::Runner;
use iota_stronghold::procedures::StrongholdProcedure;
use iota_stronghold::Location;
use iota_stronghold::Stronghold;
use jsonprooftoken::jpa::algs::ProofAlgorithm;
use std::str::FromStr;
use std::sync::Arc;
use tokio::sync::MutexGuard;
use zeroize::Zeroizing;
use zkryptium::bbsplus::keys::BBSplusSecretKey;

use crate::ed25519;
use crate::stronghold_key_type::StrongholdKeyType;
Expand Down Expand Up @@ -56,7 +62,68 @@ impl StrongholdStorage {
}
}

async fn get_ed25519_public_key(&self, key_id: &KeyId) -> KeyStorageResult<Jwk> {
let stronghold = self.get_stronghold().await;
let client = get_client(&stronghold)?;

let location = Location::generic(
IDENTITY_VAULT_PATH.as_bytes().to_vec(),
key_id.to_string().as_bytes().to_vec(),
);

let public_key_procedure = iota_stronghold::procedures::PublicKey {
ty: ProceduresKeyType::Ed25519,
private_key: location,
};

let procedure_result = client
.execute_procedure(StrongholdProcedure::PublicKey(public_key_procedure))
.map_err(|err| KeyStorageError::new(KeyStorageErrorKind::KeyNotFound).with_source(err))?;

let public_key: Vec<u8> = procedure_result.into();

let mut params = JwkParamsOkp::new();
params.x = jwu::encode_b64(public_key);
params.crv = EdCurve::Ed25519.name().to_owned();
let mut jwk: Jwk = Jwk::from_params(params);
jwk.set_alg(JwsAlgorithm::EdDSA.name());
jwk.set_kid(jwk.thumbprint_sha256_b64());

Ok(jwk)
}

async fn get_bls12381g2_public_key(&self, key_id: &KeyId) -> KeyStorageResult<Jwk> {
let stronghold = self.get_stronghold().await;
let client = get_client(&stronghold)?;

let location = Location::generic(
IDENTITY_VAULT_PATH.as_bytes().to_vec(),
key_id.to_string().as_bytes().to_vec(),
);

client
.get_guards([location], |[sk]| {
let sk = BBSplusSecretKey::from_bytes(&sk.borrow()).map_err(|e| FatalProcedureError::from(e.to_string()))?;
let pk = sk.public_key();
let public_jwk = encode_bls_jwk(&sk, &pk, ProofAlgorithm::BLS12381_SHA256).1;

drop(Zeroizing::new(sk.to_bytes()));
Ok(public_jwk)
})
.map_err(|e| KeyStorageError::new(KeyStorageErrorKind::KeyNotFound).with_source(e))
}

/// Attepts to retrieve the public key corresponding to the key of id `key_id`,
/// returning it as a `key_type` encoded public JWK.
pub async fn get_public_key_with_type(&self, key_id: &KeyId, key_type: StrongholdKeyType) -> KeyStorageResult<Jwk> {
match key_type {
StrongholdKeyType::Ed25519 => self.get_ed25519_public_key(key_id).await,
StrongholdKeyType::Bls12381G2 => self.get_bls12381g2_public_key(key_id).await,
}
}

/// Retrieve the public key corresponding to `key_id`.
#[deprecated(since = "1.3.0", note = "use `get_public_key_with_type` instead")]
pub async fn get_public_key(&self, key_id: &KeyId) -> KeyStorageResult<Jwk> {
let stronghold = self.get_stronghold().await;
let client = get_client(&stronghold)?;
Expand Down Expand Up @@ -100,8 +167,12 @@ impl JwkStorage for StrongholdStorage {

let keytype: ProceduresKeyType = match key_type {
StrongholdKeyType::Ed25519 => ProceduresKeyType::Ed25519,
StrongholdKeyType::BLS12381G2 => {
todo!("return an error that instruct the user to call the BBS+ flavor for this function.")
StrongholdKeyType::Bls12381G2 => {
return Err(
KeyStorageError::new(KeyStorageErrorKind::Unspecified).with_custom_message(format!(
"`{key_type}` is supported but `JwkStorageBbsPlusExt::generate_bbs` should be called instead."
)),
)
}
};

Expand Down
165 changes: 0 additions & 165 deletions identity_stronghold/src/stronghold_jwk_storage_ext.rs

This file was deleted.

8 changes: 4 additions & 4 deletions identity_stronghold/src/stronghold_key_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ const BLS12381G2_KEY_TYPE_STR: &str = "BLS12381G2";
#[derive(Debug, Copy, Clone)]
pub enum StrongholdKeyType {
Ed25519,
BLS12381G2,
Bls12381G2,
}

impl StrongholdKeyType {
/// String representation of the key type.
const fn name(&self) -> &'static str {
match self {
StrongholdKeyType::Ed25519 => ED25519_KEY_TYPE_STR,
StrongholdKeyType::BLS12381G2 => BLS12381G2_KEY_TYPE_STR,
StrongholdKeyType::Bls12381G2 => BLS12381G2_KEY_TYPE_STR,
}
}
}
Expand All @@ -45,7 +45,7 @@ impl TryFrom<&KeyType> for StrongholdKeyType {
fn try_from(value: &KeyType) -> Result<Self, Self::Error> {
match value.as_str() {
ED25519_KEY_TYPE_STR => Ok(StrongholdKeyType::Ed25519),
BLS12381G2_KEY_TYPE_STR => Ok(StrongholdKeyType::BLS12381G2),
BLS12381G2_KEY_TYPE_STR => Ok(StrongholdKeyType::Bls12381G2),
_ => Err(KeyStorageError::new(KeyStorageErrorKind::UnsupportedKeyType)),
}
}
Expand Down Expand Up @@ -91,7 +91,7 @@ impl TryFrom<&Jwk> for StrongholdKeyType {
.with_custom_message("only Ed curves are supported for signing")
.with_source(err)
})? {
BlsCurve::BLS12381G2 => Ok(StrongholdKeyType::BLS12381G2),
BlsCurve::BLS12381G2 => Ok(StrongholdKeyType::Bls12381G2),
curve => Err(
KeyStorageError::new(KeyStorageErrorKind::UnsupportedKeyType)
.with_custom_message(format!("{curve} not supported")),
Expand Down
6 changes: 3 additions & 3 deletions identity_stronghold/src/tests/test_bbs_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::StrongholdStorage;
async fn stronghold_bbs_keypair_gen_works() -> anyhow::Result<()> {
let stronghold_storage = StrongholdStorage::new(create_stronghold_secret_manager());
let JwkGenOutput { key_id, jwk, .. } = stronghold_storage
.generate_bbs(StrongholdKeyType::BLS12381G2.into(), ProofAlgorithm::BLS12381_SHA256)
.generate_bbs(StrongholdKeyType::Bls12381G2.into(), ProofAlgorithm::BLS12381_SHA256)

Check failure on line 26 in identity_stronghold/src/tests/test_bbs_ext.rs

View workflow job for this annotation

GitHub Actions / clippy

no method named `generate_bbs` found for struct `stronghold_jwk_storage::StrongholdStorage` in the current scope

error[E0599]: no method named `generate_bbs` found for struct `stronghold_jwk_storage::StrongholdStorage` in the current scope --> identity_stronghold/src/tests/test_bbs_ext.rs:26:6 | 25 | let JwkGenOutput { key_id, jwk, .. } = stronghold_storage | __________________________________________- 26 | | .generate_bbs(StrongholdKeyType::Bls12381G2.into(), ProofAlgorithm::BLS12381_SHA256) | | -^^^^^^^^^^^^ method not found in `StrongholdStorage` | |_____| | | ::: identity_stronghold/src/stronghold_jwk_storage.rs:44:1 | 44 | pub struct StrongholdStorage(Arc<SecretManager>); | ---------------------------- method `generate_bbs` not found for this struct | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `generate_bbs`, perhaps you need to implement it: candidate #1: `identity_storage::JwkStorageBbsPlusExt`
.await?;

assert!(jwk.is_public());
Expand All @@ -48,7 +48,7 @@ async fn stronghold_bbs_keypair_gen_fails_with_wrong_key_type() -> anyhow::Resul
async fn stronghold_bbs_keypair_gen_fails_with_wrong_alg() -> anyhow::Result<()> {
let stronghold_storage = StrongholdStorage::new(create_stronghold_secret_manager());
let error = stronghold_storage
.generate_bbs(StrongholdKeyType::BLS12381G2.into(), ProofAlgorithm::MAC_H256)
.generate_bbs(StrongholdKeyType::Bls12381G2.into(), ProofAlgorithm::MAC_H256)

Check failure on line 51 in identity_stronghold/src/tests/test_bbs_ext.rs

View workflow job for this annotation

GitHub Actions / clippy

no method named `generate_bbs` found for struct `stronghold_jwk_storage::StrongholdStorage` in the current scope

error[E0599]: no method named `generate_bbs` found for struct `stronghold_jwk_storage::StrongholdStorage` in the current scope --> identity_stronghold/src/tests/test_bbs_ext.rs:51:6 | 50 | let error = stronghold_storage | _______________- 51 | | .generate_bbs(StrongholdKeyType::Bls12381G2.into(), ProofAlgorithm::MAC_H256) | | -^^^^^^^^^^^^ method not found in `StrongholdStorage` | |_____| | | ::: identity_stronghold/src/stronghold_jwk_storage.rs:44:1 | 44 | pub struct StrongholdStorage(Arc<SecretManager>); | ---------------------------- method `generate_bbs` not found for this struct | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `generate_bbs`, perhaps you need to implement it: candidate #1: `identity_storage::JwkStorageBbsPlusExt`
.await
.unwrap_err();

Expand All @@ -61,7 +61,7 @@ async fn stronghold_bbs_keypair_gen_fails_with_wrong_alg() -> anyhow::Result<()>
async fn stronghold_sign_bbs_works() -> anyhow::Result<()> {
let stronghold_storage = StrongholdStorage::new(create_stronghold_secret_manager());
let JwkGenOutput { key_id, jwk, .. } = stronghold_storage
.generate_bbs(StrongholdKeyType::BLS12381G2.into(), ProofAlgorithm::BLS12381_SHA256)
.generate_bbs(StrongholdKeyType::Bls12381G2.into(), ProofAlgorithm::BLS12381_SHA256)

Check failure on line 64 in identity_stronghold/src/tests/test_bbs_ext.rs

View workflow job for this annotation

GitHub Actions / clippy

no method named `generate_bbs` found for struct `stronghold_jwk_storage::StrongholdStorage` in the current scope

error[E0599]: no method named `generate_bbs` found for struct `stronghold_jwk_storage::StrongholdStorage` in the current scope --> identity_stronghold/src/tests/test_bbs_ext.rs:64:6 | 63 | let JwkGenOutput { key_id, jwk, .. } = stronghold_storage | __________________________________________- 64 | | .generate_bbs(StrongholdKeyType::Bls12381G2.into(), ProofAlgorithm::BLS12381_SHA256) | | -^^^^^^^^^^^^ method not found in `StrongholdStorage` | |_____| | | ::: identity_stronghold/src/stronghold_jwk_storage.rs:44:1 | 44 | pub struct StrongholdStorage(Arc<SecretManager>); | ---------------------------- method `generate_bbs` not found for this struct | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `generate_bbs`, perhaps you need to implement it: candidate #1: `identity_storage::JwkStorageBbsPlusExt`
.await?;
let pk = expand_bls_jwk(&jwk)?.1;
let sk = {
Expand Down
5 changes: 4 additions & 1 deletion identity_stronghold/src/tests/test_jwk_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ async fn retrieve() {
.unwrap();
let key_id = &generate.key_id;

let pub_key: Jwk = stronghold_storage.get_public_key(key_id).await.unwrap();
let pub_key: Jwk = stronghold_storage
.get_public_key_with_type(key_id, crate::stronghold_key_type::StrongholdKeyType::Ed25519)
.await
.unwrap();
assert_eq!(generate.jwk, pub_key);
}

Expand Down

0 comments on commit b347a1e

Please sign in to comment.