private static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey, int keyStrength = 2048)
        {
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

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

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var subjectDN = new X509Name(subjectName);
            var issuerDN  = new X509Name(issuerName);

            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

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

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

            // Generating the Certificate
            var issuerKeyPair = subjectKeyPair;

            // selfsign certificate
            var signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random);
            var certificate      = certificateGenerator.Generate(signatureFactory);

            // correcponding private key
            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            // merge into X509Certificate2
            var x509 = new X509Certificate2(certificate.GetEncoded());

            var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());

            if (seq.Count != 9)
            {
                throw new PemException("malformed sequence in RSA private key");
            }

            var rsa = new RsaPrivateKeyStructure(seq);
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
            return(x509);
        }
Beispiel #2
0
        public async Task ValidateMergeCertificate()
        {
            string serverCertificateName = Recording.GenerateId();

            // Generate the request.
            CertificatePolicy policy = new CertificatePolicy(WellKnownIssuerNames.Unknown, "CN=Azure SDK")
            {
                CertificateTransparency = false,
                ContentType             = CertificateContentType.Pkcs12,
            };

            CertificateOperation operation = await Client.StartCreateCertificateAsync(serverCertificateName, policy);

            RegisterForCleanup(serverCertificateName);
            await using IAsyncDisposable disposableOperation = EnsureDeleted(operation);

            // Read the CA.
            byte[]           caCertificateBytes = Convert.FromBase64String(CaPublicKeyBase64);
            X509Certificate2 caCertificate      = new X509Certificate2(caCertificateBytes);

            // Read CA private key since getting it from caCertificate above throws.
            AsymmetricCipherKeyPair caPrivateKey;

            using (StringReader caPrivateKeyReader = new StringReader(CaPrivateKeyPem))
            {
                Org.BouncyCastle.OpenSsl.PemReader reader = new Org.BouncyCastle.OpenSsl.PemReader(caPrivateKeyReader);
                caPrivateKey = (AsymmetricCipherKeyPair)reader.ReadObject();
            }

            // Read the CSR.
            Pkcs10CertificationRequest csr     = new Pkcs10CertificationRequest(operation.Properties.Csr);
            CertificationRequestInfo   csrInfo = csr.GetCertificationRequestInfo();

            // Parse the issuer subject name.
            Hashtable oidLookup = new Hashtable(X509Name.DefaultLookup)
            {
                { "s", new DerObjectIdentifier("2.5.4.8") },
            };

            X509Name issuerName = new X509Name(true, oidLookup, caCertificate.Subject);

            // Sign the request.
            X509V3CertificateGenerator generator = new X509V3CertificateGenerator();

            generator.SetIssuerDN(issuerName);
            generator.SetSerialNumber(BigInteger.One);
            generator.SetNotBefore(DateTime.Now);
            generator.SetNotAfter(DateTime.Now.AddDays(1));
            generator.SetSubjectDN(csrInfo.Subject);
            generator.SetPublicKey(csr.GetPublicKey());

            Asn1SignatureFactory signatureFactory      = new Asn1SignatureFactory("SHA256WITHRSA", caPrivateKey.Private);
            X509Certificate      serverSignedPublicKey = generator.Generate(signatureFactory);

            // Merge the certificate chain.
            MergeCertificateOptions       options = new MergeCertificateOptions(serverCertificateName, new[] { serverSignedPublicKey.GetEncoded(), caCertificateBytes });
            KeyVaultCertificateWithPolicy mergedServerCertificate = await Client.MergeCertificateAsync(options);

            X509Certificate2 serverCertificate = new X509Certificate2(mergedServerCertificate.Cer);

            Assert.AreEqual(csrInfo.Subject.ToString(), serverCertificate.Subject);
            Assert.AreEqual(serverCertificateName, mergedServerCertificate.Name);

            KeyVaultCertificateWithPolicy completedServerCertificate = await WaitForCompletion(operation);

            Assert.AreEqual(mergedServerCertificate.Name, completedServerCertificate.Name);
            CollectionAssert.AreEqual(mergedServerCertificate.Cer, completedServerCertificate.Cer);
        }
        /// <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());
            }
        }
        // Only the ctor should be calling with isAuthority = true
        // if isAuthority, value for isMachineCert doesn't matter
        private X509CertificateContainer CreateCertificate(bool isAuthority, bool isMachineCert, X509Certificate signingCertificate, CertificateCreationSettings certificateCreationSettings)
        {
            if (certificateCreationSettings == null)
            {
                if (isAuthority)
                {
                    certificateCreationSettings = new CertificateCreationSettings();
                }
                else
                {
                    throw new Exception("Parameter certificateCreationSettings cannot be null when isAuthority is false");
                }
            }

            // Set to default cert creation settings if not set
            if (certificateCreationSettings.ValidityNotBefore == default(DateTime))
            {
                certificateCreationSettings.ValidityNotBefore = _defaultValidityNotBefore;
            }
            if (certificateCreationSettings.ValidityNotAfter == default(DateTime))
            {
                certificateCreationSettings.ValidityNotAfter = _defaultValidityNotAfter;
            }

            if (!isAuthority ^ (signingCertificate != null))
            {
                throw new ArgumentException("Either isAuthority == true or signingCertificate is not null");
            }
            string subject = certificateCreationSettings.Subject;

            // If certificateCreationSettings.SubjectAlternativeNames == null, then we should add exactly one SubjectAlternativeName == Subject
            // so that the default certificate generated is compatible with mainline scenarios
            // However, if certificateCreationSettings.SubjectAlternativeNames == string[0], then allow this as this is a legit scenario we want to test out
            if (certificateCreationSettings.SubjectAlternativeNames == null)
            {
                certificateCreationSettings.SubjectAlternativeNames = new string[1] {
                    subject
                };
            }

            string[] subjectAlternativeNames = certificateCreationSettings.SubjectAlternativeNames;

            if (!isAuthority && string.IsNullOrWhiteSpace(subject))
            {
                throw new ArgumentException("Certificate Subject must not be an empty string or only whitespace", "creationSettings.Subject");
            }

            EnsureInitialized();

            s_certGenerator.Reset();

            // Tag on the generation time to prevent caching of the cert CRL in Linux
            X509Name authorityX509Name = CreateX509Name(string.Format("{0} {1}", _authorityCanonicalName, DateTime.Now.ToString("s")));
            var      serialNum         = new BigInteger(64 /*sizeInBits*/, _random).Abs();

            var keyPair = isAuthority ? _authorityKeyPair : _keyPairGenerator.GenerateKeyPair();

            if (isAuthority)
            {
                s_certGenerator.SetIssuerDN(authorityX509Name);
                s_certGenerator.SetSubjectDN(authorityX509Name);

                var authorityKeyIdentifier = new AuthorityKeyIdentifier(
                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(_authorityKeyPair.Public),
                    new GeneralNames(new GeneralName(authorityX509Name)),
                    serialNum);

                s_certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, authorityKeyIdentifier);
                s_certGenerator.AddExtension(X509Extensions.KeyUsage, false, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyCertSign | X509KeyUsage.KeyEncipherment | X509KeyUsage.CrlSign));
            }
            else
            {
                X509Name subjectName = CreateX509Name(subject);
                s_certGenerator.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(signingCertificate));
                s_certGenerator.SetSubjectDN(subjectName);

                s_certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(_authorityKeyPair.Public));
                s_certGenerator.AddExtension(X509Extensions.KeyUsage, false, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyEncipherment));
            }

            s_certGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keyPair.Public));

            s_certGenerator.SetSerialNumber(serialNum);
            s_certGenerator.SetNotBefore(certificateCreationSettings.ValidityNotBefore);
            s_certGenerator.SetNotAfter(certificateCreationSettings.ValidityNotAfter);
            s_certGenerator.SetPublicKey(keyPair.Public);

            s_certGenerator.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(isAuthority));
            if (certificateCreationSettings.EKU == null || certificateCreationSettings.EKU.Count == 0)
            {
                s_certGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth));
            }
            else
            {
                s_certGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(certificateCreationSettings.EKU));
            }

            if (!isAuthority)
            {
                if (isMachineCert)
                {
                    List <Asn1Encodable> subjectAlternativeNamesAsAsn1EncodableList = new List <Asn1Encodable>();

                    // All endpoints should also be in the Subject Alt Names
                    for (int i = 0; i < subjectAlternativeNames.Length; i++)
                    {
                        if (!string.IsNullOrWhiteSpace(subjectAlternativeNames[i]))
                        {
                            // Machine certs can have additional DNS names
                            subjectAlternativeNamesAsAsn1EncodableList.Add(new GeneralName(GeneralName.DnsName, subjectAlternativeNames[i]));
                        }
                    }

                    s_certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNamesAsAsn1EncodableList.ToArray()));
                }
                else
                {
                    if (subjectAlternativeNames.Length > 1)
                    {
                        var subjectAlternativeNamesAsAsn1EncodableList = new Asn1EncodableVector();

                        // Only add a SAN for the user if there are any
                        for (int i = 1; i < subjectAlternativeNames.Length; i++)
                        {
                            if (!string.IsNullOrWhiteSpace(subjectAlternativeNames[i]))
                            {
                                Asn1EncodableVector otherNames = new Asn1EncodableVector();
                                otherNames.Add(new DerObjectIdentifier(_upnObjectId));
                                otherNames.Add(new DerTaggedObject(true, 0, new DerUtf8String(subjectAlternativeNames[i])));

                                Asn1Object genName = new DerTaggedObject(false, 0, new DerSequence(otherNames));

                                subjectAlternativeNamesAsAsn1EncodableList.Add(genName);
                            }
                        }
                        s_certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNamesAsAsn1EncodableList));
                    }
                }
            }

            if (isAuthority || certificateCreationSettings.IncludeCrlDistributionPoint)
            {
                var crlDistributionPoints = new DistributionPoint[1]
                {
                    new DistributionPoint(
                        new DistributionPointName(
                            new GeneralNames(
                                new GeneralName(
                                    GeneralName.UniformResourceIdentifier, string.Format("{0}", _crlUri, serialNum.ToString(radix: 16))))),
                        null,
                        null)
                };
                var revocationListExtension = new CrlDistPoint(crlDistributionPoints);
                s_certGenerator.AddExtension(X509Extensions.CrlDistributionPoints, false, revocationListExtension);
            }

            ISignatureFactory signatureFactory = new Asn1SignatureFactory(_signatureAlgorithm, _authorityKeyPair.Private, _random);
            X509Certificate   cert             = s_certGenerator.Generate(signatureFactory);

            switch (certificateCreationSettings.ValidityType)
            {
            case CertificateValidityType.Revoked:
                RevokeCertificateBySerialNumber(serialNum.ToString(radix: 16));
                break;

            case CertificateValidityType.Expired:
                break;

            default:
                EnsureCertificateIsValid(cert);
                break;
            }

            // For now, given that we don't know what format to return it in, preserve the formats so we have
            // the flexibility to do what we need to

            X509CertificateContainer container = new X509CertificateContainer();

            X509CertificateEntry[] chain = new X509CertificateEntry[1];
            chain[0] = new X509CertificateEntry(cert);

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry(
                certificateCreationSettings.FriendlyName != null ? certificateCreationSettings.FriendlyName : string.Empty,
                new AsymmetricKeyEntry(keyPair.Private),
                chain);

            using (MemoryStream stream = new MemoryStream())
            {
                store.Save(stream, _password.ToCharArray(), _random);
                container.Pfx = stream.ToArray();
            }

            X509Certificate2 outputCert;

            if (isAuthority)
            {
                // don't hand out the private key for the cert when it's the authority
                outputCert = new X509Certificate2(cert.GetEncoded());
            }
            else
            {
                // Otherwise, allow encode with the private key. note that X509Certificate2.RawData will not provide the private key
                // you will have to re-export this cert if needed
                outputCert = new X509Certificate2(container.Pfx, _password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
            }

            container.Subject             = subject;
            container.InternalCertificate = cert;
            container.Certificate         = outputCert;
            container.Thumbprint          = outputCert.Thumbprint;

            Trace.WriteLine("[CertificateGenerator] generated a certificate:");
            Trace.WriteLine(string.Format("    {0} = {1}", "isAuthority", isAuthority));
            if (!isAuthority)
            {
                Trace.WriteLine(string.Format("    {0} = {1}", "Signed by", signingCertificate.SubjectDN));
                Trace.WriteLine(string.Format("    {0} = {1}", "Subject (CN) ", subject));
                Trace.WriteLine(string.Format("    {0} = {1}", "Subject Alt names ", string.Join(", ", subjectAlternativeNames)));
                Trace.WriteLine(string.Format("    {0} = {1}", "Friendly Name ", certificateCreationSettings.FriendlyName));
            }
            Trace.WriteLine(string.Format("    {0} = {1}", "HasPrivateKey:", outputCert.HasPrivateKey));
            Trace.WriteLine(string.Format("    {0} = {1}", "Thumbprint", outputCert.Thumbprint));
            Trace.WriteLine(string.Format("    {0} = {1}", "CertificateValidityType", certificateCreationSettings.ValidityType));

            return(container);
        }
