void TestCertifyX509_1(Tpm2 tpm, TestContext testCtx) { testCtx.ReportParams("Test phase: TestCertifyX509_1"); var policy = new PolicyTree(TpmAlgId.Sha256); policy.SetPolicyRoot(new TpmPolicyCommand(TpmCc.CertifyX509)); var keyTemplate = new TpmPublic( TpmAlgId.Sha256, ObjectAttr.Restricted | ObjectAttr.Sign | ObjectAttr.FixedParent | ObjectAttr.FixedTPM | ObjectAttr.UserWithAuth | ObjectAttr.AdminWithPolicy | ObjectAttr.SensitiveDataOrigin, policy.GetPolicyDigest(), new RsaParms(new SymDefObject(), new SchemeRsassa(TpmAlgId.Sha256), 2048, 0), new Tpm2bPublicKeyRsa() ); // Make two keys TpmPublic certifyingKeyPub, keyToBeCertifiedPub; TpmHandle hCertifyingKey = Substrate.CreatePrimary(tpm, keyTemplate, out certifyingKeyPub); TpmHandle hKeyToBeCertified = Substrate.CreatePrimary(tpm, keyTemplate, out keyToBeCertifiedPub); var partialCert = CertifyX509Support.MakeExemplarPartialCert(); var partialCertBytes = partialCert.GetDerEncoded(); // If you want to paste in your own hex put it here and s //var partialCertBytes = Globs.ByteArrayFromHex("01020304"); AuthSession sess = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256); sess.RunPolicy(tpm, policy); // I used this to test that the auth is OK. Of course you need to change the PolicyCommandCode above //var attestInfo = tpm[sess].Certify(hKeyToBeCertified, hCertifyingKey, new byte[0], new NullSigScheme(), out var legacySignature); byte[] tbsHash; ISignatureUnion signature; byte[] addedTo = tpm[sess].CertifyX509(hKeyToBeCertified, hCertifyingKey, new byte[0], new NullSigScheme(), partialCertBytes, out tbsHash, out signature); var addedToCert = AddedToCertificate.FromDerEncoding(addedTo); var returnedCert = CertifyX509Support.AssembleCertificate(partialCert, addedToCert, ((SignatureRsa)signature).GetTpmRepresentation()); // Does the expected hash match the returned hash? var tbsBytes = returnedCert.GetTbsCertificate(); var expectedTbsHash = TpmHash.FromData(TpmAlgId.Sha256, tbsBytes); Debug.Assert(Globs.ArraysAreEqual(expectedTbsHash.HashData, tbsHash)); // If you get this far we can check the cert is properly signed but we'll need to do a // bit of TPM<->Bouncy Castle data type conversion. tpm.FlushContext(hCertifyingKey); tpm.FlushContext(hKeyToBeCertified); } // TestCertifyX509_1
void TestCertifyX509Impl(Tpm2 tpm, TestContext testCtx, TpmPublic subjectTemplate, TpmPublic sigKeyTemplate, PolicyTree policy, string testLabel) { var partialCert = X509Helpers.MakePartialCert(subjectTemplate); var partialCertBytes = partialCert.GetDerEncoded(); // If you want to paste in your own hex put it here and s //var partialCertBytes = Globs.ByteArrayFromHex("01020304"); // Certify RSA with RSA TpmPublic certifyingKeyPub, keyToBeCertifiedPub; TpmHandle hSigKey = Substrate.CreatePrimary(tpm, sigKeyTemplate, out certifyingKeyPub); TpmHandle hSubjectKey = Substrate.CreatePrimary(tpm, subjectTemplate, out keyToBeCertifiedPub); AuthSession sess = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256); sess.RunPolicy(tpm, policy); ISignatureUnion sig; byte[] tbsHash; byte[] addedTo = tpm[sess].CertifyX509(hSubjectKey, hSigKey, null, new NullSigScheme(), partialCertBytes, out tbsHash, out sig); tpm.FlushContext(sess); tpm.FlushContext(hSubjectKey); var addedToCert = AddedToCertificate.FromDerEncoding(addedTo); X509Certificate returnedCert = X509Helpers.AssembleCertificate(partialCert, addedToCert, sig is SignatureRsa ? ((SignatureRsa)sig).GetTpmRepresentation() : ((SignatureEcc)sig).GetTpmRepresentation()); // Does the expected hash match the returned hash? var tbsBytes = returnedCert.GetTbsCertificate(); var expectedTbsHash = TpmHash.FromData(TpmAlgId.Sha256, tbsBytes); Debug.Assert(Globs.ArraysAreEqual(expectedTbsHash.HashData, tbsHash)); // Is the cert properly signed? if (TpmHelper.GetScheme(sigKeyTemplate).GetUnionSelector() != TpmAlgId.Rsapss) { // Software crypto layer does not support PSS bool sigOk = certifyingKeyPub.VerifySignatureOverHash(tbsHash, sig); if (sigKeyTemplate.type == TpmAlgId.Ecc) { #if !__NETCOREAPP2__ // No ECC in .Net Core testCtx.Assert("Sign" + testLabel, sigOk); #endif } else { testCtx.Assert("Sign" + testLabel, sigOk); } } tpm.VerifySignature(hSigKey, tbsHash, sig); tpm.FlushContext(hSigKey); }