// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use anyhow::{bail, Result};
use regex::Regex;
use serde_annotate::Annotate;
use std::any::Any;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use structopt::StructOpt;

use opentitanlib::app::command::CommandDispatch;
use opentitanlib::app::TransportWrapper;
use opentitanlib::crypto::rsa::{
    Exponent, Modulus, N0Inv, RsaPrivateKey, RsaPublicKey, Signature, RR,
};
use opentitanlib::crypto::sha256::Sha256Digest;
use opentitanlib::util::parse_int::ParseInt;

/// Given the path to a public key, returns the public key. Given
/// the path to a private key, extracts the public key from the private
/// key and returns the public key.
fn load_pub_or_priv_key(path: &PathBuf) -> Result<RsaPublicKey> {
    if let Ok(key) = RsaPublicKey::from_pkcs1_der_file(path) {
        return Ok(key);
    }
    Ok(RsaPublicKey::from_private_key(
        &RsaPrivateKey::from_pkcs8_der_file(path)?,
    ))
}

#[derive(serde::Serialize)]
pub struct RsaKeyInfo {
    pub key_num_bits: usize,
    pub modulus: Modulus,
    pub public_exponent: Exponent,
    pub n0_inv: N0Inv,
    pub rr: RR,
}

#[derive(serde::Serialize)]
pub struct RsaKeyInfoInWords {
    pub key_num_bits: usize,
    pub modulus: Vec<String>,
    pub public_exponent: Vec<String>,
    pub n0_inv: Vec<String>,
    pub rr: Vec<String>,
}

/// Show public information of a private or public RSA key
#[derive(Debug, StructOpt)]
pub struct RsaKeyShowCommand {
    #[structopt(
        name = "DER_FILE",
        help = "RSA public or private key file in DER format"
    )]
    der_file: PathBuf,
}

impl CommandDispatch for RsaKeyShowCommand {
    fn run(
        &self,
        _context: &dyn Any,
        _transport: &TransportWrapper,
    ) -> Result<Option<Box<dyn Annotate>>> {
        let key = load_pub_or_priv_key(&self.der_file)?;

        Ok(Some(Box::new(RsaKeyInfo {
            key_num_bits: key.modulus_num_bits(),
            modulus: key.modulus(),
            public_exponent: key.exponent(),
            n0_inv: key.n0_inv()?,
            rr: key.rr(),
        })))
    }
}

/// Generate a 3072-bit RSA public private key pair with exponent 65537. RSA private key will
/// be written to <OUTPUT_DIR>/<BASENAME>.der and RSA public key will be written to
/// <OUTPUT_DIR>/<BASENAME>.pub.der
#[derive(Debug, StructOpt)]
pub struct RsaKeyGenerateCommand {
    #[structopt(name = "OUTPUT_DIR", help = "Output directory")]
    output_dir: PathBuf,
    #[structopt(name = "BASENAME", help = "Basename for the generated key pair")]
    basename: String,
}

impl CommandDispatch for RsaKeyGenerateCommand {
    fn run(
        &self,
        _context: &dyn Any,
        _transport: &TransportWrapper,
    ) -> Result<Option<Box<dyn Annotate>>> {
        let private_key = RsaPrivateKey::new()?;
        let mut der_file = self.output_dir.to_owned();
        der_file.push(&self.basename);
        der_file.set_extension("der");
        private_key.to_pkcs8_der_file(&der_file)?;

        der_file.set_extension("pub.der");
        RsaPublicKey::from_private_key(&private_key).to_pkcs1_der_file(&der_file)?;

        Ok(None)
    }
}

/// Export public information of a private or public RSA key
/// to a C header that can be used in the ROM or ROM_EXT
#[derive(Debug, StructOpt)]
pub struct RsaKeyExportCommand {
    #[structopt(
        name = "DER_FILE",
        help = "RSA public or private key file in DER format"
    )]
    der_file: PathBuf,
    #[structopt(name = "OUTPUT_FILE", help = "output header file to generate")]
    output_file: Option<PathBuf>,
}

/// Write the content of a big integer as an array of 32-bit words.
/// The number must be represented as an array of bytes in little-endian whose
/// length is a multiple of four. The output is compatible with the format used
/// by the ROM and ROM_EXT with sigverify_rom_key_t, ie the modulus and n0_inv
/// are represented as an array of 32-bit words in little-endian. To make the function's
/// output flexible, the function can print up to a specified number of items per
/// line, and each line can be prefixed and suffixed with a specified string
fn write_bigint_as_u32<W: Write>(
    out: &mut W,
    number: Vec<u8>,
    nr_per_line: usize,
    prefix: &str,
    suffix: &str,
) -> Result<()> {
    let chunk = std::mem::size_of::<u32>();
    assert!(
        number.len() % chunk == 0,
        "the big integer size is not a multiple of 4 bytes"
    );
    for (idx, num) in number.windows(chunk).step_by(chunk).enumerate() {
        // print prefix and newline on multiples of nr_per_line
        if idx % nr_per_line == 0 {
            if idx != 0 {
                write!(out, "{}\n", suffix)?;
            }
            write!(out, "{}", prefix)?;
        }
        // print one 32-bit word
        let val = u32::from_le_bytes(num.try_into().unwrap());
        write!(out, "{:#010x}, ", val)?;
    }
    // extra return to the line
    write!(out, "{}\n", suffix)?;
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use anyhow::Result;

    #[test]
    fn test_write_bigint_as_u32() -> Result<()> {
        let mut buf: Vec<u8> = Vec::new();
        let bignum = vec![
            0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe, 0x18, 0x29, 0x3a, 0x4b,
        ];
        write_bigint_as_u32(&mut buf, bignum, 2, "X", "Y")?;
        let output = br#"X0x76543210, 0xfedcba98, Y
X0x4b3a2918, Y
"#;
        assert_eq!(buf, output);
        Ok(())
    }
}

