コード例 #1
0
        /// <summary>
        /// append password to CSR: csrWithPassword = (csr, password)
        /// </summary>
        /// <param name="csr"></param>
        /// <param name="password"></param>
        /// <returns>CSR that  contains password</returns>
        public byte[] AppendPassword(byte[] csr, string password)
        {
            if (csr == null)
            {
                throw new ArgumentNullException(nameof(csr));
            }
            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException(nameof(password));
            }

            var originalCsr = new Pkcs10CertificationRequest(csr);

            CertificationRequestInfo cri = originalCsr.GetCertificationRequestInfo();

            DerSet attributesSet = AddPasswordAttribute(password, cri.Attributes);

            AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(cri.SubjectPublicKeyInfo);

            string signatureAlgorithm = originalCsr.SignatureAlgorithm.Algorithm.Id;

            // build new CSR from original + password attribute
            var csrWithPassword =
                new Pkcs10CertificationRequestDelaySigned(signatureAlgorithm, cri.Subject, publicKey, attributesSet);

            // this signing key is not used for signing but here only to suppress exception thrown in ctor
            csrWithPassword.SignRequest(new byte[] { });

            var csrWithPasswordBytes = csrWithPassword.GetDerEncoded();

            return(csrWithPasswordBytes);
        }
コード例 #2
0
        public void GenerateCsr(Pkcs11KeyInfo privKeyInfo, Pkcs11KeyInfo pubKeyInfo, DnEntry[] dnEntries, HashAlgorithm hashAlgorithm, out string fileName, out byte[] fileContent)
        {
            string   signatureAlgorithmOid = hashAlgorithm.SignatureAlgorithmOid[(CKK)privKeyInfo.CkaKeyType];
            X509Name x509Name = Utils.CreateX509Name(dnEntries);
            AsymmetricKeyParameter publicKeyParameters = GetPubKeyParams(privKeyInfo, pubKeyInfo);

            if (signatureAlgorithmOid.Length == 0)
            {
                signatureAlgorithmOid = "SHA256withECDSA";
            }
            Pkcs10CertificationRequestDelaySigned pkcs10 = new Pkcs10CertificationRequestDelaySigned(signatureAlgorithmOid, x509Name, publicKeyParameters, null);

            byte[] dataToSign = pkcs10.GetDataToSign();
            byte[] digest     = hashAlgorithm.ComputeDigest(dataToSign);
            byte[] digestInfo = digest;
            CKM    mecha      = CKM.CKM_ECDSA;

            if ((CKK)privKeyInfo.CkaKeyType == CKK.CKK_RSA)
            {
                digestInfo = Utils.CreateDigestInfo(digest, hashAlgorithm.Oid);
                mecha      = CKM.CKM_RSA_PKCS;
            }

            byte[] signature = null;

            using (ISession session = _slot.OpenSession(SessionType.ReadWrite))
                using (IMechanism mechanism = session.Factories.MechanismFactory.Create(mecha))
                    signature = session.Sign(mechanism, privKeyInfo.ObjectHandle, digestInfo);

            pkcs10.SignRequest(new DerBitString(signature));
            byte[] csr = pkcs10.GetDerEncoded();

            fileName    = (!string.IsNullOrEmpty(privKeyInfo.CkaLabel)) ? Utils.NormalizeFileName(privKeyInfo.CkaLabel + ".csr") : "pkcs10.csr";
            fileContent = csr;
        }
コード例 #3
0
        /// <summary>
        /// Calculates hash (digest) of the given CSR using the specified hash algorithm OID
        /// </summary>
        /// <param name="csr">CSR without password</param>
        /// <param name="algorithm">digest algorithm OID, for example for SHA256 use: "2.16.840.1.101.3.4.2.1"</param>
        /// <returns>Hash of csr</returns>
        public byte[] BuildHash(byte[] csr, string algorithm)
        {
            var originalCsr = new Pkcs10CertificationRequestDelaySigned(csr);

            // parse CSR to Org.BouncyCastle.Pkcs.Pkcs10CertificationRequestDelaySigned
            //  requires CSR to have:
            // 1. Subject
            //      a. X509Name
            //      b. subject public key
            //      c. attributes
            //          c1. password - should be empty
            //          c2. extensions - should contain ... doesn't matter - don't touch
            // 2. SignatureAlgorithmId - keep as it is defined by user request
            // 3. SignBits of user for the given CSR

            // hash = function(csrWithPassword without signature/signature algorithm)
            // for some hash algorithms Hash may depend on a random number,
            // thus giving different Hash every time it is calculated even for the same Data, PrivateKey

            byte[] dataToSign = originalCsr.GetDataToSign();

            //byte[] digest = DigestUtilities.CalculateDigest(CmsSignedGenerator.DigestSha256, dataToSign);
            byte[] digest = DigestUtilities.CalculateDigest(algorithm, dataToSign);

            return(digest);
        }
