summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java15
-rw-r--r--base/common/src/com/netscape/certsrv/system/TPSConnectorClient.java66
-rw-r--r--base/common/src/com/netscape/certsrv/system/TPSConnectorCollection.java17
-rw-r--r--base/common/src/com/netscape/certsrv/system/TPSConnectorData.java153
-rw-r--r--base/common/src/com/netscape/certsrv/system/TPSConnectorResource.java91
-rw-r--r--base/common/src/com/netscape/certsrv/tks/TKSClient.java2
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java62
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigService.java13
-rw-r--r--base/common/src/com/netscape/cms/servlet/tks/TPSConnectorService.java376
-rw-r--r--base/java-tools/src/com/netscape/cmstools/cli/TKSCLI.java2
-rw-r--r--base/java-tools/src/com/netscape/cmstools/system/TPSConnectorAddCLI.java52
-rw-r--r--base/java-tools/src/com/netscape/cmstools/system/TPSConnectorCLI.java94
-rw-r--r--base/java-tools/src/com/netscape/cmstools/system/TPSConnectorFindCLI.java88
-rw-r--r--base/java-tools/src/com/netscape/cmstools/system/TPSConnectorRemoveCLI.java53
-rw-r--r--base/server/etc/default.cfg1
-rw-r--r--base/server/python/pki/server/deployment/pkihelper.py125
-rw-r--r--base/server/python/pki/server/deployment/pkimessages.py5
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/initialization.py3
-rw-r--r--base/tks/src/com/netscape/tks/TKSApplication.java4
-rw-r--r--base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java78
20 files changed, 1298 insertions, 2 deletions
diff --git a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java
index 23021a573..4fdf594d1 100644
--- a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java
+++ b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java
@@ -84,6 +84,8 @@ public class ConfigurationRequest {
private static final String KRA_URI = "kraUri";
private static final String ENABLE_SERVER_SIDE_KEYGEN = "enableServerSideKeygen";
+ // TKS/TPS shared secret parameters
+ private static final String IMPORT_SHARED_SECRET = "importSharedSecret";
//defaults
public static final String TOKEN_DEFAULT = "Internal Key Storage Token";
@@ -243,6 +245,9 @@ public class ConfigurationRequest {
@XmlElement(defaultValue="false")
protected String enableServerSideKeyGen;
+ @XmlElement(defaultValue="false")
+ protected String importSharedSecret;
+
public ConfigurationRequest() {
// required for JAXB
}
@@ -298,6 +303,7 @@ public class ConfigurationRequest {
tksUri = form.getFirst(TKS_URI);
kraUri = form.getFirst(KRA_URI);
enableServerSideKeyGen = form.getFirst(ENABLE_SERVER_SIDE_KEYGEN);
+ importSharedSecret = form.getFirst(IMPORT_SHARED_SECRET);
}
public String getSubsystemName() {
@@ -878,6 +884,14 @@ public class ConfigurationRequest {
this.enableServerSideKeyGen = enableServerSideKeyGen;
}
+ public String getImportSharedSecret() {
+ return importSharedSecret;
+ }
+
+ public void setImportSharedSecret(String importSharedSecret) {
+ this.importSharedSecret = importSharedSecret;
+ }
+
@Override
public String toString() {
return "ConfigurationRequest [pin=XXXX" +
@@ -930,6 +944,7 @@ public class ConfigurationRequest {
", kraUri=" + kraUri +
", tksUri=" + tksUri +
", enableServerSideKeyGen=" + enableServerSideKeyGen +
+ ", importSharedSecret=" + importSharedSecret +
"]";
}
}
diff --git a/base/common/src/com/netscape/certsrv/system/TPSConnectorClient.java b/base/common/src/com/netscape/certsrv/system/TPSConnectorClient.java
new file mode 100644
index 000000000..09ba9db45
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/system/TPSConnectorClient.java
@@ -0,0 +1,66 @@
+package com.netscape.certsrv.system;
+
+import java.net.URISyntaxException;
+
+import com.netscape.certsrv.client.Client;
+import com.netscape.certsrv.client.PKIClient;
+import com.netscape.certsrv.key.KeyData;
+
+public class TPSConnectorClient extends Client {
+
+ private TPSConnectorResource tpsConnectorClient;
+
+ public TPSConnectorClient(PKIClient client) throws URISyntaxException {
+ this(client, client.getSubsystem());
+ }
+
+ public TPSConnectorClient(PKIClient client, String subsystem) throws URISyntaxException {
+ super(client, subsystem, "tpsconnector");
+ init();
+ }
+
+ public void init() throws URISyntaxException {
+ tpsConnectorClient = createProxy(TPSConnectorResource.class);
+ }
+
+ public TPSConnectorCollection listConnectors() {
+ return tpsConnectorClient.listConnectors();
+ }
+
+ public TPSConnectorData getConnector(String id) {
+ return tpsConnectorClient.getConnector(id);
+ }
+
+ public TPSConnectorData getConnector(String host, String port) {
+ return tpsConnectorClient.getConnector(host, port);
+ }
+
+ public TPSConnectorData createConnector(String tpsHost, String tpsPort) {
+ return tpsConnectorClient.createConnector(tpsHost, tpsPort);
+ }
+
+ public void deleteConnector(String id) {
+ tpsConnectorClient.deleteConnector(id);
+ }
+
+ public KeyData createSharedSecret(String id) {
+ return tpsConnectorClient.createSharedSecret(id);
+ }
+
+ public KeyData replaceSharedSecret(String id) {
+ return tpsConnectorClient.replaceSharedSecret(id);
+ };
+
+ public void deleteSharedSecret(String id) {
+ tpsConnectorClient.deleteSharedSecret(id);
+ }
+
+ public KeyData getSharedSecret(String id) {
+ return tpsConnectorClient.getSharedSecret(id);
+ }
+
+ public void deleteConnector(String host, String port) {
+ tpsConnectorClient.deleteConnector(host, port);
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/system/TPSConnectorCollection.java b/base/common/src/com/netscape/certsrv/system/TPSConnectorCollection.java
new file mode 100644
index 000000000..106a681bf
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/system/TPSConnectorCollection.java
@@ -0,0 +1,17 @@
+package com.netscape.certsrv.system;
+
+import java.util.Collection;
+
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import com.netscape.certsrv.base.DataCollection;
+
+@XmlRootElement(name="TPSConnectors")
+public class TPSConnectorCollection extends DataCollection<TPSConnectorData> {
+
+ @XmlElementRef
+ public Collection<TPSConnectorData> getEntries() {
+ return super.getEntries();
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/system/TPSConnectorData.java b/base/common/src/com/netscape/certsrv/system/TPSConnectorData.java
new file mode 100644
index 000000000..d5e1480eb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/system/TPSConnectorData.java
@@ -0,0 +1,153 @@
+package com.netscape.certsrv.system;
+
+import java.io.StringReader;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.jboss.resteasy.plugins.providers.atom.Link;
+
+@XmlRootElement(name="TPSSystemClient")
+public class TPSConnectorData {
+
+ public static Marshaller marshaller;
+ public static Unmarshaller unmarshaller;
+
+ static {
+ try {
+ marshaller = JAXBContext.newInstance(TPSConnectorData.class).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ unmarshaller = JAXBContext.newInstance(TPSConnectorData.class).createUnmarshaller();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ String id;
+ String host;
+ String port;
+ String userID;
+ String nickname;
+
+ Link link;
+
+ @XmlAttribute(name="id")
+ public String getID() {
+ return id;
+ }
+
+ public void setID(String id) {
+ this.id = id;
+ }
+
+ @XmlAttribute(name="Host")
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ @XmlAttribute(name="Port")
+ public String getPort() {
+ return port;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ @XmlElement(name="UserID")
+ public String getUserID() {
+ return userID;
+ }
+
+ public void setUserID(String userID) {
+ this.userID = userID;
+ }
+
+ @XmlAttribute(name="Nickname")
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public Link getLink() {
+ return link;
+ }
+
+ public void setLink(Link link) {
+ this.link = link;
+ }
+
+ public static TPSConnectorData valueOf(String string) throws Exception {
+ try {
+ return (TPSConnectorData)unmarshaller.unmarshal(new StringReader(string));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "TPSSystemClientData [id=" + id + ", host=" + host + ", port=" + port +
+ ", userID=" + userID + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((port == null) ? 0 : port.hashCode());
+ result = prime * result + ((userID == null) ? 0 : userID.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TPSConnectorData other = (TPSConnectorData) obj;
+ if (host == null) {
+ if (other.host != null)
+ return false;
+ } else if (!host.equals(other.host))
+ return false;
+ if (port == null) {
+ if (other.port != null)
+ return false;
+ } else if (!port.equals(other.port))
+ return false;
+ if (userID == null) {
+ if (other.userID != null)
+ return false;
+ } else if (!userID.equals(other.userID))
+ return false;
+ return true;
+ }
+
+ public static void main(String args[]) throws Exception {
+ TPSConnectorData before = new TPSConnectorData();
+ before.setID("tps0");
+ before.setUserID("user1");
+
+ String string = before.toString();
+ System.out.println(string);
+
+ TPSConnectorData after = TPSConnectorData.valueOf(string);
+ System.out.println(before.equals(after));
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/system/TPSConnectorResource.java b/base/common/src/com/netscape/certsrv/system/TPSConnectorResource.java
new file mode 100644
index 000000000..8a76ee696
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/system/TPSConnectorResource.java
@@ -0,0 +1,91 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.system;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import com.netscape.certsrv.acls.ACLMapping;
+import com.netscape.certsrv.authentication.AuthMethodMapping;
+import com.netscape.certsrv.key.KeyData;
+
+/**
+ * @author Ade Lee
+ */
+@Path("/admin/tps-connectors")
+@AuthMethodMapping("admin")
+public interface TPSConnectorResource {
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public TPSConnectorCollection listConnectors();
+
+ @GET
+ @Path("{id}")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public TPSConnectorData getConnector(@PathParam("id") String id);
+
+ @GET
+ @Path("search")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public TPSConnectorData getConnector(@QueryParam("host") String host,
+ @QueryParam("port") String port);
+
+ @POST
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public TPSConnectorData createConnector(@QueryParam("host") String host,
+ @QueryParam("port") String port);
+
+ @DELETE
+ @Path("{id}")
+ public void deleteConnector(@PathParam("id") String id);
+
+ @POST
+ @Path("{id}/shared-secret")
+ @ACLMapping("admin.sharedsecret")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public KeyData createSharedSecret(@PathParam("id") String id);
+
+ @PUT
+ @Path("{id}/shared-secret")
+ @ACLMapping("admin.sharedsecret")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public KeyData replaceSharedSecret(@PathParam("id") String id);
+
+ @DELETE
+ @Path("{id}/shared-secret")
+ @ACLMapping("admin.sharedsecret")
+ public void deleteSharedSecret(@PathParam("id") String id);
+
+ @DELETE
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public void deleteConnector(@QueryParam("host") String host,
+ @QueryParam("port") String port);
+
+ @GET
+ @Path("{id}/shared-secret")
+ @ACLMapping("admin.sharedsecret")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public KeyData getSharedSecret(@PathParam("id") String id);
+}
diff --git a/base/common/src/com/netscape/certsrv/tks/TKSClient.java b/base/common/src/com/netscape/certsrv/tks/TKSClient.java
index baecf8ddb..a13089f86 100644
--- a/base/common/src/com/netscape/certsrv/tks/TKSClient.java
+++ b/base/common/src/com/netscape/certsrv/tks/TKSClient.java
@@ -22,6 +22,7 @@ import java.net.URISyntaxException;
import com.netscape.certsrv.client.PKIClient;
import com.netscape.certsrv.client.SubsystemClient;
import com.netscape.certsrv.group.GroupClient;
+import com.netscape.certsrv.system.TPSConnectorClient;
import com.netscape.certsrv.user.UserClient;
public class TKSClient extends SubsystemClient {
@@ -34,5 +35,6 @@ public class TKSClient extends SubsystemClient {
public void init() throws URISyntaxException {
addClient(new GroupClient(client, name));
addClient(new UserClient(client, name));
+ addClient(new TPSConnectorClient(client, name));
}
}
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 78d14b3f5..1e6ee25a3 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -147,11 +147,14 @@ import com.netscape.certsrv.client.PKIClient;
import com.netscape.certsrv.client.PKIConnection;
import com.netscape.certsrv.dbs.IDBSubsystem;
import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord;
+import com.netscape.certsrv.key.KeyData;
import com.netscape.certsrv.ldap.ILdapConnFactory;
import com.netscape.certsrv.ocsp.IDefStore;
import com.netscape.certsrv.ocsp.IOCSPAuthority;
import com.netscape.certsrv.system.InstallToken;
import com.netscape.certsrv.system.SecurityDomainClient;
+import com.netscape.certsrv.system.TPSConnectorClient;
+import com.netscape.certsrv.system.TPSConnectorData;
import com.netscape.certsrv.usrgrp.EUsrGrpException;
import com.netscape.certsrv.usrgrp.IGroup;
import com.netscape.certsrv.usrgrp.IUGSubsystem;
@@ -3568,6 +3571,63 @@ public class ConfigurationUtils {
return null;
}
+ public static void getSharedSecret(String tksHost, int tksPort, boolean importKey) throws EPropertyNotFound,
+ EBaseException, URISyntaxException {
+ IConfigStore cs = CMS.getConfigStore();
+ String host = cs.getString("service.machineName");
+ String port = cs.getString("service.securePort");
+ String dbDir = cs.getString("instanceRoot") + "/alias";
+ String dbNick = cs.getString("tps.cert.subsystem.nickname");
+
+ String passwordFile = cs.getString("passwordFile");
+ IConfigStore psStore = CMS.createFileConfigStore(passwordFile);
+ String dbPass = psStore.getString("internal");
+
+ ClientConfig config = new ClientConfig();
+ config.setServerURI("https://" + tksHost + ":" + tksPort + "/tks");
+ config.setCertDatabase(dbDir);
+ config.setCertNickname(dbNick);
+ config.setCertPassword(dbPass);
+
+ PKIClient client = new PKIClient(config);
+ PKIConnection connection = client.getConnection();
+
+ // Ignore the "UNTRUSTED_ISSUER" and "CA_CERT_INVALID" validity status
+ // during PKI instance creation since we are using an untrusted temporary CA cert.
+ connection.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER);
+ connection.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID);
+
+ AccountClient accountClient = new AccountClient(client);
+ TPSConnectorClient tpsConnectorClient = new TPSConnectorClient(client);
+
+ accountClient.login();
+ TPSConnectorData data = tpsConnectorClient.getConnector(host, port);
+ KeyData keyData = null;
+ if (data == null) {
+ data = tpsConnectorClient.createConnector(host, port);
+ keyData = tpsConnectorClient.createSharedSecret(data.getID());
+ } else {
+ String connId = data.getID();
+ keyData = tpsConnectorClient.getSharedSecret(connId);
+ if (keyData != null) {
+ keyData = tpsConnectorClient.replaceSharedSecret(connId);
+ } else {
+ keyData = tpsConnectorClient.createSharedSecret(connId);
+ }
+ }
+ accountClient.logout();
+
+ if (importKey) {
+ // TODO - we need code here to import the key into the tps certdb
+ // this is not needed if we are using a shared database with
+ // the tks.
+ }
+
+ // store the new nick in CS.cfg
+ String nick = "TPS-" + host + "-" + port + " sharedSecret";
+ cs.putString("conn.tks1.tksSharedSymKeyName", nick);
+ cs.commit(false);
+ }
public static void importCACertToOCSP() throws IOException, EBaseException, CertificateEncodingException {
IConfigStore config = CMS.getConfigStore();
@@ -3729,7 +3789,7 @@ public class ConfigurationUtils {
CMS.debug("registerUser: status=" + status);
if (status.equals(SUCCESS)) {
- CMS.debug("registerUser: Successfully added user " + uid + " to " + targetURI +
+ CMS.debug("registerUser: Successfully added user " + uid + " to " + targetURI +
" using " + targetURL);
} else if (status.equals(AUTH_FAILURE)) {
throw new EAuthException(AUTH_FAILURE);
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigService.java b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigService.java
index 1884ca3d2..fbadc80d3 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigService.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/SystemConfigService.java
@@ -504,6 +504,13 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
String transportCert = ConfigurationUtils.getTransportCert(secdomainURI, kraURI);
ConfigurationUtils.exportTransportCert(secdomainURI, tksURI, transportCert);
}
+
+ // generate shared secret from the tks
+ ConfigurationUtils.getSharedSecret(
+ tksURI.getHost(),
+ tksURI.getPort(),
+ Boolean.getBoolean(data.getImportSharedSecret()));
+
} catch (URISyntaxException e) {
throw new BadRequestException("Invalid URI for CA, TKS or KRA");
} catch (Exception e) {
@@ -1146,6 +1153,12 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
}
// TODO check connection with authdb
+
+ if (data.getImportSharedSecret().equalsIgnoreCase("true")) {
+ data.setImportSharedSecret("true");
+ } else {
+ data.setImportSharedSecret("false");
+ }
}
}
}
diff --git a/base/common/src/com/netscape/cms/servlet/tks/TPSConnectorService.java b/base/common/src/com/netscape/cms/servlet/tks/TPSConnectorService.java
new file mode 100644
index 000000000..97478d699
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/tks/TPSConnectorService.java
@@ -0,0 +1,376 @@
+package com.netscape.cms.servlet.tks;
+
+import java.io.IOException;
+import java.net.URI;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.commons.lang.StringUtils;
+import org.jboss.resteasy.plugins.providers.atom.Link;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.crypto.InvalidKeyFormatException;
+import org.mozilla.jss.crypto.TokenException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.BadRequestException;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.PKIException;
+import com.netscape.certsrv.base.UnauthorizedException;
+import com.netscape.certsrv.key.KeyData;
+import com.netscape.certsrv.system.TPSConnectorCollection;
+import com.netscape.certsrv.system.TPSConnectorData;
+import com.netscape.certsrv.system.TPSConnectorResource;
+import com.netscape.certsrv.tps.cert.TPSCertResource;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cmscore.realm.PKIPrincipal;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+public class TPSConnectorService implements TPSConnectorResource {
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ @Context
+ private UriInfo uriInfo;
+
+ @Context
+ private HttpServletRequest servletRequest;
+
+ public IUGSubsystem userGroupManager = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ @Override
+ public TPSConnectorCollection listConnectors() {
+ try {
+ String tpsList = cs.getString("tps.list", "");
+ if (tpsList.isEmpty()) {
+ return null;
+ }
+
+ TPSConnectorCollection ret = new TPSConnectorCollection();
+ for (String tpsID : tpsList.split(",")) {
+ ret.addEntry(createTPSSystemClientData(tpsID));
+ }
+ return ret;
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Unable to get TPS connection data" + e);
+ }
+ }
+
+ private TPSConnectorData createTPSSystemClientData(String tpsID) throws EBaseException {
+ TPSConnectorData data = new TPSConnectorData();
+ data.setID(tpsID);
+ data.setHost(cs.getString("tps." + tpsID + ".host", ""));
+ data.setPort(cs.getString("tps." + tpsID + ".port", ""));
+ data.setUserID(cs.getString("tps." + tpsID + ".userid", ""));
+ data.setNickname(cs.getString("tps." + tpsID + ".nickname", ""));
+ URI uri = uriInfo.getBaseUriBuilder().path(TPSCertResource.class).path("{id}").build(tpsID);
+ data.setLink(new Link("self", uri));
+ return data;
+ }
+
+ @Override
+ public TPSConnectorData getConnector(String id) {
+ try {
+ String tpsList = cs.getString("tps.list", "");
+ if (tpsList.isEmpty()) {
+ return null;
+ }
+
+ for (String tpsID : tpsList.split(",")) {
+ if (tpsID.equals(id))
+ return createTPSSystemClientData(tpsID);
+ }
+ return null;
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Unable to get TPS connection data" + e);
+ }
+ }
+
+ @Override
+ public TPSConnectorData getConnector(String host, String port) {
+ try {
+ String tpsList = cs.getString("tps.list", "");
+ if (tpsList.isEmpty()) {
+ return null;
+ }
+
+ for (String tpsID : tpsList.split(",")) {
+ TPSConnectorData data = createTPSSystemClientData(tpsID);
+ if (data.getHost().equals(host) && data.getPort().equals(port))
+ return data;
+ }
+ return null;
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Unable to get TPS connection data" + e);
+ }
+ }
+
+ @Override
+ public TPSConnectorData createConnector(String tpsHost, String tpsPort) {
+ TPSConnectorData newData = new TPSConnectorData();
+ newData.setHost(tpsHost);
+ newData.setPort(tpsPort);
+ newData.setUserID("TPS-" + tpsHost + "-" + tpsPort);
+ try {
+ int index = 0;
+ boolean indexFound = false;
+ String tpsList = cs.getString("tps.list", "");
+ if (!tpsList.isEmpty()) {
+ List<String> sorted = new ArrayList<String>(Arrays.asList(tpsList.split(",")));
+ Collections.sort(sorted);
+ for (String tpsID : sorted) {
+ TPSConnectorData data = createTPSSystemClientData(tpsID);
+ if (data.equals(newData)) {
+ throw new BadRequestException("TPS connection already exists at " + data.getLink());
+ }
+ if (!indexFound && tpsID.equals(index)) {
+ index++;
+ } else {
+ indexFound = true;
+ }
+ }
+ }
+ String newID = Integer.toString(index);
+ newData.setID(newID);
+ URI uri = uriInfo.getBaseUriBuilder().path(TPSCertResource.class).path("{id}").build(newID);
+ newData.setLink(new Link("self", uri));
+ saveClientData(newData);
+
+ cs.putString("tps.list", tpsList.isEmpty() ? Integer.toString(index) :
+ tpsList + "," + index);
+ cs.commit(false);
+
+ return newData;
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Unable to create new TPS connection data" + e);
+ }
+ }
+
+ private void saveClientData(TPSConnectorData newData) throws EBaseException {
+ String id = newData.getID();
+ if ((id == null) || (id.isEmpty())) {
+ CMS.debug("saveClientData: Attempt to save tps connection with null or empty id");
+ return;
+ // throw exception here?
+ }
+ String prefix = "tps." + id + ".";
+
+ if (newData.getHost() != null)
+ cs.putString(prefix + "host", newData.getHost());
+ if (newData.getPort() != null)
+ cs.putString(prefix + "port", newData.getPort());
+ if (newData.getUserID() != null)
+ cs.putString(prefix + "userid", newData.getUserID());
+ if (newData.getNickname() != null)
+ cs.putString(prefix + "nickname", newData.getNickname());
+
+ cs.commit(false);
+ }
+
+ @Override
+ public void deleteConnector(String id) {
+ try {
+ if ((id == null) || id.isEmpty())
+ throw new BadRequestException("Attempt to delete TPS connection with null or empty id");
+
+ if (getConnector(id) == null) {
+ return;
+ // return 404 here?
+ }
+
+ deleteSharedSecret(id);
+
+ String prefix = "tps." + id;
+ cs.removeSubStore(prefix);
+
+ String tpsList = cs.getString("tps.list", "");
+ if (tpsList.isEmpty()) {
+ return;
+ }
+
+ List<String> newList = new ArrayList<String>();
+ for (String tpsID : tpsList.split(",")) {
+ if (!tpsID.equals(id)) {
+ newList.add(tpsID);
+ }
+ }
+ cs.putString("tps.list", StringUtils.join(newList, ","));
+ cs.commit(false);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Failed to delete TPS connection" + e);
+ }
+ }
+
+ @Override
+ public KeyData createSharedSecret(String id) {
+ try {
+ if (getConnector(id) == null) {
+ throw new BadRequestException("TPS Connection does not exist");
+ }
+
+ // get and validate user
+ String userid = validateUser(id);
+
+ // get user cert
+ IUser user = userGroupManager.getUser(userid);
+ X509Certificate[] certs = user.getX509Certificates();
+
+ String nickname = userid + " sharedSecret";
+ if (CryptoUtil.sharedSecretExists(nickname)) {
+ throw new BadRequestException("Shared secret already exists");
+ }
+
+ CryptoUtil.createSharedSecret(nickname);
+
+ cs.putString("tps." + id + ".nickname", nickname);
+ cs.commit(false);
+
+ byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]);
+ KeyData keyData = new KeyData();
+ keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey));
+ return keyData;
+
+ } catch (InvalidKeyException | IllegalStateException | NoSuchAlgorithmException
+ | InvalidAlgorithmParameterException | EBaseException
+ | NotInitializedException | TokenException | IOException | InvalidKeyFormatException e) {
+ e.printStackTrace();
+ CMS.debug("Error in generating and exporting shared secret: " + e);
+ throw new PKIException("Error in generating and exporting shared secret: " + e);
+ }
+ }
+
+ private String validateUser(String id) throws EBaseException {
+ String userid = cs.getString("tps." + id + ".userid", "");
+ if (userid.isEmpty()) {
+ throw new PKIException("Bad TPS connection configuration: userid not defined");
+ }
+
+ PKIPrincipal principal = (PKIPrincipal) servletRequest.getUserPrincipal();
+ if (principal == null) {
+ throw new UnauthorizedException("User credentials not provided");
+ }
+
+ String uid = principal.getName();
+ if (!uid.equals(userid)) {
+ throw new UnauthorizedException("TPS Connection belongs to another user");
+ }
+ return userid;
+ }
+
+ @Override
+ public KeyData replaceSharedSecret(String id) {
+ try {
+ if (getConnector(id) == null) {
+ throw new BadRequestException("TPS Connection does not exist");
+ }
+
+ // get and validate user
+ String userid = validateUser(id);
+
+ // get user cert
+ IUser user = userGroupManager.getUser(userid);
+ X509Certificate[] certs = user.getX509Certificates();
+
+ String nickname = userid + " sharedSecret";
+ if (!CryptoUtil.sharedSecretExists(nickname)) {
+ throw new BadRequestException("Cannot replace. Shared secret does not exist");
+ }
+
+ CryptoUtil.deleteSharedSecret(nickname);
+ CryptoUtil.createSharedSecret(nickname);
+ byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]);
+ KeyData keyData = new KeyData();
+ keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey));
+ return keyData;
+ } catch (InvalidKeyException | IllegalStateException | NoSuchAlgorithmException
+ | InvalidAlgorithmParameterException | EBaseException
+ | NotInitializedException | TokenException | IOException | InvalidKeyFormatException e) {
+ e.printStackTrace();
+ CMS.debug("Error in replacing shared secret: " + e);
+ throw new PKIException("Error in replacing shared secret: " + e);
+ }
+ }
+
+ @Override
+ public void deleteSharedSecret(String id) {
+ try {
+ if (getConnector(id) == null) {
+ return;
+ }
+
+ // get and validate user
+ String userid = validateUser(id);
+
+ String nickname = userid + " sharedSecret";
+ if (!CryptoUtil.sharedSecretExists(nickname)) {
+ return;
+ }
+ CryptoUtil.deleteSharedSecret(nickname);
+
+ cs.putString("tps." + id + ".nickname", "");
+ cs.commit(false);
+ } catch (InvalidKeyException | IllegalStateException | EBaseException
+ | NotInitializedException | TokenException e) {
+ e.printStackTrace();
+ CMS.debug("Error in deleting shared secret: " + e);
+ throw new PKIException("Error in deleting shared secret: " + e);
+ }
+ }
+
+ @Override
+ public KeyData getSharedSecret(String id) {
+ try {
+ if (getConnector(id) == null) {
+ throw new BadRequestException("TPS Connection does not exist");
+ }
+
+ // get and validate user
+ String userid = validateUser(id);
+
+ // get user cert
+ IUser user = userGroupManager.getUser(userid);
+ X509Certificate[] certs = user.getX509Certificates();
+
+ String nickname = userid + " sharedSecret";
+ if (!CryptoUtil.sharedSecretExists(nickname)) {
+ return null;
+ }
+ byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]);
+ KeyData keyData = new KeyData();
+ keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey));
+ return keyData;
+ } catch (InvalidKeyException | IllegalStateException | NoSuchAlgorithmException
+ | InvalidAlgorithmParameterException | EBaseException
+ | NotInitializedException | TokenException | IOException | InvalidKeyFormatException e) {
+ e.printStackTrace();
+ CMS.debug("Error in obtaining shared secret: " + e);
+ throw new PKIException("Error in obtaining shared secret: " + e);
+ }
+ }
+
+ @Override
+ public void deleteConnector(String host, String port) {
+ TPSConnectorData data = getConnector(host, port);
+ if (data == null) {
+ return;
+ }
+ deleteConnector(data.getID());
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/TKSCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/TKSCLI.java
index df7050189..b8c90ed47 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/TKSCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/TKSCLI.java
@@ -21,6 +21,7 @@ package com.netscape.cmstools.cli;
import com.netscape.certsrv.client.Client;
import com.netscape.certsrv.tks.TKSClient;
import com.netscape.cmstools.group.GroupCLI;
+import com.netscape.cmstools.system.TPSConnectorCLI;
import com.netscape.cmstools.user.UserCLI;
/**
@@ -34,6 +35,7 @@ public class TKSCLI extends SubsystemCLI {
super("tks", "TKS management commands", parent);
addModule(new GroupCLI(this));
+ addModule(new TPSConnectorCLI(this));
addModule(new UserCLI(this));
}
diff --git a/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorAddCLI.java b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorAddCLI.java
new file mode 100644
index 000000000..c9e1df985
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorAddCLI.java
@@ -0,0 +1,52 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools.system;
+
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+/**
+ * @author Ade Lee
+ */
+public class TPSConnectorAddCLI extends CLI {
+ public TPSConnectorCLI tpsConnectorCLI;
+
+ public TPSConnectorAddCLI(TPSConnectorCLI tpsConnectorCLI) {
+ super("add", "Add TPS Connector to TKS", tpsConnectorCLI);
+ this.tpsConnectorCLI = tpsConnectorCLI;
+ }
+
+ public void printHelp() {
+ formatter.printHelp(getFullName() + " <TPS Host> <TPS Port>", options);
+ }
+
+ public void execute(String[] args) throws Exception {
+ if (args.length != 2) {
+ printHelp();
+ System.exit(1);
+ }
+
+ String tpsHost = args[0];
+ String tpsPort = args[1];
+
+ tpsConnectorCLI.tpsConnectorClient.createConnector(tpsHost, tpsPort);
+
+ MainCLI.printMessage("Added TPS connector \""+tpsHost + ":" + tpsPort +"\"");
+ }
+
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorCLI.java b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorCLI.java
new file mode 100644
index 000000000..7a87c3428
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorCLI.java
@@ -0,0 +1,94 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools.system;
+
+import java.util.Arrays;
+
+import org.jboss.resteasy.plugins.providers.atom.Link;
+
+import com.netscape.certsrv.system.TPSConnectorClient;
+import com.netscape.certsrv.system.TPSConnectorData;
+import com.netscape.cmstools.cli.CLI;
+
+/**
+ * @author Ade Lee
+ */
+public class TPSConnectorCLI extends CLI {
+
+ public TPSConnectorClient tpsConnectorClient;
+
+ public TPSConnectorCLI(CLI parent) {
+ super("tpsconnector", "TPS Connector management commands", parent);
+
+ addModule(new TPSConnectorAddCLI(this));
+ addModule(new TPSConnectorFindCLI(this));
+ addModule(new TPSConnectorRemoveCLI(this));
+ }
+
+ public String getFullName() {
+ return parent.getFullName() + "-" + name;
+ }
+
+ public void execute(String[] args) throws Exception {
+
+ client = parent.getClient();
+ tpsConnectorClient = (TPSConnectorClient)parent.getClient("tpsconnector");
+
+ if (tpsConnectorClient == null) {
+ // if parent doesn't have user client then create a new one
+ tpsConnectorClient = new TPSConnectorClient(client);
+ }
+
+ if (args.length == 0) {
+ printHelp();
+ System.exit(1);
+ }
+
+ String command = args[0];
+ String[] commandArgs = Arrays.copyOfRange(args, 1, args.length);
+
+ if (command == null) {
+ printHelp();
+ System.exit(1);
+ }
+
+ CLI module = getModule(command);
+ if (module != null) {
+ module.execute(commandArgs);
+
+ } else {
+ System.err.println("Error: Invalid command \""+command+"\"");
+ printHelp();
+ System.exit(1);
+ }
+ }
+
+ public static void printConnectorInfo(TPSConnectorData data) {
+ System.out.println(" Connector ID: " + data.getID());
+ if (data.getHost() != null) System.out.println(" Host: " + data.getHost());
+ if (data.getPort() != null) System.out.println(" Port: " + data.getPort());
+ if (data.getUserID() != null) System.out.println(" User ID: " + data.getUserID());
+ if (data.getNickname() != null) System.out.println(" Nickname: " + data.getNickname());
+
+ Link link = data.getLink();
+ if (verbose && link != null) {
+ System.out.println(" Link: " + link.getHref());
+ }
+ }
+
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorFindCLI.java b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorFindCLI.java
new file mode 100644
index 000000000..0a42b7d3f
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorFindCLI.java
@@ -0,0 +1,88 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools.system;
+
+import java.util.Collection;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+
+import com.netscape.certsrv.system.TPSConnectorCollection;
+import com.netscape.certsrv.system.TPSConnectorData;
+import com.netscape.cmstools.cli.CLI;
+
+/**
+ * @author Ade Lee
+ */
+public class TPSConnectorFindCLI extends CLI {
+ public TPSConnectorCLI tpsConnectorCLI;
+
+ public TPSConnectorFindCLI(TPSConnectorCLI tpsConnectorCLI) {
+ super("find", "Find TPS connector details on TKS", tpsConnectorCLI);
+ this.tpsConnectorCLI = tpsConnectorCLI;
+ }
+
+ public void printHelp() {
+ formatter.printHelp(getFullName() + " [OPTIONS...]", options);
+ }
+
+ public void execute(String[] args) throws Exception {
+ Option option = new Option(null, "host", true, "TPS host");
+ option.setArgName("host");
+ options.addOption(option);
+
+ option = new Option(null, "port", true, "TPS port");
+ option.setArgName("port");
+ options.addOption(option);
+
+ CommandLine cmd = null;
+
+ try {
+ cmd = parser.parse(options, args);
+
+ } catch (Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ printHelp();
+ System.exit(1);
+ }
+
+ String tpsHost = cmd.getOptionValue("host");
+ String tpsPort = cmd.getOptionValue("port");
+
+ if (tpsHost != null) {
+ if (tpsPort == null) tpsPort = "443";
+ TPSConnectorData data = tpsConnectorCLI.tpsConnectorClient.getConnector(
+ tpsHost, tpsPort);
+ TPSConnectorCLI.printConnectorInfo(data);
+ } else {
+ TPSConnectorCollection result = tpsConnectorCLI.tpsConnectorClient.listConnectors();
+ Collection<TPSConnectorData> conns = result.getEntries();
+
+ boolean first = true;
+ for (TPSConnectorData data: conns) {
+ if (first) {
+ first = false;
+ } else {
+ System.out.println();
+ }
+
+ TPSConnectorCLI.printConnectorInfo(data);
+ }
+ }
+ }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorRemoveCLI.java b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorRemoveCLI.java
new file mode 100644
index 000000000..f721fe28f
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/system/TPSConnectorRemoveCLI.java
@@ -0,0 +1,53 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmstools.system;
+
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+/**
+ * @author Ade Lee
+ */
+public class TPSConnectorRemoveCLI extends CLI {
+ public TPSConnectorCLI tpsConnectorCLI;
+
+ public TPSConnectorRemoveCLI(TPSConnectorCLI tpsConnectorCLI) {
+ super("del", "Remove TPS connector from TKS", tpsConnectorCLI);
+ this.tpsConnectorCLI = tpsConnectorCLI;
+ }
+
+ public void printHelp() {
+ formatter.printHelp(getFullName() + " <TPS Host> <TPS Port>", options);
+ }
+
+ public void execute(String[] args) throws Exception {
+
+ if (args.length != 2) {
+ printHelp();
+ System.exit(1);
+ }
+
+ String tpsHost = args[0];
+ String tpsPort = args[1];
+
+ tpsConnectorCLI.tpsConnectorClient.deleteConnector(tpsHost, tpsPort);
+
+ MainCLI.printMessage("Removed TPS connector \""+tpsHost + ":" + tpsPort +"\"");
+ }
+
+}
diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg
index d8ca7fe1f..88f9f780c 100644
--- a/base/server/etc/default.cfg
+++ b/base/server/etc/default.cfg
@@ -551,6 +551,7 @@ pki_ca_uri=https://%(pki_hostname)s:%(pki_https_port)s
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
# 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 9257cbfb8..ce800471b 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -2721,6 +2721,129 @@ class KRAConnector:
# and this will raise an exception
subprocess.check_output(command,stderr=subprocess.STDOUT)
+class TPSConnector:
+ """PKI Deployment TPS Connector Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+ self.password = deployer.password
+
+ def deregister(self, critical_failure=False):
+ try:
+ # this is applicable to TPSs only
+ if self.master_dict['pki_subsystem_type'] != "tps":
+ return
+
+ config.pki_log.info(
+ log.PKIHELPER_TPSCONNECTOR_UPDATE_CONTACT,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ cs_cfg = PKIConfigParser.read_simple_configuration_file(
+ self.master_dict['pki_target_cs_cfg'])
+ tpshost = cs_cfg.get('service.machineName')
+ tpsport = cs_cfg.get('pkicreate.secure_port')
+ tkshostport = cs_cfg.get('conn.tks1.hostport')
+ if tkshostport is None:
+ config.pki_log.warning(
+ log.PKIHELPER_TPSCONNECTOR_UPDATE_FAILURE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_TKS_HOST_PORT,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_UNDEFINED_TKS_HOST_PORT)
+ else:
+ return
+
+ #retrieve tks host and port
+ if ':' in tkshostport:
+ tkshost = tkshostport.split(':')[0]
+ tksport = tkshostport.split(':')[1]
+ else:
+ tkshost = tkshostport
+ tksport = '443'
+
+ # retrieve subsystem nickname
+ subsystemnick = cs_cfg.get('tps.cert.subsystem.nickname')
+ if subsystemnick is None:
+ config.pki_log.warning(
+ log.PKIHELPER_TPSCONNECTOR_UPDATE_FAILURE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_SUBSYSTEM_NICKNAME,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_UNDEFINED_SUBSYSTEM_NICKNAME)
+ else:
+ return
+
+ # retrieve name of token based upon type (hardware/software)
+ if ':' in subsystemnick:
+ token_name = subsystemnick.split(':')[0]
+ else:
+ token_name = "internal"
+
+ token_pwd = self.password.get_password(
+ self.master_dict['pki_shared_password_conf'],
+ token_name,
+ critical_failure)
+
+ if token_pwd is None or token_pwd == '':
+ config.pki_log.warning(
+ log.PKIHELPER_TPSCONNECTOR_UPDATE_FAILURE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_TOKEN_PASSWD_1,
+ token_name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_UNDEFINED_TOKEN_PASSWD_1 % token_name)
+ else:
+ return
+
+ self.execute_using_pki(tkshost, tksport, subsystemnick,
+ token_pwd, tpshost, tpsport)
+
+ except subprocess.CalledProcessError as exc:
+ config.pki_log.warning(
+ log.PKIHELPER_TPSCONNECTOR_UPDATE_FAILURE_2,
+ str(tkshost),
+ str(tksport),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def execute_using_pki(self, tkshost, tksport, subsystemnick,
+ token_pwd, tpshost, tpsport, critical_failure=False):
+ command = ["/bin/pki",
+ "-p", str(tksport),
+ "-h", tkshost,
+ "-n", subsystemnick,
+ "-P", "https",
+ "-d", self.master_dict['pki_database_path'],
+ "-c", token_pwd,
+ "-t", "tks",
+ "tks-tpsconnector-del", tpshost, str(tpsport)]
+
+ output = subprocess.check_output(command,
+ stderr=subprocess.STDOUT,
+ shell=False)
+
+ error = re.findall("ClientResponseFailure:(.*?)", output)
+ if error:
+ config.pki_log.warning(
+ log.PKIHELPER_TPSCONNECTOR_UPDATE_FAILURE_2,
+ str(tpshost),
+ str(tpsport),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, output,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_SUBPROCESS_ERROR_1 % output)
+
class SecurityDomain:
"""PKI Deployment Security Domain Class"""
@@ -3498,6 +3621,7 @@ class ConfigClient:
data.authdbPort = self.master_dict['pki_authdb_port']
data.authdbBaseDN = self.master_dict['pki_authdb_basedn']
data.authdbSecureConn = self.master_dict['pki_authdb_secure_conn']
+ data.importSharedSecret = self.master_dict['pki_import_shared_secret']
def create_system_cert(self, tag):
cert = pki.system.SystemCertData()
@@ -3549,6 +3673,7 @@ class PKIDeployer:
self.kra_connector = KRAConnector(self)
self.security_domain = SecurityDomain(self)
self.systemd = Systemd(self)
+ self.tps_connector = TPSConnector(self)
self.config_client = ConfigClient(self)
diff --git a/base/server/python/pki/server/deployment/pkimessages.py b/base/server/python/pki/server/deployment/pkimessages.py
index a3be42e97..339ee149e 100644
--- a/base/server/python/pki/server/deployment/pkimessages.py
+++ b/base/server/python/pki/server/deployment/pkimessages.py
@@ -272,6 +272,10 @@ PKIHELPER_TOMCAT_INSTANCE_SUBSYSTEMS_2 = "instance '%s' contains '%d' "\
PKIHELPER_TOMCAT_INSTANCES_2 = "PKI Tomcat registry '%s' contains '%d' "\
"Tomcat PKI instances"
PKIHELPER_TOUCH_1 = "touch %s"
+PKIHELPER_TPSCONNECTOR_UPDATE_CONTACT = \
+ "contacting the TKS to update the TPS connector"
+PKIHELPER_TPSCONNECTOR_UPDATE_FAILURE = "Failed to update TPS connector on TKS"
+PKIHELPER_TPSCONNECTOR_UPDATE_FAILURE_2 = "Failed to update TPS connector for %s:%s"
PKIHELPER_UID_2 = "UID of '%s' is %s"
PKIHELPER_UNDEFINED_CA_HOST_PORT = "CA Host or Port is undefined"
PKIHELPER_UNDEFINED_CLIENT_DATABASE_PASSWORD_2 = \
@@ -280,6 +284,7 @@ PKIHELPER_UNDEFINED_CLIENT_DATABASE_PASSWORD_2 = \
PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 = \
"A value for '%s' MUST be defined in '%s'"
PKIHELPER_UNDEFINED_SUBSYSTEM_NICKNAME = "subsystem nickname not defined"
+PKIHELPER_UNDEFINED_TKS_HOST_PORT = "TKS Host or Port is undefined"
PKIHELPER_UNDEFINED_TOKEN_PASSWD_1 = "Password for token '%s' not defined"
PKIHELPER_USER_1 = "retrieving UID for '%s' . . ."
PKIHELPER_USER_ADD_2 = "adding UID '%s' for user '%s' . . ."
diff --git a/base/server/python/pki/server/deployment/scriptlets/initialization.py b/base/server/python/pki/server/deployment/scriptlets/initialization.py
index 54349fc01..ecfb4d195 100644
--- a/base/server/python/pki/server/deployment/scriptlets/initialization.py
+++ b/base/server/python/pki/server/deployment/scriptlets/initialization.py
@@ -99,6 +99,9 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
# remove kra connector from CA if this is a KRA
deployer.kra_connector.deregister()
+ # remove tps connector from TKS if this is a TPS
+ deployer.tps_connector.deregister()
+
# de-register instance from its Security Domain
#
# NOTE: Since the security domain of an instance must be up
diff --git a/base/tks/src/com/netscape/tks/TKSApplication.java b/base/tks/src/com/netscape/tks/TKSApplication.java
index b2d43ae87..1ec0576e4 100644
--- a/base/tks/src/com/netscape/tks/TKSApplication.java
+++ b/base/tks/src/com/netscape/tks/TKSApplication.java
@@ -16,6 +16,7 @@ import com.netscape.cms.servlet.admin.UserCertService;
import com.netscape.cms.servlet.admin.UserMembershipService;
import com.netscape.cms.servlet.admin.UserService;
import com.netscape.cms.servlet.csadmin.SystemConfigService;
+import com.netscape.cms.servlet.tks.TPSConnectorService;
public class TKSApplication extends Application {
@@ -40,6 +41,9 @@ public class TKSApplication extends Application {
// system certs
classes.add(SystemCertService.class);
+ // tps connections and shared secrets
+ classes.add(TPSConnectorService.class);
+
// exception mapper
classes.add(PKIException.Mapper.class);
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
index 5957f046d..c8941777d 100644
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
@@ -42,6 +42,8 @@ import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.Vector;
+import javax.crypto.SecretKey;
+
import netscape.security.pkcs.PKCS10;
import netscape.security.pkcs.PKCS7;
import netscape.security.util.BigInt;
@@ -68,6 +70,7 @@ import netscape.security.x509.X509Key;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.CryptoManager.NotInitializedException;
import org.mozilla.jss.NoSuchTokenException;
+import org.mozilla.jss.SecretDecoderRing.KeyManager;
import org.mozilla.jss.asn1.ASN1Util;
import org.mozilla.jss.asn1.BIT_STRING;
import org.mozilla.jss.asn1.InvalidBERException;
@@ -95,12 +98,14 @@ 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.SecretKeyFacade;
import org.mozilla.jss.crypto.Signature;
import org.mozilla.jss.crypto.SignatureAlgorithm;
import org.mozilla.jss.crypto.SymmetricKey;
import org.mozilla.jss.crypto.TokenException;
import org.mozilla.jss.crypto.X509Certificate;
import org.mozilla.jss.pkcs11.PK11ECPublicKey;
+import org.mozilla.jss.pkcs11.PK11PubKey;
import org.mozilla.jss.pkcs12.PasswordConverter;
import org.mozilla.jss.pkcs7.EncryptedContentInfo;
import org.mozilla.jss.pkix.crmf.CertReqMsg;
@@ -1639,6 +1644,78 @@ public class CryptoUtil {
return encoded;
}
+ public static boolean sharedSecretExists(String nickname) throws NotInitializedException, TokenException {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ KeyManager km = new KeyManager(token);
+ return km.uniqueNamedKeyExists(nickname);
+ }
+
+ public static void createSharedSecret(String nickname) throws NotInitializedException, TokenException {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ KeyManager km = new KeyManager(token);
+ km.generateUniqueNamedKey(nickname);
+ }
+
+ public static void deleteSharedSecret(String nickname) throws NotInitializedException, TokenException,
+ InvalidKeyException {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ KeyManager km = new KeyManager(token);
+ km.deleteUniqueNamedKey(nickname);
+ }
+
+ public static byte[] exportSharedSecret(String nickname, java.security.cert.X509Certificate wrappingCert)
+ throws NotInitializedException, TokenException, IOException, NoSuchAlgorithmException, InvalidKeyException,
+ InvalidAlgorithmParameterException, InvalidKeyFormatException {
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ KeyManager km = new KeyManager(token);
+ if (!km.uniqueNamedKeyExists(nickname)) {
+ throw new IOException("Shared secret " + nickname + " does not exist");
+ }
+ SecretKey skey = km.lookupUniqueNamedKey(EncryptionAlgorithm.DES3_ECB, nickname);
+
+ KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.RSA);
+ PublicKey pub = wrappingCert.getPublicKey();
+ PK11PubKey pubK = PK11PubKey.fromSPKI(pub.getEncoded());
+ keyWrap.initWrap(pubK, null);
+ byte[] wrappedKey = keyWrap.wrap(((SecretKeyFacade) skey).key);
+ return wrappedKey;
+ }
+
+ /*
+ public static void importSharedSecret(KeyData data) throws EBaseException, NotInitializedException, TokenException,
+ NoSuchAlgorithmException, ObjectNotFoundException, InvalidKeyException, InvalidAlgorithmParameterException,
+ IOException {
+ byte[] wrappedKey = Utils.base64decode(data.getWrappedPrivateData());
+
+ IConfigStore cs = CMS.getConfigStore();
+ String subsystemNick = cs.getString("tps.cert.subsystem.nickname");
+ String keyNick = cs.getString("conn.tks1.tksSharedSymKeyName", "sharedSecret");
+
+ CryptoManager cm = CryptoManager.getInstance();
+ CryptoToken token = cm.getInternalKeyStorageToken();
+ KeyManager km = new KeyManager(token);
+
+ if (km.uniqueNamedKeyExists(keyNick)) {
+ throw new IOException("Shared secret " + keyNick + " already exists");
+ }
+
+ KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.RSA);
+ X509Certificate cert = cm.findCertByNickname(subsystemNick);
+ PrivateKey subsystemPrivateKey = cm.findPrivKeyByCert(cert);
+ keyWrap.initUnwrap(subsystemPrivateKey, null);
+
+ @SuppressWarnings("unused")
+ SymmetricKey unwrapped = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES,
+ SymmetricKey.Usage.DECRYPT, 0);
+
+ // TODO - I have a key - now what to do with it?
+ // need to somehow import/label the symkey
+ }*/
+
public static String[] getECcurves() {
return ecCurves;
}
@@ -1667,7 +1744,6 @@ public class CryptoUtil {
}
}
-
// START ENABLE_ECC
// This following can be removed when JSS with ECC capability
// is integrated.