Merge "[public] Make marshal and parsing functions methods"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b572595..cfc4dc0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,3 +11,11 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 
 ## [Unreleased]
+
+### Changed
+- In the `public` module, functions to parse and marshal DER-encoded
+  public/private keys have been moved from bare functions to methods on the
+  `DerPublicKey` and `DerPrivateKey` traits.
+- In the `public::ec` module, functions to parse and marshal DER-encoded
+  public/private keys as the `EcPubKeyAnyCurve` and `EcPrivKeyAnyCurve` types
+  have been moved from bare functions to methods on those types.
\ No newline at end of file
diff --git a/src/public/ec/mod.rs b/src/public/ec/mod.rs
index 6bbc6e9..6a0117e 100644
--- a/src/public/ec/mod.rs
+++ b/src/public/ec/mod.rs
@@ -223,7 +223,7 @@
 /// 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. It is returned from [`parse_public_key_der_any_curve`].
+/// curves.
 #[allow(missing_docs)]
 #[derive(Debug)]
 pub enum EcPubKeyAnyCurve {
@@ -232,10 +232,57 @@
     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. It is returned from [`parse_private_key_der_any_curve`].
+/// curves.
 #[allow(missing_docs)]
 #[derive(Debug)]
 pub enum EcPrivKeyAnyCurve {
@@ -254,97 +301,52 @@
             EcPrivKeyAnyCurve::P521(key) => EcPubKeyAnyCurve::P521(key.public()),
         }
     }
-}
 
-/// Parses a public key in DER format with any curve.
-///
-/// `parse_public_key_der_any_curve` is like [`parse_public_key_der`], but it
-/// accepts any [`PCurve`] rather than a particular, static curve.
-///
-/// Since `parse_public_key_der` takes a [`PublicKey`] type argument, and
-/// [`EcPubKey`] requires a static [`PCurve`] type parameter,
-/// `parse_public_key_der` can only be called when the curve is known ahead of
-/// time. `parse_public_key_der_any_curve`, on the other hand, accepts any
-/// curve. It returns an [`EcPubKeyAnyCurve`], which is an enum of keys over the
-/// three supported curves.
-///
-/// Because the curve is not known statically, one must be specified in the DER
-/// input.
-///
-/// [`parse_public_key_der`]: ::public::parse_public_key_der
-/// [`PublicKey`]: ::public::PublicKey
-#[must_use]
-pub fn parse_public_key_der_any_curve(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("malformed DER input".to_string()));
-        }
+    /// 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(),
+                ));
+            }
 
-        // 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())?,
-                }),
-            },
-        )
-    })
-}
-
-/// Parses a private key in DER format with any curve.
-///
-/// `parse_private_key_der_any_curve` is like [`parse_private_key_der`], but it
-/// accepts any [`PCurve`] rather than a particular, static curve.
-///
-/// Since `parse_private_key_der` takes a [`PrivateKey`] type argument, and
-/// [`EcPrivKey`] requires a static [`PCurve`] type parameter,
-/// `parse_private_key_der` can only be called when the curve is known ahead of
-/// time. `parse_private_key_der_any_curve`, on the other hand, accepts any
-/// curve. It returns an [`EcPrivKeyAnyCurve`], which is an enum of keys over
-/// the three supported curves.
-///
-/// Because the curve is not known statically, one must be specified in the DER
-/// input.
-///
-/// [`parse_private_key_der`]: ::public::parse_private_key_der
-/// [`PrivateKey`]: ::public::PrivateKey
-#[must_use]
-pub fn parse_private_key_der_any_curve(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("malformed 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())?,
-                }),
-            },
-        )
-    })
+            // 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.
@@ -544,10 +546,7 @@
     use super::*;
     use hash::Sha256;
     use public::ec::ecdsa::*;
-    use public::{
-        marshal_private_key_der, marshal_public_key_der, parse_private_key_der,
-        parse_public_key_der, Signature,
-    };
+    use public::Signature;
     use util::should_fail;
 
     #[test]
@@ -580,28 +579,21 @@
             const MESSAGE: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7];
             let key = EcPrivKey::<C>::generate().unwrap();
 
