Example #1
0
        /// <summary>
        /// Create a root (self-signed) CA
        /// </summary>
        /// <param name="Config">CA Config structure containing the initialisation parameters</param>
        /// <returns>Full pathname for the configuration file</returns>
        public static string CreateRootCA(CAConfig Config)
        {
            if (Config.profile != CA_Profile.rootCA)
            {
                throw new ArgumentException("Invalid profile specified", Config.profile.ToString());
            }

            // Start/end dates
            DateTime startDate = DateTime.UtcNow;
            DateTime expiryDate;

            switch (Config.units)
            {
            case "Years":
                expiryDate = startDate.AddYears(Config.life);
                break;

            case "Months":
                expiryDate = startDate.AddMonths(Config.life);
                break;

            case "Days":
                expiryDate = startDate.AddDays(Config.life);
                break;

            default:
                throw new ArgumentException("Invalid lifetime unit", Config.units);
            }

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

            // Certificate
            ICertGen certGen;

            // The OLD method was to use the Config.pkAlgo field to select a hard-coded CSP
            // The new approach is to have the user select a CSP
            //OLD method
            if (Config.FIPS140)
            {
                switch (Config.caType)
                {
                case CA_Type.sysCA:
                case CA_Type.dhTA:
                    privateKeyCapi = SysKeyManager.Create(Config.pkSize, Config.pkAlgo, Config.name);
                    publicKey      = SysKeyManager.getPublicKey(privateKeyCapi, Config.pkAlgo);
                    if (Config.version == X509ver.V1)
                    {
                        certGen = new SysV1CertGen();
                    }
                    else
                    {
                        certGen = new SysV3CertGen();
                    }
                    break;

                case CA_Type.cngCA:
                    privateKeyCng = CngKeyManager.Create(CngAlgorithm.ECDsaP256, Config.name);
                    publicKey     = CngKeyManager.getPublicKey(privateKeyCng);
                    //if (Config.version == X509ver.V1)
                    //    certGen = new CngV1CertGen();
                    //else
                    certGen = new CngV3CertGen();
                    break;

                default:
                    throw new InvalidParameterException("CA Type not compatible with Fips140 flag: " + Config.caType.ToString());
                }
            }
            else
            {
                keyPair = BcKeyManager.Create(Config.pkSize, Config.pkAlgo);

                // Create a system CspParameters entry for use by XmlSigner
                // Only for RSA and DSA currently until EC XML signing is sorted
                if (!Config.pkAlgo.Contains("EC"))
                {
                    privateKeyCapi = SysKeyManager.LoadCsp(keyPair.Private);
                }
                else
                {
                    privateKeyCapi = null;
                }

                publicKey = keyPair.Public;
                if (Config.version == X509ver.V1)
                {
                    certGen = new BcV1CertGen();
                }
                else
                {
                    certGen = new BcV3CertGen();
                }
            }

            //NEW method
            //if ((Config.FIPS140) && (Config.CSPNum > 0))    // System crypto
            //{
            //    cspParam = SysKeyManager.Create(Config.pkSize, Config.CSPName, Config.CSPNum, Config.name);
            //}

            // V1 and V3 fields
            certGen.SetSerialNumber(serialNumber);
            certGen.SetIssuerDN(Config.DN);
            certGen.SetNotBefore(startDate);
            certGen.SetNotAfter(expiryDate);
            certGen.SetSubjectDN(Config.DN);
            certGen.SetPublicKey(publicKey);
            certGen.SetSignatureAlgorithm(Config.sigAlgo);

            // V3 extensions
            if (Config.version == X509ver.V3)
            {
                ((V3CertGen)certGen).AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(publicKey));
                ((V3CertGen)certGen).AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(publicKey));
                ((V3CertGen)certGen).AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));
                ((V3CertGen)certGen).AddExtension(X509Extensions.KeyUsage, true, new X509KeyUsage(Config.keyUsage));
            }

            X509Certificate caCert;

            if (Config.FIPS140)
            {
                switch (Config.caType)
                {
                case CA_Type.sysCA:
                case CA_Type.dhTA:
                    caCert = ((IsysCertGen)certGen).Generate(privateKeyCapi);
                    break;

                case CA_Type.cngCA:
                    caCert = ((IcngCertGen)certGen).Generate(privateKeyCng);
                    break;

                default:
                    throw new InvalidParameterException("CA Type not compatible with Fips140 flag: " + Config.caType.ToString());
                }
            }
            else
            {
                caCert = ((IbcCertGen)certGen).Generate(keyPair.Private);
            }

            caCert.Verify(caCert.GetPublicKey());

            string configFile;

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

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

            // Create CA database
            string dbFile = Database.CreateDB(Config, caCert, privateKeyCapi);

            // Insert Root CA certificate
            byte[] dummy = new byte[0];
            Database.AddCertificate(caCert, dummy, "rootCA", dbFile, caCert, privateKeyCapi);

            return(configFile);
        }