Beispiel #5
0
        public System.Security.Cryptography.X509Certificates.X509Certificate2 GenerateSelfSignedCertificate(string certificateName, List <string> subjectAlternateNames, string certificateFileName, string privateKeyFilePassword, string issuerName, AsymmetricKeyParameter issuerPrivKey, int keyStrength)
        {
            string subjectName = string.Format("CN={0}", certificateName);

            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

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

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var subjectDN = new X509Name(subjectName);

            // original code var issuerDN = issuerName;
            var issuerDN = new X509Name(issuerName);

            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

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

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

            KeyUsage keyUsage = new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment);

            certificateGenerator.AddExtension(X509Extensions.KeyUsage, true, keyUsage);

            // Add the “Extended Key Usage” attribute, specifying “server authentication”.
            var usages = new[] { KeyPurposeID.IdKPServerAuth };

            certificateGenerator.AddExtension(
                X509Extensions.ExtendedKeyUsage.Id,
                false,
                new ExtendedKeyUsage(usages));

            /* DNS Name=*.fullyqualified.domainname.com */
            if (subjectAlternateNames.Count <= 1)
            {
                /* the <=1 is for the simple reason of showing an alternate syntax .. */
                foreach (string subjectAlternateName in subjectAlternateNames)
                {
                    GeneralName  altName        = new GeneralName(GeneralName.DnsName, subjectAlternateName);
                    GeneralNames subjectAltName = new GeneralNames(altName);
                    certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltName);
                }
            }
            else
            {
                //Asn1Encodable[] ansiEncodeSubjectAlternativeNames = new Asn1Encodable[]
                // {
                // //new GeneralName(GeneralName.DnsName, “*.fullyqualified.domainname.com”),
                // new GeneralName(GeneralName.DnsName, “*.fullyqualified.domainname.com”)
                // };

                List <Asn1Encodable> asn1EncodableList = new List <Asn1Encodable>();
                foreach (string subjectAlternateName in subjectAlternateNames)
                {
                    asn1EncodableList.Add(new GeneralName(GeneralName.DnsName, subjectAlternateName));
                }

                DerSequence subjectAlternativeNamesExtension = new DerSequence(asn1EncodableList.ToArray());
                certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension);
            }

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

            // Generating the Certificate
            var issuerKeyPair = subjectKeyPair;

            // selfsign certificate
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);

            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);

            // correcponding private key
            PrivateKeyInfo pinfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            // merge into X509Certificate2
            var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

            var seq = (Asn1Sequence)Asn1Object.FromByteArray(pinfo.ParsePrivateKey().GetDerEncoded());

            if (seq.Count != 9)
            {
                throw new PemException("malformed sequence in RSA private key");
            }

            RsaPrivateKeyStructure     rsa       = RsaPrivateKeyStructure.GetInstance(seq);
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);

            File.WriteAllBytes(certificateFileName.Replace(".pfx", ".cer"), x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));

            // Export Certificate with private key
            File.WriteAllBytes(certificateFileName, x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, privateKeyFilePassword));

            return(x509);
        }
Beispiel #6
0
        private void overrideAttrsTest(AsymmetricKeyParameter privateKey, X509Certificate cert, IX509Store certs)
        {
            SignerInfoGeneratorBuilder signerInfoGenBuilder = new SignerInfoGeneratorBuilder();

            IssuerSerial issuerSerial = new IssuerSerial(
                new GeneralNames(
                    new GeneralName(
                        X509CertificateStructure.GetInstance(cert.GetEncoded()).Issuer)),
                new DerInteger(cert.SerialNumber));

            byte[] certHash256;
            byte[] certHash;

            {
                Asn1DigestFactory digCalc = Asn1DigestFactory.Get(OiwObjectIdentifiers.IdSha1);
                IStreamCalculator calc    = digCalc.CreateCalculator();
                using (Stream s = calc.Stream)
                {
                    byte[] crt = cert.GetEncoded();
                    s.Write(crt, 0, crt.Length);
                }

                certHash = ((SimpleBlockResult)calc.GetResult()).Collect();
            }


            {
                Asn1DigestFactory digCalc = Asn1DigestFactory.Get(NistObjectIdentifiers.IdSha256);
                IStreamCalculator calc    = digCalc.CreateCalculator();
                using (Stream s = calc.Stream)
                {
                    byte[] crt = cert.GetEncoded();
                    s.Write(crt, 0, crt.Length);
                }

                certHash256 = ((SimpleBlockResult)calc.GetResult()).Collect();
            }


            EssCertID   essCertid   = new EssCertID(certHash, issuerSerial);
            EssCertIDv2 essCertidV2 = new EssCertIDv2(certHash256, issuerSerial);

            signerInfoGenBuilder.WithSignedAttributeGenerator(new TestAttrGen()
            {
                EssCertID   = essCertid,
                EssCertIDv2 = essCertidV2
            });


            Asn1SignatureFactory sigfact = new Asn1SignatureFactory("SHA1WithRSA", privateKey);
            SignerInfoGenerator
                signerInfoGenerator = signerInfoGenBuilder.Build(sigfact, cert);

            TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(
                signerInfoGenerator,
                Asn1DigestFactory.Get(OiwObjectIdentifiers.IdSha1), new DerObjectIdentifier("1.2"), true);


            tsTokenGen.SetCertificates(certs);


            TimeStampRequestGenerator reqGen  = new TimeStampRequestGenerator();
            TimeStampRequest          request = reqGen.Generate(TspAlgorithms.Sha1, new byte[20], BigInteger.ValueOf(100));

            TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TspAlgorithms.Allowed);

            TimeStampResponse tsResp = tsRespGen.Generate(request, BigInteger.ValueOf(23), DateTime.UtcNow);

            tsResp = new TimeStampResponse(tsResp.GetEncoded());

            TimeStampToken tsToken = tsResp.TimeStampToken;

            tsToken.Validate(cert);

            Asn1.Cms.AttributeTable table = tsToken.SignedAttributes;

            Assert.NotNull(table[PkcsObjectIdentifiers.IdAASigningCertificate], "no signingCertificate attribute found");
            Assert.NotNull(table[PkcsObjectIdentifiers.IdAASigningCertificateV2], "no signingCertificateV2 attribute found");

            SigningCertificate sigCert = SigningCertificate.GetInstance(table[PkcsObjectIdentifiers.IdAASigningCertificate].AttrValues[0]);

            Assert.IsTrue(cert.CertificateStructure.Issuer.Equals(sigCert.GetCerts()[0].IssuerSerial.Issuer.GetNames()[0].Name));
            Assert.IsTrue(cert.CertificateStructure.SerialNumber.Value.Equals(sigCert.GetCerts()[0].IssuerSerial.Serial.Value));
            Assert.IsTrue(Arrays.AreEqual(certHash, sigCert.GetCerts()[0].GetCertHash()));

            SigningCertificate sigCertV2 = SigningCertificate.GetInstance(table[PkcsObjectIdentifiers.IdAASigningCertificateV2].AttrValues[0]);

            Assert.IsTrue(cert.CertificateStructure.Issuer.Equals(sigCertV2.GetCerts()[0].IssuerSerial.Issuer.GetNames()[0].Name));
            Assert.IsTrue(cert.CertificateStructure.SerialNumber.Value.Equals(sigCertV2.GetCerts()[0].IssuerSerial.Serial.Value));
            Assert.IsTrue(Arrays.AreEqual(certHash256, sigCertV2.GetCerts()[0].GetCertHash()));
        }