-            let parsed_key: EcPrivKey<C> =
-                parse_private_key_der(&marshal_private_key_der(&key)).unwrap();
-            let parsed_key_any_curve = unwrap_priv_any(
-                parse_private_key_der_any_curve(&marshal_private_key_der(&key)).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_public_key_der(&marshal_public_key_der(&pubkey)).unwrap();
-            let parsed_pubkey_any_curve = unwrap_pub_any(
-                parse_public_key_der_any_curve(&marshal_public_key_der(&pubkey)).unwrap(),
-            );
+            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<C1: PCurve, C2: PCurve>(
-                privkey: &EcPrivKey<C1>,
-                pubkey: &EcPubKey<C2>,
-            ) where
-                Sha256: EcdsaHash<C1>,
-                Sha256: EcdsaHash<C2>,
+            fn sign_and_verify<C: PCurve>(privkey: &EcPrivKey<C>, pubkey: &EcPubKey<C>)
+            where
+                Sha256: EcdsaHash<C>,
             {
-                let sig = EcdsaSignature::<C1, Sha256>::sign(&privkey, MESSAGE).unwrap();
+                let sig = EcdsaSignature::<C, Sha256>::sign(&privkey, MESSAGE).unwrap();
                 assert!(
-                    EcdsaSignature::<C2, Sha256>::from_bytes(sig.bytes()).verify(&pubkey, MESSAGE)
+                    EcdsaSignature::<C, Sha256>::from_bytes(sig.bytes()).verify(&pubkey, MESSAGE)
                 )
             }
 
@@ -617,8 +609,8 @@
             sign_and_verify(&parsed_key_any_curve, &parsed_pubkey);
             sign_and_verify(&parsed_key_any_curve, &parsed_pubkey_any_curve);
 
-            let _ = marshal_public_key_der::<EcPubKey<C>>;
-            let _ = parse_public_key_der::<EcPubKey<C>>;
+            let _ = EcPubKey::<C>::marshal_to_der;
+            let _ = EcPubKey::<C>::parse_from_der;
         }
 
         macro_rules! unwrap_any_curve {
@@ -679,22 +671,22 @@
         // Test that invalid input is rejected.
         fn test_parse_invalid<C: PCurve>() {
             should_fail(
-                parse_private_key_der::<EcPrivKey<C>>(&[]),
+                EcPrivKey::<C>::parse_from_der(&[]),
                 "parse_private_key_der",
                 "elliptic curve routines:OPENSSL_internal:DECODE_ERROR",
             );
             should_fail(
-                parse_public_key_der::<EcPubKey<C>>(&[]),
+                EcPubKey::<C>::parse_from_der(&[]),
                 "parse_public_key_der",
                 "public key routines:OPENSSL_internal:DECODE_ERROR",
             );
             should_fail(
-                parse_private_key_der_any_curve(&[]),
+                EcPrivKeyAnyCurve::parse_from_der(&[]),
                 "parse_private_key_der_any_curve",
                 "elliptic curve routines:OPENSSL_internal:DECODE_ERROR",
             );
             should_fail(
-                parse_public_key_der_any_curve(&[]),
+                EcPubKeyAnyCurve::parse_from_der(&[]),
                 "parse_public_key_der_any_curve",
                 "public key routines:OPENSSL_internal:DECODE_ERROR",
             );
@@ -708,15 +700,15 @@
         // rejected.
         fn test_parse_wrong_curve<C1: PCurve, C2: PCurve>() {
             let privkey = EcPrivKey::<C1>::generate().unwrap();
-            let key_der = marshal_private_key_der(&privkey);
+            let key_der = privkey.marshal_to_der();
             should_fail(
-                parse_private_key_der::<EcPrivKey<C2>>(&key_der),
+                EcPrivKey::<C2>::parse_from_der(&key_der),
                 "parse_private_key_der",
                 "elliptic curve routines:OPENSSL_internal:GROUP_MISMATCH",
             );
-            let key_der = marshal_public_key_der(&privkey.public());
+            let key_der = privkey.public().marshal_to_der();
             should_fail(
-                parse_public_key_der::<EcPubKey<C2>>(&key_der),
+                EcPubKey::<C2>::parse_from_der(&key_der),
                 "parse_public_key_der",
                 "unexpected curve:",
             );
diff --git a/src/public/mod.rs b/src/public/mod.rs
index 2734b19..5233bb0 100644
--- a/src/public/mod.rs
+++ b/src/public/mod.rs
@@ -50,10 +50,108 @@
 }
 
 /// A public key which can be encoded as a DER object.
-pub trait DerPublicKey: PublicKey + self::inner::DerKey {}
+pub trait DerPublicKey: PublicKey + self::inner::DerKey {
+    /// Marshals a public key in DER format.
+    ///
+    /// `marshal_to_der` marshals a public key as a DER-encoded
+    /// SubjectPublicKeyInfo structure as defined in [RFC 5280].
+    ///
+    /// [RFC 5280]: https://tools.ietf.org/html/rfc5280
+    #[must_use]
+    fn marshal_to_der(&self) -> Vec<u8> {
+        let mut evp_pkey = CHeapWrapper::default();
+        self.boring().pkey_assign(&mut evp_pkey);
+        // cbb_new can only fail due to OOM
+        let mut cbb = CStackWrapper::cbb_new(64).unwrap();
+        evp_pkey
+            .evp_marshal_public_key(&mut cbb)
+            .expect("failed to marshal public key");
+        cbb.cbb_with_data(<[u8]>::to_vec)
+    }
+
+    /// Parses a public key in DER format.
+    ///
+    /// `parse_from_der` parses a public key from a DER-encoded
+    /// SubjectPublicKeyInfo structure as defined in [RFC 5280].
+    ///
+    /// # Elliptic Curve Keys
+    ///
+    /// For Elliptic Curve keys ([`EcPubKey`]), the curve itself is validated.
+    /// If the curve is not known ahead of time, and any curve must be supported
+    /// at runtime, use the [`EcPubKeyAnyCurve::parse_from_der`] function.
+    ///
+    /// [RFC 5280]: https://tools.ietf.org/html/rfc5280
+    /// [`EcPubKey`]: ::public::ec::EcPubKey
+    /// [`EcPubKeyAnyCurve::parse_from_der`]: ::public::ec::EcPubKeyAnyCurve::parse_from_der
+    #[must_use]
+    fn parse_from_der(bytes: &[u8]) -> Result<Self, Error> {
+        CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
+            let mut evp_pkey = CHeapWrapper::evp_parse_public_key(cbs)?;
+            // NOTE: For EC, panics if evp_pkey doesn't have its group set. This is
+            // OK because EVP_parse_public_key guarantees that the returned key has
+            // its group set.
+            let key = Self::Boring::pkey_get(&mut evp_pkey)?;
+            if cbs.cbs_len() > 0 {
+                return Err(Error::new("malformed DER input".to_string()));
+            }
+            Ok(Self::from_boring(key))
+        })
+    }
+}
 
 /// A private key which can be encoded as a DER object.
