//! PKCS#8 encoding/decoding support. use super::SecretKey; use crate::{ pkcs8::{self, der::Decode, AssociatedOid}, sec1::{ModulusSize, ValidatePublicKey}, Curve, FieldBytesSize, ALGORITHM_OID, }; use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier}; use sec1::EcPrivateKey; // Imports for the `EncodePrivateKey` impl #[cfg(all(feature = "alloc", feature = "arithmetic"))] use { crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, CurveArithmetic, }, pkcs8::{der, EncodePrivateKey}, }; // Imports for actual PEM support #[cfg(feature = "pem")] use { crate::{error::Error, Result}, core::str::FromStr, pkcs8::DecodePrivateKey, }; impl AssociatedAlgorithmIdentifier for SecretKey where C: AssociatedOid + Curve, { type Params = ObjectIdentifier; const ALGORITHM_IDENTIFIER: AlgorithmIdentifier = AlgorithmIdentifier { oid: ALGORITHM_OID, parameters: Some(C::OID), }; } impl TryFrom> for SecretKey where C: AssociatedOid + Curve + ValidatePublicKey, FieldBytesSize: ModulusSize, { type Error = pkcs8::Error; fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result { private_key_info .algorithm .assert_oids(ALGORITHM_OID, C::OID)?; let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key)?; Ok(Self::try_from(ec_private_key)?) } } #[cfg(all(feature = "alloc", feature = "arithmetic"))] impl EncodePrivateKey for SecretKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { fn to_pkcs8_der(&self) -> pkcs8::Result { // TODO(tarcieri): make `PrivateKeyInfo` generic around `Params` let algorithm_identifier = pkcs8::AlgorithmIdentifierRef { oid: ALGORITHM_OID, parameters: Some((&C::OID).into()), }; let ec_private_key = self.to_sec1_der()?; let pkcs8_key = pkcs8::PrivateKeyInfo::new(algorithm_identifier, &ec_private_key); Ok(der::SecretDocument::encode_msg(&pkcs8_key)?) } } #[cfg(feature = "pem")] impl FromStr for SecretKey where C: Curve + AssociatedOid + ValidatePublicKey, FieldBytesSize: ModulusSize, { type Err = Error; fn from_str(s: &str) -> Result { Self::from_pkcs8_pem(s).map_err(|_| Error) } }