Beispiel #1
0
        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);
        }
Beispiel #2
0
        /// <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));
        }