use crate::key_storage::JwkStorage;
use crate::key_storage::KeyId;
use crate::key_storage::KeyStorageErrorKind;
use crate::key_storage::KeyType;
use crypto::signatures::ed25519::PublicKey;
use crypto::signatures::ed25519::SecretKey;
use crypto::signatures::ed25519::Signature;
use identity_verification::jose::jwk::EdCurve;
use identity_verification::jose::jwk::Jwk;
use identity_verification::jose::jwk::JwkParamsOkp;
use identity_verification::jose::jwu;
use identity_verification::jwk::EcCurve;
use identity_verification::jwk::JwkParamsEc;
use identity_verification::jws::JwsAlgorithm;
pub(crate) async fn test_insertion(store: impl JwkStorage) {
let (private_key, public_key) = generate_ed25519();
let mut jwk: Jwk = crate::key_storage::ed25519::encode_jwk(&private_key, &public_key);
let err = store.insert(jwk.clone()).await.unwrap_err();
assert!(matches!(err.kind(), KeyStorageErrorKind::UnsupportedSignatureAlgorithm));
jwk.set_alg(JwsAlgorithm::EdDSA.name());
store.insert(jwk.clone()).await.unwrap();
let err = store.insert(jwk.to_public().unwrap()).await.unwrap_err();
assert!(matches!(err.kind(), KeyStorageErrorKind::Unspecified))
}
pub(crate) async fn test_incompatible_key_alg(store: impl JwkStorage) {
let (private_key, public_key) = generate_ed25519();
let mut jwk: Jwk = crate::key_storage::ed25519::encode_jwk(&private_key, &public_key);
jwk.set_alg(JwsAlgorithm::ES256.name());
let err = store.insert(jwk.clone()).await.unwrap_err();
assert!(matches!(err.kind(), KeyStorageErrorKind::KeyAlgorithmMismatch));
}
pub(crate) async fn test_incompatible_key_type(store: impl JwkStorage) {
let mut ec_params = JwkParamsEc::new();
ec_params.crv = EcCurve::P256.name().to_string();
ec_params.x = String::new();
ec_params.y = String::new();
ec_params.d = Some(String::new());
let jwk_ec = Jwk::from_params(ec_params);
let err = store.insert(jwk_ec).await.unwrap_err();
assert!(matches!(err.kind(), KeyStorageErrorKind::UnsupportedKeyType));
}
pub(crate) async fn test_generate_and_sign(store: impl JwkStorage) {
let test_msg: &[u8] = b"test";
let generate = store
.generate(KeyType::new("Ed25519"), JwsAlgorithm::EdDSA)
.await
.unwrap();
let signature = store.sign(&generate.key_id, test_msg, &generate.jwk).await.unwrap();
let signature: Signature = Signature::from_bytes(signature.try_into().unwrap());
let public_key: PublicKey = expand_public_jwk(&generate.jwk);
assert!(public_key.verify(&signature, test_msg));
let key_id: KeyId = generate.key_id;
assert!(store.exists(&key_id).await.unwrap());
store.delete(&key_id).await.unwrap();
}
pub(crate) async fn test_key_exists(store: impl JwkStorage) {
assert!(!store.exists(&KeyId::new("non-existent-id")).await.unwrap());
}
pub(crate) fn expand_public_jwk(jwk: &Jwk) -> PublicKey {
let params: &JwkParamsOkp = jwk.try_okp_params().unwrap();
if params.try_ed_curve().unwrap() != EdCurve::Ed25519 {
panic!("expected an ed25519 jwk");
}
let pk: [u8; PublicKey::LENGTH] = jwu::decode_b64(params.x.as_str()).unwrap().try_into().unwrap();
PublicKey::try_from(pk).unwrap()
}
pub(crate) fn generate_ed25519() -> (SecretKey, PublicKey) {
let private_key = SecretKey::generate().unwrap();
let public_key = private_key.public_key();
(private_key, public_key)
}