Beispiel #1
0
        /// <summary>
        /// Validate the tester by emulating the actions of the TPM
        /// </summary>
        internal static void TestTester()
        {
            var random = new SecureRandom();

            // Algorithms to test
            var algInfo = new[] {
                new { genner = (IAsymmetricCipherKeyPairGenerator) new ECKeyPairGenerator(), strength = 256, signingAlgorithm = "SHA256WITHECDSA" },
                new { genner = (IAsymmetricCipherKeyPairGenerator) new RsaKeyPairGenerator(), strength = 2048, signingAlgorithm = "SHA256WITHRSAENCRYPTION" }
            };

            foreach (var keyType in algInfo)
            {
                // Make a two keys of the specified algorithm
                var keyGenerationParameters = new KeyGenerationParameters(random, keyType.strength);
                keyType.genner.Init(keyGenerationParameters);

                var signingKey           = keyType.genner.GenerateKeyPair();
                var toBeCertifiedKeyPair = keyType.genner.GenerateKeyPair();

                // Make the partial certificate that is input to the TPM
                PartialCertificate partialCert = MakeExemplarPartialCert();

                // Simulate the actions of the TPM.  This returns both the full and partial (AddedTo) certificate
                // The full certitificate is just for debugging
                var certTuple /*(CompleteCertificate, AddedTo)*/ =
                    SimulateX509Certify(partialCert, toBeCertifiedKeyPair.Public, signingKey.Private, keyType.signingAlgorithm);
                X509Certificate    CompleteCertificate = certTuple.Item1;
                AddedToCertificate AddedTo             = certTuple.Item2;

                // Is the full certificate OK (it certainly should be)
                CompleteCertificate.Verify(signingKey.Public);
                // Debugging help...
                DebugPrintHex(CompleteCertificate.GetEncoded(), "ActualCert");

                // When using TPM2_CertifyX509() the TPM does not return the whole certificate: it returns the
                // parts of the certificate that were not originally provided in partialCertificate in a data
                // structure called AddedTo, as well as the signature.  The caller/TSS has to recosntruct
                // the full certificate.

                var signature    = CompleteCertificate.GetSignature();
                var finishedCert = AssembleCertificate(partialCert, AddedTo, signature);
                DebugPrintHex(finishedCert.GetEncoded(), "AssembledCert");

                // sanity check that we can parse a DER encoded AddedTo (this is what the TPM will return.)
                var addedToBytes         = AddedTo.GetDerEncoded();
                var reconstructedAddedTo = AddedToCertificate.FromDerEncoding(addedToBytes);
                AssertByteArraysTheSame(addedToBytes, reconstructedAddedTo.ToAsn1Object().GetDerEncoded());

                // Sanity
                AssertByteArraysTheSame(CompleteCertificate.GetEncoded(), finishedCert.GetEncoded());

                // and more sanity
                finishedCert.Verify(signingKey.Public);
            }
            return;
        }
Beispiel #2
0
        /// <summary>
        /// To be called after the TPM has returned the addedTo part of the certificate and the signature.  Assembles
        /// partialCert, addedTo, and the signature to form  an actual X.509 certificate encapsulated in a Bouncy Castle
        /// X509Certificate
        /// </summary>
        /// <param name="partialCert"></param>
        /// <param name="addedToCertificate"></param>
        /// <param name="signature"></param>
        /// <returns></returns>
        internal static X509Certificate AssembleCertificate(
            PartialCertificate partialCert, AddedToCertificate addedToCertificate,
            byte[] signatureBytes)
        {
            Debug.Assert(addedToCertificate.Version.ToString() == "2");
            var signature = new DerBitString(signatureBytes);
            var sigAlgID  = partialCert.SigAlgID ?? addedToCertificate.SigAlgID;

            // Assemble TBS.  Start with a vector which we will later convert to a sequence
            Asn1EncodableVector tbsContents = new Asn1EncodableVector();

            tbsContents.Add(new DerTaggedObject(0, new DerInteger(BigInteger.ValueOf(2))));
            tbsContents.Add(addedToCertificate.SerialNumber);
            tbsContents.Add(sigAlgID);
            tbsContents.Add(partialCert.Issuer);
            tbsContents.Add(new CertificateValidity(partialCert.NotBefore, partialCert.NotAfter));
            tbsContents.Add(partialCert.Subject);
            tbsContents.Add(addedToCertificate.SubjectPublicKeyInfo);
            // Add optional components
            if (partialCert.IssuerUniqueId != null)
            {
                tbsContents.Add(new DerTaggedObject(false, 1, new DerBitString(partialCert.IssuerUniqueId)));
            }
            if (partialCert.SubjectUniqueId != null)
            {
                tbsContents.Add(new DerTaggedObject(false, 2, new DerBitString(partialCert.SubjectUniqueId)));
            }
            if (partialCert.Extensions != null)
            {
                tbsContents.Add(new DerTaggedObject(3, partialCert.Extensions.ToAsn1Object()));
            }

            // Convert the vector to an ASN SEQUENCE
            var tbsCertificate = new DerSequence(tbsContents);

            // assemble the certificate.  Start with the components as a vector
            Asn1EncodableVector certContents = new Asn1EncodableVector();

            certContents.Add(tbsCertificate);
            certContents.Add(sigAlgID);
            certContents.Add(signature);

            // Convert to a SEQUENCE.  certSequence will contain the DER encoded certificate
            var certSequence = new DerSequence(certContents);

            // Convert to a first-class BC X509Certificate
            var certBytes = certSequence.GetEncoded();
            var cert      = new X509CertificateParser().ReadCertificate(certSequence.GetEncoded());

            // and return it
            return(cert);
        }
