// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

//! Elliptic Curve-based cryptographic algorithms over NIST P curves.
//!
//! This module only supports elliptic curve cryptography over NIST's P curves,
//! defined in FIPS 186-3. These are the P-256, P-384, and P-521 curves (P-224
//! is considered insecure, and thus is not supported). The ECDSA and ECDH
//! algorithms are both defined over P curves, and so are exposed in this
//! module.
//!
//! Other elliptic curve algorithms on non-P curves live in other modules (e.g.,
//! operations on the Edwards 25519 curve live in the [`ed25519`] module).
//!
//! [`ed25519`]: ::public::ed25519

mod curve;

pub use public::ec::curve::{PCurve, P256, P384, P521};

use std::fmt::{self, Debug, Formatter};

use boringssl::{CHeapWrapper, CStackWrapper};
use public::ec::curve::CurveKind;
use public::ec::inner::EcKey;
use public::{inner::DerKey, DerPrivateKey, DerPublicKey, PrivateKey, PublicKey};
use util::Sealed;
use Error;

mod inner {
    use std::marker::PhantomData;

    use boringssl::{self, BoringError, CHeapWrapper, CStackWrapper};
    use public::ec::curve::PCurve;
    use public::inner::BoringDerKey;
    use Error;

    // A convenience wrapper around boringssl::EC_KEY.
    //
    // EcKey maintains the following invariants:
    // - The key is valid.
    // - The key is on the curve C.
    //
    // This is marked pub and put in this (non-public) module so that using it in impls of
    // the Key trait don't result in public-in-private errors.
    #[derive(Clone)]
    pub struct EcKey<C: PCurve> {
        pub key: CHeapWrapper<boringssl::EC_KEY>,
        _marker: PhantomData<C>,
    }

    impl<C: PCurve> EcKey<C> {
        pub fn generate() -> Result<EcKey<C>, BoringError> {
            let mut key = CHeapWrapper::default();
            // EC_KEY_set_group only errors if there's already a group set
            key.ec_key_set_group(&C::group()).unwrap();
            key.ec_key_generate_key()?;
            Ok(EcKey { key, _marker: PhantomData })
        }

        /// Creates an `EcKey` from a BoringSSL `EC_KEY`.
        ///
        /// `from_EC_KEY` validates that `key`'s curve is `C`.
        ///
        /// # Panics
        ///
        /// `from_EC_KEY` panics if `key`'s group is not set.
        #[allow(non_snake_case)]
        pub fn from_EC_KEY(key: CHeapWrapper<boringssl::EC_KEY>) -> Result<EcKey<C>, Error> {
            // ec_key_get0_group returns the EC_KEY's internal group pointer,
            // which is guaranteed to be set by the caller.
            C::validate_group(key.ec_key_get0_group().unwrap())?;
            Ok(EcKey { key, _marker: PhantomData })
        }
    }

    impl<C: PCurve> BoringDerKey for EcKey<C> {
        fn pkey_assign(&self, pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>) {
            pkey.evp_pkey_assign_ec_key(self.key.clone())
        }

        // NOTE: panics if the key is an EC key and doesn't have a group set
        // (due to EcKey::from_EC_KEY)
        fn pkey_get(pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>) -> Result<Self, Error> {
            let key = pkey.evp_pkey_get1_ec_key()?;
            EcKey::from_EC_KEY(key)
        }

        fn parse_private_key(cbs: &mut CStackWrapper<boringssl::CBS>) -> Result<EcKey<C>, Error> {
            // The last argument is a group. If it's not None, then it is either
            // used as the group or, if the DER encoding also contains a group,
            // the encoded group is validated against the group passed as an
            // argument. Note that this validation is mostly redundant - similar
            // validation is performed in EcKey::from_EC_KEY - however, it's not
            // fully redundant, since it allows keys to be parsed which have no
            // group.
            let key = CHeapWrapper::ec_key_parse_private_key(cbs, Some(C::group()))?;
            EcKey::from_EC_KEY(key)
        }