Beispiel #7
0
        protected override void CompleteWizard()
        {
            // Generate the CSR
            X509Name subjectName;

            try
            {
                subjectName = new X509Name(string.Format("C={0},ST={1},L={2},O={3},OU={4},CN={5}",
                                                         _wizardData.Country,
                                                         _wizardData.State,
                                                         _wizardData.City,
                                                         _wizardData.Organization,
                                                         _wizardData.Unit,
                                                         _wizardData.CommonName));
            }
            catch (ArgumentException ex)
            {
                ShowError(ex, Text, false);
                return;
            }

            // Generate the private/public keypair
            RsaKeyPairGenerator      kpgen           = new RsaKeyPairGenerator();
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();

            kpgen.Init(new KeyGenerationParameters(new SecureRandom(randomGenerator), _wizardData.Length));
            AsymmetricCipherKeyPair keyPair = kpgen.GenerateKeyPair();
            // Generate the CSR

            Asn1Set attributes = new DerSet(
                new DerSequence(
                    new DerObjectIdentifier("1.3.6.1.4.1.311.13.2.3"),
                    new DerSet(new DerIA5String(Environment.OSVersion.Version.ToString()))),
                new DerSequence(
                    new DerObjectIdentifier("1.3.6.1.4.1.311.21.20"),
                    new DerSet(
                        new DerSequence(
                            new DerInteger(5),
                            new DerUtf8String(Environment.MachineName),
                            new DerUtf8String(Environment.UserName),
                            new DerUtf8String("JexusManager.exe")))),
                new DerSequence(
                    new DerObjectIdentifier("1.3.6.1.4.1.311.13.2.2"),
                    new DerSet(
                        new DerSequence(
                            new DerInteger(1),
                            new DerBmpString("Microsoft RSA SChannel Cryptographic Provider"),
                            new DerBitString(new byte[0])))),
                new DerSequence(
                    new DerObjectIdentifier("1.2.840.113549.1.9.14"),
                    new DerSet(
                        new DerSequence(
                            new DerSequence(
                                new DerObjectIdentifier("2.5.29.15"),
                                new DerBoolean(new byte[] { 0x01 }),
                                new DerOctetString(new byte[] { 0x03, 0x02, 0x04, 0xF0 })),
                            new DerSequence(
                                new DerObjectIdentifier("2.5.29.37"),
                                new DerOctetString(new byte[]
            {
                0x30, 0x0a, 0x06, 0x08,
                0x2b, 0x06, 0x01, 0x05,
                0x05, 0x07, 0x03, 0x01
            })),
                            new DerSequence(
                                new DerObjectIdentifier("1.2.840.113549.1.9.15"),
                                new DerOctetString(new byte[]
            {
                0x30, 0x69, 0x30, 0x0e,
                0x06, 0x08, 0x2a, 0x86,
                0x48, 0x86, 0xf7, 0x0d,
                0x03, 0x02, 0x02, 0x02,
                0x00, 0x80, 0x30, 0x0e,
                0x06, 0x08, 0x2a, 0x86,
                0x48, 0x86, 0xf7, 0x0d,
                0x03, 0x04, 0x02, 0x02,
                0x00, 0x80, 0x30, 0x0b,
                0x06, 0x09, 0x60, 0x86,
                0x48, 0x01, 0x65, 0x03,
                0x04, 0x01, 0x2a, 0x30,
                0x0b, 0x06, 0x09, 0x60,
                0x86, 0x48, 0x01, 0x65,
                0x03, 0x04, 0x01, 0x2d,
                0x30, 0x0b, 0x06, 0x09,
                0x60, 0x86, 0x48, 0x01,
                0x65, 0x03, 0x04, 0x01,
                0x02, 0x30, 0x0b, 0x06,
                0x09, 0x60, 0x86, 0x48,
                0x01, 0x65, 0x03, 0x04,
                0x01, 0x05, 0x30, 0x07,
                0x06, 0x05, 0x2b, 0x0e,
                0x03, 0x02, 0x07, 0x30,
                0x0a, 0x06, 0x08, 0x2a,
                0x86, 0x48, 0x86, 0xf7,
                0x0d, 0x03, 0x07
            })),
                            new DerSequence(
                                new DerObjectIdentifier("2.5.29.14"),
                                new DerOctetString(new byte[]
            {
                0x04, 0x14, 0xaa, 0x25,
                0xd9, 0xa2, 0x39, 0x7e,
                0x49, 0xd2, 0x94, 0x85,
                0x7e, 0x82, 0xa8, 0x8f,
                0x3b, 0x20, 0xf1, 0x4e, 0x65, 0xe5
            }))))));

            var signing = new Asn1SignatureFactory("SHA256withRSA", keyPair.Private);
            Pkcs10CertificationRequest kpGen = new Pkcs10CertificationRequest(signing, subjectName, keyPair.Public, attributes);

            using (var stream = new StreamWriter(_wizardData.FileName))
            {
                stream.WriteLine(_wizardData.UseIisStyle ? "-----BEGIN NEW CERTIFICATE REQUEST-----" : "-----BEGIN CERTIFICATE REQUEST-----");
                stream.WriteLine(Convert.ToBase64String(kpGen.GetDerEncoded(), Base64FormattingOptions.InsertLineBreaks));
                stream.WriteLine(_wizardData.UseIisStyle ? "-----END NEW CERTIFICATE REQUEST-----" : "-----END CERTIFICATE REQUEST-----");
            }

            var        key = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair.Private);
            PrivateKey pvk = new PrivateKey();

            pvk.RSA = new RSACryptoServiceProvider();
            pvk.RSA.ImportParameters(key);

            var file   = DialogHelper.GetPrivateKeyFile(subjectName.ToString());
            var folder = Path.GetDirectoryName(file);

            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }

            pvk.Save(file);
        }
Beispiel #8
0
        public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, int keyStrength)
        {
            try
            {
                // Generating Random Numbers
                var randomGenerator = new VmpcRandomGenerator();
                var random          = new SecureRandom(randomGenerator);

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

                // Serial Number
                var serialNumber = BigInteger.ProbablePrime(128, new Random());
                certificateGenerator.SetSerialNumber(serialNumber);

                // Issuer and Subject Name
                var subjectDN = new X509Name(subjectName);
                var issuerDN  = new X509Name(issuerName);
                certificateGenerator.SetIssuerDN(issuerDN);
                certificateGenerator.SetSubjectDN(subjectDN);

                // Valid For
                var notBefore = DateTime.UtcNow.Date.AddYears(-1);
                var notAfter  = notBefore.AddYears(10);
                certificateGenerator.SetNotBefore(notBefore);
                certificateGenerator.SetNotAfter(notAfter);

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

                if (userKeyPair == null)
                {
                    userKeyPair = keyPairGenerator.GenerateKeyPair();
                }

                certificateGenerator.SetPublicKey(userKeyPair.Public);

                //Extented
                certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false,
                                                  new SubjectKeyIdentifierStructure(userKeyPair.Public));
                certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false,
                                                  new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory
                                                                             .CreateSubjectPublicKeyInfo(userKeyPair.Public)));
                var valueData = Encoding.ASCII.GetBytes("Client");
                certificateGenerator.AddExtension("1.3.6.1.5.5.7.13.3", false, valueData);

                // Generating the Certificate
                var issuerKeyPair = userKeyPair;

                // Signature Algorithm
                ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", userKeyPair.Private, random);

                // selfsign certificate
                var certificate = certificateGenerator.Generate(signatureFactory);

                // correcponding private key
                var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(userKeyPair.Private);

                // merge into X509Certificate2
                var x509 = new X509Certificate2(certificate.GetEncoded());

                var seq = (Asn1Sequence)info.ParsePrivateKey();
                if (seq.Count != 9)
                {
                    throw new Exception("malformed sequence in RSA private key");
                }

                var rsa       = RsaPrivateKeyStructure.GetInstance(seq);
                var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent,
                                                               rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2,
                                                               rsa.Coefficient);
                x509 = x509.CopyWithPrivateKey(PemUtilsHelper.ToRSA(rsaparams));
                return(x509);
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"The Method \"{nameof(GenerateSelfSignedCertificate)}\" has failed.");
                return(null);
            }
        }
Beispiel #9
0
        public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey)
        {
            const int keyStrength = 2048;

            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom             random          = new SecureRandom(randomGenerator);

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

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Signature Algorithm
            //const string signatureAlgorithm = "SHA256WithRSA";
            //certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

            // Issuer and Subject Name
            X509Name subjectDN = new X509Name(subjectName);
            X509Name issuerDN  = new X509Name(issuerName);

            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

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

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

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

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

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Generating the Certificate
            AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

            // selfsign certificate
            //Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerPrivKey, random);
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random);

            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);



            // correcponding private key
            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);


            // merge into X509Certificate2
            X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

            Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());

            if (seq.Count != 9)
            {
                //throw new PemException("malformed sequence in RSA private key");
            }

            RsaPrivateKeyStructure     rsa       = new RsaPrivateKeyStructure(seq);
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            //x509.PrivateKey = ToDotNetKey(rsaparams);
            x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
            return(x509);
        }
