diff options
9 files changed, 435 insertions, 197 deletions
diff --git a/base/common/src/com/netscape/certsrv/key/KeyData.java b/base/common/src/com/netscape/certsrv/key/KeyData.java index 6da4d38ec..e31cfb3e7 100644 --- a/base/common/src/com/netscape/certsrv/key/KeyData.java +++ b/base/common/src/com/netscape/certsrv/key/KeyData.java @@ -48,7 +48,11 @@ public class KeyData { @XmlElement Integer size; - String privateData; + @XmlElement + String additionalWrappedPrivateData; + // Optionally used for importing a shared secret from TKS to TPS + // Will contain wrapped shared secret data. + // Can be used for anything in other scenarios public KeyData() { // required for JAXB (defaults) @@ -68,6 +72,15 @@ public class KeyData { this.wrappedPrivateData = wrappedPrivateData; } + public String getAdditionalWrappedPrivateData() { + return additionalWrappedPrivateData; + } + + + public void setAdditionalWrappedPrivateData(String additionalWrappedPrivateData) { + this.additionalWrappedPrivateData = additionalWrappedPrivateData; + } + /** * @return the nonceData */ @@ -126,11 +139,5 @@ public class KeyData { this.size = size; } - public String getPrivateData() { - return privateData; - } - public void setPrivateData(String privateData) { - this.privateData = privateData; - } } 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 308f3e7f8..ab5e4d63d 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 @@ -15,7 +15,7 @@ // (C) 2012 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- - package com.netscape.cms.servlet.csadmin; +package com.netscape.cms.servlet.csadmin; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -58,6 +58,34 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; 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.PKCS12; +import netscape.security.pkcs.PKCS12Util; +import netscape.security.pkcs.PKCS7; +import netscape.security.pkcs.SignerInfo; +import netscape.security.util.DerOutputStream; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.AlgorithmId; +import netscape.security.x509.BasicConstraintsExtension; +import netscape.security.x509.CertificateChain; +import netscape.security.x509.Extension; +import netscape.security.x509.Extensions; +import netscape.security.x509.KeyUsageExtension; +import netscape.security.x509.X500Name; +import netscape.security.x509.X509CertImpl; +import netscape.security.x509.X509Key; + import org.apache.commons.lang.StringUtils; import org.apache.velocity.context.Context; import org.mozilla.jss.CryptoManager; @@ -149,36 +177,9 @@ import com.netscape.certsrv.usrgrp.IUGSubsystem; import com.netscape.certsrv.usrgrp.IUser; import com.netscape.cmsutil.crypto.CryptoUtil; import com.netscape.cmsutil.ldap.LDAPUtil; +import com.netscape.cmsutil.util.Utils; import com.netscape.cmsutil.xml.XMLObject; -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.PKCS12; -import netscape.security.pkcs.PKCS12Util; -import netscape.security.pkcs.PKCS7; -import netscape.security.pkcs.SignerInfo; -import netscape.security.util.DerOutputStream; -import netscape.security.util.ObjectIdentifier; -import netscape.security.x509.AlgorithmId; -import netscape.security.x509.BasicConstraintsExtension; -import netscape.security.x509.CertificateChain; -import netscape.security.x509.Extension; -import netscape.security.x509.Extensions; -import netscape.security.x509.KeyUsageExtension; -import netscape.security.x509.X500Name; -import netscape.security.x509.X509CertImpl; -import netscape.security.x509.X509Key; - /** * Utility class for functions to be used by the RESTful installer. * @@ -377,7 +378,7 @@ public class ConfigurationUtils { if (eqPos != -1) { String name = line.substring(0, eqPos).trim(); String tempval = line.substring(eqPos + 1).trim(); - String value = tempval.replaceAll("(^\")|(\";$)",""); + String value = tempval.replaceAll("(^\")|(\";$)", ""); if (name.equals(header)) { return value; @@ -634,7 +635,7 @@ public class ConfigurationUtils { throw new IOException("The server you want to contact is not available"); } - CMS.debug("content from admin interface ="+ c); + CMS.debug("content from admin interface =" + c); // when the admin servlet is unavailable, we return a badly formatted error page // in that case, this will throw an exception and be passed into the catch block. parser = new XMLObject(new ByteArrayInputStream(c.getBytes())); @@ -685,8 +686,7 @@ public class ConfigurationUtils { public static boolean updateConfigEntries(String hostname, int port, boolean https, String servlet, MultivaluedMap<String, String> content, IConfigStore config) - throws Exception { - + throws Exception { CMS.debug("updateConfigEntries start"); String c = post(hostname, port, https, servlet, content, null, null); @@ -892,7 +892,8 @@ public class ConfigurationUtils { // pkeyinfo_v stores private key (PrivateKeyInfo) and subject DN (String) Vector<Object> pkeyinfo_v = new Vector<Object>(); pkeyinfo_v.addElement(pkeyinfo); - if (subjectDN != null) pkeyinfo_v.addElement(subjectDN); + if (subjectDN != null) + pkeyinfo_v.addElement(subjectDN); pkeyinfo_collection.addElement(pkeyinfo_v); @@ -941,7 +942,8 @@ public class ConfigurationUtils { // cert_v stores certificate (byte[]) and nickname (String) Vector<Object> cert_v = new Vector<Object>(); cert_v.addElement(x509cert); - if (nickname != null) cert_v.addElement(nickname); + if (nickname != null) + cert_v.addElement(nickname); cert_collection.addElement(cert_v); } @@ -992,10 +994,11 @@ public class ConfigurationUtils { 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 { + ) throws IOException, CertificateException, TokenException, + NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, + IllegalStateException, + IllegalBlockSizeException, BadPaddingException, NotInitializedException, NicknameConflictException, + UserCertConflictException, NoSuchItemOnTokenException, EPropertyNotFound, EBaseException { CMS.debug("ConfigurationUtils.importKeyCert()"); CryptoManager cm = CryptoManager.getInstance(); @@ -1069,7 +1072,7 @@ public class ConfigurationUtils { String name = (String) cert_v.elementAt(1); CMS.debug("- Certificate: " + name); - if (! masterList.contains(name)) { + if (!masterList.contains(name)) { CMS.debug(" Certificate not in master list, ignore certificate"); continue; } @@ -1160,10 +1163,11 @@ public class ConfigurationUtils { return true; try { X500Name xname = new X500Name(nickname); - for (String key: masterList) { + for (String key : masterList) { try { X500Name xkey = new X500Name(key); - if (xkey.equals(xname)) return true; + if (xkey.equals(xname)) + return true; } catch (IOException e) { // xkey not an X500Name } @@ -1216,10 +1220,12 @@ public class ConfigurationUtils { 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; + if (nickname.equals(name)) + return true; return false; } @@ -1271,7 +1277,7 @@ public class ConfigurationUtils { while (st.hasMoreTokens()) { String s = st.nextToken(); if (s.equals("sslserver")) - continue; + continue; String name = "preop.master." + s + ".nickname"; String nickname = cs.getString(name); list.add(nickname); @@ -1293,14 +1299,16 @@ public class ConfigurationUtils { X509CertImpl impl = null; impl = new X509CertImpl(b); Principal subjectdn = impl.getSubjectDN(); - if (LDAPDN.equals(subjectdn.toString(), nickname)) return b; + if (LDAPDN.equals(subjectdn.toString(), nickname)) + return b; } return null; } public static void releaseConnection(LDAPConnection conn) { try { - if (conn != null) conn.disconnect(); + if (conn != null) + conn.disconnect(); } catch (LDAPException e) { CMS.debug(e); CMS.debug("releaseConnection: " + e); @@ -1551,14 +1559,15 @@ public class ConfigurationUtils { LDAPSearchResults res = conn.search( "cn=mapping tree, cn=config", LDAPConnection.SCOPE_ONE, "nsslapd-backend=" + LDAPUtil.escapeFilter(database), - null, false, (LDAPSearchConstraints)null); + null, false, (LDAPSearchConstraints) null); while (res.hasMoreElements()) { LDAPEntry entry = res.next(); LDAPAttribute cn = entry.getAttribute("cn"); String dn = cn.getStringValueArray()[0]; - if (LDAPDN.equals(baseDN, dn)) continue; + if (LDAPDN.equals(baseDN, dn)) + continue; CMS.debug("confirmMappings: Database " + database + " is used by " + dn + "."); throw new EBaseException("The database (" + database + ") is used by another base DN. " + @@ -1646,12 +1655,12 @@ public class ConfigurationUtils { private static void checkParentExists(String baseDN, LDAPConnection conn) throws EBaseException { String[] dns = LDAPDN.explodeDN(baseDN, false); - if (dns.length == 1 ) { + if (dns.length == 1) { CMS.debug("checkParentExists: no parent in baseDN: " + baseDN); throw new EBaseException("Invalid BaseDN. No parent DN in " + baseDN); } String parentDN = Arrays.toString(Arrays.copyOfRange(dns, 1, dns.length)); - parentDN = parentDN.substring(1,parentDN.length() -1); + parentDN = parentDN.substring(1, parentDN.length() - 1); try { CMS.debug("checkParentExists: Checking parent " + parentDN + "."); conn.read(parentDN); @@ -1666,11 +1675,13 @@ public class ConfigurationUtils { } } - public static void importLDIFS(String param, LDAPConnection conn) throws EPropertyNotFound, IOException, EBaseException { + public static void importLDIFS(String param, LDAPConnection conn) throws EPropertyNotFound, IOException, + EBaseException { importLDIFS(param, conn, true); } - public static void importLDIFS(String param, LDAPConnection conn, boolean suppressErrors) throws IOException, EPropertyNotFound, + public static void importLDIFS(String param, LDAPConnection conn, boolean suppressErrors) throws IOException, + EPropertyNotFound, EBaseException { IConfigStore cs = CMS.getConfigStore(); @@ -1764,7 +1775,7 @@ public class ConfigurationUtils { try { LDAPSearchResults res = conn.search( dn, LDAPConnection.SCOPE_BASE, "objectclass=*", - null, true, (LDAPSearchConstraints)null); + null, true, (LDAPSearchConstraints) null); deleteEntries(res, conn, excludedDNs); } catch (LDAPException e) { @@ -1777,14 +1788,15 @@ public class ConfigurationUtils { } } - public static void deleteEntries(LDAPSearchResults res, LDAPConnection conn, String[] excludedDNs) throws LDAPException { + public static void deleteEntries(LDAPSearchResults res, LDAPConnection conn, String[] excludedDNs) + throws LDAPException { while (res.hasMoreElements()) { LDAPEntry entry = res.next(); String dn = entry.getDN(); LDAPSearchResults res1 = conn.search( dn, 1, "objectclass=*", - null, true, (LDAPSearchConstraints)null); + null, true, (LDAPSearchConstraints) null); deleteEntries(res1, conn, excludedDNs); deleteEntry(conn, dn, excludedDNs); } @@ -1792,7 +1804,8 @@ public class ConfigurationUtils { public static void deleteEntry(LDAPConnection conn, String dn, String[] excludedDNs) throws LDAPException { for (String excludedDN : excludedDNs) { - if (!LDAPDN.equals(dn, excludedDN)) continue; + if (!LDAPDN.equals(dn, excludedDN)) + continue; CMS.debug("deleteEntry: entry with this dn " + dn + " is not deleted."); return; @@ -1997,7 +2010,7 @@ public class ConfigurationUtils { String status = replicationStatus(replicadn, masterConn, masterAgreementName); if (!status.startsWith("0 ")) { - CMS.debug("setupReplication: consumer initialization failed. " +status); + CMS.debug("setupReplication: consumer initialization failed. " + status); throw new IOException("consumer initialization failed. " + status); } @@ -2015,7 +2028,7 @@ public class ConfigurationUtils { releaseConnection(masterConn); releaseConnection(replicaConn); } -} + } public static void createReplicationManager(LDAPConnection conn, String bindUser, String pwd) throws LDAPException { @@ -2277,7 +2290,8 @@ public class ConfigurationUtils { CMS.reinit(IUGSubsystem.ID); } - public static void setExternalCACert(String certStr, String subsystem, IConfigStore config, Cert certObj) throws Exception { + public static void setExternalCACert(String certStr, String subsystem, IConfigStore config, Cert certObj) + throws Exception { certStr = CryptoUtil.stripCertBrackets(certStr.trim()); certStr = CryptoUtil.normalizeCertStr(certStr); config.putString(subsystem + ".external_ca.cert", certStr); @@ -2365,7 +2379,8 @@ public class ConfigurationUtils { String sslType = "ECDHE"; try { sslType = config.getString(PCERT_PREFIX + ct + "ec.type", "ECDHE"); - } catch (Exception e) {} + } catch (Exception e) { + } // ECDHE needs "SIGN" but no "DERIVE" org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask[] = { @@ -2380,13 +2395,15 @@ public class ConfigurationUtils { do { if (ct.equals("sslserver") && sslType.equalsIgnoreCase("ECDH")) { - CMS.debug("ConfigurationUtils: 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"); + CMS.debug("ConfigurationUtils: 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("ConfigurationUtils: 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"); + CMS.debug("ConfigurationUtils: 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); } @@ -2443,7 +2460,8 @@ public class ConfigurationUtils { setSigningAlgorithm(ct, keyAlgo, config); } - public static void setSigningAlgorithm(String ct, String keyAlgo, IConfigStore config) throws EPropertyNotFound, EBaseException { + 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")) { @@ -2523,16 +2541,16 @@ public class ConfigurationUtils { // retrieve and store original 'CS.cfg' entries preop_ca_type = config.getString("preop.ca.type", ""); preop_cert_signing_type = config.getString("preop.cert.signing.type", ""); - preop_cert_signing_profile = config.getString("preop.cert.signing.profile",""); + preop_cert_signing_profile = config.getString("preop.cert.signing.profile", ""); preop_cert_sslserver_type = config.getString("preop.cert.sslserver.type", ""); - preop_cert_sslserver_profile = config.getString("preop.cert.sslserver.profile",""); + preop_cert_sslserver_profile = config.getString("preop.cert.sslserver.profile", ""); // add/modify 'CS.cfg' entries config.putString("preop.ca.type", "sdca"); config.putString("preop.cert.signing.type", "remote"); - config.putString("preop.cert.signing.profile","caInstallCACert"); + config.putString("preop.cert.signing.profile", "caInstallCACert"); config.putString("preop.cert.sslserver.type", "remote"); - config.putString("preop.cert.sslserver.profile","caInternalAuthServerCert"); + config.putString("preop.cert.sslserver.profile", "caInternalAuthServerCert"); // store original caType original_caType = caType; @@ -2568,7 +2586,7 @@ public class ConfigurationUtils { if (standalone) { // Treat standalone subsystem the same as "otherca" config.putString(subsystem + "." + certTag + ".cert", - "...paste certificate here..."); + "...paste certificate here..."); } else { String sd_hostname = config.getString("securitydomain.host", ""); @@ -2594,8 +2612,8 @@ public class ConfigurationUtils { try { if (sign_clone_sslserver_cert_using_master) { CMS.debug("ConfigurationUtils: For this Cloned CA, always use its Master CA to generate " + - "the 'sslserver' certificate to avoid any changes which may have been " + - "made to the X500Name directory string encoding order."); + "the 'sslserver' certificate to avoid any changes which may have been " + + "made to the X500Name directory string encoding order."); ca_hostname = config.getString("preop.master.hostname", ""); ca_port = config.getInteger("preop.master.httpsport", -1); } else { @@ -2607,12 +2625,12 @@ public class ConfigurationUtils { String sslserver_extension = ""; Boolean injectSAN = config.getBoolean( - "service.injectSAN", false); - CMS.debug("ConfigurationUtils: injectSAN="+injectSAN); + "service.injectSAN", false); + CMS.debug("ConfigurationUtils: injectSAN=" + injectSAN); if (certTag.equals("sslserver") && - injectSAN == true) { + injectSAN == true) { sslserver_extension = - CertUtil.buildSANSSLserverURLExtension(config); + CertUtil.buildSANSSLserverURLExtension(config); } MultivaluedMap<String, String> content = new MultivaluedHashMap<String, String>(); @@ -3115,7 +3133,8 @@ public class ConfigurationUtils { IConfigStore config = CMS.getConfigStore(); boolean enable = config.getBoolean(PCERT_PREFIX + certTag + ".enable", true); - if (!enable) return 0; + if (!enable) + return 0; CMS.debug("handleCerts(): for cert tag '" + cert.getCertTag() + "' using cert type '" + cert.getType() + "'"); String b64 = cert.getCert(); @@ -3131,7 +3150,8 @@ public class ConfigurationUtils { } if (findCertificate(tokenname, nickname)) { - if (!certTag.equals("sslserver")) return 0; + if (!certTag.equals("sslserver")) + return 0; } X509CertImpl impl = CertUtil.createLocalCert(config, x509key, PCERT_PREFIX, certTag, cert.getType(), null); @@ -3156,7 +3176,8 @@ public class ConfigurationUtils { CMS.debug("handleCerts(): cert imported for certTag '" + certTag + "'"); } catch (Exception ee) { CMS.debug(ee); - CMS.debug("handleCerts(): import certificate for certTag=" + certTag + " Exception: " + ee.toString()); + CMS.debug("handleCerts(): import certificate for certTag=" + certTag + " Exception: " + + ee.toString()); } } } else if (cert.getType().equals("remote")) { @@ -3216,7 +3237,7 @@ public class ConfigurationUtils { CMS.debug("handleCerts(): import certificate successfully, certTag=" + certTag); } catch (Exception ee) { ee.printStackTrace(); - CMS.debug("handleCerts: import certificate for certTag=" + certTag + " Exception: "+ ee.toString()); + CMS.debug("handleCerts: import certificate for certTag=" + certTag + " Exception: " + ee.toString()); } } else { @@ -3268,7 +3289,8 @@ public class ConfigurationUtils { public static void setCertPermissions(String tag) throws EBaseException, NotInitializedException, ObjectNotFoundException, TokenException { - if (tag.equals("signing") || tag.equals("external_signing")) return; + if (tag.equals("signing") || tag.equals("external_signing")) + return; IConfigStore cs = CMS.getConfigStore(); String nickname = cs.getString("preop.cert." + tag + ".nickname", ""); @@ -3327,7 +3349,6 @@ public class ConfigurationUtils { return true; } - public static boolean findBootstrapServerCert() throws EBaseException, NotInitializedException, TokenException { IConfigStore cs = CMS.getConfigStore(); @@ -3342,7 +3363,8 @@ public class ConfigurationUtils { } Principal issuerDN = cert.getIssuerDN(); Principal subjectDN = cert.getSubjectDN(); - if (issuerDN.equals(subjectDN)) return true; + if (issuerDN.equals(subjectDN)) + return true; return false; } @@ -3473,7 +3495,8 @@ public class ConfigurationUtils { } public static byte[] addCertBag(X509Certificate x509cert, String nickname, - SEQUENCE safeContents) throws CertificateEncodingException, NoSuchAlgorithmException, CharConversionException { + SEQUENCE safeContents) throws CertificateEncodingException, NoSuchAlgorithmException, + CharConversionException { byte[] localKeyId = null; ASN1Value cert = new OCTET_STRING(x509cert.getEncoded()); @@ -3636,49 +3659,56 @@ public class ConfigurationUtils { if (select.equals("new")) { group = system.getGroupFromName("Security Domain Administrators"); if (group != null && !group.isMember(uid)) { - CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + "' to group 'Security Domain Administrators'"); + CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + + "' to group 'Security Domain Administrators'"); group.addMemberName(uid); system.modifyGroup(group); } group = system.getGroupFromName("Enterprise CA Administrators"); if (group != null && !group.isMember(uid)) { - CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + "' to group 'Enterprise CA Administrators'"); + CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + + "' to group 'Enterprise CA Administrators'"); group.addMemberName(uid); system.modifyGroup(group); } group = system.getGroupFromName("Enterprise KRA Administrators"); if (group != null && !group.isMember(uid)) { - CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + "' to group 'Enterprise KRA Administrators'"); + CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + + "' to group 'Enterprise KRA Administrators'"); group.addMemberName(uid); system.modifyGroup(group); } group = system.getGroupFromName("Enterprise RA Administrators"); if (group != null && !group.isMember(uid)) { - CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + "' to group 'Enterprise RA Administrators'"); + CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + + "' to group 'Enterprise RA Administrators'"); group.addMemberName(uid); system.modifyGroup(group); } group = system.getGroupFromName("Enterprise TKS Administrators"); if (group != null && !group.isMember(uid)) { - CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + "' to group 'Enterprise TKS Administrators'"); + CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + + "' to group 'Enterprise TKS Administrators'"); group.addMemberName(uid); system.modifyGroup(group); } group = system.getGroupFromName("Enterprise OCSP Administrators"); if (group != null && !group.isMember(uid)) { - CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + "' to group 'Enterprise OCSP Administrators'"); + CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + + "' to group 'Enterprise OCSP Administrators'"); group.addMemberName(uid); system.modifyGroup(group); } group = system.getGroupFromName("Enterprise TPS Administrators"); if (group != null && !group.isMember(uid)) { - CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + "' to group 'Enterprise TPS Administrators'"); + CMS.debug("ConfigurationUtils: createAdmin: add user '" + uid + + "' to group 'Enterprise TPS Administrators'"); group.addMemberName(uid); system.modifyGroup(group); } @@ -3833,7 +3863,7 @@ public class ConfigurationUtils { CMS.debug("Cloning a domain master"); } - String url = "/ca/admin/ca/updateDomainXML"; + String url = "/ca/admin/ca/updateDomainXML"; MultivaluedMap<String, String> content = new MultivaluedHashMap<String, String>(); content.putSingle("list", type + "List"); @@ -3862,7 +3892,7 @@ public class ConfigurationUtils { CMS.debug("Unable to access admin interface: " + e); CMS.debug("Update security domain using agent interface"); - url = "/ca/agent/ca/updateDomainXML"; + url = "/ca/agent/ca/updateDomainXML"; updateDomainXML(sd_host, sd_agent_port, true, url, content, true); } @@ -3903,7 +3933,7 @@ public class ConfigurationUtils { public static void updateDomainXML(String hostname, int port, boolean https, String servlet, MultivaluedMap<String, String> content, boolean useClientAuth) - throws Exception { + throws Exception { CMS.debug("ConfigurationUtils: updateDomainXML start hostname=" + hostname + " port=" + port); @@ -4047,7 +4077,7 @@ public class ConfigurationUtils { try { CMS.debug("setupClientAuthUser: Adding cert to user: " + id); system.addUserCert(user); - } catch(ConflictingOperationException e) { + } catch (ConflictingOperationException e) { // ignore exception CMS.debug("setupClientAuthUser: Cert already added: " + e); } @@ -4121,7 +4151,9 @@ public class ConfigurationUtils { } public static void getSharedSecret(String tksHost, int tksPort, boolean importKey) throws EPropertyNotFound, - EBaseException, URISyntaxException { + EBaseException, URISyntaxException, InvalidKeyException, NoSuchAlgorithmException, + InvalidAlgorithmParameterException, NotInitializedException, TokenException, ObjectNotFoundException, + IOException { IConfigStore cs = CMS.getConfigStore(); String host = cs.getString("service.machineName"); String port = cs.getString("service.securePort"); @@ -4140,6 +4172,8 @@ public class ConfigurationUtils { PKIClient client = new PKIClient(config, null); + CMS.debug("In ConfigurationUtils.getSharedSecret! importKey: " + importKey); + // Ignore the "UNTRUSTED_ISSUER" and "CA_CERT_INVALID" validity status // during PKI instance creation since we are using an untrusted temporary CA cert. client.addIgnoredCertStatus(SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER); @@ -4156,6 +4190,9 @@ public class ConfigurationUtils { // no connector exists data = null; } + + + // The connId or data.getID will be the id of the shared secret KeyData keyData = null; if (data == null) { data = tpsConnectorClient.createConnector(host, port); @@ -4171,14 +4208,24 @@ public class ConfigurationUtils { } accountClient.logout(); + String nick = "TPS-" + host + "-" + port + " sharedSecret"; + if (importKey) { - // TODO - we need code here to import the key into the tps certdb + CMS.debug("getSharedSecret: About to attempt to import shared secret key."); + byte[] sessionKeyData = Utils.base64decode(keyData.getWrappedPrivateData()); + byte[] sharedSecretData = Utils.base64decode(keyData.getAdditionalWrappedPrivateData()); + + try { + CryptoUtil.importSharedSecret(sessionKeyData, sharedSecretData, dbNick, nick); + } catch (Exception e) { + CMS.debug("getSharedSecret()): WARNING, Failed to automatically import shared secret. Please follow the manual procedure." + e.toString()); + } // 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); } @@ -4388,7 +4435,7 @@ public class ConfigurationUtils { if (status.equals(SUCCESS)) { CMS.debug("registerUser: Successfully added user " + uid + " to " + targetURI + - " using " + targetURL); + " using " + targetURL); } else if (status.equals(AUTH_FAILURE)) { throw new EAuthException(AUTH_FAILURE); @@ -4500,7 +4547,6 @@ public class ConfigurationUtils { cs.putString("auths.instance.ldap1.ldap.ldapconn.secureConn", secureConn); } - public static void updateNextRanges() throws EBaseException, LDAPException { IConfigStore cs = CMS.getConfigStore(); @@ -4541,6 +4587,7 @@ public class ConfigurationUtils { /** * save variables needed for cloning and remove preops + * * @throws EBaseException */ public static void removePreopConfigEntries() throws EBaseException { diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java index 7dab14045..9593816a3 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java +++ b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java @@ -418,7 +418,8 @@ public class SecureChannelProtocol { String method = "SecureChannelProtocol.getSharedSecretKeyName:"; CMS.debug(method + " Entering..."); - if (name != null && SecureChannelProtocol.sharedSecretKeyName == null) { + // No longer cache the secret name, there could be a different one for each incoming TPS connection. + if (name != null) { SecureChannelProtocol.sharedSecretKeyName = name; } diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java b/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java index ab2ade958..9c143fd31 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java +++ b/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java @@ -70,6 +70,7 @@ public class TokenServlet extends CMSServlet { public static int ERROR = 1; String mKeyNickName = null; String mNewKeyNickName = null; + String mCurrentUID = null; IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":"); private final static String LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST = @@ -951,8 +952,6 @@ public class TokenServlet extends CMSServlet { transportKeyName = getSharedSecretName(sconfig); - CMS.debug("TokenServlet: ComputeSessionKey(): tksSharedSymKeyName: " + transportKeyName); - String rcard_challenge = req.getParameter(IRemoteRequest.TOKEN_CARD_CHALLENGE); String rhost_challenge = req.getParameter(IRemoteRequest.TOKEN_HOST_CHALLENGE); String rKeyInfo = req.getParameter(IRemoteRequest.TOKEN_KEYINFO); @@ -1537,13 +1536,32 @@ public class TokenServlet extends CMSServlet { if (useNewNames) { String tpsList = cs.getString("tps.list", ""); + String firstSharedSecretName = null; if (!tpsList.isEmpty()) { for (String tpsID : tpsList.split(",")) { String sharedSecretName = cs.getString("tps." + tpsID + ".nickname", ""); + + // This one will be a fall back in case we can't get a specific one + if (firstSharedSecretName == null) { + firstSharedSecretName = sharedSecretName; + } + if (!sharedSecretName.isEmpty()) { - return sharedSecretName; + if (mCurrentUID != null) { + String csUid = cs.getString("tps." + tpsID + ".userid", ""); + + if (mCurrentUID.equalsIgnoreCase(csUid)) { + CMS.debug("TokenServlet.getSharedSecretName: found a match of the user id! " + csUid); + return sharedSecretName; + } + } } } + + if (firstSharedSecretName != null) { + //Return the first in the list if we couldn't isolate one + return firstSharedSecretName; + } } CMS.debug("getSharedSecretName: no shared secret has been configured"); throw new EBaseException("No shared secret has been configured"); @@ -2351,6 +2369,8 @@ public class TokenServlet extends CMSServlet { IAuthToken authToken = authenticate(cmsReq); AuthzToken authzToken = null; + mCurrentUID = (String) authToken.get(IAuthToken.UID) ; + try { authzToken = authorize(mAclMethod, authToken, mAuthzResourceName, "execute"); diff --git a/base/server/man/man8/pkispawn.8 b/base/server/man/man8/pkispawn.8 index 3678cffa6..40ec7f0ad 100644 --- a/base/server/man/man8/pkispawn.8 +++ b/base/server/man/man8/pkispawn.8 @@ -719,10 +719,15 @@ pki_tks_uri=\fIhttps://<tks_hostname>:<tks_https_port>\fP .fi .PP -If TPS and TKS are installed on separate instances the shared secret key needs -to be generated manually in TKS, then manually imported into TPS. +If TPS and TKS are installed on separate instances the shared secret key +should be imported over the wire between the TKS and TPS automatically. -Generate the shared secret key in TKS with the following command: +If the automated procedure fails for any unlikely reason the following +manual procedure will serve as a fallback. The key needs to be created +on the TKS side and imported into the TPS side in this case. + + +Generate the shared secret key (if needed) in TKS with the following command: .IP tkstool -T -d /var/lib/pki/pki-tomcat/alias -n sharedSecret diff --git a/base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java b/base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java index bc655d6d0..a2d18f166 100644 --- a/base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java +++ b/base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java @@ -1,5 +1,6 @@ package org.dogtagpki.server.tks.rest; +import java.io.CharConversionException; import java.io.IOException; import java.net.URI; import java.security.InvalidAlgorithmParameterException; @@ -10,6 +11,7 @@ import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; @@ -20,8 +22,13 @@ import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.jboss.resteasy.plugins.providers.atom.Link; +import org.mozilla.jss.CryptoManager; import org.mozilla.jss.CryptoManager.NotInitializedException; +import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.InvalidKeyFormatException; +import org.mozilla.jss.crypto.KeyGenAlgorithm; +import org.mozilla.jss.crypto.KeyGenerator; +import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import com.netscape.certsrv.apps.CMS; @@ -60,30 +67,32 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou public Response findConnectors(Integer start, Integer size) { try { String tpsList = cs.getString(TPS_LIST, ""); - Iterator<String> entries = Arrays.asList(StringUtils.split(tpsList,",")).iterator(); + Iterator<String> entries = Arrays.asList(StringUtils.split(tpsList, ",")).iterator(); TPSConnectorCollection response = new TPSConnectorCollection(); int i = 0; // skip to the start of the page - for ( ; i<start && entries.hasNext(); i++) entries.next(); + for (; i < start && entries.hasNext(); i++) + entries.next(); // return entries up to the page size - for ( ; i<start+size && entries.hasNext(); i++) { + for (; i < start + size && entries.hasNext(); i++) { response.addEntry(createTPSConnectorData(entries.next())); } // count the total entries - for ( ; entries.hasNext(); i++) entries.next(); + for (; entries.hasNext(); i++) + entries.next(); response.setTotal(i); if (start > 0) { - URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start-size, 0)).build(); + URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start - size, 0)).build(); response.addLink(new Link("prev", uri)); } - if (start+size < i) { - URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start+size).build(); + if (start + size < i) { + URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start + size).build(); response.addLink(new Link("next", uri)); } @@ -114,7 +123,8 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou public TPSConnectorData getConnectorData(String id) { - if (id == null) throw new BadRequestException("TPS connector ID is null."); + if (id == null) + throw new BadRequestException("TPS connector ID is null."); try { if (!connectorExists(id)) @@ -131,8 +141,10 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou @Override public Response getConnector(String host, String port) { - if (host == null) throw new BadRequestException("TPS connector host is null."); - if (port == null) throw new BadRequestException("TPS connector port is null."); + if (host == null) + throw new BadRequestException("TPS connector host is null."); + if (port == null) + throw new BadRequestException("TPS connector port is null."); try { String id = getConnectorID(host, port); @@ -151,8 +163,10 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou @Override public Response createConnector(String tpsHost, String tpsPort) { - if (tpsHost == null) throw new BadRequestException("TPS connector host is null."); - if (tpsPort == null) throw new BadRequestException("TPS connector port is null."); + if (tpsHost == null) + throw new BadRequestException("TPS connector host is null."); + if (tpsPort == null) + throw new BadRequestException("TPS connector port is null."); try { String id = getConnectorID(tpsHost, tpsPort); @@ -245,7 +259,8 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou if (StringUtils.isEmpty(id)) throw new BadRequestException("Attempt to delete TPS connection with null or empty id"); - if (!connectorExists(id)) return createNoContentResponse(); + if (!connectorExists(id)) + return createNoContentResponse(); deleteSharedSecret(id); cs.removeSubStore("tps." + id); @@ -263,8 +278,10 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou @Override public Response deleteConnector(String host, String port) { - if (host == null) throw new BadRequestException("TPS connector host is null."); - if (port == null) throw new BadRequestException("TPS connector port is null."); + if (host == null) + throw new BadRequestException("TPS connector host is null."); + if (port == null) + throw new BadRequestException("TPS connector port is null."); String id; try { @@ -281,7 +298,10 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou @Override public Response createSharedSecret(String id) { - if (id == null) throw new BadRequestException("TPS connector ID is null."); + CMS.debug("TPSConnectorService.createSharedSecret.id: " + id); + + if (id == null) + throw new BadRequestException("TPS connector ID is null."); try { if (!connectorExists(id)) { @@ -293,9 +313,13 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou // get user cert IUser user = userGroupManager.getUser(userid); + + CMS.debug("TPSConnectorService.createSharedSecret.userid: " + userid); X509Certificate[] certs = user.getX509Certificates(); String nickname = userid + " sharedSecret"; + + CMS.debug("TPSConnectorService.createSharedSecret. nickname: " + nickname); if (CryptoUtil.sharedSecretExists(nickname)) { throw new BadRequestException("Shared secret already exists"); } @@ -305,9 +329,21 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou cs.putString("tps." + id + ".nickname", nickname); cs.commit(true); - byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]); + //Create des3 session sym key to wrap the shared secret. + SymmetricKey tempKey = createDes3SessionKeyOnInternal(); + + if (tempKey == null) { + return createNoContentResponse(); + } + + List<byte[]> listWrappedKeys = CryptoUtil.exportSharedSecret(nickname, certs[0], tempKey); + + byte[] wrappedSessionKey = listWrappedKeys.get(0); + byte[] wrappedSharedSecret = listWrappedKeys.get(1); + KeyData keyData = new KeyData(); - keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey)); + keyData.setWrappedPrivateData(Utils.base64encode(wrappedSessionKey)); + keyData.setAdditionalWrappedPrivateData(Utils.base64encode(wrappedSharedSecret)); return createOKResponse(keyData); @@ -341,7 +377,8 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou @Override public Response replaceSharedSecret(String id) { - if (id == null) throw new BadRequestException("TPS connector ID is null."); + if (id == null) + throw new BadRequestException("TPS connector ID is null."); try { if (!connectorExists(id)) { @@ -362,9 +399,22 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou CryptoUtil.deleteSharedSecret(nickname); CryptoUtil.createSharedSecret(nickname); - byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]); + + //Create des3 session sym key to wrap the shared secret. + SymmetricKey tempKey = createDes3SessionKeyOnInternal(); + + if (tempKey == null) { + return createNoContentResponse(); + } + + List<byte[]> listWrappedKeys = CryptoUtil.exportSharedSecret(nickname,certs[0], tempKey); + + byte[] wrappedSessionKey = listWrappedKeys.get(0); + byte[] wrappedSharedSecret = listWrappedKeys.get(1); + KeyData keyData = new KeyData(); - keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey)); + keyData.setWrappedPrivateData(Utils.base64encode(wrappedSessionKey)); + keyData.setAdditionalWrappedPrivateData(Utils.base64encode(wrappedSharedSecret)); return createOKResponse(keyData); @@ -380,7 +430,8 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou @Override public Response deleteSharedSecret(String id) { - if (id == null) throw new BadRequestException("TPS connector ID is null."); + if (id == null) + throw new BadRequestException("TPS connector ID is null."); try { if (!connectorExists(id)) { @@ -415,8 +466,10 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou @Override public Response getSharedSecret(String id) { - if (id == null) throw new BadRequestException("TPS connector ID is null."); + if (id == null) + throw new BadRequestException("TPS connector ID is null."); + CMS.debug("TPSConnectorServlet.getSharedSecret: id : " + id); try { if (!connectorExists(id)) { throw new ResourceNotFoundException("TPS connection does not exist"); @@ -434,9 +487,20 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou IUser user = userGroupManager.getUser(userid); X509Certificate[] certs = user.getX509Certificates(); - byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]); + //Create des3 session sym key to wrap the shared secrt. + SymmetricKey tempKey = createDes3SessionKeyOnInternal(); + + if (tempKey == null) { + return createNoContentResponse(); + } + + List<byte[]> listWrappedKeys = CryptoUtil.exportSharedSecret(nickname, certs[0], tempKey); + byte[] wrappedSessionKey = listWrappedKeys.get(0); + byte[] wrappedSharedSecret = listWrappedKeys.get(1); + KeyData keyData = new KeyData(); - keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey)); + keyData.setWrappedPrivateData(Utils.base64encode(wrappedSessionKey)); + keyData.setAdditionalWrappedPrivateData(Utils.base64encode(wrappedSharedSecret)); return createOKResponse(keyData); @@ -456,7 +520,7 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou private String getConnectorID(String host, String port) throws EBaseException { String tpsList = cs.getString(TPS_LIST, ""); - for (String tpsID : StringUtils.split(tpsList,",")) { + for (String tpsID : StringUtils.split(tpsList, ",")) { TPSConnectorData data = createTPSConnectorData(tpsID); if (data.getHost().equals(host) && data.getPort().equals(port)) return tpsID; @@ -486,7 +550,36 @@ public class TPSConnectorService extends PKIService implements TPSConnectorResou sorted.addAll(Arrays.asList(StringUtils.split(tpsList, ","))); int index = 0; - while (sorted.contains(Integer.toString(index))) index++; + while (sorted.contains(Integer.toString(index))) + index++; return Integer.toString(index); } + + private SymmetricKey createDes3SessionKeyOnInternal() throws EBaseException { + + SymmetricKey tempKey = null; + try { + CryptoManager cm = CryptoManager.getInstance(); + CryptoToken token = cm.getInternalKeyStorageToken(); + KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3); + + SymmetricKey.Usage usages[] = new SymmetricKey.Usage[4]; + usages[0] = SymmetricKey.Usage.WRAP; + usages[1] = SymmetricKey.Usage.UNWRAP; + usages[2] = SymmetricKey.Usage.ENCRYPT; + usages[3] = SymmetricKey.Usage.DECRYPT; + + kg.setKeyUsages(usages); + kg.temporaryKeys(true); + tempKey = kg.generate(); + } catch (NoSuchAlgorithmException | TokenException | IllegalStateException | CharConversionException + | NotInitializedException e) { + CMS.debug("TPSConnectorService.createDes3SesisonKeyOnInternal: Can't generate temporary session key."); + + throw new EBaseException(e); + } + + return tempKey; + } + } diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java index ff6420879..94e6497ce 100644 --- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java +++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java @@ -33,6 +33,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import netscape.security.x509.RevocationReason; + import org.dogtagpki.server.tps.TPSSession; import org.dogtagpki.server.tps.TPSSubsystem; import org.dogtagpki.server.tps.authentication.AuthUIParameter; @@ -96,8 +98,6 @@ import com.netscape.certsrv.tps.token.TokenStatus; import com.netscape.cms.servlet.tks.SecureChannelProtocol; import com.netscape.symkey.SessionKey; -import netscape.security.x509.RevocationReason; - public class TPSProcessor { public static final int RESULT_NO_ERROR = 0; @@ -686,9 +686,6 @@ public class TPSProcessor { sessionKey = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret, sessionKeyWrapped.toBytesArray(), false); - - - if (sessionKey == null) { CMS.debug("TPSProcessor.generateSecureChannel: Can't extract session key!"); throw new TPSException("TPSProcessor.generateSecureChannel: Can't extract session key!", @@ -708,7 +705,6 @@ public class TPSProcessor { TPSStatus.STATUS_ERROR_SECURE_CHANNEL); } - //CMS.debug("TPSProcessor.generateSecureChannel: retrieved enc session key: " + encSessionKey); CMS.debug("TPSProcessor.generateSecureChannel: retrieved enc session key"); TPSBuffer drmDesKey = null; diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java b/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java index dab80e491..068293e60 100644 --- a/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java +++ b/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java @@ -142,11 +142,21 @@ public class TPSInstallerService extends SystemConfigService { ConfigurationUtils.exportTransportCert(secdomainURI, tksURI, transportCert); } + String doImportStr = request.getImportSharedSecret(); + CMS.debug("finalizeConfiguration: importSharedSecret:" + doImportStr); // generate shared secret from the tks + + boolean doImport = false; + + if("true".equalsIgnoreCase(doImportStr)) { + CMS.debug("finalizeConfiguration: importSharedSecret: importSharedSecret is true."); + doImport = true; + } + ConfigurationUtils.getSharedSecret( tksURI.getHost(), tksURI.getPort(), - Boolean.getBoolean(request.getImportSharedSecret())); + doImport); } catch (URISyntaxException e) { throw new BadRequestException("Invalid URI for CA, TKS or KRA"); diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java index 4a2558b75..9cabdc5cc 100644 --- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java +++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java @@ -47,7 +47,32 @@ import java.util.Random; import java.util.StringTokenizer; import java.util.Vector; -import javax.crypto.SecretKey; +import netscape.security.pkcs.PKCS10; +import netscape.security.pkcs.PKCS10Attribute; +import netscape.security.pkcs.PKCS10Attributes; +import netscape.security.pkcs.PKCS7; +import netscape.security.pkcs.PKCS9Attribute; +import netscape.security.util.BigInt; +import netscape.security.util.DerInputStream; +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.AlgorithmId; +import netscape.security.x509.CertificateAlgorithmId; +import netscape.security.x509.CertificateChain; +import netscape.security.x509.CertificateExtensions; +import netscape.security.x509.CertificateIssuerName; +import netscape.security.x509.CertificateSerialNumber; +import netscape.security.x509.CertificateSubjectName; +import netscape.security.x509.CertificateValidity; +import netscape.security.x509.CertificateVersion; +import netscape.security.x509.CertificateX509Key; +import netscape.security.x509.Extensions; +import netscape.security.x509.X500Name; +import netscape.security.x509.X500Signer; +import netscape.security.x509.X509CertImpl; +import netscape.security.x509.X509CertInfo; +import netscape.security.x509.X509Key; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.CryptoManager.NotInitializedException; @@ -82,7 +107,6 @@ 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; @@ -108,33 +132,6 @@ import org.mozilla.jss.util.Password; import com.netscape.cmsutil.util.Cert; import com.netscape.cmsutil.util.Utils; -import netscape.security.pkcs.PKCS10; -import netscape.security.pkcs.PKCS10Attribute; -import netscape.security.pkcs.PKCS10Attributes; -import netscape.security.pkcs.PKCS7; -import netscape.security.pkcs.PKCS9Attribute; -import netscape.security.util.BigInt; -import netscape.security.util.DerInputStream; -import netscape.security.util.DerOutputStream; -import netscape.security.util.DerValue; -import netscape.security.util.ObjectIdentifier; -import netscape.security.x509.AlgorithmId; -import netscape.security.x509.CertificateAlgorithmId; -import netscape.security.x509.CertificateChain; -import netscape.security.x509.CertificateExtensions; -import netscape.security.x509.CertificateIssuerName; -import netscape.security.x509.CertificateSerialNumber; -import netscape.security.x509.CertificateSubjectName; -import netscape.security.x509.CertificateValidity; -import netscape.security.x509.CertificateVersion; -import netscape.security.x509.CertificateX509Key; -import netscape.security.x509.Extensions; -import netscape.security.x509.X500Name; -import netscape.security.x509.X500Signer; -import netscape.security.x509.X509CertImpl; -import netscape.security.x509.X509CertInfo; -import netscape.security.x509.X509Key; - @SuppressWarnings("serial") public class CryptoUtil { @@ -2072,55 +2069,117 @@ public class CryptoUtil { km.deleteUniqueNamedKey(nickname); } - public static byte[] exportSharedSecret(String nickname, java.security.cert.X509Certificate wrappingCert) + // Return a list of two wrapped keys: first element: temp DES3 key wrapped by cert , second element: shared secret wrapped by temp DES3 key + public static List<byte[]> exportSharedSecret(String nickname, java.security.cert.X509Certificate wrappingCert,SymmetricKey wrappingKey) throws NotInitializedException, TokenException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, InvalidKeyFormatException { CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalKeyStorageToken(); + + List<byte[]> listWrappedKeys = new ArrayList<byte[]>(); + + 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); + + SymmetricKey sharedSecretKey = null; + + try { + sharedSecretKey = getSymKeyByName(token, nickname); + } catch (Exception e) { + sharedSecretKey = null; + } + + if (sharedSecretKey == null) { + throw new IOException("Shared secret " + nickname + " does not exist"); + } 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; + + //Wrap the temp DES3 key with the cert + byte[] wrappedKey = keyWrap.wrap(wrappingKey); + + listWrappedKeys.add(wrappedKey); + //Use the DES3 key to wrap the shared secret + + KeyWrapper keyWrapSharedSecret = token.getKeyWrapper(KeyWrapAlgorithm.DES3_ECB); + keyWrapSharedSecret.initWrap(wrappingKey,null); + + byte[] wrappedSharedSecret = keyWrapSharedSecret.wrap(sharedSecretKey); + + listWrappedKeys.add(wrappedSharedSecret); + + if(listWrappedKeys.size() != 2) { + throw new IOException("Can't write out shared secret data to export for nickname: " + nickname); + } + + return listWrappedKeys; } - /* - public static void importSharedSecret(KeyData data) throws EBaseException, NotInitializedException, TokenException, + + public static void importSharedSecret(byte[] wrappedSessionKey,byte[] wrappedSharedSecret,String subsystemCertNickname,String sharedSecretNickname) throws Exception, 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"); + if (km.uniqueNamedKeyExists(sharedSecretNickname)) { + throw new IOException("Shared secret " + sharedSecretNickname + " already exists"); } + //Unwrap session key + KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.RSA); - X509Certificate cert = cm.findCertByNickname(subsystemNick); + X509Certificate cert = cm.findCertByNickname(subsystemCertNickname); PrivateKey subsystemPrivateKey = cm.findPrivKeyByCert(cert); keyWrap.initUnwrap(subsystemPrivateKey, null); - @SuppressWarnings("unused") - SymmetricKey unwrapped = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES, - SymmetricKey.Usage.DECRYPT, 0); + SymmetricKey unwrappedSessionKey = keyWrap.unwrapSymmetric(wrappedSessionKey, SymmetricKey.DES3, + 0); + + SymmetricKey unwrappedSharedSecret = null; + + //Unwrap shared secret permanently with session key + + KeyWrapper sharedSecretWrap = token.getKeyWrapper(KeyWrapAlgorithm.DES3_ECB); + sharedSecretWrap.initUnwrap(unwrappedSessionKey,null); + unwrappedSharedSecret = sharedSecretWrap.unwrapSymmetricPerm(wrappedSharedSecret,SymmetricKey.DES3,0 ); + unwrappedSharedSecret.setNickName(sharedSecretNickname); + } - // TODO - I have a key - now what to do with it? - // need to somehow import/label the symkey - }*/ + public static SymmetricKey getSymKeyByName(CryptoToken token, String name) throws Exception { + + String method = "CryptoUtil.getSymKeyByName:"; + if (token == null || name == null) { + throw new Exception(method + "Invalid input data!"); + } + SymmetricKey[] keys; + + try { + keys = token.getCryptoStore().getSymmetricKeys(); + } catch (TokenException e) { + throw new Exception(method + "Can't get the list of symmetric keys!"); + } + int len = keys.length; + for (int i = 0; i < len; i++) { + SymmetricKey cur = keys[i]; + if (cur != null) { + if (name.equals(cur.getNickName())) { + return cur; + } + } + } + + return null; + } public static String[] getECcurves() { return ecCurves; |