private void TbsV3CertGenerate() { V3TbsCertificateGenerator gen = new V3TbsCertificateGenerator(); DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1); DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 2); gen.SetSerialNumber(new DerInteger(2)); gen.SetStartDate(new Time(startDate)); gen.SetEndDate(new Time(endDate)); gen.SetIssuer(new X509Name("CN=AU,O=Bouncy Castle")); gen.SetSubject(new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2")); gen.SetSignature(new AlgorithmIdentifier(PkcsObjectIdentifiers.MD5WithRsaEncryption, DerNull.Instance)); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( new AlgorithmIdentifier( OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(BigInteger.One, BigInteger.Two)), new DerInteger(3)); gen.SetSubjectPublicKeyInfo(info); // // add extensions // IList order = new ArrayList(); IDictionary extensions = new Hashtable(); order.Add(X509Extensions.AuthorityKeyIdentifier); order.Add(X509Extensions.SubjectKeyIdentifier); order.Add(X509Extensions.KeyUsage); extensions.Add(X509Extensions.AuthorityKeyIdentifier, new X509Extension(true, new DerOctetString(CreateAuthorityKeyId(info, new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2"), 2)))); extensions.Add(X509Extensions.SubjectKeyIdentifier, new X509Extension(true, new DerOctetString(new SubjectKeyIdentifier(info)))); extensions.Add(X509Extensions.KeyUsage, new X509Extension(false, new DerOctetString(new KeyUsage(KeyUsage.DataEncipherment)))); X509Extensions ex = new X509Extensions(order, extensions); gen.SetExtensions(ex); TbsCertificateStructure tbs = gen.GenerateTbsCertificate(); if (!Arrays.AreEqual(tbs.GetEncoded(), v3Cert)) { Fail("failed v3 cert generation"); } // // read back test // Asn1Object o = Asn1Object.FromByteArray(v3Cert); if (!Arrays.AreEqual(o.GetEncoded(), v3Cert)) { Fail("failed v3 cert read back test"); } }
private void TbsV3CertGenWithNullSubject() { V3TbsCertificateGenerator gen = new V3TbsCertificateGenerator(); DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1); DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 2); gen.SetSerialNumber(new DerInteger(2)); gen.SetStartDate(new Time(startDate)); gen.SetEndDate(new Time(endDate)); gen.SetIssuer(new X509Name("CN=AU,O=Bouncy Castle")); gen.SetSignature(new AlgorithmIdentifier(PkcsObjectIdentifiers.MD5WithRsaEncryption, DerNull.Instance)); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(BigInteger.One, BigInteger.Two)), new DerInteger(3)); gen.SetSubjectPublicKeyInfo(info); try { gen.GenerateTbsCertificate(); Fail("null subject not caught!"); } catch (InvalidOperationException e) { if (!e.Message.Equals("not all mandatory fields set in V3 TBScertificate generator")) { Fail("unexpected exception", e); } } // // add extensions // IList order = new ArrayList(); IDictionary extensions = new Hashtable(); order.Add(X509Extensions.SubjectAlternativeName); extensions.Add( X509Extensions.SubjectAlternativeName, new X509Extension( true, new DerOctetString( new GeneralNames( new GeneralName( new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2")))))); X509Extensions ex = new X509Extensions(order, extensions); gen.SetExtensions(ex); TbsCertificateStructure tbs = gen.GenerateTbsCertificate(); if (!Arrays.AreEqual(tbs.GetEncoded(), v3CertNullSubject)) { Fail("failed v3 null sub cert generation"); } // // read back test // Asn1Object o = Asn1Object.FromByteArray(v3CertNullSubject); if (!Arrays.AreEqual(o.GetEncoded(), v3CertNullSubject)) { Fail("failed v3 null sub cert read back test"); } }
private string GenerateX509Cert(string publicKey, string x509Subject) { Asn1Sequence asn1Sequence = null; using (var reader = new StringReader(publicKey)) { // Read the RSA public key from the input string. var pemReader = new PemReader(reader); var pemObject = pemReader.ReadPemObject(); asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(pemObject.Content); } // Generate a TBS certificate. We use placeholder-like values since // the consumer of this certificate should only use the subject // public key info. var tbsCertGen = new V3TbsCertificateGenerator(); tbsCertGen.SetSerialNumber(new DerInteger(1)); var signatureAlgId = new AlgorithmIdentifier(PkcsObjectIdentifiers.Sha1WithRsaEncryption, DerNull.Instance); tbsCertGen.SetSignature(signatureAlgId); tbsCertGen.SetIssuer(new X509Name("CN=Root Agency")); var dateTimeNow = DateTime.Now; tbsCertGen.SetStartDate(new Time(dateTimeNow.AddMinutes(-10))); tbsCertGen.SetEndDate(new Time(dateTimeNow.AddYears(1))); // Openssh key doesn`t have any start/end date, this is to satisfy RDFE tbsCertGen.SetSubject(new X509Name(x509Subject)); tbsCertGen.SetSubjectPublicKeyInfo(new SubjectPublicKeyInfo(new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), asn1Sequence)); var tbsCert = tbsCertGen.GenerateTbsCertificate(); // Per RFC 3280, the layout of an X.509 v3 certificate looks like: // Certificate ::= SEQUENCE { // tbsCertificate TBSCertificate, // signatureAlgorithm AlgorithmIdentifier, // signatureValue BIT STRING // } // Since we don't have access to the private key, we cannot create // a signature for the TBS. However, a valid certificate requires // a bit string for the signature value, so we use a 0-byte array // in its place. Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(tbsCert); v.Add(signatureAlgId); v.Add(new DerBitString(new byte[0])); var derSequence = new DerSequence(v); // Output the DER-encoded X509 certificate. var sb = new StringBuilder(); using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture)) { var pemWriter = new PemWriter(writer); pemWriter.WriteObject(new PemObject("CERTIFICATE", derSequence.GetEncoded())); } return sb.ToString(); }