Beispiel #10
0
        private async Task ProcessCsrGeneration(ThingToGenerate toGenerate)
        {
            SetStatusAndProgress("Generating...");
            var(keyGenerator, signerFactoryFactory) = await CsrGetKeyGeneratorAsync();

            var lines = txtCsrDomains.Text
                        .Split('\r')
                        .Select(x => x.Trim())
                        .Where(x => !string.IsNullOrEmpty(x))
                        .Select(x => x.Split(';', ',').Select(y => y.Trim()).Where(y => !string.IsNullOrEmpty(y)).ToArray())
                        .Where(x => x.Length >= 1)
                        .ToArray();

            string dnO     = txtCsrSubjO.Text.Trim();
            string dnOU    = txtCsrSubjOU.Text.Trim();
            string dnC     = txtCsrSubjC.Text.Trim();
            string dnST    = txtCsrSubjST.Text.Trim();
            string dnL     = txtCsrSubjL.Text.Trim();
            string dnEmail = txtCsrSubjEmail.Text.Trim();

            var dnOrdering = new List <DerObjectIdentifier>();
            var dnValues   = new List <string>();

            dnOrdering.Add(X509Name.CN);
            dnValues.Add("<placeholder>");
            if (!string.IsNullOrEmpty(dnO))
            {
                dnOrdering.Add(X509Name.O); dnValues.Add(dnO);
            }
            if (!string.IsNullOrEmpty(dnOU))
            {
                dnOrdering.Add(X509Name.OU); dnValues.Add(dnOU);
            }
            if (!string.IsNullOrEmpty(dnC))
            {
                dnOrdering.Add(X509Name.C); dnValues.Add(dnC);
            }
            if (!string.IsNullOrEmpty(dnST))
            {
                dnOrdering.Add(X509Name.ST); dnValues.Add(dnST);
            }
            if (!string.IsNullOrEmpty(dnL))
            {
                dnOrdering.Add(X509Name.L); dnValues.Add(dnL);
            }
            if (!string.IsNullOrEmpty(dnEmail))
            {
                dnOrdering.Add(X509Name.EmailAddress); dnValues.Add(dnEmail);
            }

            int cnt = 0;

            foreach (var line in lines)
            {
                SetStatusAndProgress("Generating...", (double)cnt++ / lines.Length);

                string   cn       = line[0];
                string[] altnames = line;

                var dnValuesThese = dnValues.ToArray();
                dnValuesThese[0] = cn;

                var keyPath = Path.Combine(CurrentWorkingDirectory, FixFilename($"{cn}.key"));
                AsymmetricCipherKeyPair key = null;
                if (rdCsrUseExistingKey.Checked && File.Exists(keyPath))
                {
                    try
                    {
                        PemReader pr = new PemReader(File.OpenText(keyPath));
                        key = pr.ReadObject() as AsymmetricCipherKeyPair;
                    }
                    catch { key = null; }
                }

                if (key == null)
                {
                    key = await Task.Factory.StartNew(() => keyGenerator.GenerateKeyPair());

                    WriteToPemFile(keyPath, key);
                }

                X509Name subject = new X509Name(dnOrdering, dnValuesThese);


                if ((toGenerate | ThingToGenerate.Csr) == ThingToGenerate.Csr)
                {
                    X509ExtensionsGenerator extGenerator = GetExtensionsGenerator(altnames);

                    var     exts  = extGenerator.Generate();
                    Asn1Set attrs = new DerSet(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(exts)));

                    var req = new Pkcs10CertificationRequest(
                        signerFactoryFactory(key.Private),
                        subject,
                        key.Public,
                        attrs,
                        key.Private);

                    if (!req.Verify())
                    {
                        throw new InvalidOperationException("Generated an invalid CSR.");
                    }
                    WriteToPemFile(Path.Combine(CurrentWorkingDirectory, FixFilename($"{cn}.csr")), req);
                }
                if ((toGenerate | ThingToGenerate.SelfSignedCert) == ThingToGenerate.SelfSignedCert)
                {
                    SecureRandom sr = new SecureRandom();
                    X509V3CertificateGenerator certgen = new X509V3CertificateGenerator();

                    certgen.SetSerialNumber(new BigInteger(128, sr));
                    certgen.SetIssuerDN(subject);
                    certgen.SetSubjectDN(subject);
                    certgen.SetNotBefore(DateTime.Today.Subtract(new TimeSpan(1, 0, 0, 0)));
                    certgen.SetNotAfter(DateTime.Today.AddYears(30));
                    certgen.SetPublicKey(key.Public);

                    foreach (var ext in GetExtensions(altnames))
                    {
                        certgen.AddExtension(ext.oid, ext.isCritical, ext.section);
                    }

                    ISignatureFactory signer;
                    if (key.Private is ECPrivateKeyParameters)
                    {
                        signer = new Asn1SignatureFactory("SHA256WITHECDSA", key.Private, sr);
                    }
                    else
                    {
                        signer = new Asn1SignatureFactory("SHA256WITHRSA", key.Private, sr);
                    }

                    var cert = certgen.Generate(signer);
                    cert.CheckValidity();
                    cert.Verify(key.Public);
                    WriteToPemFile(Path.Combine(CurrentWorkingDirectory, FixFilename($"{cn}.cer")), cert);
                }
            }

            SetStatusAndProgress("Generating CSRs", 1);
        }
        /// <summary>
        ///     Generates the certificate.
        /// </summary>
        /// <param name="subjectName">Name of the subject.</param>
        /// <param name="issuerName">Name of the issuer.</param>
        /// <param name="validFrom">The valid from.</param>
        /// <param name="validTo">The valid to.</param>
        /// <param name="keyStrength">The key strength.</param>
        /// <param name="signatureAlgorithm">The signature algorithm.</param>
        /// <param name="issuerPrivateKey">The issuer private key.</param>
        /// <param name="hostName">The host name</param>
        /// <returns>X509Certificate2 instance.</returns>
        /// <exception cref="PemException">Malformed sequence in RSA private key</exception>
        private static X509Certificate2 GenerateCertificate(string hostName,
                                                            string subjectName,
                                                            string issuerName, DateTime validFrom,
                                                            DateTime validTo, int keyStrength       = 2048,
                                                            string signatureAlgorithm               = "SHA256WithRSA",
                                                            AsymmetricKeyParameter issuerPrivateKey = null)
        {
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var secureRandom    = new SecureRandom(randomGenerator);

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

            // Serial Number
            var serialNumber =
                BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), secureRandom);

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var subjectDn = new X509Name(subjectName);
            var issuerDn  = new X509Name(issuerName);

            certificateGenerator.SetIssuerDN(issuerDn);
            certificateGenerator.SetSubjectDN(subjectDn);

            certificateGenerator.SetNotBefore(validFrom);
            certificateGenerator.SetNotAfter(validTo);

            if (hostName != null)
            {
                // add subject alternative names
                var subjectAlternativeNames = new Asn1Encodable[] { new GeneralName(GeneralName.DnsName, hostName) };

                var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames);
                certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false,
                                                  subjectAlternativeNamesExtension);
            }

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

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

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Set certificate intended purposes to only Server Authentication
            certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false,
                                              new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
            if (issuerPrivateKey == null)
            {
                certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(true));
            }

            var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm,
                                                            issuerPrivateKey ?? subjectKeyPair.Private, secureRandom);

            // Self-sign the certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            // Corresponding private key
            var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            var seq = (Asn1Sequence)Asn1Object.FromByteArray(privateKeyInfo.ParsePrivateKey().GetDerEncoded());

            if (seq.Count != 9)
            {
                throw new PemException("Malformed sequence in RSA private key");
            }

            var rsa       = RsaPrivateKeyStructure.GetInstance(seq);
            var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent,
                                                           rsa.Prime1, rsa.Prime2, rsa.Exponent1,
                                                           rsa.Exponent2, rsa.Coefficient);

#if NET45
            // Set private key onto certificate instance
            var x509Certificate = new X509Certificate2(certificate.GetEncoded());
            x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
#else
            var x509Certificate = WithPrivateKey(certificate, rsaparams);
            x509Certificate.FriendlyName = subjectName;
#endif

            if (!doNotSetFriendlyName)
            {
                try
                {
                    x509Certificate.FriendlyName = ProxyConstants.CNRemoverRegex.Replace(subjectName, string.Empty);
                }
                catch (PlatformNotSupportedException)
                {
                    doNotSetFriendlyName = true;
                }
            }

            return(x509Certificate);
        }
Beispiel #12
0
        public X509Certificate Generate(AsymmetricKeyParameter privateKey)
        {
            ISignatureFactory signatureFactory = new Asn1SignatureFactory(_signatureAlgorithm, privateKey, _random);

            return(_certificateGenerator.Generate(signatureFactory));
        }
Beispiel #13
0
        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),
                SigAlgID             = AlgorithmIdentifier.GetInstance(sigAlgBytes),
                SubjectPublicKeyInfo = subjectPubKeyInfo
            };

            return(cert, addedTo);
        }
