elliptic_curve/secret_key/
pkcs8.rs1use super::SecretKey;
4use crate::{
5 ALGORITHM_OID, Curve, FieldBytesSize,
6 pkcs8::{AssociatedOid, der::Decode},
7 sec1::{ModulusSize, ValidatePublicKey},
8};
9use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier};
10use sec1::EcPrivateKey;
11
12#[cfg(all(feature = "alloc", feature = "arithmetic"))]
14use {
15 crate::{
16 AffinePoint, CurveArithmetic,
17 sec1::{FromSec1Point, ToSec1Point},
18 },
19 pkcs8::{
20 EncodePrivateKey,
21 der::{self, Encode, asn1::OctetStringRef},
22 },
23 zeroize::Zeroizing,
24};
25
26#[cfg(feature = "pem")]
28use {
29 crate::{Result, error::Error},
30 core::str::FromStr,
31 pkcs8::DecodePrivateKey,
32};
33
34impl<C> AssociatedAlgorithmIdentifier for SecretKey<C>
35where
36 C: AssociatedOid + Curve,
37{
38 type Params = ObjectIdentifier;
39
40 const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<ObjectIdentifier> = AlgorithmIdentifier {
41 oid: ALGORITHM_OID,
42 parameters: Some(C::OID),
43 };
44}
45
46impl<C> TryFrom<pkcs8::PrivateKeyInfoRef<'_>> for SecretKey<C>
47where
48 C: AssociatedOid + Curve + ValidatePublicKey,
49 FieldBytesSize<C>: ModulusSize,
50{
51 type Error = pkcs8::Error;
52
53 fn try_from(private_key_info: pkcs8::PrivateKeyInfoRef<'_>) -> pkcs8::Result<Self> {
54 private_key_info
55 .algorithm
56 .assert_oids(ALGORITHM_OID, C::OID)?;
57
58 Ok(EcPrivateKey::from_der(private_key_info.private_key.as_bytes())?.try_into()?)
59 }
60}
61
62#[cfg(all(feature = "alloc", feature = "arithmetic"))]
63impl<C> EncodePrivateKey for SecretKey<C>
64where
65 C: AssociatedOid + CurveArithmetic,
66 AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
67 FieldBytesSize<C>: ModulusSize,
68{
69 fn to_pkcs8_der(&self) -> pkcs8::Result<der::SecretDocument> {
70 let algorithm_identifier = pkcs8::AlgorithmIdentifierRef {
71 oid: ALGORITHM_OID,
72 parameters: Some((&C::OID).into()),
73 };
74
75 let private_key_bytes = Zeroizing::new(self.to_bytes());
76 let public_key_bytes = self.public_key().to_sec1_point(false);
77
78 let ec_private_key = Zeroizing::new(
79 EcPrivateKey {
80 private_key: &private_key_bytes,
81 parameters: None,
82 public_key: Some(public_key_bytes.as_bytes()),
83 }
84 .to_der()?,
85 );
86
87 let pkcs8_key = pkcs8::PrivateKeyInfoRef::new(
88 algorithm_identifier,
89 OctetStringRef::new(&ec_private_key)?,
90 );
91 Ok(der::SecretDocument::encode_msg(&pkcs8_key)?)
92 }
93}
94
95#[cfg(feature = "pem")]
96impl<C> FromStr for SecretKey<C>
97where
98 C: Curve + AssociatedOid + ValidatePublicKey,
99 FieldBytesSize<C>: ModulusSize,
100{
101 type Err = Error;
102
103 fn from_str(s: &str) -> Result<Self> {
104 Self::from_pkcs8_pem(s).map_err(|_| Error)
105 }
106}