        fn marshal_private_key(
            &self,
            cbb: &mut CStackWrapper<boringssl::CBB>,
        ) -> Result<(), Error> {
            self.key.ec_key_marshal_private_key(cbb).map_err(From::from)
        }
    }

    #[cfg(test)]
    mod tests {
        use std::mem;

        use super::*;
        use public::ec::{P256, P384, P521};

        #[test]
        fn test_refcount() {
            fn test<C: PCurve>() {
                let key = EcKey::<C>::generate().unwrap();
                for i in 0..8 {
                    // make i clones and then free them all
                    let mut keys = Vec::new();
                    for _ in 0..i {
                        keys.push(key.clone());
                    }
                    mem::drop(keys);
                }
                mem::drop(key);
            }

            test::<P256>();
            test::<P384>();
            test::<P521>();
        }
    }
}

/// An elliptic curve public key over a P curve.
///
/// `EcPubKey` is a public key over the curve `C`.
pub struct EcPubKey<C: PCurve> {
    inner: EcKey<C>,
}

impl<C: PCurve> Sealed for EcPubKey<C> {}
impl<C: PCurve> DerPublicKey for EcPubKey<C> {}

impl<C: PCurve> DerKey for EcPubKey<C> {
    type Boring = EcKey<C>;
    fn boring(&self) -> &EcKey<C> {
        &self.inner
    }
    fn from_boring(inner: EcKey<C>) -> EcPubKey<C> {
        EcPubKey { inner }
    }
}

impl<C: PCurve> PublicKey for EcPubKey<C> {
    type Private = EcPrivKey<C>;
}

impl<C: PCurve> Debug for EcPubKey<C> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "EcPubKey")
    }
}

/// An elliptic curve private key over a P curve.
///
/// `EcPrivKey` is a private key over the curve `C`.
pub struct EcPrivKey<C: PCurve> {
    inner: EcKey<C>,
}

impl<C: PCurve> EcPrivKey<C> {
    /// Generates a new private key.
    #[must_use]
    pub fn generate() -> Result<EcPrivKey<C>, Error> {
        Ok(EcPrivKey { inner: EcKey::generate()? })
    }
}

impl<C: PCurve> Sealed for EcPrivKey<C> {}
impl<C: PCurve> DerPrivateKey for EcPrivKey<C> {}

impl<C: PCurve> DerKey for EcPrivKey<C> {
    type Boring = EcKey<C>;
    fn boring(&self) -> &EcKey<C> {
        &self.inner
    }
    fn from_boring(inner: EcKey<C>) -> EcPrivKey<C> {
        EcPrivKey { inner }
    }
}

impl<C: PCurve> PrivateKey for EcPrivKey<C> {
    type Public = EcPubKey<C>;

    fn public(&self) -> EcPubKey<C> {
        EcPubKey { inner: self.inner.clone() }
    }
}

impl<C: PCurve> Debug for EcPrivKey<C> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "EcPrivKey")
    }
}

/// An elliptic curve public key whose curve is unknown at compile time.
///
/// An `EcPubKeyAnyCurve` is an enum of [`EcPubKey`]s over the three supported
/// curves.
#[allow(missing_docs)]
#[derive(Debug)]
pub enum EcPubKeyAnyCurve {
    P256(EcPubKey<P256>),
    P384(EcPubKey<P384>),
    P521(EcPubKey<P521>),
}

