elliptic_curve/secret_key/
pkcs8.rs

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