private static CX509ExtensionAlternativeNames GetSAN(string cn)
        {
            var san = new CX509ExtensionAlternativeNames();
            var alternativeNames = new CAlternativeNames();

            foreach (var item in cn.Split(','))
            {
                var alternativeName = new CAlternativeName();
                alternativeName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, item);
                alternativeNames.Add(alternativeName);
            }

            san.InitializeEncode(alternativeNames);
            return(san);
        }
        private CX509Extension GetQualifiedSan(List <string> san)
        {
            CAlternativeNames altNames = new CAlternativeNames();
            CObjectId         sanOid   = new CObjectId();
            CX509ExtensionAlternativeNames encodedAltNames = new CX509ExtensionAlternativeNames();

            sanOid.InitializeFromValue("2.5.29.17");

            foreach (string strAltName in san)
            {
                CAlternativeName altName = (CAlternativeName)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CAlternativeName"));
                altName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, strAltName);
                altNames.Add(altName);
                altName = null;
            }
            encodedAltNames.InitializeEncode(altNames);
            return((CX509Extension)encodedAltNames);
        }
Exemple #3
0
        /// <summary>
        /// Create a certificate signing request.
        /// </summary>
        /// <param name="subjectName">The subject name of the certificate.</param>
        /// <param name="keyLength">Size of the key in bits.</param>
        /// <param name="durationYears">Duration of the certificate, specified in years.</param>
        /// <param name="oids">Collection of OIDs identifying certificate usage.</param>
        public static CX509CertificateRequestCertificate CreateCertificateSigningRequest(string subjectName, int keyLength, int durationYears, List <string> oids)
        {
            // Prepend the subject name with CN= if it doesn't begin with CN=, E=, etc..
            if (subjectName.IndexOf("=") < 0)
            {
                subjectName = "CN=" + subjectName;
            }

            // Generate a distinguished name.
            CX500DistinguishedName distinguishedName = new CX500DistinguishedName();

            distinguishedName.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);

            // Generate a private key.
            CX509PrivateKey privateKey = new CX509PrivateKey();

            privateKey.ExportPolicy   = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
            privateKey.KeySpec        = X509KeySpec.XCN_AT_SIGNATURE;
            privateKey.Length         = keyLength;
            privateKey.MachineContext = true;
            privateKey.ProviderName   = "Microsoft Enhanced Cryptographic Provider v1.0";
            privateKey.Create();

            // Use the SHA-512 hashing algorithm.
            CObjectId hashAlgorithm = new CObjectId();

            hashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA512");

            // Load the OIDs passed in and specify enhanced key usages.
            CObjectIds oidCollection = new CObjectIds();

            foreach (string oidID in oids)
            {
                CObjectId oid = new CObjectId();
                oid.InitializeFromValue(oidID);
                oidCollection.Add(oid);
            }

            CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage();

            keyUsage.InitializeEncode(CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE);

            CX509ExtensionEnhancedKeyUsage enhancedKeyUsages = new CX509ExtensionEnhancedKeyUsage();

            enhancedKeyUsages.InitializeEncode(oidCollection);

            string sanSubjectName = subjectName.Substring(subjectName.IndexOf("=") + 1);

            CAlternativeName sanAlternateName = new CAlternativeName();

            sanAlternateName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, sanSubjectName);

            CAlternativeNames sanAlternativeNames = new CAlternativeNames();

            sanAlternativeNames.Add(sanAlternateName);

            CX509ExtensionAlternativeNames alternativeNamesExtension = new CX509ExtensionAlternativeNames();

            alternativeNamesExtension.InitializeEncode(sanAlternativeNames);

            CX509ExtensionSmimeCapabilities smimeCapabilities = new CX509ExtensionSmimeCapabilities();

            smimeCapabilities.SmimeCapabilities.AddAvailableSmimeCapabilities(false);

            // Create the self-signing request.
            CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate();

            cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, "");
            cert.Subject   = distinguishedName;
            cert.Issuer    = distinguishedName;
            cert.NotBefore = DateTime.Now;
            cert.NotAfter  = DateTime.Now.AddYears(1);
            cert.X509Extensions.Add((CX509Extension)keyUsage);
            cert.X509Extensions.Add((CX509Extension)enhancedKeyUsages);
            cert.X509Extensions.Add((CX509Extension)alternativeNamesExtension);
            cert.X509Extensions.Add((CX509Extension)smimeCapabilities);
            cert.HashAlgorithm = hashAlgorithm;
            cert.Encode();

            return(cert);
        }
        private static StoreName store        = StoreName.My;                   // Store as a personal certificate


        private static X509Certificate2 CreateSelfSignedCertificate(string Operator, string SiteId, int SeqNo, bool isServerCert, string SAN)
        {
            // Create a custom subject name & friendly name
            string distName = $"CN={FriendlyName.ToLower()}_{SiteId}_{SeqNo}, OU={Operator}_{SiteId}, O={Operator}, C=GB";

            // create DN for subject and issuer
            //            var dn = new X500DistinguishedName(distName);
            //            dn.Encode(distName, X500NameFlags.XCN_CERT_NAME_STR_NONE);
            var dn = new CX500DistinguishedName();

            dn.Encode(distName, X500NameFlags.XCN_CERT_NAME_STR_NONE);


            // create a new private key for the certificate
            //CX509PrivateKey privateKey = new CX509PrivateKey();
            //var privateKey = new CX509PrivateKey();
            var typeName = "X509Enrollment.CX509PrivateKey";
            var type     = Type.GetTypeFromProgID(typeName);

            if (type == null)
            {
                throw new Exception(typeName + " is not available on your system: 0x80040154 (REGDB_E_CLASSNOTREG)");
            }
            var privateKey = Activator.CreateInstance(type) as IX509PrivateKey;

            if (privateKey == null)
            {
                throw new Exception("Your certlib does not know an implementation of " + typeName +
                                    " (in HKLM:\\SOFTWARE\\Classes\\Interface\\)!");
            }
            privateKey.ProviderName   = "Microsoft Base Cryptographic Provider v1.0";
            privateKey.MachineContext = true;
            privateKey.Length         = 2048;
            privateKey.KeySpec        = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited
            // privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
            privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
            privateKey.Create();

            // Use the stronger SHA512 hashing algorithm
            var hashobj = new CObjectId();

            hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
                                                ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,
                                                AlgorithmFlags.AlgorithmFlagsNone, "SHA512");

            // add extended key usage if you want - look at MSDN for a list of possible OIDs
            var oid = new CObjectId();

            //            oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL server
            if (isServerCert)
            {
                oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL Server
            }
            else
            {
                oid.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // SSL client
            }

            var oidlist = new CObjectIds();

            oidlist.Add(oid);
            var eku = new CX509ExtensionEnhancedKeyUsage();

            eku.InitializeEncode(oidlist);

            // Create the self signing request
            var cert = new CX509CertificateRequestCertificate();

            cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, "");

            if (!string.IsNullOrEmpty(SAN))
            {
                CAlternativeName  objRfc822Name       = new CAlternativeName();
                CAlternativeNames objAlternativeNames = new CAlternativeNames();
                CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames();


                // Set Alternative RFC822 Name
                objRfc822Name.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, SAN);

                // Set Alternative Names
                objAlternativeNames.Add(objRfc822Name);
                objExtensionAlternativeNames.InitializeEncode(objAlternativeNames);
                cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames);
            }

            cert.Subject   = dn;
            cert.Issuer    = dn;                          // the issuer and the subject are the same
            cert.NotBefore = DateTime.Today;
            cert.NotAfter  = DateTime.Today.AddYears(10); // expire in 10 years time
            cert.X509Extensions.Add((CX509Extension)eku); // add the EKU
            cert.HashAlgorithm = hashobj;                 // Specify the hashing algorithm
            cert.Encode();                                // encode the certificate

            // Do the final enrollment process
            var enroll = new CX509Enrollment();

            enroll.InitializeFromRequest(cert);            // load the certificate
            enroll.CertificateFriendlyName = FriendlyName; // Optional: add a friendly name
            string csr = enroll.CreateRequest();           // Output the request in base64

            // and install it back as the response
            enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
                                   csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password
                                                                                   // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
            var base64encoded = enroll.CreatePFX("",                               // no password, this is for internal consumption
                                                 PFXExportOptions.PFXExportChainWithRoot);

            // instantiate the target class with the PKCS#12 data (and the empty password)
            X509Certificate2 newCert = new X509Certificate2(System.Convert.FromBase64String(base64encoded), "",
                                                            // mark the private key as exportable (this is usually what you want to do)
                                                            System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable
                                                            // Ensure the machine key is created and retained
                                                            // http://stackoverflow.com/questions/425688/how-to-set-read-permission-on-the-private-key-file-of-x-509-certificate-from-ne
                                                            | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

            return(newCert);
        }