impl EcPubKeyAnyCurve {
    /// Parses a public key in DER format with any curve.
    ///
    /// `parse_from_der` is like [`DerPublicKey::parse_from_der`], but it
    /// accepts any [`PCurve`] rather than a particular, static curve.
    ///
    /// Since [`EcPubKey`] requires a static [`PCurve`] type parameter, the
    /// `parse_from_der` function on `EcPubKey`'s `DerPublicKey` implementation
    /// can only be called when the curve is known ahead of time. This function,
    /// on the other hand, accepts any curve.
    ///
    /// Because the curve is not known statically, one must be specified in the DER
    /// input.
    ///
    /// [`DerPublicKey::parse_from_der`]: ::public::DerPublicKey::parse_from_der
    /// [`PublicKey`]: ::public::PublicKey
    #[must_use]
    pub fn parse_from_der(bytes: &[u8]) -> Result<EcPubKeyAnyCurve, Error> {
        CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
            let mut evp_pkey = CHeapWrapper::evp_parse_public_key(cbs)?;
            let key = evp_pkey.evp_pkey_get1_ec_key()?;
            if cbs.cbs_len() > 0 {
                return Err(Error::new("excess data provided after valid DER input".to_string()));
            }

            // EVP_parse_public_key guarantees that the returned key has its group
            // set, so this unwrap is safe.
            let group = key.ec_key_get0_group().unwrap();
            Ok(match CurveKind::from_nid(group.ec_group_get_curve_name())? {
                CurveKind::P256 => {
                    EcPubKeyAnyCurve::P256(EcPubKey { inner: EcKey::from_EC_KEY(key.clone())? })
                }
                CurveKind::P384 => {
                    EcPubKeyAnyCurve::P384(EcPubKey { inner: EcKey::from_EC_KEY(key.clone())? })
                }
                CurveKind::P521 => {
                    EcPubKeyAnyCurve::P521(EcPubKey { inner: EcKey::from_EC_KEY(key.clone())? })
                }
            })
        })
    }
}

/// An elliptic curve private key whose curve is unknown at compile time.
///
/// An `EcPrivKeyAnyCurve` is an enum of [`EcPrivKey`]s over the three supported
/// curves.
#[allow(missing_docs)]
#[derive(Debug)]
pub enum EcPrivKeyAnyCurve {
    P256(EcPrivKey<P256>),
    P384(EcPrivKey<P384>),
    P521(EcPrivKey<P521>),
}

impl EcPrivKeyAnyCurve {
    /// Gets the public key corresponding to this private key.
    #[must_use]
    pub fn public(&self) -> EcPubKeyAnyCurve {
        match self {
            EcPrivKeyAnyCurve::P256(key) => EcPubKeyAnyCurve::P256(key.public()),
            EcPrivKeyAnyCurve::P384(key) => EcPubKeyAnyCurve::P384(key.public()),
            EcPrivKeyAnyCurve::P521(key) => EcPubKeyAnyCurve::P521(key.public()),
        }
    }

    /// Parses a private key in DER format with any curve.
    ///
    /// `parse_from_der` is like [`DerPrivateKey::parse_from_der`], but it
    /// accepts any [`PCurve`] rather than a particular, static curve.
    ///
    /// Since [`EcPrivKey`] requires a static [`PCurve`] type parameter, the
    /// `parse_from_der` function on `EcPrivKey`'s `DerPrivateKey`
    /// implementation can only be called when the curve is known ahead of time.
    /// This function, on the other hand, accepts any curve.
    ///
    /// Because the curve is not known statically, one must be specified in the DER
    /// input.
    ///
    /// [`DerPrivateKey::parse_from_der`]: ::public::DerPrivateKey::parse_from_der
    /// [`PrivateKey`]: ::public::PrivateKey
    #[must_use]
    pub fn parse_from_der(bytes: &[u8]) -> Result<EcPrivKeyAnyCurve, Error> {
        CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
            // The last argument is a group. Since it's None,
            // EC_KEY_parse_private_key will require the DER to name the group.
            let key = CHeapWrapper::ec_key_parse_private_key(cbs, None)?;
            if cbs.cbs_len() > 0 {
                return Err(Error::new("excess data provided after valid DER input".to_string()));
            }

            // TODO(joshlf): Add documentation to EC_KEY_parse_private_key
            // guaranteeing that the internal group pointer is set.
            let group = key.ec_key_get0_group().unwrap();
            Ok(match CurveKind::from_nid(group.ec_group_get_curve_name())? {
                CurveKind::P256 => {
                    EcPrivKeyAnyCurve::P256(EcPrivKey { inner: EcKey::from_EC_KEY(key.clone())? })
                }
                CurveKind::P384 => {
                    EcPrivKeyAnyCurve::P384(EcPrivKey { inner: EcKey::from_EC_KEY(key.clone())? })
                }
                CurveKind::P521 => {
                    EcPrivKeyAnyCurve::P521(EcPrivKey { inner: EcKey::from_EC_KEY(key.clone())? })
                }
            })
        })
    }
}

