/// <summary>
        /// Create the RSA certificate with a given public key.
        /// </summary>
        /// <returns>The signed certificate.</returns>
        private X509Certificate2 CreateForRSAWithPublicKey(ISignatureFactory signatureFactory = null)
        {
            // Cases locked out by API flow
            Debug.Assert(m_rsaPublicKey != null, "Need a public key for the certificate.");
            if ((IssuerCAKeyCert == null || !IssuerCAKeyCert.HasPrivateKey) && signatureFactory == null)
            {
                throw new NotSupportedException("Need an issuer certificate with a private key or a signature generator.");
            }

            // cert generators
            CreateDefaults();

            var cg = new X509V3CertificateGenerator();

            CreateMandatoryFields(cg);

            // set public key
            AsymmetricKeyParameter subjectPublicKey = X509Utils.GetPublicKeyParameter(m_rsaPublicKey);

            cg.SetPublicKey(subjectPublicKey);

            CreateExtensions(cg, subjectPublicKey);

            // sign certificate by issuer
            if (signatureFactory == null)
            {
                AsymmetricKeyParameter signingKey = X509Utils.GetPrivateKeyParameter(IssuerCAKeyCert);
                signatureFactory = new Asn1SignatureFactory(X509Utils.GetRSAHashAlgorithm(HashAlgorithmName), signingKey);
            }
            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create the signed cert
            return(new X509Certificate2(x509.GetEncoded()));
        }
Example #2
0
        /// <summary>
        /// Create the RSA certificate as Pfx byte array with a private key.
        /// </summary>
        /// <returns>
        /// Returns the Pfx with certificate and private key.
        /// </returns>
        private byte[] CreatePfxForRSA(string passcode, ISignatureFactory signatureFactory = null)
        {
            // Cases locked out by API flow
            Debug.Assert(m_rsaPublicKey == null, "A public key is not supported for the certificate.");

            if (signatureFactory != null && IssuerCAKeyCert == null)
            {
                throw new NotSupportedException("Need an issuer certificate for a signature generator.");
            }

            if (IssuerCAKeyCert != null &&
                (!IssuerCAKeyCert.HasPrivateKey && signatureFactory == null))
            {
                throw new NotSupportedException("Need an issuer certificate with a private key or a signature generator.");
            }

            using (var cfrg = new CertificateFactoryRandomGenerator())
            {
                // cert generators
                SecureRandom random = new SecureRandom(cfrg);

                CreateDefaults(cfrg);

                X509V3CertificateGenerator cg = new X509V3CertificateGenerator();
                CreateMandatoryFields(cg);

                // create Private/Public Keypair
                var rsa = new RSACryptoServiceProvider(m_keySize == 0 ? X509Defaults.RSAKeySize : m_keySize);
                AsymmetricKeyParameter subjectPublicKey  = X509Utils.GetPublicKeyParameter(rsa);
                AsymmetricKeyParameter subjectPrivateKey = X509Utils.GetPrivateKeyParameter(rsa);

                cg.SetPublicKey(subjectPublicKey);

                CreateExtensions(cg, subjectPublicKey);

                // sign certificate
                if (signatureFactory == null)
                {
                    AsymmetricKeyParameter signingKey;
                    if (IssuerCAKeyCert != null)
                    {
                        // signed by issuer
                        signingKey = X509Utils.GetPrivateKeyParameter(IssuerCAKeyCert);
                    }
                    else
                    {
                        // self signed
                        signingKey = subjectPrivateKey;
                    }
                    signatureFactory = new Asn1SignatureFactory(
                        X509Utils.GetRSAHashAlgorithm(HashAlgorithmName), signingKey, random);
                }
                Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

                // note: this Pfx has a private key!
                return(X509Utils.CreatePfxWithPrivateKey(x509, null, subjectPrivateKey, passcode, random));
            }
        }
Example #3
0
        /// <summary>
        /// Returns a byte array containing the private key in PEM format.
        /// </summary>
        public static byte[] ExportPrivateKeyAsPEM(
            X509Certificate2 certificate
            )
        {
            RsaPrivateCrtKeyParameters privateKeyParameter = X509Utils.GetPrivateKeyParameter(certificate);

            using (TextWriter textWriter = new StringWriter())
            {
                // write private key as PKCS#8
                PrivateKeyInfo privateKeyInfo         = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParameter);
                byte[]         serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded();
                return(EncodeAsPEM(serializedPrivateBytes, "PRIVATE KEY"));
            }
        }