Beispiel #14
0
        public static void Write(string name, string connectionString)
        {
            if (string.IsNullOrEmpty(connectionString))
            {
                throw new ArgumentException("Token not found in X509Store and no new token provided!");
            }

            SecureRandom            random = new SecureRandom();
            KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, 2048);
            RsaKeyPairGenerator     keyPairGenerator        = new RsaKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);
            AsymmetricCipherKeyPair keys = keyPairGenerator.GenerateKeyPair();

            ArrayList nameOids = new ArrayList();

            nameOids.Add(X509Name.CN);
            ArrayList nameValues = new ArrayList();

            nameValues.Add(name);
            X509Name subjectDN = new X509Name(nameOids, nameValues);
            X509Name issuerDN  = subjectDN;

            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();

            cg.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random));
            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);
            cg.SetNotBefore(DateTime.Now);
            cg.SetNotAfter(DateTime.Now.AddMonths(12));
            cg.SetPublicKey(keys.Public);

            // encrypt the token with the public key so only the owner of the assoc. private key can decrypt it and
            // "hide" it in the instruction code cert extension
            RSA              rsa       = RSA.Create();
            RSAParameters    rsaParams = new RSAParameters();
            RsaKeyParameters keyParams = (RsaKeyParameters)keys.Public;

            rsaParams.Modulus = new byte[keyParams.Modulus.ToByteArrayUnsigned().Length];
            keyParams.Modulus.ToByteArrayUnsigned().CopyTo(rsaParams.Modulus, 0);

            rsaParams.Exponent = new byte[keyParams.Exponent.ToByteArrayUnsigned().Length];
            keyParams.Exponent.ToByteArrayUnsigned().CopyTo(rsaParams.Exponent, 0);

            rsa.ImportParameters(rsaParams);
            if (rsa != null)
            {
                byte[] bytes = rsa.Encrypt(Encoding.ASCII.GetBytes(connectionString), RSAEncryptionPadding.OaepSHA1);
                if (bytes != null)
                {
                    cg.AddExtension(X509Extensions.InstructionCode, false, bytes);
                }
                else
                {
                    rsa.Dispose();
                    throw new CryptographicException("Could not encrypt IoTHub security token using generated public key!");
                }
            }
            rsa.Dispose();

            // sign the cert with the private key
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keys.Private, random);

            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create a PKCS12 store for the cert and its private key
            X509Certificate2 certificate = null;

            using (MemoryStream pfxData = new MemoryStream())
            {
                Pkcs12Store            pkcsStore = new Pkcs12StoreBuilder().Build();
                X509CertificateEntry[] chain     = new X509CertificateEntry[1];
                string passcode = "passcode";
                chain[0] = new X509CertificateEntry(x509);
                pkcsStore.SetKeyEntry(name, new AsymmetricKeyEntry(keys.Private), chain);
                pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

                // create X509Certificate2 object from PKCS12 file
                certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode);

                // Add to X509Store
                using (X509Store store = new X509Store("IoTHub", StoreLocation.CurrentUser))
                {
                    store.Open(OpenFlags.ReadWrite);

                    // remove any existing cert with our name from the store
                    foreach (X509Certificate2 cert in store.Certificates)
                    {
                        if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase))
                        {
                            store.Remove(cert);
                        }
                    }

                    // add new one
                    store.Add(certificate);
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// 生成自签名证书
        /// </summary>
        /// <param name="subjectName"></param>
        /// <param name="issuerName"></param>
        /// <param name="issuerPrivKey"></param>
        /// <param name="keyStrength"></param>
        /// <returns></returns>
        public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey, int keyStrength = 2048)
        {
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

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

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var subjectDN = new X509Name(subjectName);
            var issuerDN  = new X509Name(issuerName);

            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

            // Valid For
            var notBefore = DateTime.UtcNow.Date;
            var 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);

            // Generating the Certificate
            // var issuerKeyPair = subjectKeyPair;

            // https://stackoverflow.com/questions/60547020/c-sharp-generate-intermediate-certificate-from-self-signed-root-ca
            ISignatureFactory signatureFactory = new Asn1SignatureFactory(PkcsObjectIdentifiers.Sha256WithRsaEncryption.ToString(), issuerPrivKey, random);
            // ISignatureFactory signatureFactory = new Asn1SignatureFactory(PkcsObjectIdentifiers.Sha256WithRsaEncryption.ToString(), issuerKeyPair.Private, random);

            // selfsign certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            // Corresponding private key
            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);


            // Merge into X509Certificate2
            var x509 = new X509Certificate2(certificate.GetEncoded());

            Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());

            if (seq.Count != 9)
            {
                throw new PemException("malformed sequence in RSA private key");
            }

            RsaPrivateKeyStructure     rsa       = RsaPrivateKeyStructure.GetInstance(seq);
            RsaPrivateCrtKeyParameters rsaParams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            // https://github.com/bcgit/bc-csharp/issues/160
            // https://stackoverflow.com/questions/54752834/error-setting-x509certificate2-privatekey
            // x509.PrivateKey = DotNetUtilities.ToRSA(rsaParams);
            // return x509;
            // [DotNetUtilities class only works on Windows](https://github.com/bcgit/bc-csharp/issues/160)
            // if run on Linux will cause 'CspParameters' requires Windows Cryptographic API (CAPI), which is not available on this platform.
            // var cert = x509.CopyWithPrivateKey(DotNetUtilities.ToRSA(rsaParams));
            var parms     = DotNetUtilities.ToRSAParameters(rsaParams);
            var rsaCreate = RSA.Create();

            rsaCreate.ImportParameters(parms);
            var cert = x509.CopyWithPrivateKey(rsaCreate);

            return(cert);
        }
Beispiel #16
0
        public static X509Certificate2 CreateSelfSignedCert(string subjectName, string issuerName,
                                                            AsymmetricKeyParameter privateKey)
        {
            const int keyStrength = DEFAULT_KEY_SIZE;

            if (privateKey == null)
            {
                privateKey = CreatePrivateKeyResource(issuerName);
            }

            var issuerPrivKey = privateKey;

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

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

            certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false,
                                              new GeneralNames(new GeneralName[]
            {
                new GeneralName(GeneralName.DnsName, "localhost"), new GeneralName(GeneralName.DnsName, "127.0.0.1")
            }));
            certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                              new ExtendedKeyUsage(new List <DerObjectIdentifier>()
            {
                new DerObjectIdentifier("1.3.6.1.5.5.7.3.1")
            }));

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var subjectDn = new X509Name(subjectName);
            var issuerDn  = new X509Name(issuerName);

            certificateGenerator.SetIssuerDN(issuerDn);
            certificateGenerator.SetSubjectDN(subjectDn);

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

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

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

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

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // self sign certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            // Originally pre-processor defines were used to try and pick the supported way to get from a Bouncy Castle
            // certificate and private key to a .NET certificate. The problem is that setting the private key on a .NET
            // X509 certificate is possible in .NET Framework but NOT in .NET Core. To complicate matters even further
            // the workaround in the CovertBouncyCert method of saving a cert + pvt key to a .pfx stream and then
            // reloading does not work on macOS or Unity (and possibly elsewhere) due to .pfx serialisation not being
            // compatible. This is the exception from Unity:
            //
            // Mono.Security.ASN1..ctor (System.Byte[] data) (at <6a66fe237d4242c9924192d3c28dd540>:0)
            // Mono.Security.X509.X509Certificate.Parse(System.Byte[] data)(at < 6a66fe237d4242c9924192d3c28dd540 >:0)
            //
            // Summary:
            // .NET Framework (including Mono on Linux, macOS and WSL)
            //  - Set x509.PrivateKey works.
            // .NET Standard:
            //  - Set x509.PrivateKey for a .NET Framework application.
            //  - Set x509.PrivateKey for a .NET Core application FAILS.
            // .NET Core:
            //  - Set x509.PrivateKey for a .NET Core application FAILS.
            //  - PFX serialisation works on Windows.
            //  - PFX serialisation works on WSL and Linux.
            //  - PFX serialisation FAILS on macOS.
            //
            // For same issue see https://github.com/dotnet/runtime/issues/23635.
            // For fix in net5 see https://github.com/dotnet/corefx/pull/42226.
            try
            {
                // corresponding private key
                var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

                // merge into X509Certificate2
                var x509 = new X509Certificate2(certificate.GetEncoded());

                var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());
                if (seq.Count != 9)
                {
                    throw new PemException("malformed sequence in RSA private key");
                }

                var rsa       = RsaPrivateKeyStructure.GetInstance(seq); //new RsaPrivateKeyStructure(seq);
                var rsaparams = new RsaPrivateCrtKeyParameters(
                    rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1,
                    rsa.Exponent2, rsa.Coefficient);

                x509.PrivateKey = ToRSA(rsaparams);
                return(x509);
            }
            catch
            {
                return(ConvertBouncyCert(certificate, subjectKeyPair));
            }
        }
Beispiel #17
0
        /// <summary>
        ///   Create a X509 certificate for the specified key.
        /// </summary>
        /// <param name="keyName">
        ///   The key name.
        /// </param>
        /// <param name="cancel"></param>
        /// <returns></returns>
        public async Task <X509Certificate> CreateBCCertificateAsync(
            string keyName,
            CancellationToken cancel = default(CancellationToken))
        {
            // Get the BC key pair for the named key.
            var ekey = await Store.TryGetAsync(keyName, cancel);

            if (ekey == null)
            {
                throw new KeyNotFoundException($"The key '{keyName}' does not exist.");
            }
            AsymmetricCipherKeyPair kp = null;

            UseEncryptedKey(ekey, key =>
            {
                kp = this.GetKeyPairFromPrivateKey(key);
            });

            // A signer for the key.
            var ku = new KeyUsage(KeyUsage.DigitalSignature
                                  | KeyUsage.DataEncipherment
                                  | KeyUsage.KeyEncipherment);
            ISignatureFactory signatureFactory = null;

            if (kp.Private is ECPrivateKeyParameters)
            {
                signatureFactory = new Asn1SignatureFactory(
                    X9ObjectIdentifiers.ECDsaWithSha256.ToString(),
                    kp.Private);
            }
            else if (kp.Private is RsaPrivateCrtKeyParameters)
            {
                signatureFactory = new Asn1SignatureFactory(
                    PkcsObjectIdentifiers.Sha256WithRsaEncryption.ToString(),
                    kp.Private);
            }
            else if (kp.Private is Ed25519PrivateKeyParameters)
            {
                signatureFactory = new Asn1SignatureFactory(
                    EdECObjectIdentifiers.id_Ed25519.Id.ToString(),
                    kp.Private);
                ku = new KeyUsage(KeyUsage.DigitalSignature);
            }
            if (signatureFactory == null)
            {
                throw new NotSupportedException($"The key type {kp.Private.GetType().Name} is not supported.");
            }

            // Build the certificate.
            var dn  = new X509Name($"CN={ekey.Id}, OU=keystore, O=ipfs");
            var ski = new SubjectKeyIdentifier(Base58.Decode(ekey.Id));
            // Not a certificate authority.
            // TODO: perhaps the "self" key is a CA and all other keys issued by it.
            var bc = new BasicConstraints(false);

            var certGenerator = new X509V3CertificateGenerator();

            certGenerator.SetIssuerDN(dn);
            certGenerator.SetSubjectDN(dn);
            certGenerator.SetSerialNumber(BigInteger.ValueOf(1));
            certGenerator.SetNotAfter(DateTime.UtcNow.AddYears(10));
            certGenerator.SetNotBefore(DateTime.UtcNow);
            certGenerator.SetPublicKey(kp.Public);
            certGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, ski);
            certGenerator.AddExtension(X509Extensions.BasicConstraints, true, bc);
            certGenerator.AddExtension(X509Extensions.KeyUsage, false, ku);

            return(certGenerator.Generate(signatureFactory));
        }