/// The Elliptic Curve Digital Signature Algorithm.
pub mod ecdsa {
    use std::fmt::{self, Debug, Formatter};
    use std::marker::PhantomData;

    use boringssl;
    use hash::{inner::Digest, Hasher, Sha256, Sha384};
    use public::{
        ec::{EcPrivKey, EcPubKey, PCurve, P256, P384, P521},
        Signature,
    };
    use util::Sealed;
    use Error;

    /// A hash function which is compatible with ECDSA signatures over the curve
    /// `C`.
    ///
    /// An ECDSA signature is constructed by hashing the message and then
    /// signing the resulting digest. However, EC keys over certain curves may
    /// not be compatible with all hashes. In particular, some digests may be
    /// too long (in number of bytes) and thus not correspond to a point on the
    /// curve. `EcdsaHash<C>` is implemented by all hash functions whose digests
    /// are compatible with ECDSA signatures over the curve `C`.
    pub trait EcdsaHash<C: PCurve>: Sealed {}

    impl EcdsaHash<P256> for Sha256 {}
    impl EcdsaHash<P384> for Sha256 {}
    impl EcdsaHash<P384> for Sha384 {}
    impl EcdsaHash<P521> for Sha256 {}
    impl EcdsaHash<P521> for Sha384 {}

    // The maximum length of an ECDSA signature over P-521. Since this isn't
    // exposed in the API, we can increase later if we add support for curves
    // with larger signatures.
    //
    // This was calculated with the following equation, which is thanks to
    // agl@google.com:
    //
    //  r = s = (521 + 7)/8              # Bytes to store the integers r and s
    //        = 66
    //  DER encoded bytes =   (1         # type byte 0x02
    //                      +  1         # length byte
    //                      +  1         # possible 0 padding
    //                      +  66) * 2   # one for each of r and s
    //                      +  1         # ASN.1 SEQUENCE type byte
    //                      +  2         # outer length
    //                    =    141
    const MAX_SIGNATURE_LEN: usize = 141;

    /// A DER-encoded ECDSA signature.
    #[must_use]
    pub struct EcdsaSignature<C: PCurve, H: Hasher + EcdsaHash<C>> {
        bytes: [u8; MAX_SIGNATURE_LEN],
        // Invariant: len is in [0; MAX_SIGNATURE_LEN). If len is 0, it
        // indicates an invalid signature. Invalid signatures can be produced
        // when a caller invokes from_bytes with a byte slice longer than
        // MAX_SIGNATURE_LEN. Such signatures cannot possibly have been
        // generated by an ECDSA signature over any of the curves we support,
        // and so it could not possibly be valid. In other words, it would never
        // be correct for Signature::is_valid to return true when invoked on such a
        // signature.
        //
        // However, if we were to simply truncate the byte slice and store a
        // subset of it, then we might open ourselves up to attacks in which an
        // attacker induces a mismatch between the signature that the caller
        // /thinks/ is being verified and the signature that is /actually/ being
        // verified. Thus, it's important that we always reject such signatures.
        //
        // Finally, it's OK for us to use 0 as the sentinal value to mean
        // "invalid signature" because ECDSA can never produce a 0-byte
        // signature. Thus, we will never produce a 0-byte signature from
        // ecdsa_sign, and similarly, if the caller constructs a 0-byte
        // signature using from_bytes, it's correct for us to treat it as
        // invalid.
        len: usize,
        _marker: PhantomData<(C, H)>,
    }