Exemple #5
0
        private static string CreateCertContent(string cn, TimeSpan expirationLength, string pwd)
        {
            string base64encoded = string.Empty;
            var    dn            = new CERTENROLLLib.CX500DistinguishedName();

            dn.Encode("CN=" + cn, X500NameFlags.XCN_CERT_NAME_STR_NONE);



            CX509PrivateKey privateKey = new CX509PrivateKey();

            privateKey.ProviderName = "Microsoft Strong Cryptographic Provider";
            privateKey.Length       = 2048;
            privateKey.KeySpec      = X509KeySpec.XCN_AT_KEYEXCHANGE;
            privateKey.KeyUsage     = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_DECRYPT_FLAG |
                                      X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_KEY_AGREEMENT_FLAG;
            privateKey.MachineContext = true;
            privateKey.ExportPolicy   = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
            privateKey.Create();

            // Use the stronger SHA512 hashing algorithm
            var hashobj = new CObjectId();

            hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
                                                ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,
                                                AlgorithmFlags.AlgorithmFlagsNone, "SHA512");

            // Create the self signing request
            var cert = new CX509CertificateRequestCertificate();

            cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, "");
            cert.Subject   = dn;
            cert.Issuer    = dn; // the issuer and the subject are the same
            cert.NotBefore = DateTime.Now.Date;



            var objExtensionAlternativeNames = new CX509ExtensionAlternativeNames();

            {
                var altNames = new CAlternativeNames();
                //var dnsHostname = new CAlternativeName();
                //dnsHostname.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, Environment.MachineName);
                //altNames.Add(dnsHostname);
                //foreach (var ipAddress in Dns.GetHostAddresses(Dns.GetHostName()))
                //{
                //    if ((ipAddress.AddressFamily == AddressFamily.InterNetwork ||
                //         ipAddress.AddressFamily == AddressFamily.InterNetworkV6) && !IPAddress.IsLoopback(ipAddress))
                //    {
                //        var dns = new CAlternativeName();
                //        dns.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, ipAddress.ToString());
                //        altNames.Add(dns);
                //    }
                //}
                var dns1 = new CAlternativeName();
                dns1.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, "localhost");
                altNames.Add(dns1);
                objExtensionAlternativeNames.InitializeEncode(altNames);
            }

            cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames);

            // this cert expires immediately. Change to whatever makes sense for you
            cert.NotAfter      = cert.NotBefore + expirationLength;
            cert.HashAlgorithm = hashobj; // Specify the hashing algorithm
            cert.Encode();                // encode the certificate

            // Do the final enrollment process
            var enroll = new CX509Enrollment();

            enroll.InitializeFromRequest(cert);  // load the certificate
            enroll.CertificateFriendlyName = cn; // Optional: add a friendly name

            string csr = enroll.CreateRequest(); // Output the request in base64

            // and install it back as the response
            enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
                                   csr, EncodingType.XCN_CRYPT_STRING_BASE64, pwd); // no password
            // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
            base64encoded = enroll.CreatePFX(pwd,                                   // no password, this is for internal consumption
                                             PFXExportOptions.PFXExportChainWithRoot);
            return(base64encoded);
        }
