diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/base/Authority.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/base/Authority.java new file mode 100644 index 00000000000..4bab0e8f8b0 --- /dev/null +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/base/Authority.java @@ -0,0 +1,417 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package org.dogtagpki.server.ca.rest.base; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.cert.CertificateEncodingException; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.servlet.http.HttpServletRequest; + +import org.dogtagpki.server.authentication.AuthToken; +import org.dogtagpki.server.ca.CAEngine; +import org.mozilla.jss.netscape.security.util.Utils; +import org.mozilla.jss.netscape.security.x509.X500Name; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.netscape.ca.CertificateAuthority; +import com.netscape.certsrv.authority.AuthorityData; +import com.netscape.certsrv.authority.AuthorityResource; +import com.netscape.certsrv.base.BadRequestDataException; +import com.netscape.certsrv.base.BadRequestException; +import com.netscape.certsrv.base.ConflictingOperationException; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.ForbiddenException; +import com.netscape.certsrv.base.PKIException; +import com.netscape.certsrv.base.ResourceNotFoundException; +import com.netscape.certsrv.base.ServiceUnavailableException; +import com.netscape.certsrv.base.SessionContext; +import com.netscape.certsrv.ca.AuthorityID; +import com.netscape.certsrv.ca.CADisabledException; +import com.netscape.certsrv.ca.CAEnabledException; +import com.netscape.certsrv.ca.CAMissingCertException; +import com.netscape.certsrv.ca.CAMissingKeyException; +import com.netscape.certsrv.ca.CANotFoundException; +import com.netscape.certsrv.ca.CANotLeafException; +import com.netscape.certsrv.ca.CATypeException; +import com.netscape.certsrv.ca.IssuerUnavailableException; +import com.netscape.certsrv.common.OpDef; +import com.netscape.certsrv.common.ScopeDef; +import com.netscape.certsrv.logging.AuditEvent; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.cmscore.apps.CMS; +import com.netscape.cmscore.logging.Auditor; + +/** + * @author Marco Fargetta {@literal } + * @author ftweedal + */ +public class Authority { + private static Logger logger = LoggerFactory.getLogger(Authority.class); + + private CAEngine engine; + + public Authority(CAEngine engine) { + this.engine = engine; + } + + public List findCAs(final String id, final String parentID, final String dn, final String issuerDN) throws IOException { + final X500Name x500dn = dn == null ? null : new X500Name(dn); + final X500Name x500issuerDN = issuerDN == null ? null : new X500Name(issuerDN); + logger.info("Authority: getting authorities:"); + + return engine.getCAs().stream(). + map(this::readAuthorityData). + filter(auth -> { + if (id != null && !id.equalsIgnoreCase(auth.getID())) return false; + if (parentID != null && !parentID.equalsIgnoreCase(auth.getParentID())) return false; + try { + if (x500dn != null && !x500dn.equals(new X500Name(auth.getDN()))) return false; + if (x500issuerDN != null && !x500issuerDN.equals(new X500Name(auth.getIssuerDN()))) return false; + } catch (IOException e) { + logger.error("Authority: error converting DNs for authority {}", auth.getID()); + return false; + } + logger.info("Authority: - ID: {}", auth.getID()); + logger.info("Authority: DN: {}", auth.getDN()); + if (auth.getParentID() != null) { + logger.info("Authority: Parent ID: {}", auth.getParentID()); + } + logger.info("Authority: Issuer DN: {}", auth.getIssuerDN()); + return true; + }). + collect(Collectors.toList()); + } + + public AuthorityData getCA(String authId) { + logger.info("Authority: getting authority {}:", authId); + + AuthorityID aid = null; + if (!AuthorityResource.HOST_AUTHORITY.equals(authId)) { + try { + aid = new AuthorityID(authId); + } catch (IllegalArgumentException e) { + throw new BadRequestException("Bad AuthorityID: " + authId); + } + + } + CertificateAuthority ca = engine.getCA(aid); + + if (ca == null) + throw new ResourceNotFoundException("CA \"" + authId + "\" not found"); + + AuthorityData authority = readAuthorityData(ca); + + logger.info("Authority: DN: {}", authority.getDN()); + if (authority.getParentID() != null) { + logger.info("Authority: Parent ID: {}", authority.getParentID()); + } + logger.info("Authority: Issuer DN: {}", authority.getIssuerDN()); + + return authority; + } + + + public byte[] getBinaryCert(String authId) { + + logger.info("Authority: getting cert for authority {}", authId); + + AuthorityID aid = null; + if (!AuthorityResource.HOST_AUTHORITY.equals(authId)) { + try { + aid = new AuthorityID(authId); + } catch (IllegalArgumentException e) { + throw new BadRequestException("Bad AuthorityID: " + authId); + } + } + CertificateAuthority ca = engine.getCA(aid); + + if (ca == null) + throw new ResourceNotFoundException("CA \"" + authId + "\" not found"); + + org.mozilla.jss.crypto.X509Certificate cert = ca.getCaX509Cert(); + if (cert == null) + throw new ResourceNotFoundException( + "Certificate for CA \"" + authId + "\" not available"); + + try { + return cert.getEncoded(); + } catch (CertificateEncodingException e) { + // this really is a 500 Internal Server Error + throw new PKIException("Error encoding certificate: " + e); + } + } + + public String getPemCert(String authId) { + byte[] der = getBinaryCert(authId); + return toPem("CERTIFICATE", der); + } + + public byte[] getBinaryChain(String authId) { + + logger.info("Authority: getting cert chain for authority {}", authId); + + AuthorityID aid = null; + if (!AuthorityResource.HOST_AUTHORITY.equals(authId)) { + try { + aid = new AuthorityID(authId); + } catch (IllegalArgumentException e) { + throw new BadRequestException("Bad AuthorityID: " + authId); + } + } + CertificateAuthority ca = engine.getCA(aid); + + if (ca == null) + throw new ResourceNotFoundException("CA \"" + authId + "\" not found"); + + org.mozilla.jss.netscape.security.x509.CertificateChain chain = ca.getCACertChain(); + if (chain == null) + throw new ResourceNotFoundException( + "Certificate chain for CA \"" + authId + "\" not available"); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + chain.encode(out); + } catch (IOException e) { + throw new PKIException("Error encoding certificate chain: " + e); + } + return out.toByteArray(); + } + + public String getPemChain(String authId) { + byte[] der = getBinaryChain(authId); + return toPem("PKCS7", der); + } + + public AuthorityData createCA(AuthorityData data) { + logger.info("Authority: Creating authority {}", data.getDN()); + + CertificateAuthority hostCA = engine.getCA(); + String parentAIDString = data.getParentID(); + AuthorityID parentAID = null; + if (AuthorityResource.HOST_AUTHORITY.equals(parentAIDString)) { + parentAID = hostCA.getAuthorityID(); + } else { + try { + parentAID = new AuthorityID(parentAIDString); + } catch (IllegalArgumentException e) { + throw new BadRequestException("Bad Authority ID: " + parentAIDString, e); + } + } + + Map auditParams = new LinkedHashMap<>(); + auditParams.put("dn", data.getDN()); + if (parentAID != null) + auditParams.put("parent", parentAIDString); + if (data.getDescription() != null) + auditParams.put("description", data.getDescription()); + + AuthToken authToken = (AuthToken) SessionContext.getContext().get(SessionContext.AUTH_TOKEN); + try { + CertificateAuthority subCA = engine.createCA( + parentAID, + authToken, + data.getDN(), + data.getDescription()); + audit(ILogger.SUCCESS, OpDef.OP_ADD, + subCA.getAuthorityID().toString(), auditParams); + return readAuthorityData(subCA); + } catch (IllegalArgumentException | BadRequestDataException e) { + throw new BadRequestException(e.toString()); + } catch (CANotFoundException e) { + throw new ResourceNotFoundException(e.toString()); + } catch (IssuerUnavailableException | CADisabledException e) { + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_ADD, "", auditParams); + throw new ConflictingOperationException(e.toString()); + } catch (CAMissingCertException | CAMissingKeyException e) { + logger.error(CMS.getLogMessage("CMSCORE_CA_SIGNING_CERT_NOT_FOUND", e.toString()), e); + throw new ServiceUnavailableException(e.toString()); + } catch (Exception e) { + String message = "Error creating CA: " + e.getMessage(); + logger.error(message, e); + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_ADD, "", auditParams); + throw new PKIException(message, e); + } + } + + public AuthorityData modifyCA(String authId, AuthorityData data) { + logger.info("Authority: modifying authority {}", authId); + + AuthorityID aid = null; + try { + aid = new AuthorityID(authId); + } catch (IllegalArgumentException e) { + throw new BadRequestException("Bad AuthorityID: " + authId); + } + CertificateAuthority ca = engine.getCA(aid); + + if (ca == null) + throw new ResourceNotFoundException("CA \"" + authId + "\" not found"); + + Map auditParams = new LinkedHashMap<>(); + if (Boolean.valueOf(ca.getAuthorityEnabled()).equals(data.getEnabled())) { + logger.info("Authority: enabled: {}", data.getEnabled()); + auditParams.put("enabled", data.getEnabled().toString()); + } + + String curDesc = ca.getAuthorityDescription(); + String newDesc = data.getDescription(); + if (curDesc != null && !curDesc.equals(newDesc) + || curDesc == null && newDesc != null) { + logger.info("Authority: description: {}", data.getDescription()); + auditParams.put("description", data.getDescription()); + } + + try { + engine.modifyAuthority(ca, data.getEnabled(), data.getDescription()); + audit(ILogger.SUCCESS, OpDef.OP_MODIFY, ca.getAuthorityID().toString(), auditParams); + return readAuthorityData(ca); + } catch (CATypeException e) { + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_MODIFY, ca.getAuthorityID().toString(), auditParams); + throw new ForbiddenException(e.toString()); + } catch (IssuerUnavailableException e) { + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_MODIFY, ca.getAuthorityID().toString(), auditParams); + throw new ConflictingOperationException(e.toString()); + } catch (EBaseException e) { + String message = "Error modifying authority: " + e.getMessage(); + logger.error(message, e); + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_MODIFY, ca.getAuthorityID().toString(), auditParams); + throw new PKIException(message, e); + } + } + + public void renewCA(String authId, HttpServletRequest request) { + logger.info("Authority: renewing cert for authority {}", authId); + + AuthorityID aid = null; + try { + aid = new AuthorityID(authId); + } catch (IllegalArgumentException e) { + throw new BadRequestException("Bad AuthorityID: " + authId); + } + CertificateAuthority ca = engine.getCA(aid); + + if (ca == null) + throw new ResourceNotFoundException("CA \"" + authId + "\" not found"); + + Map auditParams = new LinkedHashMap<>(); + + try { + engine.renewAuthority(request, ca); + audit(ILogger.SUCCESS, OpDef.OP_MODIFY, authId, null); + } catch (CADisabledException e) { + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_MODIFY, authId, auditParams); + throw new ConflictingOperationException(e.toString()); + } catch (Exception e) { + String message = "Error renewing authority: " + e.getMessage(); + logger.error(message, e); + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_MODIFY, authId, auditParams); + throw new PKIException(message, e); + } + } + + public void deleteCA(String authId, HttpServletRequest httpReq) { + + logger.info("Authority: deleting authority {}", authId); + + AuthorityID aid = null; + try { + aid = new AuthorityID(authId); + } catch (IllegalArgumentException e) { + throw new BadRequestException("Bad AuthorityID: " + authId); + } + + CertificateAuthority ca = engine.getCA(aid); + + if (ca == null) + throw new ResourceNotFoundException("CA \"" + authId + "\" not found"); + + Map auditParams = new LinkedHashMap<>(); + + try { + engine.deleteAuthority(httpReq, ca); + audit(ILogger.SUCCESS, OpDef.OP_DELETE, authId, null); + } catch (CATypeException e) { + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_DELETE, authId, auditParams); + throw new ForbiddenException(e.toString()); + } catch (CAEnabledException | CANotLeafException e) { + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_DELETE, authId, auditParams); + throw new ConflictingOperationException(e.toString()); + } catch (EBaseException e) { + String message = "Error modifying authority: " + e.getMessage(); + logger.error(message, e); + auditParams.put("exception", e.toString()); + audit(ILogger.FAILURE, OpDef.OP_DELETE, authId, auditParams); + throw new PKIException(message, e); + } + } + + private AuthorityData readAuthorityData(CertificateAuthority ca) + throws PKIException { + String dn; + try { + dn = ca.getX500Name().toLdapDNString(); + } catch (IOException e) { + throw new PKIException("Error reading CA data: could not determine subject DN"); + } + + String issuerDN; + BigInteger serial; + try { + issuerDN = ca.getCACert().getIssuerName().toString(); + serial = ca.getCACert().getSerialNumber(); + } catch (EBaseException e) { + throw new PKIException("Error reading CA data: missing CA cert", e); + } + + AuthorityID parentAID = ca.getAuthorityParentID(); + return new AuthorityData( + ca.isHostAuthority(), + dn, + ca.getAuthorityID().toString(), + parentAID != null ? parentAID.toString() : null, + issuerDN, + serial, + ca.getAuthorityEnabled(), + ca.getAuthorityDescription(), + ca.isReady() + ); + } + + private String toPem(String name, byte[] data) { + return "-----BEGIN " + name + "-----\n" + + Utils.base64encode(data, true) + + "-----END " + name + "-----\n"; + } + + private void audit( + String status, String op, String id, + Map params) { + + Auditor auditor = engine.getAuditor(); + String msg = CMS.getLogMessage( + AuditEvent.AUTHORITY_CONFIG, + auditor.getSubjectID(), + status, + auditor.getParamString(ScopeDef.SC_AUTHORITY, op, id, params)); + auditor.log(msg); + } +} diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/AuthorityServlet.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/AuthorityServlet.java new file mode 100644 index 00000000000..6b8b27ef22d --- /dev/null +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/AuthorityServlet.java @@ -0,0 +1,207 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package org.dogtagpki.server.ca.rest.v2; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.net.URLEncoder; +import java.util.List; +import java.util.stream.Collectors; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.dogtagpki.server.ca.rest.base.Authority; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.netscape.certsrv.authority.AuthorityData; +import com.netscape.certsrv.base.BadRequestException; +import com.netscape.certsrv.base.MediaType; +import com.netscape.certsrv.base.RequestNotAcceptable; +import com.netscape.certsrv.base.WebAction; +import com.netscape.certsrv.util.JSONSerializer; + +/** + * @author Marco Fargetta {@literal } + */ +@WebServlet( + name = "caAuthority", + urlPatterns = "/v2/authorities/*") +public class AuthorityServlet extends CAServlet { + private static final long serialVersionUID = 1L; + private static Logger logger = LoggerFactory.getLogger(AuthorityServlet.class); + + private Authority authority; + + @Override + public void init() throws ServletException { + super.init(); + authority = new Authority(engine); + } + + @WebAction(method = HttpMethod.GET, paths = {""}) + public void findCAs(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.findCAs(): session: {}", session.getId()); + String id = request.getParameter("id"); + String parentID = request.getParameter("parentID"); + String dn = request.getParameter("dn"); + String issuerDN = request.getParameter("issuerDN"); + List authorities; + try { + authorities = authority.findCAs(id, parentID, dn, issuerDN); + } catch (IOException e) { + throw new BadRequestException("DNs not valid"); + } + PrintWriter out = response.getWriter(); + ObjectMapper mapper = new ObjectMapper(); + out.println(mapper.writeValueAsString(authorities)); + } + + @WebAction(method = HttpMethod.GET, paths = {"{}"}) + public void getCA(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.getCA(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + AuthorityData ca = authority.getCA(aid); + PrintWriter out = response.getWriter(); + out.println(ca.toJSON()); + } + + @WebAction(method = HttpMethod.GET, paths = {"{}/cert"}) + public void getCert(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.getCert(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + String accept = request.getHeader("Accept"); + if (accept == null) + accept = MediaType.ANYTYPE; + + if (accept.contains(MediaType.APPLICATION_X_PEM_FILE)) { + response.setContentType(MediaType.APPLICATION_X_PEM_FILE); + String cert = authority.getPemCert(aid); + PrintWriter out = response.getWriter(); + out.println(cert); + return; + } + if (accept.equals(MediaType.ANYTYPE) || accept.contains(MediaType.APPLICATION_PKIX_CERT)) { + response.setContentType(MediaType.APPLICATION_PKIX_CERT); + byte[] cert = authority.getBinaryCert(aid); + OutputStream out = response.getOutputStream(); + out.write(cert); + return; + } + throw new RequestNotAcceptable("Certificate format not supported: " + accept); + } + + @WebAction(method = HttpMethod.GET, paths = {"{}/chain"}) + public void getChain(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.getChain(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + String accept = request.getHeader("Accept"); + if (accept == null) + accept = MediaType.ANYTYPE; + + if (accept.contains(MediaType.APPLICATION_X_PEM_FILE)) { + response.setContentType(MediaType.APPLICATION_X_PEM_FILE); + String cert = authority.getPemChain(aid); + PrintWriter out = response.getWriter(); + out.println(cert); + return; + } + if (accept.equals(MediaType.ANYTYPE) || accept.contains(MediaType.APPLICATION_PKIX_CERT)) { + response.setContentType(MediaType.APPLICATION_PKIX_CERT); + byte[] cert = authority.getBinaryChain(aid); + OutputStream out = response.getOutputStream(); + out.write(cert); + return; + } + throw new RequestNotAcceptable("Certificate format not supported: " + accept); + } + + @WebAction(method = HttpMethod.POST, paths = {""}) + public void createCA(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.createCA(): session: {}", session.getId()); + String requestData = request.getReader().lines().collect(Collectors.joining()); + AuthorityData reqAuthority = JSONSerializer.fromJSON(requestData, AuthorityData.class); + AuthorityData newAuthhority = authority.createCA(reqAuthority); + String encodedGroupID = URLEncoder.encode(newAuthhority.getID(), "UTF-8"); + StringBuffer uri = request.getRequestURL(); + uri.append("/" + encodedGroupID); + response.setStatus(HttpServletResponse.SC_CREATED); + response.setHeader("Location", uri.toString()); + PrintWriter out = response.getWriter(); + out.println(newAuthhority.toJSON()); + } + + @WebAction(method = HttpMethod.PUT, paths = {"{}"}) + public void modifyCA(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.modifyCA(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + String requestData = request.getReader().lines().collect(Collectors.joining()); + AuthorityData reqAuthority = JSONSerializer.fromJSON(requestData, AuthorityData.class); + AuthorityData newAuthhority = authority.modifyCA(aid, reqAuthority); + PrintWriter out = response.getWriter(); + out.println(newAuthhority.toJSON()); + } + + @WebAction(method = HttpMethod.DELETE, paths = {"{}"}) + public void deleteCA(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.deleteCA(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + authority.deleteCA(aid, request); + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + } + + @WebAction(method = HttpMethod.POST, paths = {"{}/enable"}) + public void enableCA(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.enableCA(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + AuthorityData reqAuthority = new AuthorityData(null, null, null, null, null, null, true, null, null); + AuthorityData newAuthhority = authority.modifyCA(aid, reqAuthority); + PrintWriter out = response.getWriter(); + out.println(newAuthhority.toJSON()); + } + + @WebAction(method = HttpMethod.POST, paths = {"{}/disable"}) + public void disableCA(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.disableCA(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + AuthorityData reqAuthority = new AuthorityData(null, null, null, null, null, null, false, null, null); + AuthorityData newAuthhority = authority.modifyCA(aid, reqAuthority); + PrintWriter out = response.getWriter(); + out.println(newAuthhority.toJSON()); + } + + @WebAction(method = HttpMethod.POST, paths = {"{}/renew"}) + public void renewCA(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("AuthorityServlet.renewCA(): session: {}", session.getId()); + String[] pathElement = request.getPathInfo().substring(1).split("/"); + String aid = pathElement[0]; + authority.renewCA(aid, request); + response.setStatus(HttpServletResponse.SC_NO_CONTENT); + } +} diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAServlet.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAServlet.java index c4eabbc9f8a..be816aa987e 100644 --- a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAServlet.java +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/CAServlet.java @@ -6,6 +6,7 @@ package org.dogtagpki.server.ca.rest.v2; import javax.servlet.ServletContext; +import javax.servlet.ServletException; import org.dogtagpki.server.ca.CAEngine; import org.dogtagpki.server.rest.v2.PKIServlet; @@ -15,8 +16,18 @@ */ public class CAServlet extends PKIServlet { public static final long serialVersionUID = 1L; + protected CAEngine engine; + + @Override + public void init() throws ServletException { + super.init(); + engine = getCAEngine(); + } + public CAEngine getCAEngine() { + if (engine != null) + return engine; ServletContext servletContext = getServletContext(); return (CAEngine) servletContext.getAttribute("engine"); } diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AgentCertACL.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AgentCertACL.java index b6d0b2431a1..e9356350bb1 100644 --- a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AgentCertACL.java +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AgentCertACL.java @@ -18,5 +18,4 @@ public class AgentCertACL extends ACLFilter { public void init() throws ServletException { setAcl("certs"); } - } diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AuthorityACL.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AuthorityACL.java new file mode 100644 index 00000000000..75b0cd75d7f --- /dev/null +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AuthorityACL.java @@ -0,0 +1,36 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package org.dogtagpki.server.ca.rest.v2.filters; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebFilter; + +import org.dogtagpki.server.rest.v2.filters.ACLFilter; + +@WebFilter(servletNames = "caAuthority") +public class AuthorityACL extends ACLFilter { + private static final long serialVersionUID = 1L; + + private static final String CREATE = "authorities.create"; + private static final String MODIFY = "authorities.modify"; + private static final String DELETE = "authorities.delete"; + + @Override + public void init() throws ServletException { + Map aclMap = new HashMap<>(); + aclMap.put("POST:", CREATE); + aclMap.put("PUT:{}", MODIFY); + aclMap.put("DELETE:{}", DELETE); + aclMap.put("POST:{}/enable", MODIFY); + aclMap.put("POST:{}/disable", MODIFY); + aclMap.put("POST:{}/renew", MODIFY); + setAclMap(aclMap); + } + +} diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AuthorityAuthMethod.java b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AuthorityAuthMethod.java new file mode 100644 index 00000000000..c0b2fbf0bf9 --- /dev/null +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/rest/v2/filters/AuthorityAuthMethod.java @@ -0,0 +1,34 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package org.dogtagpki.server.ca.rest.v2.filters; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebFilter; + +import org.dogtagpki.server.rest.v2.filters.AuthMethodFilter; + +@WebFilter(servletNames = "caAuthority") +public class AuthorityAuthMethod extends AuthMethodFilter { + private static final long serialVersionUID = 1L; + + private static final String AUTHORITIES = "authorities"; + + @Override + public void init() throws ServletException { + Map authMethodMap = new HashMap<>(); + authMethodMap.put("POST:", AUTHORITIES); + authMethodMap.put("PUT:{}", AUTHORITIES); + authMethodMap.put("DELETE:{}", AUTHORITIES); + authMethodMap.put("POST:{}/enable", AUTHORITIES); + authMethodMap.put("POST:{}/disable", AUTHORITIES); + authMethodMap.put("POST:{}/renew", AUTHORITIES); + setAuthMethodMap(authMethodMap); + } + +} diff --git a/base/common/src/main/java/com/netscape/certsrv/base/MediaType.java b/base/common/src/main/java/com/netscape/certsrv/base/MediaType.java new file mode 100644 index 00000000000..7687198dad6 --- /dev/null +++ b/base/common/src/main/java/com/netscape/certsrv/base/MediaType.java @@ -0,0 +1,20 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package com.netscape.certsrv.base; + +/** + * @author Marco Fargetta {@literal } + */ +public class MediaType { + + public static final String ANYTYPE = "*/*"; + + public static final String APPLICATION_JSON = "application/json"; + + public static final String APPLICATION_PKIX_CERT = "application/pkix-cert"; + + public static final String APPLICATION_X_PEM_FILE = "application/x-pem-file"; +} diff --git a/base/common/src/main/java/com/netscape/certsrv/base/RequestNotAcceptable.java b/base/common/src/main/java/com/netscape/certsrv/base/RequestNotAcceptable.java new file mode 100644 index 00000000000..dccca938c00 --- /dev/null +++ b/base/common/src/main/java/com/netscape/certsrv/base/RequestNotAcceptable.java @@ -0,0 +1,29 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package com.netscape.certsrv.base; + +import javax.ws.rs.core.Response; + +/** + * @author Marco Fargetta {@literal } + */ +public class RequestNotAcceptable extends PKIException { + + private static final long serialVersionUID = 1L; + + public RequestNotAcceptable(String message) { + super(Response.Status.NOT_ACCEPTABLE, message); + } + + public RequestNotAcceptable(String message, Throwable cause) { + super(Response.Status.NOT_ACCEPTABLE, message, cause); + } + + public RequestNotAcceptable(Data data) { + super(data); + } + +} diff --git a/base/common/src/main/java/com/netscape/certsrv/base/UnsupportedMediaType.java b/base/common/src/main/java/com/netscape/certsrv/base/UnsupportedMediaType.java new file mode 100644 index 00000000000..b643ca79393 --- /dev/null +++ b/base/common/src/main/java/com/netscape/certsrv/base/UnsupportedMediaType.java @@ -0,0 +1,29 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package com.netscape.certsrv.base; + +import javax.ws.rs.core.Response; + +/** + * @author Marco Fargetta {@literal } + */ +public class UnsupportedMediaType extends PKIException { + + private static final long serialVersionUID = 1L; + + public UnsupportedMediaType(String message) { + super(Response.Status.UNSUPPORTED_MEDIA_TYPE, message); + } + + public UnsupportedMediaType(String message, Throwable cause) { + super(Response.Status.UNSUPPORTED_MEDIA_TYPE, message, cause); + } + + public UnsupportedMediaType(Data data) { + super(data); + } + +} diff --git a/base/server/src/main/java/org/dogtagpki/server/rest/v2/PKIServlet.java b/base/server/src/main/java/org/dogtagpki/server/rest/v2/PKIServlet.java index 29b32c22018..b8e3669b0c8 100644 --- a/base/server/src/main/java/org/dogtagpki/server/rest/v2/PKIServlet.java +++ b/base/server/src/main/java/org/dogtagpki/server/rest/v2/PKIServlet.java @@ -34,6 +34,7 @@ import com.netscape.certsrv.authentication.ExternalAuthToken; import com.netscape.certsrv.base.ForbiddenException; +import com.netscape.certsrv.base.MediaType; import com.netscape.certsrv.base.PKIException; import com.netscape.certsrv.base.SessionContext; import com.netscape.certsrv.base.WebAction; @@ -113,7 +114,7 @@ protected void service(HttpServletRequest req, HttpServletResponse res) throws S } private void doOperation(HttpMethod method, HttpServletRequest request, HttpServletResponse response) { - response.setContentType("application/json"); + response.setContentType(MediaType.APPLICATION_JSON); try { setSessionContext(request); Method actionMethod = getActionMethod(method, request.getPathInfo());