Example #2
0
        /// <summary>
        /// Issues the certificate.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="profile">The profile</param>
        /// <param name="notBefore">The not before.</param>
        /// <param name="notAfter">The not after.</param>
        /// <returns>
        /// Certificate
        /// </returns>
        /// <exception cref="System.ArgumentException">Invalid signature algorithm in request</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Invalid lifetime units in ValidityPeriod</exception>
        private X509Certificate issueCertificate(Pkcs10CertificationRequest request, Profile.Profile profile, DateTime notBefore, DateTime notAfter)
        {
            X509Certificate newCert;
            string          profileName = "";

            // Parse the request
            Pkcs10Parser p10 = new Pkcs10Parser(request);

            // Check that correct sig algorithm has been used
            DerObjectIdentifier sigAlgOid = X509Utilities.GetAlgorithmOid(signatureAlgorithm);

            if (!p10.SignatureAlgorithm.Equals(sigAlgOid))
            {
                logEvent(LogEvent.EventType.Error, "Invalid signature algorithm in request: " + p10.SignatureAlgorithm.ToString());
                throw new ArgumentException("Invalid signature algorithm in request", p10.SignatureAlgorithm.ToString());
            }

            // Create a Cert Generator according to the FIPS 140 policy and CA Type
            ICertGen certGen;

            if ((fips140) && (type == CA_Type.dhTA.ToString()))
            {
                certGen = new SysV1CertGen();
            }
            else if ((fips140) && (type != CA_Type.dhTA.ToString()))
            {
                certGen = new SysV3CertGen(policyEnforcement);
            }
            else
            {
                certGen = new BcV3CertGen(policyEnforcement);
            }

            // Setup the certificate
            certGen.SetSerialNumber(nextCertSerial());
            certGen.SetIssuerDN(caCertificate.SubjectDN);
            certGen.SetSubjectDN(p10.Subject);
            certGen.SetPublicKey(p10.PublicKey);
            certGen.SetSignatureAlgorithm(signatureAlgorithm);
            if (certGen.GetVersion() == X509ver.V3)
            {
                ((V3CertGen)certGen).AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCertificate.GetPublicKey()));
                ((V3CertGen)certGen).AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(p10.PublicKey));
            }

            // Add further extensions either from profile or request attributes
            // If a profile is specified ignore all attributes apart from SubjAltName
            if (profile != null)
            {
                // Add in SubjAltName if there is one
                if ((p10.SubjectAltNames != null) && (certGen.GetVersion() == X509ver.V3))
                {
                    bool critical = p10.IsCritical(X509Extensions.SubjectAlternativeName);
                    ((V3CertGen)certGen).AddExtension(X509Extensions.SubjectAlternativeName, critical, p10.SubjectAltNames);
                }

                // Capture the profile name for database
                profileName = profile.Name;

                // cut the cert
                newCert = generate(certGen, profile, notBefore, notAfter);
            }
            else    // No profile
            {
                // Set the validity period
                certGen.SetNotBefore(notBefore.ToUniversalTime());
                certGen.SetNotAfter(notAfter.ToUniversalTime());

                // Do what it says in the request
                newCert = generate(certGen, p10.Extensions);
            }

            // Add certificate to the CA DB
            Database.AddCertificate(newCert, request.GetDerEncoded(), profileName, dbFileLocation, caCertificate, cspParam);
            logEvent(LogEvent.EventType.DBAddCert, "DB: Certificate added: " + newCert.SerialNumber.ToString());

            return(newCert);
        }