// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![allow(dead_code)]
use rand::Rng;

use anyhow::{format_err, Context as _};
use fidl::{self, endpoints::ServerEnd};
use fidl_fuchsia_kms::{
    AsymmetricKeyAlgorithm, AsymmetricPrivateKeyProxy, Error, KeyManagerMarker, KeyManagerProxy,
    KeyOrigin, KeyProvider,
};
use fidl_fuchsia_mem::Buffer;
use fuchsia_async as fasync;
use fuchsia_component::client::connect_to_service;
use fuchsia_syslog as syslog;
use fuchsia_zircon as zx;
use log::info;
use serde::{Deserialize, Serialize};
use serde_json;
use std::fs;

use mundane::hash::*;
use mundane::public::ec::ecdsa::EcdsaHash;
use mundane::public::ec::*;
use mundane::public::*;

static TEST_KEY_NAME: &str = "test-key";
static CONFIG_PATH: &str = "/config/data/crypto_provider_config.json";

fn map_err_to_string<T>(result: Result<Result<T, Error>, fidl::Error>) -> Result<T, String> {
    match result {
        Ok(Ok(a)) => Ok(a),
        Ok(Err(err)) => Err(format!("{:?}", err)),
        Err(err) => Err(format!("{:?}", err)),
    }
}

#[fuchsia_async::run_singlethreaded(test)]
async fn test() -> Result<(), anyhow::Error> {
    syslog::init_with_tags(&["kms_test_client"]).expect("syslog init should not fail");
    test_asymmetric_key(AsymmetricKeyAlgorithm::EcdsaSha256P256).await?;
    test_asymmetric_key(AsymmetricKeyAlgorithm::EcdsaSha512P384).await?;
    test_asymmetric_key(AsymmetricKeyAlgorithm::EcdsaSha512P521).await?;
    test_seal_unseal_data().await?;
    Ok(())
}

#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Config<'a> {
    pub crypto_provider: &'a str,
}

fn get_provider_from_config() -> Result<KeyProvider, anyhow::Error> {
    let json = fs::read_to_string(CONFIG_PATH)?;
    let config: Config<'_> = serde_json::from_str(&json)?;
    match config.crypto_provider {
        "OpteeProvider" => Ok(KeyProvider::OpteeProvider),
        "SoftwareProvider" => Ok(KeyProvider::SoftwareProvider),
        "SoftwareAsymmetricOnlyProvider" => Ok(KeyProvider::SoftwareAsymmetricOnlyProvider),
        _ => Err(format_err!("Unsupported provider {:?}", config.crypto_provider)),
    }
}

