x509_certificate/
rfc5915.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! ASN.1 primitives defined by RFC 5915.
6
7use {
8    crate::rfc5480::EcParameters,
9    bcder::{
10        decode::{Constructed, DecodeError, Source},
11        encode::{self, PrimitiveContent, Values},
12        BitString, ConstOid, Integer, OctetString, Oid, Tag,
13    },
14};
15
16/// Named curve parameters for elliptic curve private key.
17///
18/// 1.3.6.1.5.5.7.0.56
19pub const OID_NAMED_CURVE_PARAMETERS: ConstOid = Oid(&[43, 6, 1, 5, 5, 7, 0, 56]);
20
21/// Elliptic curve private key.
22///
23/// ```ASN.1
24/// ECPrivateKey ::= SEQUENCE {
25///   version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
26///   privateKey     OCTET STRING,
27///   parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
28///   publicKey  [1] BIT STRING OPTIONAL
29/// }
30/// ```
31#[derive(Clone, Debug, Eq, PartialEq)]
32pub struct EcPrivateKey {
33    pub version: Integer,
34    pub private_key: OctetString,
35    pub parameters: Option<EcParameters>,
36    pub public_key: Option<BitString>,
37}
38
39impl EcPrivateKey {
40    pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> {
41        cons.take_sequence(|cons| {
42            let version = Integer::take_from(cons)?;
43            let private_key = OctetString::take_from(cons)?;
44            let parameters =
45                cons.take_opt_constructed_if(Tag::CTX_0, |cons| EcParameters::take_from(cons))?;
46            let public_key =
47                cons.take_opt_constructed_if(Tag::CTX_1, |cons| BitString::take_from(cons))?;
48
49            Ok(Self {
50                version,
51                private_key,
52                parameters,
53                public_key,
54            })
55        })
56    }
57
58    pub fn encode_ref(&self) -> impl Values + '_ {
59        encode::sequence((
60            self.version.encode(),
61            self.private_key.encode_ref(),
62            self.parameters
63                .as_ref()
64                .map(|parameters| parameters.encode_ref_as(Tag::CTX_0)),
65            self.public_key
66                .as_ref()
67                .map(|public_key| public_key.encode_ref_as(Tag::CTX_1)),
68        ))
69    }
70}