コード例 #4
0
        public IActionResult GenerateRootPrivateKeyAndCertificate([FromServices] CertificateService certificateService)
        {
            RootCaPrivateKeyAndCertificateChain model = new RootCaPrivateKeyAndCertificateChain();
            AsymmetricCipherKeyPair             rootCaKeyPair;
            string rootCaSubjectName = "AgileLabs Primary Root Ca";
            var    rootCaX509Name    = new X509Name($"C=UK, ST=NY, L=NY, O=MC, OU=IT Dept., CN={rootCaSubjectName}");
            var    x509cert          = certificateService.GenerateRootCaAuthority(rootCaX509Name, out rootCaKeyPair, keyStrength: 2048);

            model.CertificatePEMFormat = CertificateUtil.GetString(x509cert, X509ContentType.Cert).Replace(Environment.NewLine, "<br/>");
            model.PrivateKey           = CertificateUtil.GetString(rootCaKeyPair.Private, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----").Replace(Environment.NewLine, "<br/>");
            model.PublicKey            = CertificateUtil.GetString(rootCaKeyPair.Public, "-----BEGIN RSA PUBLIC KEY-----", "-----END RSA PUBLIC KEY-----").Replace(Environment.NewLine, "<br/>");

            //generate device key
            var deviceKeyPair = certificateService.GenerateRsaPrivateAndPublicKeyPair(2048);

            model.DevicePrivateKey = CertificateUtil.GetString(deviceKeyPair.Private, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----").Replace(Environment.NewLine, "<br/>");
            model.DevicePublicKey  = CertificateUtil.GetString(deviceKeyPair.Public, "-----BEGIN RSA PUBLIC KEY-----", "-----END RSA PUBLIC KEY-----").Replace(Environment.NewLine, "<br/>");

            //generate csr
            //PKCS #10 Certificate Signing Request
            //Requested Certificate Name
            X509Name name = new X509Name("CN=agilelabs.net, C=NL");
            //Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest("SHA1WITHRSA", name, deviceKeyPair.Public, null, deviceKeyPair.Private);
            Pkcs10CertificationRequestDelaySigned csrDelaySigned = new Pkcs10CertificationRequestDelaySigned("SHA1WITHRSA", name, deviceKeyPair.Public, null);

            //sign csr and return certificate
            var deviceCert = certificateService.Sign(csrDelaySigned, rootCaX509Name, deviceKeyPair.Private, deviceKeyPair);

            model.DeviceCertificate = CertificateUtil.GetString(deviceCert, X509ContentType.Cert).Replace(Environment.NewLine, "<br/>");
            return(View(model));
        }
コード例 #5
0
        public X509Certificate2 Sign(Pkcs10CertificationRequestDelaySigned inputCSR, X509Name issuerName, AsymmetricKeyParameter issuerPrivKey, AsymmetricCipherKeyPair pair)
        {
            const int keyStrength = 2048;

            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator  = new CryptoApiRandomGenerator();
            SecureRandom             random           = new SecureRandom(randomGenerator);
            ISignatureFactory        signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random);

            // The Certificate Generator
            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

            certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var csrInfo = inputCSR.GetCertificationRequestInfo();

            certificateGenerator.SetIssuerDN(issuerName);
            certificateGenerator.SetSubjectDN(csrInfo.Subject);

            // Valid For
            DateTime notBefore = DateTime.UtcNow.Date;
            DateTime notAfter  = notBefore.AddYears(2);

            certificateGenerator.SetNotBefore(notBefore);
            certificateGenerator.SetNotAfter(notAfter);

            // Subject Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // selfsign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);
            //var dotNetPrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private);

            // merge into X509Certificate2
            X509Certificate2 x509 = new X509Certificate2(DotNetUtilities.ToX509Certificate(certificate));

            //x509.PrivateKey = dotNetPrivateKey;
            //x509.FriendlyName = csrInfo.Subject;

            return(x509);
        }
コード例 #6
0
        public bool GenerarCsr(ref authTokenType token, string privateKeyalias, string publicKeyAlias, string subject, string fileName, string challenge)
        {
            LunaXml.xmCryptoService client = new xmCryptoService();
            try
            {
                byte[]  modulus  = new byte[] {};
                byte [] exponent = new byte[] {};
                this.Extraer(ref token, publicKeyAlias, ref modulus, ref exponent);
                RsaKeyParameters param  = new RsaKeyParameters(false, new BigInteger(modulus), new BigInteger(exponent));
                DerSet           derset = null;
                if (challenge != null)
                {
                    ChallengePassword chpass = new ChallengePassword(challenge);
                    derset = new DerSet(chpass);
                    //IList oid = new ArrayList();
                    //IList values = new ArrayList();
                    //oid.Add(PkcsObjectIdentifiers.Pkcs9AtChallengePassword);
                    //var pass = new DerPrintableString(challenge);
                    ////Asn1OctetString oct = pass.ToAsn1Object(); //new DerOctetString(pass);//Encoding.ASCII.GetBytes(Convert.ToBase64String(Encoding.UTF8.GetBytes("AABBccc22"))));

                    //X509Extension ext = new X509Extension(false,new DerOctetString(pass.GetEncoded()));
                    //values.Add(pass);
                    //X509Extensions extensions = new X509Extensions(oid, values);
                    //derset = new DerSet(extensions.ToAsn1Object());
                }
                else
                {
                    derset = new DerSet();
                }

                //string sub =
                //"2.5.4.45=SAT970701NN3 / GATF730321GG5, SERIALNUMBER= / GATF730321HJCRRR01, O=SERVICIO DE ADMINISTRACION TRIBUTARIA, OU=PACNLC091211KC657202";
                //+ ", 1.2.840.113549.1.9.7= NtLink2012"
                X509Name sub = new X509Name(subject, new ConverterSidetec());
                Pkcs10CertificationRequestDelaySigned ds = new Pkcs10CertificationRequestDelaySigned("SHA1WITHRSA", sub, param, derset);
                string pafirmar = Convert.ToBase64String(ds.GetDataToSign());
                string firmados = Firmar(ref token, pafirmar, privateKeyalias, SignatureModeType.SHA1withRSA);
                byte[] bytes    = Convert.FromBase64String(firmados);

                ds.SignRequest(bytes);
                File.WriteAllBytes(fileName, ds.GetDerEncoded());
                return(true);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                return(false);
            }
            finally
            {
                client.Dispose();
            }
        }
コード例 #7
0
        /// <summary>
        /// Creates new csr from given CSR + signature
        /// </summary>
        /// <param name="csr">CSR to be used for appending signature</param>
        /// <param name="signature">signature to be appended to CSR</param>
        /// <returns>new CSR with signature appended inside</returns>
        public byte[] AppendSignature(byte[] csr, byte[] signature)
        {
            if (csr == null)
            {
                throw new ArgumentNullException(nameof(csr));
            }

            var originalCsr = new Pkcs10CertificationRequestDelaySigned(csr);

            originalCsr.SignRequest(signature);

            byte[] csrBytes = originalCsr.GetDerEncoded();

            return(csrBytes);
        }
コード例 #8
0
        /// <summary>
        /// Verify signature using specified signer
        /// </summary>
        /// <param name="csrSigned"></param>
        private void Verify2(byte[] csrSigned)
        {
            var csr      = new Pkcs10CertificationRequestDelaySigned(csrSigned);
            var sigBytes = csr.Signature.GetBytes();//.GetDerEncoded();
            var data     = csr.GetDataToSign();
            AsymmetricKeyParameter publicSigningKey = csr.GetPublicKey();
            var signerAlgorithm = csr.SignatureAlgorithm.Algorithm.Id;

            var s = SignerUtilities.GetSigner(signerAlgorithm);

            s.Init(false, publicSigningKey);
            s.BlockUpdate(data, 0, data.Length);
            bool isValidSignature = s.VerifySignature(sigBytes);

            Assert.IsTrue(isValidSignature, "ECDSA verification failed");
        }
コード例 #9
0
ファイル: CaFactory.cs プロジェクト: hugocurran/OSCA2
        /// <summary>
        /// Create a new Subordinate CA certificate request using the setup parameters from a CAConfig object
        /// </summary>
        /// <remarks>Only System cryptography supported</remarks>
        /// <param name="Config">CAConfig object</param>
        /// <returns>PKCS#10 certificate request</returns>
        public static Pkcs10CertificationRequest CreateSubCA(CAConfig Config)
        {
            if (Config.profile != CA_Profile.SubCA)
            {
                throw new ArgumentException("Invalid profile specified", Config.profile.ToString());
            }

            if (!Config.FIPS140)
            {
                throw new InvalidParameterException("Only FIPS mode supported");
            }

            // Serial number
            BigInteger serialNumber = new BigInteger(1, BitConverter.GetBytes(DateTime.Now.Ticks));

            // Key material
            CspParameters cspParam = SysKeyManager.Create(Config.pkSize, Config.pkAlgo, Config.name);

            // PKCS#10 Request
            Pkcs10CertificationRequestDelaySigned p10 = new Pkcs10CertificationRequestDelaySigned(
                Config.sigAlgo,
                Config.DN,
                SysKeyManager.getPublicKey(cspParam, Config.pkAlgo),
                null);

            // Signature
            byte[] buffer    = p10.GetDataToSign();
            byte[] signature = SysSigner.Sign(buffer, cspParam, Config.sigAlgo);
            p10.SignRequest(signature);

            if (!p10.Verify())
            {
                throw new SignatureException("Cannot validate POP signature");
            }

            // Create the CA Config file
            createPendingCAConfig(Config, serialNumber, p10, "");

            return(p10);
        }
コード例 #10
0
ファイル: CaFactory.cs プロジェクト: hugocurran/OSCA2
        /// <summary>
        /// Create a new Subordinate CA using the setup parameters from a CAConfig object
        /// The Issuing CA must be available to create and sign a certificate
        /// </summary>
        /// <param name="Config">CAConfig object</param>
        /// <param name="IssuingCA">Object reference for issuing CA</param>
        /// <returns>Full pathname of CA config file</returns>
        public static string CreateSubCA(CAConfig Config, ICA IssuingCA)
        {
            if (Config.profile != CA_Profile.SubCA)
            {
                throw new ArgumentException("Invalid profile specified", Config.profile.ToString());
            }

            // Serial number
            BigInteger serialNumber = new BigInteger(1, BitConverter.GetBytes(DateTime.Now.Ticks));


            // Key material
            Pkcs10CertificationRequest p10;

            if (Config.FIPS140)
            {
                privateKeyCapi = SysKeyManager.Create(Config.pkSize, Config.pkAlgo, Config.name);

                // PKCS#10 Request
                p10 = new Pkcs10CertificationRequestDelaySigned(
                    Config.sigAlgo,
                    Config.DN,
                    SysKeyManager.getPublicKey(privateKeyCapi, Config.pkAlgo),
                    null);
                // Signature
                byte[] buffer    = ((Pkcs10CertificationRequestDelaySigned)p10).GetDataToSign();
                byte[] signature = SysSigner.Sign(buffer, privateKeyCapi, Config.sigAlgo);
                ((Pkcs10CertificationRequestDelaySigned)p10).SignRequest(signature);
            }
            else
            {
                keyPair = BcKeyManager.Create(Config.pkSize, Config.pkAlgo);
                // Create a system CspParameters entry for use by XmlSigner
                privateKeyCapi = SysKeyManager.LoadCsp(keyPair.Private);

                // PKCS#10 Request
                p10 = new Pkcs10CertificationRequest(
                    Config.sigAlgo,
                    Config.DN,
                    keyPair.Public,
                    null,
                    keyPair.Private);
            }
            // Test the signature
            if (!p10.Verify())
            {
                throw new SignatureException("Cannot validate POP signature");
            }

            // Request cert from issuing CA
            X509Certificate cert = IssuingCA.IssueCertificate(p10, new Profile.Profile(Config.profileFile));

            string configFile;

            if (Config.FIPS140)
            {
                // Create the CA Config file
                configFile = createFinalCAConfig(Config, serialNumber, cert, null);
                LogEvent.WriteEvent(eventLog, LogEvent.EventType.CreateCA, "Subordinate CA (FIPS) Created: " + configFile);
            }
            else
            {
                // Store key material in a PKCS#12 file
                MemoryStream stream = BcKeyManager.SaveP12(keyPair.Private, cert, Config.password, Config.name);
                string       caKey  = Convert.ToBase64String(stream.ToArray());

                // Create the CA Config file
                configFile = createFinalCAConfig(Config, serialNumber, null, caKey);
                LogEvent.WriteEvent(eventLog, LogEvent.EventType.CreateCA, "Root CA (BC) Created: " + configFile);
            }
            // Create CA database
            Database.CreateDB(Config, cert, privateKeyCapi);

            return(configFile);
        }
コード例 #11
0
        private bool saveAs(bool Signed)
        {
            //SaveFileDialog dialog;

            mSubjectItemsOIDs.Add(X509Name.C);
            mSubjectItemsOIDs.Add(X509Name.OU);
            mSubjectItemsOIDs.Add(X509Name.CN);
            mSubjectItemsOIDs.Add(X509Name.TelephoneNumber);

            mSubjectItems.Add(CountryCodeTB.Text.Trim());
            mSubjectItems.Add(OrganizationalUnitTB.Text.Trim());
            mSubjectItems.Add(CommonNameTB.Text.Trim());
            mSubjectItems.Add(PhoneNumberTB.Text.Trim());

            mExtItemsOIDs.Add(X509Extensions.SubjectAlternativeName);
            mExtItems.Add(new X509Extension(false,
                                            new DerOctetString(new GeneralNames(new GeneralName(GeneralName.Rfc822Name, EmailTB.Text)))));


            string mKeyUsageDescription = "digitalSignature, nonRepudiation";

            int key_usage_bit_map = 0;

            key_usage_bit_map |= KeyUsage.DigitalSignature;
            key_usage_bit_map |= KeyUsage.NonRepudiation;

            KeyUsage mKeyUsage = new KeyUsage(key_usage_bit_map);

            mExtItemsOIDs.Add(X509Extensions.KeyUsage);
            mExtItems.Add(new X509Extension(true, new DerOctetString(mKeyUsage)));

            try
            {
                /* dialog = new SaveFileDialog();
                *  dialog.Filter = "CSR files (*.pem)|*.pem|All files (*.*)|*.*";
                *  dialog.RestoreDirectory = true;*/

                //if (dialog.ShowDialog() == DialogResult.OK)
                //{
                X509Name subject            = new X509Name(mSubjectItemsOIDs, mSubjectItems);
                string   signatureAlgorithm = "SHA256withECDSA";

                DerSet attributes = new DerSet();
                if (mExtItemsOIDs.Count > 0)
                {
                    attributes.AddObject(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(
                                                               new X509Extensions(mExtItemsOIDs, mExtItems)))); // mExtItemsOIDs.Zip(mExtItems, (k, v) => new { Key = k, Value = v })
                                                                                                                //              .ToDictionary(x => x.Key, x => x.Value)
                }

                AsymmetricKeyParameter local_pub_key;

                if (Signed)
                {
                    local_pub_key = mPublicKey;
                }
                else
                {
                    local_pub_key = new RsaKeyParameters(false, BigInteger.One, BigInteger.One); // DUMMY RSA public key - for templates
                }
                Pkcs10CertificationRequestDelaySigned csr_ds =
                    new Pkcs10CertificationRequestDelaySigned(signatureAlgorithm, subject, local_pub_key, attributes);

                byte[] dataToSign = csr_ds.GetDataToSign();
                byte[] toSave;
                string header_footer;

                if (Signed)
                {
                    byte[] SignedData = uFRSigner(dataToSign);
                    // Rest of the input parameters needed (here accessible directly from UI):
                    //      - digest_alg, signature_cipher, card_key_index
                    csr_ds.SignRequest(SignedData);

                    toSave        = csr_ds.GetDerEncoded();
                    header_footer = "CERTIFICATE REQUEST";
                }
                else
                {
                    toSave        = dataToSign;
                    header_footer = "TBS CERTIFICATE REQUEST";
                }

                var file_extension = Path.GetExtension("CSR.pem");
                if (file_extension.Equals(".pem"))
                {
                    //var textWriter = new StreamWriter(dialog.FileName);
                    var textWriter = new StreamWriter("CSR.pem");

                    textWriter.Write(der2pem(toSave, header_footer));
                    textWriter.Flush();
                    textWriter.Close();
                }

                /* else
                 * {
                 *   using (var fs = new FileStream(dialog.FileName, FileMode.Create, FileAccess.Write))
                 *   {
                 *       fs.Write(toSave, 0, toSave.Length);
                 *       fs.Flush();
                 *       fs.Close();
                 *   }
                 * }*/
                // }
                //else
                //return false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            return(true);
        }
コード例 #12
0
        /// <summary>
        /// Generates certificate request in PKCS#10 format defined by RFC 2986
        /// </summary>
        /// <param name="session">Read-write session with user logged in</param>
        /// <param name="publicKeyHandle">Handle of existing public key</param>
        /// <param name="privateKeyHandle">Handle of existing private key</param>
        /// <param name="subjectDistinguishedName">Subject entity's distinguished name</param>
        /// <param name="digestAlgorithm">Standard digest (hash) algorithm used for the creation of request signature</param>
        /// <param name="asn1Attributes"><exception cref="Asn1Set"> representing attributes to be added to the certificate request</exception></param>
        /// <returns>Certificate request in PKCS#10 format</returns>
        public static byte[] GeneratePkcs10(Session session, ObjectHandle publicKeyHandle, ObjectHandle privateKeyHandle, string subjectDistinguishedName, DigestAlgorithm digestAlgorithm, Asn1Set asn1Attributes)
        {
            var pubKeyAttrsToRead = new List <CKA>();

            pubKeyAttrsToRead.Add(CKA.CKA_KEY_TYPE);
            pubKeyAttrsToRead.Add(CKA.CKA_MODULUS);
            pubKeyAttrsToRead.Add(CKA.CKA_PUBLIC_EXPONENT);

            // Read public key attributes
            var publicKeyAttributes = session.GetAttributeValue(publicKeyHandle, pubKeyAttrsToRead);

            if (CKK.CKK_RSA != (CKK)publicKeyAttributes[0].GetValueAsUlong())
            {
                throw new NotSupportedException("Currently only RSA keys are supported");
            }

            // Create instance of RsaKeyParameters class usable for BouncyCastle
            var modulus             = new BigInteger(1, publicKeyAttributes[1].GetValueAsByteArray());
            var publicExponent      = new BigInteger(1, publicKeyAttributes[2].GetValueAsByteArray());
            var publicKeyParameters = new RsaKeyParameters(false, modulus, publicExponent);

            // Determine algorithms
            Mechanism mechanism = null;
            string    signatureAlgorithm;

            switch (digestAlgorithm)
            {
            case DigestAlgorithm.SHA1:
                mechanism          = new Mechanism(CKM.CKM_SHA1_RSA_PKCS);
                signatureAlgorithm = PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id;
                break;

            case DigestAlgorithm.SHA256:
                mechanism          = new Mechanism(CKM.CKM_SHA256_RSA_PKCS);
                signatureAlgorithm = PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id;
                break;

            case DigestAlgorithm.SHA384:
                mechanism          = new Mechanism(CKM.CKM_SHA384_RSA_PKCS);
                signatureAlgorithm = PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id;
                break;

            case DigestAlgorithm.SHA512:
                mechanism          = new Mechanism(CKM.CKM_SHA512_RSA_PKCS);
                signatureAlgorithm = PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(digestAlgorithm), digestAlgorithm, null);
            }

            // Generate and sign PKCS#10 request. See RFC 2986 4.2 CertificationRequest
            var pkcs10 = new Pkcs10CertificationRequestDelaySigned(signatureAlgorithm, new X509Name(subjectDistinguishedName), publicKeyParameters, asn1Attributes);

            // Use HSM to generate signature for the csr
            byte[] signature = session.Sign(mechanism, privateKeyHandle, pkcs10.GetDataToSign());
            // set the signature BIT STRING of the pkcs#10 request. See RFC 2986 4.2 CertificationRequest
            pkcs10.SignRequest(new DerBitString(signature));

            return(pkcs10.GetDerEncoded());
        }