diff options
Diffstat (limited to 'pki/base/kra')
6 files changed, 331 insertions, 14 deletions
diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java index 51cead47b..651873b20 100644 --- a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java +++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java @@ -1,13 +1,26 @@ package com.netscape.cms.servlet.test; +import java.io.IOException; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.URL; +import java.net.UnknownHostException; import java.util.Collection; +import java.util.Enumeration; import java.util.Iterator; +import org.apache.commons.httpclient.ConnectTimeoutException; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.jboss.resteasy.client.ClientExecutor; import org.jboss.resteasy.client.ClientResponse; import org.jboss.resteasy.client.ProxyFactory; - import com.netscape.certsrv.dbs.keydb.KeyId; import com.netscape.certsrv.request.RequestId; +import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor; import com.netscape.cms.servlet.admin.SystemCertificateResource; import com.netscape.cms.servlet.cert.model.CertificateData; import com.netscape.cms.servlet.key.KeyResource; @@ -23,20 +36,146 @@ import com.netscape.cms.servlet.request.model.KeyRequestInfos; import com.netscape.cms.servlet.request.model.RecoveryRequestData; import com.netscape.cmsutil.util.Utils; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; +import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback; +import org.mozilla.jss.ssl.SSLSocket; + public class DRMRestClient { + // Callback to approve or deny returned SSL server certs + // Right now, simply approve the cert. + // ToDO: Look into taking this JSS http client code and move it into + // its own class to be used by possible future clients. + private class ServerCertApprovalCB implements SSLCertificateApprovalCallback { + + public boolean approve(org.mozilla.jss.crypto.X509Certificate servercert, + SSLCertificateApprovalCallback.ValidityStatus status) { + + //For now lets just accept the server cert. This is a test tool, being + // pointed at a well know kra instance. + + + if (servercert != null) { + System.out.println("Peer cert details: " + + "\n subject: " + servercert.getSubjectDN().toString() + + "\n issuer: " + servercert.getIssuerDN().toString() + + "\n serial: " + servercert.getSerialNumber().toString() + ); + } + + SSLCertificateApprovalCallback.ValidityItem item; + + Enumeration<?> errors = status.getReasons(); + int i = 0; + while (errors.hasMoreElements()) { + i++; + item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement(); + System.out.println("item " + i + + " reason=" + item.getReason() + + " depth=" + item.getDepth()); + + int reason = item.getReason(); + + if (reason == + SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER || + reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) { + + //Allow these two since we haven't necessarily installed the CA cert for trust + // and we are choosing "localhost" as the host for this client. + + return true; + + } + } + + //For other errors return false + + return false; + } + } + + private class JSSProtocolSocketFactory implements ProtocolSocketFactory { + + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + + SSLSocket sock = createJSSSocket(host,port, null, 0, null); + return (Socket) sock; + } + + @Override + public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, + UnknownHostException { + + SSLSocket sock = createJSSSocket(host,port, clientHost, clientPort, null); + return (Socket) sock; + } + + @Override + public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) + throws IOException, UnknownHostException, ConnectTimeoutException { + + SSLSocket sock = createJSSSocket(host, port, localAddress, localPort, null); + return (Socket) sock; + } + } + + private SSLSocket createJSSSocket(String host, int port, InetAddress localAddress, + int localPort, SSLClientCertificateSelectionCallback clientCertSelectionCallback) + throws IOException, UnknownHostException, ConnectTimeoutException { + + SSLSocket sock = new SSLSocket(InetAddress.getByName(host), + port, + localAddress, + localPort, + new ServerCertApprovalCB(), + null); + + if(sock != null && clientCertNickname != null) { + sock.setClientCertNickname(clientCertNickname); + } + + return sock; + + } private KeyResource keyClient; private KeysResource keysClient; private KeyRequestsResource keyRequestsClient; private KeyRequestResource keyRequestClient; private SystemCertificateResource systemCertClient; - public DRMRestClient(String baseUri) { - systemCertClient = ProxyFactory.create(SystemCertificateResource.class, baseUri); - keyRequestsClient = ProxyFactory.create(KeyRequestsResource.class, baseUri); - keyRequestClient = ProxyFactory.create(KeyRequestResource.class, baseUri); - keysClient = ProxyFactory.create(KeysResource.class, baseUri); - keyClient = ProxyFactory.create(KeyResource.class, baseUri); + private String clientCertNickname = null; + + public DRMRestClient(String baseUri, String clientCertNick) throws MalformedURLException { + + // For SSL we are assuming the caller has already intialized JSS and has + // a valid CryptoManager and CryptoToken + // optional clientCertNickname is provided for use if required. + + + URL url = new URL(baseUri); + + String protocol = url.getProtocol(); + int port = url.getPort(); + + clientCertNickname = null; + if(protocol != null && protocol.equals("https")) { + if (clientCertNick != null) { + clientCertNickname = clientCertNick; + } + + Protocol.registerProtocol("https", + new Protocol(protocol, new JSSProtocolSocketFactory(), port)); + } + + HttpClient httpclient = new HttpClient(); + ClientExecutor executor = new ApacheHttpClientExecutor(httpclient); + + systemCertClient = ProxyFactory.create(SystemCertificateResource.class, baseUri, executor); + keyRequestsClient = ProxyFactory.create(KeyRequestsResource.class, baseUri, executor); + keyRequestClient = ProxyFactory.create(KeyRequestResource.class, baseUri, executor); + keysClient = ProxyFactory.create(KeysResource.class, baseUri, executor); + keyClient = ProxyFactory.create(KeyResource.class, baseUri, executor); } public String getTransportCert() { @@ -124,7 +263,4 @@ public class DRMRestClient { KeyData key = keyClient.retrieveKey(data); return key; } - - - -}
\ No newline at end of file +} diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java index 8020ec2ca..8d83247b8 100644 --- a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java +++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java @@ -17,6 +17,7 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.test; +import java.net.MalformedURLException; import java.util.Calendar; import java.util.Collection; import java.util.Iterator; @@ -61,6 +62,8 @@ public class DRMTest { String port = null; String token_pwd = null; String db_dir = "./"; + String protocol = "http"; + String clientCertNickname = "KRA Administrator of Instance pki-kra's SjcRedhat Domain ID"; // parse command line arguments Options options = new Options(); @@ -68,6 +71,8 @@ public class DRMTest { options.addOption("p", true, "Port of the DRM"); options.addOption("w", true, "Token password"); options.addOption("d", true, "Directory for tokendb"); + options.addOption("s", true, "Attempt Optional Secure SSL connection"); + options.addOption("c", true, "Optional SSL Client cert Nickname"); try { CommandLineParser parser = new PosixParser(); @@ -97,6 +102,20 @@ public class DRMTest { if (cmd.hasOption("d")) { db_dir = cmd.getOptionValue("d"); } + + if (cmd.hasOption("s")) { + if(cmd.getOptionValue("s") != null && cmd.getOptionValue("s").equals("true")) { + protocol = "https"; + } + } + + if (cmd.hasOption("c")) { + String nick = cmd.getOptionValue("c"); + + if (nick != null && protocol.equals("https")) { + clientCertNickname = nick; + } + } } catch (ParseException e) { System.err.println("Error in parsing command line options: " + e.getMessage()); @@ -173,8 +192,17 @@ public class DRMTest { } // Set base URI and get client - String baseUri = "http://" + host + ":" + port + "/kra/pki"; - DRMRestClient client = new DRMRestClient(baseUri); + + + String baseUri = protocol + "://" + host + ":" + port + "/kra/pki"; + DRMRestClient client; + try { + client = new DRMRestClient(baseUri, clientCertNickname); + } catch (MalformedURLException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + return; + } // Test 1: Get transport certificate from DRM transportCert = client.getTransportCert(); diff --git a/pki/base/kra/shared/conf/acl.ldif b/pki/base/kra/shared/conf/acl.ldif index 4c219eaaa..38a9a088c 100644 --- a/pki/base/kra/shared/conf/acl.ldif +++ b/pki/base/kra/shared/conf/acl.ldif @@ -30,3 +30,13 @@ resourceACLS: certServer.kra.TokenKeyRecovery:submit:allow (submit) group="Data resourceACLS: certServer.kra.registerUser:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to register a new agent resourceACLS: certServer.kra.getTransportCert:read:allow (read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to retrieve the transport cert resourceACLS: certServer.clone.configuration:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators":Only Enterprise Administrators are allowed to clone the configuration. +resourceACLS: certServer.kra.pki.key.retrieve:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may retrieve archived key +resourceACLS: certServer.kra.pki.keyrequests:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read keyrequests data +resourceACLS: certServer.kra.pki.keyrequest:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read keyrequest data +resourceACLS: certServer.kra.pki.keyrequest.archive:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may issue archival request +resourceACLS: certServer.kra.pki.keyrequest.recover:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may issue recovery request +resourceACLS: certServer.kra.pki.keyrequest.approve:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may approve security data request +resourceACLS: certServer.kra.pki.keyrequest.reject:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may reject key security data request +resourceACLS: certServer.kra.pki.keyrequest.cancel:execute:allow (execute) group="Data Recovery Manager Agents":Data Recovery Manager Agents may cancel security data request +resourceACLS: certServer.kra.pki.keys:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read security data +resourceACLS: certServer.kra.pki.config.cert.transport:read:allow (read) group="Data Recovery Manager Agents":Data Recovery Manager Agents may read transport cert data diff --git a/pki/base/kra/shared/conf/server.xml b/pki/base/kra/shared/conf/server.xml index fcd849ef2..58121d448 100644 --- a/pki/base/kra/shared/conf/server.xml +++ b/pki/base/kra/shared/conf/server.xml @@ -229,8 +229,58 @@ Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown) resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm. --> + + <!-- <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> + --> + + <!-- Custom PKIJNDI realm + + Example: + + <Realm className="com.netscape.cmscore.realm.PKIJNDIRealm" : classpath to realm + connectionURL="ldap://localhost:389" : standard JNDI connection URL + userBase="ou=people,dc=localhost-pki-kra" : standard JNDI userBase property + userSearch="(description={0})" : Attribute to search for user of incoming client auth certificate + : Use userSearch="(UID={0})" if wanting to search isolate user based on UID + : Also set the following: certUIDLabel="UID" or whatever the field containing + : the user's UID happens to be. This will cause the incoming's cert dn to be + : be searched for <certUIDLabel>=<uid value> + + certAttrName="userCertificate" : Attribute containing user's client auth certificate + roleBase="ou=groups,dc=localhost-pki-kra" : Standard JNDI search base for roles or groups + roleName="cn" : Standard attribute name containg roles or groups + roleSubtree="true" : Standard JNDI roleSubtree property + roleSearch="(uniqueMember={0})" : How to search for a user in a specific role or group + connectionName="cn=Directory Manager" : Connection name, needs elevated privileges + connectionPassword="secret123" : Password for elevated user + aclBase ="cn=aclResources,dc=localhost-pki-kra" : Custom base location of PKI ACL's in directory + aclAttrName="resourceACLS" : Name of attribute containing PKI ACL's + /> + + Uncomment and customize below to activate Realm. + Also umcomment Security Constraints and login config values + in WEB-INF/web.xml as well. + --> + + <!-- + <Realm className="com.netscape.cmscore.realm.PKIJNDIRealm" + connectionURL="ldap://localhost:389" + userBase="ou=people,dc=localhost-pki-kra" + userSearch="(description={0})" + certAttrName="userCertificate" + roleBase="ou=groups,dc=localhost-pki-kra" + roleName="cn" + roleSubtree="true" + roleSearch="(uniqueMember={0})" + connectionName="cn=Directory Manager" + connectionPassword="netscape" + aclBase ="cn=aclResources,dc=localhost-pki-kra" + aclAttrName="resourceACLS" + /> + + --> <!-- Define the default virtual host Note: XML Schema validation will not work with Xerces 2.2. diff --git a/pki/base/kra/shared/webapps/kra/WEB-INF/auth.properties b/pki/base/kra/shared/webapps/kra/WEB-INF/auth.properties new file mode 100644 index 000000000..a206aa9e4 --- /dev/null +++ b/pki/base/kra/shared/webapps/kra/WEB-INF/auth.properties @@ -0,0 +1,16 @@ +# Restful API auth/authz mapping info +# +# Format: +# <Rest API URL> = <ACL Resource ID>,<ACL resource operation> +# ex: /kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute + +/kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute +/kra/pki/keyrequests = certServer.kra.pki.keyrequests,read +/kra/pki/keyrequest = certServer.kra.pki.keyrequest,read +/kra/pki/keyrequest/archive = certServer.kra.pki.keyrequest.archive,execute +/kra/pki/keyrequest/recover = certServer.kra.pki.keyrequest.recover,execute +/kra/pki/keyrequest/approve = certServer.kra.pki.keyrequest.approve,execute +/kra/pki/keyrequest/reject = certServer.kra.pki.keyrequest.reject,execute +/kra/pki/keyrequest/cancel = certServer.kra.pki.keyrequest.cancel,execute +/kra/pki/keys = certServer.kra.pki.keys,read +/kra/pki/config/cert/transport = certServer.kra.pki.config.cert.transport,read diff --git a/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml b/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml index 529aeadbc..c6e9934eb 100644 --- a/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml +++ b/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml @@ -1034,5 +1034,82 @@ <session-config> <session-timeout>30</session-timeout> </session-config> -</web-app> +<!-- Default login configuration uses form-based authentication --> +<!-- Security Constraint for agent access to the Security Data Rest Interface --> + +<!-- Uncomment to activate PKIJNDI realm as in conf/server.xml --> +<!-- +<security-constraint> + <display-name>KRA Top Level Constraint</display-name> + <web-resource-collection> + <web-resource-name>KRA Protected Area</web-resource-name> + <url-pattern>/pki/* + </url-pattern> + </web-resource-collection> + <user-data-constraint> + <transport-guarantee>CONFIDENTIAL</transport-guarantee> + </user-data-constraint> + <auth-constraint> + <role-name>*</role-name> + </auth-constraint> +</security-constraint> +--> + +<!-- Security Constraint to deny certain http methods for key/retrieve --> +<!-- Uncomment to activate PKIJNDI realm as in conf/server.xml --> +<!-- +<security-constraint> +<display-name>Key forbidden</display-name> +<web-resource-collection> + <web-resource-name>Key forbidden</web-resource-name> + <url-pattern>/pki/key/retrieve</url-pattern> + <http-method>GET</http-method> + <http-method>PUT</http-method> + <http-method>DELETE</http-method> +</web-resource-collection> +<auth-constraint/> +</security-constraint> +--> + +<!-- Security Constraint to deny certain http methods for keyrequest/* --> +<!-- Uncomment to activate PKIJNDI realm as in conf/server.xml --> + +<!-- +<security-constraint> +<display-name>KeyRequest forbidden</display-name> +<web-resource-collection> + <web-resource-name>KeyRequest forbidden</web-resource-name> + <url-pattern>/pki/keyrequest/archive</url-pattern> + <url-pattern>/pki/keyrequest/recover</url-pattern> + <url-pattern>/pki/keyrequest/approve/*</url-pattern> + <url-pattern>/pki/keyrequest/reject/*</url-pattern> + <url-pattern>/pki/keyrequest/cancel/*</url-pattern> + <http-method>GET</http-method> + <http-method>PUT</http-method> + <http-method>DELETE</http-method> +</web-resource-collection> +<auth-constraint/> +</security-constraint> +--> + + +<!-- Customized SSL Client auth login config + uncomment to activate PKIJNDI realm as in conf/server.xml +--> + +<!-- + +<login-config> + <realm-name>PKIJNDIRealm</realm-name> + <auth-method>CLIENT-CERT</auth-method> + <realm-name>Client Cert Protected Area</realm-name> +</login-config> + +<security-role> + <role-name>*</role-name> +</security-role> + +--> + +</web-app> |