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)); }