    impl<C: PCurve, H: Hasher + EcdsaHash<C>> EcdsaSignature<C, H> {
        /// Constructs an `EcdsaSignature` from raw bytes.
        #[must_use]
        pub fn from_bytes(bytes: &[u8]) -> EcdsaSignature<C, H> {
            if bytes.len() > MAX_SIGNATURE_LEN {
                // see comment on the len field for why we do this
                return Self::empty();
            }
            let mut ret = Self::empty();
            (&mut ret.bytes[..bytes.len()]).copy_from_slice(bytes);
            ret.len = bytes.len();
            ret
        }

        // TODO(joshlf): Once we have const generics, have this return a
        // fixed-length array.

        /// Gets the raw bytes of this `EcdsaSignature`.
        #[must_use]
        pub fn bytes(&self) -> &[u8] {
            &self.bytes[..self.len]
        }

        fn is_valid_format(&self) -> bool {
            self.len != 0
        }

        fn empty() -> EcdsaSignature<C, H> {
            EcdsaSignature { bytes: [0u8; MAX_SIGNATURE_LEN], len: 0, _marker: PhantomData }
        }
    }

    impl<C: PCurve, H: Hasher + EcdsaHash<C>> Sealed for EcdsaSignature<C, H> {}
    impl<C: PCurve, H: Hasher + EcdsaHash<C>> Signature for EcdsaSignature<C, H> {
        type PrivateKey = EcPrivKey<C>;

        fn sign(key: &EcPrivKey<C>, message: &[u8]) -> Result<EcdsaSignature<C, H>, Error> {
            let digest = H::hash(message);
            let mut sig = EcdsaSignature::empty();
            sig.len = boringssl::ecdsa_sign(digest.as_ref(), &mut sig.bytes[..], &key.inner.key)?;
            Ok(sig)
        }

        fn is_valid(&self, key: &EcPubKey<C>, message: &[u8]) -> bool {
            if !self.is_valid_format() {
                // see comment on EcdsaSignature::len for why we do this
                return false;
            }
            let digest = H::hash(message);
            boringssl::ecdsa_verify(digest.as_ref(), self.bytes(), &key.inner.key)
        }
    }