async fn test_asymmetric_key(algorithm: AsymmetricKeyAlgorithm) -> Result<(), anyhow::Error> {
    info!("Begin asymmetric key tests for algorithm: {:?}", algorithm);
    let key_manager = connect_to_service::<KeyManagerMarker>()
        .context("Failed to connect to key manager service")?;
    let public_key = {
        // Generate a new key.
        let asymmetric_key_proxy =
            generate_asymmetric_key(&key_manager, TEST_KEY_NAME, algorithm).await?;

        // Export public key.
        let public_key = test_export_public_key(&asymmetric_key_proxy).await?;

        // Get key property.
        let key_algorithm = get_asymmetric_key_algorithm(&asymmetric_key_proxy).await?;
        assert_eq!(key_algorithm, algorithm, "Key algorithm mismatch!");
        let key_origin = get_asymmetric_key_origin(&asymmetric_key_proxy).await?;
        assert_eq!(key_origin, KeyOrigin::Generated, "Key origin mismatch!");
        let provider = get_asymmetric_key_provider(&asymmetric_key_proxy).await?;
        assert_eq!(
            provider,
            get_provider_from_config().unwrap_or(KeyProvider::SoftwareProvider),
            "Using the wrong crypto provider."
        );

        public_key
    };

    // Compare the exported public key.
    let asymmetric_key_proxy = get_asymmetric_key(&key_manager, TEST_KEY_NAME).await?;
    let public_key_compare = test_export_public_key(&asymmetric_key_proxy).await?;
    assert_eq!(public_key, public_key_compare, "Public key for the same key mismatch.");

    // Test signing using the generated key.
    test_sign_verify_data(algorithm, &key_manager).await?;

    {
        // Test generating a key with the same name.
        test_generate_asymmetric_key_exists(&key_manager, TEST_KEY_NAME, algorithm).await?;
    }

    {
        // Read the generated key.
        let asymmetric_key_proxy = get_asymmetric_key(&key_manager, TEST_KEY_NAME).await?;
        // Test deleting the generated key.
        test_delete_key(&key_manager, TEST_KEY_NAME).await?;
        // Verify that the key is deleted.
        check_key_not_exist(&key_manager, TEST_KEY_NAME).await?;
        // Verify that user would get key_not_found if trying to use the deleted key.
        test_sign_key_not_exists(&asymmetric_key_proxy).await?;
        // Verify deleting a deleted key would fail.
        test_delete_key_not_exist(&key_manager, TEST_KEY_NAME).await?;
    }

    {
        // Generate a new key_manager to simulate another user.
        let key_manager_2 = connect_to_service::<KeyManagerMarker>()
            .context("Failed to connect to key manager service")?;
        // The first user create a new key.
        let asymmetric_key_proxy =
            generate_asymmetric_key(&key_manager, TEST_KEY_NAME, algorithm).await?;
        // The second user delete the same key.
        test_delete_key(&key_manager_2, TEST_KEY_NAME).await?;
        // The first user should get key_not_found if trying to get the deleted key.
        check_key_not_exist(&key_manager, TEST_KEY_NAME).await?;
        // The first user should get key_not_found if trying to use the deleted key.
        test_sign_key_not_exists(&asymmetric_key_proxy).await?;
    }

    {
        // Test importing private key.
        let (private_key_data, public_key_data) = match algorithm {
            AsymmetricKeyAlgorithm::EcdsaSha256P256 => {
                let test_key = EcPrivKey::<P256>::generate()?;
                (test_key.marshal_to_der(), test_key.public().marshal_to_der())
            }
            AsymmetricKeyAlgorithm::EcdsaSha512P384 => {
                let test_key = EcPrivKey::<P384>::generate()?;
                (test_key.marshal_to_der(), test_key.public().marshal_to_der())
            }
            AsymmetricKeyAlgorithm::EcdsaSha512P521 => {
                let test_key = EcPrivKey::<P521>::generate()?;
                (test_key.marshal_to_der(), test_key.public().marshal_to_der())
            }
            _ => panic!("not implemented!"),
        };

        let asymmetric_key_proxy =
            import_asymmetric_key(&key_manager, private_key_data, TEST_KEY_NAME, algorithm).await?;

        // Export public key.
        let public_key = test_export_public_key(&asymmetric_key_proxy).await?;
        assert_eq!(public_key, public_key_data, "Public key mismatch!");

        // Get key property.
        let key_algorithm = get_asymmetric_key_algorithm(&asymmetric_key_proxy).await?;
        assert_eq!(key_algorithm, algorithm, "Key algorithm in key property mismatch!");
        let key_origin = get_asymmetric_key_origin(&asymmetric_key_proxy).await?;
        assert_eq!(key_origin, KeyOrigin::Imported, "Key origin mismatch!");

        // Test signing using the imported key.
        test_sign_verify_data(algorithm, &key_manager).await?;

        // Test deleting the imported key.
        test_delete_key(&key_manager, TEST_KEY_NAME).await?;
    }

    info!("All asymmetric key tests for algorithm: {:?} passed!", algorithm);
    Ok(())
}

