Пример #1
0
        /// <summary>
        /// Construct a CA object
        /// </summary>
        /// <param name="ConfigFile">Full pathname to config file</param>
        /// <param name="Password">Password for key file</param>
        public simpleCA(string ConfigFile, string Password)
        {
            this.configFile = ConfigFile;
            this.password   = Password.ToCharArray();

            // Read in the configuration
            XDocument config;

            if (XmlSigning.VerifyXmlFile(configFile))
            {
                config = XDocument.Load(configFile);
            }
            else
            {
                throw new GeneralSecurityException("Signature failed on CA config file");
            }

            XElement ca = config.Element("OSCA").Element("CA");

            this.name               = ca.Element("name").Value;
            this.type               = ca.Element("type").Value;
            this.dbFileLocation     = ca.Element("dbFileLocation").Value;
            this.publicKeyAlgorithm = ca.Element("publicKeyAlgorithm").Value;
            this.publicKeySize      = ca.Element("publicKeySize").Value;
            this.signatureAlgorithm = ca.Element("signatureAlgorithm").Value;
            this.fips140            = Convert.ToBoolean(ca.Element("fips140").Value);
            this.lastSerial         = ca.Element("lastSerial").Value;
            this.crlFileLocation    = ca.Element("crlFileLocation").Value;
            this.lastCRL            = ca.Element("lastCRL").Value;
            this.crlInterval        = Convert.ToDouble(ca.Element("crlInterval").Value);
            this.profilesLocation   = ca.Element("profilesLocation").Value;

            //Read in the private key and certificate
            MemoryStream p12stream = new MemoryStream(Convert.FromBase64String(ca.Element("caKey").Value));
            Pkcs12Store  p12       = new Pkcs12Store(p12stream, password);

            this.privateKey    = p12.GetKey(this.name).Key;
            this.caCertificate = p12.GetCertificate(this.name).Certificate;

            if (ca.Element("policyEnforcement") != null)
            {
                policyEnforcement = PolicyEnforcementFactory.initialise(caCertificate, ca.Element("policyEnforcement"));
            }

            // Create CspParameters to support XML signing
            cspParam = SysKeyManager.LoadCsp(privateKey);

            // Setup the Event Logger
            eventLog = new Logger(ca.Element("logFileLocation").Value, caCertificate, cspParam);

            // Check our certificate is valid
            // --- TODO

            // Log startup event
            logEvent(LogEvent.EventType.StartCA, "CA Started");

            // Expire any old certificates
            Database.ExpireCertificate(dbFileLocation, caCertificate, cspParam);
        }
Пример #2
0
        /// <summary>
        /// Create an instance of a generic Bouncy Castle Crypto CA
        /// </summary>
        /// <param name="ConfigFile">Full pathname to config file</param>
        /// <param name="Password">Password for CA key file</param>
        public bcCA(string ConfigFile, string Password) : base(ConfigFile)
        {
            // Make sure the CA_Type is correct
            if (fips140)
            {
                throw new InvalidParameterException("Invalid FIPS140 flag for this CA instance");
            }

            this.password = Password.ToCharArray();

            //Read in the private key and certificate
            MemoryStream p12stream = new MemoryStream(Convert.FromBase64String(ca.Element("caKey").Value));
            Pkcs12Store  p12       = new Pkcs12Store(p12stream, password);

            this.privateKey    = p12.GetKey(this.name).Key;
            this.caCertificate = p12.GetCertificate(this.name).Certificate;

            // Setup CA policy
            if (ca.Element("policyEnforcement") != null)
            {
                policyEnforcement = PolicyEnforcementFactory.initialise(caCertificate, ca.Element("policyEnforcement"));
            }

            // Create CspParameters to support XML signing
            cspParam = SysKeyManager.LoadCsp(privateKey);

            // Setup the Event Logger
            eventLog = new Logger(ca.Element("logFileLocation").Value, caCertificate, cspParam);

            // Check our certificate is valid
            // --- TODO

            // Log startup event
            logEvent(LogEvent.EventType.StartCA, "CA Started");

            // Expire any old certificates
            Database.ExpireCertificate(dbFileLocation, caCertificate, cspParam);
        }
Пример #3
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);
        }
Пример #4
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);
        }