impl CommandDispatch for RsaKeyExportCommand {
    fn run(
        &self,
        _context: &dyn Any,
        _transport: &TransportWrapper,
    ) -> Result<Option<Box<dyn Annotate>>> {
        let key = load_pub_or_priv_key(&self.der_file)?;

        let output_path = match &self.output_file {
            Some(path) => path.clone(),
            None => {
                // if no output file is provided, derive the name of the file from the
                // name of the key
                let mut out_path = self.der_file.clone();
                out_path.set_extension("h");
                out_path
            }
        };
        // We try to catch the mistake of a user that specifies the key file as output,
        // which would overwrite it. This will not detect situations where there is a symlink
        // involved so this will only catch "obvious" mistakes.
        if self.der_file == output_path {
            bail!("the output file is the same as the key file, this would overwrite the key, not allowing this")
        }
        println!("exporting key to {}", output_path.display());

        let mut file = File::create(&output_path)?;
        // construct a key name from the key file name
        let keyname = self
            .der_file
            .file_name()
            .expect("this should be a valid file name since we opened the file")
            .to_string_lossy();
        let re = Regex::new(r#"(.pub)?.der$"#).unwrap();
        let keyname = re.replace_all(&keyname, "");
        let re = Regex::new(r#"[^a-zA-Z0-9]"#).unwrap();
        let keyname = re.replace_all(&keyname, "_").to_ascii_uppercase();
        // we cannot know the purpose of this key but the header guard should probably include it
        // so we add some extra text to the guard that will not compile to force the user to fix it
        let header_guard = format!("{}_H", keyname);
        // write header guard
        writeln!(&mut file, "#ifndef {}", header_guard)?;
        writeln!(&mut file, "#define {}", header_guard)?;
        writeln!(&mut file, "")?;
        writeln!(&mut file, "#define {} \\", keyname)?;
        writeln!(&mut file, " {{ \\")?;
        writeln!(&mut file, "    .n = \\")?;
        writeln!(&mut file, "        {{{{ \\")?;
        write_bigint_as_u32(
            &mut file,
            key.modulus().to_le_bytes(),
            5,
            "            ",
            "\\",
        )?;
        writeln!(&mut file, "        }}}}, \\")?;
        writeln!(&mut file, "    .n0_inv = {{ \\")?;
        write_bigint_as_u32(&mut file, key.n0_inv()?.to_le_bytes(), 4, "        ", "\\")?;
        writeln!(&mut file, "        }}, \\")?;
        writeln!(&mut file, " }}")?;
        writeln!(&mut file, "")?;
        writeln!(&mut file, "#endif // {}", header_guard)?;

        Ok(None)
    }
}

#[derive(Debug, StructOpt, CommandDispatch)]
pub enum RsaKeySubcommands {
    Show(RsaKeyShowCommand),
    Generate(RsaKeyGenerateCommand),
    Export(RsaKeyExportCommand),
}

#[derive(serde::Serialize)]
pub struct RsaSignResult {
    pub digest: String,
    pub signature: String,
}

#[derive(Debug, StructOpt)]
pub struct RsaSignCommand {
    #[structopt(
        name = "DER_FILE",
        parse(try_from_str=RsaPrivateKey::from_pkcs8_der_file),
        help = "RSA private key file in PKCS#1 DER format"
    )]
    private_key: RsaPrivateKey,
    #[structopt(
        name = "SHA256_DIGEST",
        parse(try_from_str=ParseInt::from_str),
        help = "SHA256 digest of the message"
    )]
    digest: Sha256Digest,
    #[structopt(
        name = "output",
        short,
        long,
        help = "File name to write the signature to"
    )]
    output: Option<PathBuf>,
}

impl CommandDispatch for RsaSignCommand {
    fn run(
        &self,
        _context: &dyn Any,
        _transport: &TransportWrapper,
    ) -> Result<Option<Box<dyn Annotate>>> {
        let signature = self.private_key.sign(&self.digest)?;
        if let Some(output) = &self.output {
            signature.write_to_file(output)?;
        }
        Ok(Some(Box::new(RsaSignResult {
            digest: self.digest.to_string(),
            signature: signature.to_string(),
        })))
    }
}

#[derive(Debug, StructOpt)]
pub struct RsaVerifyCommand {
    #[structopt(name = "KEY", help = "Key file in DER format")]
    der_file: PathBuf,
    #[structopt(
        name = "SHA256_DIGEST",
        help = "SHA256 digest of the message as a hex string (big-endian), i.e. 0x..."
    )]
    digest: String,
    #[structopt(
        name = "SIGNATURE",
        help = "Signature to be verified as a hex string (big-endian), i.e. 0x..."
    )]
    signature: String,
}

impl CommandDispatch for RsaVerifyCommand {
    fn run(
        &self,
        _context: &dyn Any,
        _transport: &TransportWrapper,
    ) -> Result<Option<Box<dyn Annotate>>> {
        let key = RsaPublicKey::from_pkcs1_der_file(&self.der_file)?;
        let digest = Sha256Digest::from_str(&self.digest)?;
        let signature = Signature::from_str(&self.signature)?;
        key.verify(&digest, &signature)?;
        Ok(None)
    }
}

#[derive(Debug, StructOpt, CommandDispatch)]
/// RSA commands.
#[allow(clippy::large_enum_variant)]
pub enum Rsa {
    Key(RsaKeySubcommands),
    Sign(RsaSignCommand),
    Verify(RsaVerifyCommand),
}
