@@ -6,123 +6,176 @@ use crate::structures::{Public, RsaExponent};
6
6
use crate :: { Error , WrapperErrorKind } ;
7
7
8
8
use core:: convert:: TryFrom ;
9
- use oid:: ObjectIdentifier ;
10
- use picky_asn1:: bit_string:: BitString ;
11
- use picky_asn1:: wrapper:: { IntegerAsn1 , OctetStringAsn1 } ;
12
- use picky_asn1_x509:: {
13
- AlgorithmIdentifier , EcParameters , EcPoint , PublicKey , RsaPublicKey , SubjectPublicKeyInfo ,
9
+ use elliptic_curve:: {
10
+ // See TODO below, you're upgrading from 0.13 to 0.14 and
11
+ // that moved the implementation from generic-array to
12
+ // hybrid-array, you can now use TryFrom
13
+ generic_array:: typenum:: Unsigned ,
14
+ sec1:: { EncodedPoint , FromEncodedPoint , ModulusSize , ToEncodedPoint } ,
15
+ AffinePoint ,
16
+ CurveArithmetic ,
17
+ FieldBytesSize ,
18
+ PublicKey ,
14
19
} ;
20
+ use rsa:: { pkcs8:: EncodePublicKey , BigUint , RsaPublicKey } ;
21
+ use x509_cert:: spki:: SubjectPublicKeyInfoOwned ;
15
22
16
- /// Can be converted from [`crate::structures::Public`] when not a fully constructed
17
- /// [`picky_asn1_x509::SubjectPublicKeyInfo`] is required.
18
- ///
19
- /// # Details
20
- /// Holds either [`picky_asn1_x509::RsaPublicKey`] for [`crate::structures::Public::Rsa`] or
21
- /// [`picky_asn1_x509::EcPoint`] for [`crate::structures::Public::Ecc`].
22
- ///
23
- /// This object can be serialized and deserialized
24
- /// using serde if the `serde` feature is enabled.
25
- #[ derive( Debug , PartialEq , Eq , Clone ) ]
26
- #[ cfg_attr( feature = "serde" , derive( serde:: Deserialize , serde:: Serialize ) ) ]
27
- pub enum DecodedKey {
28
- RsaPublicKey ( RsaPublicKey ) ,
29
- EcPoint ( EcPoint ) ,
23
+ impl < C > TryFrom < & Public > for PublicKey < C >
24
+ where
25
+ C : CurveArithmetic + AssociatedTpmCurve ,
26
+ FieldBytesSize < C > : ModulusSize ,
27
+ AffinePoint < C > : FromEncodedPoint < C > + ToEncodedPoint < C > ,
28
+ {
29
+ type Error = Error ;
30
+
31
+ fn try_from ( value : & Public ) -> Result < Self , Self :: Error > {
32
+ match value {
33
+ Public :: Ecc {
34
+ parameters, unique, ..
35
+ } => {
36
+ if parameters. ecc_curve ( ) != C :: TPM_CURVE {
37
+ return Err ( Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ;
38
+ }
39
+
40
+ let x = unique. x ( ) . as_bytes ( ) ;
41
+ let y = unique. y ( ) . as_bytes ( ) ;
42
+
43
+ // TODO: When elliptic_curve bumps to 0.14, we can use the TryFrom implementation instead
44
+ // of checking lengths manually
45
+ if x. len ( ) != FieldBytesSize :: < C > :: USIZE {
46
+ return Err ( Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ;
47
+ }
48
+ if y. len ( ) != FieldBytesSize :: < C > :: USIZE {
49
+ return Err ( Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ;
50
+ }
51
+
52
+ let encoded_point =
53
+ EncodedPoint :: < C > :: from_affine_coordinates ( x. into ( ) , y. into ( ) , false ) ;
54
+ let public_key = PublicKey :: < C > :: try_from ( & encoded_point)
55
+ . map_err ( |_| Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ?;
56
+
57
+ Ok ( public_key)
58
+ }
59
+ _ => Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) ,
60
+ }
61
+ }
30
62
}
31
63
32
- impl TryFrom < Public > for DecodedKey {
64
+ impl TryFrom < & Public > for RsaPublicKey {
33
65
type Error = Error ;
34
66
35
- fn try_from ( value : Public ) -> Result < Self , Self :: Error > {
36
- public_to_decoded_key ( & value)
67
+ fn try_from ( value : & Public ) -> Result < Self , Self :: Error > {
68
+ match value {
69
+ Public :: Rsa {
70
+ unique, parameters, ..
71
+ } => {
72
+ let exponent = match parameters. exponent ( ) {
73
+ RsaExponent :: ZERO_EXPONENT => BigUint :: from ( 65537u32 ) ,
74
+ _ => BigUint :: from ( parameters. exponent ( ) . value ( ) ) ,
75
+ } ;
76
+ let modulus = BigUint :: from_bytes_be ( unique. as_bytes ( ) ) ;
77
+
78
+ let public_key = RsaPublicKey :: new ( modulus, exponent)
79
+ . map_err ( |_| Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ?;
80
+
81
+ Ok ( public_key)
82
+ }
83
+ _ => Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) ,
84
+ }
37
85
}
38
86
}
39
87
40
- impl TryFrom < Public > for SubjectPublicKeyInfo {
88
+ impl TryFrom < & Public > for SubjectPublicKeyInfoOwned {
41
89
type Error = Error ;
42
90
43
- /// Converts [`crate::structures::Public::Rsa`] and [`crate::structures::Public::Ecc`] to [`picky_asn1_x509::SubjectPublicKeyInfo `].
91
+ /// Converts [`crate::structures::Public::Rsa`] and [`crate::structures::Public::Ecc`] to [`x509_cert::spki::SubjectPublicKeyInfoOwned `].
44
92
///
45
93
/// # Details
46
- /// The result can be used to convert TPM public keys to DER using `picky_asn1_der `.
94
+ /// The result can be used to convert TPM public keys to DER using `x509-cert `.
47
95
///
48
96
/// # Errors
49
97
/// * if other instances of [`crate::structures::Public`] are used `UnsupportedParam` will be returned.
50
- fn try_from ( value : Public ) -> Result < Self , Self :: Error > {
51
- let decoded_key = public_to_decoded_key ( & value) ?;
52
-
53
- match ( value, decoded_key) {
54
- ( Public :: Rsa { .. } , DecodedKey :: RsaPublicKey ( key) ) => Ok ( SubjectPublicKeyInfo {
55
- algorithm : AlgorithmIdentifier :: new_rsa_encryption ( ) ,
56
- subject_public_key : PublicKey :: Rsa ( key. into ( ) ) ,
57
- } ) ,
58
- ( Public :: Ecc { parameters, .. } , DecodedKey :: EcPoint ( point) ) => {
59
- Ok ( SubjectPublicKeyInfo {
60
- algorithm : AlgorithmIdentifier :: new_elliptic_curve ( EcParameters :: NamedCurve (
61
- curve_oid ( parameters. ecc_curve ( ) ) ?. into ( ) ,
62
- ) ) ,
63
- subject_public_key : PublicKey :: Ec ( BitString :: with_bytes ( point) . into ( ) ) ,
64
- } )
98
+ fn try_from ( value : & Public ) -> Result < Self , Self :: Error > {
99
+ match value {
100
+ Public :: Rsa { .. } => {
101
+ let public_key = RsaPublicKey :: try_from ( value) ?;
102
+
103
+ Ok ( public_key
104
+ . to_public_key_der ( )
105
+ . map_err ( |_| Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ?
106
+ . decode_msg :: < Self > ( )
107
+ . map_err ( |_| Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ?)
108
+ }
109
+ #[ allow( unused) ]
110
+ Public :: Ecc { parameters, .. } => {
111
+ macro_rules! read_key {
112
+ ( $curve: expr, $key_type: ty) => {
113
+ if parameters. ecc_curve( ) == <$key_type>:: TPM_CURVE {
114
+ let public_key = PublicKey :: <$key_type>:: try_from( value) ?;
115
+
116
+ return Ok ( public_key
117
+ . to_public_key_der( )
118
+ . map_err( |_| Error :: local_error( WrapperErrorKind :: InvalidParam ) ) ?
119
+ . decode_msg:: <Self >( )
120
+ . map_err( |_| {
121
+ Error :: local_error( WrapperErrorKind :: InvalidParam )
122
+ } ) ?) ;
123
+ }
124
+ } ;
125
+ }
126
+
127
+ #[ cfg( feature = "p192" ) ]
128
+ read_key ! ( EccCurve :: NistP192 , p192:: NistP192 ) ;
129
+ #[ cfg( feature = "p224" ) ]
130
+ read_key ! ( EccCurve :: NistP224 , p224:: NistP224 ) ;
131
+ #[ cfg( feature = "p256" ) ]
132
+ read_key ! ( EccCurve :: NistP256 , p256:: NistP256 ) ;
133
+ #[ cfg( feature = "p384" ) ]
134
+ read_key ! ( EccCurve :: NistP384 , p384:: NistP384 ) ;
135
+ #[ cfg( feature = "p521" ) ]
136
+ read_key ! ( EccCurve :: NistP521 , p521:: NistP521 ) ;
137
+ #[ cfg( feature = "sm2" ) ]
138
+ read_key ! ( EccCurve :: Sm2P256 , sm2:: Sm2 ) ;
139
+
140
+ Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) )
65
141
}
66
142
_ => Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) ,
67
143
}
68
144
}
69
145
}
70
146
71
- /// Converts [`crate::structures::Public::Rsa`] and [`crate::structures::Public::Ecc`] to [DecodedKey].
72
- ///
73
- /// # Details
74
- /// Does basic key conversion to either RSA or ECC. In RSA conversion the TPM zero exponent is replaced with `65537`.
75
- ///
76
- /// # Errors
77
- /// * if other instances of [`crate::structures::Public`] are used `UnsupportedParam` will be returned.
78
- fn public_to_decoded_key ( public : & Public ) -> Result < DecodedKey , Error > {
79
- match public {
80
- Public :: Rsa {
81
- unique, parameters, ..
82
- } => {
83
- let exponent = match parameters. exponent ( ) {
84
- RsaExponent :: ZERO_EXPONENT => 65537 ,
85
- _ => parameters. exponent ( ) . value ( ) ,
86
- }
87
- . to_be_bytes ( ) ;
88
- Ok ( DecodedKey :: RsaPublicKey ( RsaPublicKey {
89
- modulus : IntegerAsn1 :: from_bytes_be_unsigned ( unique. as_bytes ( ) . to_vec ( ) ) ,
90
- public_exponent : IntegerAsn1 :: from_bytes_be_signed ( exponent. to_vec ( ) ) ,
91
- } ) )
92
- }
93
- Public :: Ecc { unique, .. } => {
94
- let x = unique. x ( ) . as_bytes ( ) . to_vec ( ) ;
95
- let y = unique. y ( ) . as_bytes ( ) . to_vec ( ) ;
96
- Ok ( DecodedKey :: EcPoint ( OctetStringAsn1 (
97
- elliptic_curve_point_to_octet_string ( x, y) ,
98
- ) ) )
99
- }
147
+ /// Provides the value of the curve used in this crate for the specific curve.
148
+ pub trait AssociatedTpmCurve {
149
+ /// Value of the curve when interacting with the TPM.
150
+ const TPM_CURVE : EccCurve ;
151
+ }
100
152
101
- _ => Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) ,
102
- }
153
+ #[ cfg( feature = "p192" ) ]
154
+ impl AssociatedTpmCurve for p192:: NistP192 {
155
+ const TPM_CURVE : EccCurve = EccCurve :: NistP192 ;
103
156
}
104
157
105
- // Taken from https://github.com/parallaxsecond/parsec/blob/561235f3cc37bcff3d9a6cb29c84eeae5d55100b/src/providers/tpm/utils.rs#L319
106
- // Points on elliptic curves are represented as defined in section 2.3.3 of https://www.secg.org/sec1-v2.pdf
107
- // The (uncompressed) representation is [ 0x04 || x || y ] where x and y are the coordinates of the point
108
- fn elliptic_curve_point_to_octet_string ( mut x : Vec < u8 > , mut y : Vec < u8 > ) -> Vec < u8 > {
109
- let mut octet_string = vec ! [ 0x04 ] ;
110
- octet_string. append ( & mut x) ;
111
- octet_string. append ( & mut y) ;
112
- octet_string
158
+ #[ cfg( feature = "p224" ) ]
159
+ impl AssociatedTpmCurve for p224:: NistP224 {
160
+ const TPM_CURVE : EccCurve = EccCurve :: NistP224 ;
113
161
}
114
162
115
- // Map TPM supported ECC curves to their respective OIDs
116
- fn curve_oid ( ecc_curve : EccCurve ) -> Result < ObjectIdentifier , Error > {
117
- match ecc_curve {
118
- EccCurve :: NistP192 => Ok ( picky_asn1_x509:: oids:: secp192r1 ( ) ) ,
119
- EccCurve :: NistP224 => Ok ( picky_asn1_x509:: oids:: secp256r1 ( ) ) ,
120
- EccCurve :: NistP256 => Ok ( picky_asn1_x509:: oids:: secp256r1 ( ) ) ,
121
- EccCurve :: NistP384 => Ok ( picky_asn1_x509:: oids:: secp384r1 ( ) ) ,
122
- EccCurve :: NistP521 => Ok ( picky_asn1_x509:: oids:: secp521r1 ( ) ) ,
123
- // Barreto-Naehrig curves seem to not have any OIDs
124
- EccCurve :: BnP256 => Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) ,
125
- EccCurve :: BnP638 => Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) ,
126
- EccCurve :: Sm2P256 => Ok ( ObjectIdentifier :: try_from ( "1.2.156.10197.1.301" ) . unwrap ( ) ) ,
127
- }
163
+ #[ cfg( feature = "p256" ) ]
164
+ impl AssociatedTpmCurve for p256:: NistP256 {
165
+ const TPM_CURVE : EccCurve = EccCurve :: NistP256 ;
166
+ }
167
+
168
+ #[ cfg( feature = "p384" ) ]
169
+ impl AssociatedTpmCurve for p384:: NistP384 {
170
+ const TPM_CURVE : EccCurve = EccCurve :: NistP384 ;
171
+ }
172
+
173
+ #[ cfg( feature = "p521" ) ]
174
+ impl AssociatedTpmCurve for p521:: NistP521 {
175
+ const TPM_CURVE : EccCurve = EccCurve :: NistP521 ;
176
+ }
177
+
178
+ #[ cfg( feature = "sm2" ) ]
179
+ impl AssociatedTpmCurve for sm2:: Sm2 {
180
+ const TPM_CURVE : EccCurve = EccCurve :: Sm2P256 ;
128
181
}
0 commit comments