//! # SCT.rs: SCT verification library
//! This library implements verification of Signed Certificate Timestamps.
//! These are third-party assurances that a particular certificate has
//! been included in a Certificate Transparency log.
//!
//! See RFC6962 for the details of the formats implemented here.
//!
//! It is intended to be useful to libraries which perform certificate
//! validation, OCSP libraries, and TLS libraries.

#![forbid(unsafe_code,
          unstable_features)]
#![deny(trivial_casts,
        trivial_numeric_casts,
        missing_docs,
        unused_import_braces,
        unused_extern_crates,
        unused_qualifications)]

/// Describes a CT log
///
/// This structure contains some metadata fields not used by the library.
/// Rationale: it makes sense to keep this metadata with the other
/// values for review purposes.
#[derive(Debug)]
pub struct Log<'a> {
    /// The operator's name/description of the log.
    /// This field is not used by the library.
    pub description: &'a str,

    /// The certificate submission url.
    /// This field is not used by the library.
    pub url: &'a str,

    /// Which entity operates the log.
    /// This field is not used by the library.
    pub operated_by: &'a str,

    /// Public key usable for verifying certificates.
    /// TODO: fixme format of this; should be a SPKI
    /// so the `id` is verifiable, but currently is a
    /// raw public key (like, an ECPoint or RSAPublicKey).
    pub key: &'a [u8],

    /// Key hash, which is SHA256 applied to the SPKI
    /// encoding.
    pub id: [u8; 32],

    /// The log's maximum merge delay.
    /// This field is not used by the library.
    pub max_merge_delay: usize
}

/// How sct.rs reports errors.
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Error {
    /// The SCT was somehow misencoded, truncated or otherwise corrupt.
    MalformedSCT,

    /// The SCT contained an invalid signature.
    InvalidSignature,

    /// The SCT was signed in the future.  Clock skew?
    TimestampInFuture,

    /// The SCT had a version that this library does not handle.
    UnsupportedSCTVersion,

    /// The SCT was refers to an unknown log.
    UnknownLog,
}

impl Error {
    /// Applies a suggested policy for error handling:
    ///
    /// Returns `true` if the error should end processing
    /// for whatever the SCT is attached to (like, abort a TLS
    /// handshake).
    ///
    /// Returns `false` if this error should be a 'soft failure'
    /// -- the SCT is unverifiable with this library and set of
    /// logs.
    pub fn should_be_fatal(&self) -> bool {
        match *self {
            Error::UnknownLog
                | Error::UnsupportedSCTVersion => false,
            _ => true
        }
    }
}

fn lookup(logs: &[&Log], id: &[u8]) -> Result<usize, Error> {
    for (i, l) in logs.iter().enumerate() {
        if id == &l.id {
            return Ok(i);
        }
    }

    Err(Error::UnknownLog)
}

fn decode_u64(inp: untrusted::Input) -> u64 {
    let b = inp.as_slice_less_safe();
    assert_eq!(b.len(), 8);
    (b[0] as u64) << 56 |
        (b[1] as u64) << 48 |
        (b[2] as u64) << 40 |
        (b[3] as u64) << 32 |
        (b[4] as u64) << 24 |
        (b[5] as u64) << 16 |
        (b[6] as u64) << 8 |
        (b[7] as u64)
}

fn decode_u16(inp: untrusted::Input) -> u16 {
    let b = inp.as_slice_less_safe();
    assert_eq!(b.len(), 2);
    (b[0] as u16) << 8 | (b[1] as u16)
}

fn write_u64(v: u64, out: &mut Vec<u8>) {
    out.push((v >> 56) as u8);
    out.push((v >> 48) as u8);
    out.push((v >> 40) as u8);
    out.push((v >> 32) as u8);
    out.push((v >> 24) as u8);
    out.push((v >> 16) as u8);
    out.push((v >> 8) as u8);
    out.push(v as u8);
}

fn write_u24(v: u32, out: &mut Vec<u8>) {
    out.push((v >> 16) as u8);
    out.push((v >> 8) as u8);
    out.push(v as u8);
}

fn write_u16(v: u16, out: &mut Vec<u8>) {
    out.push((v >> 8) as u8);
    out.push(v as u8);
}

struct SCT<'a> {
    log_id: &'a [u8],
    timestamp: u64,
    sig_alg: u16,
    sig: &'a [u8],
    exts: &'a [u8],
}