Exemple #6
0
        public static X509Certificate2 CreateCertificate(Certificate crt)
        {
            bool isCA = !crt.SignByCertificateAuthority;

            // create DN for subject and issuer
            var dn = new CX500DistinguishedName();

            dn.Encode(GetEncodedDistinguishedName(crt), X500NameFlags.XCN_CERT_NAME_STR_NONE);

            // create a new private key for the certificate
            CX509PrivateKey privateKey = new CX509PrivateKey
            {
                ProviderName   = "Microsoft Base Cryptographic Provider v1.0",
                MachineContext = crt.MachineContext,
                Length         = crt.KeyLength,
                KeySpec        = X509KeySpec.XCN_AT_SIGNATURE, // use is not limited
                ExportPolicy   = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG
            };

            privateKey.Create();

            var hashobj = new CObjectId();

            hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
                                                ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,
                                                AlgorithmFlags.AlgorithmFlagsNone, crt.DigestAlgorithm);

            CERTENROLLLib.X509KeyUsageFlags x509KeyUsageFlags;
            CX509ExtensionBasicConstraints  bc = new CX509ExtensionBasicConstraints();

            if (isCA)
            {
                x509KeyUsageFlags =
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_CERT_SIGN_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_CRL_SIGN_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_OFFLINE_CRL_SIGN_KEY_USAGE;

                bc.InitializeEncode(true, -1);
                bc.Critical = true;
            }
            else
            {
                x509KeyUsageFlags =
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE;

                if (crt.CertificateType == CertificateType.ClientCertificate)
                {
                    x509KeyUsageFlags |= CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE;
                }
                if (crt.CertificateType == CertificateType.ServerCertificate)
                {
                    x509KeyUsageFlags |= CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE;
                }

                bc.InitializeEncode(false, -1);
                bc.Critical = false;
            }

            CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage();

            keyUsage.InitializeEncode(x509KeyUsageFlags);
            keyUsage.Critical = false;

            // SAN
            var canList = new List <CAlternativeName>();

            foreach (var sanItem in crt.SANList)
            {
                if (!string.IsNullOrWhiteSpace(sanItem.Value))
                {
                    var can = new CAlternativeName();
                    switch (sanItem.Type)
                    {
                    case Certificate.SANType.DNS:
                        can.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, sanItem.Value);
                        break;

                    case Certificate.SANType.IP:
                        can.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, EncodingType.XCN_CRYPT_STRING_BASE64,
                                                  Convert.ToBase64String(IPAddress.Parse(sanItem.Value).GetAddressBytes()));
                        break;

                    case Certificate.SANType.URI:
                        can.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_URL, sanItem.Value);
                        break;

                    case Certificate.SANType.email:
                        can.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, sanItem.Value);
                        break;
                    }
                    canList.Add(can);
                }
            }

            CX509ExtensionAlternativeNames san = null;

            if (canList.Any())
            {
                san = new CX509ExtensionAlternativeNames();
                var cans = new CAlternativeNames();
                foreach (var item in canList)
                {
                    cans.Add(item);
                }
                san.InitializeEncode(cans);
            }

            CX509ExtensionEnhancedKeyUsage eku = null;

            if (crt.CertificateType != CertificateType.None)
            {
                const string XCN_OID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1";
                const string XCN_OID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2";

                var oid = new CObjectId();
                if (crt.CertificateType == CertificateType.ServerCertificate)
                {
                    oid.InitializeFromValue(XCN_OID_PKIX_KP_SERVER_AUTH);
                }
                if (crt.CertificateType == CertificateType.ClientCertificate)
                {
                    oid.InitializeFromValue(XCN_OID_PKIX_KP_CLIENT_AUTH);
                }

                var oidlist = new CObjectIds();
                oidlist.Add(oid);
                eku = new CX509ExtensionEnhancedKeyUsage();
                eku.InitializeEncode(oidlist);
            }

            // Create the self signing request
            var cereq = new CX509CertificateRequestCertificate();

            cereq.InitializeFromPrivateKey(crt.MachineContext ? X509CertificateEnrollmentContext.ContextMachine : X509CertificateEnrollmentContext.ContextUser, privateKey, "");

            cereq.Subject   = dn;
            cereq.Issuer    = dn;
            cereq.NotBefore = DateTime.UtcNow.AddDays(-1);
            cereq.NotAfter  = DateTime.UtcNow.AddDays(crt.Lifetime.Value);

            if (crt.SignByCertificateAuthority)
            {
                var issuer = MyCurrentUserX509Store.Certificates
                             .Find(X509FindType.FindByThumbprint, crt.CertificateAuthority, false)
                             .OfType <X509Certificate2>()
                             .Where(c => c.HasPrivateKey).FirstOrDefault() ?? throw new Exception("Issuer not found: " + crt.CertificateAuthority);

                cereq.SignerCertificate = new CSignerCertificate();
                cereq.SignerCertificate.Initialize(false, X509PrivateKeyVerify.VerifyNone, EncodingType.XCN_CRYPT_STRING_HEX, issuer.GetRawCertDataString());

                cereq.Issuer = new CX500DistinguishedName();
                cereq.Issuer.Encode(issuer.Subject, X500NameFlags.XCN_CERT_NAME_STR_NONE);
            }

            cereq.X509Extensions.Add((CX509Extension)keyUsage);
            if (eku != null)
            {
                cereq.X509Extensions.Add((CX509Extension)eku);               // EnhancedKeyUsage
            }
            if (bc != null)
            {
                cereq.X509Extensions.Add((CX509Extension)bc);                // ExtensionBasicConstraints
            }
            if (san != null)
            {
                cereq.X509Extensions.Add((CX509Extension)san); // SAN
            }
            cereq.HashAlgorithm = hashobj;                     // Specify the hashing algorithm
            cereq.Encode();                                    // encode the certificate

            // Do the final enrollment process
            var enroll = new CX509Enrollment();

            enroll.InitializeFromRequest(cereq); // load the certificate
            //enroll.CertificateFriendlyName = subjectName; // Optional: add a friendly name
            string csr = enroll.CreateRequest(); // Output the request in base64

            // and install it back as the response

            enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password

            // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
            var base64encoded = enroll.CreatePFX("", // no password, this is for internal consumption
                                                 PFXExportOptions.PFXExportChainWithRoot);

            // instantiate the target class with the PKCS#12 data (and the empty password)
            var x509Certificate2 = new X509Certificate2(
                Convert.FromBase64String(base64encoded), "",
                X509KeyStorageFlags.Exportable); // mark the private key as exportable (this is usually what you want to do)

            if (isCA)
            {
                X509Store rootStore = null;
                try
                {
                    rootStore = new X509Store(StoreName.Root, crt.MachineContext ? StoreLocation.LocalMachine : StoreLocation.CurrentUser);
                    rootStore.Open(OpenFlags.ReadWrite);
                    // install to CA store
                    var crtPub = new X509Certificate2(x509Certificate2)
                    {
                        PrivateKey = null
                    };
                    rootStore.Add(crtPub);
                    crtPub.Reset();
                }
                catch
                {
                    // ignore when adding to trust root failed
                }
                finally
                {
                    rootStore?.Close();
                }
            }

            crt.Value = x509Certificate2;

            return(x509Certificate2);
        }