-pub trait DerPrivateKey: PrivateKey + self::inner::DerKey {}
+pub trait DerPrivateKey: PrivateKey + self::inner::DerKey {
+    /// Marshals a private key in DER format.
+    ///
+    /// `marshal_to_der` marshal a private key as a DER-encoded structure. The
+    /// exact structure encoded depends on the type of key:
+    /// - For an EC key, it is an ECPrivateKey structure as defined in [RFC
+    ///   5915].
+    /// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC
+    ///   3447].
+    ///
+    /// [RFC 5915]: https://tools.ietf.org/html/rfc5915
+    /// [RFC 3447]: https://tools.ietf.org/html/rfc3447
+    #[must_use]
+    fn marshal_to_der(&self) -> Vec<u8> {
+        // cbb_new can only fail due to OOM
+        let mut cbb = CStackWrapper::cbb_new(64).unwrap();
+        self.boring()
+            .marshal_private_key(&mut cbb)
+            .expect("failed to marshal private key");
+        cbb.cbb_with_data(<[u8]>::to_vec)
+    }
+
+    /// Parses a private key in DER format.
+    ///
+    /// `parse_from_der` parses a private key from a DER-encoded format. The
+    /// exact structure expected depends on the type of key:
+    /// - For an EC key, it is an ECPrivateKey structure as defined in [RFC
+    ///   5915].
+    /// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC
+    ///   3447].
+    ///
+    /// # Elliptic Curve Keys
+    ///
+    /// For Elliptic Curve keys ([`EcPrivKey`]), the curve itself is validated. If
+    /// the curve is not known ahead of time, and any curve must be supported at
+    /// runtime, use the [`EcPrivKeyAnyCurve::parse_from_der`] function.
+    ///
+    /// [RFC 5915]: https://tools.ietf.org/html/rfc5915
+    /// [RFC 3447]: https://tools.ietf.org/html/rfc3447
+    /// [`EcPrivKey`]: ::public::ec::EcPrivKey
+    /// [`EcPrivKeyAnyCurve::parse_from_der`]: ::public::ec::EcPrivKeyAnyCurve::parse_from_der
+    #[must_use]
+    fn parse_from_der(bytes: &[u8]) -> Result<Self, Error> {
+        CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
+            let key = Self::Boring::parse_private_key(cbs)?;
+            if cbs.cbs_len() > 0 {
+                return Err(Error::new("malformed DER input".to_string()));
+            }
+            Ok(Self::from_boring(key))
+        })
+    }
+}
 
 /// A cryptographic signature generated by a private key.
 pub trait Signature: Sealed + Sized {
@@ -110,100 +208,6 @@
     }
 }
 
