public static TpmPrivate GetPlaintextPrivate(Tpm2 tpm, TpmHandle key, PolicyTree policy) { AuthSession sess = tpm.StartAuthSessionEx(TpmSe.Policy, policy.HashAlg); sess.RunPolicy(tpm, policy); TpmPrivate privPlain = null; byte[] symSeed; tpm[sess]._ExpectResponses(TpmRc.Success, TpmRc.Attributes) .Duplicate(key, TpmRh.Null, null, new SymDefObject(), out privPlain, out symSeed); Debug.Assert(!tpm._LastCommandSucceeded() || symSeed.Length == 0); tpm.FlushContext(sess); return(Globs.IsEmpty(privPlain.buffer) ? null : privPlain); }
/// <summary> /// The callback to sign the TpmPolicySignature challenge from the TPM. /// </summary> /// <param name="policyTree">The policy tree to check.</param> /// <param name="ace">The policy element (TpmPolicySignature) to evaluate.</param> /// <param name="nonceTpm">The nonce from the TPM.</param> /// <returns>Signature of the nonce.</returns> public static ISignatureUnion SignerCallback(PolicyTree policyTree, TpmPolicySigned ace, byte[] nonceTpm, out TpmPublic verificationKey) { // // This function checks the parameters of the associated TpmPolicySigned // ACE, and if they are those expected the TPM challenge is signed. // Note that policy expressions are often obtained from untrustworthy // sources, so it is important for key-holders to check what they // are bing asked to do before signing anything. // // // The policy just contains the name of the signature verification key, however the // TPM needs the actual public key to verify the signature. Check that the name // matches, and if it does return the public key. // byte[] expectedName = _publicSigningKey.GetPublicParms().GetName(); if (!expectedName.SequenceEqual(ace.AuthObjectName)) { throw new Exception("Unexpected name in policy."); } verificationKey = _publicSigningKey.GetPublicParms(); // // Check that the key is the one that we expect // if (ace.NodeId != "Signing Key 1") { throw new Exception("Unrecognized key"); } // // Check that nonceTom is not null (otherwise anything we sign can // be used for any session). // if (Globs.IsEmpty(nonceTpm)) { throw new Exception("Sign challenges with expiration time need nonce."); } // // Check PolicyRef and cpHash are what we want to sign // if (!Globs.IsEmpty(ace.CpHash)) { throw new Exception("I only sign null-cpHash"); } if (!ace.PolicyRef.SequenceEqual(new byte[] { 1, 2, 3, 4 })) { throw new Exception("Incorrect PolicyRef"); } // // And finally check that the expiration is set correctly. Check for // positive values (simple signing policy) and negative values (sining // policy with ticket). // if (ace.ExpirationTime != _expectedExpirationTime) { throw new Exception("Unexpected expiration time"); } // // Everything is OK, so get a formatted bloc containing the challenge // data and then sign it. // byte[] dataToSign = PolicyTree.PackDataToSign(ace.ExpirationTime, nonceTpm, ace.CpHash, ace.PolicyRef); return(_publicSigningKey.Sign(dataToSign)); }