Beispiel #3
0
        SimulateX509Certify(PartialCertificate partialCert, AsymmetricKeyParameter publicKeyToCertify,
                            AsymmetricKeyParameter signingKey, string signingAlgorithm)
        {
            // We can simulate ECDSA/SHA256 and RSA/SHA256

            ISignatureFactory   signatureFactory;
            DerObjectIdentifier sigAlgOid;

            if (signingKey is ECPrivateKeyParameters)
            {
                sigAlgOid = X9ObjectIdentifiers.ECDsaWithSha256;
            }
            else
            {
                sigAlgOid = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
            }


            //signatureFactory = new Asn1SignatureFactory(sigAlgOid.ToString(), signingKey);
            signatureFactory = new Asn1SignatureFactory(sigAlgOid.ToString(), signingKey);

            // Make the certificate
            var certGenerator = new X509V3CertificateGenerator();

            certGenerator.SetIssuerDN(partialCert.Issuer);
            certGenerator.SetSubjectDN(partialCert.Subject);
            certGenerator.SetSerialNumber(BigInteger.ValueOf(1));
            certGenerator.SetNotBefore(partialCert.NotBefore);
            certGenerator.SetNotAfter(partialCert.NotAfter);
            certGenerator.SetPublicKey(publicKeyToCertify);
            if (partialCert.SubjectUniqueId != null)
            {
                certGenerator.SetSubjectUniqueID(ByteArrayToBoolArray(partialCert.SubjectUniqueId));
            }
            if (partialCert.IssuerUniqueId != null)
            {
                certGenerator.SetIssuerUniqueID(ByteArrayToBoolArray(partialCert.IssuerUniqueId));
            }

            // process the extensions.  Note that this will not preserve the order
            var extensions = partialCert.Extensions;

            if (extensions != null)
            {
                foreach (var critExtOid in extensions.GetCriticalExtensionOids())
                {
                    certGenerator.AddExtension(critExtOid.ToString(), true, extensions.GetExtension(critExtOid).GetParsedValue());
                }
                foreach (var nonCritExtOid in extensions.GetNonCriticalExtensionOids())
                {
                    certGenerator.AddExtension(nonCritExtOid.ToString(), false, extensions.GetExtension(nonCritExtOid).GetParsedValue());
                }
            }

            // and sign to make the cert
            var cert = certGenerator.Generate(signatureFactory);

            // take things apart again for addedToCert
            var subjectPubKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKeyToCertify);

            // get the exact bytes for the signature algorithm
            var tbsSequence = ((DerSequence)DerSequence.FromByteArray(cert.GetTbsCertificate()));
            var sigAlgBytes = tbsSequence[2];

            AddedToCertificate addedTo = new AddedToCertificate()
            {
                Version              = new DerInteger(BigInteger.ValueOf(cert.Version)),
                SerialNumber         = new DerInteger(cert.SerialNumber),
                Signature            = AlgorithmIdentifier.GetInstance(sigAlgBytes),
                SubjectPublicKeyInfo = subjectPubKeyInfo
            };

            return(System.ValueTuple.Create(cert, addedTo));
        }