Exemple #7
0
    public static X509Certificate2 CreateCertificate(string certSubject, bool isCA)
    {
        string CAsubject          = certSubject;
        CX500DistinguishedName dn = new CX500DistinguishedName();

        dn.Encode("CN=" + CAsubject, X500NameFlags.XCN_CERT_NAME_STR_NONE);

        string strRfc822Name = certSubject;

        CAlternativeName  objRfc822Name       = new CAlternativeName();
        CAlternativeNames objAlternativeNames = new CAlternativeNames();
        CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames();

        // Set Alternative RFC822 Name
        objRfc822Name.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, strRfc822Name);

        // Set Alternative Names
        objAlternativeNames.Add(objRfc822Name);
        objExtensionAlternativeNames.InitializeEncode(objAlternativeNames);
        //objPkcs10.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames);



        //Issuer Property for cleanup
        string issuer = "__Interceptor_Trusted_Root";
        CX500DistinguishedName issuerdn = new CX500DistinguishedName();

        issuerdn.Encode("CN=" + issuer, X500NameFlags.XCN_CERT_NAME_STR_NONE);
        // Create a new Private Key

        CX509PrivateKey key = new CX509PrivateKey();

        key.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider"; //"Microsoft Enhanced Cryptographic Provider v1.0"
                                                                                    // Set CAcert to 1 to be used for Signature
        if (isCA)
        {
            key.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;
        }
        else
        {
            key.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
        }
        key.Length         = 2048;
        key.MachineContext = true;
        key.Create();

        // Create Attributes
        //var serverauthoid = new X509Enrollment.CObjectId();
        CObjectId serverauthoid = new CObjectId();

        serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1");
        CObjectIds ekuoids = new CObjectIds();

        ekuoids.Add(serverauthoid);
        CX509ExtensionEnhancedKeyUsage ekuext = new CX509ExtensionEnhancedKeyUsage();

        ekuext.InitializeEncode(ekuoids);

        CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate();

        cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, key, "");
        cert.Subject   = dn;
        cert.Issuer    = issuerdn;
        cert.NotBefore = (DateTime.Now).AddDays(-1); //Backup One day to Avoid Timing Issues
        cert.NotAfter  = cert.NotBefore.AddDays(90); //Arbitrary... Change to persist longer...
                                                     //Use Sha256
        CObjectId hashAlgorithmObject = new CObjectId();

        hashAlgorithmObject.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, 0, 0, "SHA256");
        cert.HashAlgorithm = hashAlgorithmObject;

        cert.X509Extensions.Add((CX509Extension)ekuext);
        cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames);
        //https://blogs.msdn.microsoft.com/alejacma/2011/11/07/how-to-add-subject-alternative-name-to-your-certificate-requests-c/
        if (isCA)
        {
            CX509ExtensionBasicConstraints basicConst = new CX509ExtensionBasicConstraints();
            basicConst.InitializeEncode(true, 1);
            cert.X509Extensions.Add((CX509Extension)basicConst);
        }
        else
        {
            var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection signer = store.Certificates.Find(X509FindType.FindBySubjectName, "__Interceptor_Trusted_Root", false);

            CSignerCertificate signerCertificate = new CSignerCertificate();
            signerCertificate.Initialize(true, 0, EncodingType.XCN_CRYPT_STRING_HEX, signer[0].Thumbprint);
            cert.SignerCertificate = signerCertificate;
        }
        cert.Encode();

        CX509Enrollment enrollment = new CX509Enrollment();

        enrollment.InitializeFromRequest(cert);
        string certdata = enrollment.CreateRequest(0);

        enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, certdata, 0, "");

        if (isCA)
        {
            //Install CA Root Certificate
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certList = store.Certificates.Find(X509FindType.FindBySubjectName, "__Interceptor_Trusted_Root", false);
            store.Close();

            X509Store rootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
            rootStore.Open(OpenFlags.ReadWrite);
            X509Certificate2Collection rootcertList = rootStore.Certificates.Find(X509FindType.FindBySubjectName, "__Interceptor_Trusted_Root", false);
            rootStore.Add(certList[0]);
            rootStore.Close();
            return(certList[0]);
        }
        else
        {
            //Return Per Domain Cert
            X509Store xstore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            xstore.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certList = xstore.Certificates.Find(X509FindType.FindBySubjectName, certSubject, false);
            xstore.Close();
            return(certList[0]);
        }
    }
        /// <summary>
        /// Create a certificate signing request.
        /// </summary>
        /// <param name="subjectName">The subject name of the certificate.</param>
        /// <param name="keyLength">Size of the key in bits.</param>
        /// <param name="durationYears">Duration of the certificate, specified in years.</param>
        /// <param name="oids">Collection of OIDs identifying certificate usage.</param>
        public static CX509CertificateRequestCertificate CreateCertificateSigningRequest(string subjectName, int keyLength, int durationYears, List<string> oids)
        {
            // Prepend the subject name with CN= if it doesn't begin with CN=, E=, etc..
            if (subjectName.IndexOf("=") < 0)
                subjectName = "CN=" + subjectName;

            // Generate a distinguished name.
            CX500DistinguishedName distinguishedName = new CX500DistinguishedName();
            distinguishedName.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);

            // Generate a private key.
            CX509PrivateKey privateKey = new CX509PrivateKey();
            privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
            privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;
            privateKey.Length = keyLength;
            privateKey.MachineContext = true;
            privateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
            privateKey.Create();

            // Use the SHA-512 hashing algorithm.
            CObjectId hashAlgorithm = new CObjectId();
            hashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA512");

            // Load the OIDs passed in and specify enhanced key usages.
            CObjectIds oidCollection = new CObjectIds();
            foreach (string oidID in oids)
            {
                CObjectId oid = new CObjectId();
                oid.InitializeFromValue(oidID);
                oidCollection.Add(oid);
            }

            CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage();
            keyUsage.InitializeEncode(CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE);

            CX509ExtensionEnhancedKeyUsage enhancedKeyUsages = new CX509ExtensionEnhancedKeyUsage();
            enhancedKeyUsages.InitializeEncode(oidCollection);

            string sanSubjectName = subjectName.Substring(subjectName.IndexOf("=") + 1);

            CAlternativeName sanAlternateName = new CAlternativeName();
            sanAlternateName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, sanSubjectName);

            CAlternativeNames sanAlternativeNames = new CAlternativeNames();
            sanAlternativeNames.Add(sanAlternateName);

            CX509ExtensionAlternativeNames alternativeNamesExtension = new CX509ExtensionAlternativeNames();
            alternativeNamesExtension.InitializeEncode(sanAlternativeNames);

            CX509ExtensionSmimeCapabilities smimeCapabilities = new CX509ExtensionSmimeCapabilities();
            smimeCapabilities.SmimeCapabilities.AddAvailableSmimeCapabilities(false);

            // Create the self-signing request.
            CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate();
            cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, "");
            cert.Subject = distinguishedName;
            cert.Issuer = distinguishedName;
            cert.NotBefore = DateTime.Now;
            cert.NotAfter = DateTime.Now.AddYears(1);
            cert.X509Extensions.Add((CX509Extension)keyUsage);
            cert.X509Extensions.Add((CX509Extension)enhancedKeyUsages);
            cert.X509Extensions.Add((CX509Extension)alternativeNamesExtension);
            cert.X509Extensions.Add((CX509Extension)smimeCapabilities);
            cert.HashAlgorithm = hashAlgorithm;
            cert.Encode();

            return cert;
        }