Example #4
0
        /// <summary>
        /// Returns a byte array containing the private key in PEM format.
        /// </summary>
        public static byte[] ExportPrivateKeyAsPEM(
            X509Certificate2 certificate,
            string password = null
            )
        {
            if (!String.IsNullOrEmpty(password))
            {
                throw new ArgumentException(nameof(password), "Export with password not supported on this platform.");
            }
            RsaPrivateCrtKeyParameters privateKeyParameter = X509Utils.GetPrivateKeyParameter(certificate);
            // write private key as PKCS#8
            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParameter);

            byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded();
            return(EncodeAsPEM(serializedPrivateBytes, "PRIVATE KEY"));
        }
        /// <summary>
        /// Create a Pfx with a private key by combining
        /// an existing X509Certificate2 and a RSA private key.
        /// </summary>
        public static byte[] CreatePfxWithRSAPrivateKey(
            X509Certificate2 certificate,
            string friendlyName,
            RSA privateKey,
            string passcode)
        {
            var x509 = new X509CertificateParser().ReadCertificate(certificate.RawData);

            using (var cfrg = new CertificateFactoryRandomGenerator())
            {
                return(X509Utils.CreatePfxWithPrivateKey(
                           x509, friendlyName,
                           X509Utils.GetPrivateKeyParameter(privateKey),
                           passcode,
                           new SecureRandom(cfrg)));
            }
        }
        /// <summary>
        /// Creates a certificate signing request from an
        /// existing certificate with a private key.
        /// </summary>
        public static byte[] CreateSigningRequest(
            X509Certificate2 certificate,
            IList <String> domainNames = null
            )
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }
            using (var cfrg = new CertificateFactoryRandomGenerator())
            {
                SecureRandom random = new SecureRandom(cfrg);

                // try to get signing/private key from certificate passed in
                AsymmetricKeyParameter signingKey = X509Utils.GetPrivateKeyParameter(certificate);
                RsaKeyParameters       publicKey  = X509Utils.GetPublicKeyParameter(certificate);

                ISignatureFactory signatureFactory =
                    new Asn1SignatureFactory(X509Utils.GetRSAHashAlgorithm(X509Defaults.HashAlgorithmName), signingKey, random);

                Asn1Set attributes = null;
                var     san        = X509Extensions.FindExtension <X509SubjectAltNameExtension>(certificate);
                X509SubjectAltNameExtension alternateName = new X509SubjectAltNameExtension(san, san.Critical);

                string applicationUri = null;
                domainNames = domainNames ?? new List <String>();
                if (alternateName != null)
                {
                    if (alternateName.Uris.Count > 0)
                    {
                        applicationUri = alternateName.Uris[0];
                    }
                    foreach (var name in alternateName.DomainNames)
                    {
                        if (!domainNames.Any(s => s.Equals(name, StringComparison.OrdinalIgnoreCase)))
                        {
                            domainNames.Add(name);
                        }
                    }
                    foreach (var ipAddress in alternateName.IPAddresses)
                    {
                        if (!domainNames.Any(s => s.Equals(ipAddress, StringComparison.OrdinalIgnoreCase)))
                        {
                            domainNames.Add(ipAddress);
                        }
                    }
                }

                // build CSR extensions
                var generalNames = new List <GeneralName>();

                if (applicationUri != null)
                {
                    generalNames.Add(new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri));
                }

                if (domainNames.Count > 0)
                {
                    generalNames.AddRange(BouncyCastle.X509Extensions.CreateSubjectAlternateNameDomains(domainNames));
                }

                if (generalNames.Count > 0)
                {
                    IList oids   = new ArrayList();
                    IList values = new ArrayList();
                    oids.Add(Org.BouncyCastle.Asn1.X509.X509Extensions.SubjectAlternativeName);
                    values.Add(new Org.BouncyCastle.Asn1.X509.X509Extension(false,
                                                                            new DerOctetString(new GeneralNames(generalNames.ToArray()).GetDerEncoded())));
                    var attribute = new Org.BouncyCastle.Asn1.Pkcs.AttributePkcs(Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.Pkcs9AtExtensionRequest,
                                                                                 new DerSet(new Org.BouncyCastle.Asn1.X509.X509Extensions(oids, values)));
                    attributes = new DerSet(attribute);
                }

                var pkcs10CertificationRequest = new Pkcs10CertificationRequest(
                    signatureFactory,
                    new CertificateFactoryX509Name(false, certificate.Subject),
                    publicKey,
                    attributes);

                return(pkcs10CertificationRequest.GetEncoded());
            }
        }