1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
//! 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<C> AssociatedAlgorithmIdentifier for SecretKey<C>
where
C: AssociatedOid + Curve,
{
type Params = ObjectIdentifier;
const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<ObjectIdentifier> = AlgorithmIdentifier {
oid: ALGORITHM_OID,
parameters: Some(C::OID),
};
}
impl<C> TryFrom<pkcs8::PrivateKeyInfo<'_>> for SecretKey<C>
where
C: AssociatedOid + Curve + ValidatePublicKey,
FieldBytesSize<C>: ModulusSize,
{
type Error = pkcs8::Error;
fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
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<C> EncodePrivateKey for SecretKey<C>
where
C: AssociatedOid + CurveArithmetic,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
FieldBytesSize<C>: ModulusSize,
{
fn to_pkcs8_der(&self) -> pkcs8::Result<der::SecretDocument> {
// 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<C> FromStr for SecretKey<C>
where
C: Curve + AssociatedOid + ValidatePublicKey,
FieldBytesSize<C>: ModulusSize,
{
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
Self::from_pkcs8_pem(s).map_err(|_| Error)
}
}
|