From a25705a6fff3525b26a855d03f0c117bfadc1979 Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Wed, 23 May 2012 14:14:38 -0500 Subject: Added cert revocation REST service. The cert revocation REST service is based on DoRevoke and DoUnrevoke servlets. It provides an interface to manage certificate revocation. Ticket #161 --- .../netscape/certsrv/dbs/certdb/CertIdAdapter.java | 7 +- .../netscape/certsrv/dbs/keydb/KeyIdAdapter.java | 7 +- .../netscape/certsrv/request/RequestIdAdapter.java | 7 +- .../com/netscape/certsrv/user/UserCertData.java | 15 +- .../src/com/netscape/certsrv/util/DateAdapter.java | 40 ++ .../netscape/cms/client/user/UserAddCertCLI.java | 2 +- .../src/com/netscape/cms/client/user/UserCLI.java | 26 +- .../netscape/cms/client/user/UserFindCertCLI.java | 2 +- .../netscape/cms/client/user/UserShowCertCLI.java | 8 +- .../cms/servlet/admin/UserCertResourceService.java | 5 +- .../cms/servlet/base/BadRequestException.java | 2 +- .../cms/servlet/base/CMSResourceService.java | 4 +- .../com/netscape/cms/servlet/base/CMSServlet.java | 5 + .../cms/servlet/base/UnauthorizedException.java | 43 ++ .../netscape/cms/servlet/cert/CertResource.java | 24 +- .../cms/servlet/cert/CertResourceService.java | 223 ++++++++- .../cms/servlet/cert/CertsResourceService.java | 15 +- .../cms/servlet/cert/RevocationProcessor.java | 501 +++++++++++++++++++++ .../netscape/cms/servlet/cert/model/CertDAO.java | 132 +++--- .../cms/servlet/cert/model/CertDataInfo.java | 152 ++++++- .../cms/servlet/cert/model/CertRevokeRequest.java | 205 +++++++++ .../servlet/cert/model/CertUnrevokeRequest.java | 124 +++++ .../cms/servlet/cert/model/CertificateData.java | 252 ++++++++--- .../cms/servlet/key/KeyResourceService.java | 14 +- .../netscape/cms/servlet/processors/Processor.java | 20 +- .../cms/servlet/request/model/CMSRequestInfo.java | 11 +- .../cms/servlet/request/model/CertRequestDAO.java | 4 +- .../cms/servlet/request/model/CertRequestInfo.java | 2 + .../request/model/CertRequestInfoFactory.java | 80 ++-- .../cms/servlet/request/model/KeyRequestDAO.java | 2 +- 30 files changed, 1686 insertions(+), 248 deletions(-) create mode 100644 base/common/src/com/netscape/certsrv/util/DateAdapter.java create mode 100644 base/common/src/com/netscape/cms/servlet/base/UnauthorizedException.java create mode 100644 base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java create mode 100644 base/common/src/com/netscape/cms/servlet/cert/model/CertRevokeRequest.java create mode 100644 base/common/src/com/netscape/cms/servlet/cert/model/CertUnrevokeRequest.java (limited to 'base/common/src/com') diff --git a/base/common/src/com/netscape/certsrv/dbs/certdb/CertIdAdapter.java b/base/common/src/com/netscape/certsrv/dbs/certdb/CertIdAdapter.java index cfafff064..f6e46cad5 100644 --- a/base/common/src/com/netscape/certsrv/dbs/certdb/CertIdAdapter.java +++ b/base/common/src/com/netscape/certsrv/dbs/certdb/CertIdAdapter.java @@ -19,19 +19,20 @@ package com.netscape.certsrv.dbs.certdb; import javax.xml.bind.annotation.adapters.XmlAdapter; +import org.apache.commons.lang.StringUtils; + /** * The CertIdAdapter class provides custom marshaling for CertId. * * @author Endi S. Dewata - * @version $Revision$ $Date$ */ public class CertIdAdapter extends XmlAdapter { public CertId unmarshal(String value) throws Exception { - return new CertId(value); + return StringUtils.isEmpty(value) ? null : new CertId(value); } public String marshal(CertId value) throws Exception { - return value.toString(); + return value == null ? null : value.toHexString(); } } diff --git a/base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.java b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.java index 3232999fd..0f0c43c82 100644 --- a/base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.java +++ b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyIdAdapter.java @@ -19,19 +19,20 @@ package com.netscape.certsrv.dbs.keydb; import javax.xml.bind.annotation.adapters.XmlAdapter; +import org.apache.commons.lang.StringUtils; + /** * The KeyIdAdapter class provides custom marshaling for KeyId. * * @author Endi S. Dewata - * @version $Revision$ $Date$ */ public class KeyIdAdapter extends XmlAdapter { public KeyId unmarshal(String value) throws Exception { - return new KeyId(value); + return StringUtils.isEmpty(value) ? null : new KeyId(value); } public String marshal(KeyId value) throws Exception { - return value.toString(); + return value == null ? null : value.toString(); } } diff --git a/base/common/src/com/netscape/certsrv/request/RequestIdAdapter.java b/base/common/src/com/netscape/certsrv/request/RequestIdAdapter.java index 1780bc337..a6051fa8d 100644 --- a/base/common/src/com/netscape/certsrv/request/RequestIdAdapter.java +++ b/base/common/src/com/netscape/certsrv/request/RequestIdAdapter.java @@ -19,19 +19,20 @@ package com.netscape.certsrv.request; import javax.xml.bind.annotation.adapters.XmlAdapter; +import org.apache.commons.lang.StringUtils; + /** * The RequestIdAdapter class provides custom marshaling for RequestId. * * @author Endi S. Dewata - * @version $Revision$ $Date$ */ public class RequestIdAdapter extends XmlAdapter { public RequestId unmarshal(String value) throws Exception { - return new RequestId(value); + return StringUtils.isEmpty(value) ? null : new RequestId(value); } public String marshal(RequestId value) throws Exception { - return value.toString(); + return value == null ? null : value.toString(); } } \ No newline at end of file diff --git a/base/common/src/com/netscape/certsrv/user/UserCertData.java b/base/common/src/com/netscape/certsrv/user/UserCertData.java index d77e1dc8b..708d03430 100644 --- a/base/common/src/com/netscape/certsrv/user/UserCertData.java +++ b/base/common/src/com/netscape/certsrv/user/UserCertData.java @@ -21,7 +21,6 @@ package com.netscape.certsrv.user; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; -import java.math.BigInteger; import java.util.StringTokenizer; import javax.ws.rs.FormParam; @@ -31,10 +30,13 @@ import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.jboss.resteasy.plugins.providers.atom.Link; import com.netscape.certsrv.common.Constants; +import com.netscape.certsrv.dbs.certdb.CertId; +import com.netscape.certsrv.dbs.certdb.CertIdAdapter; /** * @author Endi S. Dewata @@ -56,7 +58,7 @@ public class UserCertData { } Integer version; - BigInteger serialNumber; + CertId serialNumber; String issuerDN; String subjectDN; String prettyPrint; @@ -76,7 +78,7 @@ public class UserCertData { public void setID(String id) { StringTokenizer st = new StringTokenizer(id, ";"); version = Integer.valueOf(st.nextToken()); - serialNumber = new BigInteger(st.nextToken()); + serialNumber = new CertId(st.nextToken()); issuerDN = st.nextToken(); subjectDN = st.nextToken(); } @@ -91,11 +93,12 @@ public class UserCertData { } @XmlElement(name="SerialNumber") - public BigInteger getSerialNumber() { + @XmlJavaTypeAdapter(CertIdAdapter.class) + public CertId getSerialNumber() { return serialNumber; } - public void setSerialNumber(BigInteger serialNumber) { + public void setSerialNumber(CertId serialNumber) { this.serialNumber = serialNumber; } @@ -240,7 +243,7 @@ public class UserCertData { UserCertData before = new UserCertData(); before.setVersion(1); - before.setSerialNumber(new BigInteger("12512514865863765114")); + before.setSerialNumber(new CertId("12512514865863765114")); before.setIssuerDN("CN=Test User,UID=testuser,O=EXAMPLE-COM"); before.setSubjectDN("CN=Test User,UID=testuser,O=EXAMPLE-COM"); before.setEncoded(sw.toString()); diff --git a/base/common/src/com/netscape/certsrv/util/DateAdapter.java b/base/common/src/com/netscape/certsrv/util/DateAdapter.java new file mode 100644 index 000000000..e01f2d98a --- /dev/null +++ b/base/common/src/com/netscape/certsrv/util/DateAdapter.java @@ -0,0 +1,40 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.certsrv.util; + +import java.util.Date; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +import org.apache.commons.lang.StringUtils; + +/** + * The DateAdapter class provides custom marshaling for Date. + * + * @author Endi S. Dewata + */ +public class DateAdapter extends XmlAdapter { + + public Date unmarshal(String value) throws Exception { + return StringUtils.isEmpty(value) ? null : new Date(Long.parseLong(value)); + } + + public String marshal(Date value) throws Exception { + return value == null ? null : Long.toString(value.getTime()); + } +} diff --git a/base/common/src/com/netscape/cms/client/user/UserAddCertCLI.java b/base/common/src/com/netscape/cms/client/user/UserAddCertCLI.java index 2370865ad..61ca60137 100644 --- a/base/common/src/com/netscape/cms/client/user/UserAddCertCLI.java +++ b/base/common/src/com/netscape/cms/client/user/UserAddCertCLI.java @@ -92,6 +92,6 @@ public class UserAddCertCLI extends CLI { MainCLI.printMessage("Added certificate \"" + userCertData.getID() + "\""); - UserCLI.printCert(userCertData); + UserCLI.printCert(userCertData, false, false); } } diff --git a/base/common/src/com/netscape/cms/client/user/UserCLI.java b/base/common/src/com/netscape/cms/client/user/UserCLI.java index a7bc752e1..e9c9acd67 100644 --- a/base/common/src/com/netscape/cms/client/user/UserCLI.java +++ b/base/common/src/com/netscape/cms/client/user/UserCLI.java @@ -125,28 +125,32 @@ public class UserCLI extends CLI { } } - public static void printCert(UserCertData userCertData) throws Exception { + public static void printCert( + UserCertData userCertData, + boolean showPrettyPrint, + boolean showEncoded) { + System.out.println(" Cert ID: " + userCertData.getID()); - System.out.println(" Serial Number: " + userCertData.getSerialNumber()); System.out.println(" Version: " + userCertData.getVersion()); - System.out.println(" Issuer DN: " + userCertData.getIssuerDN()); - System.out.println(" Subject DN: " + userCertData.getSubjectDN()); + System.out.println(" Serial Number: " + userCertData.getSerialNumber().toHexString()); + System.out.println(" Issuer: " + userCertData.getIssuerDN()); + System.out.println(" Subject: " + userCertData.getSubjectDN()); + + Link link = userCertData.getLink(); + if (verbose && link != null) { + System.out.println(" Link: " + link.getHref()); + } String prettyPrint = userCertData.getPrettyPrint(); - if (prettyPrint != null) { + if (showPrettyPrint && prettyPrint != null) { System.out.println(); System.out.println(prettyPrint); } String encoded = userCertData.getEncoded(); - if (encoded != null) { + if (showEncoded && encoded != null) { System.out.println(); System.out.println(encoded); } - - Link link = userCertData.getLink(); - if (verbose && link != null) { - System.out.println(" Link: " + link.getHref()); - } } } diff --git a/base/common/src/com/netscape/cms/client/user/UserFindCertCLI.java b/base/common/src/com/netscape/cms/client/user/UserFindCertCLI.java index 41fe3984a..c06d21faf 100644 --- a/base/common/src/com/netscape/cms/client/user/UserFindCertCLI.java +++ b/base/common/src/com/netscape/cms/client/user/UserFindCertCLI.java @@ -96,7 +96,7 @@ public class UserFindCertCLI extends CLI { System.out.println(); } - UserCLI.printCert(userCertData); + UserCLI.printCert(userCertData, false, false); } MainCLI.printMessage("Number of entries returned " + entries.size()); diff --git a/base/common/src/com/netscape/cms/client/user/UserShowCertCLI.java b/base/common/src/com/netscape/cms/client/user/UserShowCertCLI.java index 7e58fb1b0..71e14b4fc 100644 --- a/base/common/src/com/netscape/cms/client/user/UserShowCertCLI.java +++ b/base/common/src/com/netscape/cms/client/user/UserShowCertCLI.java @@ -50,6 +50,9 @@ public class UserShowCertCLI extends CLI { option.setArgName("file"); options.addOption(option); + options.addOption(null, "pretty", false, "Pretty print"); + options.addOption(null, "encoded", false, "Base-64 encoded"); + CommandLine cmd = null; try { @@ -61,6 +64,9 @@ public class UserShowCertCLI extends CLI { System.exit(1); } + boolean showPrettyPrint = cmd.hasOption("pretty"); + boolean showEncoded = cmd.hasOption("encoded"); + String[] cmdArgs = cmd.getArgs(); if (cmdArgs.length != 2) { @@ -82,6 +88,6 @@ public class UserShowCertCLI extends CLI { out.close(); } - UserCLI.printCert(userCertData); + UserCLI.printCert(userCertData, showPrettyPrint, showEncoded); } } diff --git a/base/common/src/com/netscape/cms/servlet/admin/UserCertResourceService.java b/base/common/src/com/netscape/cms/servlet/admin/UserCertResourceService.java index ebeb5b134..e0e2ddfde 100644 --- a/base/common/src/com/netscape/cms/servlet/admin/UserCertResourceService.java +++ b/base/common/src/com/netscape/cms/servlet/admin/UserCertResourceService.java @@ -42,6 +42,7 @@ import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.ICertPrettyPrint; import com.netscape.certsrv.common.OpDef; import com.netscape.certsrv.common.ScopeDef; +import com.netscape.certsrv.dbs.certdb.CertId; import com.netscape.certsrv.logging.IAuditor; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.user.UserCertCollection; @@ -68,7 +69,7 @@ public class UserCertResourceService extends CMSResourceService implements UserC UserCertData userCertData = new UserCertData(); userCertData.setVersion(cert.getVersion()); - userCertData.setSerialNumber(cert.getSerialNumber()); + userCertData.setSerialNumber(new CertId(cert.getSerialNumber())); userCertData.setIssuerDN(cert.getIssuerDN().toString()); userCertData.setSubjectDN(cert.getSubjectDN().toString()); @@ -358,7 +359,7 @@ public class UserCertResourceService extends CMSResourceService implements UserC // read the data back userCertData.setVersion(cert.getVersion()); - userCertData.setSerialNumber(cert.getSerialNumber()); + userCertData.setSerialNumber(new CertId(cert.getSerialNumber())); userCertData.setIssuerDN(cert.getIssuerDN().toString()); userCertData.setSubjectDN(cert.getSubjectDN().toString()); String certID = userCertData.getID(); diff --git a/base/common/src/com/netscape/cms/servlet/base/BadRequestException.java b/base/common/src/com/netscape/cms/servlet/base/BadRequestException.java index f33baa487..b5c5e0b12 100644 --- a/base/common/src/com/netscape/cms/servlet/base/BadRequestException.java +++ b/base/common/src/com/netscape/cms/servlet/base/BadRequestException.java @@ -23,7 +23,7 @@ public class BadRequestException extends CMSException { private static final long serialVersionUID = -4784839378360933483L; public BadRequestException(String message) { - super(Response.Status.BAD_REQUEST,message); + super(Response.Status.BAD_REQUEST, message); } public BadRequestException(String message, Throwable cause) { diff --git a/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java index d6b4a9e42..48daeca6e 100644 --- a/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java +++ b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java @@ -94,7 +94,7 @@ public class CMSResourceService { throws CertificateEncodingException { CertificateData data = new CertificateData(); String b64 = HEADER + CMS.BtoA(cert.getEncoded()) + TRAILER; - data.setB64(b64); + data.setEncoded(b64); return data; } @@ -120,7 +120,7 @@ public class CMSResourceService { null, source, level, - getClass().getSimpleName()+": " + message); + getClass().getSimpleName() + ": " + message); } public void audit(String message, String scope, String type, String id, Map params, String status) { diff --git a/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java b/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java index f035285e2..2273abc21 100644 --- a/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java +++ b/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java @@ -208,6 +208,8 @@ public abstract class CMSServlet extends HttpServlet { // members. + protected ServletConfig servletConfig; + protected boolean mRenderResult = true; protected String mFinalErrorMsg = FINAL_ERROR_MSG; protected Hashtable mTemplates = new Hashtable(); @@ -271,6 +273,9 @@ public abstract class CMSServlet extends HttpServlet { public void init(ServletConfig sc) throws ServletException { super.init(sc); + + this.servletConfig = sc; + mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ); mId = sc.getInitParameter(PROP_ID); diff --git a/base/common/src/com/netscape/cms/servlet/base/UnauthorizedException.java b/base/common/src/com/netscape/cms/servlet/base/UnauthorizedException.java new file mode 100644 index 000000000..7dfa3d6d4 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/base/UnauthorizedException.java @@ -0,0 +1,43 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cms.servlet.base; + +import javax.ws.rs.core.Response; + +/** + * @author Endi S. Dewata + */ +public class UnauthorizedException extends CMSException { + + private static final long serialVersionUID = -2025082875126996556L; + + public UnauthorizedException(String message) { + super(Response.Status.UNAUTHORIZED, message); + } + + public UnauthorizedException(String message, Throwable cause) { + super(Response.Status.UNAUTHORIZED, message, cause); + } + + public UnauthorizedException(Data data) { + super(data); + } + +} + diff --git a/base/common/src/com/netscape/cms/servlet/cert/CertResource.java b/base/common/src/com/netscape/cms/servlet/cert/CertResource.java index 9df06d8e8..1c99b3147 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/CertResource.java +++ b/base/common/src/com/netscape/cms/servlet/cert/CertResource.java @@ -1,13 +1,18 @@ package com.netscape.cms.servlet.cert; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import com.netscape.certsrv.dbs.certdb.CertId; +import com.netscape.cms.servlet.cert.model.CertRevokeRequest; +import com.netscape.cms.servlet.cert.model.CertUnrevokeRequest; import com.netscape.cms.servlet.cert.model.CertificateData; +import com.netscape.cms.servlet.request.model.CertRequestInfo; @Path("/cert") public interface CertResource { @@ -15,6 +20,23 @@ public interface CertResource { @GET @Path("{id}") @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML }) - public CertificateData retrieveCert(@PathParam("id") CertId id); + public CertificateData getCert(@PathParam("id") CertId id); + @POST + @Path("{id}/revoke-ca") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public CertRequestInfo revokeCACert(@PathParam("id") CertId id, CertRevokeRequest request); + + @POST + @Path("{id}/revoke") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public CertRequestInfo revokeCert(@PathParam("id") CertId id, CertRevokeRequest request); + + @POST + @Path("{id}/unrevoke") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public CertRequestInfo unrevokeCert(@PathParam("id") CertId id, CertUnrevokeRequest request); } diff --git a/base/common/src/com/netscape/cms/servlet/cert/CertResourceService.java b/base/common/src/com/netscape/cms/servlet/cert/CertResourceService.java index c05d61b1c..9c25a626a 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/CertResourceService.java +++ b/base/common/src/com/netscape/cms/servlet/cert/CertResourceService.java @@ -18,24 +18,54 @@ package com.netscape.cms.servlet.cert; - +import java.io.IOException; +import java.math.BigInteger; import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import netscape.security.x509.RevocationReason; +import netscape.security.x509.X509CertImpl; +import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.EDBRecordNotFoundException; import com.netscape.certsrv.dbs.certdb.CertId; +import com.netscape.certsrv.dbs.certdb.ICertRecord; +import com.netscape.certsrv.logging.AuditFormat; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.request.IRequest; import com.netscape.cms.servlet.base.BadRequestException; import com.netscape.cms.servlet.base.CMSException; import com.netscape.cms.servlet.base.CMSResourceService; +import com.netscape.cms.servlet.base.UnauthorizedException; import com.netscape.cms.servlet.cert.model.CertDAO; +import com.netscape.cms.servlet.cert.model.CertRevokeRequest; +import com.netscape.cms.servlet.cert.model.CertUnrevokeRequest; import com.netscape.cms.servlet.cert.model.CertificateData; +import com.netscape.cms.servlet.processors.Processor; +import com.netscape.cms.servlet.request.model.CertRequestDAO; +import com.netscape.cms.servlet.request.model.CertRequestInfo; import com.netscape.cms.servlet.request.model.CertRetrievalRequestData; /** * @author alee * */ -public class CertResourceService extends CMSResourceService implements CertResource{ +public class CertResourceService extends CMSResourceService implements CertResource { + + ICertificateAuthority authority; + + public CertResourceService() { + authority = (ICertificateAuthority) CMS.getSubsystem("ca"); + } + + public CertDAO createDAO() { + CertDAO dao = new CertDAO(); + dao.setLocale(getLocale()); + dao.setUriInfo(uriInfo); + return dao; + } private void validateRequest(CertId id) { @@ -46,27 +76,206 @@ public class CertResourceService extends CMSResourceService implements CertResou } @Override - public CertificateData retrieveCert(CertId id) { + public CertificateData getCert(CertId id) { validateRequest(id); CertRetrievalRequestData data = new CertRetrievalRequestData(); data.setCertId(id); - CertDAO dao = new CertDAO(); + CertDAO dao = createDAO(); CertificateData certData = null; try { certData = dao.getCert(data); - } catch(EDBRecordNotFoundException e) { + } catch (EDBRecordNotFoundException e) { throw new CertNotFoundException(id); - } catch (EBaseException e) { + } catch (EBaseException e) { throw new CMSException("Problem returning certificate: " + id); - } catch(CertificateEncodingException e) { + } catch (CertificateEncodingException e) { throw new CMSException("Problem encoding certificate searched for: " + id); } return certData; } + + @Override + public CertRequestInfo revokeCACert(CertId id, CertRevokeRequest request) { + return revokeCert(id, request, true); + } + + @Override + public CertRequestInfo revokeCert(CertId id, CertRevokeRequest request) { + return revokeCert(id, request, false); + } + + public CertRequestInfo revokeCert(CertId id, CertRevokeRequest request, boolean caCert) { + + RevocationReason revReason = request.getReason(); + if (revReason == RevocationReason.REMOVE_FROM_CRL) { + CertUnrevokeRequest unrevRequest = new CertUnrevokeRequest(); + unrevRequest.setRequestID(request.getRequestID()); + return unrevokeCert(id, unrevRequest); + } + + RevocationProcessor processor; + try { + processor = new RevocationProcessor("caDoRevoke-agent", getLocale()); + processor.setStartTime(CMS.getCurrentDate().getTime()); + + // TODO: set initiative based on auth info + processor.setInitiative(AuditFormat.FROMAGENT); + + processor.setSerialNumber(id); + processor.setRequestID(request.getRequestID()); + + processor.setRevocationReason(revReason); + processor.setRequestType(revReason == RevocationReason.CERTIFICATE_HOLD + ? RevocationProcessor.ON_HOLD : RevocationProcessor.REVOKE); + processor.setInvalidityDate(request.getInvalidityDate()); + processor.setComments(request.getComments()); + + processor.setAuthority(authority); + + } catch (EBaseException e) { + throw new CMSException(e.getMessage()); + } + + try { + X509Certificate clientCert = null; + try { + clientCert = Processor.getSSLClientCertificate(servletRequest); + } catch (EBaseException e) { + // No client certificate, ignore. + } + + ICertRecord clientRecord = null; + BigInteger clientSerialNumber = null; + String clientSubjectDN = null; + + if (clientCert != null) { + clientSerialNumber = clientCert.getSerialNumber(); + clientSubjectDN = clientCert.getSubjectDN().toString(); + clientRecord = processor.getCertificateRecord(clientSerialNumber); + + // Verify client cert is not revoked. + // TODO: This should be checked during authentication. + if (clientRecord.getStatus().equals(ICertRecord.STATUS_REVOKED)) { + throw new UnauthorizedException(CMS.getLogMessage("CMSGW_UNAUTHORIZED")); + } + } + + // Find target cert record if different from client cert. + ICertRecord targetRecord = id.equals(clientSerialNumber) ? clientRecord : processor.getCertificateRecord(id); + X509CertImpl targetCert = targetRecord.getCertificate(); + + processor.createCRLExtension(); + processor.validateCertificateToRevoke(clientSubjectDN, targetRecord, caCert); + processor.addCertificateToRevoke(targetCert); + processor.createRevocationRequest(); + + processor.auditChangeRequest(ILogger.SUCCESS); + + } catch (CMSException e) { + processor.log(ILogger.LL_FAILURE, e.getMessage()); + processor.auditChangeRequest(ILogger.FAILURE); + throw e; + + } catch (EBaseException e) { + processor.log(ILogger.LL_FAILURE, "Error " + e); + processor.auditChangeRequest(ILogger.FAILURE); + + throw new CMSException(e.getMessage()); + + } catch (IOException e) { + processor.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED_1", e.toString())); + processor.auditChangeRequest(ILogger.FAILURE); + + throw new CMSException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED")); + } + + // change audit processing from "REQUEST" to "REQUEST_PROCESSED" + // to distinguish which type of signed audit log message to save + // as a failure outcome in case an exception occurs + + try { + processor.processRevocationRequest(); + + processor.auditChangeRequestProcessed(ILogger.SUCCESS); + + } catch (EBaseException e) { + processor.log(ILogger.LL_FAILURE, "Error " + e); + processor.auditChangeRequestProcessed(ILogger.FAILURE); + + throw new CMSException(e.getMessage()); + } + + try { + IRequest certRequest = processor.getRequest(); + CertRequestDAO dao = new CertRequestDAO(); + return dao.getRequest(certRequest.getRequestId(), uriInfo); + + } catch (EBaseException e) { + throw new CMSException(e.getMessage()); + } + } + + @Override + public CertRequestInfo unrevokeCert(CertId id, CertUnrevokeRequest request) { + + RevocationProcessor processor; + try { + processor = new RevocationProcessor("caDoUnrevoke", getLocale()); + + // TODO: set initiative based on auth info + processor.setInitiative(AuditFormat.FROMAGENT); + + processor.setSerialNumber(id); + processor.setRequestID(request.getRequestID()); + processor.setRevocationReason(RevocationReason.CERTIFICATE_HOLD); + processor.setAuthority(authority); + + } catch (EBaseException e) { + throw new CMSException(e.getMessage()); + } + + try { + processor.addSerialNumberToUnrevoke(id.toBigInteger()); + processor.createUnrevocationRequest(); + + processor.auditChangeRequest(ILogger.SUCCESS); + + } catch (EBaseException e) { + processor.log(ILogger.LL_FAILURE, "Error " + e); + processor.auditChangeRequest(ILogger.FAILURE); + + throw new CMSException(e.getMessage()); + } + + // change audit processing from "REQUEST" to "REQUEST_PROCESSED" + // to distinguish which type of signed audit log message to save + // as a failure outcome in case an exception occurs + + try { + processor.processUnrevocationRequest(); + + processor.auditChangeRequestProcessed(ILogger.SUCCESS); + + } catch (EBaseException e) { + processor.log(ILogger.LL_FAILURE, "Error " + e); + processor.auditChangeRequestProcessed(ILogger.FAILURE); + + throw new CMSException(e.getMessage()); + } + + try { + IRequest certRequest = processor.getRequest(); + CertRequestDAO dao = new CertRequestDAO(); + return dao.getRequest(certRequest.getRequestId(), uriInfo); + + } catch (EBaseException e) { + throw new CMSException(e.getMessage()); + } + } } diff --git a/base/common/src/com/netscape/cms/servlet/cert/CertsResourceService.java b/base/common/src/com/netscape/cms/servlet/cert/CertsResourceService.java index ed503dad4..60daee11f 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/CertsResourceService.java +++ b/base/common/src/com/netscape/cms/servlet/cert/CertsResourceService.java @@ -38,6 +38,13 @@ import com.netscape.cmsutil.ldap.LDAPUtil; */ public class CertsResourceService extends CMSResourceService implements CertsResource { + public CertDAO createDAO() { + CertDAO dao = new CertDAO(); + dao.setLocale(getLocale()); + dao.setUriInfo(uriInfo); + return dao; + } + private String createSearchFilter(String status) { String filter = ""; @@ -70,10 +77,10 @@ public class CertsResourceService extends CMSResourceService implements CertsRes String filter = createSearchFilter(status); CMS.debug("listKeys: filter is " + filter); - CertDAO dao = new CertDAO(); + CertDAO dao = createDAO(); CertDataInfos infos; try { - infos = dao.listCerts(filter, maxResults, maxTime, uriInfo); + infos = dao.listCerts(filter, maxResults, maxTime); } catch (EBaseException e) { e.printStackTrace(); throw new CMSException("Error listing certs in CertsResourceService.listCerts!"); @@ -88,11 +95,11 @@ public class CertsResourceService extends CMSResourceService implements CertsRes throw new WebApplicationException(Response.Status.BAD_REQUEST); } String filter = createSearchFilter(data); - CertDAO dao = new CertDAO(); + CertDAO dao = createDAO(); CertDataInfos infos; try { - infos = dao.listCerts(filter, maxResults, maxTime, uriInfo); + infos = dao.listCerts(filter, maxResults, maxTime); } catch (EBaseException e) { e.printStackTrace(); throw new CMSException("Error listing certs in CertsResourceService.listCerts!"); diff --git a/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java b/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java new file mode 100644 index 000000000..3f0fffbf4 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java @@ -0,0 +1,501 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cms.servlet.cert; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.Principal; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Locale; + +import netscape.security.x509.CRLExtensions; +import netscape.security.x509.CRLReasonExtension; +import netscape.security.x509.InvalidityDateExtension; +import netscape.security.x509.RevocationReason; +import netscape.security.x509.RevokedCertImpl; +import netscape.security.x509.X509CertImpl; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.EPropertyNotFound; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.dbs.certdb.CertId; +import com.netscape.certsrv.dbs.certdb.ICertRecord; +import com.netscape.certsrv.dbs.certdb.ICertificateRepository; +import com.netscape.certsrv.logging.AuditFormat; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.publish.IPublisherProcessor; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.IRequestQueue; +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; +import com.netscape.cms.servlet.base.BadRequestException; +import com.netscape.cms.servlet.base.UnauthorizedException; + +/** + * @author Endi S. Dewata + */ +public class RevocationProcessor extends CertProcessor { + + public final static String REVOKE = "revoke"; + public final static String ON_HOLD = "on-hold"; + public final static String OFF_HOLD = "off-hold"; + + public final static String LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST = + "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5"; + public final static String LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED = + "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7"; + + long startTime; + + ICertificateAuthority authority; + ICertificateRepository repo; + IRequestQueue requestQueue; + IPublisherProcessor publisherProcessor; + + String initiative; + RequestId requestID; + CertId serialNumber; + RevocationReason revocationReason; + Date invalidityDate; + String comments; + String requestType; + + CRLExtensions entryExtn; + Collection certificates = new ArrayList(); + Collection revCertImpls = new ArrayList(); + IRequest request; + RequestStatus requestStatus; + + public RevocationProcessor(String id, Locale locale) throws EPropertyNotFound, EBaseException { + super(id, locale); + } + + public ICertificateAuthority getAuthority() { + return authority; + } + + public void setAuthority(ICertificateAuthority authority) { + this.authority = authority; + repo = authority.getCertificateRepository(); + requestQueue = authority.getRequestQueue(); + publisherProcessor = authority.getPublisherProcessor(); + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public String getInitiative() { + return initiative; + } + + public void setInitiative(String initiative) { + this.initiative = initiative; + } + + public RequestId getRequestID() { + return requestID; + } + + public void setRequestID(RequestId requestID) { + this.requestID = requestID; + } + + public CertId getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(CertId serialNumber) { + this.serialNumber = serialNumber; + } + + public RevocationReason getRevocationReason() { + return revocationReason; + } + + public void setRevocationReason(RevocationReason revocationReason) { + this.revocationReason = revocationReason; + } + + public Date getInvalidityDate() { + return invalidityDate; + } + + public void setInvalidityDate(Date invalidityDate) { + this.invalidityDate = invalidityDate; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public String getRequestType() { + return requestType; + } + + public void setRequestType(String requestType) { + this.requestType = requestType; + } + + public RequestStatus getRequestStatus() { + return requestStatus; + } + + public void setRequestStatus(RequestStatus requestStatus) { + this.requestStatus = requestStatus; + } + + public void addCertificate(X509CertImpl cert) { + certificates.add(cert); + } + + public Collection getCertificates() { + return certificates; + } + + public IRequest getRequest() { + return request; + } + + public void validateCertificateToRevoke(String clientSubjectDN, ICertRecord targetRecord, boolean revokingCACert) { + + X509CertImpl targetCert = targetRecord.getCertificate(); + BigInteger targetSerialNumber = targetCert.getSerialNumber(); + Principal targetSubjectDN = targetCert.getSubjectDN(); + + // Verify client cert's subject DN matches the target cert's subject DN. + if (clientSubjectDN != null && !clientSubjectDN.equals(targetSubjectDN.toString())) { + throw new UnauthorizedException( + "Certificate 0x" + targetSerialNumber.toString(16) + " belongs to different subject."); + } + + boolean targetIsCACert = isSystemCertificate(targetCert); + + // If not revoking CA cert verify target cert is not CA cert. + if (!revokingCACert && targetIsCACert) { + throw new UnauthorizedException( + "Certificate 0x" + targetSerialNumber.toString(16) + " is a CA signing certificate"); + } + + // If revoking CA Cert verify target cert is CA cert. + if (revokingCACert && !targetIsCACert) { + throw new UnauthorizedException( + "Certificate 0x" + targetSerialNumber.toString(16) + " is not a CA signing certificate"); + } + + // Verify target cert is not already revoked. + if (targetRecord.getStatus().equals(ICertRecord.STATUS_REVOKED)) { + throw new BadRequestException( + CMS.getLogMessage("CA_CERTIFICATE_ALREADY_REVOKED_1", targetSerialNumber.toString(16))); + } + } + + public void addCertificateToRevoke(X509CertImpl cert) { + addCertificate(cert); + revCertImpls.add(new RevokedCertImpl(cert.getSerialNumber(), CMS.getCurrentDate(), entryExtn)); + } + + public void addSerialNumberToUnrevoke(BigInteger serialNumber) throws EBaseException { + ICertRecord record = getCertificateRecord(serialNumber); + X509CertImpl cert = record.getCertificate(); + addCertificate(cert); + } + + public ICertRecord[] getCertificateRecords(BigInteger[] serialNumbers) throws EBaseException { + ICertRecord[] records = new ICertRecord[serialNumbers.length]; + for (int i=0; i serialNumbers = new ArrayList(); + for (X509CertImpl cert : certificates) { + serialNumbers.add(cert.getSerialNumber()); + } + request.setExtData(IRequest.OLD_SERIALS, serialNumbers.toArray(new BigInteger[serialNumbers.size()])); + request.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT); + } + + public void processUnrevocationRequest() throws EBaseException { + + requestQueue.processRequest(request); + requestStatus = request.getRequestStatus(); + + String type = request.getRequestType(); + + if (requestStatus == RequestStatus.COMPLETE + || requestStatus == RequestStatus.SVC_PENDING && type.equals(IRequest.CLA_UNCERT4CRL_REQUEST)) { + + Integer result = request.getExtDataInInteger(IRequest.RESULT); + + if (result != null && result.equals(IRequest.RES_SUCCESS)) { + for (X509CertImpl cert : certificates) { + logUnrevoke(request, cert, "completed"); + } + + } else { + String error = request.getExtDataInString(IRequest.ERROR); + for (X509CertImpl cert : certificates) { + logUnrevoke(request, cert, "completed with error: " + error); + } + } + + } else { + for (X509CertImpl cert : certificates) { + logUnrevoke(request, cert, requestStatus.toString()); + } + } + } + + /** + * A system certificate such as the CA signing certificate + * should not be allowed to delete. + * The main purpose is to avoid revoking the self signed + * CA certificate accidentally. + */ + public boolean isSystemCertificate(X509Certificate cert) { + + X509Certificate caCert = authority.getCACert(); + if (caCert == null) + return false; + + // check whether it's a CA certificate + if (!caCert.getSerialNumber().equals(cert.getSerialNumber())) + return false; + + // check whether it's a self-signed we certificate + return caCert.getSubjectDN().equals(caCert.getIssuerDN()); + } + + public void logRevoke(IRequest revocationRequest, X509Certificate cert, String status, String message) { + + if (logger == null) + return; + + logger.log( + ILogger.EV_AUDIT, + ILogger.S_OTHER, + AuditFormat.LEVEL, + AuditFormat.DOREVOKEFORMAT, + new Object[] { + revocationRequest.getRequestId(), + initiative, + status, + cert.getSubjectDN(), + cert.getSerialNumber().toString(16), + message + }); + } + + public void logUnrevoke(IRequest unrevocationRequest, X509Certificate cert, String status) { + + if (logger == null) + return; + + logger.log( + ILogger.EV_AUDIT, + ILogger.S_OTHER, + AuditFormat.LEVEL, + AuditFormat.DOUNREVOKEFORMAT, + new Object[] { + unrevocationRequest.getRequestId(), + initiative, + status, + cert.getSubjectDN(), + cert.getSerialNumber().toString(16), + }); + } + + public void auditChangeRequest(String status) { + + if (auditor == null) + return; + + String auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST, + auditor.getSubjectID(), + status, + requestID == null ? ILogger.UNIDENTIFIED : requestID.toString(), + serialNumber == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : serialNumber.toHexString(), + requestType); + + auditor.log(auditMessage); + } + + public void auditChangeRequestProcessed(String status) { + + if (auditor == null) + return; + + // store a message in the signed audit log file + // if and only if "requestStatus" is + // "complete", "revoked", or "canceled" + + if (!(requestStatus == RequestStatus.COMPLETE + || requestStatus == RequestStatus.REJECTED + || requestStatus == RequestStatus.CANCELED)) return; + + String auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED, + auditor.getSubjectID(), + status, + requestID == null ? ILogger.UNIDENTIFIED : requestID.toString(), + serialNumber == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : serialNumber.toHexString(), + requestType, + String.valueOf(revocationReason.toInt()), + requestStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : requestStatus.toString()); + + auditor.log(auditMessage); + } + + public void log(int level, String message) { + log(ILogger.S_CA, level, message); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/cert/model/CertDAO.java b/base/common/src/com/netscape/cms/servlet/cert/model/CertDAO.java index e71055580..1177b66f6 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/model/CertDAO.java +++ b/base/common/src/com/netscape/cms/servlet/cert/model/CertDAO.java @@ -18,7 +18,7 @@ package com.netscape.cms.servlet.cert.model; import java.io.ByteArrayOutputStream; -import java.math.BigInteger; +import java.net.URI; import java.security.Principal; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; @@ -26,9 +26,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.List; +import java.util.Locale; -import javax.ws.rs.Path; -import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import netscape.security.pkcs.ContentInfo; @@ -37,8 +36,11 @@ import netscape.security.pkcs.SignerInfo; import netscape.security.x509.AlgorithmId; import netscape.security.x509.X509CertImpl; +import org.jboss.resteasy.plugins.providers.atom.Link; + import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.ICertPrettyPrint; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.certdb.CertId; import com.netscape.certsrv.dbs.certdb.ICertRecord; @@ -53,6 +55,9 @@ import com.netscape.cmsutil.util.Utils; */ public class CertDAO { + Locale locale; + UriInfo uriInfo; + private ICertificateRepository repo; private ICertificateAuthority ca; @@ -61,6 +66,22 @@ public class CertDAO { repo = ca.getCertificateRepository(); } + public Locale getLocale() { + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public UriInfo getUriInfo() { + return uriInfo; + } + + public void setUriInfo(UriInfo uriInfo) { + this.uriInfo = uriInfo; + } + /** * Returns list of certs meeting specified search filter. * Currently, vlv searches are not used for certs. @@ -72,7 +93,7 @@ public class CertDAO { * @return * @throws EBaseException */ - public CertDataInfos listCerts(String filter, int maxResults, int maxTime, UriInfo uriInfo) + public CertDataInfos listCerts(String filter, int maxResults, int maxTime) throws EBaseException { List list = new ArrayList(); Enumeration e = null; @@ -85,7 +106,7 @@ public class CertDAO { while (e.hasMoreElements()) { ICertRecord rec = e.nextElement(); if (rec != null) { - list.add(createCertDataInfo(rec, uriInfo)); + list.add(createCertDataInfo(rec)); } } @@ -97,96 +118,61 @@ public class CertDAO { public CertificateData getCert(CertRetrievalRequestData data) throws EBaseException, CertificateEncodingException { - CertificateData certData = null; CertId certId = data.getCertId(); //find the cert in question + ICertRecord record = repo.readCertificateRecord(certId.toBigInteger()); + X509CertImpl cert = record.getCertificate(); - ICertRecord rec = null; - BigInteger seq = certId.toBigInteger(); - - rec = repo.readCertificateRecord(seq); - X509CertImpl x509cert = null; - - if (rec != null) { - x509cert = rec.getCertificate(); - } - - if (x509cert != null) { - certData = new CertificateData(); - - byte[] ba = null; - String encoded64 = null; + CertificateData certData = new CertificateData(); - ba = x509cert.getEncoded(); + certData.setSerialNumber(certId); - encoded64 = Utils.base64encode(ba); + Principal issuerDN = cert.getIssuerDN(); + if (issuerDN != null) certData.setIssuerDN(issuerDN.toString()); - String prettyPrint = x509cert.toString(); + Principal subjectDN = cert.getSubjectDN(); + if (subjectDN != null) certData.setSubjectDN(subjectDN.toString()); - certData.setB64(encoded64); - certData.setPrettyPrint(prettyPrint); + String base64 = CMS.getEncodedCert(cert); + certData.setEncoded(base64); - String subjectNameStr = null; - Principal subjectName = x509cert.getSubjectDN(); - - if (subjectName != null) { - subjectNameStr = subjectName.toString(); - } + ICertPrettyPrint print = CMS.getCertPrettyPrint(cert); + certData.setPrettyPrint(print.toString(locale)); - certData.setSubjectName(subjectNameStr); + String p7Str = getCertChainData(cert); + certData.setPkcs7CertChain(p7Str); - //Try to get the chain + Date notBefore = cert.getNotBefore(); + if (notBefore != null) certData.setNotBefore(notBefore.toString()); - String p7Str = getCertChainData(x509cert); + Date notAfter = cert.getNotAfter(); + if (notAfter != null) certData.setNotAfter(notAfter.toString()); - certData.setPkcs7CertChain(p7Str); + certData.setStatus(record.getStatus()); - certData.setSerialNo(certId); + URI uri = uriInfo.getBaseUriBuilder().path(CertResource.class).path("{id}").build(certId.toHexString()); + certData.setLink(new Link("self", uri)); - Date notBefore = x509cert.getNotBefore(); - Date notAfter = x509cert.getNotAfter(); - - String notBeforeStr = null; - String notAfterStr = null; - - if (notBefore != null) { - notBeforeStr = notBefore.toString(); - } - - if (notAfter != null) { - notAfterStr = notAfter.toString(); - } - - certData.setNotBefore(notBeforeStr); - certData.setNotAfter(notAfterStr); - - String issuerNameStr = null; - - Principal issuerName = x509cert.getIssuerDN(); - - if (issuerName != null) { - issuerNameStr = issuerName.toString(); - } + return certData; + } - certData.setIssuerName(issuerNameStr); + private CertDataInfo createCertDataInfo(ICertRecord record) throws EBaseException { - } + CertDataInfo info = new CertDataInfo(); - return certData; - } + CertId id = new CertId(record.getSerialNumber()); + info.setID(id); - private CertDataInfo createCertDataInfo(ICertRecord rec, UriInfo uriInfo) throws EBaseException { - CertDataInfo ret = new CertDataInfo(); + X509Certificate cert = record.getCertificate(); + info.setSubjectDN(cert.getSubjectDN().toString()); - Path certPath = CertResource.class.getAnnotation(Path.class); - BigInteger serial = rec.getSerialNumber(); + info.setStatus(record.getStatus()); - UriBuilder certBuilder = uriInfo.getBaseUriBuilder(); - certBuilder.path(certPath.value() + "/" + serial); - ret.setCertURL(certBuilder.build().toString()); + URI uri = uriInfo.getBaseUriBuilder().path(CertResource.class).path("{id}").build(id.toHexString()); + info.setLink(new Link("self", uri)); - return ret; + return info; } private String getCertChainData(X509CertImpl x509cert) { diff --git a/base/common/src/com/netscape/cms/servlet/cert/model/CertDataInfo.java b/base/common/src/com/netscape/cms/servlet/cert/model/CertDataInfo.java index 0f8d35e05..4c6a9b19e 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/model/CertDataInfo.java +++ b/base/common/src/com/netscape/cms/servlet/cert/model/CertDataInfo.java @@ -20,48 +20,154 @@ */ package com.netscape.cms.servlet.cert.model; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.jboss.resteasy.plugins.providers.atom.Link; import com.netscape.certsrv.dbs.certdb.CertId; +import com.netscape.certsrv.dbs.certdb.CertIdAdapter; /** * @author alee * */ @XmlRootElement(name = "CertDataInfo") -@XmlAccessorType(XmlAccessType.FIELD) public class CertDataInfo { - @XmlElement - protected String certURL; + public static Marshaller marshaller; + public static Unmarshaller unmarshaller; + + static { + try { + JAXBContext context = JAXBContext.newInstance(CertDataInfo.class); + marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + unmarshaller = context.createUnmarshaller(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + CertId id; + String subjectDN; + String status; + + Link link; + + @XmlAttribute(name="id") + @XmlJavaTypeAdapter(CertIdAdapter.class) + public CertId getID() { + return id; + } + + public void setID(CertId id) { + this.id = id; + } + + @XmlElement(name="SubjectDN") + public String getSubjectDN() { + return subjectDN; + } + + public void setSubjectDN(String subjectDN) { + this.subjectDN = subjectDN; + } + + @XmlElement(name="Status") + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @XmlElement(name="Link") + public Link getLink() { + return link; + } + + public void setLink(Link link) { + this.link = link; + } - public CertDataInfo() { - // required for JAXB (defaults) + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + ((subjectDN == null) ? 0 : subjectDN.hashCode()); + return result; } - /** - * @return the CertURL - */ - public String getCertURL() { - return certURL; + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CertDataInfo other = (CertDataInfo) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + if (subjectDN == null) { + if (other.subjectDN != null) + return false; + } else if (!subjectDN.equals(other.subjectDN)) + return false; + return true; } - /** - * @param CertURL the certURL to set - */ - public void setCertURL(String certURL) { - this.certURL = certURL; + public String toString() { + try { + StringWriter sw = new StringWriter(); + marshaller.marshal(this, sw); + return sw.toString(); + + } catch (Exception e) { + return super.toString(); + } } - /** - * @return the Cert ID in the CertURL - */ - public CertId getCertId() { - String id = certURL.substring(certURL.lastIndexOf("/") + 1); - return new CertId(id); + public static CertDataInfo valueOf(String string) throws Exception { + try { + return (CertDataInfo)unmarshaller.unmarshal(new StringReader(string)); + } catch (Exception e) { + return null; + } } + public static void main(String args[]) throws Exception { + + CertDataInfo before = new CertDataInfo(); + before.setID(new CertId("12512514865863765114")); + before.setSubjectDN("CN=Test User,UID=testuser,O=EXAMPLE-COM"); + before.setStatus("VALID"); + + String string = before.toString(); + System.out.println(string); + + CertDataInfo after = CertDataInfo.valueOf(string); + + System.out.println(before.equals(after)); + } } diff --git a/base/common/src/com/netscape/cms/servlet/cert/model/CertRevokeRequest.java b/base/common/src/com/netscape/cms/servlet/cert/model/CertRevokeRequest.java new file mode 100644 index 000000000..ef9ccebc3 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/cert/model/CertRevokeRequest.java @@ -0,0 +1,205 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cms.servlet.cert.model; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Date; + +import javax.ws.rs.FormParam; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import netscape.security.x509.RevocationReason; +import netscape.security.x509.RevocationReasonAdapter; + +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestIdAdapter; +import com.netscape.certsrv.util.DateAdapter; + +/** + * @author Endi S. Dewata + */ +@XmlRootElement(name="CertRevokeRequest") +public class CertRevokeRequest { + + public static Marshaller marshaller; + public static Unmarshaller unmarshaller; + + static { + try { + JAXBContext context = JAXBContext.newInstance(CertRevokeRequest.class); + marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + unmarshaller = context.createUnmarshaller(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + RequestId requestID; + RevocationReason reason; + Date invalidityDate; + String comments; + String encoded; + + + @XmlElement(name="RequestID") + @FormParam("requestId") + @XmlJavaTypeAdapter(RequestIdAdapter.class) + public RequestId getRequestID() { + return requestID; + } + + public void setRequestID(RequestId requestID) { + this.requestID = requestID; + } + + @XmlElement(name="Reason") + @FormParam("revocationReason") + @XmlJavaTypeAdapter(RevocationReasonAdapter.class) + public RevocationReason getReason() { + return reason; + } + + public void setReason(RevocationReason reason) { + this.reason = reason; + } + + @XmlElement(name="InvalidityDate") + @FormParam("invalidityDate") + @XmlJavaTypeAdapter(DateAdapter.class) + public Date getInvalidityDate() { + return invalidityDate; + } + + public void setInvalidityDate(Date invalidityDate) { + this.invalidityDate = invalidityDate; + } + + @XmlElement(name="Comments") + @FormParam(IRequest.REQUESTOR_COMMENTS) + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + @XmlElement(name="Encoded") + @FormParam("b64eCertificate") + public String getEncoded() { + return encoded; + } + + public void setEncoded(String encoded) { + this.encoded = encoded; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((comments == null) ? 0 : comments.hashCode()); + result = prime * result + ((encoded == null) ? 0 : encoded.hashCode()); + result = prime * result + ((invalidityDate == null) ? 0 : invalidityDate.hashCode()); + result = prime * result + ((reason == null) ? 0 : reason.hashCode()); + result = prime * result + ((requestID == null) ? 0 : requestID.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CertRevokeRequest other = (CertRevokeRequest) obj; + if (comments == null) { + if (other.comments != null) + return false; + } else if (!comments.equals(other.comments)) + return false; + if (encoded == null) { + if (other.encoded != null) + return false; + } else if (!encoded.equals(other.encoded)) + return false; + if (invalidityDate == null) { + if (other.invalidityDate != null) + return false; + } else if (!invalidityDate.equals(other.invalidityDate)) + return false; + if (reason == null) { + if (other.reason != null) + return false; + } else if (!reason.equals(other.reason)) + return false; + if (requestID == null) { + if (other.requestID != null) + return false; + } else if (!requestID.equals(other.requestID)) + return false; + return true; + } + + public String toString() { + try { + StringWriter sw = new StringWriter(); + marshaller.marshal(this, sw); + return sw.toString(); + + } catch (Exception e) { + return super.toString(); + } + } + + public static CertRevokeRequest valueOf(String string) throws Exception { + try { + return (CertRevokeRequest)unmarshaller.unmarshal(new StringReader(string)); + } catch (Exception e) { + return null; + } + } + + public static void main(String args[]) throws Exception { + + CertRevokeRequest before = new CertRevokeRequest(); + before.setRequestID(new RequestId("42323234")); + before.setReason(RevocationReason.CERTIFICATE_HOLD); + before.setInvalidityDate(new Date()); + before.setComments("test"); + before.setEncoded("test"); + + String string = before.toString(); + System.out.println(string); + + CertRevokeRequest after = CertRevokeRequest.valueOf(string); + + System.out.println(before.equals(after)); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/cert/model/CertUnrevokeRequest.java b/base/common/src/com/netscape/cms/servlet/cert/model/CertUnrevokeRequest.java new file mode 100644 index 000000000..98d24d363 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/cert/model/CertUnrevokeRequest.java @@ -0,0 +1,124 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cms.servlet.cert.model; + +import java.io.StringReader; +import java.io.StringWriter; + +import javax.ws.rs.FormParam; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestIdAdapter; + +/** + * @author Endi S. Dewata + */ +@XmlRootElement(name="CertUnrevokeRequest") +public class CertUnrevokeRequest { + + public static Marshaller marshaller; + public static Unmarshaller unmarshaller; + + static { + try { + JAXBContext context = JAXBContext.newInstance(CertUnrevokeRequest.class); + marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + unmarshaller = context.createUnmarshaller(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + RequestId requestID; + + @XmlElement(name="requestID") + @FormParam("requestId") + @XmlJavaTypeAdapter(RequestIdAdapter.class) + public RequestId getRequestID() { + return requestID; + } + + public void setRequestID(RequestId requestID) { + this.requestID = requestID; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((requestID == null) ? 0 : requestID.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CertUnrevokeRequest other = (CertUnrevokeRequest) obj; + if (requestID == null) { + if (other.requestID != null) + return false; + } else if (!requestID.equals(other.requestID)) + return false; + return true; + } + + public String toString() { + try { + StringWriter sw = new StringWriter(); + marshaller.marshal(this, sw); + return sw.toString(); + + } catch (Exception e) { + return super.toString(); + } + } + + public static CertUnrevokeRequest valueOf(String string) throws Exception { + try { + return (CertUnrevokeRequest)unmarshaller.unmarshal(new StringReader(string)); + } catch (Exception e) { + return null; + } + } + + public static void main(String args[]) throws Exception { + + CertUnrevokeRequest before = new CertUnrevokeRequest(); + before.setRequestID(new RequestId("42323234")); + + String string = before.toString(); + System.out.println(string); + + CertUnrevokeRequest after = CertUnrevokeRequest.valueOf(string); + + System.out.println(before.equals(after)); + } +} diff --git a/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java b/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java index cb6ed937d..bfdb894cb 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java +++ b/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java @@ -17,12 +17,20 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.cert.model; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.jboss.resteasy.plugins.providers.atom.Link; + import com.netscape.certsrv.dbs.certdb.CertId; import com.netscape.certsrv.dbs.certdb.CertIdAdapter; @@ -31,51 +39,62 @@ import com.netscape.certsrv.dbs.certdb.CertIdAdapter; * */ @XmlRootElement(name = "CertificateData") -@XmlAccessorType(XmlAccessType.FIELD) public class CertificateData { - @XmlElement - private String b64; - @XmlElement - private String prettyPrint; + public static Marshaller marshaller; + public static Unmarshaller unmarshaller; - @XmlElement - private String subjectName; + static { + try { + marshaller = JAXBContext.newInstance(CertificateData.class).createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + unmarshaller = JAXBContext.newInstance(CertificateData.class).createUnmarshaller(); + } catch (Exception e) { + e.printStackTrace(); + } + } - @XmlElement - private String pkcs7CertChain; + CertId serialNumber; + String issuerDN; + String subjectDN; + String prettyPrint; + String encoded; + String pkcs7CertChain; + String notBefore; + String notAfter; + String status; - @XmlElement - @XmlJavaTypeAdapter(CertIdAdapter.class) - private CertId serialNo; + Link link; - @XmlElement - private String notBefore; + @XmlAttribute(name="id") + @XmlJavaTypeAdapter(CertIdAdapter.class) + public CertId getSerialNumber() { + return serialNumber; + } - @XmlElement - private String notAfter; + public void setSerialNumber(CertId serialNumber) { + this.serialNumber = serialNumber; + } - @XmlElement - private String issuerName; + @XmlElement(name="IssuerDN") + public String getIssuerDN() { + return issuerDN; + } - public CertificateData() { - // required for jaxb + public void setIssuerDN(String issuerDN) { + this.issuerDN = issuerDN; } - /** - * @return the b64 - */ - public String getB64() { - return b64; + @XmlElement(name="SubjectDN") + public String getSubjectDN() { + return subjectDN; } - /** - * @param b64 the b64 to set - */ - public void setB64(String b64) { - this.b64 = b64; + public void setSubjectDN(String subjectDN) { + this.subjectDN = subjectDN; } + @XmlElement(name="PrettyPrint") public String getPrettyPrint() { return prettyPrint; } @@ -84,30 +103,25 @@ public class CertificateData { this.prettyPrint = prettyPrint; } - public void setPkcs7CertChain(String chain) { - this.pkcs7CertChain = chain; - } - - public String getPkcs7CertChain() { - return pkcs7CertChain; - } - - public String getSubjectName() { - return subjectName; + @XmlElement(name="Encoded") + public String getEncoded() { + return encoded; } - public void setSubjectName(String subjectName) { - this.subjectName = subjectName; + public void setEncoded(String encoded) { + this.encoded = encoded; } - public CertId getSerialNo() { - return serialNo; + @XmlElement(name="PKCS7CertChain") + public void setPkcs7CertChain(String chain) { + this.pkcs7CertChain = chain; } - public void setSerialNo(CertId serialNo) { - this.serialNo = serialNo; + public String getPkcs7CertChain() { + return pkcs7CertChain; } + @XmlElement(name="NotBefore") public String getNotBefore() { return notBefore; } @@ -116,6 +130,7 @@ public class CertificateData { this.notBefore = notBefore; } + @XmlElement(name="NotAfter") public String getNotAfter() { return notAfter; } @@ -124,12 +139,145 @@ public class CertificateData { this.notAfter = notAfter; } - public String getIssuerName() { - return issuerName; + @XmlElement(name="Status") + public String getStatus() { + return status; } - public void setIssuerName(String issuerName) { - this.issuerName = issuerName; + public void setStatus(String status) { + this.status = status; } + @XmlElement(name="Link") + public Link getLink() { + return link; + } + + public void setLink(Link link) { + this.link = link; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((encoded == null) ? 0 : encoded.hashCode()); + result = prime * result + ((issuerDN == null) ? 0 : issuerDN.hashCode()); + result = prime * result + ((notAfter == null) ? 0 : notAfter.hashCode()); + result = prime * result + ((notBefore == null) ? 0 : notBefore.hashCode()); + result = prime * result + ((pkcs7CertChain == null) ? 0 : pkcs7CertChain.hashCode()); + result = prime * result + ((prettyPrint == null) ? 0 : prettyPrint.hashCode()); + result = prime * result + ((serialNumber == null) ? 0 : serialNumber.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + ((subjectDN == null) ? 0 : subjectDN.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CertificateData other = (CertificateData) obj; + if (encoded == null) { + if (other.encoded != null) + return false; + } else if (!encoded.equals(other.encoded)) + return false; + if (issuerDN == null) { + if (other.issuerDN != null) + return false; + } else if (!issuerDN.equals(other.issuerDN)) + return false; + if (notAfter == null) { + if (other.notAfter != null) + return false; + } else if (!notAfter.equals(other.notAfter)) + return false; + if (notBefore == null) { + if (other.notBefore != null) + return false; + } else if (!notBefore.equals(other.notBefore)) + return false; + if (pkcs7CertChain == null) { + if (other.pkcs7CertChain != null) + return false; + } else if (!pkcs7CertChain.equals(other.pkcs7CertChain)) + return false; + if (prettyPrint == null) { + if (other.prettyPrint != null) + return false; + } else if (!prettyPrint.equals(other.prettyPrint)) + return false; + if (serialNumber == null) { + if (other.serialNumber != null) + return false; + } else if (!serialNumber.equals(other.serialNumber)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + if (subjectDN == null) { + if (other.subjectDN != null) + return false; + } else if (!subjectDN.equals(other.subjectDN)) + return false; + return true; + } + + public String toString() { + try { + StringWriter sw = new StringWriter(); + marshaller.marshal(this, sw); + return sw.toString(); + + } catch (Exception e) { + return super.toString(); + } + } + + public static CertificateData valueOf(String string) throws Exception { + try { + return (CertificateData)unmarshaller.unmarshal(new StringReader(string)); + } catch (Exception e) { + return null; + } + } + + public static void main(String args[]) throws Exception { + + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw, true); + + out.println("-----BEGIN CERTIFICATE-----"); + out.println("MIIB/zCCAWgCCQCtpWH58pqsejANBgkqhkiG9w0BAQUFADBEMRQwEgYDVQQKDAtF"); + out.println("WEFNUExFLUNPTTEYMBYGCgmSJomT8ixkAQEMCHRlc3R1c2VyMRIwEAYDVQQDDAlU"); + out.println("ZXN0IFVzZXIwHhcNMTIwNTE0MTcxNzI3WhcNMTMwNTE0MTcxNzI3WjBEMRQwEgYD"); + out.println("VQQKDAtFWEFNUExFLUNPTTEYMBYGCgmSJomT8ixkAQEMCHRlc3R1c2VyMRIwEAYD"); + out.println("VQQDDAlUZXN0IFVzZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKmmiPJp"); + out.println("Agh/gPUAZjfgJ3a8QiHvpMzZ/hZy1FVP3+2sNhCkMv+D/I8Y7AsrbJGxxvD7bTDm"); + out.println("zQYtYx2ryGyOgY7KBRxEj/IrNVHIkJMYq5G/aIU4FAzpc6ntNSwUQBYUAamfK8U6"); + out.println("Wo4Cp6rLePXIDE6sfGn3VX6IeSJ8U2V+vwtzAgMBAAEwDQYJKoZIhvcNAQEFBQAD"); + out.println("gYEAY9bjcD/7Z+oX6gsJtX6Rd79E7X5IBdOdArYzHNE4vjdaQrZw6oCxrY8ffpKC"); + out.println("0T0q5PX9I7er+hx/sQjGPMrJDEN+vFBSNrZE7sTeLRgkyiqGvChSyuG05GtGzXO4"); + out.println("bFBr+Gwk2VF2wJvOhTXU2hN8sfkkd9clzIXuL8WCDhWk1bY="); + out.println("-----END CERTIFICATE-----"); + + CertificateData before = new CertificateData(); + before.setSerialNumber(new CertId("12512514865863765114")); + before.setIssuerDN("CN=Test User,UID=testuser,O=EXAMPLE-COM"); + before.setSubjectDN("CN=Test User,UID=testuser,O=EXAMPLE-COM"); + before.setEncoded(sw.toString()); + + String string = before.toString(); + System.out.println(string); + + CertificateData after = CertificateData.valueOf(string); + System.out.println(before.equals(after)); + } } diff --git a/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java index 0ec84b8f6..e475591a5 100644 --- a/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java +++ b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java @@ -23,17 +23,17 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.dbs.keydb.KeyId; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; import com.netscape.cms.servlet.base.CMSResourceService; import com.netscape.cms.servlet.key.model.KeyDAO; import com.netscape.cms.servlet.key.model.KeyData; import com.netscape.cms.servlet.request.model.KeyRequestDAO; import com.netscape.cms.servlet.request.model.KeyRequestInfo; import com.netscape.cms.servlet.request.model.RecoveryRequestData; -import com.netscape.certsrv.request.IRequest; -import com.netscape.certsrv.request.RequestId; -import com.netscape.certsrv.request.RequestStatus; -import com.netscape.certsrv.base.EBaseException; -import com.netscape.certsrv.dbs.keydb.KeyId; /** * @author alee @@ -112,8 +112,8 @@ public class KeyResourceService extends CMSResourceService implements KeyResourc // TO-DO // confirm request is in approved state - String status = reqInfo.getRequestStatus(); - if (!status.equals(RequestStatus.APPROVED.toString())) { + RequestStatus status = reqInfo.getRequestStatus(); + if (!status.equals(RequestStatus.APPROVED)) { // log error throw new WebApplicationException(Response.Status.UNAUTHORIZED); } diff --git a/base/common/src/com/netscape/cms/servlet/processors/Processor.java b/base/common/src/com/netscape/cms/servlet/processors/Processor.java index d5893a479..a39ba715b 100644 --- a/base/common/src/com/netscape/cms/servlet/processors/Processor.java +++ b/base/common/src/com/netscape/cms/servlet/processors/Processor.java @@ -15,6 +15,7 @@ // (C) 2012 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- + package com.netscape.cms.servlet.processors; import java.math.BigInteger; @@ -49,6 +50,7 @@ import com.netscape.certsrv.base.SessionContext; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.certdb.ICertRecord; import com.netscape.certsrv.dbs.certdb.ICertificateRepository; +import com.netscape.certsrv.logging.IAuditor; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.profile.IEnrollProfile; import com.netscape.certsrv.profile.IProfile; @@ -147,11 +149,14 @@ public class Processor { protected ICertificateRepository certdb; //logging and stats + + protected ILogger logger = CMS.getLogger(); + protected IAuditor auditor = CMS.getAuditor(); protected ILogger signedAuditLogger = CMS.getSignedAuditLogger(); protected LinkedHashSet statEvents = new LinkedHashSet(); public Processor(String id, Locale locale) throws EPropertyNotFound, EBaseException { - IConfigStore cs = CMS.getConfigStore().getSubStore("profile." + id); + IConfigStore cs = CMS.getConfigStore().getSubStore("processor." + id); this.locale = locale; this.profileID = cs.getString(PROFILE_ID, "").isEmpty() ? null : cs.getString(PROFILE_ID); this.authzResourceName = cs.getString(AUTHZ_RESOURCE_NAME, "").isEmpty() ? null : @@ -350,6 +355,7 @@ public class Processor { if (cert == null) { // just don't have a cert. + CMS.debug(CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL")); return null; } @@ -361,6 +367,7 @@ public class Processor { } catch (CertificateEncodingException e) { CMS.debug(CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_ENCODE", e.getMessage())); return null; + } catch (CertificateException e) { CMS.debug(CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_DECODE", e.getMessage())); return null; @@ -368,6 +375,17 @@ public class Processor { return cert; } + public void log(int source, int level, String message) { + + if (logger == null) return; + + logger.log(ILogger.EV_SYSTEM, + null, + source, + level, + getClass().getSimpleName() + ": " + message); + } + protected static Hashtable toHashtable(HttpServletRequest req) { Hashtable httpReqHash = new Hashtable(); Enumeration names = req.getParameterNames(); diff --git a/base/common/src/com/netscape/cms/servlet/request/model/CMSRequestInfo.java b/base/common/src/com/netscape/cms/servlet/request/model/CMSRequestInfo.java index 07a02cd1c..f06334f6b 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/CMSRequestInfo.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/CMSRequestInfo.java @@ -20,15 +20,20 @@ package com.netscape.cms.servlet.request.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; +import com.netscape.certsrv.request.RequestStatusAdapter; @XmlAccessorType(XmlAccessType.FIELD) public class CMSRequestInfo { + @XmlElement protected String requestType; @XmlElement - protected String requestStatus; + @XmlJavaTypeAdapter(RequestStatusAdapter.class) + protected RequestStatus requestStatus; @XmlElement protected String requestURL; @@ -50,14 +55,14 @@ public class CMSRequestInfo { /** * @return the requestStatus */ - public String getRequestStatus() { + public RequestStatus getRequestStatus() { return requestStatus; } /** * @param requestStatus the requestStatus to set */ - public void setRequestStatus(String requestStatus) { + public void setRequestStatus(RequestStatus requestStatus) { this.requestStatus = requestStatus; } diff --git a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java index da1c78661..193a53c89 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java @@ -43,6 +43,7 @@ import com.netscape.cms.servlet.cert.RequestProcessor; import com.netscape.cms.servlet.processors.Processor; import com.netscape.cms.servlet.request.RequestNotFoundException; + /** * @author alee * @@ -55,7 +56,6 @@ public class CertRequestDAO extends CMSRequestDAO { private Random random = null; public static final String ATTR_SERIALNO = "serialNumber"; - public static final String REQ_COMPLETE = "complete"; public CertRequestDAO() { super("ca"); @@ -154,7 +154,6 @@ public class CertRequestDAO extends CMSRequestDAO { return info; } - private void addNonce(AgentEnrollmentRequestData info, HttpServletRequest servletRequest) throws EBaseException { if (nonces != null) { long n = random.nextLong(); @@ -209,7 +208,6 @@ public class CertRequestDAO extends CMSRequestDAO { processor.processRequest(request, data, ireq, op); } - @Override public CertRequestInfo createCMSRequestInfo(IRequest request, UriInfo uriInfo) { return CertRequestInfoFactory.create(request, uriInfo); diff --git a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java index 20c298136..0754fe547 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java @@ -29,6 +29,8 @@ import com.netscape.certsrv.dbs.certdb.CertId; @XmlAccessorType(XmlAccessType.FIELD) public class CertRequestInfo extends CMSRequestInfo { + public static final String REQ_COMPLETE = "complete"; + @XmlElement protected String certURL; diff --git a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfoFactory.java b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfoFactory.java index 7045f3366..c21ea35c9 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfoFactory.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfoFactory.java @@ -1,20 +1,21 @@ -//--- BEGIN COPYRIGHT BLOCK --- -//This program is free software; you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation; version 2 of the License. +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. // -//This program is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU General Public License for more details. +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -//You should have received a copy of the GNU General Public License along -//with this program; if not, write to the Free Software Foundation, Inc., -//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // -//(C) 2012 Red Hat, Inc. -//All rights reserved. -//--- END COPYRIGHT BLOCK --- +// (C) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + package com.netscape.cms.servlet.request.model; import java.math.BigInteger; @@ -25,57 +26,58 @@ import javax.ws.rs.core.UriInfo; import netscape.security.x509.X509CertImpl; +import org.apache.commons.lang.StringUtils; + import com.netscape.certsrv.profile.IEnrollProfile; import com.netscape.certsrv.request.IRequest; import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; import com.netscape.cms.servlet.cert.CertResource; import com.netscape.cms.servlet.request.CertRequestResource; public class CertRequestInfoFactory { - public static final String REQ_COMPLETE = "complete"; - public static CertRequestInfo create(IRequest request, UriInfo uriInfo) { - CertRequestInfo ret = new CertRequestInfo(); + + CertRequestInfo info = new CertRequestInfo(); + String requestType = request.getRequestType(); - String requestStatus = request.getRequestStatus().toString(); + RequestStatus requestStatus = request.getRequestStatus(); - ret.setRequestType(requestType); - ret.setRequestStatus(requestStatus); + info.setRequestType(requestType); + info.setRequestStatus(requestStatus); - ret.setCertRequestType(request.getExtDataInString("cert_request_type")); + info.setCertRequestType(request.getExtDataInString("cert_request_type")); Path certRequestPath = CertRequestResource.class.getAnnotation(Path.class); - RequestId rid = request.getRequestId(); + RequestId requestId = request.getRequestId(); UriBuilder reqBuilder = uriInfo.getBaseUriBuilder(); - reqBuilder.path(certRequestPath.value() + "/" + rid); - ret.setRequestURL(reqBuilder.build().toString()); + reqBuilder.path(certRequestPath.value() + "/" + requestId); + info.setRequestURL(reqBuilder.build().toString()); + + //Get Cert info if issued. - //Get cert info if issued. String serialNoStr = null; - if ((requestType != null) && (requestStatus != null)) { - if (requestStatus.equals(REQ_COMPLETE)) { - X509CertImpl impl[] = new X509CertImpl[1]; - impl[0] = request.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT); + if (requestType != null && requestStatus == RequestStatus.COMPLETE) { + X509CertImpl impl[] = new X509CertImpl[1]; + impl[0] = request.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT); - BigInteger serialNo; - if (impl[0] != null) { - serialNo = impl[0].getSerialNumber(); - serialNoStr = serialNo.toString(); - } + BigInteger serialNo; + if (impl[0] != null) { + serialNo = impl[0].getSerialNumber(); + serialNoStr = serialNo.toString(); } - } - if (serialNoStr != null && !serialNoStr.equals("")) { + if (!StringUtils.isEmpty(serialNoStr)) { Path certPath = CertResource.class.getAnnotation(Path.class); UriBuilder certBuilder = uriInfo.getBaseUriBuilder(); certBuilder.path(certPath.value() + "/" + serialNoStr); - ret.setCertURL(certBuilder.build().toString()); + info.setCertURL(certBuilder.build().toString()); } - return ret; - } + return info; + } } diff --git a/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java index 9def75248..ac54d5cca 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java @@ -216,7 +216,7 @@ public class KeyRequestDAO extends CMSRequestDAO { KeyRequestInfo ret = new KeyRequestInfo(); ret.setRequestType(request.getRequestType()); - ret.setRequestStatus(request.getRequestStatus().toString()); + ret.setRequestStatus(request.getRequestStatus()); Path keyRequestPath = KeyRequestResource.class.getAnnotation(Path.class); RequestId rid = request.getRequestId(); -- cgit