Beispiel #18
0
        public static (Certificate crtificate, AsymmetricKeyParameter privateKey) CreateSelfSignedTlsCert(
            string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivateKey)
        {
            const int keyStrength = DEFAULT_KEY_SIZE;

            if (issuerPrivateKey == null)
            {
                issuerPrivateKey = CreatePrivateKeyResource(issuerName);
            }

            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", issuerPrivateKey, random);

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

            certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false,
                                              new GeneralNames(new GeneralName[]
            {
                new GeneralName(GeneralName.DnsName, "localhost"), new GeneralName(GeneralName.DnsName, "127.0.0.1")
            }));
            certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                              new ExtendedKeyUsage(new List <DerObjectIdentifier>()
            {
                new DerObjectIdentifier("1.3.6.1.5.5.7.3.1")
            }));

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var subjectDn = new X509Name(subjectName);
            var issuerDn  = new X509Name(issuerName);

            certificateGenerator.SetIssuerDN(issuerDn);
            certificateGenerator.SetSubjectDN(subjectDn);

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

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

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

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

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // self sign certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            var chain          = new X509CertificateStructure[] { X509CertificateStructure.GetInstance(certificate.GetEncoded()) };
            var tlsCertificate = new Certificate(chain);

            return(tlsCertificate, subjectKeyPair.Private);
        }
Beispiel #19
0
        public X509Certificate2 GenerateSelfSignedCertificate(string friendlyName, ArrayList listOidSubject, ArrayList listValuesSubject, ArrayList listOidIssuer, ArrayList listValuesIssuer, int keyStrength = 2048)
        {
            AsymmetricKeyParameter issuerPrivKey = GenerateCaCertificate(listOidIssuer, listValuesIssuer);
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

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

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Signature Algorithm
            const string signatureAlgorithm = "SHA256WithRSA";
            //certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

            // Issuer and Subject Name
            var subjectDn = new X509Name(listOidSubject, listValuesSubject);
            var issuerDn  = new X509Name(listOidIssuer, listValuesIssuer);

            certificateGenerator.SetIssuerDN(issuerDn);
            certificateGenerator.SetSubjectDN(subjectDn);

            // Valid For
            var notBefore = DateTime.UtcNow.Date;
            var 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
            ISignatureFactory signatureCalculatorFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivKey, random);
            var certificate = certificateGenerator.Generate(signatureCalculatorFactory);

            // correcponding private key
            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);


            // merge into X509Certificate2
            var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

            var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());

            if (seq.Count != 9)
            {
                throw new PemException("malformed sequence in RSA private key");
            }

            var rsa       = RsaPrivateKeyStructure.GetInstance(seq);
            var rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            x509.PrivateKey   = DotNetUtilities.ToRSA(rsaparams);
            x509.FriendlyName = friendlyName;

            return(x509);
        }
Beispiel #20
0
        // Note: Much of this code comes from https://stackoverflow.com/a/22247129
        private static X509Certificate2 GenerateSelfSignedCertificate(string subject)
        {
            const int keyStrength = 2048;

            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

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

            // Serial Number
            certificateGenerator.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random));

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

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

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Subject DN
            certificateGenerator.SetSubjectDN(new X509Name("CN=" + subject));

            // Subject Alternative Name
            var subjectAlternativeNames = new List <Asn1Encodable>()
            {
                new GeneralName(GeneralName.DnsName, Environment.MachineName),
                new GeneralName(GeneralName.DnsName, "localhost"),
                new GeneralName(GeneralName.IPAddress, "127.0.0.1"),
            };

            if (subject != "localhost" && subject != Environment.MachineName)
            {
                subjectAlternativeNames.Add(new GeneralName(GeneralName.DnsName, subject));
            }

            certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, new DerSequence(subjectAlternativeNames.ToArray()));

            // Issuer
            certificateGenerator.SetIssuerDN(new X509Name("CN=" + subject));
            certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public)));

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

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

            // Add basic constraint
            certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(false));

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

            // Signature Algorithm
            const string signatureAlgorithm = "SHA256WithRSA";
            var          signatureFactory   = new Asn1SignatureFactory(signatureAlgorithm, subjectKeyPair.Private);

            // selfsign certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            // correcponding private key
            var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            // merge into X509Certificate2
            var x509 = new X509Certificate2(certificate.GetEncoded());
            var seq  = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());

            if (seq.Count != 9)
            {
                // throw new PemException("malformed sequence in RSA private key");
            }

            var rsa       = RsaPrivateKeyStructure.GetInstance(seq);
            var rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            try
            {
                x509.PrivateKey = ToDotNetKey(rsaparams); // x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
            }
            catch (CryptographicException e)
            {
                throw new Exception($"Exception on cert generation!\nSubject {subject}\nHostname {Environment.MachineName}\nSequenceCount {seq.Count} (should be 9?)", e);
            }

            return(x509);
        }
Beispiel #21
0
        /// <summary>
        /// Creates a self signed application instance certificate.
        /// </summary>
        /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param>
        /// <param name="storePath">The store path (syntax depends on storeType).</param>
        /// <param name="password">The password to use to protect the certificate.</param>
        /// <param name="applicationUri">The application uri (created if not specified).</param>
        /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param>
        /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param>
        /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param>
        /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param>
        /// <param name="startTime">The start time.</param>
        /// <param name="lifetimeInMonths">The lifetime of the key in months.</param>
        /// <param name="hashSizeInBits">The hash size in bits.</param>
        /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param>
        /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param>
        /// <returns>The certificate with a private key.</returns>
        public static X509Certificate2 CreateCertificate(
            string storeType,
            string storePath,
            string password,
            string applicationUri,
            string applicationName,
            string subjectName,
            IList <String> domainNames,
            ushort keySize,
            DateTime startTime,
            ushort lifetimeInMonths,
            ushort hashSizeInBits,
            bool isCA,
            X509Certificate2 issuerCAKeyCert)
        {
            if (issuerCAKeyCert != null)
            {
                if (!issuerCAKeyCert.HasPrivateKey)
                {
                    throw new NotSupportedException("Cannot sign with a CA certificate without a private key.");
                }

                throw new NotSupportedException("Signing with an issuer CA certificate is currently unsupported.");
            }

            // set default values.
            SetSuitableDefaults(
                ref applicationUri,
                ref applicationName,
                ref subjectName,
                ref domainNames,
                ref keySize,
                ref lifetimeInMonths,
                isCA);

            // cert generators
            SecureRandom random           = new SecureRandom();
            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();

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

            cg.SetSerialNumber(serialNumber);

            // build name attributes
            var nameOids = new ArrayList();

            nameOids.Add(X509Name.DC);
            nameOids.Add(X509Name.CN);

            var nameValues = new ArrayList();

            nameValues.Add(domainNames[0]);
            nameValues.Add(subjectName);

            // self signed
            X509Name subjectDN = new X509Name(nameOids, nameValues);
            X509Name issuerDN  = subjectDN;

            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);

            // valid for
            cg.SetNotBefore(startTime);
            cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths));

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

            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            cg.SetPublicKey(subjectKeyPair.Public);

            // add extensions
            // Subject key identifier
            cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false,
                            new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public)));

            // Basic constraints
            cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA));

            // Authority Key identifier
            var issuerKeyPair      = subjectKeyPair;
            var issuerSerialNumber = serialNumber;

            cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false,
                            new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public),
                                                       new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber));

            if (!isCA)
            {
                // Key usage
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature |
                                             KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment));

                // Extended Key usage
                cg.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                new ExtendedKeyUsage(new List <DerObjectIdentifier>()
                {
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth
                }));

                // subject alternate name
                cg.AddExtension(X509Extensions.SubjectAlternativeName, false,
                                new GeneralNames(new GeneralName[] {
                    new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri),
                    new GeneralName(GeneralName.DnsName, domainNames[0])
                }));
            }
            else
            {
                // Key usage CA
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign));
            }

            // sign certificate
            ISignatureFactory signatureFactory =
                new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", subjectKeyPair.Private, random);

            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create pkcs12 store for cert and private key
            X509Certificate2 certificate = null;

            using (MemoryStream pfxData = new MemoryStream())
            {
                Pkcs12Store            pkcsStore = new Pkcs12StoreBuilder().Build();
                X509CertificateEntry[] chain     = new X509CertificateEntry[1];
                string passcode = "passcode";
                chain[0] = new X509CertificateEntry(x509);
                pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain);
                pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

                // merge into X509Certificate2
                certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode);
            }

            Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint);

            // add cert to the store.
            if (!String.IsNullOrEmpty(storePath))
            {
                ICertificateStore store = null;
                if (storeType == CertificateStoreType.X509Store)
                {
                    store = new X509CertificateStore();
                }
                else if (storeType == CertificateStoreType.Directory)
                {
                    store = new DirectoryCertificateStore();
                }
                else
                {
                    throw new ArgumentException("Invalid store type");
                }

                store.Open(storePath);
                store.Add(certificate);
                store.Close();
                store.Dispose();
            }

            // note: this cert has a private key!
            return(certificate);
        }
