elliptic_curve/secret_key/
pkcs8.rs

1//! PKCS#8 encoding/decoding support.
2
3use super::SecretKey;
4use crate::{
5    pkcs8::{self, AssociatedOid, DecodePrivateKey},
6    sec1::{ModulusSize, ValidatePublicKey},
7    Curve, FieldSize, ALGORITHM_OID,
8};
9use der::Decode;
10use sec1::EcPrivateKey;
11
12// Imports for the `EncodePrivateKey` impl
13// TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `EncodePrivateKey` impl
14#[cfg(all(feature = "arithmetic", feature = "pem"))]
15use {
16    crate::{
17        sec1::{FromEncodedPoint, ToEncodedPoint},
18        AffinePoint, ProjectiveArithmetic,
19    },
20    pkcs8::EncodePrivateKey,
21};
22
23// Imports for actual PEM support
24#[cfg(feature = "pem")]
25use {
26    crate::{error::Error, Result},
27    core::str::FromStr,
28};
29
30#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
31impl<C> TryFrom<pkcs8::PrivateKeyInfo<'_>> for SecretKey<C>
32where
33    C: Curve + AssociatedOid + ValidatePublicKey,
34    FieldSize<C>: ModulusSize,
35{
36    type Error = pkcs8::Error;
37
38    fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
39        private_key_info
40            .algorithm
41            .assert_oids(ALGORITHM_OID, C::OID)?;
42
43        let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key)?;
44        Ok(Self::try_from(ec_private_key)?)
45    }
46}
47
48#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
49impl<C> DecodePrivateKey for SecretKey<C>
50where
51    C: Curve + AssociatedOid + ValidatePublicKey,
52    FieldSize<C>: ModulusSize,
53{
54}
55
56// TODO(tarcieri): use weak activation of `pkcs8/alloc` for this when possible
57// It doesn't strictly depend on `pkcs8/pem` but we can't easily activate `pkcs8/alloc`
58// without adding a separate crate feature just for this functionality.
59#[cfg(all(feature = "arithmetic", feature = "pem"))]
60#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
61#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
62impl<C> EncodePrivateKey for SecretKey<C>
63where
64    C: Curve + AssociatedOid + ProjectiveArithmetic,
65    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
66    FieldSize<C>: ModulusSize,
67{
68    fn to_pkcs8_der(&self) -> pkcs8::Result<der::SecretDocument> {
69        let algorithm_identifier = pkcs8::AlgorithmIdentifier {
70            oid: ALGORITHM_OID,
71            parameters: Some((&C::OID).into()),
72        };
73
74        let ec_private_key = self.to_sec1_der()?;
75        let pkcs8_key = pkcs8::PrivateKeyInfo::new(algorithm_identifier, &ec_private_key);
76        Ok(der::SecretDocument::encode_msg(&pkcs8_key)?)
77    }
78}
79
80#[cfg(feature = "pem")]
81#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
82impl<C> FromStr for SecretKey<C>
83where
84    C: Curve + AssociatedOid + ValidatePublicKey,
85    FieldSize<C>: ModulusSize,
86{
87    type Err = Error;
88
89    fn from_str(s: &str) -> Result<Self> {
90        Self::from_pkcs8_pem(s).map_err(|_| Error)
91    }
92}