diff options
author | Ade Lee <alee@redhat.com> | 2012-04-13 13:51:32 -0400 |
---|---|---|
committer | Ade Lee <alee@redhat.com> | 2012-05-01 17:22:38 -0400 |
commit | 80aff97bedf8c2ee5f58209f36f18ebbc475ccb1 (patch) | |
tree | 7a4e6a79f0e29c0596c81aaef47009d66cb56ccf /base/common | |
parent | dd566ed3c64a69801a9edf3b27f11077aa40ecef (diff) | |
download | pki-80aff97bedf8c2ee5f58209f36f18ebbc475ccb1.tar.gz pki-80aff97bedf8c2ee5f58209f36f18ebbc475ccb1.tar.xz pki-80aff97bedf8c2ee5f58209f36f18ebbc475ccb1.zip |
RESTful servlet to configure system in a single servlet.
Installation code common to the panels and the installation servlet are extracted to a
ConfigurationUtils file. The panel code will be cleaned up to use the code in this
class in a later commit.
Contains restful client and test driver code. The test driver code should be modified
and placed in a junit/system test framework. Installation has been tested to work with
the following installations: master CA, clone CA, KRA, OCSP, TKS, subordinate CA, CA
signed by external CA (parts 1 and 2).
Ticket #155
Diffstat (limited to 'base/common')
17 files changed, 7318 insertions, 4 deletions
diff --git a/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java b/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java new file mode 100644 index 000000000..4ac322d63 --- /dev/null +++ b/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java @@ -0,0 +1,1048 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.test; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.net.URISyntaxException; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import netscape.security.x509.X500Name; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.BIT_STRING; +import org.mozilla.jss.asn1.INTEGER; +import org.mozilla.jss.asn1.InvalidBERException; +import org.mozilla.jss.asn1.SEQUENCE; +import org.mozilla.jss.crypto.AlreadyInitializedException; +import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.KeyPairAlgorithm; +import org.mozilla.jss.crypto.KeyPairGenerator; +import org.mozilla.jss.crypto.TokenException; +import org.mozilla.jss.pkix.crmf.CertReqMsg; +import org.mozilla.jss.pkix.crmf.CertRequest; +import org.mozilla.jss.pkix.crmf.CertTemplate; +import org.mozilla.jss.pkix.crmf.POPOPrivKey; +import org.mozilla.jss.pkix.crmf.ProofOfPossession; +import org.mozilla.jss.pkix.primitive.Name; +import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; +import org.mozilla.jss.util.Password; + +import com.netscape.cms.servlet.csadmin.ConfigurationRESTClient; +import com.netscape.cms.servlet.csadmin.model.CertData; +import com.netscape.cms.servlet.csadmin.model.ConfigurationData; +import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData; +import com.netscape.cmsutil.util.Utils; + +/** + * @author alee + * + */ +public class ConfigurationTest { + + public static void usage(Options options) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("ConfigurationTest", options); + System.exit(1); + } + + public static void main(String args[]) throws NoSuchAlgorithmException, TokenException, IOException, InvalidBERException { + String host = null; + String port = null; + String cstype = null; + String token_pwd = null; + String db_dir = "./"; + String protocol = "https"; + String pin = null; + String extCertFile = null; + String extChainFile = null; + int testnum=1; + + // parse command line arguments + Options options = new Options(); + options.addOption("t", true, "Subsystem type"); + options.addOption("h", true, "Hostname of the CS subsystem"); + options.addOption("p", true, "Port of the CS subsystem"); + options.addOption("w", true, "Token password"); + options.addOption("d", true, "Directory for tokendb"); + options.addOption("s", true, "preop pin"); + options.addOption("e", true, "File for externally signed signing cert"); + options.addOption("g", true, "File for external CA cert chain"); + options.addOption("x", true, "Test number"); + + try { + CommandLineParser parser = new PosixParser(); + CommandLine cmd = parser.parse(options, args); + + if (cmd.hasOption("t")) { + cstype = cmd.getOptionValue("t"); + } else { + System.err.println("Error: no subsystem type provided."); + usage(options); + } + + if (cmd.hasOption("h")) { + host = cmd.getOptionValue("h"); + } else { + System.err.println("Error: no hostname provided."); + usage(options); + } + + if (cmd.hasOption("p")) { + port = cmd.getOptionValue("p"); + } else { + System.err.println("Error: no port provided"); + usage(options); + } + + if (cmd.hasOption("w")) { + token_pwd = cmd.getOptionValue("w"); + } else { + System.err.println("Error: no token password provided"); + usage(options); + } + + if (cmd.hasOption("d")) { + db_dir = cmd.getOptionValue("d"); + } + + if (cmd.hasOption("s")) { + pin = cmd.getOptionValue("s"); + } + + if (cmd.hasOption("e")) { + extCertFile = cmd.getOptionValue("e"); + } + + if (cmd.hasOption("g")) { + extChainFile = cmd.getOptionValue("g"); + } + + if (cmd.hasOption("x")) { + testnum = Integer.parseInt(cmd.getOptionValue("x")); + } + } catch (ParseException e) { + System.err.println("Error in parsing command line options: " + e.getMessage()); + usage(options); + } + + // Initialize token + try { + CryptoManager.initialize(db_dir); + } catch (AlreadyInitializedException e) { + // it is ok if it is already initialized + } catch (Exception e) { + System.out.println("INITIALIZATION ERROR: " + e.toString()); + System.exit(1); + } + + // log into token + CryptoManager manager = null; + CryptoToken token = null; + try { + manager = CryptoManager.getInstance(); + token = manager.getInternalKeyStorageToken(); + Password password = new Password(token_pwd.toCharArray()); + try { + token.login(password); + } catch (Exception e) { + System.out.println("login Exception: " + e.toString()); + if (!token.isLoggedIn()) { + token.initPassword(password, password); + } + } + } catch (Exception e) { + System.out.println("Exception in logging into token:" + e.toString()); + } + + String baseUri = protocol + "://" + host + ":" + port + "/" + cstype + "/pki"; + ConfigurationRESTClient client = null; + try { + client = new ConfigurationRESTClient(baseUri, null); + } catch (URISyntaxException e1) { + e1.printStackTrace(); + System.exit(1); + } + + ConfigurationData data = null; + switch (testnum) { + case 1: + data = constructCAData(host, port, pin, db_dir, token_pwd, token); + break; + case 2: + data = constructCloneCAData(host, port, pin, db_dir, token_pwd, token); + break; + case 3: + data = constructKRAData(host, port, pin, db_dir, token_pwd, token); + break; + case 4: + data = constructOCSPData(host, port, pin, db_dir, token_pwd, token); + break; + case 5: + data = constructTKSData(host, port, pin, db_dir, token_pwd, token); + break; + case 6: + data = constructSubCAData(host, port, pin, db_dir, token_pwd, token); + break; + case 7: + data = constructExternalCADataPart1(host, port, pin, db_dir, token_pwd, token); + break; + case 8: + data = constructExternalCADataPart2(host, port, pin, db_dir, token_pwd, token, extCertFile, extChainFile); + break; + default: + System.out.println("Invalid test"); + System.exit(1); + } + + ConfigurationResponseData response = client.configure(data); + + System.out.println("status: " + response.getStatus()); + System.out.println("adminCert: " + response.getAdminCert().getCert()); + Collection<CertData> certs = response.getSystemCerts(); + Iterator<CertData> iterator = certs.iterator(); + while (iterator.hasNext()) { + CertData cdata = iterator.next(); + System.out.println("tag: " + cdata.getTag()); + System.out.println("cert: " + cdata.getCert()); + System.out.println("request: " + cdata.getRequest()); + } + + } + + private static ConfigurationData constructCAData(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException, + InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + data.setSecurityDomainType(ConfigurationData.NEW_DOMAIN); + data.setSecurityDomainName("Testca2 security domain"); + data.setIsClone("false"); + data.setHierarchy("root"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test ca subsystem"); + + data.setDsHost(host); + data.setDsPort("7389"); + data.setBaseDN("o=testca2"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testca2"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("true"); + data.setBackupFile("/tmp/testca.p12"); + data.setBackupPassword("redhat123"); + + data.setAdminEmail("alee@redhat.com"); + data.setAdminName("admin"); + data.setAdminPassword("redhat123"); + data.setAdminProfileID("caAdminCert"); + data.setAdminUID("admin"); + String subjectdn = "CN=CA Administrator of Instance testca, UID=admin, E=alee@redhat.com, o=testca2"; + data.setAdminSubjectDN(subjectdn); + + String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false); + data.setAdminCertRequest(crmf_request); + data.setAdminCertRequestType("crmf"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + CertData cert1 = new CertData(); + cert1.setTag("signing"); + cert1.setKeyAlgorithm("SHA256withRSA"); + cert1.setKeySize("2048"); + cert1.setKeyType("rsa"); + cert1.setNickname("signingCert testca"); + cert1.setSigningAlgorithm("SHA256withRSA"); + cert1.setSubjectDN("CN=CA Signing Certificate"); + cert1.setToken("Internal Key Storage Token"); + + systemCerts.add(cert1); + + CertData cert2 = new CertData(); + cert2.setTag("ocsp_signing"); + cert2.setKeyAlgorithm("SHA256withRSA"); + cert2.setKeySize("2048"); + cert2.setKeyType("rsa"); + cert2.setNickname("ocspSigningCert testca"); + cert2.setSigningAlgorithm("SHA256withRSA"); + cert2.setSubjectDN("CN= CA OCSP Signing Certificate"); + cert2.setToken("Internal Key Storage Token"); + systemCerts.add(cert2); + + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testca"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + CertData cert4 = new CertData(); + cert4.setTag("subsystem"); + cert4.setKeyAlgorithm("SHA256withRSA"); + cert4.setKeySize("2048"); + cert4.setKeyType("rsa"); + cert4.setNickname("subsystemCert testca"); + cert4.setSubjectDN("CN=CA Subsystem Certificate"); + cert4.setToken("Internal Key Storage Token"); + systemCerts.add(cert4); + + CertData cert5 = new CertData(); + cert5.setTag("audit_signing"); + cert5.setKeyAlgorithm("SHA256withRSA"); + cert5.setKeySize("2048"); + cert5.setKeyType("rsa"); + cert5.setNickname("auditSigningCert testca"); + cert5.setSigningAlgorithm("SHA256withRSA"); + cert5.setSubjectDN("CN=CA Audit Signing Certificate"); + cert5.setToken("Internal Key Storage Token"); + systemCerts.add(cert5); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static ConfigurationData constructSubCAData(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException, + InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + + data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN); + data.setSecurityDomainUri("https://" + host + ":9225"); + data.setSecurityDomainUser("admin"); + data.setSecurityDomainPassword("redhat123"); + + data.setIsClone("false"); + data.setHierarchy("join"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test subca subsystem"); + + data.setDsHost(host); + data.setDsPort("7389"); + data.setBaseDN("o=testsubca"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testsubca"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("true"); + data.setBackupFile("/tmp/testsubca.p12"); + data.setBackupPassword("redhat123"); + + data.setAdminEmail("alee@redhat.com"); + data.setAdminName("admin"); + data.setAdminPassword("redhat123"); + data.setAdminProfileID("caAdminCert"); + data.setAdminUID("admin"); + String subjectdn = "CN=CA Administrator of Instance testsubca, UID=admin, E=alee@redhat.com, o=testsubca"; + data.setAdminSubjectDN(subjectdn); + + String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false); + data.setAdminCertRequest(crmf_request); + data.setAdminCertRequestType("crmf"); + + data.setIssuingCA("https://" + host + ":9224"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + CertData cert1 = new CertData(); + cert1.setTag("signing"); + cert1.setKeyAlgorithm("SHA256withRSA"); + cert1.setKeySize("2048"); + cert1.setKeyType("rsa"); + cert1.setNickname("signingCert testsubca"); + cert1.setSigningAlgorithm("SHA256withRSA"); + cert1.setSubjectDN("CN=SubCA Signing Certificate"); + cert1.setToken("Internal Key Storage Token"); + + systemCerts.add(cert1); + + CertData cert2 = new CertData(); + cert2.setTag("ocsp_signing"); + cert2.setKeyAlgorithm("SHA256withRSA"); + cert2.setKeySize("2048"); + cert2.setKeyType("rsa"); + cert2.setNickname("ocspSigningCert testsubca"); + cert2.setSigningAlgorithm("SHA256withRSA"); + cert2.setSubjectDN("CN= SubCA OCSP Signing Certificate"); + cert2.setToken("Internal Key Storage Token"); + systemCerts.add(cert2); + + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testsubca"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + CertData cert4 = new CertData(); + cert4.setTag("subsystem"); + cert4.setKeyAlgorithm("SHA256withRSA"); + cert4.setKeySize("2048"); + cert4.setKeyType("rsa"); + cert4.setNickname("subsystemCert testsubca"); + cert4.setSubjectDN("CN=SubCA Subsystem Certificate"); + cert4.setToken("Internal Key Storage Token"); + systemCerts.add(cert4); + + CertData cert5 = new CertData(); + cert5.setTag("audit_signing"); + cert5.setKeyAlgorithm("SHA256withRSA"); + cert5.setKeySize("2048"); + cert5.setKeyType("rsa"); + cert5.setNickname("auditSigningCert testsubca"); + cert5.setSigningAlgorithm("SHA256withRSA"); + cert5.setSubjectDN("CN=SubCA Audit Signing Certificate"); + cert5.setToken("Internal Key Storage Token"); + systemCerts.add(cert5); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static ConfigurationData constructExternalCADataPart1(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException, + InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + + data.setSecurityDomainType(ConfigurationData.NEW_DOMAIN); + data.setSecurityDomainName("External CA security domain"); + + data.setIsClone("false"); + data.setHierarchy("join"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test external ca subsystem"); + + data.setDsHost(host); + data.setDsPort("7389"); + data.setBaseDN("o=testexternalca"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testexternalca"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("true"); + data.setBackupFile("/tmp/testexternalca.p12"); + data.setBackupPassword("redhat123"); + + data.setAdminEmail("alee@redhat.com"); + data.setAdminName("admin"); + data.setAdminPassword("redhat123"); + data.setAdminProfileID("caAdminCert"); + data.setAdminUID("admin"); + String subjectdn = "CN=CA Administrator of Instance testexternalca, UID=admin, E=alee@redhat.com, o=testexternalca"; + data.setAdminSubjectDN(subjectdn); + + String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false); + data.setAdminCertRequest(crmf_request); + data.setAdminCertRequestType("crmf"); + + data.setIssuingCA("External CA"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + CertData cert1 = new CertData(); + cert1.setTag("signing"); + cert1.setKeyAlgorithm("SHA256withRSA"); + cert1.setKeySize("2048"); + cert1.setKeyType("rsa"); + cert1.setNickname("signingCert testexternalca"); + cert1.setSigningAlgorithm("SHA256withRSA"); + cert1.setSubjectDN("CN=External CA Signing Certificate"); + cert1.setToken("Internal Key Storage Token"); + + systemCerts.add(cert1); + + CertData cert2 = new CertData(); + cert2.setTag("ocsp_signing"); + cert2.setKeyAlgorithm("SHA256withRSA"); + cert2.setKeySize("2048"); + cert2.setKeyType("rsa"); + cert2.setNickname("ocspSigningCert testexternalca"); + cert2.setSigningAlgorithm("SHA256withRSA"); + cert2.setSubjectDN("CN= External CA OCSP Signing Certificate"); + cert2.setToken("Internal Key Storage Token"); + systemCerts.add(cert2); + + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testexternalca"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + CertData cert4 = new CertData(); + cert4.setTag("subsystem"); + cert4.setKeyAlgorithm("SHA256withRSA"); + cert4.setKeySize("2048"); + cert4.setKeyType("rsa"); + cert4.setNickname("subsystemCert testexternalca"); + cert4.setSubjectDN("CN=External CA Subsystem Certificate"); + cert4.setToken("Internal Key Storage Token"); + systemCerts.add(cert4); + + CertData cert5 = new CertData(); + cert5.setTag("audit_signing"); + cert5.setKeyAlgorithm("SHA256withRSA"); + cert5.setKeySize("2048"); + cert5.setKeyType("rsa"); + cert5.setNickname("auditSigningCert testexternalca"); + cert5.setSigningAlgorithm("SHA256withRSA"); + cert5.setSubjectDN("CN=SubCA Audit Signing Certificate"); + cert5.setToken("Internal Key Storage Token"); + systemCerts.add(cert5); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static ConfigurationData constructExternalCADataPart2(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token, String extCertFile, String extChainFile) + throws NoSuchAlgorithmException, TokenException, IOException, InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + + data.setSecurityDomainType(ConfigurationData.NEW_DOMAIN); + data.setSecurityDomainName("External CA security domain"); + + data.setIsClone("false"); + data.setHierarchy("join"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test external ca subsystem"); + + data.setDsHost(host); + data.setDsPort("7389"); + data.setBaseDN("o=testexternalca"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testexternalca"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("true"); + data.setBackupFile("/tmp/testexternalca.p12"); + data.setBackupPassword("redhat123"); + + data.setAdminEmail("alee@redhat.com"); + data.setAdminName("admin"); + data.setAdminPassword("redhat123"); + data.setAdminProfileID("caAdminCert"); + data.setAdminUID("admin"); + String subjectdn = "CN=CA Administrator of Instance testexternalca, UID=admin, E=alee@redhat.com, o=testexternalca"; + data.setAdminSubjectDN(subjectdn); + + String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false); + data.setAdminCertRequest(crmf_request); + data.setAdminCertRequestType("crmf"); + + data.setIssuingCA("External CA"); + data.setStepTwo("true"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + CertData cert1 = new CertData(); + cert1.setTag("signing"); + cert1.setKeyAlgorithm("SHA256withRSA"); + cert1.setKeySize("2048"); + cert1.setKeyType("rsa"); + cert1.setNickname("signingCert testexternalca"); + cert1.setSigningAlgorithm("SHA256withRSA"); + cert1.setSubjectDN("CN=External CA Signing Certificate"); + cert1.setToken("Internal Key Storage Token"); + + String extCert = ""; + BufferedReader in = new BufferedReader(new FileReader(extCertFile)); + while (in.ready()) { + extCert += in.readLine(); + } + in.close(); + cert1.setCert(extCert); + + String extCertChain = ""; + in = new BufferedReader(new FileReader(extChainFile)); + while (in.ready()) { + extCertChain += in.readLine(); + } + in.close(); + cert1.setCertChain(extCertChain); + + systemCerts.add(cert1); + + CertData cert2 = new CertData(); + cert2.setTag("ocsp_signing"); + cert2.setKeyAlgorithm("SHA256withRSA"); + cert2.setKeySize("2048"); + cert2.setKeyType("rsa"); + cert2.setNickname("ocspSigningCert testexternalca"); + cert2.setSigningAlgorithm("SHA256withRSA"); + cert2.setSubjectDN("CN= External CA OCSP Signing Certificate"); + cert2.setToken("Internal Key Storage Token"); + systemCerts.add(cert2); + + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testexternalca"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + CertData cert4 = new CertData(); + cert4.setTag("subsystem"); + cert4.setKeyAlgorithm("SHA256withRSA"); + cert4.setKeySize("2048"); + cert4.setKeyType("rsa"); + cert4.setNickname("subsystemCert testexternalca"); + cert4.setSubjectDN("CN=External CA Subsystem Certificate"); + cert4.setToken("Internal Key Storage Token"); + systemCerts.add(cert4); + + CertData cert5 = new CertData(); + cert5.setTag("audit_signing"); + cert5.setKeyAlgorithm("SHA256withRSA"); + cert5.setKeySize("2048"); + cert5.setKeyType("rsa"); + cert5.setNickname("auditSigningCert testexternalca"); + cert5.setSigningAlgorithm("SHA256withRSA"); + cert5.setSubjectDN("CN=SubCA Audit Signing Certificate"); + cert5.setToken("Internal Key Storage Token"); + systemCerts.add(cert5); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static ConfigurationData constructCloneCAData(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException, + InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN); + data.setSecurityDomainUri("https://" + host + ":9225"); + data.setSecurityDomainUser("admin"); + data.setSecurityDomainPassword("redhat123"); + + data.setIsClone("true"); + data.setCloneUri("https://" + host + ":9224" ); + data.setP12File("master.p12"); + data.setP12Password("redhat123"); + + data.setHierarchy("root"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test clone ca subsystem"); + + data.setDsHost(host); + data.setDsPort("7494"); + data.setBaseDN("o=testca2"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testca2"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("false"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testca"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static ConfigurationData constructKRAData(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException, + InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + + data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN); + data.setSecurityDomainUri("https://" + host + ":9225"); + data.setSecurityDomainUser("admin"); + data.setSecurityDomainPassword("redhat123"); + + data.setIsClone("false"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test kra subsystem"); + + data.setDsHost(host); + data.setDsPort("7389"); + data.setBaseDN("o=testkra22"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testkra"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("true"); + data.setBackupFile("/tmp/testkra.p12"); + data.setBackupPassword("redhat123"); + + data.setAdminEmail("alee@redhat.com"); + data.setAdminName("admin"); + data.setAdminPassword("redhat123"); + data.setAdminProfileID("caAdminCert"); + data.setAdminUID("admin"); + String subjectdn = "CN=KRA Administrator of Instance testkra, UID=admin, E=alee@redhat.com, o=testkra22"; + data.setAdminSubjectDN(subjectdn); + + String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false); + data.setAdminCertRequest(crmf_request); + data.setAdminCertRequestType("crmf"); + + data.setIssuingCA("https://" + host + ":9224"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + CertData cert1 = new CertData(); + cert1.setTag("transport"); + cert1.setKeyAlgorithm("SHA256withRSA"); + cert1.setKeySize("2048"); + cert1.setKeyType("rsa"); + cert1.setNickname("transportCert testkra"); + cert1.setSigningAlgorithm("SHA256withRSA"); + cert1.setSubjectDN("CN=KRA Transport Certificate"); + cert1.setToken("Internal Key Storage Token"); + + systemCerts.add(cert1); + + CertData cert2 = new CertData(); + cert2.setTag("storage"); + cert2.setKeyAlgorithm("SHA256withRSA"); + cert2.setKeySize("2048"); + cert2.setKeyType("rsa"); + cert2.setNickname("storageCert testkra"); + cert2.setSigningAlgorithm("SHA256withRSA"); + cert2.setSubjectDN("CN= KRA Storage Certificate"); + cert2.setToken("Internal Key Storage Token"); + systemCerts.add(cert2); + + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testkra"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + CertData cert4 = new CertData(); + cert4.setTag("subsystem"); + cert4.setKeyAlgorithm("SHA256withRSA"); + cert4.setKeySize("2048"); + cert4.setKeyType("rsa"); + cert4.setNickname("subsystemCert testkra"); + cert4.setSubjectDN("CN=KRA Subsystem Certificate"); + cert4.setToken("Internal Key Storage Token"); + systemCerts.add(cert4); + + CertData cert5 = new CertData(); + cert5.setTag("audit_signing"); + cert5.setKeyAlgorithm("SHA256withRSA"); + cert5.setKeySize("2048"); + cert5.setKeyType("rsa"); + cert5.setNickname("auditSigningCert testkra"); + cert5.setSigningAlgorithm("SHA256withRSA"); + cert5.setSubjectDN("CN=KRA Audit Signing Certificate"); + cert5.setToken("Internal Key Storage Token"); + systemCerts.add(cert5); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static ConfigurationData constructOCSPData(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException, + InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + + data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN); + data.setSecurityDomainUri("https://" + host + ":9225"); + data.setSecurityDomainUser("admin"); + data.setSecurityDomainPassword("redhat123"); + + data.setIsClone("false"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test ocsp subsystem"); + + data.setDsHost(host); + data.setDsPort("7389"); + data.setBaseDN("o=testocsp22"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testocsp22"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("true"); + data.setBackupFile("/tmp/testocsp.p12"); + data.setBackupPassword("redhat123"); + + data.setAdminEmail("alee@redhat.com"); + data.setAdminName("admin"); + data.setAdminPassword("redhat123"); + data.setAdminProfileID("caAdminCert"); + data.setAdminUID("admin"); + String subjectdn = "CN=OCSP Administrator of Instance testocsp, UID=admin, E=alee@redhat.com, o=testocsp22"; + data.setAdminSubjectDN(subjectdn); + + String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false); + data.setAdminCertRequest(crmf_request); + data.setAdminCertRequestType("crmf"); + + data.setIssuingCA("https://" + host + ":9224"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + CertData cert1 = new CertData(); + cert1.setTag("signing"); + cert1.setKeyAlgorithm("SHA256withRSA"); + cert1.setKeySize("2048"); + cert1.setKeyType("rsa"); + cert1.setNickname("ocspSigningCert testocsp"); + cert1.setSigningAlgorithm("SHA256withRSA"); + cert1.setSubjectDN("CN=OCSP Signing Certificate"); + cert1.setToken("Internal Key Storage Token"); + + systemCerts.add(cert1); + + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testocsp"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + CertData cert4 = new CertData(); + cert4.setTag("subsystem"); + cert4.setKeyAlgorithm("SHA256withRSA"); + cert4.setKeySize("2048"); + cert4.setKeyType("rsa"); + cert4.setNickname("subsystemCert testocsp"); + cert4.setSubjectDN("CN=OCSP Subsystem Certificate"); + cert4.setToken("Internal Key Storage Token"); + systemCerts.add(cert4); + + CertData cert5 = new CertData(); + cert5.setTag("audit_signing"); + cert5.setKeyAlgorithm("SHA256withRSA"); + cert5.setKeySize("2048"); + cert5.setKeyType("rsa"); + cert5.setNickname("auditSigningCert testocsp"); + cert5.setSigningAlgorithm("SHA256withRSA"); + cert5.setSubjectDN("CN=OCSP Audit Signing Certificate"); + cert5.setToken("Internal Key Storage Token"); + systemCerts.add(cert5); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static ConfigurationData constructTKSData(String host, String port, String pin, String db_dir, + String token_pwd, CryptoToken token) throws NoSuchAlgorithmException, TokenException, IOException, + InvalidBERException { + ConfigurationData data = new ConfigurationData(); + data.setPin(pin); + + data.setSecurityDomainType(ConfigurationData.EXISTING_DOMAIN); + data.setSecurityDomainUri("https://" + host + ":9225"); + data.setSecurityDomainUser("admin"); + data.setSecurityDomainPassword("redhat123"); + + data.setIsClone("false"); + data.setToken(ConfigurationData.TOKEN_DEFAULT); + data.setSubsystemName("test tks subsystem"); + + data.setDsHost(host); + data.setDsPort("7389"); + data.setBaseDN("o=testtks22"); + data.setBindDN("cn=Directory Manager"); + data.setDatabase("o=testtks22"); + data.setBindpwd("redhat123"); + data.setRemoveData("true"); + data.setSecureConn("false"); + + data.setBackupKeys("true"); + data.setBackupFile("/tmp/testtks.p12"); + data.setBackupPassword("redhat123"); + + data.setAdminEmail("alee@redhat.com"); + data.setAdminName("admin"); + data.setAdminPassword("redhat123"); + data.setAdminProfileID("caAdminCert"); + data.setAdminUID("admin"); + String subjectdn = "CN=TKS Administrator of Instance testtks, UID=admin, E=alee@redhat.com, o=testtks22"; + data.setAdminSubjectDN(subjectdn); + + String crmf_request = generateCRMFRequest(token, "2048", subjectdn, false); + data.setAdminCertRequest(crmf_request); + data.setAdminCertRequestType("crmf"); + + data.setIssuingCA("https://" + host + ":9224"); + + // create system certs + Collection<CertData> systemCerts = new ArrayList<CertData>(); + + CertData cert3 = new CertData(); + cert3.setTag("sslserver"); + cert3.setKeyAlgorithm("SHA256withRSA"); + cert3.setKeySize("2048"); + cert3.setKeyType("rsa"); + cert3.setNickname("sslServerCert testtks"); + cert3.setSubjectDN("CN=" + host); + cert3.setToken("Internal Key Storage Token"); + systemCerts.add(cert3); + + CertData cert4 = new CertData(); + cert4.setTag("subsystem"); + cert4.setKeyAlgorithm("SHA256withRSA"); + cert4.setKeySize("2048"); + cert4.setKeyType("rsa"); + cert4.setNickname("subsystemCert testtks"); + cert4.setSubjectDN("CN=TKS Subsystem Certificate"); + cert4.setToken("Internal Key Storage Token"); + systemCerts.add(cert4); + + CertData cert5 = new CertData(); + cert5.setTag("audit_signing"); + cert5.setKeyAlgorithm("SHA256withRSA"); + cert5.setKeySize("2048"); + cert5.setKeyType("rsa"); + cert5.setNickname("auditSigningCert testtks"); + cert5.setSigningAlgorithm("SHA256withRSA"); + cert5.setSubjectDN("CN=TKS Audit Signing Certificate"); + cert5.setToken("Internal Key Storage Token"); + systemCerts.add(cert5); + + data.setSystemCerts(systemCerts); + + return data; + } + + private static String generateCRMFRequest(CryptoToken token, String keysize, String subjectdn, boolean dualkey) + throws NoSuchAlgorithmException, TokenException, IOException, InvalidBERException { + KeyPairGenerator kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); + + Integer x = new Integer(keysize); + int key_len = x.intValue(); + + kg.initialize(key_len); + + // 1st key pair + KeyPair pair = kg.genKeyPair(); + + // create CRMF + CertTemplate certTemplate = new CertTemplate(); + + certTemplate.setVersion(new INTEGER(2)); + + if (subjectdn != null) { + X500Name name = new X500Name(subjectdn); + ByteArrayInputStream cs = new ByteArrayInputStream(name.getEncoded()); + Name n = (Name) Name.getTemplate().decode(cs); + certTemplate.setSubject(n); + } + + certTemplate.setPublicKey(new SubjectPublicKeyInfo(pair.getPublic())); + + SEQUENCE seq = new SEQUENCE(); + CertRequest certReq = new CertRequest(new INTEGER(1), certTemplate, + seq); + byte popdata[] = { 0x0, 0x3, 0x0 }; + + ProofOfPossession pop = ProofOfPossession.createKeyEncipherment( + POPOPrivKey.createThisMessage(new BIT_STRING(popdata, 3))); + + CertReqMsg crmfMsg = new CertReqMsg(certReq, pop, null); + + SEQUENCE s1 = new SEQUENCE(); + + // 1st : Encryption key + + s1.addElement(crmfMsg); + + // 2nd : Signing Key + + if (dualkey) { + System.out.println("dualkey = true"); + SEQUENCE seq1 = new SEQUENCE(); + CertRequest certReqSigning = new CertRequest(new INTEGER(1), + certTemplate, seq1); + CertReqMsg signingMsg = new CertReqMsg(certReqSigning, pop, null); + + s1.addElement(signingMsg); + } + + byte encoded[] = ASN1Util.encode(s1); + + // BASE64Encoder encoder = new BASE64Encoder(); + // String Req1 = encoder.encodeBuffer(encoded); + String Req1 = Utils.base64encode(encoded); + return Req1; + } +} diff --git a/base/common/src/CMakeLists.txt b/base/common/src/CMakeLists.txt index 43f3a5a77..3cfd3ba01 100644 --- a/base/common/src/CMakeLists.txt +++ b/base/common/src/CMakeLists.txt @@ -76,6 +76,13 @@ find_file(RESTEASY_JAXRS_JAR /usr/share/java/resteasy ) +find_file(HTTPCLIENT_JAR + NAMES + httpclient.jar + PATHS + /usr/share/java/httpcomponents +) + set(pki-certsrv_java_SRCS com/netscape/certsrv/apps/ICommandQueue.java com/netscape/certsrv/apps/CMS.java @@ -647,6 +654,19 @@ set(pki-cms_java_SRCS com/netscape/cms/servlet/csadmin/DownloadPKCS12.java com/netscape/cms/servlet/csadmin/SavePKCS12Panel.java com/netscape/cms/servlet/csadmin/NamePanel.java + com/netscape/cms/servlet/csadmin/ConfigurationUtils.java + com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java + com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java + com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java + com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java + com/netscape/cms/servlet/csadmin/model/CertData.java + com/netscape/cms/servlet/csadmin/model/ConfigurationData.java + com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java + com/netscape/cms/servlet/csadmin/model/DomainInfo.java + com/netscape/cms/servlet/csadmin/model/InstallToken.java + com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java + com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java + com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java com/netscape/cms/servlet/wizard/WizardServlet.java com/netscape/cms/servlet/wizard/IWizardPanel.java com/netscape/cms/servlet/processors/PKCS10Processor.java @@ -1042,7 +1062,7 @@ set(pki-cmsbundle_RCS set(CMAKE_JAVA_INCLUDE_PATH ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR} ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR} ${XALAN_JAR} ${XERCES_JAR} - ${JSS_JAR} ${COMMONS_CODEC_JAR} ${TOMCAT_CATALINA_JAR} ${SYMKEY_JAR} ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR}) + ${JSS_JAR} ${COMMONS_CODEC_JAR} ${TOMCAT_CATALINA_JAR} ${SYMKEY_JAR} ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR} ${HTTPCLIENT_JAR}) set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION}) diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java b/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java index 0aedded83..066f9dea1 100644 --- a/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java +++ b/base/common/src/com/netscape/cms/servlet/csadmin/Cert.java @@ -33,6 +33,7 @@ public class Cert { private boolean mEnable = true; private boolean mSigningRequired = false; private String mSubsystem = ""; + private String certChain = ""; public Cert(String tokenName, String nickName, String certTag) { mTokenname = tokenName; @@ -176,4 +177,12 @@ public class Cert { public void setCustomCurvename(String curve) { mCustomCurvename = curve; } + + public String getCertChain() { + return certChain; + } + + public void setCertChain(String certChain) { + this.certChain = certChain; + } } diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java index e3068d7b3..35ec7c515 100644 --- a/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java +++ b/base/common/src/com/netscape/cms/servlet/csadmin/CertUtil.java @@ -194,7 +194,9 @@ public class CertUtil { return certReqs; } catch (Throwable e) { CMS.debug(e); - context.put("errorString", e.toString()); + if (context != null) { + context.put("errorString", e.toString()); + } CMS.debug("CertUtil getPKCS10: " + e.toString()); throw new IOException(e.toString()); } @@ -453,8 +455,9 @@ public class CertUtil { } if (cr == null) { - context.put("errorString", - "Ceritifcate Authority is not ready to serve."); + if (context != null) { + context.put("errorString", "Ceritifcate Authority is not ready to serve."); + } throw new IOException("Ceritifcate Authority is not ready to serve."); } diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java new file mode 100644 index 000000000..d98d8f93d --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationErrorInterceptor.java @@ -0,0 +1,64 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; + +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.client.core.ClientErrorInterceptor; + +import com.netscape.cms.servlet.base.CMSException; + +/** + * @author alee + * + */ +public class ConfigurationErrorInterceptor implements ClientErrorInterceptor { + + public void handle(ClientResponse<?> response) { + + // handle HTTP code 4xx and 5xx + int code = response.getResponseStatus().getStatusCode(); + if (code < 400) return; + + MultivaluedMap<String, String> headers = response.getHeaders(); + String contentType = headers.getFirst("Content-Type"); + + // handle XML content only + if (!contentType.startsWith(MediaType.TEXT_XML)) return; + + CMSException exception; + + try { + // Requires RESTEasy 2.3.2 + // https://issues.jboss.org/browse/RESTEASY-652 + CMSException.Data data = response.getEntity(CMSException.Data.class); + + Class<?> clazz = Class.forName(data.className); + exception = (CMSException) clazz.getConstructor(CMSException.Data.class).newInstance(data); + + } catch (Exception e) { + e.printStackTrace(); + return; + } + + throw exception; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java new file mode 100644 index 000000000..330cdf19d --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationRESTClient.java @@ -0,0 +1,197 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.util.Enumeration; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.scheme.LayeredSchemeSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeSocketFactory; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.params.HttpParams; +import org.jboss.resteasy.client.ClientExecutor; +import org.jboss.resteasy.client.ProxyFactory; +import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor; +import org.jboss.resteasy.spi.ResteasyProviderFactory; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; +import org.mozilla.jss.ssl.SSLSocket; + +import com.netscape.cms.servlet.csadmin.model.ConfigurationData; +import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData; +import com.netscape.cms.servlet.csadmin.model.InstallToken; +import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest; + + +/** + * @author alee + * + */ +public class ConfigurationRESTClient { + private class ServerCertApprovalCB implements SSLCertificateApprovalCallback { + + public boolean approve(org.mozilla.jss.crypto.X509Certificate servercert, + SSLCertificateApprovalCallback.ValidityStatus status) { + + //For now lets just accept the server cert. This is a test tool, being + // pointed at a well known instance. + + + if (servercert != null) { + System.out.println("Peer cert details: " + + "\n subject: " + servercert.getSubjectDN().toString() + + "\n issuer: " + servercert.getIssuerDN().toString() + + "\n serial: " + servercert.getSerialNumber().toString() + ); + } + + SSLCertificateApprovalCallback.ValidityItem item; + Enumeration<?> errors = status.getReasons(); + int i = 0; + while (errors.hasMoreElements()) { + i++; + item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement(); + System.out.println("item " + i + + " reason=" + item.getReason() + + " depth=" + item.getDepth()); + + int reason = item.getReason(); + + if (reason == + SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER || + reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) { + + //Allow these two since we haven't necessarily installed the CA cert for trust + // and we are choosing "localhost" as the host for this client. + + return true; + + } + } + + //For other errors return false + return false; + } + } + + private class JSSProtocolSocketFactory implements SchemeSocketFactory, LayeredSchemeSocketFactory { + @Override + public Socket createSocket(HttpParams params) + throws IOException { + return null; + } + + @Override + public Socket connectSocket(Socket sock, InetSocketAddress remoteAddress, + InetSocketAddress localAddress, HttpParams params) + throws IOException, UnknownHostException { + Socket socket; + String hostName = null; + int port = 0; + if (remoteAddress != null) { + hostName = remoteAddress.getHostName(); + port = remoteAddress.getPort(); + + } + + int localPort = 0; + InetAddress localAddr = null; + if (localAddress != null) { + localPort = localAddress.getPort(); + localAddr = localAddress.getAddress(); + } + + if (sock == null) { + socket = new SSLSocket(InetAddress.getByName(hostName), port, localAddr, localPort, + new ServerCertApprovalCB(), null); + + } else { + socket = new SSLSocket(sock, hostName, new ServerCertApprovalCB(), null); + } + + return socket; + } + + @Override + public boolean isSecure(Socket sock) { + //We only use this factory in the case of SSL Connections + return true; + } + + @Override + public Socket createLayeredSocket(Socket arg0, String arg1, int arg2, boolean arg3) throws IOException, + UnknownHostException { + //This method implementation is required to get SSL working. + return null; + } + } + + private String clientCertNickname; + private SystemConfigurationResource configClient; + + public ConfigurationRESTClient(String baseUri, String clientCertNick) throws URISyntaxException { + + // For SSL we are assuming the caller has already intialized JSS and has + // a valid CryptoManager and CryptoToken + // optional clientCertNickname is provided for use if required. + + + URI uri = new URI(baseUri); + + String protocol = uri.getScheme(); + int port = uri.getPort(); + + clientCertNickname = null; + HttpClient httpclient = new DefaultHttpClient(); + if(protocol != null && protocol.equals("https")) { + if (clientCertNick != null) { + clientCertNickname = clientCertNick; + } + + Scheme scheme = new Scheme("https",port, new JSSProtocolSocketFactory()); + + // Register for port 443 our SSLSocketFactory to the ConnectionManager + httpclient.getConnectionManager().getSchemeRegistry().register(scheme); + + } + + + ClientExecutor executor = new ApacheHttpClient4Executor(httpclient); + + ResteasyProviderFactory providerFactory = ResteasyProviderFactory.getInstance(); + providerFactory.addClientErrorInterceptor(new ConfigurationErrorInterceptor()); + configClient = ProxyFactory.create(SystemConfigurationResource.class, uri, executor, providerFactory); + } + + public ConfigurationResponseData configure(ConfigurationData data) { + ConfigurationResponseData response = configClient.configure(data); + return response; + } + + public InstallToken getInstallToken(InstallTokenRequest data) { + InstallToken token = configClient.getInstallToken(data); + return token; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java new file mode 100644 index 000000000..d4bcfd661 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java @@ -0,0 +1,3452 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + package com.netscape.cms.servlet.csadmin; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.CharConversionException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintStream; +import java.math.BigInteger; +import java.net.ConnectException; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.security.DigestException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Vector; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.ParserConfigurationException; + +import netscape.ldap.LDAPAttribute; +import netscape.ldap.LDAPAttributeSet; +import netscape.ldap.LDAPConnection; +import netscape.ldap.LDAPDN; +import netscape.ldap.LDAPEntry; +import netscape.ldap.LDAPException; +import netscape.ldap.LDAPModification; +import netscape.ldap.LDAPSearchConstraints; +import netscape.ldap.LDAPSearchResults; +import netscape.ldap.LDAPv3; +import netscape.security.pkcs.ContentInfo; +import netscape.security.pkcs.PKCS10; +import netscape.security.pkcs.PKCS7; +import netscape.security.pkcs.SignerInfo; +import netscape.security.x509.AlgorithmId; +import netscape.security.x509.CertificateChain; +import netscape.security.x509.X509CertImpl; +import netscape.security.x509.X509Key; + +import org.apache.velocity.context.Context; +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.CryptoManager.NicknameConflictException; +import org.mozilla.jss.CryptoManager.NotInitializedException; +import org.mozilla.jss.CryptoManager.UserCertConflictException; +import org.mozilla.jss.NoSuchTokenException; +import org.mozilla.jss.asn1.ANY; +import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.ASN1Value; +import org.mozilla.jss.asn1.BMPString; +import org.mozilla.jss.asn1.InvalidBERException; +import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; +import org.mozilla.jss.asn1.OCTET_STRING; +import org.mozilla.jss.asn1.SEQUENCE; +import org.mozilla.jss.asn1.SET; +import org.mozilla.jss.crypto.BadPaddingException; +import org.mozilla.jss.crypto.Cipher; +import org.mozilla.jss.crypto.CryptoStore; +import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.EncryptionAlgorithm; +import org.mozilla.jss.crypto.IVParameterSpec; +import org.mozilla.jss.crypto.IllegalBlockSizeException; +import org.mozilla.jss.crypto.InternalCertificate; +import org.mozilla.jss.crypto.InvalidKeyFormatException; +import org.mozilla.jss.crypto.KeyGenAlgorithm; +import org.mozilla.jss.crypto.KeyGenerator; +import org.mozilla.jss.crypto.KeyWrapAlgorithm; +import org.mozilla.jss.crypto.KeyWrapper; +import org.mozilla.jss.crypto.NoSuchItemOnTokenException; +import org.mozilla.jss.crypto.ObjectNotFoundException; +import org.mozilla.jss.crypto.PBEAlgorithm; +import org.mozilla.jss.crypto.PrivateKey; +import org.mozilla.jss.crypto.SymmetricKey; +import org.mozilla.jss.crypto.TokenException; +import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.pkcs11.PK11Store; +import org.mozilla.jss.pkcs12.AuthenticatedSafes; +import org.mozilla.jss.pkcs12.CertBag; +import org.mozilla.jss.pkcs12.PFX; +import org.mozilla.jss.pkcs12.PasswordConverter; +import org.mozilla.jss.pkcs12.SafeBag; +import org.mozilla.jss.pkix.primitive.Attribute; +import org.mozilla.jss.pkix.primitive.EncryptedPrivateKeyInfo; +import org.mozilla.jss.pkix.primitive.PrivateKeyInfo; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; +import org.mozilla.jss.util.IncorrectPasswordException; +import org.mozilla.jss.util.Password; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.EAuthException; +import com.netscape.certsrv.authentication.IAuthSubsystem; +import com.netscape.certsrv.authorization.IAuthzSubsystem; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.EPropertyNotFound; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.base.ISubsystem; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.dbs.IDBSubsystem; +import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord; +import com.netscape.certsrv.ldap.ILdapConnFactory; +import com.netscape.certsrv.ocsp.IDefStore; +import com.netscape.certsrv.ocsp.IOCSPAuthority; +import com.netscape.certsrv.usrgrp.IGroup; +import com.netscape.certsrv.usrgrp.IUGSubsystem; +import com.netscape.certsrv.usrgrp.IUser; +import com.netscape.cmsutil.crypto.CryptoUtil; +import com.netscape.cmsutil.http.HttpClient; +import com.netscape.cmsutil.http.HttpRequest; +import com.netscape.cmsutil.http.HttpResponse; +import com.netscape.cmsutil.http.JssSSLSocketFactory; +import com.netscape.cmsutil.ldap.LDAPUtil; +import com.netscape.cmsutil.xml.XMLObject; + +import com.netscape.cms.servlet.csadmin.model.InstallToken; +import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest; + +/** + * Utility class for functions to be used both by the RESTful installer + * and the UI Panels. + * + * @author alee + * + */ +public class ConfigurationUtils { + + private static final String PCERT_PREFIX = "preop.cert."; + public static String SUCCESS = "0"; + public static String FAILURE = "1"; + public static String AUTH_FAILURE = "2"; + public static final BigInteger BIG_ZERO = new BigInteger("0"); + public static final Long MINUS_ONE = Long.valueOf(-1); + + public static boolean loginToken(CryptoToken token, String tokPwd) throws TokenException, + IncorrectPasswordException { + boolean rv = true; + Password password = null; + password = new Password(tokPwd.toCharArray()); + + if (token.passwordIsInitialized()) { + CMS.debug("loginToken():token password is initialized"); + if (!token.isLoggedIn()) { + CMS.debug("loginToken():Token is not logged in, try it"); + token.login(password); + } else { + CMS.debug("loginToken():Token has already logged on"); + } + } else { + CMS.debug("loginToken():Token password not initialized"); + rv = false; + } + return rv; + } + + //TODO - replace with Jack's connector code + // or as we replace calls with restful calls, remove altogether + public static String getHttpResponse(String hostname, int port, boolean secure, + String uri, String content, String clientnickname, + SSLCertificateApprovalCallback certApprovalCallback) + throws IOException { + HttpClient httpclient = null; + String c = null; + + try { + if (secure) { + JssSSLSocketFactory factory = null; + if (clientnickname != null && clientnickname.length() > 0) + factory = new JssSSLSocketFactory(clientnickname); + else + factory = new JssSSLSocketFactory(); + + httpclient = new HttpClient(factory, certApprovalCallback); + } else { + httpclient = new HttpClient(); + } + httpclient.connect(hostname, port); + HttpRequest httprequest = new HttpRequest(); + + httprequest.setMethod(HttpRequest.POST); + httprequest.setURI(uri); + httprequest.setHeader("user-agent", "HTTPTool/1.0"); + httprequest.setHeader("content-type", + "application/x-www-form-urlencoded"); + if (content != null && content.length() > 0) { + String content_c = content; + httprequest.setHeader("content-length", "" + content_c.length()); + httprequest.setContent(content_c); + } + HttpResponse httpresponse = httpclient.send(httprequest); + + c = httpresponse.getContent(); + } catch (ConnectException e) { + CMS.debug("getHttpResponse: " + e.toString()); + throw new IOException("The server you tried to contact is not running."); + } catch (Exception e) { + CMS.debug("getHttpResponse: " + e.toString()); + throw new IOException(e.toString()); + } finally { + if (httpclient.connected()) { + httpclient.disconnect(); + } + } + + return c; + } + + public static void importCertChain(String host, int port, String serverPath, String tag) + throws IOException, SAXException, ParserConfigurationException, CertificateEncodingException, + CertificateException, NotInitializedException, TokenException { + IConfigStore cs = CMS.getConfigStore(); + ConfigCertApprovalCallback certApprovalCallback = new ConfigCertApprovalCallback(); + XMLObject parser = null; + String c = ConfigurationUtils.getHttpResponse(host, port, true, serverPath, null, null, + certApprovalCallback); + if (c != null) { + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + parser = new XMLObject(bis); + String certchain = parser.getValue("ChainBase64"); + if ((certchain != null) && (certchain.length() > 0)) { + cs.putString("preop." + tag + ".pkcs7", certchain); + CryptoUtil.importCertificateChain(certchain); + } else { + throw new IOException("importCertChain: Security Domain response does not contain certificate chain"); + } + } else { + throw new IOException("importCertChain: Failed to get response from security domain"); + } + } + + public static String getInstallToken(String sdhost, int sdport, String user, String passwd) + throws EPropertyNotFound, EBaseException, URISyntaxException { + IConfigStore cs = CMS.getConfigStore(); + String csType = cs.getString("cs.type"); + + InstallTokenRequest data = new InstallTokenRequest(user, passwd, csType, CMS.getEEHost(), CMS.getAdminPort()); + String baseUri = "https://" + sdhost + ":" + sdport + "/ca/pki"; + ConfigurationRESTClient client = null; + client = new ConfigurationRESTClient(baseUri, null); + InstallToken token = client.getInstallToken(data); + + return token.getToken(); + } + + public static String getGroupName(String uid, String subsystemname) { + IUGSubsystem subsystem = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID)); + if (subsystem.isMemberOf(uid, "Enterprise CA Administrators") && subsystemname.equals("CA")) { + return "Enterprise CA Administrators"; + } else if (subsystem.isMemberOf(uid, "Enterprise KRA Administrators") && subsystemname.equals("KRA")) { + return "Enterprise KRA Administrators"; + } else if (subsystem.isMemberOf(uid, "Enterprise OCSP Administrators") && subsystemname.equals("OCSP")) { + return "Enterprise OCSP Administrators"; + } else if (subsystem.isMemberOf(uid, "Enterprise TKS Administrators") && subsystemname.equals("TKS")) { + return "Enterprise TKS Administrators"; + } else if (subsystem.isMemberOf(uid, "Enterprise RA Administrators") && subsystemname.equals("RA")) { + return "Enterprise RA Administrators"; + } else if (subsystem.isMemberOf(uid, "Enterprise TPS Administrators") && subsystemname.equals("TPS")) { + return "Enterprise TPS Administrators"; + } + return null; + } + + public static String getDomainXML(String hostname, int https_admin_port, boolean https) + throws IOException, SAXException, ParserConfigurationException { + CMS.debug("getDomainXML start"); + String c = getHttpResponse(hostname, https_admin_port, https, "/ca/admin/ca/getDomainXML", null, null, null); + if (c != null) { + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = null; + + parser = new XMLObject(bis); + String status = parser.getValue("Status"); + CMS.debug("getDomainXML: status=" + status); + + if (status.equals(SUCCESS)) { + String domainInfo = parser.getValue("DomainInfo"); + CMS.debug("getDomainXML: domainInfo=" + domainInfo); + return domainInfo; + } else { + String error = parser.getValue("Error"); + throw new IOException(error); + } + + } + return null; + } + + public static void getSecurityDomainPorts(String domainXML, String host, int port) throws SAXException, + IOException, ParserConfigurationException { + ByteArrayInputStream bis = new ByteArrayInputStream(domainXML.getBytes()); + IConfigStore cs = CMS.getConfigStore(); + + XMLObject parser = new XMLObject(bis); + Document doc = parser.getDocument(); + NodeList nodeList = doc.getElementsByTagName("CA"); + + int len = nodeList.getLength(); + CMS.debug("len is " + len); + for (int i = 0; i < len; i++) { + String hostname = parser.getValuesFromContainer(nodeList.item(i), "Host").elementAt(0); + String admin_port = parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort").elementAt(0); + CMS.debug("hostname: <" + hostname + ">"); + CMS.debug("admin_port: <" + admin_port + ">"); + + if (hostname.equals(host) && admin_port.equals(port + "")) { + cs.putString("securitydomain.httpport", + parser.getValuesFromContainer(nodeList.item(i), "UnSecurePort").elementAt(0)); + cs.putString("securitydomain.httpsagentport", + parser.getValuesFromContainer(nodeList.item(i), "SecureAgentPort").elementAt(0)); + cs.putString("securitydomain.httpseeport", + parser.getValuesFromContainer(nodeList.item(i), "SecurePort").elementAt(0)); + + break; + } + } + } + + public static Vector<String> getUrlListFromSecurityDomain(IConfigStore config, + String type, String portType) + throws EPropertyNotFound, EBaseException, IOException, SAXException, ParserConfigurationException { + Vector<String> v = new Vector<String>(); + + String hostname = config.getString("securitydomain.host"); + int httpsadminport = config.getInteger("securitydomain.httpsadminport"); + + CMS.debug("getUrlListFromSecurityDomain(): Getting domain.xml from CA..."); + String c = getDomainXML(hostname, httpsadminport, true); + + CMS.debug("getUrlListFromSecurityDomain: Getting " + portType + " from Security Domain ..."); + if (!portType.equals("UnSecurePort") && + !portType.equals("SecureAgentPort") && + !portType.equals("SecurePort") && + !portType.equals("SecureAdminPort")) { + CMS.debug("getUrlListFromSecurityDomain: " + + "unknown port type " + portType); + return v; + } + + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = new XMLObject(bis); + Document doc = parser.getDocument(); + NodeList nodeList = doc.getElementsByTagName(type); + + // save domain name in cfg + config.putString("securitydomain.name", parser.getValue("Name")); + + int len = nodeList.getLength(); + + CMS.debug("Len " + len); + for (int i = 0; i < len; i++) { + Vector<String> v_name = parser.getValuesFromContainer(nodeList.item(i), "SubsystemName"); + Vector<String> v_host = parser.getValuesFromContainer(nodeList.item(i), "Host"); + Vector<String> v_port = parser.getValuesFromContainer(nodeList.item(i), portType); + Vector<String> v_admin_port = parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort"); + + if (v_host.elementAt(0).equals(hostname) + && v_admin_port.elementAt(0).equals(new Integer(httpsadminport).toString())) { + // add security domain CA to the beginning of list + v.add(0, v_name.elementAt(0) + " - https://" + v_host.elementAt(0) + ":" + v_port.elementAt(0)); + } else { + v.addElement(v_name.elementAt(0) + " - https://" + v_host.elementAt(0) + ":" + v_port.elementAt(0)); + } + } + + return v; + } + + public static boolean isValidCloneURI(String domainXML, String cloneHost, int clonePort) throws EPropertyNotFound, + EBaseException, SAXException, IOException, ParserConfigurationException { + IConfigStore cs = CMS.getConfigStore(); + String csType = cs.getString("cs.type"); + ByteArrayInputStream bis = new ByteArrayInputStream(domainXML.getBytes()); + + XMLObject parser = new XMLObject(bis); + Document doc = parser.getDocument(); + NodeList nodeList = doc.getElementsByTagName(csType.toUpperCase()); + + int len = nodeList.getLength(); + for (int i = 0; i < len; i++) { + String hostname = parser.getValuesFromContainer(nodeList.item(i), "Host").elementAt(0); + String secure_port = parser.getValuesFromContainer(nodeList.item(i), "SecurePort").elementAt(0); + + if (hostname.equals(cloneHost) && secure_port.equals(clonePort + "")) { + cs.putString("preop.master.hostname", cloneHost); + cs.putInteger("preop.master.httpsport", clonePort); + cs.putString("preop.master.httpsadminport", + parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort").elementAt(0)); + return true; + } + } + + return false; + } + + public static void getConfigEntriesFromMaster() + throws IOException, EBaseException, SAXException, ParserConfigurationException { + + IConfigStore config = CMS.getConfigStore(); + String cstype = ""; + + cstype = config.getString("cs.type", ""); + + cstype = cstype.toLowerCase(); + + String session_id = CMS.getConfigSDSessionId(); + String master_hostname = ""; + int master_port = -1; + int master_ee_port = -1; + master_hostname = config.getString("preop.master.hostname", ""); + master_port = config.getInteger("preop.master.httpsadminport", -1); + master_ee_port = config.getInteger("preop.master.httpsport", -1); + + String content = ""; + if (cstype.equals("ca") || cstype.equals("kra")) { + content = "type=request&xmlOutput=true&sessionID=" + session_id; + CMS.debug("http content=" + content); + updateNumberRange(master_hostname, master_ee_port, true, content, "request"); + + content = "type=serialNo&xmlOutput=true&sessionID=" + session_id; + updateNumberRange(master_hostname, master_ee_port, true, content, "serialNo"); + + content = "type=replicaId&xmlOutput=true&sessionID=" + session_id; + updateNumberRange(master_hostname, master_ee_port, true, content, "replicaId"); + } + + String list = ""; + + list = config.getString("preop.cert.list", ""); + + StringBuffer c1 = new StringBuffer(); + StringBuffer s1 = new StringBuffer(); + StringTokenizer tok = new StringTokenizer(list, ","); + while (tok.hasMoreTokens()) { + String t1 = tok.nextToken(); + if (t1.equals("sslserver")) + continue; + c1.append(",cloning." + t1 + ".nickname"); + c1.append(",cloning." + t1 + ".dn"); + c1.append(",cloning." + t1 + ".keytype"); + c1.append(",cloning." + t1 + ".keyalgorithm"); + c1.append(",cloning." + t1 + ".privkey.id"); + c1.append(",cloning." + t1 + ".pubkey.exponent"); + c1.append(",cloning." + t1 + ".pubkey.modulus"); + c1.append(",cloning." + t1 + ".pubkey.encoded"); + + if (s1.length() != 0) + s1.append(","); + s1.append(cstype + "." + t1); + } + + if (!cstype.equals("ca")) { + c1.append(",cloning.ca.hostname,cloning.ca.httpport,cloning.ca.httpsport,cloning.ca.list,cloning.ca.pkcs7,cloning.ca.type"); + } + + if (cstype.equals("ca")) { + /* get ca connector details */ + if (s1.length() != 0) + s1.append(","); + s1.append("ca.connector.KRA"); + } + + s1.append(",internaldb,internaldb.ldapauth,internaldb.ldapconn"); + + content = + "op=get&names=cloning.module.token,cloning.token,instanceId,internaldb.basedn,internaldb.ldapauth.password," + + "internaldb.replication.password" + c1.toString() + + "&substores=" + s1.toString() + + "&xmlOutput=true&sessionID=" + + session_id; + boolean success = updateConfigEntries(master_hostname, master_port, true, + "/" + cstype + "/admin/" + cstype + "/getConfigEntries", content, config); + if (!success) { + throw new IOException("Failed to get configuration entries from the master"); + } + config.putString("preop.clone.configuration", "true"); + + config.commit(false); + + } + + public static void updateNumberRange(String hostname, int port, boolean https, String content, String type) + throws IOException, EBaseException, SAXException, ParserConfigurationException { + CMS.debug("updateNumberRange start host=" + hostname + " port=" + port); + IConfigStore cs = CMS.getConfigStore(); + + String cstype = ""; + cstype = cs.getString("cs.type", ""); + cstype = cstype.toLowerCase(); + + String serverPath = "/" + cstype + "/ee/" + cstype + "/updateNumberRange"; + String c = getHttpResponse(hostname, port, https, serverPath, content, null, null); + if (c == null || c.equals("")) { + CMS.debug("updateNumberRange: content is null."); + throw new IOException("The server you want to contact is not available"); + } else { + CMS.debug("content=" + c); + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = null; + parser = new XMLObject(bis); + String status = parser.getValue("Status"); + + CMS.debug("updateNumberRange(): status=" + status); + if (status.equals(SUCCESS)) { + String beginNum = parser.getValue("beginNumber"); + String endNum = parser.getValue("endNumber"); + if (type.equals("request")) { + cs.putString("dbs.beginRequestNumber", beginNum); + cs.putString("dbs.endRequestNumber", endNum); + } else if (type.equals("serialNo")) { + cs.putString("dbs.beginSerialNumber", beginNum); + cs.putString("dbs.endSerialNumber", endNum); + } else if (type.equals("replicaId")) { + cs.putString("dbs.beginReplicaNumber", beginNum); + cs.putString("dbs.endReplicaNumber", endNum); + } + // enable serial number management in clone + cs.putString("dbs.enableSerialManagement", "true"); + cs.commit(false); + return; + } else if (status.equals(AUTH_FAILURE)) { + throw new EAuthException(AUTH_FAILURE); + } else { + String error = parser.getValue("Error"); + throw new IOException(error); + } + } + } + + public static boolean updateConfigEntries(String hostname, int port, boolean https, + String servlet, String uri, IConfigStore config) + throws IOException, EBaseException, SAXException, ParserConfigurationException { + CMS.debug("updateConfigEntries start"); + String c = getHttpResponse(hostname, port, https, servlet, uri, null, null); + + if (c != null) { + + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = null; + + parser = new XMLObject(bis); + + String status = parser.getValue("Status"); + CMS.debug("updateConfigEntries: status=" + status); + + if (status.equals(SUCCESS)) { + String cstype = ""; + + cstype = config.getString("cs.type", ""); + + Document doc = parser.getDocument(); + NodeList list = doc.getElementsByTagName("name"); + int len = list.getLength(); + for (int i = 0; i < len; i++) { + Node n = list.item(i); + NodeList nn = n.getChildNodes(); + String name = nn.item(0).getNodeValue(); + Node parent = n.getParentNode(); + nn = parent.getChildNodes(); + int len1 = nn.getLength(); + String v = ""; + for (int j = 0; j < len1; j++) { + Node nv = nn.item(j); + String val = nv.getNodeName(); + if (val.equals("value")) { + NodeList n2 = nv.getChildNodes(); + if (n2.getLength() > 0) + v = n2.item(0).getNodeValue(); + break; + } + } + + if (name.equals("internaldb.basedn")) { + config.putString(name, v); + config.putString("preop.internaldb.master.basedn", v); + } else if (name.startsWith("internaldb")) { + config.putString(name.replaceFirst("internaldb", "preop.internaldb.master"), v); + } else if (name.equals("instanceId")) { + config.putString("preop.master.instanceId", v); + } else if (name.equals("cloning.signing.nickname")) { + config.putString("preop.master.signing.nickname", v); + config.putString("preop.cert.signing.nickname", v); + } else if (name.equals("cloning.ocsp_signing.nickname")) { + config.putString("preop.master.ocsp_signing.nickname", v); + config.putString("preop.cert.ocsp_signing.nickname", v); + } else if (name.equals("cloning.subsystem.nickname")) { + config.putString("preop.master.subsystem.nickname", v); + config.putString("preop.cert.subsystem.nickname", v); + } else if (name.equals("cloning.transport.nickname")) { + config.putString("preop.master.transport.nickname", v); + config.putString("kra.transportUnit.nickName", v); + config.putString("preop.cert.transport.nickname", v); + } else if (name.equals("cloning.storage.nickname")) { + config.putString("preop.master.storage.nickname", v); + config.putString("kra.storageUnit.nickName", v); + config.putString("preop.cert.storage.nickname", v); + } else if (name.equals("cloning.audit_signing.nickname")) { + config.putString("preop.master.audit_signing.nickname", v); + config.putString("preop.cert.audit_signing.nickname", v); + config.putString(name, v); + } else if (name.startsWith("cloning.ca")) { + config.putString(name.replaceFirst("cloning", "preop"), v); + } else if (name.equals("cloning.signing.keyalgorithm")) { + config.putString(name.replaceFirst("cloning", "preop.cert"), v); + if (cstype.equals("CA")) { + config.putString("ca.crl.MasterCRL.signingAlgorithm", v); + config.putString("ca.signing.defaultSigningAlgorithm", v); + } else if (cstype.equals("OCSP")) { + config.putString("ocsp.signing.defaultSigningAlgorithm", v); + } + } else if (name.equals("cloning.transport.keyalgorithm")) { + config.putString(name.replaceFirst("cloning", "preop.cert"), v); + config.putString("kra.transportUnit.signingAlgorithm", v); + } else if (name.equals("cloning.ocsp_signing.keyalgorithm")) { + config.putString(name.replaceFirst("cloning", "preop.cert"), v); + if (cstype.equals("CA")) { + config.putString("ca.ocsp_signing.defaultSigningAlgorithm", v); + } + } else if (name.startsWith("cloning")) { + config.putString(name.replaceFirst("cloning", "preop.cert"), v); + } else { + config.putString(name, v); + } + } + + // set master ldap password (if it exists) temporarily in password store + // in case it is needed for replication. Not stored in password.conf. + + String master_pwd = config.getString("preop.internaldb.master.ldapauth.password", ""); + if (!master_pwd.equals("")) { + config.putString("preop.internaldb.master.ldapauth.bindPWPrompt", "master_internaldb"); + String passwordFile = config.getString("passwordFile"); + IConfigStore psStore = CMS.createFileConfigStore(passwordFile); + psStore.putString("master_internaldb", master_pwd); + psStore.commit(false); + } + + return true; + } else if (status.equals(AUTH_FAILURE)) { + throw new EAuthException(AUTH_FAILURE); + } else { + String error = parser.getValue("Error"); + throw new IOException(error); + } + } + + return false; + } + + public static void restoreCertsFromP12(String p12File, String p12Pass) throws EPropertyNotFound, EBaseException, + InvalidKeyException, CertificateException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, IllegalStateException, TokenException, IllegalBlockSizeException, + BadPaddingException, NotInitializedException, NicknameConflictException, UserCertConflictException, + NoSuchItemOnTokenException, InvalidBERException, IOException { + byte b[] = new byte[1000000]; + IConfigStore cs = CMS.getConfigStore(); + String instanceRoot = cs.getString("instanceRoot"); + + FileInputStream fis = new FileInputStream(instanceRoot + "/alias/" + p12File); + while (fis.available() > 0) + fis.read(b); + fis.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(b); + StringBuffer reason = new StringBuffer(); + Password password = new Password(p12Pass.toCharArray()); + PFX pfx = null; + boolean verifypfx = false; + + pfx = (PFX) (new PFX.Template()).decode(bis); + verifypfx = pfx.verifyAuthSafes(password, reason); + + if (verifypfx) { + AuthenticatedSafes safes = pfx.getAuthSafes(); + Vector<Vector<Object>> pkeyinfo_collection = new Vector<Vector<Object>>(); + Vector<Vector<Object>> cert_collection = new Vector<Vector<Object>>(); + for (int i = 0; i < safes.getSize(); i++) { + SEQUENCE scontent = safes.getSafeContentsAt(null, i); + for (int j = 0; j < scontent.size(); j++) { + SafeBag bag = (SafeBag) scontent.elementAt(j); + OBJECT_IDENTIFIER oid = bag.getBagType(); + if (oid.equals(SafeBag.PKCS8_SHROUDED_KEY_BAG)) { + EncryptedPrivateKeyInfo privkeyinfo = + (EncryptedPrivateKeyInfo) bag.getInterpretedBagContent(); + PrivateKeyInfo pkeyinfo = privkeyinfo.decrypt(password, new PasswordConverter()); + Vector<Object> pkeyinfo_v = new Vector<Object>(); + pkeyinfo_v.addElement(pkeyinfo); + SET bagAttrs = bag.getBagAttributes(); + for (int k = 0; k < bagAttrs.size(); k++) { + Attribute attrs = (Attribute) bagAttrs.elementAt(k); + OBJECT_IDENTIFIER aoid = attrs.getType(); + if (aoid.equals(SafeBag.FRIENDLY_NAME)) { + SET val = attrs.getValues(); + ANY ss = (ANY) val.elementAt(0); + ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded()); + BMPString sss = (BMPString) new BMPString.Template().decode(bbis); + String s = sss.toString(); + pkeyinfo_v.addElement(s); + } + } + pkeyinfo_collection.addElement(pkeyinfo_v); + } else if (oid.equals(SafeBag.CERT_BAG)) { + CertBag cbag = (CertBag) bag.getInterpretedBagContent(); + OCTET_STRING str = (OCTET_STRING) cbag.getInterpretedCert(); + byte[] x509cert = str.toByteArray(); + Vector<Object> cert_v = new Vector<Object>(); + cert_v.addElement(x509cert); + SET bagAttrs = bag.getBagAttributes(); + + if (bagAttrs != null) { + for (int k = 0; k < bagAttrs.size(); k++) { + Attribute attrs = (Attribute) bagAttrs.elementAt(k); + OBJECT_IDENTIFIER aoid = attrs.getType(); + if (aoid.equals(SafeBag.FRIENDLY_NAME)) { + SET val = attrs.getValues(); + ANY ss = (ANY) val.elementAt(0); + ByteArrayInputStream bbis = new ByteArrayInputStream(ss.getEncoded()); + BMPString sss = (BMPString) (new BMPString.Template()).decode(bbis); + String s = sss.toString(); + cert_v.addElement(s); + } + } + } + + cert_collection.addElement(cert_v); + } + } + } + + importkeycert(pkeyinfo_collection, cert_collection); + } else { + throw new IOException("P12 File is incorrect"); + } + + } + + public static boolean isCertdbCloned() { + IConfigStore cs = CMS.getConfigStore(); + try { + CryptoManager cm = CryptoManager.getInstance(); + String certList = cs.getString("preop.cert.list"); + String cstype = cs.getString("cs.type").toLowerCase(); + StringTokenizer st = new StringTokenizer(certList, ","); + while (st.hasMoreTokens()) { + String tag = st.nextToken(); + if (tag.equals("sslserver")) + continue; + String tokenname = cs.getString("preop.module.token", ""); + cm.getTokenByName(tokenname); // throw exception if token doesn't exist + String name1 = "preop.master." + tag + ".nickname"; + String nickname = cs.getString(name1, ""); + if (!tokenname.equals("Internal Key Storage Token") && + !tokenname.equals("internal")) + nickname = tokenname + ":" + nickname; + + CMS.debug("isCertdbCloned: " + nickname); + + // TODO : remove this when we eliminate the extraneous nicknames + // needed for self tests + cs.putString(cstype + ".cert." + tag + ".nickname", nickname); + + X509Certificate cert = cm.findCertByNickname(nickname); + if (cert == null) + return false; + } + } catch (Exception e) { + return false; + } + + return true; + } + + public static void importkeycert(Vector<Vector<Object>> pkeyinfo_collection, + Vector<Vector<Object>> cert_collection) throws IOException, CertificateException, TokenException, + NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalStateException, + IllegalBlockSizeException, BadPaddingException, NotInitializedException, NicknameConflictException, + UserCertConflictException, NoSuchItemOnTokenException, EPropertyNotFound, EBaseException { + CryptoManager cm = CryptoManager.getInstance(); + + // delete all existing certificates first + deleteExistingCerts(); + + for (int i = 0; i < pkeyinfo_collection.size(); i++) { + Vector<Object> pkeyinfo_v = pkeyinfo_collection.elementAt(i); + PrivateKeyInfo pkeyinfo = (PrivateKeyInfo) pkeyinfo_v.elementAt(0); + String nickname = (String) pkeyinfo_v.elementAt(1); + byte[] x509cert = getX509Cert(nickname, cert_collection); + X509Certificate cert = cm.importCACertPackage(x509cert); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + pkeyinfo.encode(bos); + byte[] pkey = bos.toByteArray(); + + PublicKey publickey = cert.getPublicKey(); + CryptoToken token = cm.getInternalKeyStorageToken(); + CryptoStore store = token.getCryptoStore(); + + try { + store.deleteCert(cert); + } catch (NoSuchItemOnTokenException e) { + // this is OK + } + + KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3); + SymmetricKey sk = kg.generate(); + byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec param = new IVParameterSpec(iv); + Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); + c.initEncrypt(sk, param); + byte[] encpkey = c.doFinal(pkey); + + KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); + wrapper.initUnwrap(sk, param); + wrapper.unwrapPrivate(encpkey, getPrivateKeyType(publickey), publickey); + + } + + for (int i = 0; i < cert_collection.size(); i++) { + + Vector<Object> cert_v = cert_collection.elementAt(i); + byte[] cert = (byte[]) cert_v.elementAt(0); + if (cert_v.size() > 1) { + String name = (String) cert_v.elementAt(1); + // we need to delete the trusted CA certificate if it is + // the same as the ca signing certificate + if (isCASigningCert(name)) { + X509Certificate certchain = getX509CertFromToken(cert); + if (certchain != null) { + CryptoToken token = cm.getInternalKeyStorageToken(); + CryptoStore store = token.getCryptoStore(); + if (store instanceof PK11Store) { + try { + PK11Store pk11store = (PK11Store) store; + pk11store.deleteCertOnly(certchain); + } catch (Exception ee) { + CMS.debug("importKeyCert: Exception=" + ee.toString()); + } + } + } + } + + X509Certificate xcert = cm.importUserCACertPackage(cert, name); + if (isCASigningCert(name)) { + // we need to change the trust attribute to CT + InternalCertificate icert = (InternalCertificate) xcert; + icert.setSSLTrust(InternalCertificate.TRUSTED_CA + | InternalCertificate.TRUSTED_CLIENT_CA + | InternalCertificate.VALID_CA); + } else if (isAuditSigningCert(name)) { + InternalCertificate icert = (InternalCertificate) xcert; + icert.setObjectSigningTrust(InternalCertificate.USER + | InternalCertificate.VALID_PEER | InternalCertificate.TRUSTED_PEER); + } + } else { + cm.importCACertPackage(cert); + } + } + } + + public static X509Certificate getX509CertFromToken(byte[] cert) + throws IOException, CertificateException, NotInitializedException { + + X509CertImpl impl = new X509CertImpl(cert); + String issuer_impl = impl.getIssuerDN().toString(); + BigInteger serial_impl = impl.getSerialNumber(); + CryptoManager cm = CryptoManager.getInstance(); + X509Certificate[] permcerts = cm.getPermCerts(); + for (int i = 0; i < permcerts.length; i++) { + String issuer_p = permcerts[i].getSubjectDN().toString(); + BigInteger serial_p = permcerts[i].getSerialNumber(); + if (issuer_p.equals(issuer_impl) && serial_p.compareTo(serial_impl) == 0) { + return permcerts[i]; + } + } + return null; + } + + public static org.mozilla.jss.crypto.PrivateKey.Type getPrivateKeyType(PublicKey pubkey) { + CMS.debug("Key Algorithm '" + pubkey.getAlgorithm() + "'"); + if (pubkey.getAlgorithm().equals("EC")) { + return org.mozilla.jss.crypto.PrivateKey.Type.EC; + } + return org.mozilla.jss.crypto.PrivateKey.Type.RSA; + } + + public static boolean isCASigningCert(String name) { + IConfigStore cs = CMS.getConfigStore(); + try { + String nickname = cs.getString("preop.master.signing.nickname"); + if (nickname.equals(name)) return true; + } catch(Exception e) { + // nickname may not exist if this is not cloning a CA + }; + + return false; + } + + public static boolean isAuditSigningCert(String name) throws EPropertyNotFound, EBaseException { + IConfigStore cs = CMS.getConfigStore(); + String nickname = cs.getString("preop.master.audit_signing.nickname"); + if (nickname.equals(name)) return true; + return false; + } + + public static void deleteExistingCerts() { + IConfigStore cs = CMS.getConfigStore(); + try { + String list = cs.getString("preop.cert.list", ""); + StringTokenizer st = new StringTokenizer(list, ","); + while (st.hasMoreTokens()) { + String s = st.nextToken(); + if (s.equals("sslserver")) + continue; + String name = "preop.master." + s + ".nickname"; + String nickname = cs.getString(name, ""); + CryptoManager cm = CryptoManager.getInstance(); + X509Certificate xcert = null; + try { + xcert = cm.findCertByNickname(nickname); + } catch (Exception ee) { + CMS.debug("deleteExistingCerts: Exception=" + ee.toString()); + } + CryptoToken ct = cm.getInternalKeyStorageToken(); + CryptoStore store = ct.getCryptoStore(); + try { + store.deleteCert(xcert); + } catch (Exception ee) { + CMS.debug("deleteExistingCerts: Exception=" + ee.toString()); + } + } + } catch (Exception e) { + CMS.debug("deleteExistingCerts: Exception=" + e.toString()); + } + } + + public static byte[] getX509Cert(String nickname, Vector<Vector<Object>> cert_collection) + throws CertificateException { + for (int i = 0; i < cert_collection.size(); i++) { + Vector<Object> v = cert_collection.elementAt(i); + byte[] b = (byte[]) v.elementAt(0); + X509CertImpl impl = null; + impl = new X509CertImpl(b); + Principal subjectdn = impl.getSubjectDN(); + if (LDAPDN.equals(subjectdn.toString(), nickname)) return b; + } + return null; + } + + public static void releaseConnection(LDAPConnection conn) { + try { + if (conn != null) conn.disconnect(); + } catch (LDAPException e) { + e.printStackTrace(); + CMS.debug("releaseConnection: " + e); + } + } + + public static void populateDB() throws IOException, EBaseException { + IConfigStore cs = CMS.getConfigStore(); + + String baseDN = cs.getString("internaldb.basedn"); + String database = cs.getString("internaldb.database", ""); + String remove = cs.getString("preop.database.removeData", "false"); + + IConfigStore dbCfg = cs.getSubStore("internaldb"); + ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory(); + dbFactory.init(dbCfg); + LDAPConnection conn = dbFactory.getConn(); + + // check that the database and baseDN do not exist + boolean foundBaseDN = false; + try { + LDAPEntry entry = conn.read(baseDN); + if (entry != null) foundBaseDN = true; + } catch (LDAPException e) { + switch (e.getLDAPResultCode()) { + case LDAPException.NO_SUCH_OBJECT: + break; + default: + e.printStackTrace(); + CMS.debug("populateDB: LDAPException " + e.toString()); + releaseConnection(conn); + throw new IOException("Failed to determine if basedDN exists."); + } + } + + boolean foundDatabase = false; + try { + String dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config"; + LDAPEntry entry = conn.read(dn); + if (entry != null) foundDatabase = true; + } catch (LDAPException e) { + switch (e.getLDAPResultCode()) { + case LDAPException.NO_SUCH_OBJECT: + break; + default: + e.printStackTrace(); + CMS.debug("populatedb: LDAPException " + e.toString()); + releaseConnection(conn); + throw new IOException("Failed to determine if database exists."); + } + } + try { + String dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config"; + LDAPEntry entry = conn.read(dn); + if (entry != null) foundDatabase = true; + } catch (LDAPException e) { + switch (e.getLDAPResultCode()) { + case LDAPException.NO_SUCH_OBJECT: + break; + default: + e.printStackTrace(); + CMS.debug("populateDB: LDAPException " + e.toString()); + releaseConnection(conn); + throw new IOException("Failed to determine if mapping tree exists."); + } + } + + if (foundDatabase) { + CMS.debug("populatedb: This database has already been used."); + if (remove.equals("false")) { + releaseConnection(conn); + throw new IOException("This database has already been used. " + + "Select the checkbox below to remove all data and reuse this database"); + } else { + CMS.debug("populateDB: Deleting existing DB and reusing base DN"); + cleanupDB(conn, baseDN, database); + foundBaseDN = false; + foundDatabase = false; + } + } + + if (foundBaseDN) { + CMS.debug("DatabasePanel update: This base DN has already been used."); + if (remove.equals("false")) { + releaseConnection(conn); + throw new IOException( "This base DN (" + baseDN + + ") has already been used. Select the checkbox below to remove all data and reuse this base DN"); + } else { + CMS.debug("populateDB: Deleting existing DB and reusing base DN"); + cleanupDB(conn, baseDN, database); + foundBaseDN = false; + foundDatabase = false; + } + } + + // create database + try { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + String oc[] = { "top", "extensibleObject", "nsBackendInstance" }; + attrs.add(new LDAPAttribute("objectClass", oc)); + attrs.add(new LDAPAttribute("cn", database)); + attrs.add(new LDAPAttribute("nsslapd-suffix", baseDN)); + String dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config"; + LDAPEntry entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (Exception e) { + CMS.debug("populateDB: Warning: database creation error - " + e.toString()); + releaseConnection(conn); + throw new IOException("Failed to create the database."); + } + + try { + LDAPAttributeSet attrs = new LDAPAttributeSet(); + String oc2[] = { "top", "extensibleObject", "nsMappingTree" }; + attrs.add(new LDAPAttribute("objectClass", oc2)); + attrs.add(new LDAPAttribute("cn", baseDN)); + attrs.add(new LDAPAttribute("nsslapd-backend", database)); + attrs.add(new LDAPAttribute("nsslapd-state", "Backend")); + String dn = "cn=\"" + baseDN + "\",cn=mapping tree, cn=config"; + LDAPEntry entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (Exception e) { + CMS.debug("populateDB: Warning: database mapping tree creation error - " + e.toString()); + releaseConnection(conn); + throw new IOException("Failed to create the database."); + } + + try { + // create base dn + CMS.debug("Creating base DN: " + baseDN); + String dns3[] = LDAPDN.explodeDN(baseDN, false); + StringTokenizer st = new StringTokenizer(dns3[0], "="); + String n = st.nextToken(); + String v = st.nextToken(); + LDAPAttributeSet attrs = new LDAPAttributeSet(); + String oc3[] = { "top", "domain" }; + if (n.equals("o")) { + oc3[1] = "organization"; + } else if (n.equals("ou")) { + oc3[1] = "organizationalUnit"; + } + attrs.add(new LDAPAttribute("objectClass", oc3)); + attrs.add(new LDAPAttribute(n, v)); + + LDAPEntry entry = new LDAPEntry(baseDN, attrs); + conn.add(entry); + } catch (Exception e) { + CMS.debug("populateDB: Warning: suffix creation error - " + e.toString()); + releaseConnection(conn); + throw new IOException("Failed to create the base DN: " + baseDN); + } + + try { + String select = cs.getString("preop.subsystem.select", ""); + if (select.equals("clone")) { + // if this is clone, add index before replication + // don't put in the schema or bad things will happen + importLDIFS("preop.internaldb.ldif", conn); + importLDIFS("preop.internaldb.index_ldif", conn); + importLDIFS("preop.internaldb.manager_ldif", conn); + } else { + // data will be replicated from the master to the clone + // so clone does not need the data + importLDIFS("preop.internaldb.schema.ldif", conn); + importLDIFS("preop.internaldb.ldif", conn); + importLDIFS("preop.internaldb.data_ldif", conn); + importLDIFS("preop.internaldb.index_ldif", conn); + importLDIFS("preop.internaldb.manager_ldif", conn); + } + } catch (Exception e) { + e.printStackTrace(); + CMS.debug("Failed to import ldif files" + e); + releaseConnection(conn); + throw new IOException("Failed to import ldif files"); + } + + releaseConnection(conn); + } + + public static void importLDIFS(String param, LDAPConnection conn) throws IOException, EPropertyNotFound, + EBaseException { + IConfigStore cs = CMS.getConfigStore(); + + CMS.debug("importLDIFS: param=" + param); + String v = cs.getString(param); + + String baseDN = cs.getString("internaldb.basedn"); + String database = cs.getString("internaldb.database"); + String instancePath = cs.getString("instanceRoot"); + String instanceId = cs.getString("instanceId"); + String dbuser = "uid=" + cs.getString("cs.type") + "-" + cs.getString("machineName") + "-" + + cs.getString("service.securePort") + ",ou=people," + baseDN; + String configDir = instancePath + File.separator + "conf"; + + StringTokenizer tokenizer = new StringTokenizer(v, ","); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken().trim(); + int index = token.lastIndexOf("/"); + String name = token; + + if (index != -1) { + name = token.substring(index + 1); + } + + CMS.debug("importLDIFS(): ldif file = " + token); + String filename = configDir + File.separator + name; + + CMS.debug("importLDIFS(): ldif file copy to " + filename); + PrintStream ps = null; + BufferedReader in = null; + + in = new BufferedReader(new FileReader(token)); + ps = new PrintStream(new FileOutputStream(filename, false)); + while (in.ready()) { + String s = in.readLine(); + int n = s.indexOf("{"); + + if (n == -1) { + ps.println(s); + } else { + boolean endOfline = false; + + while (n != -1) { + ps.print(s.substring(0, n)); + int n1 = s.indexOf("}"); + String tok = s.substring(n + 1, n1); + + if (tok.equals("instanceId")) { + ps.print(instanceId); + } else if (tok.equals("rootSuffix")) { + ps.print(baseDN); + } else if (tok.equals("database")) { + ps.print(database); + } else if (tok.equals("dbuser")) { + ps.print(dbuser); + } + if ((s.length() + 1) == n1) { + endOfline = true; + break; + } + s = s.substring(n1 + 1); + n = s.indexOf("{"); + } + + if (!endOfline) { + ps.println(s); + } + } + } + in.close(); + ps.close(); + + ArrayList<String> errors = new ArrayList<String>(); + LDAPUtil.importLDIF(conn, filename, errors); + if (!errors.isEmpty()) { + CMS.debug("importLDIFS(): LDAP Errors in importing " + filename); + for (String error : errors) { + CMS.debug(error); + } + } + } + } + + public static void cleanupDB(LDAPConnection conn, String baseDN, String database) { + String[] entries = {}; + String filter = "objectclass=*"; + LDAPSearchConstraints cons = null; + String[] attrs = null; + String dn = ""; + try { + CMS.debug("cleanupDB: Deleting baseDN: " + baseDN); + LDAPSearchResults res = conn.search(baseDN, LDAPConnection.SCOPE_BASE, filter, + attrs, true, cons); + if (res != null) + deleteEntries(res, conn, baseDN, entries); + } catch (LDAPException e) { + CMS.debug("cleanupDB: ldapexception thrown" + e); + } + + try { + dn = "cn=mapping tree, cn=config"; + filter = "nsslapd-backend=" + database; + LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_ONE, filter, + attrs, true, cons); + if (res != null) { + while (res.hasMoreElements()) { + dn = res.next().getDN(); + filter = "objectclass=*"; + LDAPSearchResults res2 = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, + attrs, true, cons); + if (res2 != null) + deleteEntries(res2, conn, dn, entries); + } + } + } catch (LDAPException e) { + CMS.debug("cleanupDB: ldapexception thrown" + e); + } + + try { + dn = "cn=" + database + ",cn=ldbm database, cn=plugins, cn=config"; + LDAPSearchResults res = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, + attrs, true, cons); + if (res != null) { + deleteEntries(res, conn, dn, entries); + String dbdir = getInstanceDir(conn) + "/db/" + database; + if (dbdir != null) { + CMS.debug("cleanupDB: Deleting dbdir " + dbdir); + boolean success = deleteDir(new File(dbdir)); + if (!success) { + CMS.debug("cleanupDB: Unable to delete database directory " + dbdir); + } + } + } + } catch (LDAPException e) { + CMS.debug("cleanupDB: ldapexception thrown" + e); + } + } + + public static void deleteEntries(LDAPSearchResults res, LDAPConnection conn, + String dn, String[] entries) { + String[] attrs = null; + LDAPSearchConstraints cons = null; + String filter = "objectclass=*"; + + try { + if (res.getCount() == 0) + return; + else { + while (res.hasMoreElements()) { + LDAPEntry entry = res.next(); + String dn1 = entry.getDN(); + LDAPSearchResults res1 = conn.search(dn1, 1, filter, attrs, true, cons); + deleteEntries(res1, conn, dn1, entries); + deleteEntry(conn, dn1, entries); + } + } + } catch (Exception ee) { + CMS.debug("deleteEntries: Exception=" + ee.toString()); + } + } + + public static void deleteEntry(LDAPConnection conn, String dn, String[] entries) { + try { + for (int i = 0; i < entries.length; i++) { + if (LDAPDN.equals(dn, entries[i])) { + CMS.debug("deleteEntry: entry with this dn " + dn + " is not deleted."); + return; + } + } + + CMS.debug("deleteEntry: deleting dn=" + dn); + conn.delete(dn); + } catch (Exception e) { + CMS.debug("deleteEntry: Exception=" + e.toString()); + } + } + + public static String getInstanceDir(LDAPConnection conn) throws LDAPException { + String instancedir = ""; + + String filter = "(objectclass=*)"; + String[] attrs = { "nsslapd-directory" }; + LDAPSearchResults results = conn.search("cn=config,cn=ldbm database,cn=plugins,cn=config", + LDAPv3.SCOPE_SUB, filter, attrs, false); + + while (results.hasMoreElements()) { + LDAPEntry entry = results.next(); + String dn = entry.getDN(); + CMS.debug("getInstanceDir: DN for storing nsslapd-directory: " + dn); + LDAPAttributeSet entryAttrs = entry.getAttributeSet(); + + @SuppressWarnings("unchecked") + Enumeration<LDAPAttribute> attrsInSet = entryAttrs.getAttributes(); + while (attrsInSet.hasMoreElements()) { + LDAPAttribute nextAttr = attrsInSet.nextElement(); + String attrName = nextAttr.getName(); + CMS.debug("getInstanceDir: attribute name: " + attrName); + @SuppressWarnings("unchecked") + Enumeration<String> valsInAttr = nextAttr.getStringValues(); + while (valsInAttr.hasMoreElements()) { + String nextValue = valsInAttr.nextElement(); + if (attrName.equalsIgnoreCase("nsslapd-directory")) { + CMS.debug("getInstanceDir: instanceDir=" + nextValue); + return nextValue.substring(0, nextValue.lastIndexOf("/db")); + } + } + } + } + + return instancedir; + } + + public static boolean deleteDir(File dir) { + if (dir.isDirectory()) { + String[] children = dir.list(); + for (int i = 0; i < children.length; i++) { + boolean success = deleteDir(new File(dir, children[i])); + if (!success) { + return false; + } + } + } + return dir.delete(); + } + + public static void populateIndexes() throws EPropertyNotFound, EBaseException, IOException, LDAPException { + CMS.debug("populateIndexes(): start"); + IConfigStore cs = CMS.getConfigStore(); + + IConfigStore dbCfg = cs.getSubStore("internaldb"); + ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory(); + dbFactory.init(dbCfg); + LDAPConnection conn = dbFactory.getConn(); + + try { + importLDIFS("preop.internaldb.post_ldif", conn); + + /* For vlvtask, we need to check if the task has + been completed or not. Presence of nsTaskExitCode means task is complete + */ + String wait_dn = cs.getString("preop.internaldb.wait_dn", ""); + if (!wait_dn.equals("")) { + LDAPEntry task = null; + boolean taskComplete = false; + CMS.debug("Checking wait_dn " + wait_dn); + do { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // restore the interrupted status + Thread.currentThread().interrupt(); + } + + try { + task = conn.read(wait_dn, (String[]) null); + if (task != null) { + LDAPAttribute attr = task.getAttribute("nsTaskExitCode"); + if (attr != null) { + taskComplete = true; + String val = (String) attr.getStringValues().nextElement(); + if (val.compareTo("0") != 0) { + CMS.debug("Error in populating local indexes: nsTaskExitCode=" + val); + } + } + } + } catch (Exception le) { + CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + le.toString() + ")"); + } + } while (!taskComplete); + } + } catch (Exception e) { + CMS.debug("populateIndexes(): Exception thrown: " + e); + throw e; + } finally { + releaseConnection(conn); + } + } + + public static void setupReplication() throws EBaseException, IOException { + IConfigStore cs = CMS.getConfigStore(); + + String machinename = cs.getString("machineName", ""); + String instanceId = cs.getString("instanceId", ""); + String secure = cs.getString("internaldb.ldapconn.secureConn"); + String replicationSecurity = cs.getString("internaldb.ldapconn.replicationSecurity"); + int masterReplicationPort = cs.getInteger("internaldb.ldapconn.masterReplicationPort"); + int cloneReplicationPort = cs.getInteger("internaldb.ldapconn.cloneReplicationPort"); + + //setup replication agreement + String masterAgreementName = "masterAgreement1-" + machinename + "-" + instanceId; + cs.putString("internaldb.replication.master", masterAgreementName); + String cloneAgreementName = "cloneAgreement1-" + machinename + "-" + instanceId; + cs.putString("internaldb.replication.consumer", cloneAgreementName); + + cs.commit(false); + + // get connection to master + LDAPConnection masterConn = null; + ILdapConnFactory masterFactory = null; + try { + IConfigStore masterCfg = cs.getSubStore("preop.internaldb.master"); + masterFactory = CMS.getLdapBoundConnFactory(); + masterFactory.init(masterCfg); + masterConn = masterFactory.getConn(); + } catch (Exception e) { + CMS.debug("setupEeplication: Failed to set up connection to master:" + e.toString()); + e.printStackTrace(); + releaseConnection(masterConn); + throw new IOException("Failed to set up replication: No connection to master"); + } + + // get connection to replica + LDAPConnection replicaConn = null; + ILdapConnFactory replicaFactory = null; + try { + IConfigStore replicaCfg = cs.getSubStore("internaldb"); + replicaFactory = CMS.getLdapBoundConnFactory(); + replicaFactory.init(replicaCfg); + replicaConn = replicaFactory.getConn(); + } catch (Exception e) { + CMS.debug("SetupReplication: Failed to set up connection to replica:" + e.toString()); + e.printStackTrace(); + releaseConnection(masterConn); + releaseConnection(replicaConn); + throw new IOException("Failed to set up replication: No connection to replica"); + } + + try { + String master_hostname = cs.getString("preop.internaldb.master.ldapconn.host", ""); + String master_replicationpwd = cs.getString("preop.internaldb.master.replication.password", ""); + String replica_hostname = cs.getString("internaldb.ldapconn.host", ""); + String replica_replicationpwd = cs.getString("preop.internaldb.replicationpwd", ""); + String basedn = cs.getString("internaldb.basedn"); + String suffix = cs.getString("internaldb.basedn", ""); + + String replicadn = "cn=replica,cn=\"" + suffix + "\",cn=mapping tree,cn=config"; + CMS.debug("DatabasePanel setupReplication: replicadn=" + replicadn); + + String masterBindUser = "Replication Manager " + masterAgreementName; + String cloneBindUser = "Replication Manager " + cloneAgreementName; + + createReplicationManager(masterConn, masterBindUser, master_replicationpwd); + createReplicationManager(replicaConn, cloneBindUser, replica_replicationpwd); + + String dir1 = getInstanceDir(masterConn); + createChangeLog(masterConn, dir1 + "/changelogs"); + + String dir2 = getInstanceDir(replicaConn); + createChangeLog(replicaConn, dir2 + "/changelogs"); + + int replicaId = cs.getInteger("dbs.beginReplicaNumber", 1); + + replicaId = enableReplication(replicadn, masterConn, masterBindUser, basedn, replicaId); + replicaId = enableReplication(replicadn, replicaConn, cloneBindUser, basedn, replicaId); + cs.putString("dbs.beginReplicaNumber", Integer.toString(replicaId)); + + CMS.debug("setupReplication: Finished enabling replication"); + + createReplicationAgreement(replicadn, masterConn, masterAgreementName, + replica_hostname, cloneReplicationPort, replica_replicationpwd, basedn, + cloneBindUser, secure, replicationSecurity); + + createReplicationAgreement(replicadn, replicaConn, cloneAgreementName, + master_hostname, masterReplicationPort, master_replicationpwd, basedn, + masterBindUser, secure, replicationSecurity); + + // initialize consumer + initializeConsumer(replicadn, masterConn, masterAgreementName); + + while (!replicationDone(replicadn, masterConn, masterAgreementName)) { + CMS.debug("setupReplication: Waiting for replication to complete"); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + String status = replicationStatus(replicadn, masterConn, masterAgreementName); + if (!status.startsWith("0 ")) { + CMS.debug("setupReplication: consumer initialization failed. " +status); + throw new IOException("consumer initialization failed. " + status); + } + + // remove master ldap password from password.conf (if present) + String passwordFile = cs.getString("passwordFile"); + IConfigStore psStore = CMS.createFileConfigStore(passwordFile); + psStore.remove("master_internaldb"); + psStore.commit(false); + + } catch (Exception e) { + e.printStackTrace(); + CMS.debug("setupReplication: " + e.toString()); + throw new IOException("Failed to setup the replication for cloning."); + } finally { + releaseConnection(masterConn); + releaseConnection(replicaConn); + } +} + + public static void createReplicationManager(LDAPConnection conn, String bindUser, String pwd) + throws LDAPException { + LDAPAttributeSet attrs = null; + LDAPEntry entry = null; + String dn = "cn=" + bindUser + ",ou=csusers,cn=config"; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "person")); + attrs.add(new LDAPAttribute("userpassword", pwd)); + attrs.add(new LDAPAttribute("cn", bindUser)); + attrs.add(new LDAPAttribute("sn", "manager")); + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + CMS.debug("createReplicationManager: Replication Manager has already used"); + try { + conn.delete(dn); + conn.add(entry); + } catch (LDAPException ee) { + CMS.debug("createReplicationManager: " + ee.toString()); + } + return; + } else { + CMS.debug("createReplicationManager: Failed to create replication manager. Exception: " + + e.toString()); + throw e; + } + } + + CMS.debug("createReplicationManager: Successfully created Replication Manager"); + } + + public static void createChangeLog(LDAPConnection conn, String dir) + throws LDAPException { + LDAPAttributeSet attrs = null; + LDAPEntry entry = null; + String dn = "cn=changelog5,cn=config"; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "extensibleObject")); + attrs.add(new LDAPAttribute("cn", "changelog5")); + attrs.add(new LDAPAttribute("nsslapd-changelogdir", dir)); + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + CMS.debug("createChangeLog: Changelog entry has already used"); + /* leave it, dont delete it because it will have operation error */ + return; + } else { + CMS.debug("createChangeLog: Failed to create changelog entry. Exception: " + e.toString()); + throw e; + } + } + + CMS.debug("createChangeLog: Successfully create change log entry"); + } + + public static int enableReplication(String replicadn, LDAPConnection conn, String bindUser, String basedn, int id) + throws LDAPException { + CMS.debug("enableReplication: replicadn: " + replicadn); + LDAPAttributeSet attrs = null; + LDAPEntry entry = null; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "nsDS5Replica")); + attrs.add(new LDAPAttribute("objectclass", "extensibleobject")); + attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn)); + attrs.add(new LDAPAttribute("nsDS5ReplicaType", "3")); + attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN", + "cn=" + bindUser + ",ou=csusers,cn=config")); + attrs.add(new LDAPAttribute("cn", "replica")); + attrs.add(new LDAPAttribute("nsDS5ReplicaId", Integer.toString(id))); + attrs.add(new LDAPAttribute("nsds5flags", "1")); + entry = new LDAPEntry(replicadn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + /* BZ 470918 -we cant just add the new dn. We need to do a replace instead + * until the DS code is fixed */ + CMS.debug("enableReplication: " + replicadn + " has already been used"); + + try { + entry = conn.read(replicadn); + LDAPAttribute attr = entry.getAttribute("nsDS5ReplicaBindDN"); + attr.addValue("cn=" + bindUser + ",ou=csusers,cn=config"); + LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr); + conn.modify(replicadn, mod); + } catch (LDAPException ee) { + CMS.debug("enableReplication: Failed to modify " + + replicadn + " entry. Exception: " + e.toString()); + } + return id; + } else { + CMS.debug("enableReplication: Failed to create " + + replicadn + " entry. Exception: " + e.toString()); + return id; + } + } + + CMS.debug("enableReplication: Successfully create " + replicadn + " entry."); + return id + 1; + } + + public static void createReplicationAgreement(String replicadn, LDAPConnection conn, String name, + String replicahost, int replicaport, String replicapwd, String basedn, String bindUser, + String secure, String replicationSecurity) throws LDAPException { + String dn = "cn=" + name + "," + replicadn; + CMS.debug("createReplicationAgreement: dn: " + dn); + LDAPEntry entry = null; + LDAPAttributeSet attrs = null; + try { + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", + "nsds5replicationagreement")); + attrs.add(new LDAPAttribute("cn", name)); + attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn)); + attrs.add(new LDAPAttribute("nsDS5ReplicaHost", replicahost)); + + attrs.add(new LDAPAttribute("nsDS5ReplicaPort", "" + replicaport)); + attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN", + "cn=" + bindUser + ",ou=csusers,cn=config")); + attrs.add(new LDAPAttribute("nsDS5ReplicaBindMethod", "Simple")); + attrs.add(new LDAPAttribute("nsds5replicacredentials", replicapwd)); + + if (replicationSecurity.equals("SSL")) { + attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "SSL")); + } else if (replicationSecurity.equals("TLS")) { + attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "TLS")); + } + + CMS.debug("About to set description attr to " + name); + attrs.add(new LDAPAttribute("description", name)); + + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { + CMS.debug("createReplicationAgreement: " + dn + " has already used"); + try { + conn.delete(dn); + } catch (LDAPException ee) { + CMS.debug("createReplicationAgreement: " + ee.toString()); + throw ee; + } + + try { + conn.add(entry); + } catch (LDAPException ee) { + CMS.debug("createReplicationAgreement: " + ee.toString()); + throw ee; + } + } else { + CMS.debug("createReplicationAgreement: Failed to create " + + dn + " entry. Exception: " + e.toString()); + throw e; + } + } + + CMS.debug("createReplicationAgreement: Successfully create replication agreement " + name); + } + + public static void initializeConsumer(String replicadn, LDAPConnection conn, String name) throws LDAPException { + String dn = "cn=" + name + "," + replicadn; + CMS.debug("initializeConsumer: initializeConsumer dn: " + dn); + CMS.debug("initializeConsumer: initializeConsumer host: " + conn.getHost() + " port: " + conn.getPort()); + + LDAPAttribute attr = new LDAPAttribute("nsds5beginreplicarefresh", "start"); + LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr); + conn.modify(dn, mod); + + CMS.debug("initializeConsumer: Successfully initialized consumer"); + } + + public static boolean replicationDone(String replicadn, LDAPConnection conn, String name) + throws LDAPException, IOException { + String dn = "cn=" + name + "," + replicadn; + String filter = "(objectclass=*)"; + String[] attrs = { "nsds5beginreplicarefresh" }; + + CMS.debug("replicationDone: dn: " + dn); + + LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, attrs, true); + int count = results.getCount(); + if (count < 1) { + throw new IOException("Replication entry not found"); + } + + LDAPEntry entry = results.next(); + LDAPAttribute refresh = entry.getAttribute("nsds5beginreplicarefresh"); + if (refresh == null) { + return true; + } + return false; + } + + public static String replicationStatus(String replicadn, LDAPConnection conn, String name) + throws IOException, LDAPException { + String dn = "cn=" + name + "," + replicadn; + String filter = "(objectclass=*)"; + String[] attrs = { "nsds5replicalastinitstatus" }; + + CMS.debug("replicationStatus: dn: " + dn); + + LDAPSearchResults results = conn.search(dn, LDAPConnection.SCOPE_BASE, filter, attrs, false); + + int count = results.getCount(); + if (count < 1) { + throw new IOException("Replication entry not found"); + } + + LDAPEntry entry = results.next(); + LDAPAttribute attr = entry.getAttribute("nsds5replicalastinitstatus"); + if (attr != null) { + @SuppressWarnings("unchecked") + Enumeration<String> valsInAttr = attr.getStringValues(); + if (valsInAttr.hasMoreElements()) { + return valsInAttr.nextElement(); + } else { + throw new IOException("No value returned for nsds5replicalastinitstatus"); + } + } else { + throw new IOException("nsDS5ReplicaLastInitStatus is null."); + } + } + + public static void reInitSubsystem(String csType) throws EBaseException { + CMS.reinit(IDBSubsystem.SUB_ID); + if (csType.equals("CA")) + CMS.reinit(ICertificateAuthority.ID); + CMS.reinit(IAuthSubsystem.ID); + CMS.reinit(IAuthzSubsystem.ID); + CMS.reinit(IUGSubsystem.ID); + } + + public static void createECCKeyPair(String token, String curveName, IConfigStore config, String ct) + throws NoSuchAlgorithmException, NoSuchTokenException, TokenException, + CryptoManager.NotInitializedException, EPropertyNotFound, EBaseException { + CMS.debug("createECCKeyPair: Generating ECC key pair with curvename=" + curveName + ", token=" + token); + KeyPair pair = null; + /* + * default ssl server cert to ECDHE unless stated otherwise + * note: IE only supports "ECDHE", but "ECDH" is more efficient + * + * for "ECDHE", server.xml should have the following for ciphers: + * +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + * -TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * + * for "ECDH", server.xml should have the following for ciphers: + * -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + * +TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + */ + String sslType = "ECDHE"; + try { + sslType = config.getString(PCERT_PREFIX + ct + "ec.type", "ECDHE"); + } catch (Exception e) {} + + // ECDHE needs "SIGN" but no "DERIVE" + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask[] = { + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE + }; + + // ECDH needs "DERIVE" but no any kind of "SIGN" + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage ECDH_usages_mask[] = { + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN, + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER, + }; + + do { + if (ct.equals("sslserver") && sslType.equalsIgnoreCase("ECDH")) { + CMS.debug("SizePanel: createECCKeypair: sslserver cert for ECDH. Make sure server.xml is set " + + "properly with -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"); + pair = CryptoUtil.generateECCKeyPair(token, curveName, null, ECDH_usages_mask); + } else { + if (ct.equals("sslserver")) { + CMS.debug("SizePanel: createECCKeypair: sslserver cert for ECDHE. Make sure server.xml is set " + + "properly with +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"); + } + pair = CryptoUtil.generateECCKeyPair(token, curveName, null, usages_mask); + } + + // XXX - store curve , w + byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID(); + String kid = CryptoUtil.byte2string(id); + config.putString(PCERT_PREFIX + ct + ".privkey.id", kid); + + // try to locate the private key + org.mozilla.jss.crypto.PrivateKey privk = CryptoUtil.findPrivateKeyFromID(CryptoUtil.string2byte(kid)); + if (privk == null) { + CMS.debug("Found bad ECC key id " + kid); + pair = null; + } + } while (pair == null); + + CMS.debug("Public key class " + pair.getPublic().getClass().getName()); + byte encoded[] = pair.getPublic().getEncoded(); + config.putString(PCERT_PREFIX + ct + ".pubkey.encoded", CryptoUtil.byte2string(encoded)); + + String keyAlgo = config.getString(PCERT_PREFIX + ct + ".signingalgorithm"); + setSigningAlgorithm(ct, keyAlgo, config); + } + + public static void createRSAKeyPair(String token, int keysize, IConfigStore config, String ct) + throws NoSuchAlgorithmException, NoSuchTokenException, TokenException, + CryptoManager.NotInitializedException, EPropertyNotFound, EBaseException { + /* generate key pair */ + KeyPair pair = null; + do { + pair = CryptoUtil.generateRSAKeyPair(token, keysize); + byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID(); + String kid = CryptoUtil.byte2string(id); + config.putString(PCERT_PREFIX + ct + ".privkey.id", kid); + // try to locate the private key + org.mozilla.jss.crypto.PrivateKey privk = + CryptoUtil.findPrivateKeyFromID(CryptoUtil.string2byte(kid)); + if (privk == null) { + CMS.debug("Found bad RSA key id " + kid); + pair = null; + } + } while (pair == null); + + byte modulus[] = ((RSAPublicKey) pair.getPublic()).getModulus().toByteArray(); + byte exponent[] = ((RSAPublicKey) pair.getPublic()).getPublicExponent().toByteArray(); + + config.putString(PCERT_PREFIX + ct + ".pubkey.modulus", + CryptoUtil.byte2string(modulus)); + config.putString(PCERT_PREFIX + ct + ".pubkey.exponent", + CryptoUtil.byte2string(exponent)); + + String keyAlgo = config.getString(PCERT_PREFIX + ct + ".signingalgorithm"); + setSigningAlgorithm(ct, keyAlgo, config); + } + + public static void setSigningAlgorithm(String ct, String keyAlgo, IConfigStore config) throws EPropertyNotFound, EBaseException { + String systemType = config.getString("cs.type"); + if (systemType.equalsIgnoreCase("CA")) { + if (ct.equals("signing")) { + config.putString("ca.signing.defaultSigningAlgorithm", keyAlgo); + config.putString("ca.crl.MasterCRL.signingAlgorithm", keyAlgo); + } else if (ct.equals("ocsp_signing")) { + config.putString("ca.ocsp_signing.defaultSigningAlgorithm", keyAlgo); + } + } else if (systemType.equalsIgnoreCase("OCSP")) { + if (ct.equals("signing")) { + config.putString("ocsp.signing.defaultSigningAlgorithm", keyAlgo); + } + } else if (systemType.equalsIgnoreCase("KRA") || systemType.equalsIgnoreCase("DRM")) { + if (ct.equals("transport")) { + config.putString("kra.transportUnit.signingAlgorithm", keyAlgo); + } + } + } + + public static void configCert(HttpServletRequest request, HttpServletResponse response, + Context context, Cert certObj, WizardPanelBase panel) throws IOException { + + IConfigStore config = CMS.getConfigStore(); + String caType = certObj.getType(); + CMS.debug("configCert: caType is " + caType); + X509CertImpl cert = null; + String certTag = certObj.getCertTag(); + + try { + updateConfig(config, certTag); + if (caType.equals("remote")) { + String v = config.getString("preop.ca.type", ""); + + CMS.debug("configCert: remote CA"); + String pkcs10 = CertUtil.getPKCS10(config, PCERT_PREFIX, certObj, context); + certObj.setRequest(pkcs10); + String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem"); + config.putString(subsystem + "." + certTag + ".certreq", pkcs10); + String profileId = config.getString(PCERT_PREFIX + certTag + ".profile"); + String session_id = CMS.getConfigSDSessionId(); + String sd_hostname = ""; + int sd_ee_port = -1; + try { + sd_hostname = config.getString("securitydomain.host", ""); + sd_ee_port = config.getInteger("securitydomain.httpseeport", -1); + } catch (Exception ee) { + CMS.debug("configCert(): exception caught:" + ee.toString()); + } + String sysType = config.getString("cs.type", ""); + String machineName = config.getString("machineName", ""); + String securePort = config.getString("service.securePort", ""); + if (certTag.equals("subsystem")) { + String content = + "requestor_name=" + + sysType + "-" + machineName + "-" + securePort + "&profileId=" + profileId + + "&cert_request_type=pkcs10&cert_request=" + URLEncoder.encode(pkcs10, "UTF-8") + + "&xmlOutput=true&sessionID=" + session_id; + cert = CertUtil.createRemoteCert(sd_hostname, sd_ee_port, + content, response, panel); + if (cert == null) { + throw new IOException("Error: remote certificate is null"); + } + } else if (v.equals("sdca")) { + String ca_hostname = ""; + int ca_port = -1; + try { + ca_hostname = config.getString("preop.ca.hostname", ""); + ca_port = config.getInteger("preop.ca.httpsport", -1); + } catch (Exception ee) { + } + + String content = + "requestor_name=" + + sysType + "-" + machineName + "-" + securePort + "&profileId=" + profileId + + "&cert_request_type=pkcs10&cert_request=" + URLEncoder.encode(pkcs10, "UTF-8") + + "&xmlOutput=true&sessionID=" + session_id; + cert = CertUtil.createRemoteCert(ca_hostname, ca_port, + content, response, panel); + if (cert == null) { + throw new IOException("Error: remote certificate is null"); + } + } else if (v.equals("otherca")) { + config.putString(subsystem + "." + certTag + ".cert", + "...paste certificate here..."); + } else { + CMS.debug("NamePanel: no preop.ca.type is provided"); + } + } else { // not remote CA, ie, self-signed or local + ISubsystem ca = CMS.getSubsystem(ICertificateAuthority.ID); + + if (ca == null) { + String s = PCERT_PREFIX + certTag + ".type"; + + CMS.debug( + "The value for " + s + + " should be remote, nothing else."); + throw new IOException( + "The value for " + s + " should be remote"); + } + + String pubKeyType = config.getString( + PCERT_PREFIX + certTag + ".keytype"); + if (pubKeyType.equals("rsa")) { + + String pubKeyModulus = config.getString( + PCERT_PREFIX + certTag + ".pubkey.modulus"); + String pubKeyPublicExponent = config.getString( + PCERT_PREFIX + certTag + ".pubkey.exponent"); + String subsystem = config.getString( + PCERT_PREFIX + certTag + ".subsystem"); + + if (certTag.equals("signing")) { + X509Key x509key = CryptoUtil.getPublicX509Key( + CryptoUtil.string2byte(pubKeyModulus), + CryptoUtil.string2byte(pubKeyPublicExponent)); + + cert = CertUtil.createLocalCert(config, x509key, + PCERT_PREFIX, certTag, caType, context); + } else { + String cacert = config.getString("ca.signing.cert", ""); + + if (cacert.equals("") || cacert.startsWith("...")) { + certObj.setCert( + "...certificate be generated internally..."); + config.putString(subsystem + "." + certTag + ".cert", + "...certificate be generated internally..."); + } else { + X509Key x509key = CryptoUtil.getPublicX509Key( + CryptoUtil.string2byte(pubKeyModulus), + CryptoUtil.string2byte(pubKeyPublicExponent)); + + cert = CertUtil.createLocalCert(config, x509key, + PCERT_PREFIX, certTag, caType, context); + } + } + } else if (pubKeyType.equals("ecc")) { + String pubKeyEncoded = config.getString( + PCERT_PREFIX + certTag + ".pubkey.encoded"); + String subsystem = config.getString( + PCERT_PREFIX + certTag + ".subsystem"); + + if (certTag.equals("signing")) { + + X509Key x509key = CryptoUtil.getPublicX509ECCKey(CryptoUtil.string2byte(pubKeyEncoded)); + cert = CertUtil.createLocalCert(config, x509key, + PCERT_PREFIX, certTag, caType, context); + } else { + String cacert = config.getString("ca.signing.cert", ""); + + if (cacert.equals("") || cacert.startsWith("...")) { + certObj.setCert( + "...certificate be generated internally..."); + config.putString(subsystem + "." + certTag + ".cert", + "...certificate be generated internally..."); + } else { + X509Key x509key = CryptoUtil.getPublicX509ECCKey( + CryptoUtil.string2byte(pubKeyEncoded)); + + cert = CertUtil.createLocalCert(config, x509key, + PCERT_PREFIX, certTag, caType, context); + } + } + } else { + // invalid key type + CMS.debug("Invalid key type " + pubKeyType); + } + if (cert != null) { + if (certTag.equals("subsystem")) + CertUtil.addUserCertificate(cert); + } + } // done self-signed or local + + if (cert != null) { + byte[] certb = cert.getEncoded(); + String certs = CryptoUtil.base64Encode(certb); + + certObj.setCert(certs); + String subsystem = config.getString( + PCERT_PREFIX + certTag + ".subsystem"); + config.putString(subsystem + "." + certTag + ".cert", certs); + } + config.commit(false); + } catch (IOException e) { + throw e; + } catch (Exception e) { + CMS.debug("configCert() exception caught:" + e.toString()); + } + } + + public static void updateConfig(IConfigStore config, String certTag) + throws EBaseException, IOException { + String token = config.getString("preop.module.token"); + String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem"); + String nickname = getNickname(config, certTag); + + CMS.debug("NamePanel: updateConfig() for certTag " + certTag); + if (certTag.equals("signing") || certTag.equals("ocsp_signing")) { + CMS.debug("NamePanel: setting signing nickname=" + nickname); + config.putString(subsystem + "." + certTag + ".cacertnickname", nickname); + config.putString(subsystem + "." + certTag + ".certnickname", nickname); + } + + // if KRA, hardware token needs param "kra.storageUnit.hardware" in CS.cfg + String cstype = config.getString("cs.type", null); + cstype = cstype.toLowerCase(); + if (cstype.equals("kra")) { + if (!token.equals("Internal Key Storage Token")) { + if (certTag.equals("storage")) { + config.putString(subsystem + ".storageUnit.hardware", token); + config.putString(subsystem + ".storageUnit.nickName", token + ":" + nickname); + } else if (certTag.equals("transport")) { + config.putString(subsystem + ".transportUnit.nickName", token + ":" + nickname); + } + } else { // software token + if (certTag.equals("storage")) { + config.putString(subsystem + ".storageUnit.nickName", nickname); + } else if (certTag.equals("transport")) { + config.putString(subsystem + ".transportUnit.nickName", nickname); + } + } + } + + String serverCertNickname = nickname; + String path = CMS.getConfigStore().getString("instanceRoot", ""); + if (certTag.equals("sslserver")) { + if (!token.equals("Internal Key Storage Token")) { + serverCertNickname = token + ":" + nickname; + } + PrintStream ps = new PrintStream(new FileOutputStream(path + "/conf/serverCertNick.conf")); + ps.println(serverCertNickname); + ps.close(); + } + + config.putString(subsystem + "." + certTag + ".nickname", nickname); + config.putString(subsystem + "." + certTag + ".tokenname", token); + if (certTag.equals("audit_signing")) { + if (!token.equals("Internal Key Storage Token") && !token.equals("")) { + config.putString("log.instance.SignedAudit.signedAuditCertNickname", + token + ":" + nickname); + } else { + config.putString("log.instance.SignedAudit.signedAuditCertNickname", + nickname); + } + } + + // for system certs verification + if (!token.equals("Internal Key Storage Token") && !token.equals("")) { + config.putString(subsystem + ".cert." + certTag + ".nickname", + token + ":" + nickname); + } else { + config.putString(subsystem + ".cert." + certTag + ".nickname", nickname); + } + + config.commit(false); + CMS.debug("updateConfig() done"); + } + + public static String getNickname(IConfigStore config, String certTag) throws EBaseException { + String instanceID = config.getString("instanceId", ""); + + String nickname = certTag + "Cert cert-" + instanceID; + String preferredNickname = null; + try { + preferredNickname = config.getString(PCERT_PREFIX + certTag + ".nickname", null); + } catch (EBaseException e) { + } + + if (preferredNickname != null) { + return preferredNickname; + } + return nickname; + } + + public static int getPortFromSecurityDomain(String domainXML, String host, int port, String csType, + String givenTag, String wantedTag) throws SAXException, IOException, ParserConfigurationException { + IConfigStore cs = CMS.getConfigStore(); + ByteArrayInputStream bis = new ByteArrayInputStream(domainXML.getBytes()); + XMLObject parser = new XMLObject(bis); + Document doc = parser.getDocument(); + NodeList nodeList = doc.getElementsByTagName(csType); + + // save domain name in cfg + cs.putString("securitydomain.name", parser.getValue("Name")); + + int len = nodeList.getLength(); + CMS.debug("len: "+ len); + for (int i = 0; i < len; i++) { + Node node = nodeList.item(i); + String v_host = parser.getValuesFromContainer(node, "Host").elementAt(0); + CMS.debug("v_host " + v_host); + String v_given_port = parser.getValuesFromContainer(node, givenTag).elementAt(0); + CMS.debug("v_port " + v_given_port); + if (!(v_host.equals(host) && v_given_port.equals(port + ""))) + continue; + String wanted_port = parser.getValuesFromContainer(node, wantedTag).elementAt(0); + return Integer.parseInt(wanted_port); + } + + return 0; + } + + public static void updateCloneConfig() + throws EBaseException, IOException { + IConfigStore config = CMS.getConfigStore(); + String cstype = config.getString("cs.type", null); + cstype = cstype.toLowerCase(); + if (cstype.equals("kra")) { + String token = config.getString("preop.module.token"); + if (!token.equals("Internal Key Storage Token")) { + CMS.debug("NamePanel: updating configuration for KRA clone with hardware token"); + String subsystem = config.getString(PCERT_PREFIX + "storage.subsystem"); + String storageNickname = getNickname(config, "storage"); + String transportNickname = getNickname(config, "transport"); + + config.putString(subsystem + ".storageUnit.hardware", token); + config.putString(subsystem + ".storageUnit.nickName", token + ":" + storageNickname); + config.putString(subsystem + ".transportUnit.nickName", token + ":" + transportNickname); + config.commit(false); + } else { // software token + // parameters already set + } + } + + // audit signing cert + String audit_nn = config.getString(cstype + ".audit_signing" + ".nickname", ""); + String audit_tk = config.getString(cstype + ".audit_signing" + ".tokenname", ""); + if (!audit_tk.equals("Internal Key Storage Token") && !audit_tk.equals("")) { + config.putString("log.instance.SignedAudit.signedAuditCertNickname", + audit_tk + ":" + audit_nn); + } else { + config.putString("log.instance.SignedAudit.signedAuditCertNickname", + audit_nn); + } + } + + public static void handleCertRequest(IConfigStore config, String certTag, Cert cert) throws EPropertyNotFound, + EBaseException, InvalidKeyException, NotInitializedException, TokenException, NoSuchAlgorithmException, + NoSuchProviderException, CertificateException, SignatureException, IOException { + + // get public key + String pubKeyType = config.getString(PCERT_PREFIX + certTag + ".keytype"); + String algorithm = config.getString(PCERT_PREFIX + certTag + ".keyalgorithm"); + X509Key pubk = null; + if (pubKeyType.equals("rsa")) { + pubk = getRSAX509Key(config, certTag); + } else if (pubKeyType.equals("ecc")) { + pubk = getECCX509Key(config, certTag); + } else { + CMS.debug("handleCertRequest() - " + "pubKeyType " + pubKeyType + " is unsupported!"); + return; + } + + CMS.debug("handleCertRequest: tag=" + certTag); + if (pubk == null) { + CMS.debug("handleCertRequest: error getting public key null"); + return; + } + + // get private key + String privKeyID = config.getString(PCERT_PREFIX + certTag + ".privkey.id"); + CMS.debug("privKeyID=" + privKeyID); + byte[] keyIDb = CryptoUtil.string2byte(privKeyID); + + PrivateKey privk = CryptoUtil.findPrivateKeyFromID(keyIDb); + if (privk == null) { + CMS.debug("handleCertRequest: error getting private key"); + } + + // construct cert request + String caDN = config.getString(PCERT_PREFIX + certTag + ".dn"); + + cert.setDN(caDN); + PKCS10 certReq = CryptoUtil.createCertificationRequest(caDN, pubk, privk, algorithm); + + CMS.debug("handleCertRequest: created cert request"); + byte[] certReqb = certReq.toByteArray(); + String certReqs = CryptoUtil.base64Encode(certReqb); + String certReqf = CryptoUtil.reqFormat(certReqs); + + String subsystem = config.getString(PCERT_PREFIX + certTag + ".subsystem"); + config.putString(subsystem + "." + certTag + ".certreq", certReqs); + config.commit(false); + cert.setRequest(certReqf); + + } + + public static X509Key getECCX509Key(IConfigStore config, String certTag) throws EPropertyNotFound, EBaseException, + InvalidKeyException { + X509Key pubk = null; + String pubKeyEncoded = config.getString(PCERT_PREFIX + certTag + ".pubkey.encoded"); + pubk = CryptoUtil.getPublicX509ECCKey(CryptoUtil.string2byte(pubKeyEncoded)); + return pubk; + } + + public static X509Key getRSAX509Key(IConfigStore config, String certTag) throws EPropertyNotFound, EBaseException, + InvalidKeyException { + X509Key pubk = null; + + String pubKeyModulus = config.getString(PCERT_PREFIX + certTag + ".pubkey.modulus"); + String pubKeyPublicExponent = config.getString(PCERT_PREFIX + certTag + ".pubkey.exponent"); + pubk = CryptoUtil.getPublicX509Key( + CryptoUtil.string2byte(pubKeyModulus), + CryptoUtil.string2byte(pubKeyPublicExponent)); + return pubk; + } + + public static int handleCerts(Cert cert) throws IOException, EBaseException, CertificateException, + NotInitializedException, TokenException, InvalidKeyException { + String certTag = cert.getCertTag(); + String subsystem = cert.getSubsystem(); + String nickname = cert.getNickname(); + IConfigStore config = CMS.getConfigStore(); + + boolean enable = config.getBoolean(PCERT_PREFIX + certTag + ".enable", true); + if (!enable) return 0; + + CMS.debug("handleCerts(): for cert tag " + cert.getCertTag()); + String b64 = cert.getCert(); + String tokenname = config.getString("preop.module.token", ""); + + if (cert.getType().equals("local") && b64.equals("...certificate be generated internally...")) { + String pubKeyType = config.getString(PCERT_PREFIX + certTag + ".keytype"); + X509Key x509key = null; + if (pubKeyType.equals("rsa")) { + x509key = getRSAX509Key(config, certTag); + } else if (pubKeyType.equals("ecc")) { + x509key = getECCX509Key(config, certTag); + } + + if (findCertificate(tokenname, nickname)) { + if (!certTag.equals("sslserver")) return 0; + } + X509CertImpl impl = CertUtil.createLocalCert(config, x509key, + PCERT_PREFIX, certTag, cert.getType(), null); + + if (impl != null) { + byte[] certb = impl.getEncoded(); + String certs = CryptoUtil.base64Encode(certb); + + cert.setCert(certs); + config.putString(subsystem + "." + certTag + ".cert", certs); + CMS.debug("handleCerts(): nickname=" + nickname); + + try { + if (certTag.equals("sslserver") && findBootstrapServerCert()) + deleteBootstrapServerCert(); + if (findCertificate(tokenname, nickname)) + deleteCert(tokenname, nickname); + if (certTag.equals("signing") && subsystem.equals("ca")) + CryptoUtil.importUserCertificate(impl, nickname); + else + CryptoUtil.importUserCertificate(impl, nickname, false); + CMS.debug("handleCerts(): cert imported for certTag " + certTag); + } catch (Exception ee) { + CMS.debug("handleCerts(): import certificate for certTag=" + certTag + " Exception: " + ee.toString()); + } + } + } else if (cert.getType().equals("remote")) { + if (b64 != null && b64.length() > 0 && !b64.startsWith("...")) { + CMS.debug("handleCert(): process remote...import cert"); + String b64chain = cert.getCertChain(); + + try { + if (certTag.equals("sslserver") && findBootstrapServerCert()) + deleteBootstrapServerCert(); + if (findCertificate(tokenname, nickname)) { + deleteCert(tokenname, nickname); + } + } catch (Exception e) { + CMS.debug("CertRequestPanel update (remote): deleteCert Exception=" + e.toString()); + } + byte[] certb = CryptoUtil.base64Decode(b64); + + config.putString(subsystem + "." + certTag + ".cert", b64); + try { + CryptoManager cm = CryptoManager.getInstance(); + X509Certificate x509cert = cm.importCertPackage(certb, nickname); + CryptoUtil.trustCertByNickname(nickname); + + X509Certificate[] certchains = cm.buildCertificateChain(x509cert); + X509Certificate leaf = null; + + if (certchains != null) { + CMS.debug("handleCerts(): certchains length=" + certchains.length); + leaf = certchains[certchains.length - 1]; + } + + if (leaf == null) { + CMS.debug("handleCerts(): leaf is null!"); + throw new IOException("leaf is null"); + } + + if (b64chain != null && b64chain.length() != 0) { + CMS.debug("handlecerts: cert might not have contained chain...calling importCertificateChain: " + + b64chain); + try { + CryptoUtil.importCertificateChain(CryptoUtil.normalizeCertAndReq(b64chain)); + } catch (Exception e) { + CMS.debug("handleCerts(): importCertChain: Exception: " + e.toString()); + } + } + + InternalCertificate icert = (InternalCertificate) leaf; + + icert.setSSLTrust( + InternalCertificate.TRUSTED_CA + | InternalCertificate.TRUSTED_CLIENT_CA + | InternalCertificate.VALID_CA); + CMS.debug("handleCerts(): import certificate successfully, certTag=" + certTag); + } catch (Exception ee) { + CMS.debug("handleCerts: import certificate for certTag=" + certTag + " Exception: "+ ee.toString()); + } + + } else { + CMS.debug("handleCert(): b64 not set"); + return 1; + } + } else { + b64 = CryptoUtil.stripCertBrackets(b64.trim()); + String certs = CryptoUtil.normalizeCertStr(b64); + byte[] certb = CryptoUtil.base64Decode(certs); + X509CertImpl impl = new X509CertImpl(certb); + try { + if (certTag.equals("sslserver") && findBootstrapServerCert()) + deleteBootstrapServerCert(); + if (findCertificate(tokenname, nickname)) { + deleteCert(tokenname, nickname); + } + } catch (Exception ee) { + CMS.debug("handleCert(): deleteCert Exception=" + ee.toString()); + } + + try { + if (certTag.equals("signing") && subsystem.equals("ca")) + CryptoUtil.importUserCertificate(impl, nickname); + else + CryptoUtil.importUserCertificate(impl, nickname, false); + } catch (Exception ee) { + CMS.debug("handleCerts(): Failed to import user certificate." + ee.toString()); + return 1; + } + } + + //update requests in request queue for local certs to allow renewal + if ((cert.getType().equals("local")) || (cert.getType().equals("selfsign"))) { + CertUtil.updateLocalRequest(config, certTag, cert.getRequest(), "pkcs10", null); + } + + if (certTag.equals("signing") && subsystem.equals("ca")) { + String NickName = nickname; + if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")) + NickName = tokenname + ":" + nickname; + + CMS.debug("handleCerts(): set trust on CA signing cert " + NickName); + CryptoUtil.trustCertByNickname(NickName); + CMS.reinit(ICertificateAuthority.ID); + } + return 0; + } + + public static void setCertPermissions(String tag) throws EBaseException, NotInitializedException, + ObjectNotFoundException, TokenException { + if (tag.equals("signing")) return; + + IConfigStore cs = CMS.getConfigStore(); + String nickname = cs.getString("preop.cert." + tag + ".nickname", ""); + String tokenname = cs.getString("preop.module.token", ""); + if (!tokenname.equals("Internal Key Storage Token")) + nickname = tokenname + ":" + nickname; + + CryptoManager cm = CryptoManager.getInstance(); + X509Certificate c = cm.findCertByNickname(nickname); + + if (c instanceof InternalCertificate) { + InternalCertificate ic = (InternalCertificate) c; + ic.setSSLTrust(InternalCertificate.USER); + ic.setEmailTrust(InternalCertificate.USER); + if (tag.equals("audit_signing")) { + ic.setObjectSigningTrust(InternalCertificate.USER + | InternalCertificate.VALID_PEER | InternalCertificate.TRUSTED_PEER); + } else { + ic.setObjectSigningTrust(InternalCertificate.USER); + } + } + } + + public static boolean findCertificate(String tokenname, String nickname) throws NotInitializedException, + TokenException, IOException { + IConfigStore cs = CMS.getConfigStore(); + CryptoManager cm = CryptoManager.getInstance(); + + String fullnickname = nickname; + boolean hardware = false; + if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token")) { + hardware = true; + fullnickname = tokenname + ":" + nickname; + } + + X509Certificate cert = null; + try { + cert = cm.findCertByNickname(fullnickname); + } catch (ObjectNotFoundException e) { + return false; + } + + if (cert == null) + return false; + try { + @SuppressWarnings("unused") + boolean done = cs.getBoolean("preop.CertRequestPanel.done"); // check for errors + } catch (Exception ee) { + if (hardware) { + CMS.debug("CertRequestPanel findCertificate: The certificate with the same nickname: " + + fullnickname + " has been found on HSM. Please remove it before proceeding."); + throw new IOException("The certificate with the same nickname: " + + fullnickname + " has been found on HSM. Please remove it before proceeding."); + } + } + return true; + } + + + public static boolean findBootstrapServerCert() throws EBaseException, NotInitializedException, TokenException { + IConfigStore cs = CMS.getConfigStore(); + + String instanceID = cs.getString("instanceId", ""); + String nickname = "Server-Cert cert-" + instanceID; + + CryptoManager cm = CryptoManager.getInstance(); + X509Certificate cert; + try { + cert = cm.findCertByNickname(nickname); + } catch (ObjectNotFoundException e) { + return false; + } + Principal issuerDN = cert.getIssuerDN(); + Principal subjectDN = cert.getSubjectDN(); + if (issuerDN.equals(subjectDN)) return true; + + return false; + } + + public static void deleteBootstrapServerCert() throws EBaseException, NotInitializedException, + NoSuchTokenException, TokenException { + IConfigStore cs = CMS.getConfigStore(); + String instanceID = cs.getString("instanceId", ""); + String nickname = "Server-Cert cert-" + instanceID; + deleteCert("Internal Key Storage Token", nickname); + } + + public static void deleteCert(String tokenname, String nickname) throws NotInitializedException, + NoSuchTokenException, TokenException { + + CryptoManager cm = CryptoManager.getInstance(); + CryptoToken tok = cm.getTokenByName(tokenname); + CryptoStore store = tok.getCryptoStore(); + String fullnickname = nickname; + if (!tokenname.equals("") && + !tokenname.equals("Internal Key Storage Token") && + !tokenname.equals("internal")) + fullnickname = tokenname + ":" + nickname; + + CMS.debug("deleteCert: nickname=" + fullnickname); + X509Certificate cert; + try { + cert = cm.findCertByNickname(fullnickname); + } catch (ObjectNotFoundException e) { + CMS.debug("deleteCert: cert not found"); + return; + } + + if (store instanceof PK11Store) { + PK11Store pk11store = (PK11Store) store; + try { + pk11store.deleteCertOnly(cert); + } catch (NoSuchItemOnTokenException e) { + } + CMS.debug("deleteCert: cert deleted successfully"); + } + } + + public static void backupKeys(String pwd, String fname) throws EPropertyNotFound, EBaseException, + NotInitializedException, ObjectNotFoundException, TokenException, DigestException, + InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidBERException, + CertificateEncodingException, IllegalStateException, IllegalBlockSizeException, BadPaddingException, + IOException { + CMS.debug("backupKeys(): start"); + IConfigStore cs = CMS.getConfigStore(); + String certlist = cs.getString("preop.cert.list"); + + StringTokenizer st = new StringTokenizer(certlist, ","); + CryptoManager cm = CryptoManager.getInstance(); + + Password pass = new org.mozilla.jss.util.Password(pwd.toCharArray()); + SEQUENCE encSafeContents = new SEQUENCE(); + SEQUENCE safeContents = new SEQUENCE(); + while (st.hasMoreTokens()) { + String t = st.nextToken(); + if (t.equals("sslserver")) + continue; + String nickname = cs.getString("preop.cert." + t + ".nickname"); + String modname = cs.getString("preop.module.token"); + + if (!modname.equals("Internal Key Storage Token")) + nickname = modname + ":" + nickname; + + X509Certificate x509cert = cm.findCertByNickname(nickname); + byte localKeyId[] = addCertBag(x509cert, nickname, safeContents); + PrivateKey pkey = cm.findPrivKeyByCert(x509cert); + addKeyBag(pkey, x509cert, pass, localKeyId, encSafeContents); + } + + X509Certificate[] cacerts = cm.getCACerts(); + + for (int i = 0; i < cacerts.length; i++) { + String nickname = null; + addCertBag(cacerts[i], nickname, safeContents); + } + + AuthenticatedSafes authSafes = new AuthenticatedSafes(); + authSafes.addSafeContents(safeContents); + authSafes.addSafeContents(encSafeContents); + PFX pfx = new PFX(authSafes); + pfx.computeMacData(pass, null, 5); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + pfx.encode(bos); + byte[] output = bos.toByteArray(); + cs.putString("preop.pkcs12", CryptoUtil.byte2string(output)); + pass.clear(); + cs.commit(false); + + if (fname != null) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(fname); + fout.write(output); + } catch (Exception e) { + throw new IOException("Failed to store keys in backup file" + e); + } finally { + if (fout != null) { + fout.close(); + } + } + } + } + + public static void addKeyBag(PrivateKey pkey, X509Certificate x509cert, + Password pass, byte[] localKeyId, SEQUENCE safeContents) + throws NoSuchAlgorithmException, InvalidBERException, InvalidKeyException, + InvalidAlgorithmParameterException, NotInitializedException, TokenException, IllegalStateException, + IllegalBlockSizeException, BadPaddingException, CharConversionException { + + PasswordConverter passConverter = new PasswordConverter(); + + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + byte salt[] = random.generateSeed(4); // 4 bytes salt + byte[] priData = getEncodedKey(pkey); + + PrivateKeyInfo pki = (PrivateKeyInfo) + ASN1Util.decode(PrivateKeyInfo.getTemplate(), priData); + ASN1Value key = EncryptedPrivateKeyInfo.createPBE( + PBEAlgorithm.PBE_SHA1_DES3_CBC, + pass, salt, 1, passConverter, pki); + SET keyAttrs = createBagAttrs( + x509cert.getSubjectDN().toString(), localKeyId); + SafeBag keyBag = new SafeBag(SafeBag.PKCS8_SHROUDED_KEY_BAG, + key, keyAttrs); + safeContents.addElement(keyBag); + + } + + public static byte[] addCertBag(X509Certificate x509cert, String nickname, + SEQUENCE safeContents) throws CertificateEncodingException, NoSuchAlgorithmException, CharConversionException { + byte[] localKeyId = null; + + ASN1Value cert = new OCTET_STRING(x509cert.getEncoded()); + localKeyId = createLocalKeyId(x509cert); + SET certAttrs = null; + if (nickname != null) + certAttrs = createBagAttrs(nickname, localKeyId); + SafeBag certBag = new SafeBag(SafeBag.CERT_BAG, + new CertBag(CertBag.X509_CERT_TYPE, cert), certAttrs); + safeContents.addElement(certBag); + + return localKeyId; + } + + public static byte[] getEncodedKey(PrivateKey pkey) throws NotInitializedException, NoSuchAlgorithmException, + TokenException, IllegalStateException, CharConversionException, InvalidKeyException, + InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { + CryptoManager cm = CryptoManager.getInstance(); + CryptoToken token = cm.getInternalKeyStorageToken(); + KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3); + SymmetricKey sk = kg.generate(); + KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); + byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; + IVParameterSpec param = new IVParameterSpec(iv); + wrapper.initWrap(sk, param); + byte[] enckey = wrapper.wrap(pkey); + Cipher c = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); + c.initDecrypt(sk, param); + byte[] recovered = c.doFinal(enckey); + return recovered; + } + + public static byte[] createLocalKeyId(X509Certificate cert) + throws NoSuchAlgorithmException, CertificateEncodingException { + + // SHA1 hash of the X509Cert der encoding + byte certDer[] = cert.getEncoded(); + + MessageDigest md = MessageDigest.getInstance("SHA"); + + md.update(certDer); + return md.digest(); + + } + + public static SET createBagAttrs(String nickName, byte localKeyId[]) throws CharConversionException { + + SET attrs = new SET(); + SEQUENCE nickNameAttr = new SEQUENCE(); + + nickNameAttr.addElement(SafeBag.FRIENDLY_NAME); + SET nickNameSet = new SET(); + + nickNameSet.addElement(new BMPString(nickName)); + nickNameAttr.addElement(nickNameSet); + attrs.addElement(nickNameAttr); + SEQUENCE localKeyAttr = new SEQUENCE(); + + localKeyAttr.addElement(SafeBag.LOCAL_KEY_ID); + SET localKeySet = new SET(); + + localKeySet.addElement(new OCTET_STRING(localKeyId)); + localKeyAttr.addElement(localKeySet); + attrs.addElement(localKeyAttr); + return attrs; + + } + + public static void createAdminCertificate(String certRequest, String certRequestType, String subject) + throws InvalidBERException, IOException, InvalidKeyException, InvalidKeyFormatException, + NoSuchAlgorithmException, SignatureException, NoSuchProviderException, EBaseException { + IConfigStore cs = CMS.getConfigStore(); + X509Key x509key = null; + if (certRequestType.equals("crmf")) { + byte[] b = CMS.AtoB(certRequest); + SEQUENCE crmfMsgs = CryptoUtil.parseCRMFMsgs(b); + subject = CryptoUtil.getSubjectName(crmfMsgs); + x509key = CryptoUtil.getX509KeyFromCRMFMsgs(crmfMsgs); + } else if (certRequestType.equals("pkcs10")) { + byte[] b = CMS.AtoB(certRequest); + PKCS10 pkcs10 = new PKCS10(b); + x509key = pkcs10.getSubjectPublicKeyInfo(); + } + + if (x509key == null) { + CMS.debug("createAdminCertificate() - x509key is null!"); + throw new IOException("x509key is null"); + } + + cs.putString(PCERT_PREFIX + "admin.dn", subject); + String caType = cs.getString(PCERT_PREFIX + "admin.type", "local"); + X509CertImpl impl = CertUtil.createLocalCert(cs, x509key, PCERT_PREFIX, "admin", caType, null); + + // update the locally created request for renewal + CertUtil.updateLocalRequest(cs, "admin", certRequest, certRequestType, subject); + + ISubsystem ca = CMS.getSubsystem("ca"); + if (ca != null) { + createPKCS7(impl); + } + cs.putString("preop.admincert.serialno.0", impl.getSerialNumber().toString(16)); + } + + public static void createPKCS7(X509CertImpl cert) throws IOException { + IConfigStore cs = CMS.getConfigStore(); + ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem("ca"); + CertificateChain cachain = ca.getCACertChain(); + java.security.cert.X509Certificate[] cacerts = cachain.getChain(); + X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1]; + int m = 1, n = 0; + + for (; n < cacerts.length; m++, n++) { + userChain[m] = (X509CertImpl) cacerts[n]; + } + + userChain[0] = cert; + PKCS7 p7 = new PKCS7(new AlgorithmId[0], + new ContentInfo(new byte[0]), userChain, new SignerInfo[0]); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + p7.encodeSignedData(bos); + byte[] p7Bytes = bos.toByteArray(); + String p7Str = CMS.BtoA(p7Bytes); + cs.putString("preop.admincert.pkcs7", CryptoUtil.normalizeCertStr(p7Str)); + } + + public static void createAdmin(String uid, String email, String name, String pwd) throws IOException, + EBaseException { + IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID)); + IConfigStore config = CMS.getConfigStore(); + String groupName = config.getString("preop.admin.group", "Certificate Manager Agents"); + + IUser user = null; + + try { + user = system.createUser(uid); + user.setEmail(email); + user.setPassword(pwd); + user.setFullName(name); + user.setUserType("adminType"); + user.setState("1"); + user.setPhone(""); + system.addUser(user); + } catch (LDAPException e) { + CMS.debug("AdminPanel createAdmin: addUser " + e.toString()); + if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) { + throw new IOException(e.toString()); + } + } catch (Exception e) { + CMS.debug("AdminPanel createAdmin: addUser " + e.toString()); + throw new IOException(e.toString()); + } + + IGroup group = null; + + group = system.getGroupFromName(groupName); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + group = system.getGroupFromName("Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + + String select = config.getString("securitydomain.select", ""); + if (select.equals("new")) { + group = system.getGroupFromName("Security Domain Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + + group = system.getGroupFromName("Enterprise CA Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + + group = system.getGroupFromName("Enterprise KRA Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + + group = system.getGroupFromName("Enterprise RA Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + + group = system.getGroupFromName("Enterprise TKS Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + + group = system.getGroupFromName("Enterprise OCSP Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + + group = system.getGroupFromName("Enterprise TPS Administrators"); + if (!group.isMember(uid)) { + group.addMemberName(uid); + system.modifyGroup(group); + } + } + } + + public static String submitAdminCertRequest(String ca_hostname, int ca_port, String profileId, + String certRequestType, String certRequest, String subjectDN) throws IOException, EBaseException, + SAXException, ParserConfigurationException { + IConfigStore config = CMS.getConfigStore(); + + if (profileId == null) { + profileId = config.getString("preop.admincert.profile", "caAdminCert"); + } + certRequest = URLEncoder.encode(certRequest, "UTF-8"); + String session_id = CMS.getConfigSDSessionId(); + String content = "profileId=" + profileId + "&cert_request_type=" + certRequestType + + "&cert_request=" + certRequest + "&xmlOutput=true&sessionID=" + session_id + "&subject=" + subjectDN; + + String c = getHttpResponse(ca_hostname, ca_port, true, "/ca/ee/ca/profileSubmit", content, null, null); + + // retrieve the request Id and admin certificate + if (c != null) { + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = new XMLObject(bis); + + String status = parser.getValue("Status"); + CMS.debug("submitAdminXertRequest: status=" + status); + if (status.equals(AUTH_FAILURE)) { + throw new EAuthException(AUTH_FAILURE); + } else if (!status.equals(SUCCESS)) { + String error = parser.getValue("Error"); + throw new IOException(error); + } + + IConfigStore cs = CMS.getConfigStore(); + String id = parser.getValue("Id"); + + cs.putString("preop.admincert.requestId.0", id); + String serial = parser.getValue("serialno"); + + cs.putString("preop.admincert.serialno.0", serial); + String b64 = parser.getValue("b64"); + + // save in a file for access by ImportAdminCertPanel + String instanceRoot = cs.getString("instanceRoot", ""); + String dir = instanceRoot + File.separator + "conf" + File.separator + "admin.b64"; + cs.putString("preop.admincert.b64", dir); + + PrintStream ps = new PrintStream(new FileOutputStream(dir)); + ps.println(b64); + ps.flush(); + ps.close(); + + return b64; + } else { + throw new IOException("submitAdminCertRequest: Failed to get response from ca"); + } + } + + public static void createSecurityDomain() throws EBaseException, LDAPException, NumberFormatException, IOException, + SAXException, ParserConfigurationException { + IConfigStore cs = CMS.getConfigStore(); + IConfigStore dbCfg = cs.getSubStore("internaldb"); + ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory(); + dbFactory.init(dbCfg); + LDAPConnection conn = dbFactory.getConn(); + LDAPEntry entry = null; + LDAPAttributeSet attrs = null; + + // Create security domain ldap entry + String basedn = cs.getString("internaldb.basedn"); + String secdomain = cs.getString("securitydomain.name"); + + String dn = "ou=Security Domain," + basedn; + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "pkiSecurityDomain")); + attrs.add(new LDAPAttribute("name", secdomain)); + attrs.add(new LDAPAttribute("ou", "Security Domain")); + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + + // create list containers + String clist[] = { "CAList", "OCSPList", "KRAList", "RAList", "TKSList", "TPSList" }; + for (int i = 0; i < clist.length; i++) { + dn = "cn=" + clist[i] + ",ou=Security Domain," + basedn; + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "pkiSecurityGroup")); + attrs.add(new LDAPAttribute("cn", clist[i])); + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + } + + // Add this host + String cn = CMS.getEESSLHost() + ":" + CMS.getAdminPort(); + dn = "cn=" + cn + ",cn=CAList,ou=Security Domain," + basedn; + String subsystemName = cs.getString("preop.subsystem.name"); + attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectclass", "top")); + attrs.add(new LDAPAttribute("objectclass", "pkiSubsystem")); + attrs.add(new LDAPAttribute("Host", CMS.getEESSLHost())); + attrs.add(new LDAPAttribute("SecurePort", CMS.getEESSLPort())); + attrs.add(new LDAPAttribute("SecureAgentPort", CMS.getAgentPort())); + attrs.add(new LDAPAttribute("SecureAdminPort", CMS.getAdminPort())); + if (CMS.getEEClientAuthSSLPort() != null) { + attrs.add(new LDAPAttribute("SecureEEClientAuthPort", CMS.getEEClientAuthSSLPort())); + } + attrs.add(new LDAPAttribute("UnSecurePort", CMS.getEENonSSLPort())); + attrs.add(new LDAPAttribute("Clone", "FALSE")); + attrs.add(new LDAPAttribute("SubsystemName", subsystemName)); + attrs.add(new LDAPAttribute("cn", cn)); + attrs.add(new LDAPAttribute("DomainManager", "TRUE")); + entry = new LDAPEntry(dn, attrs); + conn.add(entry); + + CMS.debug("createSecurityDomain(): finish updating domain info"); + conn.disconnect(); + + // Fetch the "new" security domain and display it + // CMS.debug("createSecurityDomain(): Dump contents of new Security Domain . . ."); + // @SuppressWarnings("unused") + // String c = getDomainXML(CMS.getEESSLHost(), Integer.parseInt(CMS.getAdminPort()), true); + } + + public static void updateSecurityDomain() throws IOException, SAXException, ParserConfigurationException, + EPropertyNotFound, EBaseException { + IConfigStore cs = CMS.getConfigStore(); + + int sd_agent_port = cs.getInteger("securitydomain.httpsagentport"); + int sd_admin_port = cs.getInteger("securitydomain.httpsadminport"); + String select = cs.getString("preop.subsystem.select"); + String type = cs.getString("cs.type"); + String sd_host = cs.getString("securitydomain.host"); + String subsystemName = cs.getString("preop.subsystem.name"); + + boolean cloneMaster = false; + + if (select.equals("clone") && type.equalsIgnoreCase("CA") && isSDHostDomainMaster(cs)) { + cloneMaster = true; + CMS.debug("Cloning a domain master"); + } + + String cloneStr = select.equals("clone") ? "&clone=true" : "&clone=false"; + String domainMasterStr = cloneMaster ? "&dm=true" : "&dm=false"; + String eecaStr = (CMS.getEEClientAuthSSLPort() != null) ? "&eeclientauthsport=" + CMS.getEEClientAuthSSLPort() + : ""; + + updateDomainXML(sd_host, sd_agent_port, true, + "/ca/agent/ca/updateDomainXML", + "list=" + type + "List" + + "&type=" + type + + "&host=" + CMS.getEESSLHost() + + "&name=" + subsystemName + + "&sport=" + CMS.getEESSLPort() + + domainMasterStr + + cloneStr + + "&agentsport=" + CMS.getAgentPort() + + "&adminsport=" + CMS.getAdminPort() + + eecaStr + + "&httpport=" + CMS.getEENonSSLPort()); + + // Fetch the "updated" security domain and display it + CMS.debug("updateSecurityDomain(): Dump contents of updated Security Domain . . ."); + @SuppressWarnings("unused") + String c = getDomainXML(sd_host, sd_admin_port, true); + } + + public static boolean isSDHostDomainMaster(IConfigStore config) throws EPropertyNotFound, EBaseException, + IOException, SAXException, ParserConfigurationException { + String dm = "false"; + + String hostname = config.getString("securitydomain.host"); + int httpsadminport = config.getInteger("securitydomain.httpsadminport"); + + CMS.debug("isSDHostDomainMaster(): Getting domain.xml from CA..."); + String c = getDomainXML(hostname, httpsadminport, true); + + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = new XMLObject(bis); + Document doc = parser.getDocument(); + NodeList nodeList = doc.getElementsByTagName("CA"); + + int len = nodeList.getLength(); + for (int i = 0; i < len; i++) { + Vector<String> v_hostname = parser.getValuesFromContainer(nodeList.item(i), "Host"); + Vector<String> v_https_admin_port = parser.getValuesFromContainer(nodeList.item(i), "SecureAdminPort"); + Vector<String> v_domain_mgr = parser.getValuesFromContainer(nodeList.item(i), "DomainManager"); + + if (v_hostname.elementAt(0).equals(hostname) && + v_https_admin_port.elementAt(0).equals(Integer.toString(httpsadminport))) { + dm = v_domain_mgr.elementAt(0).toString(); + break; + } + } + return dm.equalsIgnoreCase("true"); + } + + public static void updateDomainXML(String hostname, int port, boolean https, + String servlet, String uri) throws IOException, EBaseException, SAXException, ParserConfigurationException { + CMS.debug("WizardPanelBase updateDomainXML start hostname=" + hostname + " port=" + port); + IConfigStore cs = CMS.getConfigStore(); + String nickname = cs.getString("preop.cert.subsystem.nickname", ""); + String tokenname = cs.getString("preop.module.token", ""); + + if (!tokenname.equals("") && + !tokenname.equals("Internal Key Storage Token") && + !tokenname.equals("internal")) { + nickname = tokenname + ":" + nickname; + } + CMS.debug("updateDomainXML() nickname=" + nickname); + + String c = getHttpResponse(hostname, port, https, servlet, uri, nickname, null); + if (c != null) { + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject obj = new XMLObject(bis); + String status = obj.getValue("Status"); + CMS.debug("WizardPanelBase updateDomainXML: status=" + status); + + if (status.equals(SUCCESS)) { + return; + } else { + String error = obj.getValue("Error"); + throw new IOException(error); + } + } + } + + public static void updateConnectorInfo(String ownagenthost, String ownagentsport) + throws IOException, EBaseException, SAXException, ParserConfigurationException { + IConfigStore cs = CMS.getConfigStore(); + int port = -1; + String url = ""; + String host = null; + String transportCert = ""; + + url = cs.getString("preop.ca.url", ""); + if (!url.equals("")) { + host = cs.getString("preop.ca.hostname", ""); + port = cs.getInteger("preop.ca.httpsadminport", -1); + transportCert = cs.getString("kra.transport.cert", ""); + } + + if (host == null) { + CMS.debug("updateConnectorInfo(): preop.ca.url is not defined. External CA selected. No transport certificate setup is required"); + } else { + CMS.debug("updateConnectorInfo(): Transport certificate is being setup in " + url); + String session_id = CMS.getConfigSDSessionId(); + String content = "ca.connector.KRA.enable=true&ca.connector.KRA.local=false&ca.connector.KRA.timeout=30" + + "&ca.connector.KRA.uri=/kra/agent/kra/connector&ca.connector.KRA.host=" + ownagenthost + + "&ca.connector.KRA.port=" + ownagentsport + + "&ca.connector.KRA.transportCert=" + URLEncoder.encode(transportCert, "UTF-8") + + "&sessionID=" + session_id; + + updateConnectorInfo(host, port, true, content); + } + } + + public static void updateConnectorInfo(String host, int port, boolean https, + String content) throws IOException, SAXException, ParserConfigurationException { + CMS.debug("updateConnectorInfo start"); + String c = getHttpResponse(host, port, https, "/ca/admin/ca/updateConnector", content, null, null); + if (c != null) { + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = null; + parser = new XMLObject(bis); + String status = parser.getValue("Status"); + CMS.debug("updateConnectorInfo: status=" + status); + if (!status.equals(SUCCESS)) { + String error = parser.getValue("Error"); + throw new IOException(error); + } + } + } + + public static void setupClientAuthUser() throws EBaseException, CertificateException, IOException, SAXException, + ParserConfigurationException, LDAPException { + IConfigStore cs = CMS.getConfigStore(); + String host = cs.getString("preop.ca.hostname", ""); + int port = cs.getInteger("preop.ca.httpsadminport", -1); + + // retrieve CA subsystem certificate from the CA + IUGSubsystem system = + (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID)); + String id = ""; + + String b64 = getSubsystemCert(host, port, true); + if (b64 != null) { + int num = cs.getInteger("preop.subsystem.count", 0); + id = "CA-" + host + "-" + port; + num++; + cs.putInteger("preop.subsystem.count", num); + cs.putInteger("subsystem.count", num); + IUser user = system.createUser(id); + user.setFullName(id); + user.setEmail(""); + user.setPassword(""); + user.setUserType("agentType"); + user.setState("1"); + user.setPhone(""); + X509CertImpl[] certs = new X509CertImpl[1]; + certs[0] = new X509CertImpl(CMS.AtoB(b64)); + user.setX509Certificates(certs); + try { + system.addUser(user); + } catch (LDAPException e) { + if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) { + throw e; + } + } + CMS.debug("DonePanel display: successfully add the user"); + system.addUserCert(user); + CMS.debug("DonePanel display: successfully add the user certificate"); + cs.commit(false); + } + + String groupName = "Trusted Managers"; + IGroup group = system.getGroupFromName(groupName); + if (!group.isMember(id)) { + group.addMemberName(id); + system.modifyGroup(group); + CMS.debug("DonePanel display: successfully added the user to the group."); + } + + } + + public static String getSubsystemCert(String host, int port, boolean https) + throws IOException, SAXException, ParserConfigurationException { + CMS.debug("getSubsystemCert() start"); + String c = getHttpResponse(host, port, https, "/ca/admin/ca/getSubsystemCert", null, null, null); + if (c != null) { + ByteArrayInputStream bis = + new ByteArrayInputStream(c.getBytes()); + XMLObject parser = new XMLObject(bis); + String status = parser.getValue("Status"); + if (status.equals(SUCCESS)) { + String s = parser.getValue("Cert"); + return s; + } else { + return null; + } + } + return null; + } + + public static void importCACertToOCSP() throws IOException, EBaseException, CertificateEncodingException { + IConfigStore config = CMS.getConfigStore(); + + // get certificate chain from CA + String b64 = config.getString("preop.ca.pkcs7", ""); + if (b64.equals("")) { + throw new IOException("Failed to get certificate chain."); + } + + // this could be a chain + java.security.cert.X509Certificate[] certs = com.netscape.cmsutil.util.Cert.mapCertFromPKCS7(b64); + java.security.cert.X509Certificate leafCert = null; + if (certs != null && certs.length > 0) { + if (certs[0].getSubjectDN().getName().equals(certs[0].getIssuerDN().getName())) { + leafCert = certs[certs.length - 1]; + } else { + leafCert = certs[0]; + } + + IOCSPAuthority ocsp = (IOCSPAuthority) CMS.getSubsystem(IOCSPAuthority.ID); + IDefStore defStore = ocsp.getDefaultStore(); + + // (1) need to normalize (sort) the chain + // (2) store certificate (and certificate chain) into + // database + ICRLIssuingPointRecord rec = defStore.createCRLIssuingPointRecord( + leafCert.getSubjectDN().getName(), + BIG_ZERO, + MINUS_ONE, null, null); + + rec.set(ICRLIssuingPointRecord.ATTR_CA_CERT, leafCert.getEncoded()); + defStore.addCRLIssuingPoint(leafCert.getSubjectDN().getName(), rec); + + CMS.debug("importCACertToOCSP(): Added CA certificate."); + } + } + + public static void updateOCSPConfig() + throws IOException, EBaseException, SAXException, ParserConfigurationException { + IConfigStore config = CMS.getConfigStore(); + String cahost = config.getString("preop.ca.hostname", ""); + int caport = config.getInteger("preop.ca.httpsport", -1); + String ocsphost = CMS.getAgentHost(); + int ocspport = Integer.parseInt(CMS.getAgentPort()); + String session_id = CMS.getConfigSDSessionId(); + String content = "xmlOutput=true&sessionID=" + session_id + "&ocsp_host=" + ocsphost + "&ocsp_port=" + ocspport; + + String c = getHttpResponse(cahost, caport, true, "/ca/ee/ca/updateOCSPConfig", content, null, null); + if (c == null || c.equals("")) { + CMS.debug("WizardPanelBase updateOCSPConfig: content is null."); + throw new IOException("The server you want to contact is not available"); + } else { + ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes()); + XMLObject parser = new XMLObject(bis); + + String status = parser.getValue("Status"); + CMS.debug("WizardPanelBase updateOCSPConfig: status=" + status); + + if (status.equals(SUCCESS)) { + CMS.debug("WizardPanelBase updateOCSPConfig: Successfully update the OCSP configuration in the CA."); + } else if (status.equals(AUTH_FAILURE)) { + throw new EAuthException(AUTH_FAILURE); + } else { + String error = parser.getValue("Error"); + throw new IOException(error); + } + } + } + + public static void setupDBUser(String dbuser) throws CertificateException, LDAPException, EBaseException, + NotInitializedException, ObjectNotFoundException, TokenException, IOException { + IUGSubsystem system = + (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID)); + + String b64 = getSubsystemCert(); + if (b64 == null) { + CMS.debug("setupDBUser(): failed to fetch subsystem cert"); + return; + } + + IUser user = system.createUser(dbuser); + user.setFullName(dbuser); + user.setEmail(""); + user.setPassword(""); + user.setUserType("agentType"); + user.setState("1"); + user.setPhone(""); + X509CertImpl[] certs = new X509CertImpl[1]; + certs[0] = new X509CertImpl(CMS.AtoB(b64)); + user.setX509Certificates(certs); + system.addUser(user); + CMS.debug("setupDBUser(): successfully added the user"); + system.addUserCert(user); + CMS.debug("setupDBUser(): successfully add the user certificate"); + } + + public static String getSubsystemCert() throws EBaseException, NotInitializedException, ObjectNotFoundException, + TokenException, CertificateEncodingException, IOException { + IConfigStore cs = CMS.getConfigStore(); + String nickname = cs.getString("preop.cert.subsystem.nickname", ""); + String tokenname = cs.getString("preop.module.token", ""); + + if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token") + && !tokenname.equals("")) { + nickname = tokenname + ":" + nickname; + } + + CMS.debug("DonePanel getSubsystemCert: nickname=" + nickname); + + CryptoManager cm = CryptoManager.getInstance(); + org.mozilla.jss.crypto.X509Certificate cert = cm.findCertByNickname(nickname); + if (cert == null) { + CMS.debug("DonePanel getSubsystemCert: subsystem cert is null"); + return null; + } + byte[] bytes = cert.getEncoded(); + String s = CryptoUtil.normalizeCertStr(CryptoUtil.base64Encode(bytes)); + return s; + } + + public static void updateNextRanges() throws EBaseException, LDAPException { + IConfigStore cs = CMS.getConfigStore(); + + String endRequestNumStr = cs.getString("dbs.endRequestNumber", ""); + String endSerialNumStr = cs.getString("dbs.endSerialNumber", ""); + String type = cs.getString("cs.type"); + String basedn = cs.getString("internaldb.basedn"); + + BigInteger endRequestNum = new BigInteger(endRequestNumStr); + BigInteger endSerialNum = new BigInteger(endSerialNumStr); + BigInteger oneNum = new BigInteger("1"); + + // update global next range entries + IConfigStore dbCfg = cs.getSubStore("internaldb"); + ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory(); + dbFactory.init(dbCfg); + LDAPConnection conn = dbFactory.getConn(); + + String serialdn = ""; + if (type.equals("CA")) { + serialdn = "ou=certificateRepository,ou=" + type.toLowerCase() + "," + basedn; + } else { + serialdn = "ou=keyRepository,ou=" + type.toLowerCase() + "," + basedn; + } + LDAPAttribute attrSerialNextRange = + new LDAPAttribute("nextRange", endSerialNum.add(oneNum).toString()); + LDAPModification serialmod = new LDAPModification(LDAPModification.REPLACE, attrSerialNextRange); + conn.modify(serialdn, serialmod); + + String requestdn = "ou=" + type.toLowerCase() + ",ou=requests," + basedn; + LDAPAttribute attrRequestNextRange = + new LDAPAttribute("nextRange", endRequestNum.add(oneNum).toString()); + LDAPModification requestmod = new LDAPModification(LDAPModification.REPLACE, attrRequestNextRange); + conn.modify(requestdn, requestmod); + + conn.disconnect(); + } + + /** + * save variables needed for cloning and remove preops + * @throws EBaseException + */ + public static void removePreopConfigEntries() throws EBaseException { + IConfigStore cs = CMS.getConfigStore(); + String type = cs.getString("cs.type"); + String list = cs.getString("preop.cert.list", ""); + StringTokenizer st = new StringTokenizer(list, ","); + + while (st.hasMoreTokens()) { + String ss = st.nextToken(); + if (ss.equals("sslserver")) + continue; + cs.putString("cloning." + ss + ".nickname", cs.getString("preop.cert." + ss + ".nickname", "")); + cs.putString("cloning." + ss + ".dn", cs.getString("preop.cert." + ss + ".dn", "")); + cs.putString("cloning." + ss + ".keytype", cs.getString("preop.cert." + ss + ".keytype", "")); + cs.putString("cloning." + ss + ".keyalgorithm", cs.getString("preop.cert." + ss + ".keyalgorithm", "")); + cs.putString("cloning." + ss + ".privkey.id", cs.getString("preop.cert." + ss + ".privkey.id", "")); + cs.putString("cloning." + ss + ".pubkey.exponent", + cs.getString("preop.cert." + ss + ".pubkey.exponent", "")); + cs.putString("cloning." + ss + ".pubkey.modulus", + cs.getString("preop.cert." + ss + ".pubkey.modulus", "")); + cs.putString("cloning." + ss + ".pubkey.encoded", + cs.getString("preop.cert." + ss + ".pubkey.encoded", "")); + } + cs.putString("cloning.module.token", cs.getString("preop.module.token", "")); + cs.putString("cloning.list", list); + + // more cloning variables needed for non-ca clones + + if (!type.equals("CA")) { + String val = cs.getString("preop.ca.hostname", ""); + if (val.length() > 0) + cs.putString("cloning.ca.hostname", val); + + val = cs.getString("preop.ca.httpport", ""); + if (val.length() != 0) + cs.putString("cloning.ca.httpport", val); + + val = cs.getString("preop.ca.httpsport", ""); + if (val.length() != 0) + cs.putString("cloning.ca.httpsport", val); + + val = cs.getString("preop.ca.list", ""); + if (val.length() != 0) + cs.putString("cloning.ca.list", val); + + val = cs.getString("preop.ca.pkcs7", ""); + if (val.length() != 0) + cs.putString("cloning.ca.pkcs7", val); + + val = cs.getString("preop.ca.type", ""); + if (val.length() != 0) + cs.putString("cloning.ca.type", val); + } + + // save EC type for sslserver cert (if present) + cs.putString("jss.ssl.sslserver.ectype", cs.getString("preop.cert.sslserver.ec.type", "ECDHE")); + + cs.removeSubStore("preop"); + cs.commit(false); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java new file mode 100644 index 000000000..ff582561c --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResource.java @@ -0,0 +1,66 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; + +import com.netscape.cms.servlet.csadmin.model.ConfigurationData; +import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData; +import com.netscape.cms.servlet.csadmin.model.DomainInfo; +import com.netscape.cms.servlet.csadmin.model.InstallToken; +import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest; + +/** + * @author alee + * + */ +@Path("/installer") +public interface SystemConfigurationResource { + + @POST + @Path("configure") + @Produces({ MediaType.TEXT_XML }) + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED}) + public ConfigurationResponseData configure(MultivaluedMap<String, String> form); + + @POST + @Path("configure") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public ConfigurationResponseData configure(ConfigurationData data); + + @POST + @Path("installToken") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public InstallToken getInstallToken(InstallTokenRequest data); + + @GET + @Path("domainInfo") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public DomainInfo getDomainInfo(); + + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java new file mode 100644 index 000000000..b2bb39fa9 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigurationResourceService.java @@ -0,0 +1,944 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.UnknownHostException; +import java.security.NoSuchAlgorithmException; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Random; +import java.util.StringTokenizer; +import java.util.Vector; + +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import netscape.security.x509.X509CertImpl; + +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.CryptoManager.NotInitializedException; +import org.mozilla.jss.NoSuchTokenException; +import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.TokenException; +import org.mozilla.jss.util.IncorrectPasswordException; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.EPropertyNotFound; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.base.ISecurityDomainSessionTable; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.dbs.certdb.ICertificateRepository; +import com.netscape.certsrv.ocsp.IOCSPAuthority; +import com.netscape.certsrv.usrgrp.IUGSubsystem; +import com.netscape.certsrv.usrgrp.IUser; +import com.netscape.cms.servlet.base.CMSException; +import com.netscape.cms.servlet.base.CMSResourceService; +import com.netscape.cms.servlet.csadmin.model.CertData; +import com.netscape.cms.servlet.csadmin.model.ConfigurationData; +import com.netscape.cms.servlet.csadmin.model.ConfigurationResponseData; +import com.netscape.cms.servlet.csadmin.model.DomainInfo; +import com.netscape.cms.servlet.csadmin.model.InstallToken; +import com.netscape.cms.servlet.csadmin.model.InstallTokenRequest; +import com.netscape.cmsutil.crypto.CryptoUtil; +import com.netscape.cmsutil.util.Utils; + +/** + * @author alee + * + */ +public class SystemConfigurationResourceService extends CMSResourceService implements SystemConfigurationResource { + IConfigStore cs; + String csType; + String csState; + boolean isMasterCA = false; + String instanceRoot; + + public static String SUCCESS = "0"; + public static final String RESTART_SERVER_AFTER_CONFIGURATION = + "restart_server_after_configuration"; + private Random random = null; + + public SystemConfigurationResourceService() throws EPropertyNotFound, EBaseException { + cs = CMS.getConfigStore(); + csType = cs.getString("cs.type"); + csState = cs.getString("cs.state"); + String domainType = cs.getString("securitydomain.select", "existingdomain"); + if (csType.equals("CA") && domainType.equals("new")) { + isMasterCA = true; + } + instanceRoot = cs.getString("instanceRoot"); + random = new Random(); + } + + /* (non-Javadoc) + * @see com.netscape.cms.servlet.csadmin.SystemConfigurationResource#configure(javax.ws.rs.core.MultivaluedMap) + */ + @Override + public ConfigurationResponseData configure(MultivaluedMap<String, String> form) { + ConfigurationData data = new ConfigurationData(form); + return configure(data); + } + + /* (non-Javadoc) + * @see com.netscape.cms.servlet.csadmin.SystemConfigurationResource#configure(com.netscape.cms.servlet.csadmin.data.ConfigurationData) + */ + @Override + public ConfigurationResponseData configure(ConfigurationData data){ + if (csState.equals("1")) { + throw new CMSException(Response.Status.BAD_REQUEST, "System is already configured"); + } + + String certList; + try { + certList = cs.getString("preop.cert.list"); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Unable to get certList from config file"); + } + + validateData(data); + ConfigurationResponseData response = new ConfigurationResponseData(); + + // specify module and log into token + String token = data.getToken(); + if (token == null) { + token = ConfigurationData.TOKEN_DEFAULT; + } + cs.putString("preop.module.token", token); + + if (! token.equals(ConfigurationData.TOKEN_DEFAULT)) { + try { + CryptoManager cryptoManager = CryptoManager.getInstance(); + CryptoToken ctoken = cryptoManager.getTokenByName(token); + String tokenpwd = data.getTokenPassword(); + ConfigurationUtils.loginToken(ctoken, tokenpwd); + } catch (NotInitializedException e) { + throw new CMSException("Token is not initialized"); + } catch (NoSuchTokenException e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid Token provided. No such token."); + } catch (TokenException e) { + e.printStackTrace(); + throw new CMSException("Token Exception" + e); + } catch (IncorrectPasswordException e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Incorrect Password provided for token."); + } + } + + //configure security domain + String securityDomainType = data.getSecurityDomainType(); + String securityDomainName = data.getSecurityDomainName(); + String securityDomainURL = data.getSecurityDomainUri(); + String domainXML = null; + if (securityDomainType.equals(ConfigurationData.NEW_DOMAIN)) { + cs.putString("preop.securitydomain.select", "new"); + cs.putString("securitydomain.select", "new"); + cs.putString("preop.securitydomain.name", securityDomainName); + cs.putString("securitydomain.name", securityDomainName); + cs.putString("securitydomain.host", CMS.getEENonSSLHost()); + cs.putString("securitydomain.httpport", CMS.getEENonSSLPort()); + cs.putString("securitydomain.httpsagentport", CMS.getAgentPort()); + cs.putString("securitydomain.httpseeport", CMS.getEESSLPort()); + cs.putString("securitydomain.httpsadminport", CMS.getAdminPort()); + cs.putString("preop.cert.subsystem.type", "local"); + cs.putString("preop.cert.subsystem.profile", "subsystemCert.profile"); + } else { + cs.putString("preop.securitydomain.select", "existing"); + cs.putString("securitydomain.select", "existing"); + cs.putString("preop.cert.subsystem.type", "remote"); + cs.putString("preop.cert.subsystem.profile", "caInternalAuthSubsystemCert"); + + // contact and log onto security domain + URL secdomainURL; + String host; + int port; + try { + secdomainURL = new URL(securityDomainURL); + host = secdomainURL.getHost(); + port = secdomainURL.getPort(); + cs.putString("securitydomain.host", host); + cs.putInteger("securitydomain.httpsadminport",port); + ConfigurationUtils.importCertChain(host, port, "/ca/admin/ca/getCertChain", "securitydomain"); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Failed to import certificate chain from security domain master: " + e); + } + + // log onto security domain and get token + String user = data.getSecurityDomainUser(); + String pass = data.getSecurityDomainPassword(); + String installToken; + try { + installToken = ConfigurationUtils.getInstallToken(host, port, user, pass); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Failed to obtain installation token from security domain: " + e); + } + + if (installToken == null) { + throw new CMSException("Failed to obtain installation token from security domain"); + } + CMS.setConfigSDSessionId(installToken); + + try { + domainXML = ConfigurationUtils.getDomainXML(host, port, true); + ConfigurationUtils.getSecurityDomainPorts(domainXML, host, port); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Failed to obtain security domain decriptor from security domain master: " + e); + } + } + + cs.putString("preop.subsystem.name", data.getSubsystemName()); + + // is this a clone of another subsystem? + if (data.getIsClone().equals("false")) { + cs.putString("preop.subsystem.select", "new"); + cs.putString("subsystem.select", "New"); + } else { + cs.putString("preop.subsystem.select", "clone"); + cs.putString("subsystem.select", "Clone"); + + StringTokenizer t = new StringTokenizer(certList, ","); + while (t.hasMoreTokens()) { + String tag = t.nextToken(); + if (tag.equals("sslserver")) { + cs.putBoolean("preop.cert." + tag + ".enable", true); + } else { + cs.putBoolean("preop.cert." + tag + ".enable", false); + } + } + + String cloneUri = data.getCloneUri(); + URL url = null; + try { + url = new URL(cloneUri); + } catch (MalformedURLException e) { + // should not reach here as this check is done in validate() + } + String masterHost = url.getHost(); + int masterPort = url.getPort(); + + // check and store cloneURI information + boolean validCloneUri; + try { + validCloneUri = ConfigurationUtils.isValidCloneURI(domainXML, masterHost, masterPort); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Error in determining whether clone URI is valid"); + } + + if (!validCloneUri) { + throw new CMSException(Response.Status.BAD_REQUEST, + "Invalid clone URI provided. Does not match the available subsystems in the security domain"); + } + + if (csType.equals("CA")) { + try { + ConfigurationUtils.importCertChain(masterHost, masterPort, "/ca/ee/ca/getCertChain", "clone"); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Failed to import certificate chain from master" + e); + } + } + + try { + ConfigurationUtils.getConfigEntriesFromMaster(); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Failed to obtain configuration entries from the master for cloning " + e); + } + + // restore certs from P12 file + if (token.equals(ConfigurationData.TOKEN_DEFAULT)) { + String p12File = data.getP12File(); + String p12Pass = data.getP12Password(); + try { + ConfigurationUtils.restoreCertsFromP12(p12File, p12Pass); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Failed to restore certificates from p12 file" + e); + } + } + + boolean cloneReady = ConfigurationUtils.isCertdbCloned(); + if (!cloneReady) { + CMS.debug("clone does not have all the certificates."); + throw new CMSException("Clone does not have all the required certificates"); + } + } + + // Hierarchy Panel + if (csType.equals("CA") && data.getIsClone().equals("false")) { + if (data.getHierarchy().equals("root")) { + cs.putString("preop.hierarchy.select", "root"); + cs.putString("hierarchy.select", "Root"); + cs.putString("preop.ca.type", "sdca"); + } else if (data.getHierarchy().equals("join")) { + cs.putString("preop.cert.signing.type", "remote"); + cs.putString("preop.hierarchy.select", "join"); + cs.putString("hierarchy.select", "Subordinate"); + } else { + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid hierarchy provided"); + } + } + + // Database Panel + cs.putString("internaldb.ldapconn.host", data.getDsHost()); + cs.putString("internaldb.ldapconn.port", data.getDsPort()); + cs.putString("internaldb.database", data.getDatabase()); + cs.putString("internaldb.basedn", data.getBaseDN()); + cs.putString("internaldb.ldapauth.bindDN", data.getBindDN()); + cs.putString("internaldb.ldapconn.secureConn", (data.getSecureConn().equals("on") ? "true" : "false")); + cs.putString("preop.database.removeData", data.getRemoveData()); + + try { + cs.commit(false); + } catch (EBaseException e2) { + e2.printStackTrace(); + throw new CMSException("Unable to commit config parameters to file"); + } + + if (data.getIsClone().equals("true")) { + String masterhost = ""; + String masterport = ""; + String masterbasedn = ""; + String realhostname = ""; + try { + masterhost = cs.getString("preop.internaldb.master.ldapconn.host", ""); + masterport = cs.getString("preop.internaldb.master.ldapconn.port", ""); + masterbasedn = cs.getString("preop.internaldb.master.basedn", ""); + realhostname = cs.getString("machineName", ""); + } catch (Exception e) { + } + + if (masterhost.equals(realhostname) && masterport.equals(data.getDsPort())) { + throw new CMSException(Response.Status.BAD_REQUEST, + "Master and clone must not share the same internal database"); + } + + if (!masterbasedn.equals(data.getBaseDN())) { + throw new CMSException(Response.Status.BAD_REQUEST, "Master and clone should have the same base DN"); + } + + String masterReplicationPort = data.getMasterReplicationPort(); + if ((masterReplicationPort != null) && (!masterReplicationPort.equals(""))) { + cs.putString("internaldb.ldapconn.masterReplicationPort", masterReplicationPort); + } else { + cs.putString("internaldb.ldapconn.masterReplicationPort", masterport); + } + + String cloneReplicationPort = data.getCloneReplicationPort(); + if ((cloneReplicationPort == null) || (cloneReplicationPort.length() == 0)) { + cloneReplicationPort = data.getDsPort(); + } + cs.putString("internaldb.ldapconn.cloneReplicationPort", cloneReplicationPort); + + String replicationSecurity = data.getReplicationSecurity(); + if ((cloneReplicationPort == data.getDsPort()) && (data.getSecureConn().equals("on"))) { + replicationSecurity = "SSL"; + } else if (replicationSecurity == null) { + replicationSecurity = "None"; + } + cs.putString("internaldb.ldapconn.replicationSecurity", replicationSecurity); + } + + try { + /* BZ 430745 create password for replication manager */ + String replicationpwd = Integer.toString(new Random().nextInt()); + + IConfigStore psStore = null; + String passwordFile = null; + passwordFile = cs.getString("passwordFile"); + psStore = CMS.createFileConfigStore(passwordFile); + psStore.putString("internaldb", data.getBindpwd()); + psStore.putString("replicationdb", replicationpwd); + psStore.commit(false); + + ConfigurationUtils.populateDB(); + + cs.putString("preop.internaldb.replicationpwd", replicationpwd); + cs.putString("preop.database.removeData", "false"); + cs.commit(false); + + ConfigurationUtils.reInitSubsystem(csType); + ConfigurationUtils.populateIndexes(); + + if (data.getIsClone().equals("true")) { + CMS.debug("Start setting up replication."); + ConfigurationUtils.setupReplication(); + ConfigurationUtils.reInitSubsystem(csType); + } + } catch (Exception e) { + throw new CMSException("Error in populating database" + e); + } + + // SizePanel, NamePanel, CertRequestPanel + //handle the CA URL + try { + if ((data.getHierarchy() == null) || (data.getHierarchy().equals("join"))) { + String url = data.getIssuingCA(); + if (url.equals("External CA")) { + CMS.debug("external CA selected"); + cs.putString("preop.ca.type", "otherca"); + cs.putString("preop.ca.pkcs7", ""); + cs.putInteger("preop.ca.certchain.size", 0); + if (csType.equals("CA")) { + cs.putString("preop.cert.signing.type", "remote"); + } + } else { + CMS.debug("local CA selected"); + url = url.substring(url.indexOf("https")); + cs.putString("preop.ca.url", url); + + URL urlx = new URL(url); + String host = urlx.getHost(); + int port = urlx.getPort(); + int admin_port = ConfigurationUtils.getPortFromSecurityDomain(domainXML, + host, port, "CA", "SecurePort", "SecureAdminPort"); + + cs.putString("preop.ca.type", "sdca"); + cs.putString("preop.ca.hostname", host); + cs.putInteger("preop.ca.httpsport", port); + cs.putInteger("preop.ca.httpsadminport", admin_port); + + if (!data.getIsClone().equals("true")) { + ConfigurationUtils.importCertChain(host, admin_port, "/ca/admin/ca/getCertChain", "ca"); + } + + if (csType.equals("CA")) { + cs.putString("preop.cert.signing.type", "remote"); + cs.putString("preop.cert.signing.profile","caInstallCACert"); + } + } + } + } catch (Exception e) { + throw new CMSException("Error in obtaining certificate chain from issuing CA: " + e); + } + + boolean hasSigningCert = false; + Vector<Cert> certs = new Vector<Cert>(); + try { + StringTokenizer t = new StringTokenizer(certList, ","); + while (t.hasMoreTokens()) { + String ct = t.nextToken(); + boolean enable = cs.getBoolean("preop.cert." + ct + ".enable", true); + if (!enable) continue; + + Collection<CertData> certData = data.getSystemCerts(); + Iterator<CertData> iterator = certData.iterator(); + CertData cdata = null; + while (iterator.hasNext()) { + cdata = iterator.next(); + if (cdata.getTag().equals(ct)) break; + } + + String keytype = (cdata.getKeyType() != null) ? cdata.getKeyType() : "rsa"; + + String keyalgorithm = cdata.getKeyAlgorithm(); + if (keyalgorithm == null) { + keyalgorithm = (keytype.equals("ecc")) ? "SHA256withEC" : "SHA256withRSA"; + } + + String signingalgorithm = (cdata.getSigningAlgorithm() != null)? cdata.getSigningAlgorithm(): keyalgorithm ; + String nickname = (cdata.getNickname() != null) ? cdata.getNickname() : + cs.getString("preop.cert." + ct + ".nickname"); + String dn = (cdata.getSubjectDN() != null)? cdata.getSubjectDN() : + cs.getString("preop.cert." + ct + ".dn"); + + + cs.putString("preop.cert." + ct + ".keytype", keytype); + cs.putString("preop.cert." + ct + ".keyalgorithm", keyalgorithm); + cs.putString("preop.cert." + ct + ".signingalgorithm", signingalgorithm); + cs.putString("preop.cert." + ct + ".nickname", nickname); + cs.putString("preop.cert." + ct + ".dn", dn); + + if (data.getStepTwo() == null) { + if (keytype.equals("ecc")) { + String curvename = (cdata.getKeyCurveName() != null) ? + cdata.getKeyCurveName() : cs.getString("keys.ecc.curve.default"); + cs.putString("preop.cert." + ct + ".curvename.name", curvename); + ConfigurationUtils.createECCKeyPair(token, curvename, cs, ct); + } else { + String keysize = cdata.getKeySize() != null ? cdata.getKeySize() : cs + .getString("keys.rsa.keysize.default"); + cs.putString("preop.cert." + ct + ".keysize.size", keysize); + ConfigurationUtils.createRSAKeyPair(token, Integer.parseInt(keysize), cs, ct); + } + } else { + CMS.debug("configure(): step two selected. keys will not be generated"); + } + + String tokenName = cdata.getToken() != null ? cdata.getToken() : token; + Cert certObj = new Cert(tokenName, nickname, ct); + certObj.setDN(dn); + certObj.setSubsystem(cs.getString("preop.cert." + ct + ".subsystem")); + certObj.setType(cs.getString("preop.cert." + ct + ".type")); + + if (data.getStepTwo() == null) { + ConfigurationUtils.configCert(null, null, null, certObj, null); + } else { + String subsystem = cs.getString("preop.cert." + ct + ".subsystem"); + String certStr = cs.getString(subsystem + "." + ct + ".cert" ); + certObj.setCert(certStr); + CMS.debug("Step 2: certStr for " + ct + " is " + certStr); + } + ConfigurationUtils.handleCertRequest(cs, ct, certObj); + + if (data.getIsClone().equals("true")) { + ConfigurationUtils.updateCloneConfig(); + } + + // to determine if we have the signing cert when using an external ca + // this will only execute on a ca + String b64 = cdata.getCert(); + if (ct.equals("signing") && (b64!= null) && (b64.length()>0) && (!b64.startsWith("..."))) { + hasSigningCert = true; + if (data.getIssuingCA().equals("External CA")) { + b64 = CryptoUtil.stripCertBrackets(b64.trim()); + certObj.setCert(CryptoUtil.normalizeCertStr(b64)); + + if (cdata.getCertChain() != null) { + certObj.setCertChain(cdata.getCertChain()); + } else { + throw new CMSException(Response.Status.BAD_REQUEST, "CertChain not provided"); + } + } + } + + certs.addElement(certObj); + } + // make sure to commit changes here for step 1 + cs.commit(false); + + } catch (NumberFormatException e) { + // move these validations to validate()? + throw new CMSException(Response.Status.BAD_REQUEST, "Non-integer value for key size"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid algorithm " + e); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Error in setting certificate names and key sizes: " + e); + } + + // submitting to external ca + if ((data.getIssuingCA()!= null) && data.getIssuingCA().equals("External CA") && (!hasSigningCert)) { + response.setSystemCerts(certs); + return response; + } + + Enumeration<Cert> c = certs.elements(); + while (c.hasMoreElements()) { + Cert cert = c.nextElement(); + int ret; + try { + ret = ConfigurationUtils.handleCerts(cert); + ConfigurationUtils.setCertPermissions(cert.getCertTag()); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Error in confguring system certificates" + e); + } + if (ret != 0) { + throw new CMSException("Error in confguring system certificates"); + } + } + response.setSystemCerts(certs); + + // BackupKeyCertPanel/SavePKCS12Panel + if (data.getBackupKeys().equals("true")) { + try { + ConfigurationUtils.backupKeys(data.getBackupPassword(), data.getBackupFile()); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Error in creating pkcs12 to backup keys and certs: " + e); + } + } + + // AdminPanel + if (!data.getIsClone().equals("true")) { + try { + X509CertImpl admincerts[] = new X509CertImpl[1]; + ConfigurationUtils.createAdmin(data.getAdminUID(), data.getAdminEmail(), + data.getAdminName(), data.getAdminPassword()); + if (csType.equals("CA")) { + ConfigurationUtils.createAdminCertificate(data.getAdminCertRequest(), + data.getAdminCertRequestType(), data.getAdminSubjectDN()); + + String serialno = cs.getString("preop.admincert.serialno.0"); + ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(ICertificateAuthority.ID); + ICertificateRepository repo = ca.getCertificateRepository(); + admincerts[0] = repo.getX509Certificate(new BigInteger(serialno, 16)); + } else { + String type = cs.getString("preop.ca.type", ""); + String ca_hostname = ""; + int ca_port = -1; + if (type.equals("sdca")) { + ca_hostname = cs.getString("preop.ca.hostname"); + ca_port = cs.getInteger("preop.ca.httpsport"); + } else { + ca_hostname = cs.getString("securitydomain.host", ""); + ca_port = cs.getInteger("securitydomain.httpseeport"); + } + String b64 = ConfigurationUtils.submitAdminCertRequest(ca_hostname, ca_port, + data.getAdminProfileID(), data.getAdminCertRequestType(), + data.getAdminCertRequest(), data.getAdminSubjectDN()); + b64 = CryptoUtil.stripCertBrackets(b64.trim()); + byte[] b = CryptoUtil.base64Decode(b64); + admincerts[0] = new X509CertImpl(b); + } + CMS.reinit(IUGSubsystem.ID); + + IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(IUGSubsystem.ID); + IUser user = ug.getUser(data.getAdminUID()); + user.setX509Certificates(admincerts); + ug.addUserCert(user); + response.setAdminCert(admincerts[0]); + + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Error in creating admin user: " + e); + } + } + + // Done Panel + // Create or update security domain + try { + if (securityDomainType.equals(ConfigurationData.NEW_DOMAIN)) { + ConfigurationUtils.createSecurityDomain(); + } else { + ConfigurationUtils.updateSecurityDomain(); + } + cs.putString("service.securityDomainPort", CMS.getAgentPort()); + cs.putString("securitydomain.store", "ldap"); + cs.commit(false); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Error while updating security domain: " + e); + } + + // need to push connector information to the CA + String ca_host=""; + try { + ca_host = cs.getString("preop.ca.hostname", ""); + } catch (EBaseException e) { + e.printStackTrace(); + } + + // need to push connector information to the CA + try { + if (csType.equals("KRA") && (!ca_host.equals(""))) { + ConfigurationUtils.updateConnectorInfo(CMS.getAgentHost(), CMS.getAgentPort()); + ConfigurationUtils.setupClientAuthUser(); + } + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Errors in pushing KRA connector information to the CA: " + e); + } + + // import the CA certificate into the OCSP + // configure the CRL Publishing to OCSP in CA + try { + if (csType.equals("OCSP") && (!ca_host.equals(""))) { + CMS.reinit(IOCSPAuthority.ID); + ConfigurationUtils.importCACertToOCSP(); + ConfigurationUtils.updateOCSPConfig(); + ConfigurationUtils.setupClientAuthUser(); + } + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Errors in configuring CA publishing to OCSP: " + e); + } + + if (!data.getIsClone().equals("true")) { + try { + if (csType.equals("CA") || csType.equals("KRA")) { + ConfigurationUtils.updateNextRanges(); + } + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Errors in updating nxt serial number ranges in DB: " + e); + } + } + + try { + if (data.getIsClone().equals("true") && csType.equalsIgnoreCase("CA") + && ConfigurationUtils.isSDHostDomainMaster(cs)) { + // cloning a domain master CA, the clone is also master of its domain + cs.putString("securitydomain.host", CMS.getEEHost()); + cs.putString("securitydomain.httpport", CMS.getEENonSSLPort()); + cs.putString("securitydomain.httpsadminport", CMS.getAdminPort()); + cs.putString("securitydomain.httpsagentport", CMS.getAgentPort()); + cs.putString("securitydomain.httpseeport", CMS.getEESSLPort()); + cs.putString("securitydomain.select", "new"); + + } + } catch (Exception e1) { + e1.printStackTrace(); + throw new CMSException("Errors in determining if security domain host is a master CA"); + } + + try { + String dbuser = csType + "-" + CMS.getEEHost() + "-" + CMS.getEESSLPort(); + if (! securityDomainType.equals(ConfigurationData.NEW_DOMAIN)) { + ConfigurationUtils.setupDBUser(dbuser); + } + IUGSubsystem system = (IUGSubsystem) (CMS.getSubsystem(IUGSubsystem.ID)); + IUser user = system.getUser(dbuser); + system.addCertSubjectDN(user); + } catch (Exception e) { + e.printStackTrace(); + throw new CMSException("Errors in creating or updating dbuser: " + e); + } + + cs.putInteger("cs.state", 1); + + // update serial numbers for clones + + // save some variables, remove remaining preops + try { + ConfigurationUtils.removePreopConfigEntries(); + } catch (EBaseException e) { + e.printStackTrace(); + throw new CMSException("Errors when removing preop config entries: " + e); + } + + // Create an empty file that designates the fact that although + // this server instance has been configured, it has NOT yet + // been restarted! + String restart_server = instanceRoot + "/conf/" + RESTART_SERVER_AFTER_CONFIGURATION; + Utils.exec("touch " + restart_server); + Utils.exec("chmod 00660 " + restart_server); + + response.setStatus(SUCCESS); + return response; + } + + private void validateData(ConfigurationData data) { + // get required info from CS.cfg + String preopPin; + try { + preopPin = cs.getString("preop.pin"); + } catch (Exception e) { + CMS.debug("validateData: Failed to get required config form CS.cfg"); + e.printStackTrace(); + throw new CMSException("Unable to retrieve required configuration from configuration files"); + } + + // get the preop pin and validate it + String pin = data.getPin(); + if (pin == null) { + throw new CMSException(Response.Status.BAD_REQUEST, "No preop pin provided"); + } + if (!preopPin.equals(pin)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Incorrect pin provided"); + } + + // validate security domain settings + String domainType = data.getSecurityDomainType(); + if (domainType == null) { + throw new CMSException(Response.Status.BAD_REQUEST, "Security Domain Type not provided"); + } + + if (domainType.equals(ConfigurationData.NEW_DOMAIN)) { + if (!csType.equals("CA")) { + throw new CMSException(Response.Status.BAD_REQUEST, "New Domain is only valid for CA subsytems"); + } + if (data.getSecurityDomainName() == null) { + throw new CMSException(Response.Status.BAD_REQUEST, "Security Domain Name is not provided"); + } + } else if (domainType.equals(ConfigurationData.EXISTING_DOMAIN)) { + String domainURI = data.getSecurityDomainUri(); + if (domainURI == null) { + throw new CMSException(Response.Status.BAD_REQUEST, + "Existing security domain requested, but no security domain URI provided"); + } + + try { + @SuppressWarnings("unused") + URL admin_u = new URL(domainURI); // check for invalid URL + } catch (MalformedURLException e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid security domain URI"); + } + if ((data.getSecurityDomainUser() == null) || (data.getSecurityDomainPassword() == null)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Security domain user or password not provided"); + } + + } else { + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid security domain URI provided"); + } + + if ((data.getSubsystemName() == null) || (data.getSubsystemName().length() ==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid or no subsystem name provided"); + } + + if (data.getIsClone().equals("true")) { + String cloneUri = data.getCloneUri(); + if (cloneUri == null) { + throw new CMSException(Response.Status.BAD_REQUEST, "Clone selected, but no clone URI provided"); + } + try { + @SuppressWarnings("unused") + URL url = new URL(cloneUri); // check for invalid URL + // confirm protocol is https + } catch (MalformedURLException e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid clone URI"); + } + + if (data.getToken().equals(ConfigurationData.TOKEN_DEFAULT)) { + if (data.getP12File() == null) { + throw new CMSException(Response.Status.BAD_REQUEST, "P12 filename not provided"); + } + + if (data.getP12Password() == null) { + throw new CMSException(Response.Status.BAD_REQUEST, "P12 password not provided"); + } + } + } + + String dsHost = data.getDsHost(); + if (dsHost == null || dsHost.length() == 0) { + throw new CMSException(Response.Status.BAD_REQUEST, "Internal database host not provided"); + } + + try { + Integer.parseInt(data.getDsPort()); // check for errors + } catch (NumberFormatException e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Internal database port is invalid"); + } + + String basedn = data.getBaseDN(); + if (basedn == null || basedn.length() == 0) { + throw new CMSException(Response.Status.BAD_REQUEST, "Internal database basedn not provided"); + } + + String binddn = data.getBindDN(); + if (binddn == null || binddn.length() == 0) { + throw new CMSException(Response.Status.BAD_REQUEST, "Internal database basedn not provided"); + } + + String database = data.getDatabase(); + if (database == null || database.length() == 0) { + throw new CMSException(Response.Status.BAD_REQUEST, "Internal database database name not provided"); + } + + String bindpwd = data.getBindpwd(); + if (bindpwd == null || bindpwd.length() == 0) { + throw new CMSException(Response.Status.BAD_REQUEST, "Internal database database name not provided"); + } + + String masterReplicationPort = data.getMasterReplicationPort(); + if (masterReplicationPort != null && masterReplicationPort.length() > 0) { + try { + Integer.parseInt(masterReplicationPort); // check for errors + } catch (NumberFormatException e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Master replication port is invalid"); + } + } + + String cloneReplicationPort = data.getCloneReplicationPort(); + if (cloneReplicationPort != null && cloneReplicationPort.length() > 0) { + try { + Integer.parseInt(cloneReplicationPort); // check for errors + } catch (Exception e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Clone replication port is invalid"); + } + } + + if ((data.getBackupKeys() != null) && data.getBackupKeys().equals("true")) { + if ((data.getBackupFile() == null) || (data.getBackupFile().length()<=0)) { + //TODO: also check for valid path, perhaps by touching file there + throw new CMSException(Response.Status.BAD_REQUEST, "Invalid key backup file name"); + } + + if ((data.getBackupPassword() == null) || (data.getBackupPassword().length()<=8)) { + throw new CMSException(Response.Status.BAD_REQUEST, "key backup password must be at least 8 characters"); + } + } + + if (csType.equals("CA") && (data.getHierarchy() == null)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Hierarchy is requred for CA, not provided"); + } + + if (data.getIsClone().equals("false")) { + if ((data.getAdminUID() == null) || (data.getAdminUID().length()==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Admin UID not provided"); + } + if ((data.getAdminPassword() == null) || (data.getAdminPassword().length()==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Admin Password not provided"); + } + if ((data.getAdminEmail() == null) || (data.getAdminEmail().length()==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Admin UID not provided"); + } + if ((data.getAdminName() == null) || (data.getAdminName().length()==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Admin name not provided"); + } + if ((data.getAdminCertRequest() == null) || (data.getAdminCertRequest().length()==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Admin cert request not provided"); + } + if ((data.getAdminCertRequestType() == null) || (data.getAdminCertRequestType().length()==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Admin cert request type not provided"); + } + if ((data.getAdminSubjectDN() == null) || (data.getAdminSubjectDN().length()==0)) { + throw new CMSException(Response.Status.BAD_REQUEST, "Admin subjectDN not provided"); + } + } + + } + + @Override + public InstallToken getInstallToken(InstallTokenRequest data) { + // TODO Figure out how to do authentication here based on user/pass + // For now, allow all user/pass to be valid + CMS.debug("getInstallToken(): starting"); + String user = data.getUser(); + String host = data.getHost(); + String subsystem = data.getSubsystem(); + String groupname = ConfigurationUtils.getGroupName(user, subsystem); + + // assign cookie + long num = random.nextLong(); + String cookie = num + ""; + ISecurityDomainSessionTable ctable = CMS.getSecurityDomainSessionTable(); + String ip; + try { + ip = InetAddress.getByName(host).toString(); + } catch (UnknownHostException e) { + throw new CMSException(Response.Status.BAD_REQUEST, "Unable to resolve host " + host + + "to an IP address: " + e); + } + int index = ip.indexOf("/"); + if (index > 0) ip = ip.substring(index + 1); + + ctable.addEntry(cookie, ip, user, groupname); + + return new InstallToken(cookie); + } + + @Override + public DomainInfo getDomainInfo() { + // TODO Auto-generated method stub for a RESTful method that returns the security domain + return null; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/CertData.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/CertData.java new file mode 100644 index 000000000..d9e5e8005 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/CertData.java @@ -0,0 +1,270 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cms.servlet.csadmin.model; + +import javax.ws.rs.core.MultivaluedMap; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author alee + * + */ +@XmlRootElement(name="CertData") +@XmlAccessorType(XmlAccessType.FIELD) +public class CertData { + public static final String TAG = "tag"; + public static final String NICKNAME = "nickname"; + public static final String TOKEN = "token"; + public static final String KEY_TYPE = "keyType"; + public static final String KEY_ALGORITHM = "keyAlgorithm"; + public static final String SIGNING_ALGORITHM = "signingAlgorithm"; + public static final String KEY_SIZE = "keySize"; + public static final String KEY_CURVENAME = "keyCurveName"; + public static final String REQUEST = "request"; + public static final String SUBJECT_DN = "subjectDN"; + public static final String CERT = "cert"; + public static final String CERT_CHAIN = "certChain"; + + @XmlElement + protected String tag; + + @XmlElement + protected String nickname; + + @XmlElement + protected String token; + + @XmlElement + protected String keyType; + + @XmlElement + protected String keyAlgorithm; + + @XmlElement + protected String signingAlgorithm; + + @XmlElement + protected String keySize; + + @XmlElement + protected String keyCurveName; + + @XmlElement + protected String request; + + @XmlElement + protected String subjectDN; + + @XmlElement + protected String cert; + + @XmlElement + protected String certChain; + + public CertData() { + // required for JAXB + } + + public CertData(MultivaluedMap<String, String> form) { + tag = form.getFirst(TAG); + nickname = form.getFirst(NICKNAME); + token = form.getFirst(TOKEN); + keyType = form.getFirst(KEY_TYPE); + keyAlgorithm = form.getFirst(KEY_ALGORITHM); + signingAlgorithm = form.getFirst(SIGNING_ALGORITHM); + keySize = form.getFirst(KEY_SIZE); + keyCurveName = form.getFirst(KEY_CURVENAME); + request = form.getFirst(REQUEST); + subjectDN = form.getFirst(SUBJECT_DN); + cert = form.getFirst(CERT); + certChain = form.getFirst(CERT_CHAIN); + } + + /** + * @return the tag + */ + public String getTag() { + return tag; + } + + /** + * @param tag the tag to set + */ + public void setTag(String tag) { + this.tag = tag; + } + + /** + * @return the nickname + */ + public String getNickname() { + return nickname; + } + + /** + * @param nickname the nickname to set + */ + public void setNickname(String nickname) { + this.nickname = nickname; + } + + /** + * @return the token + */ + public String getToken() { + return token; + } + + /** + * @param token the token to set + */ + public void setToken(String token) { + this.token = token; + } + + /** + * @return the keyType + */ + public String getKeyType() { + return keyType; + } + + /** + * @param keyType the keyType to set + */ + public void setKeyType(String keyType) { + this.keyType = keyType; + } + + /** + * @return the keyAlgorithm + */ + public String getKeyAlgorithm() { + return keyAlgorithm; + } + + /** + * @param keyAlgorithm the keyAlgorithm to set + */ + public void setKeyAlgorithm(String keyAlgorithm) { + this.keyAlgorithm = keyAlgorithm; + } + + /** + * @return the signingAlgorithm + */ + public String getSigningAlgorithm() { + return signingAlgorithm; + } + + /** + * @param signingAlgorithm the signingAlgorithm to set + */ + public void setSigningAlgorithm(String signingAlgorithm) { + this.signingAlgorithm = signingAlgorithm; + } + + /** + * @return the keySize + */ + public String getKeySize() { + return keySize; + } + + /** + * @param keySize the keySize to set + */ + public void setKeySize(String keySize) { + this.keySize = keySize; + } + + /** + * @return the keyCurveName + */ + public String getKeyCurveName() { + return keyCurveName; + } + + /** + * @param keyCurveName the keyCurveName to set + */ + public void setKeyCurveName(String keyCurveName) { + this.keyCurveName = keyCurveName; + } + + /** + * @return the request + */ + public String getRequest() { + return request; + } + + /** + * @param request the request to set + */ + public void setRequest(String request) { + this.request = request; + } + + /** + * @return the subjectDN + */ + public String getSubjectDN() { + return subjectDN; + } + + /** + * @param subjectDN the subjectDN to set + */ + public void setSubjectDN(String subjectDN) { + this.subjectDN = subjectDN; + } + + /** + * @return the cert + */ + public String getCert() { + return cert; + } + + /** + * @param cert the cert to set + */ + public void setCert(String cert) { + this.cert = cert; + } + + /** + * @return the certChain + */ + public String getCertChain() { + return certChain; + } + + /** + * @param certChain the certChain to set + */ + public void setCertChain(String certChain) { + this.certChain = certChain; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationData.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationData.java new file mode 100644 index 000000000..3c1bea86b --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationData.java @@ -0,0 +1,724 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin.model; + +import java.util.Collection; + +import javax.ws.rs.core.MultivaluedMap; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author alee + * + */ +@XmlRootElement(name="ConfigurationData") +@XmlAccessorType(XmlAccessType.FIELD) +public class ConfigurationData { + private static final String PIN = "pin"; + private static final String TOKEN = "token"; + private static final String TOKEN_PASSWORD = "tokenPassword"; + private static final String SECURITY_DOMAIN_TYPE = "securityDomainType"; + private static final String SECURITY_DOMAIN_URI = "securityDomainUri"; + private static final String SECURITY_DOMAIN_NAME = "securityDomainName"; + private static final String SECURITY_DOMAIN_USER = "securityDomainUser"; + private static final String SECURITY_DOMAIN_PASSWORD = "securityDomainPassword"; + private static final String IS_CLONE = "isClone"; + private static final String CLONE_URI = "cloneUri"; + private static final String SUBSYSTEM_NAME = "subsystemName"; + private static final String P12_FILE = "p12File"; + private static final String P12_PASSWORD = "p12Password"; + private static final String HIERARCHY = "hierarchy"; + private static final String DSHOST = "dsHost"; + private static final String DSPORT = "dsPort"; + private static final String BASEDN = "basedn"; + private static final String BINDDN = "binddn"; + private static final String DATABASE = "database"; + private static final String SECURECONN = "secureConn"; + private static final String REMOVEDATA = "removeData"; + private static final String MASTER_REPLICATION_PORT = "masterReplicationPort"; + private static final String CLONE_REPLICATION_PORT = "cloneReplicationPort"; + private static final String REPLICATION_SECURITY = "replicationSecurity"; + private static final String ISSUING_CA = "issuingCa"; + private static final String BACKUP_KEYS = "backupKeys"; + private static final String BACKUP_FILE = "backupFile"; + private static final String BACKUP_PASSWORD = "backupPassword"; + private static final String ADMIN_UID = "adminUid"; + private static final String ADMIN_EMAIL = "adminEmail"; + private static final String ADMIN_PASSWORD = "adminPassword"; + private static final String ADMIN_CERT_REQUEST = "adminCertRequest"; + private static final String ADMIN_CERT_REQUEST_TYPE = "adminCertRequestType"; + private static final String ADMIN_SUBJECT_DN = "adminSubjectDN"; + private static final String ADMIN_NAME = "adminName"; + private static final String ADMIN_PROFILE_ID = "adminProfileID"; + private static final String STEP_TWO = "stepTwo"; + + //defaults + public static final String TOKEN_DEFAULT = "Internal Key Storage Token"; + public static final String NEW_DOMAIN = "newdomain"; + public static final String EXISTING_DOMAIN = "existingdomain"; + + @XmlElement + protected String pin; + + @XmlElement(defaultValue=TOKEN_DEFAULT) + protected String token; + + @XmlElement + protected String tokenPassword; + + @XmlElement + protected String securityDomainType; + + @XmlElement + protected String securityDomainUri; + + @XmlElement + protected String securityDomainName; + + @XmlElement + protected String securityDomainUser; + + @XmlElement + protected String securityDomainPassword; + + @XmlElement(defaultValue="false") + protected String isClone; + + @XmlElement + protected String cloneUri; + + @XmlElement + protected String subsystemName; + + @XmlElement + protected String p12File; + + @XmlElement + protected String p12Password; + + @XmlElement + protected String hierarchy; + + @XmlElement + protected String dsHost; + + @XmlElement + protected String dsPort; + + @XmlElement + protected String baseDN; + + @XmlElement + protected String bindDN; + + @XmlElement + protected String bindpwd; + + @XmlElement + protected String database; + + @XmlElement(defaultValue = "off") + protected String secureConn; + + @XmlElement + protected String removeData; + + @XmlElement + protected String masterReplicationPort; + + @XmlElement + protected String cloneReplicationPort; + + @XmlElement + protected String replicationSecurity; + + @XmlElementRef + protected Collection<CertData> systemCerts; + + @XmlElement + protected String issuingCA; + + @XmlElement + protected String backupKeys; + + @XmlElement + protected String backupPassword; + + @XmlElement + protected String backupFile; + + @XmlElement + protected String adminUID; + + @XmlElement + protected String adminPassword; + + @XmlElement + protected String adminEmail; + + @XmlElement + protected String adminCertRequest; + + @XmlElement + protected String adminCertRequestType; + + @XmlElement + protected String adminSubjectDN; + + @XmlElement + protected String adminName; + + @XmlElement + protected String adminProfileID; + + @XmlElement + protected String stepTwo; + + public ConfigurationData() { + // required for JAXB + } + + public ConfigurationData(MultivaluedMap<String, String> form) { + pin = form.getFirst(PIN); + token = form.getFirst(TOKEN); + tokenPassword = form.getFirst(TOKEN_PASSWORD); + securityDomainType = form.getFirst(SECURITY_DOMAIN_TYPE); + securityDomainUri = form.getFirst(SECURITY_DOMAIN_URI); + securityDomainName = form.getFirst(SECURITY_DOMAIN_NAME); + securityDomainUser = form.getFirst(SECURITY_DOMAIN_USER); + securityDomainPassword = form.getFirst(SECURITY_DOMAIN_PASSWORD); + isClone = form.getFirst(IS_CLONE); + cloneUri = form.getFirst(CLONE_URI); + subsystemName = form.getFirst(SUBSYSTEM_NAME); + p12File = form.getFirst(P12_FILE); + p12Password = form.getFirst(P12_PASSWORD); + hierarchy = form.getFirst(HIERARCHY); + dsHost = form.getFirst(DSHOST); + dsPort = form.getFirst(DSPORT); + baseDN = form.getFirst(BASEDN); + bindDN = form.getFirst(BINDDN); + database = form.getFirst(DATABASE); + secureConn = form.getFirst(SECURECONN); + removeData = form.getFirst(REMOVEDATA); + masterReplicationPort = form.getFirst(MASTER_REPLICATION_PORT); + cloneReplicationPort = form.getFirst(CLONE_REPLICATION_PORT); + replicationSecurity = form.getFirst(REPLICATION_SECURITY); + //TODO - figure out how to get the cert requests + issuingCA = form.getFirst(ISSUING_CA); + backupFile = form.getFirst(BACKUP_FILE); + backupPassword = form.getFirst(BACKUP_PASSWORD); + backupKeys = form.getFirst(BACKUP_KEYS); + adminUID = form.getFirst(ADMIN_UID); + adminEmail = form.getFirst(ADMIN_EMAIL); + adminPassword = form.getFirst(ADMIN_PASSWORD); + adminCertRequest = form.getFirst(ADMIN_CERT_REQUEST); + adminCertRequestType = form.getFirst(ADMIN_CERT_REQUEST_TYPE); + adminSubjectDN = form.getFirst(ADMIN_SUBJECT_DN); + adminName = form.getFirst(ADMIN_NAME); + adminProfileID = form.getFirst(ADMIN_PROFILE_ID); + stepTwo = form.getFirst(STEP_TWO); + } + + + public String getSubsystemName() { + return subsystemName; + } + + public void setSubsystemName(String subsystemName) { + this.subsystemName = subsystemName; + } + + public String getPin() { + return pin; + } + + public void setPin(String pin) { + this.pin = pin; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getSecurityDomainType() { + return securityDomainType; + } + + public void setSecurityDomainType(String securityDomainType) { + this.securityDomainType = securityDomainType; + } + + public String getSecurityDomainUri() { + return securityDomainUri; + } + + public void setSecurityDomainUri(String securityDomainUri) { + this.securityDomainUri = securityDomainUri; + } + + public String getSecurityDomainName() { + return securityDomainName; + } + + public void setSecurityDomainName(String securityDomainName) { + this.securityDomainName = securityDomainName; + } + + public String getSecurityDomainUser() { + return securityDomainUser; + } + + public void setSecurityDomainUser(String securityDomainUser) { + this.securityDomainUser = securityDomainUser; + } + + public String getSecurityDomainPassword() { + return securityDomainPassword; + } + + public void setSecurityDomainPassword(String securityDomainPassword) { + this.securityDomainPassword = securityDomainPassword; + } + + public String getIsClone() { + return isClone; + } + + public void setIsClone(String isClone) { + this.isClone = isClone; + } + + public String getCloneUri() { + return cloneUri; + } + + public void setCloneUri(String cloneUri) { + this.cloneUri = cloneUri; + } + + /** + * @return the p12File + */ + public String getP12File() { + return p12File; + } + + /** + * @param p12File the p12File to set + */ + public void setP12File(String p12File) { + this.p12File = p12File; + } + + /** + * @return the p12Password + */ + public String getP12Password() { + return p12Password; + } + + /** + * @param p12Password the p12Password to set + */ + public void setP12Password(String p12Password) { + this.p12Password = p12Password; + } + + /** + * @return the tokenPassword + */ + public String getTokenPassword() { + return tokenPassword; + } + + /** + * @param tokenPassword the tokenPassword to set + */ + public void setTokenPassword(String tokenPassword) { + this.tokenPassword = tokenPassword; + } + + /** + * @return the hierarchy + */ + public String getHierarchy() { + return hierarchy; + } + + /** + * @param hierarchy the hierarchy to set + */ + public void setHierarchy(String hierarchy) { + this.hierarchy = hierarchy; + } + + /** + * @return the dsHost + */ + public String getDsHost() { + return dsHost; + } + + /** + * @param dsHost the dsHost to set + */ + public void setDsHost(String dsHost) { + this.dsHost = dsHost; + } + + /** + * @return the dsPort + */ + public String getDsPort() { + return dsPort; + } + + /** + * @param dsPort the dsPort to set + */ + public void setDsPort(String dsPort) { + this.dsPort = dsPort; + } + + /** + * @return the baseDN + */ + public String getBaseDN() { + return baseDN; + } + + /** + * @param baseDN the baseDN to set + */ + public void setBaseDN(String baseDN) { + this.baseDN = baseDN; + } + + /** + * @return the bindDN + */ + public String getBindDN() { + return bindDN; + } + + /** + * @param bindDN the bindDN to set + */ + public void setBindDN(String bindDN) { + this.bindDN = bindDN; + } + + /** + * @return the bindpwd + */ + public String getBindpwd() { + return bindpwd; + } + + /** + * @param bindpwd the bindpwd to set + */ + public void setBindpwd(String bindpwd) { + this.bindpwd = bindpwd; + } + + /** + * @return the secureConn + */ + public String getSecureConn() { + return secureConn; + } + + /** + * @param secureConn the secureConn to set + */ + public void setSecureConn(String secureConn) { + this.secureConn = secureConn; + } + + /** + * @return the removeData + */ + public String getRemoveData() { + return removeData; + } + + /** + * @param removeData the removeData to set + */ + public void setRemoveData(String removeData) { + this.removeData = removeData; + } + + /** + * @return the masterReplicationPort + */ + public String getMasterReplicationPort() { + return masterReplicationPort; + } + + /** + * @param masterReplicationPort the masterReplicationPort to set + */ + public void setMasterReplicationPort(String masterReplicationPort) { + this.masterReplicationPort = masterReplicationPort; + } + + /** + * @return the cloneReplicationPort + */ + public String getCloneReplicationPort() { + return cloneReplicationPort; + } + + /** + * @param cloneReplicationPort the cloneReplicationPort to set + */ + public void setCloneReplicationPort(String cloneReplicationPort) { + this.cloneReplicationPort = cloneReplicationPort; + } + + /** + * @return the replicationSecurity + */ + public String getReplicationSecurity() { + return replicationSecurity; + } + + /** + * @param replicationSecurity the replicationSecurity to set + */ + public void setReplicationSecurity(String replicationSecurity) { + this.replicationSecurity = replicationSecurity; + } + + /** + * @return the database + */ + public String getDatabase() { + return database; + } + + /** + * @param database the database to set + */ + public void setDatabase(String database) { + this.database = database; + } + + /** + * + * @return systemCerts + */ + public Collection<CertData> getSystemCerts() { + return systemCerts; + } + + /** + * + * @param systemCerts + */ + public void setSystemCerts(Collection<CertData> systemCerts) { + this.systemCerts = systemCerts; + } + + /** + * @return the issuingCA + */ + public String getIssuingCA() { + return issuingCA; + } + + /** + * @param issuingCA the issuingCA to set + */ + public void setIssuingCA(String issuingCA) { + this.issuingCA = issuingCA; + } + + /** + * @return the backupKeys + */ + public String getBackupKeys() { + return backupKeys; + } + + /** + * @param backupKeys the backupKeys to set + */ + public void setBackupKeys(String backupKeys) { + this.backupKeys = backupKeys; + } + + /** + * @return the backupFile + */ + public String getBackupFile() { + return backupFile; + } + + /** + * @param backupFile the backupFile to set + */ + public void setBackupFile(String backupFile) { + this.backupFile = backupFile; + } + + /** + * @return the backupPassword + */ + public String getBackupPassword() { + return backupPassword; + } + + /** + * @param backupPassword the backupPassword to set + */ + public void setBackupPassword(String backupPassword) { + this.backupPassword = backupPassword; + } + + /** + * @return the adminUID + */ + public String getAdminUID() { + return adminUID; + } + + /** + * @param adminUID the adminUID to set + */ + public void setAdminUID(String adminUID) { + this.adminUID = adminUID; + } + + /** + * @return the adminPassword + */ + public String getAdminPassword() { + return adminPassword; + } + + /** + * @param adminPassword the adminPassword to set + */ + public void setAdminPassword(String adminPassword) { + this.adminPassword = adminPassword; + } + + /** + * @return the adminEmail + */ + public String getAdminEmail() { + return adminEmail; + } + + /** + * @param adminEmail the adminEmail to set + */ + public void setAdminEmail(String adminEmail) { + this.adminEmail = adminEmail; + } + + /** + * @return the adminCertRequest + */ + public String getAdminCertRequest() { + return adminCertRequest; + } + + /** + * @param adminCertRequest the adminCertRequest to set + */ + public void setAdminCertRequest(String adminCertRequest) { + this.adminCertRequest = adminCertRequest; + } + + /** + * @return the adminCertRequestType + */ + public String getAdminCertRequestType() { + return adminCertRequestType; + } + + /** + * @param adminCertRequestType the adminCertRequestType to set + */ + public void setAdminCertRequestType(String adminCertRequestType) { + this.adminCertRequestType = adminCertRequestType; + } + + /** + * @return the adminSubjectDN + */ + public String getAdminSubjectDN() { + return adminSubjectDN; + } + + /** + * @param adminSubjectDN the adminSubjectDN to set + */ + public void setAdminSubjectDN(String adminSubjectDN) { + this.adminSubjectDN = adminSubjectDN; + } + + /** + * @return the adminName + */ + public String getAdminName() { + return adminName; + } + + /** + * @param adminName the adminName to set + */ + public void setAdminName(String adminName) { + this.adminName = adminName; + } + + /** + * @return the adminProfileID + */ + public String getAdminProfileID() { + return adminProfileID; + } + + /** + * @param adminProfileID the adminProfileID to set + */ + public void setAdminProfileID(String adminProfileID) { + this.adminProfileID = adminProfileID; + } + + public String getStepTwo() { + return stepTwo; + } + + public void setStepTwo(String stepTwo) { + this.stepTwo = stepTwo; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java new file mode 100644 index 000000000..d1656fdda --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/ConfigurationResponseData.java @@ -0,0 +1,120 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin.model; + +import java.security.cert.CertificateEncodingException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Vector; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlRootElement; + +import netscape.security.x509.X509CertImpl; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.cms.servlet.csadmin.Cert; + +/** + * @author alee + * + */ +@XmlRootElement(name="ConfigurationResponseData") +@XmlAccessorType(XmlAccessType.FIELD) +public class ConfigurationResponseData { + + @XmlElementRef + protected Collection<CertData> systemCerts; + + @XmlElement + protected CertData adminCert; + + @XmlElement + protected String status; + + public ConfigurationResponseData() { + systemCerts = new ArrayList<CertData>(); + adminCert = new CertData(); + } + + public void setSystemCerts(Vector<Cert> certs) { + systemCerts.clear(); + Enumeration<Cert> e = certs.elements(); + while (e.hasMoreElements()) { + Cert cert = e.nextElement(); + CertData cdata = new CertData(); + cdata.setCert(cert.getCert()); + cdata.setRequest(cert.getRequest()); + cdata.setTag(cert.getCertTag()); + cdata.setCertChain(cert.getCertChain()); + systemCerts.add(cdata); + } + } + + /** + * @return the systemCerts + */ + public Collection<CertData> getSystemCerts() { + return systemCerts; + } + + /** + * @param systemCerts the systemCerts to set + */ + public void setSystemCerts(Collection<CertData> systemCerts) { + this.systemCerts = systemCerts; + } + + /** + * @return the adminCert + */ + public CertData getAdminCert() { + return adminCert; + } + + /** + * @param adminCert the adminCert to set + */ + public void setAdminCert(CertData adminCert) { + this.adminCert = adminCert; + } + + /** + * @return the status + */ + public String getStatus() { + return status; + } + + /** + * @param status the status to set + */ + public void setStatus(String status) { + this.status = status; + } + + + + public void setAdminCert(X509CertImpl x509CertImpl) throws CertificateEncodingException { + adminCert.setCert(CMS.BtoA(x509CertImpl.getEncoded())); + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/DomainInfo.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/DomainInfo.java new file mode 100644 index 000000000..7ba351cb1 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/DomainInfo.java @@ -0,0 +1,155 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin.model; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author alee + * + */ +@XmlRootElement(name="DomainInfo") +public class DomainInfo { + + @XmlElement(name="CAList") + protected SecurityDomainHostList caList; + + @XmlElement(name="KRAList") + protected SecurityDomainHostList kraList; + + @XmlElement(name="OCSPList") + protected SecurityDomainHostList ocspList; + + @XmlElement(name="TKSList") + protected SecurityDomainHostList tksList; + + @XmlElement(name="TPSList") + protected SecurityDomainHostList tpsList; + + @XmlElement(name="RAList") + protected SecurityDomainHostList raList; + + @XmlElement + protected String name; + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the caList + */ + public SecurityDomainHostList getCaList() { + return caList; + } + + /** + * @param caList the caList to set + */ + public void setCaList(SecurityDomainHostList caList) { + this.caList = caList; + } + + /** + * @return the kraList + */ + public SecurityDomainHostList getKraList() { + return kraList; + } + + /** + * @param kraList the kraList to set + */ + public void setKraList(SecurityDomainHostList kraList) { + this.kraList = kraList; + } + + /** + * @return the ocspList + */ + public SecurityDomainHostList getOcspList() { + return ocspList; + } + + /** + * @param ocspList the ocspList to set + */ + public void setOcspList(SecurityDomainHostList ocspList) { + this.ocspList = ocspList; + } + + /** + * @return the tksList + */ + public SecurityDomainHostList getTksList() { + return tksList; + } + + /** + * @param tksList the tksList to set + */ + public void setTksList(SecurityDomainHostList tksList) { + this.tksList = tksList; + } + + /** + * @return the tpsList + */ + public SecurityDomainHostList getTpsList() { + return tpsList; + } + + /** + * @param tpsList the tpsList to set + */ + public void setTpsList(SecurityDomainHostList tpsList) { + this.tpsList = tpsList; + } + + /** + * @return the raList + */ + public SecurityDomainHostList getRaList() { + return raList; + } + + /** + * @param raList the raList to set + */ + public void setRaList(SecurityDomainHostList raList) { + this.raList = raList; + } + + + + + + + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallToken.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallToken.java new file mode 100644 index 000000000..59284de37 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallToken.java @@ -0,0 +1,50 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author alee + * + */ +@XmlRootElement(name="CertData") +@XmlAccessorType(XmlAccessType.FIELD) +public class InstallToken { + @XmlElement + private String token; + + public InstallToken(String token) { + this.token = token; + } + + public InstallToken() { + // required by jaxb + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java new file mode 100644 index 000000000..40be4179d --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/InstallTokenRequest.java @@ -0,0 +1,99 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin.model; + +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlAccessType; + +/** + * @author alee + * + */ +@XmlRootElement(name="InstallTokenRequest") +@XmlAccessorType(XmlAccessType.FIELD) +public class InstallTokenRequest { + @XmlElement + private String user; + + @XmlElement + private String password; + + @XmlElement + private String subsystem; + + @XmlElement + private String host; + + @XmlElement + private String port; + + public InstallTokenRequest(String user, String password, String subsystem, String host, String port) { + this.user = user; + this.password = password; + this.subsystem = subsystem; + this.host = host; + this.port = port; + } + + public InstallTokenRequest() { + // required for jaxb + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getSubsystem() { + return subsystem; + } + + public void setSubsystem(String subsystem) { + this.subsystem = subsystem; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java new file mode 100644 index 000000000..cd12cfaf2 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHost.java @@ -0,0 +1,40 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.servlet.csadmin.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author alee + * + */ +@XmlRootElement(name="DomainInfo") +@XmlAccessorType(XmlAccessType.FIELD) +public class SecurityDomainHost { + protected String host; + protected String securePort; + protected String secureAgentPort; + protected String secureAdminPort; + protected String secureEEClientAuthPort; + protected String unSecurePort; + protected String clone; + protected String subsystemName; + protected String domainManager; +} diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java new file mode 100644 index 000000000..71922731e --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/csadmin/model/SecurityDomainHostList.java @@ -0,0 +1,53 @@ +/** + * + */ +package com.netscape.cms.servlet.csadmin.model; + +import java.util.Collection; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author alee + * + */ +@XmlRootElement +public class SecurityDomainHostList { + protected Collection<SecurityDomainHost> systems; + + @XmlElement(name="SubsystemCount") + protected int count; + + /** + * @return the systems + */ + @XmlElementRef + public Collection<SecurityDomainHost> getSystems() { + return systems; + } + + /** + * @param systems the systems to set + */ + public void setSystems(Collection<SecurityDomainHost> systems) { + this.systems = systems; + } + + /** + * @return the count + */ + public int getCount() { + return count; + } + + /** + * @param count the count to set + */ + public void setCount(int count) { + this.count = count; + } + + +} |