async fn test_sign_verify_data(
    algorithm: AsymmetricKeyAlgorithm,
    key_manager: &KeyManagerProxy,
) -> Result<(), anyhow::Error> {
    // Read the key.
    let asymmetric_key_proxy = get_asymmetric_key(&key_manager, TEST_KEY_NAME).await?;
    let public_key = test_export_public_key(&asymmetric_key_proxy).await?;

    // Sign test data with the key again.
    let test_data = generate_test_data();
    let signature = test_sign(&asymmetric_key_proxy, &test_data).await?;

    // Verify signature.
    verify_signature(algorithm, &signature, &public_key, &test_data)?;
    Ok(())
}

async fn test_seal_unseal_data() -> Result<(), anyhow::Error> {
    info!("Begin sealing and unsealing data test");
    let key_manager = connect_to_service::<KeyManagerMarker>()
        .context("Failed to connect to key manager service")?;
    let test_data = generate_test_data();
    let vmo = zx::Vmo::create(test_data.len() as u64)?;
    vmo.write(&test_data, 0)?;
    let mut buffer = Buffer { vmo, size: test_data.len() as u64 };
    let result = key_manager.seal_data(&mut buffer).await;
    let result_buffer =
        map_err_to_string(result).map_err(|err| format_err!("Error sealing data: {:?}", err))?;

    let mut result_data = vec![0; result_buffer.size as usize];
    result_buffer.vmo.read(&mut result_data, 0).unwrap();

    let vmo = zx::Vmo::create(result_data.len() as u64)?;
    vmo.write(&result_data, 0)?;
    let mut buffer = Buffer { vmo, size: result_data.len() as u64 };
    let result = key_manager.unseal_data(&mut buffer).await;
    let result_buffer =
        map_err_to_string(result).map_err(|err| format_err!("Error unsealing data: {:?}", err))?;
    let mut result_data = vec![0; result_buffer.size as usize];
    result_buffer.vmo.read(&mut result_data, 0)?;
    assert_eq!(&test_data, &result_data, "Unsealing after sealing gets different data!");
    info!("Sealing and unsealing data tests passed!");
    Ok(())
}

async fn generate_asymmetric_key<'a>(
    key_manager: &'a KeyManagerProxy,
    key_name: &'static str,
    key_algorithm: AsymmetricKeyAlgorithm,
) -> Result<AsymmetricPrivateKeyProxy, anyhow::Error> {
    let (server_chan, client_chan) = zx::Channel::create()?;
    let result = key_manager
        .generate_asymmetric_key_with_algorithm(
            key_name,
            key_algorithm,
            ServerEnd::new(server_chan),
        )
        .await;
    map_err_to_string(result)
        .map_err(|err| format_err!("Error generating asymmetric key: {:?}", err))?;
    info!("Asymmetric private key successfully generated.");
    let client_async = fasync::Channel::from_channel(client_chan).unwrap();
    let asymmetric_key_proxy = AsymmetricPrivateKeyProxy::new(client_async);
    Ok(asymmetric_key_proxy)
}

async fn test_generate_asymmetric_key_exists<'a>(
    key_manager: &'a KeyManagerProxy,
    key_name: &'static str,
    key_algorithm: AsymmetricKeyAlgorithm,
) -> Result<(), anyhow::Error> {
    let (server_chan, _) = zx::Channel::create()?;
    let result = key_manager
        .generate_asymmetric_key_with_algorithm(
            key_name,
            key_algorithm,
            ServerEnd::new(server_chan),
        )
        .await
        .map_err(|err| format_err!("Error generating asymmetric key: {:?}", err))?;
    match result {
        Err(Error::KeyAlreadyExists) => {
            info!("Verify that the key already exists.");
            Ok(())
        }
        Ok(_) => Err(format_err!("Generating a key with the same name must not be allowed!")),
        Err(err) => Err(format_err!("Error generating asymmetric key: {:?}", err)),
    }
}

