use nethsm::Credentials;
use nethsm::Passphrase;
use nethsm::test::DEFAULT_KEY_ID;
use nethsm::test::DEFAULT_OPERATOR_USER_ID;
use nethsm::test::DEFAULT_OPERATOR_USER_PASSPHRASE;
use nethsm::test::NetHsmImage;
use nethsm::test::OTHER_KEY_ID;
use nethsm::test::OTHER_OPERATOR_USER_ID;
use nethsm::test::OTHER_OPERATOR_USER_PASSPHRASE;
use nethsm::test::nethsm_with_keys;
use nethsm::{NetHsm, SignatureType};
use rsa::RsaPublicKey;
use rsa::pkcs1v15::VerifyingKey;
use rsa::pkcs8::DecodePublicKey;
use rsa::sha2::Sha256;
use rsa::signature::Verifier;
use rstest::rstest;
use rustainers::Container;
use testresult::TestResult;
static MESSAGE: &[u8] = b"Hello World!";
#[rstest]
#[tokio::test]
async fn signing(
#[future] nethsm_with_keys: TestResult<(NetHsm, Container<NetHsmImage>)>,
) -> TestResult {
let (nethsm, _container) = nethsm_with_keys.await?;
nethsm.add_credentials(Credentials::new(
DEFAULT_OPERATOR_USER_ID.parse()?,
Some(Passphrase::new(
DEFAULT_OPERATOR_USER_PASSPHRASE.to_string(),
)),
));
nethsm.use_credentials(&DEFAULT_OPERATOR_USER_ID.parse()?)?;
let signature = nethsm.sign(&DEFAULT_KEY_ID.parse()?, SignatureType::EdDsa, MESSAGE)?;
println!("A raw signature created using the default key on the NetHSM: {signature:?}");
let pubkey = nethsm.get_public_key(&DEFAULT_KEY_ID.parse()?)?;
println!("The default key on the NetHSM: {pubkey}");
let pubkey_bytes = ed25519_dalek::pkcs8::PublicKeyBytes::from_public_key_pem(&pubkey)?;
let pubkey_verifier = ed25519_dalek::VerifyingKey::from_bytes(&pubkey_bytes.to_bytes())?;
let signature_parsed = ed25519_dalek::Signature::from_slice(&signature)?;
pubkey_verifier.verify(MESSAGE, &signature_parsed)?;
nethsm.add_credentials(Credentials::new(
OTHER_OPERATOR_USER_ID.parse()?,
Some(Passphrase::new(OTHER_OPERATOR_USER_PASSPHRASE.to_string())),
));
nethsm.use_credentials(&OTHER_OPERATOR_USER_ID.parse()?)?;
let signature = nethsm.sign(&OTHER_KEY_ID.parse()?, SignatureType::Pkcs1, MESSAGE)?;
println!("A raw signature created using another key on the NetHSM: {signature:?}");
let pubkey = nethsm.get_public_key(&OTHER_KEY_ID.parse()?)?;
println!("The public key of another key on the NetHSM: {pubkey}");
let pubkey = RsaPublicKey::from_public_key_pem(&pubkey)?;
let verifying_key: VerifyingKey<Sha256> = VerifyingKey::new_unprefixed(pubkey);
let signature_parsed = rsa::pkcs1v15::Signature::try_from(signature.as_slice())?;
println!(
"A signature created using an RSA pubkey for which the NetHSM provides the private key: {signature_parsed:?}"
);
verifying_key.verify(MESSAGE, &signature_parsed)?;
Ok(())
}