/// <summary> /// Create an instance of a generic System Crypto CA /// </summary> /// <param name="ConfigFile">Full pathname to config file</param> /// <exception cref="InvalidParameterException">Invalid FIPS140 flag for this CA instance</exception> public sysCA(string ConfigFile) : base(ConfigFile) { // Make sure the CA_Type is correct if (!fips140) { throw new InvalidParameterException("Invalid FIPS140 flag for this CA instance"); } // Get a reference to the key container for the signing key cspParam = SysKeyManager.Read(name); X509CertificateParser cp = new X509CertificateParser(); caCertificate = cp.ReadCertificate(Convert.FromBase64String(ca.Element("caCert").Value)); // Setup CA policy if (ca.Element("policyEnforcement") != null) { policyEnforcement = PolicyEnforcementFactory.initialise(caCertificate, ca.Element("policyEnforcement")); } // Setup the logger startLogging(); // Expire any old certificates Database.ExpireCertificate(dbFileLocation, caCertificate, cspParam); }
/// <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); }
/// <summary> /// Construct a CA object /// </summary> /// <param name="ConfigFile">Full pathname to config file</param> public fipsCA(string ConfigFile) : base() { configFile = ConfigFile; // 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"); fips140 = Convert.ToBoolean(ca.Element("fips140").Value); if (!fips140) { throw new InvalidOperationException("Invalid FIPS140 flag for this CA instance"); } if (ca.Element("rqstPending") != null) { throw new InvalidOperationException("CA is not configured: Request pending"); } name = ca.Element("name").Value; type = ca.Element("type").Value; dbFileLocation = ca.Element("dbFileLocation").Value; publicKeyAlgorithm = ca.Element("publicKeyAlgorithm").Value; publicKeySize = ca.Element("publicKeySize").Value; signatureAlgorithm = ca.Element("signatureAlgorithm").Value; lastSerial = ca.Element("lastSerial").Value; crlFileLocation = ca.Element("crlFileLocation").Value; lastCRL = ca.Element("lastCRL").Value; crlInterval = Convert.ToDouble(ca.Element("crlInterval").Value); profilesLocation = ca.Element("profilesLocation").Value; cspParam = SysKeyManager.Read(name); X509CertificateParser cp = new X509CertificateParser(); caCertificate = cp.ReadCertificate(Convert.FromBase64String(ca.Element("caCert").Value)); // Setup the Event Logger eventLog = new Logger(ca.Element("logFileLocation").Value, caCertificate, cspParam); // Log startup event logEvent(LogEvent.EventType.StartCA, "CA Started"); // Expire any old certificates Database.ExpireCertificate(dbFileLocation, caCertificate, cspParam); }
public void CreateTest1() { CspParameters cspParam = SysKeyManager.Create(1024, "DSA", "Test Key Data"); CspProviderFlags flags = cspParam.Flags; Assert.AreEqual("UseArchivableKey", flags.ToString()); Assert.AreEqual("Test_Key_Data", cspParam.KeyContainerName); Assert.AreEqual <int>(13, cspParam.ProviderType); //CryptoKeySecurity sy = cspParam.CryptoKeySecurity; }
private void butAdd_Click(object sender, EventArgs e) { if (cbImport.Checked && (keyFile == "")) { DialogResult = DialogResult.Cancel; return; } configFile = tbConfigFile.Text; CA newCA = new CA(); // Load the data from the CA config file XDocument config = XDocument.Load(configFile); newCA.CaName = config.Element("OSCA").Element("CA").Element("name").Value; newCA.Role = config.Element("OSCA").Element("CA").Element("type").Value; newCA.ConfigLocation = configFile; bool fips140 = Convert.ToBoolean(config.Element("OSCA").Element("CA").Element("fips140").Value); // If this is a FIPS CA then load the keyfile if requested, otherwise ignore the keyfile if (fips140 && cbImport.Checked) { X509CertificateParser cp = new X509CertificateParser(); X509Certificate caCert = cp.ReadCertificate(Convert.FromBase64String(config.Element("OSCA").Element("CA").Element("caCert").Value)); // Import the keyfile byte[] p12 = File.ReadAllBytes(keyFile); X509Certificate importCert = null; try { importCert = SysKeyManager.ImportFromP12(p12, null, newCA.CaName, password.ToCharArray()); } catch (IOException ex) { MessageBox.Show(ex.Message, "Import key file", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); DialogResult = DialogResult.Cancel; return; } if (!caCert.SerialNumber.Equals(importCert.SerialNumber)) { MessageBox.Show("Certificate in PKCS#12 does not match certificate in CA Config file", "Import key file", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); DialogResult = DialogResult.Cancel; return; } } mgrConfig.InsertCA(newCA); DialogResult = DialogResult.OK; }
/// <summary> /// Backup the CA key material to a PKCS#12 file /// </summary> /// <param name="Password">Strong password used for encryption</param> /// <param name="OutputFile">Full pathname to the PKCS#12 output file</param> /// <exception cref="System.ApplicationException">Failed Key Backup</exception> public override void Backup(string Password, string OutputFile) { try { SysKeyManager.ExportToP12(cspParam, caCertificate, OutputFile, Password, name); logEvent(LogEvent.EventType.BackupCAKey, "CA Key backup: " + OutputFile); } catch (Exception ex) { logEvent(LogEvent.EventType.Error, "Failed key backup: " + ex.Message); throw new ApplicationException("Failed Key Backup", ex); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }