diff --git a/src/ec/suite_b.rs b/src/ec/suite_b.rs index 9e363563b8..fb8f8364e7 100644 --- a/src/ec/suite_b.rs +++ b/src/ec/suite_b.rs @@ -160,8 +160,17 @@ pub(crate) fn key_pair_from_pkcs8( cpu_features: cpu::Features, ) -> Result { let (ec_private_key, _) = pkcs8::unwrap_key(template, pkcs8::Version::V1Only, input)?; + key_pair_from_der(curve, template, ec_private_key, cpu_features) +} + +pub(crate) fn key_pair_from_der( + curve: &'static ec::Curve, + template: &pkcs8::Template, + input: untrusted::Input, + cpu_features: cpu::Features, +) -> Result { let (private_key, public_key) = - ec_private_key.read_all(error::KeyRejected::invalid_encoding(), |input| { + input.read_all(error::KeyRejected::invalid_encoding(), |input| { // https://tools.ietf.org/html/rfc5915#section-3 der::nested( input, diff --git a/src/ec/suite_b/ecdsa/signing.rs b/src/ec/suite_b/ecdsa/signing.rs index 5422e06b16..8e0bc38079 100644 --- a/src/ec/suite_b/ecdsa/signing.rs +++ b/src/ec/suite_b/ecdsa/signing.rs @@ -116,6 +116,30 @@ impl EcdsaKeyPair { Self::new(alg, key_pair, &rng) } + /// Constructs an ECDSA key pair by parsing an unencrypted Sec1 v1 + /// id-ecPublicKey `ECPrivateKey` key. + /// + /// The input must be in Sec1 v1 format. It must contain the public key in + /// the `ECPrivateKey` structure; `from_der()` will verify that the public + /// key and the private key are consistent with each other. The algorithm + /// identifier must identify the curve by name; it must not use an + /// "explicit" encoding of the curve. The `parameters` field of the + /// `ECPrivateKey`, if present, must be the same named curve that is in the + /// algorithm identifier in the PKCS#8 header. + pub fn from_der( + alg: &'static EcdsaSigningAlgorithm, + der: &[u8], + ) -> Result { + let key_pair = ec::suite_b::key_pair_from_der( + alg.curve, + alg.pkcs8_template, + untrusted::Input::from(der), + cpu::features(), + )?; + let rng = rand::SystemRandom::new(); // TODO: make this a parameter. + Self::new(alg, key_pair, &rng) + } + /// Constructs an ECDSA key pair from the private key and public key bytes /// /// The private key must encoded as a big-endian fixed-length integer. For