/* Copyright (c) 2023, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

//! `Pkey` and `PkeyCtx` classes for holding asymmetric keys. This module is intended for internal
//! use within this crate only, to create higher-level abstractions suitable to be exposed
//! externally.

use crate::{ec::EcKey, CSliceMut, ForeignType};

pub(crate) struct Pkey {
    ptr: *mut bssl_sys::EVP_PKEY,
}

// Safety: Implementation ensures `from_ptr(x).as_ptr == x`
unsafe impl ForeignType for Pkey {
    type CType = bssl_sys::EVP_PKEY;

    unsafe fn from_ptr(ptr: *mut Self::CType) -> Self {
        Self { ptr }
    }

    fn as_ptr(&self) -> *mut Self::CType {
        self.ptr
    }
}

impl From<&EcKey> for Pkey {
    fn from(eckey: &EcKey) -> Self {
        // Safety: EVP_PKEY_new does not have any preconditions
        let pkey = unsafe { bssl_sys::EVP_PKEY_new() };
        assert!(!pkey.is_null());
        // Safety:
        // - pkey is just allocated and is null-checked
        // - EcKey ensures eckey.ptr is valid during its lifetime
        // - EVP_PKEY_set1_EC_KEY doesn't take ownership
        let result =
            unsafe { bssl_sys::EVP_PKEY_set1_EC_KEY(pkey, eckey.as_ptr()) };
        assert_eq!(result, 1, "bssl_sys::EVP_PKEY_set1_EC_KEY failed");
        Self { ptr: pkey }
    }
}

impl Drop for Pkey {
    fn drop(&mut self) {
        // Safety: `self.ptr` is owned by this struct
        unsafe { bssl_sys::EVP_PKEY_free(self.ptr) }
    }
}

pub(crate) struct PkeyCtx {
    ptr: *mut bssl_sys::EVP_PKEY_CTX,
}

impl PkeyCtx {
    pub fn new(pkey: &Pkey) -> Self {
        // Safety:
        // - `Pkey` ensures `pkey.ptr` is valid, and EVP_PKEY_CTX_new does not take ownership.
        let pkeyctx = unsafe { bssl_sys::EVP_PKEY_CTX_new(pkey.ptr, core::ptr::null_mut()) };
        assert!(!pkeyctx.is_null());
        Self { ptr: pkeyctx }
    }

    #[allow(clippy::panic)]
    pub(crate) fn diffie_hellman(
        self,
        other_public_key: &Pkey,
        mut output: CSliceMut,
    ) -> Result<(), String> {
        let result = unsafe { bssl_sys::EVP_PKEY_derive_init(self.ptr) };
        assert_eq!(result, 1, "bssl_sys::EVP_PKEY_derive_init failed");

        let result = unsafe { bssl_sys::EVP_PKEY_derive_set_peer(self.ptr, other_public_key.ptr) };
        assert_eq!(result, 1, "bssl_sys::EVP_PKEY_derive_set_peer failed");

        let result =
            unsafe { bssl_sys::EVP_PKEY_derive(self.ptr, output.as_mut_ptr(), &mut output.len()) };
        match result {
            0 => Err("bssl_sys::EVP_PKEY_derive failed".to_owned()),
            1 => Ok(()),
            _ => panic!("Unexpected result {result:?} from bssl_sys::EVP_PKEY_derive"),
        }
    }
}

impl Drop for PkeyCtx {
    fn drop(&mut self) {
        // Safety: self.ptr is owned by this struct
        unsafe { bssl_sys::EVP_PKEY_CTX_free(self.ptr) }
    }
}