    impl<C: PCurve, H: Hasher + EcdsaHash<C>> Debug for EcdsaSignature<C, H> {
        fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
            write!(f, "EcdsaSignature")
        }
    }

    #[cfg(test)]
    mod tests {
        use super::{super::*, *};
        use public::testutil::test_signature_smoke;

        #[test]
        fn test_smoke() {
            let p256 = EcPrivKey::<P256>::generate().unwrap();
            let p384 = EcPrivKey::<P384>::generate().unwrap();
            let p521 = EcPrivKey::<P521>::generate().unwrap();

            test_signature_smoke(
                &p256,
                EcdsaSignature::<_, Sha256>::from_bytes,
                EcdsaSignature::bytes,
            );
            test_signature_smoke(
                &p384,
                EcdsaSignature::<_, Sha256>::from_bytes,
                EcdsaSignature::bytes,
            );
            test_signature_smoke(
                &p384,
                EcdsaSignature::<_, Sha384>::from_bytes,
                EcdsaSignature::bytes,
            );
            test_signature_smoke(
                &p521,
                EcdsaSignature::<_, Sha256>::from_bytes,
                EcdsaSignature::bytes,
            );
            test_signature_smoke(
                &p521,
                EcdsaSignature::<_, Sha384>::from_bytes,
                EcdsaSignature::bytes,
            );
        }

        #[test]
        fn test_invalid_signature() {
            fn test_is_invalid(sig: &EcdsaSignature<P256, Sha256>) {
                assert_eq!(sig.len, 0);
                assert!(!sig.is_valid_format());
                assert!(!sig.is_valid(&EcPrivKey::<P256>::generate().unwrap().public(), &[],));
            }
            test_is_invalid(&EcdsaSignature::from_bytes(&[0; MAX_SIGNATURE_LEN + 1]));
            test_is_invalid(&EcdsaSignature::from_bytes(&[]));
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use hash::Sha256;
    use public::ec::ecdsa::*;
    use public::Signature;
    use util::should_fail;

    #[test]
    fn test_generate() {
        EcPrivKey::<P256>::generate().unwrap();
        EcPrivKey::<P384>::generate().unwrap();
        EcPrivKey::<P521>::generate().unwrap();
    }

    #[test]
    fn test_marshal_parse() {
        // Test various combinations of parsing and serializing keys.
        //
        // Since we need to test dynamic parsing (the
        // parse_private_key_der_any_curve and parse_public_key_der_any_curve
        // functions), we need a way of unwrapping their return values into a
        // static key type. Unfortunately, there's no way (on stable Rust) to do
        // that generically, so the caller must pass a function which will do
        // it.
        fn test<
            C: PCurve,
            F: Fn(EcPrivKeyAnyCurve) -> EcPrivKey<C>,
            G: Fn(EcPubKeyAnyCurve) -> EcPubKey<C>,
        >(
            unwrap_priv_any: F,
            unwrap_pub_any: G,
        ) where
            Sha256: EcdsaHash<C>,
        {
            const MESSAGE: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7];
            let key = EcPrivKey::<C>::generate().unwrap();

            let parsed_key = EcPrivKey::<C>::parse_from_der(&key.marshal_to_der()).unwrap();
            let parsed_key_any_curve =
                unwrap_priv_any(EcPrivKeyAnyCurve::parse_from_der(&key.marshal_to_der()).unwrap());
            let pubkey = key.public();
            let parsed_pubkey = EcPubKey::<C>::parse_from_der(&pubkey.marshal_to_der()).unwrap();
            let parsed_pubkey_any_curve =
                unwrap_pub_any(EcPubKeyAnyCurve::parse_from_der(&pubkey.marshal_to_der()).unwrap());

            fn sign_and_verify<C: PCurve>(privkey: &EcPrivKey<C>, pubkey: &EcPubKey<C>)
            where
                Sha256: EcdsaHash<C>,
            {
                let sig = EcdsaSignature::<C, Sha256>::sign(&privkey, MESSAGE).unwrap();
                assert!(
                    EcdsaSignature::<C, Sha256>::from_bytes(sig.bytes()).is_valid(&pubkey, MESSAGE)
                )
            }

            // Sign and verify with every pair of keys to make sure we parsed
            // the same key we marshaled.
            sign_and_verify(&key, &pubkey);
            sign_and_verify(&key, &parsed_pubkey);
            sign_and_verify(&key, &parsed_pubkey_any_curve);
            sign_and_verify(&parsed_key, &pubkey);
            sign_and_verify(&parsed_key, &parsed_pubkey);
            sign_and_verify(&parsed_key, &parsed_pubkey_any_curve);
            sign_and_verify(&parsed_key_any_curve, &pubkey);
            sign_and_verify(&parsed_key_any_curve, &parsed_pubkey);
            sign_and_verify(&parsed_key_any_curve, &parsed_pubkey_any_curve);

            let _ = EcPubKey::<C>::marshal_to_der;
            let _ = EcPubKey::<C>::parse_from_der;
        }

        macro_rules! unwrap_any_curve {
            ($name:ident, $any_type:ty, $key_type:ty, $curve_variant:path) => {
                fn $name(key: $any_type) -> $key_type {
                    match key {
                        $curve_variant(key) => key,
                        _ => panic!("unexpected curve"),
                    }
                }
            };
        }

        unwrap_any_curve!(
            unwrap_priv_key_any_p256,
            EcPrivKeyAnyCurve,
            EcPrivKey<P256>,
            EcPrivKeyAnyCurve::P256
        );
        unwrap_any_curve!(
            unwrap_priv_key_any_p384,
            EcPrivKeyAnyCurve,
            EcPrivKey<P384>,
            EcPrivKeyAnyCurve::P384
        );
        unwrap_any_curve!(
            unwrap_priv_key_any_p521,
            EcPrivKeyAnyCurve,
            EcPrivKey<P521>,
            EcPrivKeyAnyCurve::P521
        );
        unwrap_any_curve!(
            unwrap_pub_key_any_p256,
            EcPubKeyAnyCurve,
            EcPubKey<P256>,
            EcPubKeyAnyCurve::P256
        );
        unwrap_any_curve!(
            unwrap_pub_key_any_p384,
            EcPubKeyAnyCurve,
            EcPubKey<P384>,
            EcPubKeyAnyCurve::P384
        );
        unwrap_any_curve!(
            unwrap_pub_key_any_p521,
            EcPubKeyAnyCurve,
            EcPubKey<P521>,
            EcPubKeyAnyCurve::P521
        );

        test::<P256, _, _>(unwrap_priv_key_any_p256, unwrap_pub_key_any_p256);
        test::<P384, _, _>(unwrap_priv_key_any_p384, unwrap_pub_key_any_p384);
        test::<P521, _, _>(unwrap_priv_key_any_p521, unwrap_pub_key_any_p521);
    }

    #[test]
    fn test_parse_fail() {
        // Test that invalid input is rejected.
        fn test_parse_invalid<C: PCurve>() {
            should_fail(
                EcPrivKey::<C>::parse_from_der(&[]),
                "EcPrivKey::parse_from_der",
                "elliptic curve routines:OPENSSL_internal:DECODE_ERROR",
            );
            should_fail(
                EcPubKey::<C>::parse_from_der(&[]),
                "EcPubKey::parse_from_der",
                "public key routines:OPENSSL_internal:DECODE_ERROR",
            );
            should_fail(
                EcPrivKeyAnyCurve::parse_from_der(&[]),
                "EcPrivKeyAnyCurve::parse_from_der",
                "elliptic curve routines:OPENSSL_internal:DECODE_ERROR",
            );
            should_fail(
                EcPubKeyAnyCurve::parse_from_der(&[]),
                "EcPubKeyAnyCurve::parse_from_der",
                "public key routines:OPENSSL_internal:DECODE_ERROR",
            );
        }

        test_parse_invalid::<P256>();
        test_parse_invalid::<P384>();
        test_parse_invalid::<P521>();

        // Test that, when a particular curve is expected, other curves are
        // rejected.
        fn test_parse_wrong_curve<C1: PCurve, C2: PCurve>() {
            let privkey = EcPrivKey::<C1>::generate().unwrap();
            let key_der = privkey.marshal_to_der();
            should_fail(
                EcPrivKey::<C2>::parse_from_der(&key_der),
                "EcPrivKey::parse_from_der",
                "elliptic curve routines:OPENSSL_internal:GROUP_MISMATCH",
            );
            let key_der = privkey.public().marshal_to_der();
            should_fail(
                EcPubKey::<C2>::parse_from_der(&key_der),
                "EcPubKey::parse_from_der",
                "unexpected curve:",
            );
        }

        // All pairs of curves, (X, Y), such that X != Y.
        test_parse_wrong_curve::<P256, P384>();
        test_parse_wrong_curve::<P256, P521>();
        test_parse_wrong_curve::<P384, P256>();
        test_parse_wrong_curve::<P384, P521>();
        test_parse_wrong_curve::<P521, P256>();
        test_parse_wrong_curve::<P521, P384>();
    }
}