Beispiel #22
0
        /// Note: Much of this code comes from https://stackoverflow.com/a/22247129
        /// <exception cref="CryptographicException">
        /// Sometimes thrown due to issues generating keys.
        /// </exception>
        private static X509Certificate2 GenerateSelfSignedCertificate(string subject)
        {
            const int keyStrength = 2048;

            // Generating Random Numbers
            //
            // For some reason the CryptoAPI wrapper doesn't come with the
            // .Net Core/Standard version of BouncyCastle, guessing this is most likely due to
            // platform compat issues. Use VMPC.
            var randomGenerator = new VmpcRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

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

            // Serial Number
            certificateGenerator.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random));

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

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

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Subject DN
            certificateGenerator.SetSubjectDN(new X509Name("CN=" + subject));

            // Subject Alternative Name
            var subjectAlternativeNames = new List <Asn1Encodable>()
            {
                new GeneralName(GeneralName.DnsName, Environment.MachineName),
                new GeneralName(GeneralName.DnsName, "localhost"),
                new GeneralName(GeneralName.IPAddress, "127.0.0.1"),
            };

            if (subject != "localhost" && subject != Environment.MachineName)
            {
                subjectAlternativeNames.Add(new GeneralName(GeneralName.DnsName, subject));
            }

            certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, new DerSequence(subjectAlternativeNames.ToArray()));

            // Issuer
            certificateGenerator.SetIssuerDN(new X509Name("CN=" + subject));
            certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public)));

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

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

            // Add basic constraint
            certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(false));

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

            // Signature Algorithm
            const string signatureAlgorithm = "SHA256WithRSA";
            var          signatureFactory   = new Asn1SignatureFactory(signatureAlgorithm, subjectKeyPair.Private);

            // self-signed certificate
            var certificate = certificateGenerator.Generate(signatureFactory);

            // corresponding private key
            var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            // merge into X509Certificate2
            var x509 = new X509Certificate2(certificate.GetEncoded());
            var seq  = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());

            if (seq.Count != 9)
            {
                // throw new PemException("malformed sequence in RSA private key");
            }

            var rsa       = RsaPrivateKeyStructure.GetInstance(seq);
            var rsaParams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            // This can throw CryptographicException in some cases. Catch above here and deal with it
            // in the application level.
            x509.PrivateKey = ToDotNetKey(rsaParams); // x509.PrivateKey = DotNetUtilities.ToRSA(rsaParams);

            return(x509);
        }
Beispiel #23
0
        public AsymmetricKeyParameter GenerateCACertificate(string subjectName, string privateKeyFilePassword, string rootsigningCertFileName, int keyStrength = 2048)
        {
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random          = new SecureRandom(randomGenerator);

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

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            var subjectDN = new X509Name(subjectName);
            var issuerDN  = subjectDN;

            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

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

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

            KeyUsage keyUsage = new KeyUsage(KeyUsage.KeyCertSign | KeyUsage.CrlSign);

            certificateGenerator.AddExtension(X509Extensions.KeyUsage, true, keyUsage);

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

            // Generating the Certificate
            var issuerKeyPair = subjectKeyPair;

            // selfsign certificate
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random);

            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);
            System.Security.Cryptography.X509Certificates.X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

            #region Private Key

            // correcponding private key
            PrivateKeyInfo pinfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

            var seq = (Asn1Sequence)Asn1Object.FromByteArray(pinfo.ParsePrivateKey().GetDerEncoded());
            if (seq.Count != 9)
            {
                throw new PemException("malformed sequence in RSA private key");
            }

            RsaPrivateKeyStructure     rsa       = RsaPrivateKeyStructure.GetInstance(seq);
            RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

            x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
            #endregion

            // Add CA certificate to Root store
            AddCertToStore(x509, System.Security.Cryptography.X509Certificates.StoreName.Root, System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine);

            File.WriteAllBytes(rootsigningCertFileName.Replace(".pfx", ".cer"), x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));

            // Export Certificate with private key
            File.WriteAllBytes(rootsigningCertFileName, x509.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, privateKeyFilePassword));

            return(issuerKeyPair.Private);
        }
    /// <summary>
    /// Creates a self signed application instance certificate.
    /// </summary>
    /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param>
    /// <param name="storePath">The store path (syntax depends on storeType).</param>
    /// <param name="password">The password to use to protect the certificate.</param>
    /// <param name="applicationUri">The application uri (created if not specified).</param>
    /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param>
    /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param>
    /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param>
    /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param>
    /// <param name="startTime">The start time.</param>
    /// <param name="lifetimeInMonths">The lifetime of the key in months.</param>
    /// <param name="hashSizeInBits">The hash size in bits.</param>
    /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param>
    /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param>
    /// <returns>The certificate with a private key.</returns>
    public static X509Certificate2 CreateCertificate(
        string storeType,
        string storePath,
        string password,
        string applicationUri,
        string applicationName,
        string subjectName,
        IList <String> domainNames,
        ushort keySize,
        DateTime startTime,
        ushort lifetimeInMonths,
        ushort hashSizeInBits,
        bool isCA = false,
        X509Certificate2 issuerCAKeyCert = null,
        byte[] publicKey = null)
    {
        if (issuerCAKeyCert != null)
        {
            if (!issuerCAKeyCert.HasPrivateKey)
            {
                throw new NotSupportedException("Cannot sign with a CA certificate without a private key.");
            }
        }

        if (publicKey != null && issuerCAKeyCert == null)
        {
            throw new NotSupportedException("Cannot use a public key without a CA certificate with a private key.");
        }

        // set default values.
        X509Name subjectDN = SetSuitableDefaults(
            ref applicationUri,
            ref applicationName,
            ref subjectName,
            ref domainNames,
            ref keySize,
            ref lifetimeInMonths);

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

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

            // subject and issuer DN
            X509Name issuerDN = null;
            if (issuerCAKeyCert != null)
            {
                issuerDN = new CertificateFactoryX509Name(issuerCAKeyCert.Subject);
            }
            else
            {
                // self signed
                issuerDN = subjectDN;
            }
            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);

            // valid for
            cg.SetNotBefore(startTime);
            cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths));

            // set Private/Public Key
            AsymmetricKeyParameter subjectPublicKey;
            AsymmetricKeyParameter subjectPrivateKey;
            if (publicKey == null)
            {
                var keyGenerationParameters = new KeyGenerationParameters(random, keySize);
                var keyPairGenerator        = new RsaKeyPairGenerator();
                keyPairGenerator.Init(keyGenerationParameters);
                AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair();
                subjectPublicKey  = subjectKeyPair.Public;
                subjectPrivateKey = subjectKeyPair.Private;
            }
            else
            {
                // special case, if a cert is signed by CA, the private key of the cert is not needed
                subjectPublicKey  = PublicKeyFactory.CreateKey(publicKey);
                subjectPrivateKey = null;
            }
            cg.SetPublicKey(subjectPublicKey);

            // add extensions
            // Subject key identifier
            cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false,
                            new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectPublicKey)));

            // Basic constraints
            cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA));

            // Authority Key identifier references the issuer cert or itself when self signed
            AsymmetricKeyParameter issuerPublicKey;
            BigInteger             issuerSerialNumber;
            if (issuerCAKeyCert != null)
            {
                issuerPublicKey    = GetPublicKeyParameter(issuerCAKeyCert);
                issuerSerialNumber = GetSerialNumber(issuerCAKeyCert);
                if (startTime.AddMonths(lifetimeInMonths) > issuerCAKeyCert.NotAfter)
                {
                    cg.SetNotAfter(issuerCAKeyCert.NotAfter);
                }
            }
            else
            {
                issuerPublicKey    = subjectPublicKey;
                issuerSerialNumber = serialNumber;
            }

            cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false,
                            new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerPublicKey),
                                                       new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber));

            if (!isCA)
            {
                // Key usage
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature |
                                             KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment));

                // Extended Key usage
                cg.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                new ExtendedKeyUsage(new List <DerObjectIdentifier>()
                {
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth
                }));

                // subject alternate name
                List <GeneralName> generalNames = new List <GeneralName>();
                generalNames.Add(new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri));
                generalNames.AddRange(CreateSubjectAlternateNameDomains(domainNames));
                cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(generalNames.ToArray()));
            }
            else
            {
                // Key usage CA
                cg.AddExtension(X509Extensions.KeyUsage, true,
                                new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign));
            }

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

            // convert to X509Certificate2
            X509Certificate2 certificate = null;
            if (subjectPrivateKey == null)
            {
                // create the cert without the private key
                certificate = new X509Certificate2(x509.GetEncoded());
            }
            else
            {
                // note: this cert has a private key!
                certificate = CreateCertificateWithPrivateKey(x509, null, subjectPrivateKey, random);
            }

            Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint);

            // add cert to the store.
            if (!String.IsNullOrEmpty(storePath) && !String.IsNullOrEmpty(storeType))
            {
                using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(storeType))
                {
                    if (store == null)
                    {
                        throw new ArgumentException("Invalid store type");
                    }

                    store.Open(storePath);
                    store.Add(certificate, password).Wait();
                    store.Close();
                }
            }

            return(certificate);
        }
    }