const ECDSA_SHA256: u16 = 0x0403;
const ECDSA_SHA384: u16 = 0x0503;
const RSA_PKCS1_SHA256: u16 = 0x0401;
const RSA_PKCS1_SHA384: u16 = 0x0501;
const SCT_V1: u8 = 0u8;
const SCT_TIMESTAMP: u8 = 0u8;
const SCT_X509_ENTRY: [u8; 2] = [0, 0];

impl<'a> SCT<'a> {
    fn verify(&self, key: &[u8], cert: &[u8]) -> Result<(), Error> {
        let alg: &dyn ring::signature::VerificationAlgorithm = match self.sig_alg {
            ECDSA_SHA256 => &ring::signature::ECDSA_P256_SHA256_ASN1,
            ECDSA_SHA384 => &ring::signature::ECDSA_P384_SHA384_ASN1,
            RSA_PKCS1_SHA256 => &ring::signature::RSA_PKCS1_2048_8192_SHA256,
            RSA_PKCS1_SHA384 => &ring::signature::RSA_PKCS1_2048_8192_SHA384,
            _ => return Err(Error::InvalidSignature)
        };

        let mut data = Vec::new();
        data.push(SCT_V1);
        data.push(SCT_TIMESTAMP);
        write_u64(self.timestamp, &mut data);
        data.extend_from_slice(&SCT_X509_ENTRY);
        write_u24(cert.len() as u32, &mut data);
        data.extend_from_slice(cert);
        write_u16(self.exts.len() as u16, &mut data);
        data.extend_from_slice(self.exts);

        let key = ring::signature::UnparsedPublicKey::new(alg, key);

        key.verify(&data, self.sig)
            .map_err(|_| Error::InvalidSignature)
    }

    fn parse(enc: &'a [u8]) -> Result<SCT<'a>, Error> {
        let inp = untrusted::Input::from(enc);

        inp.read_all(
            Error::MalformedSCT,
            |rd| {
                let version = rd.read_byte()
                    .map_err(|_| Error::MalformedSCT)?;
                if version != 0 {
                    return Err(Error::UnsupportedSCTVersion);
                }

                let id = rd.read_bytes(32)
                    .map_err(|_| Error::MalformedSCT)?;
                let timestamp = rd.read_bytes(8)
                    .map_err(|_| Error::MalformedSCT)
                    .map(decode_u64)?;

                let ext_len = rd.read_bytes(2)
                    .map_err(|_| Error::MalformedSCT)
                    .map(decode_u16)?;
                let exts = rd.read_bytes(ext_len as usize)
                    .map_err(|_| Error::MalformedSCT)?;

                let sig_alg = rd.read_bytes(2)
                    .map_err(|_| Error::MalformedSCT)
                    .map(decode_u16)?;
                let sig_len = rd.read_bytes(2)
                    .map_err(|_| Error::MalformedSCT)
                    .map(decode_u16)?;
                let sig = rd.read_bytes(sig_len as usize)
                    .map_err(|_| Error::MalformedSCT)?;

                let ret = SCT {
                    log_id: id.as_slice_less_safe(),
                    timestamp: timestamp,
                    sig_alg: sig_alg,
                    sig: sig.as_slice_less_safe(),
                    exts: exts.as_slice_less_safe(),
                };

                Ok(ret)
            })
    }
}

/// Verifies that the SCT `sct` (a `SignedCertificateTimestamp` encoding)
/// is a correctly signed timestamp for `cert` (a DER-encoded X.509 end-entity
/// certificate) valid `at_time`.  `logs` describe the CT logs trusted by
/// the caller to sign such an SCT.
///
/// On success, this function returns the log used as an index into `logs`.
/// Otherwise, it returns an `Error`.
pub fn verify_sct(cert: &[u8],
                  sct: &[u8],
                  at_time: u64,
                  logs: &[&Log]) -> Result<usize, Error> {
    let sct = SCT::parse(sct)?;
    let i = lookup(logs, &sct.log_id)?;
    let log = logs[i];
    sct.verify(log.key, cert)?;

    if sct.timestamp > at_time {
        return Err(Error::TimestampInFuture);
    }

    Ok(i)
}

#[cfg(test)]
mod tests_google;
#[cfg(test)]
mod tests_generated;
#[cfg(test)]
mod tests;
