use crate::{Error, Result};
use crate::crypto::asymmetric::{Decryptor, KeyPair, Signer};
use crate::crypto::backend::interface::Asymmetric;
use crate::crypto::mpi;
use crate::crypto::mpi::{ProtectedMPI, MPI};
use crate::crypto::mem::Protected;
use crate::crypto::SessionKey;
use crate::packet::key::{Key4, SecretParts};
use crate::packet::{key, Key};
use crate::types::{Curve, HashAlgorithm, PublicKeyAlgorithm};
use std::convert::{TryFrom, TryInto};
use std::time::SystemTime;
use openssl::bn::{BigNum, BigNumRef, BigNumContext};
use openssl::derive::Deriver;
use openssl::ec::{EcGroup, EcKey, EcPoint, PointConversionForm};
use openssl::ecdsa::EcdsaSig;
use openssl::nid::Nid;
use openssl::pkey::PKey;
use openssl::pkey_ctx::PkeyCtx;
use openssl::rsa::{Padding, Rsa, RsaPrivateKeyBuilder};
use openssl::sign::Signer as OpenSslSigner;
use openssl::sign::Verifier;
impl Asymmetric for super::Backend {
fn x25519_generate_key() -> Result<(Protected, [u8; 32])> {
let pair = openssl::pkey::PKey::generate_x25519()?;
Ok((pair.raw_private_key()?.into(),
pair.raw_public_key()?.as_slice().try_into()?))
}
fn x25519_derive_public(secret: &Protected) -> Result<[u8; 32]> {
let key = PKey::private_key_from_raw_bytes(
secret, openssl::pkey::Id::X25519)?;
Ok(key.raw_public_key()?.as_slice().try_into()?)
}
fn x25519_shared_point(secret: &Protected, public: &[u8; 32])
-> Result<Protected> {
let public = PKey::public_key_from_raw_bytes(
public, openssl::pkey::Id::X25519)?;
let secret = PKey::private_key_from_raw_bytes(
secret, openssl::pkey::Id::X25519)?;
let mut deriver = Deriver::new(&secret)?;
deriver.set_peer(&public)?;
Ok(deriver.derive_to_vec()?.into())
}
}
impl TryFrom<&ProtectedMPI> for BigNum {
type Error = anyhow::Error;
fn try_from(mpi: &ProtectedMPI) -> std::result::Result<BigNum, anyhow::Error> {
let mut bn = BigNum::new_secure()?;
bn.copy_from_slice(mpi.value())?;
Ok(bn)
}
}
impl From<&BigNumRef> for ProtectedMPI {
fn from(bn: &BigNumRef) -> Self {
bn.to_vec().into()
}
}
impl From<BigNum> for ProtectedMPI {
fn from(bn: BigNum) -> Self {
bn.to_vec().into()
}
}
impl From<BigNum> for MPI {
fn from(bn: BigNum) -> Self {
bn.to_vec().into()
}
}
impl TryFrom<&MPI> for BigNum {
type Error = anyhow::Error;
fn try_from(mpi: &MPI) -> std::result::Result<BigNum, anyhow::Error> {
Ok(BigNum::from_slice(mpi.value())?)
}
}
impl From<&BigNumRef> for MPI {
fn from(bn: &BigNumRef) -> Self {
bn.to_vec().into()
}
}
impl TryFrom<&Curve> for Nid {
type Error = crate::Error;
fn try_from(curve: &Curve) -> std::result::Result<Nid, crate::Error> {
Ok(match curve {
Curve::NistP256 => Nid::X9_62_PRIME256V1,
Curve::NistP384 => Nid::SECP384R1,
Curve::NistP521 => Nid::SECP521R1,
Curve::BrainpoolP256 => Nid::BRAINPOOL_P256R1,
Curve::Unknown(_) if curve.is_brainpoolp384() => Nid::BRAINPOOL_P384R1,
Curve::BrainpoolP512 => Nid::BRAINPOOL_P512R1,
Curve::Ed25519 | // Handled differently.
Curve::Cv25519 | // Handled differently.
Curve::Unknown(_) =>