summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2014-03-27 11:08:32 -0400
committerAde Lee <alee@redhat.com>2014-03-31 10:26:12 -0400
commitb834efbaa8c929c10cf00252b71ebc29e2f10456 (patch)
treee218ae6b2045cd5aa0f137efcdbd940f7de7333e
parent86f4022cc0598353d16901fa2d1ef90f474baaca (diff)
downloadpki-b834efbaa8c929c10cf00252b71ebc29e2f10456.tar.gz
pki-b834efbaa8c929c10cf00252b71ebc29e2f10456.tar.xz
pki-b834efbaa8c929c10cf00252b71ebc29e2f10456.zip
Share subsystem cert in shared tomcat instances
In shared tomcat instances, we need to share the subsystem cert and not create a new one for each additional subsystem added to the instance. In addition, if the instances share the same database, then only one pkidbuser should be created with the relevant subsystem cert and seeAlso attribute. Ticket 893
-rw-r--r--base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java45
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java4
-rw-r--r--base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java78
-rw-r--r--base/server/etc/default.cfg23
-rw-r--r--base/server/python/pki/server/deployment/pkihelper.py32
5 files changed, 157 insertions, 25 deletions
diff --git a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java
index 23f9676fe..b52344e0f 100644
--- a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java
+++ b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java
@@ -88,6 +88,11 @@ public class ConfigurationRequest {
// TKS/TPS shared secret parameters
private static final String IMPORT_SHARED_SECRET = "importSharedSecret";
+ // Parameters for shared tomcat instances
+ private static final String GENERATE_SUBSYSTEM_CERT="generateSubsystemCert";
+ private static final String SHARED_DB = "sharedDB";
+ private static final String SHARED_DBUSER_DN = "sharedDBUserDN";
+
//defaults
public static final String TOKEN_DEFAULT = "Internal Key Storage Token";
public static final String NEW_DOMAIN = "newdomain";
@@ -252,6 +257,15 @@ public class ConfigurationRequest {
@XmlElement(defaultValue="false")
protected String importSharedSecret;
+ @XmlElement(defaultValue="true")
+ protected String generateSubsystemCert;
+
+ @XmlElement(defaultValue="false")
+ protected String sharedDB;
+
+ @XmlElement
+ protected String sharedDBUserDN;
+
public ConfigurationRequest() {
// required for JAXB
}
@@ -309,6 +323,10 @@ public class ConfigurationRequest {
kraUri = form.getFirst(KRA_URI);
enableServerSideKeyGen = form.getFirst(ENABLE_SERVER_SIDE_KEYGEN);
importSharedSecret = form.getFirst(IMPORT_SHARED_SECRET);
+
+ generateSubsystemCert = form.getFirst(GENERATE_SUBSYSTEM_CERT);
+ sharedDB = form.getFirst(SHARED_DB);
+ sharedDBUserDN = form.getFirst(SHARED_DBUSER_DN);
}
public String getSubsystemName() {
@@ -905,6 +923,30 @@ public class ConfigurationRequest {
this.importSharedSecret = importSharedSecret;
}
+ public boolean getGenerateSubsystemCert() {
+ return generateSubsystemCert != null && generateSubsystemCert.equalsIgnoreCase("true");
+ }
+
+ public void setGenerateSubsystemCert(String generateSubsystemCert) {
+ this.generateSubsystemCert = generateSubsystemCert;
+ }
+
+ public boolean getSharedDB() {
+ return sharedDB != null && sharedDB.equalsIgnoreCase("true");
+ }
+
+ public void setSharedDB(String sharedDB) {
+ this.sharedDB = sharedDB;
+ }
+
+ public String getSharedDBUserDN() {
+ return sharedDBUserDN;
+ }
+
+ public void setSharedDBUserDN(String sharedDBUserDN) {
+ this.sharedDBUserDN = sharedDBUserDN;
+ }
+
@Override
public String toString() {
return "ConfigurationRequest [pin=XXXX" +
@@ -959,6 +1001,9 @@ public class ConfigurationRequest {
", tksUri=" + tksUri +
", enableServerSideKeyGen=" + enableServerSideKeyGen +
", importSharedSecret=" + importSharedSecret +
+ ", generateSubsystemCert=" + generateSubsystemCert +
+ ", sharedDB=" + sharedDB +
+ ", sharedDBUserDN=" + sharedDBUserDN +
"]";
}
}
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 5da4dddfe..51c42b7b9 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -1425,8 +1425,8 @@ public class ConfigurationUtils {
String instancePath = cs.getString("instanceRoot");
String instanceId = cs.getString("instanceId");
String cstype = cs.getString("cs.type");
-
- String dbuser = "uid=" + DBUSER + ",ou= people," + baseDN;
+ String dbuser = cs.getString("preop.internaldb.dbuser",
+ "uid=" + DBUSER + ",ou=people," + baseDN);
String configDir = instancePath + File.separator + cstype.toLowerCase() + File.separator + "conf";
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
index 901d51769..61f672c3d 100644
--- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
@@ -23,6 +23,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
@@ -39,11 +40,15 @@ import javax.ws.rs.core.UriInfo;
import netscape.security.x509.X509CertImpl;
+import org.apache.commons.lang.StringUtils;
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.ObjectNotFoundException;
+import org.mozilla.jss.crypto.PrivateKey;
import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.crypto.X509Certificate;
import org.mozilla.jss.util.IncorrectPasswordException;
import com.netscape.certsrv.apps.CMS;
@@ -205,8 +210,6 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
// CA Info Panel
caInfoPanel(data, subsystemNick);
- // retrieve and import CA cert
-
// TKS Info Panel
tksInfoPanel(data, subsystemNick);
@@ -269,6 +272,8 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
}
boolean generateServerCert = data.getGenerateServerCert().equalsIgnoreCase("false")? false : true;
+ boolean generateSubsystemCert = data.getGenerateSubsystemCert();
+
boolean hasSigningCert = false;
Vector<Cert> certs = new Vector<Cert>();
try {
@@ -323,16 +328,16 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
}
if (!generateServerCert && ct.equals("sslserver")) {
- if (!cdata.getToken().equals("internal")) {
- cs.putString(csSubsystem + ".cert.sslserver.nickname", cdata.getNickname());
- } else {
- cs.putString(csSubsystem + ".cert.sslserver.nickname", data.getToken() +
- ":" + cdata.getNickname());
- }
- cs.putString(csSubsystem + ".sslserver.nickname", cdata.getNickname());
- cs.putString(csSubsystem + ".sslserver.cert", cdata.getCert());
- cs.putString(csSubsystem + ".sslserver.certreq", cdata.getRequest());
- cs.putString(csSubsystem + ".sslserver.tokenname", cdata.getToken());
+ updateConfiguration(data, cdata, "sslserver");
+ continue;
+ }
+
+ if (!generateSubsystemCert && ct.equals("subsystem")) {
+ // update the details for the shared subsystem cert here.
+ updateConfiguration(data, cdata, "subsystem");
+
+ // get parameters needed for cloning
+ updateCloneConfiguration(cdata, "subsystem");
continue;
}
@@ -574,7 +579,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
}
try {
- ConfigurationUtils.setupDBUser();
+ if (!data.getSharedDB()) ConfigurationUtils.setupDBUser();
} catch (Exception e) {
e.printStackTrace();
throw new PKIException("Errors in creating or updating dbuser: " + e);
@@ -638,6 +643,40 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
return response;
}
+ private void updateCloneConfiguration(SystemCertData cdata, String tag) throws NotInitializedException,
+ ObjectNotFoundException, TokenException {
+ // TODO - some of these parameters may only be valid for RSA
+ CryptoManager cryptoManager = CryptoManager.getInstance();
+ X509Certificate cert = cryptoManager.findCertByNickname(cdata.getNickname());
+ PublicKey pubk = cert.getPublicKey();
+ byte[] exponent = CryptoUtil.getPublicExponent(pubk);
+ byte[] modulus = CryptoUtil.getModulus(pubk);
+ PrivateKey privk = cryptoManager.findPrivKeyByCert(cert);
+
+ cs.putString("preop.cert." + tag + ".pubkey.modulus", CryptoUtil.byte2string(modulus));
+ cs.putString("preop.cert." + tag + ".pubkey.exponent", CryptoUtil.byte2string(exponent));
+ cs.putString("preop.cert." + tag + ".privkey.id", CryptoUtil.byte2string(privk.getUniqueID()));
+ cs.putString("preop.cert." + tag + ".dn", cdata.getSubjectDN());
+ cs.putString("preop.cert." + tag + ".keyalgorithm", cdata.getKeyAlgorithm());
+ cs.putString("preop.cert." + tag + ".keytype", cdata.getKeyType());
+ cs.putString("preop.cert." + tag + ".nickname", cdata.getNickname());
+ }
+
+ private void updateConfiguration(ConfigurationRequest data, SystemCertData cdata, String tag) {
+ if (cdata.getToken().equals("Internal Key Storage Token")) {
+ cs.putString(csSubsystem + ".cert." + tag + ".nickname", cdata.getNickname());
+ } else {
+ cs.putString(csSubsystem + ".cert." + tag + ".nickname", data.getToken() +
+ ":" + cdata.getNickname());
+ }
+
+ cs.putString(csSubsystem + "." + tag + ".nickname", cdata.getNickname());
+ cs.putString(csSubsystem + "." + tag + ".tokenname", cdata.getToken());
+ cs.putString(csSubsystem + "." + tag + ".certreq", cdata.getRequest());
+ cs.putString(csSubsystem + "." + tag + ".cert", cdata.getCert());
+ cs.putString(csSubsystem + "." + tag + ".dn", cdata.getSubjectDN());
+ }
+
private void caInfoPanel(ConfigurationRequest data, String subsystemNick) {
URI caUri = null;
try {
@@ -816,6 +855,9 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
cs.putString("preop.internaldb.replicationpwd", replicationpwd);
cs.putString("preop.database.removeData", "false");
+ if (data.getSharedDB()) {
+ cs.putString("preop.internaldb.dbuser", data.getSharedDBUserDN());
+ }
cs.commit(false);
if (data.getIsClone().equals("true")) {
@@ -1234,6 +1276,16 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
data.setGenerateServerCert("true");
}
+ if (! data.getGenerateSubsystemCert()) {
+ // No subsystem cert to be generated. All interactions use a shared subsystem cert.
+ if (data.getSharedDB() && StringUtils.isEmpty(data.getSharedDBUserDN())) {
+ throw new BadRequestException("Shared db user DN not provided");
+ }
+ } else {
+ // if the subsystem cert is not shared, we do not need to worry about sharing the db
+ data.setSharedDB("false");
+ }
+
if (csType.equals("TPS")) {
if ((data.getCaUri() == null) || data.getCaUri().isEmpty()) {
throw new BadRequestException("CA URI not provided");
diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg
index ea9c54019..41b3bd39f 100644
--- a/base/server/etc/default.cfg
+++ b/base/server/etc/default.cfg
@@ -114,6 +114,8 @@ pki_ssl_server_token=Internal Key Storage Token
pki_subsystem_key_algorithm=SHA256withRSA
pki_subsystem_key_size=2048
pki_subsystem_key_type=rsa
+pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s
+pki_subsystem_subject_dn=cn=Subsystem Certificate,o=%(pki_security_domain_name)s
pki_subsystem_token=Internal Key Storage Token
pki_theme_enable=True
pki_theme_server_dir=/usr/share/pki/common-ui
@@ -399,8 +401,7 @@ pki_ds_base_dn=o=%(pki_instance_name)s-CA
pki_ds_database=%(pki_instance_name)s-CA
pki_ds_hostname=%(pki_hostname)s
pki_subsystem_name=CA %(pki_hostname)s %(pki_https_port)s
-pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s CA
-pki_subsystem_subject_dn=cn=CA Subsystem Certificate,o=%(pki_security_domain_name)s
+pki_share_db=False
# Paths
# These are used in the processing of pkispawn and are not supposed
@@ -479,8 +480,9 @@ pki_ds_base_dn=o=%(pki_instance_name)s-KRA
pki_ds_database=%(pki_instance_name)s-KRA
pki_ds_hostname=%(pki_hostname)s
pki_subsystem_name=KRA %(pki_hostname)s %(pki_https_port)s
-pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s KRA
-pki_subsystem_subject_dn=cn=KRA Subsystem Certificate,o=%(pki_security_domain_name)s
+pki_share_db=True
+pki_share_dbuser_dn=uid=pkidbuser,ou=people,o=%(pki_instance_name)s-CA
+
# Paths
# These are used in the processing of pkispawn and are not supposed
@@ -540,8 +542,9 @@ pki_ds_base_dn=o=%(pki_instance_name)s-OCSP
pki_ds_database=%(pki_instance_name)s-OCSP
pki_ds_hostname=%(pki_hostname)s
pki_subsystem_name=OCSP %(pki_hostname)s %(pki_https_port)s
-pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s OCSP
-pki_subsystem_subject_dn=cn=OCSP Subsystem Certificate,o=%(pki_security_domain_name)s
+pki_share_db=True
+pki_share_dbuser_dn=uid=pkidbuser,ou=people,o=%(pki_instance_name)s-CA
+
###############################################################################
## RA Configuration: ##
@@ -571,8 +574,8 @@ pki_ds_base_dn=o=%(pki_instance_name)s-TKS
pki_ds_database=%(pki_instance_name)s-TKS
pki_ds_hostname=%(pki_hostname)s
pki_subsystem_name=TKS %(pki_hostname)s %(pki_https_port)s
-pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s TKS
-pki_subsystem_subject_dn=cn=TKS Subsystem Certificate,o=%(pki_security_domain_name)s
+pki_share_db=True
+pki_share_dbuser_dn=uid=pkidbuser,ou=people,o=%(pki_instance_name)s-CA
###############################################################################
## TPS Configuration: ##
@@ -593,8 +596,6 @@ pki_ds_base_dn=o=%(pki_instance_name)s-TPS
pki_ds_database=%(pki_instance_name)s-TPS
pki_ds_hostname=%(pki_hostname)s
pki_subsystem_name=TPS %(pki_hostname)s %(pki_https_port)s
-pki_subsystem_nickname=subsystemCert cert-%(pki_instance_name)s TPS
-pki_subsystem_subject_dn=cn=TPS Subsystem Certificate,o=%(pki_security_domain_name)s
pki_authdb_hostname=%(pki_hostname)s
pki_authdb_port=389
pki_authdb_secure_conn=False
@@ -603,6 +604,8 @@ pki_kra_uri=https://%(pki_hostname)s:%(pki_https_port)s
pki_tks_uri=https://%(pki_hostname)s:%(pki_https_port)s
pki_enable_server_side_keygen=False
pki_import_shared_secret=False
+pki_share_db=True
+pki_share_dbuser_dn=uid=pkidbuser,ou=people,o=%(pki_instance_name)s-CA
# Paths
# These are used in the processing of pkispawn and are not supposed
diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index 66ea3620f..8a225ba1f 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -3690,6 +3690,7 @@ class ConfigClient:
# Create 'Subsystem Certificate'
if not self.clone:
if self.standalone and self.external_step_two:
+ data.generateSubsystemCert = "true"
# Stand-alone PKI (Step 2)
cert4 = self.create_system_cert("subsystem")
# Load the Stand-alone PKI 'Subsystem Certificate' (Step 2)
@@ -3698,9 +3699,20 @@ class ConfigClient:
self.master_dict['pki_external_subsystem_cert_path'],
self.subsystem)
systemCerts.append(cert4)
+ elif len(system_list) >= 2:
+ # Existing PKI Instance
+ data.generateSubsystemCert = "false"
+ for subsystem in system_list:
+ dst = self.master_dict['pki_instance_path'] + '/conf/' + \
+ subsystem.lower() + '/CS.cfg'
+ if subsystem != self.subsystem and os.path.exists(dst):
+ cert4 = self.retrieve_existing_subsystem_cert(dst)
+ systemCerts.append(cert4)
+ break
else:
# PKI KRA, PKI OCSP, PKI RA, PKI TKS, PKI TPS,
# Subordinate CA, or External CA
+ data.generateSubsystemCert = "true"
cert4 = self.create_system_cert("subsystem")
systemCerts.append(cert4)
@@ -3807,6 +3819,11 @@ class ConfigClient:
data.secureConn = "true"
else:
data.secureConn = "false"
+ if config.str2bool(self.master_dict['pki_share_db']):
+ data.sharedDB = "true"
+ data.sharedDBUserDN = self.master_dict['pki_share_dbuser_dn']
+ else:
+ data.sharedDB = "false"
def set_backup_parameters(self, data):
if config.str2bool(self.master_dict['pki_backup_keys']):
@@ -3957,6 +3974,21 @@ class ConfigClient:
cert.token = cs_cfg.get(cstype + ".sslserver.tokenname")
return cert
+ def retrieve_existing_subsystem_cert(self, cfg_file):
+ cs_cfg = PKIConfigParser.read_simple_configuration_file(cfg_file)
+ cstype = cs_cfg.get('cs.type').lower()
+ cert = pki.system.SystemCertData()
+ cert.tag = self.master_dict["pki_subsystem_tag"]
+ cert.keyAlgorithm = cs_cfg.get("cloning.subsystem.keyalgorithm")
+ cert.keySize = self.master_dict["pki_subsystem_key_size"]
+ cert.keyType = cs_cfg.get("cloning.subsystem.keytype")
+ cert.nickname = cs_cfg.get(cstype + ".subsystem.nickname")
+ cert.cert = cs_cfg.get(cstype + ".subsystem.cert")
+ cert.request = cs_cfg.get(cstype + ".subsystem.certreq")
+ cert.subjectDN = cs_cfg.get("cloning.subsystem.dn")
+ cert.token = cs_cfg.get(cstype + ".subsystem.tokenname")
+ return cert
+
class PKIDeployer:
"""Holds the global dictionaries and the utility objects"""