@@ -43,7 +43,7 @@ use tss_esapi::{
4343 structure_tags:: AttestationType ,
4444 } ,
4545 structures:: {
46- Attest , AttestInfo , Data , Digest , DigestValues , EccParameter ,
46+ Attest , AttestInfo , Auth , Data , Digest , DigestValues , EccParameter ,
4747 EccPoint , EccScheme , EncryptedSecret , HashScheme , IdObject ,
4848 KeyDerivationFunctionScheme , Name , PcrSelectionList ,
4949 PcrSelectionListBuilder , PcrSlot , PublicBuilder ,
@@ -140,6 +140,13 @@ pub enum TpmError {
140140 source : tss_esapi:: Error ,
141141 } ,
142142
143+ /// Error setting auth for persistent TPM handle
144+ #[ error( "Error setting auth for persistent TPM handle {handle}" ) ]
145+ TSSHandleSetAuthError {
146+ handle : String ,
147+ source : tss_esapi:: Error ,
148+ } ,
149+
143150 /// Error returned in case of error creating new Primary Key
144151 #[ error( "Error creating primary key" ) ]
145152 TSSCreatePrimaryError { source : tss_esapi:: Error } ,
@@ -339,6 +346,10 @@ pub enum TpmError {
339346 #[ error( "base64 decode error" ) ]
340347 Base64Decode ( #[ from] base64:: DecodeError ) ,
341348
349+ /// Hex decoding error
350+ #[ error( "hex decode error" ) ]
351+ HexDecodeError ( String ) ,
352+
342353 /// Malformed PCR selection mask
343354 #[ error( "Malformed PCR selection mask: {0}" ) ]
344355 MalformedPCRSelectionMask ( String ) ,
@@ -613,6 +624,99 @@ impl Context {
613624 Ok ( ak_handle)
614625 }
615626
627+ /// Load a key handle from a string of the handle location
628+ /// If a password is supplied, authorise the handle
629+ /// # Arguments
630+ ///
631+ /// `handle` : The string of the handle, eg. from config
632+ /// `password` ; The string password, to be converted to hex if there is the "hex:" prefix
633+ ///
634+ /// # Return
635+ /// The corresponding KeyHandle, or a TPMError
636+ fn get_key_handle (
637+ & mut self ,
638+ handle : & str ,
639+ password : & str ,
640+ ) -> Result < KeyHandle > {
641+ let handle = u32:: from_str_radix ( handle. trim_start_matches ( "0x" ) , 16 )
642+ . map_err ( |source| TpmError :: NumParse {
643+ origin : handle. to_string ( ) ,
644+ source,
645+ } ) ?;
646+ let key_handle: KeyHandle = self
647+ . inner
648+ . tr_from_tpm_public ( TpmHandle :: Persistent (
649+ PersistentTpmHandle :: new ( handle) . map_err ( |source| {
650+ TpmError :: TSSNewPersistentHandleError {
651+ handle : handle. to_string ( ) ,
652+ source,
653+ }
654+ } ) ?,
655+ ) )
656+ . map_err ( |source| TpmError :: TSSHandleFromPersistentHandleError {
657+ handle : handle. to_string ( ) ,
658+ source,
659+ } ) ?
660+ . into ( ) ;
661+ if !password. is_empty ( ) {
662+ let auth = if password. starts_with ( "hex:" ) {
663+ let ( _, hex_password) = password. split_at ( 4 ) ;
664+ let decoded_password =
665+ hex:: decode ( hex_password) . map_err ( |_| {
666+ TpmError :: HexDecodeError (
667+ "Hex decode error for identity auth value."
668+ . to_string ( ) ,
669+ )
670+ } ) ?;
671+ Auth :: try_from ( decoded_password) ?
672+ } else {
673+ Auth :: try_from ( password. as_bytes ( ) ) ?
674+ } ;
675+ self . as_mut ( ) . tr_set_auth ( key_handle. into ( ) , auth) . map_err (
676+ |source| TpmError :: TSSHandleSetAuthError {
677+ handle : handle. to_string ( ) ,
678+ source,
679+ } ,
680+ ) ?;
681+ } ;
682+
683+ Ok ( key_handle)
684+ }
685+
686+ /// Create an IDevID object from one persisted in TPM using its handle
687+ pub fn idevid_from_handle (
688+ & mut self ,
689+ handle : & str ,
690+ password : & str ,
691+ ) -> Result < IDevIDResult > {
692+ let idevid_handle = self . get_key_handle ( handle, password) ?;
693+ let ( idevid_pub, _, _) = self
694+ . inner
695+ . read_public ( idevid_handle)
696+ . map_err ( |source| TpmError :: TSSReadPublicError { source } ) ?;
697+ Ok ( IDevIDResult {
698+ public : idevid_pub,
699+ handle : idevid_handle,
700+ } )
701+ }
702+
703+ /// Create an IAK object from one persisted in TPM using its handle
704+ pub fn iak_from_handle (
705+ & mut self ,
706+ handle : & str ,
707+ password : & str ,
708+ ) -> Result < IAKResult > {
709+ let iak_handle = self . get_key_handle ( handle, password) ?;
710+ let ( iak_pub, _, _) = self
711+ . inner
712+ . read_public ( iak_handle)
713+ . map_err ( |source| TpmError :: TSSReadPublicError { source } ) ?;
714+ Ok ( IAKResult {
715+ public : iak_pub,
716+ handle : iak_handle,
717+ } )
718+ }
719+
616720 /// Creates an IDevID
617721 pub fn create_idevid (
618722 & mut self ,
0 commit comments