44//! Module for exposing a [`signature::Signer`] interface for keys
55//!
66//! This modules presents objects held in a TPM over a [`signature::DigestSigner`] interface.
7- use super :: TransientKeyContext ;
87use crate :: {
98 abstraction:: {
109 public:: AssociatedTpmCurve ,
11- transient:: { KeyMaterial , KeyParams } ,
10+ transient:: { KeyMaterial , KeyParams , TransientKeyContext } ,
1211 AssociatedHashingAlgorithm ,
1312 } ,
13+ handles:: KeyHandle ,
1414 interface_types:: algorithm:: EccSchemeAlgorithm ,
15- structures:: { Auth , Digest as TpmDigest , EccScheme , Signature as TpmSignature } ,
16- Error , WrapperErrorKind ,
15+ structures:: {
16+ Auth , Digest as TpmDigest , EccScheme , Public , Signature as TpmSignature , SignatureScheme ,
17+ } ,
18+ utils:: PublicKey as TpmPublicKey ,
19+ Context , Error , WrapperErrorKind ,
1720} ;
1821
1922use std:: { convert:: TryFrom , ops:: Add , sync:: Mutex } ;
@@ -31,21 +34,86 @@ use elliptic_curve::{
3134 subtle:: CtOption ,
3235 AffinePoint , CurveArithmetic , FieldBytesSize , PrimeCurve , PublicKey , Scalar ,
3336} ;
37+ use log:: error;
3438use signature:: { DigestSigner , Error as SigError , KeypairRef , Signer } ;
3539use x509_cert:: {
3640 der:: asn1:: AnyRef ,
3741 spki:: { AlgorithmIdentifier , AssociatedAlgorithmIdentifier , SignatureAlgorithmIdentifier } ,
3842} ;
3943
44+ pub trait TpmSigner {
45+ fn public ( & self ) -> crate :: Result < TpmPublicKey > ;
46+ fn key_params ( & self ) -> crate :: Result < KeyParams > ;
47+ fn sign ( & self , digest : TpmDigest ) -> crate :: Result < TpmSignature > ;
48+ }
49+
50+ impl TpmSigner for ( Mutex < & ' _ mut Context > , KeyHandle ) {
51+ fn public ( & self ) -> crate :: Result < TpmPublicKey > {
52+ let mut context = self . 0 . lock ( ) . expect ( "Mutex got poisoned" ) ;
53+ let ( public, _, _) = context. read_public ( self . 1 ) ?;
54+
55+ TpmPublicKey :: try_from ( public)
56+ }
57+
58+ fn key_params ( & self ) -> crate :: Result < KeyParams > {
59+ let mut context = self . 0 . lock ( ) . expect ( "Mutex got poisoned" ) ;
60+ let ( public, _, _) = context. read_public ( self . 1 ) ?;
61+
62+ match public {
63+ Public :: Rsa { parameters, .. } => Ok ( KeyParams :: Rsa {
64+ size : parameters. key_bits ( ) ,
65+ scheme : parameters. rsa_scheme ( ) ,
66+ pub_exponent : parameters. exponent ( ) ,
67+ } ) ,
68+ Public :: Ecc { parameters, .. } => Ok ( KeyParams :: Ecc {
69+ curve : parameters. ecc_curve ( ) ,
70+ scheme : parameters. ecc_scheme ( ) ,
71+ } ) ,
72+ other => {
73+ error ! ( "Unsupported key parameter used: {other:?}" ) ;
74+ Err ( Error :: local_error ( WrapperErrorKind :: InvalidParam ) )
75+ }
76+ }
77+ }
78+
79+ fn sign ( & self , digest : TpmDigest ) -> crate :: Result < TpmSignature > {
80+ let mut context = self . 0 . lock ( ) . expect ( "Mutex got poisoned" ) ;
81+ context. sign ( self . 1 , digest, SignatureScheme :: Null , None )
82+ }
83+ }
84+
85+ impl TpmSigner
86+ for (
87+ Mutex < & ' _ mut TransientKeyContext > ,
88+ KeyMaterial ,
89+ KeyParams ,
90+ Option < Auth > ,
91+ )
92+ {
93+ fn public ( & self ) -> crate :: Result < TpmPublicKey > {
94+ Ok ( self . 1 . public ( ) . clone ( ) )
95+ }
96+
97+ fn key_params ( & self ) -> crate :: Result < KeyParams > {
98+ Ok ( self . 2 )
99+ }
100+
101+ fn sign ( & self , digest : TpmDigest ) -> crate :: Result < TpmSignature > {
102+ let mut context = self . 0 . lock ( ) . expect ( "Mutex got poisoned" ) ;
103+ context. sign ( self . 1 . clone ( ) , self . 2 , self . 3 . clone ( ) , digest)
104+ }
105+ }
106+
40107/// [`EcSigner`] will sign a payload with an elliptic curve secret key stored on the TPM.
41108///
42109/// # Parameters
43110///
44111/// Parameter `C` describes the curve that is of use (Nist P-256, Nist P-384, ...)
45112///
46113/// ```no_run
114+ /// # use std::sync::Mutex;
47115/// # use tss_esapi::{
48- /// # abstraction::transient:: {EcSigner, TransientKeyContextBuilder},
116+ /// # abstraction::{EcSigner, transient:: TransientKeyContextBuilder},
49117/// # TctiNameConf
50118/// # };
51119/// use p256::NistP256;
@@ -59,52 +127,57 @@ use x509_cert::{
59127/// # .build()
60128/// # .expect("Failed to create Context");
61129///
130+ /// let key_params = EcSigner::<NistP256, ()>::key_params_default();
62131/// let (tpm_km, _tpm_auth) = context
63- /// .create_key(EcSigner::<NistP256>::key_params_default() , 0)
132+ /// .create_key(key_params , 0)
64133/// .expect("Failed to create a private keypair");
65134///
66- /// let signer = EcSigner::<NistP256>::new(&mut context, tpm_km, None)
135+ /// let signer = EcSigner::<NistP256,_ >::new((Mutex::new( &mut context) , tpm_km, key_params, None) )
67136/// .expect("Failed to create a signer");
68137/// let signature: p256::ecdsa::Signature = signer.sign(b"Hello Bob, Alice here.");
69138/// ```
70139#[ derive( Debug ) ]
71- pub struct EcSigner < ' ctx , C >
140+ pub struct EcSigner < C , Ctx >
72141where
73142 C : PrimeCurve + CurveArithmetic ,
74143{
75- context : Mutex < & ' ctx mut TransientKeyContext > ,
76- key_material : KeyMaterial ,
77- key_auth : Option < Auth > ,
144+ context : Ctx ,
78145 verifying_key : VerifyingKey < C > ,
79146}
80147
81- impl < ' ctx , C > EcSigner < ' ctx , C >
148+ impl < C , Ctx > EcSigner < C , Ctx >
82149where
83150 C : PrimeCurve + CurveArithmetic ,
84151 C : AssociatedTpmCurve ,
85152 FieldBytesSize < C > : ModulusSize ,
86153 AffinePoint < C > : FromEncodedPoint < C > + ToEncodedPoint < C > ,
154+
155+ Ctx : TpmSigner ,
87156{
88- pub fn new (
89- context : & ' ctx mut TransientKeyContext ,
90- key_material : KeyMaterial ,
91- key_auth : Option < Auth > ,
92- ) -> Result < Self , Error > {
93- let context = Mutex :: new ( context) ;
94-
95- let public_key = PublicKey :: try_from ( key_material. public ( ) ) ?;
157+ pub fn new ( context : Ctx ) -> Result < Self , Error > {
158+ match context. key_params ( ) ? {
159+ KeyParams :: Ecc { curve, .. } if curve == C :: TPM_CURVE => { }
160+ other => {
161+ error ! (
162+ "Unsupported key parameters: {other:?}, expected Ecc(curve: {:?})" ,
163+ C :: default ( )
164+ ) ;
165+ return Err ( Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ;
166+ }
167+ }
168+
169+ let public_key = context. public ( ) ?;
170+ let public_key = PublicKey :: try_from ( & public_key) ?;
96171 let verifying_key = VerifyingKey :: from ( public_key) ;
97172
98173 Ok ( Self {
99174 context,
100- key_material,
101- key_auth,
102175 verifying_key,
103176 } )
104177 }
105178}
106179
107- impl < C > EcSigner < ' _ , C >
180+ impl < C , Ctx > EcSigner < C , Ctx >
108181where
109182 C : PrimeCurve + CurveArithmetic ,
110183 C : AssociatedTpmCurve ,
@@ -137,7 +210,7 @@ where
137210 }
138211}
139212
140- impl < C > AsRef < VerifyingKey < C > > for EcSigner < ' _ , C >
213+ impl < C , Ctx > AsRef < VerifyingKey < C > > for EcSigner < C , Ctx >
141214where
142215 C : PrimeCurve + CurveArithmetic ,
143216 Scalar < C > : Invert < Output = CtOption < Scalar < C > > > + SignPrimitive < C > ,
@@ -148,7 +221,7 @@ where
148221 }
149222}
150223
151- impl < C > KeypairRef for EcSigner < ' _ , C >
224+ impl < C , Ctx > KeypairRef for EcSigner < C , Ctx >
152225where
153226 C : PrimeCurve + CurveArithmetic ,
154227 Scalar < C > : Invert < Output = CtOption < Scalar < C > > > + SignPrimitive < C > ,
@@ -157,7 +230,7 @@ where
157230 type VerifyingKey = VerifyingKey < C > ;
158231}
159232
160- impl < C , D > DigestSigner < D , Signature < C > > for EcSigner < ' _ , C >
233+ impl < C , Ctx , D > DigestSigner < D , Signature < C > > for EcSigner < C , Ctx >
161234where
162235 C : PrimeCurve + CurveArithmetic ,
163236 C : AssociatedTpmCurve ,
@@ -166,20 +239,13 @@ where
166239 Scalar < C > : Invert < Output = CtOption < Scalar < C > > > + SignPrimitive < C > ,
167240 SignatureSize < C > : ArrayLength < u8 > ,
168241 TpmDigest : From < Output < D > > ,
242+ Ctx : TpmSigner ,
169243{
170244 fn try_sign_digest ( & self , digest : D ) -> Result < Signature < C > , SigError > {
171245 let digest = TpmDigest :: from ( digest. finalize_fixed ( ) ) ;
172246
173- let key_params = Self :: key_params :: < D > ( ) ;
174- let mut context = self . context . lock ( ) . expect ( "Mutex got poisoned" ) ;
175- let signature = context
176- . sign (
177- self . key_material . clone ( ) ,
178- key_params,
179- self . key_auth . clone ( ) ,
180- digest,
181- )
182- . map_err ( SigError :: from_source) ?;
247+ //let key_params = Self::key_params::<D>();
248+ let signature = self . context . sign ( digest) . map_err ( SigError :: from_source) ?;
183249
184250 let TpmSignature :: EcDsa ( signature) = signature else {
185251 return Err ( SigError :: from_source ( Error :: local_error (
@@ -193,7 +259,7 @@ where
193259 }
194260}
195261
196- impl < C , D > DigestSigner < D , DerSignature < C > > for EcSigner < ' _ , C >
262+ impl < C , Ctx , D > DigestSigner < D , DerSignature < C > > for EcSigner < C , Ctx >
197263where
198264 C : PrimeCurve + CurveArithmetic ,
199265 C : AssociatedTpmCurve ,
@@ -205,28 +271,32 @@ where
205271
206272 MaxSize < C > : ArrayLength < u8 > ,
207273 <FieldBytesSize < C > as Add >:: Output : Add < MaxOverhead > + ArrayLength < u8 > ,
274+
275+ Ctx : TpmSigner ,
208276{
209277 fn try_sign_digest ( & self , digest : D ) -> Result < DerSignature < C > , SigError > {
210278 let signature: Signature < _ > = self . try_sign_digest ( digest) ?;
211279 Ok ( signature. to_der ( ) )
212280 }
213281}
214282
215- impl < C > Signer < Signature < C > > for EcSigner < ' _ , C >
283+ impl < C , Ctx > Signer < Signature < C > > for EcSigner < C , Ctx >
216284where
217285 C : PrimeCurve + CurveArithmetic + DigestPrimitive ,
218286 C : AssociatedTpmCurve ,
219287 <C as DigestPrimitive >:: Digest : AssociatedHashingAlgorithm ,
220288 Scalar < C > : Invert < Output = CtOption < Scalar < C > > > + SignPrimitive < C > ,
221289 SignatureSize < C > : ArrayLength < u8 > ,
222290 TpmDigest : From < Output < <C as DigestPrimitive >:: Digest > > ,
291+
292+ Ctx : TpmSigner ,
223293{
224294 fn try_sign ( & self , msg : & [ u8 ] ) -> Result < Signature < C > , SigError > {
225295 self . try_sign_digest ( C :: Digest :: new_with_prefix ( msg) )
226296 }
227297}
228298
229- impl < C > Signer < DerSignature < C > > for EcSigner < ' _ , C >
299+ impl < C , Ctx > Signer < DerSignature < C > > for EcSigner < C , Ctx >
230300where
231301 C : PrimeCurve + CurveArithmetic + DigestPrimitive ,
232302 C : AssociatedTpmCurve ,
@@ -237,13 +307,15 @@ where
237307
238308 MaxSize < C > : ArrayLength < u8 > ,
239309 <FieldBytesSize < C > as Add >:: Output : Add < MaxOverhead > + ArrayLength < u8 > ,
310+
311+ Ctx : TpmSigner ,
240312{
241313 fn try_sign ( & self , msg : & [ u8 ] ) -> Result < DerSignature < C > , SigError > {
242314 self . try_sign_digest ( C :: Digest :: new_with_prefix ( msg) )
243315 }
244316}
245317
246- impl < C > SignatureAlgorithmIdentifier for EcSigner < ' _ , C >
318+ impl < C , Ctx > SignatureAlgorithmIdentifier for EcSigner < C , Ctx >
247319where
248320 C : PrimeCurve + CurveArithmetic ,
249321 Scalar < C > : Invert < Output = CtOption < Scalar < C > > > + SignPrimitive < C > ,
0 commit comments