Exemple #9
0
        public X509Certificate2 CreateSelfSignedCertificate(string FriendlyName, string SubjectName)
        {
            try
            {
                // Create DN for Subject
                CX500DistinguishedName dnSubject = new CX500DistinguishedName();
                dnSubject.Encode(String.Format(@"CN={0}", SubjectName), X500NameFlags.XCN_CERT_NAME_STR_NONE);

                // Create DN for Issuer
                CX500DistinguishedName dnIssuer = new CX500DistinguishedName();
                dnIssuer.Encode(String.Format(@"CN={0}", IssuerName), X500NameFlags.XCN_CERT_NAME_STR_NONE);

                // Use the stronger SHA512 hashing algorithm
                CObjectId HashAlgorithm = new CObjectId();

                HashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
                                                          ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, strAlgorithmName);

                // add extended key usage if you want - look at MSDN for a list of possible OIDs
                CObjectId oid1 = new CObjectId();
                oid1.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL Server

                CObjectId oid2 = new CObjectId();
                oid2.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // SSL Client

                CObjectIds oidlist = new CObjectIds();
                oidlist.Add(oid1);
                oidlist.Add(oid2);

                CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage();
                eku.InitializeEncode(oidlist);

                CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames();
                {
                    CAlternativeNames altNames = new CAlternativeNames();

                    CAlternativeName dnsLocalHost = new CAlternativeName();
                    dnsLocalHost.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, "LOCALHOST");
                    altNames.Add(dnsLocalHost);

                    CAlternativeName dnsHostname = new CAlternativeName();
                    dnsHostname.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, Environment.MachineName);
                    altNames.Add(dnsHostname);

                    foreach (var ipAddress in Dns.GetHostAddresses(Dns.GetHostName()))
                    {
                        if ((ipAddress.AddressFamily == AddressFamily.InterNetwork) && !IPAddress.IsLoopback(ipAddress))
                        {
                            CAlternativeName dns = new CAlternativeName();
                            dns.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, ipAddress.ToString());
                            altNames.Add(dns);
                        }
                    }

                    objExtensionAlternativeNames.InitializeEncode(altNames);
                }

                //CX509ExtensionSmimeCapabilities smimeCapabilities = new CX509ExtensionSmimeCapabilities();
                //smimeCapabilities.SmimeCapabilities.AddAvailableSmimeCapabilities(false);

                CX509ExtensionBasicConstraints basicConst = new CX509ExtensionBasicConstraints();
                basicConst.InitializeEncode(dnSubject.Name == dnIssuer.Name ? true : false, 1);

                // Key Usage Extension
                CX509ExtensionKeyUsage objExtensionKeyUsage = new CX509ExtensionKeyUsage();
                objExtensionKeyUsage.InitializeEncode(
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_CERT_SIGN_KEY_USAGE
                    );

                // Create the self signing request
                CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate();
                cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, PrivateKey, "");
                cert.Subject   = dnSubject;
                cert.Issuer    = dnIssuer;
                cert.NotBefore = DateTime.Today.AddDays(-1);
                cert.NotAfter  = DateTime.Today.AddYears(ExpirationLengthInYear);

                cert.X509Extensions.Add((CX509Extension)eku); // add the EKU
                cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames);
                cert.X509Extensions.Add((CX509Extension)objExtensionKeyUsage);
                cert.X509Extensions.Add((CX509Extension)basicConst);
                //cert.X509Extensions.Add((CX509Extension)smimeCapabilities);
                cert.HashAlgorithm = HashAlgorithm; // Specify the hashing algorithm
                cert.Encode();                      // encode the certificate

                // Do the final enrollment process
                CX509Enrollment enroll = new CX509Enrollment();
                enroll.InitializeFromRequest(cert);            // load the certificate
                enroll.CertificateFriendlyName = FriendlyName; // Optional: add a friendly name

                string csr = enroll.CreateRequest();           // Output the request in base64 and install it back as the response

                // no password output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
                enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, "");

                // no password, this is for internal consumption
                var base64encoded = enroll.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot);

                // instantiate the target class with the PKCS#12 data (and the empty password)
                // mark the private key as exportable (this is usually what you want to do)

                return(new X509Certificate2(Convert.FromBase64String(base64encoded), "", X509KeyStorageFlags.Exportable));
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        public string CreateRequest()
        {
            // Create all the objects that will be required
            var    objPkcs10         = new CX509CertificateRequestPkcs10();
            var    objPrivKey        = new CX509PrivateKey();
            var    objCSP            = new CCspInformation();
            var    objCSPs           = new CCspInformations();
            var    objDN             = new CX500DistinguishedName();
            var    objEnroll         = new CX509Enrollment();
            var    objObjIds         = new CObjectIds();
            var    objObjId          = new CObjectId();
            var    objExtKeyUsage    = new CX509ExtensionKeyUsage();
            var    objExtEnhKeyUsage = new CX509ExtensionEnhancedKeyUsage();
            string strRequest;

            //objCSP.InitializeFromName(provName);
            //objCSPs.Add(objCSP);

            //objPrivKey.Length = 2048;
            //objPrivKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
            //objPrivKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
            //objPrivKey.MachineContext = true;

            //objPrivKey.CspInformations = objCSPs;
            //objPrivKey.Create();

            var strTemplateName = "1.3.6.1.4.1.311.21.8.12017375.10856495.934812.8687423.15807460.10.5731641.6795722"; // RDP All Names

            objPkcs10.InitializeFromTemplateName(X509CertificateEnrollmentContext.ContextMachine, strTemplateName);

            // Encode the name in using the DN object
            objDN.Encode("CN=" + Environment.GetEnvironmentVariable("COMPUTERNAME"),
                         X500NameFlags.XCN_CERT_NAME_STR_NONE);

            // Adding the subject name by using the DN object initialized above
            objPkcs10.Subject = objDN;

            var dnsDom            = Environment.GetEnvironmentVariable("USERDNSDOMAIN").ToLower();
            var altName           = new CAlternativeName();
            var objAlternateNames = new CAlternativeNames();
            var objExtAltNames    = new CX509ExtensionAlternativeNames();

            altName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME,
                                         Environment.GetEnvironmentVariable("COMPUTERNAME") + "." + dnsDom);
            var altName2 = new CAlternativeName();

            altName2.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME,
                                          Environment.GetEnvironmentVariable("COMPUTERNAME"));


            objAlternateNames.Add(altName2);
            objAlternateNames.Add(altName);
            objExtAltNames.InitializeEncode(objAlternateNames);
            objPkcs10.X509Extensions.Add((CX509Extension)objExtAltNames);

            // Create the enrollment request
            objEnroll.InitializeFromRequest(objPkcs10);
            strRequest = objEnroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64);

            return(strRequest);
        }