From 73f9c503229ba1a414a48fe17771e146a0d1e0b8 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Tue, 1 Sep 2015 09:57:42 -0400 Subject: [PATCH] Lightweight CAs: REST cert request param to specify authority Add the optional "ca" query parameter for REST cert request submission. Also update the ca-cert-request-submit CLI command with an option to provide an AuthorityID. Part of: https://fedorahosted.org/pki/ticket/1213 --- .../src/com/netscape/cms/servlet/test/CATest.java | 4 +- .../server/ca/rest/CertRequestService.java | 41 ++++++++++++++++++-- .../src/com/netscape/certsrv/cert/CertClient.java | 16 +++++++- .../netscape/certsrv/cert/CertRequestResource.java | 5 ++- .../cmstools/cert/CertRequestSubmitCLI.java | 44 +++++++++++++++++++++- .../cmstools/client/ClientCertRequestCLI.java | 2 +- .../netscape/cms/servlet/cert/CertRequestDAO.java | 12 ++++-- 7 files changed, 111 insertions(+), 13 deletions(-) diff --git a/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java b/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java index 15023cad939abb11927abc64fe5916e04cb65661..5876c57f985caa38ad5895f4368113620370910d 100644 --- a/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java +++ b/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java @@ -288,7 +288,7 @@ public class CATest { private static void enrollAndApproveCertRequest(CertClient client, CertEnrollmentRequest data) { CertRequestInfos reqInfo = null; try { - reqInfo = client.enrollRequest(data); + reqInfo = client.enrollRequest(data, null); } catch (Exception e) { e.printStackTrace(); log(e.toString()); @@ -308,7 +308,7 @@ public class CATest { private static void enrollCertRequest(CertClient client, CertEnrollmentRequest data) { CertRequestInfos reqInfo = null; try { - reqInfo = client.enrollRequest(data); + reqInfo = client.enrollRequest(data, null); } catch (Exception e) { e.printStackTrace(); log(e.toString()); diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java index 1da1ce1713541e52164e9e8fbcbf39ca2332540d..7cb4ff71e18b6e29bf55c11dc99bbfb9b83dd60f 100644 --- a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java +++ b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java @@ -18,6 +18,7 @@ package org.dogtagpki.server.ca.rest; +import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Enumeration; @@ -41,8 +42,11 @@ import com.netscape.certsrv.base.BadRequestException; import com.netscape.certsrv.base.ConflictingOperationException; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.PKIException; +import com.netscape.certsrv.base.ResourceNotFoundException; import com.netscape.certsrv.base.UnauthorizedException; +import com.netscape.certsrv.ca.AuthorityID; import com.netscape.certsrv.ca.CADisabledException; +import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.cert.CertEnrollmentRequest; import com.netscape.certsrv.cert.CertRequestInfo; import com.netscape.certsrv.cert.CertRequestInfos; @@ -63,6 +67,7 @@ import com.netscape.certsrv.request.RequestNotFoundException; import com.netscape.cms.servlet.base.PKIService; import com.netscape.cms.servlet.cert.CertRequestDAO; import com.netscape.cmsutil.ldap.LDAPUtil; +import netscape.security.x509.X500Name; /** * @author alee @@ -115,13 +120,43 @@ public class CertRequestService extends PKIService implements CertRequestResourc } @Override - public Response enrollCert(CertEnrollmentRequest data) { - + public Response enrollCert(CertEnrollmentRequest data, String aidString, String adnString) { if (data == null) { CMS.debug("enrollCert: data is null"); throw new BadRequestException("Unable to create enrollment reequest: Invalid input data"); } + if (aidString != null && adnString != null) + throw new BadRequestException("Cannot provide both issuer-id and issuer-dn"); + + AuthorityID aid = null; + ICertificateAuthority ca = (ICertificateAuthority) + CMS.getSubsystem(CMS.SUBSYSTEM_CA); + if (aidString != null) { + try { + aid = new AuthorityID(aidString); + } catch (IllegalArgumentException e) { + throw new BadRequestException("invalid AuthorityID: " + aidString); + } + ca = ca.getCA(aid); + if (ca == null) + throw new ResourceNotFoundException("CA not found: " + aidString); + } + if (adnString != null) { + X500Name adn = null; + try { + adn = new X500Name(adnString); + } catch (IOException e) { + throw new BadRequestException("invalid DN: " + adnString); + } + ca = ca.getCA(adn); + if (ca == null) + throw new ResourceNotFoundException("CA not found: " + adnString); + aid = ca.getAuthorityID(); + } + if (!ca.getAuthorityEnabled()) + throw new ConflictingOperationException("CA not enabled: " + aid.toString()); + data.setRemoteHost(servletRequest.getRemoteHost()); data.setRemoteAddr(servletRequest.getRemoteAddr()); @@ -129,7 +164,7 @@ public class CertRequestService extends PKIService implements CertRequestResourc CertRequestInfos infos; try { - infos = dao.submitRequest(data, servletRequest, uriInfo, getLocale(headers)); + infos = dao.submitRequest(aid, data, servletRequest, uriInfo, getLocale(headers)); } catch (EAuthException e) { CMS.debug("enrollCert: authentication failed: " + e); throw new UnauthorizedException(e.toString()); diff --git a/base/common/src/com/netscape/certsrv/cert/CertClient.java b/base/common/src/com/netscape/certsrv/cert/CertClient.java index 42b04b7021f0063894c340c177915d799b621ddd..1d4ccd2cf7e83a8ed3b33253b1416110d5504125 100644 --- a/base/common/src/com/netscape/certsrv/cert/CertClient.java +++ b/base/common/src/com/netscape/certsrv/cert/CertClient.java @@ -17,16 +17,19 @@ //--- END COPYRIGHT BLOCK --- package com.netscape.certsrv.cert; +import java.io.IOException; import java.net.URISyntaxException; import javax.ws.rs.core.Response; +import com.netscape.certsrv.ca.AuthorityID; import com.netscape.certsrv.client.Client; import com.netscape.certsrv.client.PKIClient; import com.netscape.certsrv.client.SubsystemClient; import com.netscape.certsrv.dbs.certdb.CertId; import com.netscape.certsrv.profile.ProfileDataInfos; import com.netscape.certsrv.request.RequestId; +import netscape.security.x509.X500Name; /** * @author Endi S. Dewata @@ -85,8 +88,17 @@ public class CertClient extends Client { return client.getEntity(response, CertRequestInfo.class); } - public CertRequestInfos enrollRequest(CertEnrollmentRequest data) { - Response response = certRequestClient.enrollCert(data); + public CertRequestInfos enrollRequest( + CertEnrollmentRequest data, AuthorityID aid, X500Name adn) { + String aidString = aid != null ? aid.toString() : null; + String adnString = null; + if (adn != null) { + try { + adnString = adn.toLdapDNString(); + } catch (IOException e) { + } + } + Response response = certRequestClient.enrollCert(data, aidString, adnString); return client.getEntity(response, CertRequestInfos.class); } diff --git a/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java b/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java index 7f08b4af392e3e56419abdad7cb66bd191688222..493f6f53a5a5e30804532305b199d44a66eecd24 100644 --- a/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java +++ b/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java @@ -37,7 +37,10 @@ public interface CertRequestResource { @POST @Path("certrequests") @ClientResponseType(entityType=CertRequestInfos.class) - public Response enrollCert(CertEnrollmentRequest data); + public Response enrollCert( + CertEnrollmentRequest data, + @QueryParam("issuer-id") String caIDString, + @QueryParam("issuer-dn") String caDNString); /** * Used to retrieve cert request info for a specific request diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java index 608490bb73d7df482d87e67e9c15322ddc2e5f5a..e6b59a5d7fcaced100699ea067a8f95b992722f3 100644 --- a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java @@ -2,18 +2,22 @@ package com.netscape.cmstools.cert; import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import java.util.Arrays; import java.util.Scanner; import javax.xml.bind.JAXBException; import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; import org.apache.commons.cli.ParseException; +import com.netscape.certsrv.ca.AuthorityID; import com.netscape.certsrv.cert.CertEnrollmentRequest; import com.netscape.certsrv.cert.CertRequestInfos; import com.netscape.cmstools.cli.CLI; import com.netscape.cmstools.cli.MainCLI; +import netscape.security.x509.X500Name; public class CertRequestSubmitCLI extends CLI { @@ -22,6 +26,14 @@ public class CertRequestSubmitCLI extends CLI { public CertRequestSubmitCLI(CertCLI certCLI) { super("request-submit", "Submit certificate request", certCLI); this.certCLI = certCLI; + + Option optAID = new Option(null, "issuer-id", true, "Authority ID (top-level CA if omitted)"); + optAID.setArgName("id"); + options.addOption(optAID); + + Option optADN = new Option(null, "issuer-dn", true, "Authority DN (top-level CA if omitted)"); + optADN.setArgName("dn"); + options.addOption(optADN); } public void printHelp() { @@ -55,9 +67,39 @@ public class CertRequestSubmitCLI extends CLI { System.exit(-1); } + AuthorityID aid = null; + if (cmd.hasOption("issuer-id")) { + String aidString = cmd.getOptionValue("issuer-id"); + try { + aid = new AuthorityID(aidString); + } catch (IllegalArgumentException e) { + System.err.println("Bad AuthorityID: " + aidString); + printHelp(); + System.exit(-1); + } + } + + X500Name adn = null; + if (cmd.hasOption("issuer-dn")) { + String adnString = cmd.getOptionValue("issuer-dn"); + try { + adn = new X500Name(adnString); + } catch (IOException e) { + System.err.println("Bad DN: " + adnString); + printHelp(); + System.exit(-1); + } + } + + if (aid != null && adn != null) { + System.err.println("--issuer-id and --issuer-dn options are mutually exclusive"); + printHelp(); + System.exit(-1); + } + try { CertEnrollmentRequest erd = getEnrollmentRequest(cmdArgs[0]); - CertRequestInfos cri = certCLI.certClient.enrollRequest(erd); + CertRequestInfos cri = certCLI.certClient.enrollRequest(erd, aid, adn); MainCLI.printMessage("Submitted certificate request"); CertCLI.printCertRequestInfos(cri); diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java index e6bd0d98120295ef8e798925f4e9aceb3a0d43f6..db71c8a0f7db4644290efb766178b76668c22377 100644 --- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java @@ -283,7 +283,7 @@ public class ClientCertRequestCLI extends CLI { System.out.println("Sending certificate request."); } - CertRequestInfos infos = certClient.enrollRequest(request); + CertRequestInfos infos = certClient.enrollRequest(request, null, null); MainCLI.printMessage("Submitted certificate request"); CertCLI.printCertRequestInfos(infos); diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java index 27d8b8262cb7bbcffa3706cba5318ca8aa0ad75b..a2e4b583d318ac8412361850d91233b77a447e13 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java +++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java @@ -30,6 +30,7 @@ import javax.ws.rs.core.UriInfo; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.ca.AuthorityID; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.cert.CertEnrollmentRequest; import com.netscape.certsrv.cert.CertRequestInfo; @@ -164,8 +165,13 @@ public class CertRequestDAO extends CMSRequestDAO { * @throws EBaseException * @throws ServletException */ - public CertRequestInfos submitRequest(CertEnrollmentRequest data, HttpServletRequest request, UriInfo uriInfo, - Locale locale) throws EBaseException { + public CertRequestInfos submitRequest( + AuthorityID aid, + CertEnrollmentRequest data, + HttpServletRequest request, + UriInfo uriInfo, + Locale locale) + throws EBaseException { CertRequestInfos ret = new CertRequestInfos(); @@ -175,7 +181,7 @@ public class CertRequestDAO extends CMSRequestDAO { results = processor.processRenewal(data, request); } else { EnrollmentProcessor processor = new EnrollmentProcessor("caProfileSubmit", locale); - results = processor.processEnrollment(data, request, null); + results = processor.processEnrollment(data, request, aid); } IRequest reqs[] = (IRequest[]) results.get(CAProcessor.ARG_REQUESTS); -- 2.4.3