use crate::{Error, Result};
use crate::crypto::asymmetric::{Decryptor, KeyPair, Signer};
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::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 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(_) =>
return Err(crate::Error::UnsupportedEllipticCurve(curve.clone()).into()),
})
}
}
impl Signer for KeyPair {
fn public(&self) -> &Key<key::PublicParts, key::UnspecifiedRole> {
KeyPair::public(self)
}
fn sign(&mut self, hash_algo: HashAlgorithm, digest: &[u8]) -> Result<mpi::Signature> {
use crate::PublicKeyAlgorithm::*;
#[allow(deprecated)]
self.secret().map(
|secret| match (self.public().pk_algo(), self.public().mpis(), secret) {
(
RSAEncryptSign,
mpi::PublicKey::RSA { e, n },
mpi::SecretKeyMaterial::RSA { p, q, d, .. },
)
| (
RSASign,
mpi::PublicKey::RSA { e, n },
mpi::SecretKeyMaterial::RSA { p, q, d, .. },
) => {
let key =
RsaPrivateKeyBuilder::new(n.try_into()?, e.try_into()?