Beispiel #25
0
        //
        // Summary:
        //     /// Method responsible for generate certificate. ///
        //
        // Parameters:
        //   request:
        //     The request param.
        //
        public CreateCertificateResult Generate(CreateCertificateCommand request)
        {
            AsymmetricKeyParameter caPrivateKey = null;

            var caCert = GenerateCACertificate("CN=MyROOTCA", ref caPrivateKey);


            SecureRandom random = new SecureRandom();

            RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();

            keyPairGenerator.Init(new KeyGenerationParameters(random, 2048));

            AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            IDictionary issuerAttrs  = FactoryIssuerAttrs();
            IDictionary subjectAttrs = FactorySubjectAttrs(request);

            BigInteger serialNumber = BigInteger.ProbablePrime(120, new Random());

            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

            certificateGenerator.SetSerialNumber(serialNumber);
            certificateGenerator.SetIssuerDN(new X509Name(new ArrayList(issuerAttrs.Keys), issuerAttrs));
            certificateGenerator.SetSubjectDN(new X509Name(new ArrayList(subjectAttrs.Keys), subjectAttrs));
            certificateGenerator.SetNotBefore(DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(3));
            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            certificateGenerator.AddExtension(X509Extensions.KeyUsage, true,
                                              new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyAgreement | KeyUsage.NonRepudiation));

            certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false,
                                              new ExtendedKeyUsage(new[] { KeyPurposeID.IdKPServerAuth }));

            GeneralNames subjectAltName = new GeneralNames(new GeneralName(GeneralName.DnsName, "SAN"));

            certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, subjectAltName);

            Asn1SignatureFactory signatureFactory =
                new Asn1SignatureFactory(HashType.SHA256WithRSA.ToString(), subjectKeyPair.Private);

            X509Certificate certificate = certificateGenerator.Generate(signatureFactory);

            X509CertificateEntry certEntry = new X509CertificateEntry(certificate);

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            store.SetCertificateEntry(certificate.SubjectDN.ToString(), certEntry);
            store.SetKeyEntry(certificate.SubjectDN + "_key", new AsymmetricKeyEntry(subjectKeyPair.Private),
                              new[] { certEntry });

            MemoryStream p12Stream = new MemoryStream();

            store.Save(p12Stream, request.Pin.ToCharArray(), random);

            byte[] pfx = Pkcs12Utilities.ConvertToDefiniteLength(p12Stream.ToArray(), request.Pin.ToCharArray());

            X509Certificate2 x509Certificate2 =
                new X509Certificate2(pfx, request.Pin, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);


            CreateCrl(caCert, caPrivateKey, serialNumber);

            return(FactoryResponse(x509Certificate2));
        }
    /// <summary>
    /// Revoke the certificate.
    /// The CRL number is increased by one and the new CRL is returned.
    /// </summary>
    public static X509CRL RevokeCertificate(
        X509Certificate2 issuerCertificate,
        List <X509CRL> issuerCrls,
        X509Certificate2Collection revokedCertificates
        )
    {
        if (!issuerCertificate.HasPrivateKey)
        {
            throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer certificate has no private key, cannot revoke certificate.");
        }

        using (var cfrg = new CertificateFactoryRandomGenerator())
        {
            // cert generators
            SecureRandom random          = new SecureRandom(cfrg);
            BigInteger   crlSerialNumber = BigInteger.Zero;

            Org.BouncyCastle.X509.X509Certificate bcCertCA = new X509CertificateParser().ReadCertificate(issuerCertificate.RawData);
            AsymmetricKeyParameter signingKey = GetPrivateKeyParameter(issuerCertificate);

            ISignatureFactory signatureFactory =
                new Asn1SignatureFactory(GetRSAHashAlgorithm(defaultHashSize), signingKey, random);

            X509V2CrlGenerator crlGen = new X509V2CrlGenerator();
            crlGen.SetIssuerDN(bcCertCA.IssuerDN);
            crlGen.SetThisUpdate(DateTime.UtcNow);
            crlGen.SetNextUpdate(DateTime.UtcNow.AddMonths(12));

            // merge all existing revocation list
            if (issuerCrls != null)
            {
                X509CrlParser parser = new X509CrlParser();
                foreach (X509CRL issuerCrl in issuerCrls)
                {
                    X509Crl crl = parser.ReadCrl(issuerCrl.RawData);
                    crlGen.AddCrl(crl);
                    var crlVersion = GetCrlNumber(crl);
                    if (crlVersion.IntValue > crlSerialNumber.IntValue)
                    {
                        crlSerialNumber = crlVersion;
                    }
                }
            }

            DateTime now = DateTime.UtcNow;
            if (revokedCertificates == null || revokedCertificates.Count == 0)
            {
                // add a dummy revoked cert
                crlGen.AddCrlEntry(BigInteger.One, now, CrlReason.Unspecified);
            }
            else
            {
                // add the revoked cert
                foreach (var revokedCertificate in revokedCertificates)
                {
                    crlGen.AddCrlEntry(GetSerialNumber(revokedCertificate), now, CrlReason.PrivilegeWithdrawn);
                }
            }

            crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier,
                                false,
                                new AuthorityKeyIdentifierStructure(bcCertCA));

            // set new serial number
            crlSerialNumber = crlSerialNumber.Add(BigInteger.One);
            crlGen.AddExtension(X509Extensions.CrlNumber,
                                false,
                                new CrlNumber(crlSerialNumber));

            // generate updated CRL
            X509Crl updatedCrl = crlGen.Generate(signatureFactory);
            return(new X509CRL(updatedCrl.GetEncoded()));
        }
    }
        /// <summary>
        /// Create a CSR and submit it to the Acme server for signing. Returns the certificate chain.
        /// </summary>
        /// <param name="domains">The list of domains that this certificate will be for. The first domain listed will be the CommonName.</param>
        /// <param name="keyPair">The RSA key pair for signing the certificate request, this is the key that will be used in conjunction with the certificate.</param>
        /// <returns>A tuple whose first value is the private key data and whose second value is a list of certificates. Everything is encoded in DER format, the first certificate is the signed certificate.</returns>
        public Tuple <byte[], List <byte[]> > GetCertificate(ICollection <string> domains)
        {
            //
            // Generate a new key for the certificate.
            //
            var generator = new RsaKeyPairGenerator();

            generator.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
            var keyPair = generator.GenerateKeyPair();
            var sig     = new Asn1SignatureFactory("SHA256WITHRSA", keyPair.Private);

            var commonName = new X509Name(new DerObjectIdentifier[] { X509Name.CN }, new string[] { domains.First() });

            //
            // Generate the list of subject alternative names.
            //
            List <GeneralName> names = new List <GeneralName>();

            foreach (var domain in domains)
            {
                names.Add(new GeneralName(GeneralName.DnsName, domain));
            }
            var sanOctect    = new DerOctetString(new GeneralNames(names.ToArray()));
            var sanSequence  = new DerSequence(X509Extensions.SubjectAlternativeName, sanOctect);
            var extensionSet = new DerSet(new DerSequence(sanSequence));
            var attributes   = new DerSet(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, extensionSet));

            //
            // Generate the CSR from all the data.
            //
            var csr = new Pkcs10CertificationRequest(sig, commonName, keyPair.Public, attributes, keyPair.Private);

            var payload = new
            {
                resource = "new-cert",
                csr      = UrlBase64Encode(csr.GetDerEncoded())
            };

            var certificates = new List <X509Certificate>();
            var certParser   = new X509CertificateParser();

            byte[] certData;

            //
            // Send the request and fetch the certificate data.
            //
            certData = SendMessage <byte[]>(Directory.NewCert, payload, GetNonce(), out WebHeaderCollection headers);
            certificates.Add(certParser.ReadCertificate(certData));

            //
            // Fetch all the certificates in the chain.
            //
            foreach (var link in headers.GetValues("Link"))
            {
                var match = System.Text.RegularExpressions.Regex.Match(link, "\\<(.*)\\>;rel=\"(.*)\"");
                if (match.Success && match.Groups[2].Value == "up")
                {
                    certData = GetRequest <byte[]>(match.Groups[1].Value);
                    certificates.Add(certParser.ReadCertificate(certData));
                }
            }

            var privateKeyData  = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private).ToAsn1Object().GetDerEncoded();
            var certificateData = certificates.Select(c => c.GetEncoded()).ToList();

            return(new Tuple <byte[], List <byte[]> >(privateKeyData, certificateData));
        }
    /// <summary>
    /// Creates a certificate signing request from an existing certificate.
    /// </summary>
    public static byte[] CreateSigningRequest(
        X509Certificate2 certificate,
        IList <String> domainNames = null
        )
    {
        using (var cfrg = new CertificateFactoryRandomGenerator())
        {
            SecureRandom random = new SecureRandom(cfrg);

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

            ISignatureFactory signatureFactory =
                new Asn1SignatureFactory(GetRSAHashAlgorithm(defaultHashSize), signingKey, random);

            Asn1Set attributes = null;
            X509SubjectAltNameExtension alternateName = null;
            foreach (System.Security.Cryptography.X509Certificates.X509Extension extension in certificate.Extensions)
            {
                if (extension.Oid.Value == X509SubjectAltNameExtension.SubjectAltNameOid || extension.Oid.Value == X509SubjectAltNameExtension.SubjectAltName2Oid)
                {
                    alternateName = new X509SubjectAltNameExtension(extension, extension.Critical);
                    break;
                }
            }

            domainNames = domainNames ?? new List <String>();
            if (alternateName != null)
            {
                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
            List <GeneralName> generalNames = new List <GeneralName>();

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

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

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

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

            return(pkcs10CertificationRequest.GetEncoded());
        }
    }
        /// <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
                AsymmetricKeyParameter subjectPublicKey  = null;
                AsymmetricKeyParameter subjectPrivateKey = null;
                using (var rsa = new RSACryptoServiceProvider(m_keySize == 0 ? X509Defaults.RSAKeySize : m_keySize))
                {
                    subjectPublicKey  = X509Utils.GetPublicKeyParameter(rsa);
                    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));
            }
        }
Beispiel #30
0
        public X509Certificate2 CreateCertificateAuthorityCertificate(string subjectName, out AsymmetricKeyParameter CaPrivateKey, out byte[] Android)
        {
            const int keyStrength = 2048;

            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom             random          = new SecureRandom(randomGenerator);

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

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

            certificateGenerator.SetSerialNumber(serialNumber);

            // Issuer and Subject Name
            X509Name subjectDN = new X509Name("CN=" + subjectName);
            X509Name issuerDN  = subjectDN;

            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

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

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

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

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

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Generating the Certificate
            AsymmetricCipherKeyPair issuerKeyPair    = subjectKeyPair;
            ISignatureFactory       signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", issuerKeyPair.Private, random);

            // selfsign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory);
            X509Certificate2 x509 = new X509Certificate2(certificate.GetEncoded());

            x509.FriendlyName = subjectName;
            CaPrivateKey      = issuerKeyPair.Private;

            // Now do Android...
            certificateGenerator.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));
            issuerKeyPair    = subjectKeyPair;
            signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", issuerKeyPair.Private, random);
            Org.BouncyCastle.X509.X509Certificate certificateAndroid = certificateGenerator.Generate(signatureFactory);
            X509Certificate2 x509Android = new X509Certificate2(certificateAndroid.GetEncoded());

            Android = x509Android.Export(X509ContentType.Cert, "1234");

            return(x509);
        }