MakePartialCert(X509KeyUsage keyUsage, AlgorithmIdentifier algID = null, string issuer = null, string subject = null, DateTime?notBefore = null, DateTime?notAfter = null) { X509ExtensionsGenerator g = new X509ExtensionsGenerator(); g.AddExtension(X509Extensions.KeyUsage, true, keyUsage); return(new PartialCertificate() { Issuer = new X509Name(issuer ?? "CN=TPM Test Issuer,O=TPM Test Suite"), NotBefore = notBefore ?? new DateTime(2000, 1, 1), NotAfter = notAfter ?? new DateTime(2999, 12, 31), Subject = new X509Name(subject ?? "CN=TPM X509 CA,O=MSFT"), SigAlgID = algID, Extensions = g.Generate() }); }
/// <summary> /// Makes a minimal partial certificate for a signing key /// </summary> /// <returns></returns> internal static PartialCertificate MakeExemplarPartialCert() { X509ExtensionsGenerator g = new X509ExtensionsGenerator(); g.AddExtension(X509Extensions.KeyUsage, true, new X509KeyUsage(X509KeyUsage.KeyCertSign)); var tt = new X509KeyUsage(X509KeyUsage.KeyCertSign); var yy = tt.GetDerEncoded(); return(new PartialCertificate() { Issuer = new X509Name("CN=TPM Test Issuer,O=TPM Test Suite"), NotBefore = new DateTime(2000, 1, 1), NotAfter = new DateTime(2999, 12, 31), Subject = new X509Name("CN=TPM X509 CA,O=MSFT"), // IssuerUniqueId = new byte[32], // SubjectUniqueId = new byte[32], Extensions = g.Generate() }); }
internal PkiCertificate Create(X509Name issuerName, PkiKey issuerPrivateKey, X509Name subjectName, DateTimeOffset notBefore, DateTimeOffset notAfter, byte[] serialNumber, X509KeyUsage keyUsage = null, KeyPurposeID[] extKeyUsage = null) { // Based on: // https://stackoverflow.com/a/39456955/5428506 // https://github.com/bcgit/bc-csharp/blob/master/crypto/test/src/test/CertTest.cs var pubKey = _keyPair?.PublicKey.NativeKey ?? PublicKey.NativeKey; var sigFactory = ComputeSignatureAlgorithm(issuerPrivateKey.NativeKey); var certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(new BigInteger(serialNumber)); certGen.SetIssuerDN(issuerName); certGen.SetSubjectDN(subjectName); certGen.SetNotBefore(notBefore.UtcDateTime); certGen.SetNotAfter(notAfter.UtcDateTime); certGen.SetPublicKey(pubKey); if (keyUsage == null) { keyUsage = new X509KeyUsage(X509KeyUsage.KeyEncipherment | X509KeyUsage.DigitalSignature); } if (extKeyUsage == null) { extKeyUsage = new[] { KeyPurposeID.IdKPClientAuth, KeyPurposeID.IdKPServerAuth } } ; certGen.AddExtension("2.5.29.15", true, keyUsage); certGen.AddExtension("2.5.29.37", true, new DerSequence(extKeyUsage)); // Based on: // https://boredwookie.net/blog/bouncy-castle-add-a-subject-alternative-name-when-creating-a-cer foreach (var ext in CertificateExtensions) { // certGen.AddExtension(ext.Identifier, ext.Value.IsCritical, ext.Value.Value); certGen.AddExtension(ext.Identifier, ext.IsCritical, ext.Value); } var bcCert = certGen.Generate(sigFactory); return(new PkiCertificate { NativeCertificate = bcCert, }); // Compare to LE-issued Certs: // Enhanced Key Usage: // Server Authentication (1.3.6.1.5.5.7.3.1) // Client Authentication (1.3.6.1.5.5.7.3.2) // Subject Key Identifier: // e05bf2ba81d8d3845ff45b5638551e64ca19133d // Authority Key Identifier: // KeyID=a84a6a63047dddbae6d139b7a64565eff3a8eca1 // Authority Information Access: // [1]Authority Info Access // Access Method=On-line Certificate Status Protocol (1.3.6.1.5.5.7.48.1) // Alternative Name: // URL=http://ocsp.int-x3.letsencrypt.org // [2]Authority Info Access // Access Method=Certification Authority Issuer (1.3.6.1.5.5.7.48.2) // Alternative Name: // URL=http://cert.int-x3.letsencrypt.org/ // Certificate Policies: // ... // SCT List: // ... // Key Usage: // Digital Signature, Key Encipherment (a0) // Basic Constraints: // Subject Type=End Entity // Path Length Constraint=None // CA: // Key Usage: // Digital Signature, Certificate Signing, Off-line CRL Signing, CRL Signing (86) }