-/// Marshals a public key in DER format.
-///
-/// `marshal_public_key_der` marshals a public key as a DER-encoded
-/// SubjectPublicKeyInfo structure as defined in [RFC 5280].
-///
-/// [RFC 5280]: https://tools.ietf.org/html/rfc5280
-#[must_use]
-pub fn marshal_public_key_der<P: DerPublicKey>(key: &P) -> Vec<u8> {
-    let mut evp_pkey = CHeapWrapper::default();
-    key.boring().pkey_assign(&mut evp_pkey);
-    // cbb_new can only fail due to OOM
-    let mut cbb = CStackWrapper::cbb_new(64).unwrap();
-    evp_pkey
-        .evp_marshal_public_key(&mut cbb)
-        .expect("failed to marshal public key");
-    cbb.cbb_with_data(<[u8]>::to_vec)
-}
-
-/// Marshals a private key in DER format.
-///
-/// `marshal_private_key_der` marshal a private key as a DER-encoded structure.
-/// The exact structure encoded depends on the type of key:
-/// - For an EC key, it is an ECPrivateKey structure as defined in [RFC 5915].
-/// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC 3447].
-///
-/// [RFC 5915]: https://tools.ietf.org/html/rfc5915
-/// [RFC 3447]: https://tools.ietf.org/html/rfc3447
-#[must_use]
-pub fn marshal_private_key_der<P: DerPrivateKey>(key: &P) -> Vec<u8> {
-    // cbb_new can only fail due to OOM
-    let mut cbb = CStackWrapper::cbb_new(64).unwrap();
-    key.boring()
-        .marshal_private_key(&mut cbb)
-        .expect("failed to marshal private key");
-    cbb.cbb_with_data(<[u8]>::to_vec)
-}
-
-/// Parses a public key in DER format.
-///
-/// `parse_public_key_der` parses a public key from a DER-encoded
-/// SubjectPublicKeyInfo structure as defined in [RFC 5280].
-///
-/// # Elliptic Curve Keys
-///
-/// For Elliptic Curve keys ([`EcPubKey`]), the curve itself is validated. If
-/// the curve is not known ahead of time, and any curve must be supported at
-/// runtime, use the [`parse_public_key_der_any_curve`] function.
-///
-/// [RFC 5280]: https://tools.ietf.org/html/rfc5280
-/// [`EcPubKey`]: ::public::ec::EcPubKey
-/// [`parse_public_key_der_any_curve`]: ::public::ec::parse_public_key_der_any_curve
-#[must_use]
-pub fn parse_public_key_der<P: DerPublicKey>(bytes: &[u8]) -> Result<P, Error> {
-    CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
-        let mut evp_pkey = CHeapWrapper::evp_parse_public_key(cbs)?;
-        // NOTE: For EC, panics if evp_pkey doesn't have its group set. This is
-        // OK because EVP_parse_public_key guarantees that the returned key has
-        // its group set.
-        let key = P::Boring::pkey_get(&mut evp_pkey)?;
-        if cbs.cbs_len() > 0 {
-            return Err(Error::new("malformed DER input".to_string()));
-        }
-        Ok(P::from_boring(key))
-    })
-}
-
-/// Parses a private key in DER format.
-///
-/// `parse_private_key_der` parses a private key from a DER-encoded format. The
-/// exact structure expected depends on the type of key:
-/// - For an EC key, it is an ECPrivateKey structure as defined in [RFC 5915].
-/// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC 3447].
-///
-/// # Elliptic Curve Keys
-///
-/// For Elliptic Curve keys ([`EcPrivKey`]), the curve itself is validated. If
-/// the curve is not known ahead of time, and any curve must be supported at
-/// runtime, use the [`parse_private_key_der_any_curve`] function.
-///
-/// [RFC 5915]: https://tools.ietf.org/html/rfc5915
-/// [RFC 3447]: https://tools.ietf.org/html/rfc3447
-/// [`EcPrivKey`]: ::public::ec::EcPrivKey
-/// [`parse_private_key_der_any_curve`]: ::public::ec::parse_private_key_der_any_curve
-#[must_use]
-pub fn parse_private_key_der<P: DerPrivateKey>(bytes: &[u8]) -> Result<P, Error> {
-    CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
-        let key = P::Boring::parse_private_key(cbs)?;
-        if cbs.cbs_len() > 0 {
-            return Err(Error::new("malformed DER input".to_string()));
-        }
-        Ok(P::from_boring(key))
-    })
-}
-
 #[cfg(test)]
 mod testutil {
     use super::*;