async fn get_asymmetric_key<'a>(
    key_manager: &'a KeyManagerProxy,
    key_name: &'static str,
) -> Result<AsymmetricPrivateKeyProxy, anyhow::Error> {
    let (server_chan, client_chan) = zx::Channel::create()?;
    let result =
        key_manager.get_asymmetric_private_key(key_name, ServerEnd::new(server_chan)).await;
    map_err_to_string(result)
        .map_err(|err| format_err!("Error getting asymmetric key: {:?}", err))?;
    info!("Asymmetric private key successfully read.");
    let client_async = fasync::Channel::from_channel(client_chan).unwrap();
    let asymmetric_key_proxy = AsymmetricPrivateKeyProxy::new(client_async);
    Ok(asymmetric_key_proxy)
}

async fn test_sign_key_not_exists(key: &AsymmetricPrivateKeyProxy) -> Result<(), anyhow::Error> {
    let test_data = generate_test_data();
    let vmo = zx::Vmo::create(test_data.len() as u64)?;
    vmo.write(&test_data, 0)?;
    let result = key
        .sign(&mut Buffer { vmo, size: test_data.len() as u64 })
        .await
        .map_err(|err| format_err!("Error generating signature: {:?}", err))?;
    match result {
        Err(Error::KeyNotFound) => {
            info!("Verify that the key does not exist.");
            Ok(())
        }
        Ok(_) => Err(format_err!("Key not deleted.")),
        Err(err) => Err(format_err!("Error generating signature: {:?}", err)),
    }
}

async fn check_key_not_exist<'a>(
    key_manager: &'a KeyManagerProxy,
    key_name: &'static str,
) -> Result<(), anyhow::Error> {
    let (server_chan, _client_chan) = zx::Channel::create()?;
    let result = key_manager
        .get_asymmetric_private_key(key_name, ServerEnd::new(server_chan))
        .await
        .map_err(|err| format_err!("Error getting asymmetric key: {:?}", err))?;
    match result {
        Err(Error::KeyNotFound) => {
            info!("Verify that the key does not exist.");
            Ok(())
        }
        Ok(()) => Err(format_err!("Key not deleted.")),
        Err(err) => Err(format_err!("Error getting asymmetric key: {:?}", err)),
    }
}

async fn test_sign<'a>(
    key: &'a AsymmetricPrivateKeyProxy,
    test_data: &'a Vec<u8>,
) -> Result<Vec<u8>, anyhow::Error> {
    let vmo = zx::Vmo::create(test_data.len() as u64)?;
    vmo.write(test_data, 0)?;
    let result = key.sign(&mut Buffer { vmo, size: test_data.len() as u64 }).await;
    let signature = map_err_to_string(result)
        .map_err(|err| format_err!("Error generating signature: {:?}", err))?;
    let signature_data = signature.bytes;
    info!("Signature successfully generated with size: {}", signature_data.len());
    Ok(signature_data)
}

async fn test_export_public_key(key: &AsymmetricPrivateKeyProxy) -> Result<Vec<u8>, anyhow::Error> {
    let result = key.get_public_key().await;
    let public_key = map_err_to_string(result)
        .map_err(|err| format_err!("Error exporting public key: {:?}", err))?;
    let public_key_data = public_key.bytes;
    info!("Public key successfully exported with size: {}", public_key_data.len());
    Ok(public_key_data)
}

async fn test_delete_key<'a>(
    key_manager: &'a KeyManagerProxy,
    key_name: &'static str,
) -> Result<(), anyhow::Error> {
    let result = key_manager.delete_key(key_name).await;
    map_err_to_string(result).map_err(|err| format_err!("Error deleting key: {:?}", err))?;
    info!("Key successfully deleted.");
    Ok(())
}

async fn test_delete_key_not_exist<'a>(
    key_manager: &'a KeyManagerProxy,
    key_name: &'static str,
) -> Result<(), anyhow::Error> {
    let result = key_manager
        .delete_key(key_name)
        .await
        .map_err(|err| format_err!("Error deleting key: {:?}", err))?;
    match result {
        Err(Error::KeyNotFound) => {
            info!("Verify a key that does not exist could not be deleted.");
            Ok(())
        }
        Ok(()) => Err(format_err!(
            "KEY_NOT_FOUND must be returned if the key to be deleted is not found."
        )),
        Err(err) => Err(format_err!("Error deleting key: {:?}", err)),
    }
}

