Example #1
0
        /// <summary>
        /// Create an initial CA Config file
        /// </summary>
        /// <param name="config">CA Config object</param>
        /// <param name="serialNumber">Initial serial number</param>
        /// <param name="request">Certificate request</param>
        /// <param name="caKey">CA keyfile</param>
        /// <returns>CA Config file location</returns>
        private static string createPendingCAConfig(CAConfig config, BigInteger serialNumber, Pkcs10CertificationRequest request, string caKey)
        {
            string version = "3.1";
            string caEntry = "rqstPending";
            string caValue = Utility.rqst64(request);

            return(createCaConfFile(config, serialNumber, version, caEntry, caValue, null));
        }
Example #2
0
        /// <summary>
        /// Create a final CA Config file
        /// </summary>
        /// <param name="config">CA Config object</param>
        /// <param name="serialNumber">Initial serial number</param>
        /// <param name="cert">CA certificate</param>
        /// <param name="caKey">CA keyfile</param>
        /// <returns>CA Config file location</returns>
        private static string createFinalCAConfig(CAConfig config, BigInteger serialNumber, X509Certificate cert, string caKey)
        {
            string version = "";
            string caEntry = "";
            string caValue = "";

            if (config.FIPS140)
            {
                version = "3.1";
                caEntry = "caCert";
                caValue = Utility.cert64(cert);
            }
            else
            {
                version = "3.0";
                caEntry = "caKey";
                caValue = caKey;
            }

            return(createCaConfFile(config, serialNumber, version, caEntry, caValue, cert));
        }
Example #3
0
        /// <summary>
        /// Create a new Subordinate CA certificate request using the setup parameters from a CAConfig object
        /// </summary>
        /// <remarks>Only System cryptography supported</remarks>
        /// <param name="Config">CAConfig object</param>
        /// <returns>PKCS#10 certificate request</returns>
        public static Pkcs10CertificationRequest CreateSubCA(CAConfig Config)
        {
            if (Config.profile != CA_Profile.SubCA)
            {
                throw new ArgumentException("Invalid profile specified", Config.profile.ToString());
            }

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

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

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

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

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

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

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

            return(p10);
        }
Example #4
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 #5
0
        private static string createCaConfFile(CAConfig config, BigInteger serialNumber, string version, string caEntry, string caValue, X509Certificate caCert)
        {
            string crlFileLocation  = config.location + "\\" + config.name + ".crl";
            string dbfile           = config.location + "\\CADatabase.xml";
            string logFile          = config.location + "\\CALog.xml";
            string profilesLocation = config.location + "\\Profiles";

            // Create CA config file
            XDocument conf = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                new XComment("CA Configuration"),
                new XElement("OSCA",
                             new XAttribute("version", version),
                             new XElement("CA",
                                          new XElement("name", config.name),
                                          new XElement("dn", config.DN),
                                          new XElement("type", config.profile.ToString()), // Called 'type' for historical reasons
                                          new XElement("caType", config.caType.ToString()),
                                          new XElement("created", DateTime.Now.ToUniversalTime()),
                                          new XElement("dbFileLocation", dbfile),
                                          new XElement("logFileLocation", logFile),
                                          new XElement("profilesLocation", profilesLocation),
                                          new XElement("publicKeyAlgorithm", config.pkAlgo),
                                          new XElement("publicKeySize", config.pkSize),
                                          new XElement("signatureAlgorithm", config.sigAlgo),
                                          new XElement("fips140", config.FIPS140),
                                          new XElement("cryptoServiceProvider",
                                                       new XAttribute("cspNumber", config.CSPNum),
                                                       config.CSPName),
                                          new XElement("lastSerial", serialNumber),
                                          new XElement("crlFileLocation", crlFileLocation),
                                          new XElement("lastCRL", 0),
                                          new XElement("crlInterval", config.crlInterval),
                                          new XElement("policyEnforcement"),
                                          new XElement(caEntry, caValue)
                                          )
                             )
                );

            // Do the policyEnforcement bit
            XElement pe = new XElement("policyEnforcement");

            if (config.rollOver != 0)
            {
                pe.Add(new XElement("keyRollOver", config.rollOver.ToString()));
            }

            XElement policyEnforcement = conf.Element("OSCA").Element("CA").Element("policyEnforcement");

            policyEnforcement.ReplaceWith(pe);

            // Sign and save the config file
            // Can't sign for a pending request! (no certificate)
            string configFile = config.location + "\\CAConfig.xml";

            if (caCert != null)
            {
                XmlSigning.SignXml(conf, configFile, caCert, privateKeyCapi);
                // Setup the log file
                LogFile.createLogFile(logFile, version, caCert, privateKeyCapi);
                eventLog = new Logger(logFile, caCert, privateKeyCapi);
            }
            else
            {
                XmlWriter xmlw = XmlWriter.Create(new StreamWriter(configFile));
                conf.WriteTo(xmlw);
                xmlw.Flush();
                xmlw.Close();
            }
            return(configFile);
        }
Example #6
0
        /// <summary>
        /// Create a new Subordinate CA using the setup parameters from a CAConfig object
        /// The Issuing CA must be available to create and sign a certificate
        /// </summary>
        /// <param name="Config">CAConfig object</param>
        /// <param name="IssuingCA">Object reference for issuing CA</param>
        /// <returns>Full pathname of CA config file</returns>
        public static string CreateSubCA(CAConfig Config, ICA IssuingCA)
        {
            if (Config.profile != CA_Profile.SubCA)
            {
                throw new ArgumentException("Invalid profile specified", Config.profile.ToString());
            }

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


            // Key material
            Pkcs10CertificationRequest p10;

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

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

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

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

            string configFile;

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

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

            return(configFile);
        }
Example #7
0
        /// <summary>
        /// Create a CA Database file
        /// </summary>
        /// <param name="config">CA Config object</param>
        /// <param name="cert">CA certificate</param>
        /// <param name="cspParam">CSP with signing key</param>
        /// <returns>Location of the DB file</returns>
        internal static string CreateDB(CAConfig config, X509Certificate cert, CspParameters cspParam)
        {
            string dbfile = config.location + "\\CADatabase.xml";

            return(CreateDB(dbfile, cert, cspParam));
        }
Example #8
0
 /// <summary>
 /// Derive a DN from a CAConfig object
 /// </summary>
 /// <param name="config">CA Config object</param>
 /// <returns>DN of CA</returns>
 public static X509Name getDN(CAConfig config)
 {
     return(new X509Name("CN=" + config.name));
 }