async fn get_asymmetric_key_algorithm(
    key: &AsymmetricPrivateKeyProxy,
) -> Result<AsymmetricKeyAlgorithm, anyhow::Error> {
    let result = key.get_key_algorithm().await;
    map_err_to_string(result).map_err(|err| format_err!("Error exporting public key: {:?}", err))
}

async fn get_asymmetric_key_origin(
    key: &AsymmetricPrivateKeyProxy,
) -> Result<KeyOrigin, anyhow::Error> {
    let result = key.get_key_origin().await;
    map_err_to_string(result).map_err(|err| format_err!("Error getting key origin: {:?}", err))
}

async fn get_asymmetric_key_provider(
    key: &AsymmetricPrivateKeyProxy,
) -> Result<KeyProvider, anyhow::Error> {
    let result = key.get_key_provider().await;
    map_err_to_string(result)
        .map_err(|err| format_err!("Error getting crypto provider name: {:?}", err))
}

async fn import_asymmetric_key<'a>(
    key_manager: &'a KeyManagerProxy,
    private_key_data: Vec<u8>,
    key_name: &'static str,
    key_algorithm: AsymmetricKeyAlgorithm,
) -> Result<AsymmetricPrivateKeyProxy, anyhow::Error> {
    let (server_chan, client_chan) = zx::Channel::create()?;
    let result = key_manager
        .import_asymmetric_private_key(
            &mut private_key_data.into_iter(),
            key_name,
            key_algorithm,
            ServerEnd::new(server_chan),
        )
        .await;
    map_err_to_string(result)
        .map_err(|err| format_err!("Error importing asymmetric key: {:?}", err))?;
    info!("Asymmetric private key successfully imported.");
    let client_async = fasync::Channel::from_channel(client_chan).unwrap();
    let asymmetric_key_proxy = AsymmetricPrivateKeyProxy::new(client_async);
    Ok(asymmetric_key_proxy)
}

fn generate_test_data() -> Vec<u8> {
    let mut test_data: Vec<u8> = vec![0; 512];
    let mut rng = rand::thread_rng();
    for i in 0..test_data.len() {
        test_data[i] = rng.gen();
    }
    test_data
}

fn verify_signature<'a>(
    algorithm: AsymmetricKeyAlgorithm,
    signature: &'a Vec<u8>,
    public_key: &'a Vec<u8>,
    test_data: &'a Vec<u8>,
) -> Result<(), anyhow::Error> {
    match algorithm {
        AsymmetricKeyAlgorithm::EcdsaSha256P256 => {
            verify_sig::<P256, Sha256>(&signature, &public_key, &test_data)?;
        }
        AsymmetricKeyAlgorithm::EcdsaSha512P384 => {
            verify_sig::<P384, Sha512>(&signature, &public_key, &test_data)?;
        }
        AsymmetricKeyAlgorithm::EcdsaSha512P521 => {
            verify_sig::<P521, Sha512>(&signature, &public_key, &test_data)?;
        }
        _ => (),
    }
    Ok(())
}

fn verify_sig<'a, C: PCurve, H: Hasher + EcdsaHash<C>>(
    signature: &'a Vec<u8>,
    public_key: &'a Vec<u8>,
    test_data: &'a Vec<u8>,
) -> Result<(), anyhow::Error> {
    let ec_key = EcPubKey::<C>::parse_from_der(public_key)
        .map_err(|_| format_err!("Failed to parse public key!"))?;
    let result = ecdsa::EcdsaSignature::<C, H>::from_bytes(signature).is_valid(&ec_key, test_data);
    if !result {
        Err(format_err!("Failed to verify signature."))
    } else {
        info!("Signature verified successfully with the exported public key.");
        Ok(())
    }
}
