summaryrefslogtreecommitdiffstats
path: root/base/common
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2015-01-28 02:41:10 -0500
committerFraser Tweedale <ftweedal@redhat.com>2015-09-26 14:11:51 +1000
commit2a9f56d02b4a284cda6f8b61b250e1494f19a83e (patch)
tree9b12125932ed41a5dbe06f8dafb66656e78c7ad8 /base/common
parenta5a50e95a691587e22335018538b4f578dfee6d1 (diff)
downloadpki-2a9f56d02b4a284cda6f8b61b250e1494f19a83e.tar.gz
pki-2a9f56d02b4a284cda6f8b61b250e1494f19a83e.tar.xz
pki-2a9f56d02b4a284cda6f8b61b250e1494f19a83e.zip
Lightweight CAs: initial support
This commit adds initial support for "lightweight CAs" - CAs that inhabit an existing CA instance and share the request queue and certificate database of the "top-level CA". We initially support only sub-CAs under the top-level CA - either direct sub-CAs or nested. The general design will support hosting unrelated CAs but creation or import of unrelated CAs is not yet implemented. Part of: https://fedorahosted.org/pki/ticket/1213
Diffstat (limited to 'base/common')
-rw-r--r--base/common/src/com/netscape/certsrv/authority/AuthorityData.java123
-rw-r--r--base/common/src/com/netscape/certsrv/authority/AuthorityResource.java96
-rw-r--r--base/common/src/com/netscape/certsrv/ca/AuthorityID.java36
-rw-r--r--base/common/src/com/netscape/certsrv/ca/CADisabledException.java15
-rw-r--r--base/common/src/com/netscape/certsrv/ca/CANotFoundException.java14
-rw-r--r--base/common/src/com/netscape/certsrv/ca/CATypeException.java16
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICAService.java11
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java68
-rw-r--r--base/common/src/com/netscape/certsrv/ca/IssuerUnavailableException.java15
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java5
-rw-r--r--base/common/src/com/netscape/certsrv/security/ISigningUnit.java8
11 files changed, 403 insertions, 4 deletions
diff --git a/base/common/src/com/netscape/certsrv/authority/AuthorityData.java b/base/common/src/com/netscape/certsrv/authority/AuthorityData.java
new file mode 100644
index 000000000..2312c3989
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authority/AuthorityData.java
@@ -0,0 +1,123 @@
+// --- 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) 2015 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * @author ftweedal
+ */
+package com.netscape.certsrv.authority;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import org.jboss.resteasy.plugins.providers.atom.Link;
+
+@XmlRootElement(name = "authority")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AuthorityData {
+
+ public static Marshaller marshaller;
+ public static Unmarshaller unmarshaller;
+
+ static {
+ try {
+ marshaller = JAXBContext.newInstance(AuthorityData.class).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ unmarshaller = JAXBContext.newInstance(AuthorityData.class).createUnmarshaller();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @XmlAttribute
+ protected Boolean isHostAuthority;
+
+ public Boolean getIsHostAuthority() {
+ return isHostAuthority;
+ }
+
+
+ @XmlAttribute
+ protected String id;
+
+ public String getID() {
+ return id;
+ }
+
+
+ @XmlAttribute
+ protected String parentID;
+
+ public String getParentID() {
+ return parentID;
+ }
+
+
+ @XmlAttribute
+ protected String dn;
+
+ public String getDN() {
+ return dn;
+ }
+
+
+ @XmlAttribute
+ protected Boolean enabled;
+
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+
+ @XmlAttribute
+ protected String description;
+
+ public String getDescription() {
+ return description;
+ }
+
+
+ protected Link link;
+
+ public Link getLink() {
+ return link;
+ }
+
+ public void setLink(Link link) {
+ this.link = link;
+ }
+
+ protected AuthorityData() {
+ }
+
+ public AuthorityData(
+ Boolean isHostAuthority,
+ String dn, String id, String parentID,
+ Boolean enabled, String description) {
+ this.isHostAuthority = isHostAuthority;
+ this.dn = dn;
+ this.id = id;
+ this.parentID = parentID;
+ this.enabled = enabled;
+ this.description = description;
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/authority/AuthorityResource.java b/base/common/src/com/netscape/certsrv/authority/AuthorityResource.java
new file mode 100644
index 000000000..eaef903db
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/authority/AuthorityResource.java
@@ -0,0 +1,96 @@
+package com.netscape.certsrv.authority;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+import org.jboss.resteasy.annotations.ClientResponseType;
+
+import com.netscape.certsrv.acls.ACLMapping;
+import com.netscape.certsrv.authentication.AuthMethodMapping;
+
+@Path("authorities")
+public interface AuthorityResource {
+
+ public static final String HOST_AUTHORITY = "host-authority";
+
+ @GET
+ public Response listCAs();
+ /*
+ @QueryParam("start") Integer start,
+ @QueryParam("size") Integer size);
+ */
+
+ @GET
+ @Path("{id}")
+ @ClientResponseType(entityType=AuthorityData.class)
+ public Response getCA(@PathParam("id") String caIDString);
+
+ @GET
+ @Path("{id}/cert")
+ @Produces("application/pkix-cert")
+ @ClientResponseType(entityType=byte[].class)
+ public Response getCert(@PathParam("id") String caIDString);
+
+ @GET
+ @Path("{id}/cert")
+ @Produces("application/x-pem-file")
+ @ClientResponseType(entityType=String.class)
+ public Response getCertPEM(@PathParam("id") String caIDString);
+
+ @GET
+ @Path("{id}/chain")
+ @Produces("application/pkcs7-mime")
+ @ClientResponseType(entityType=byte[].class)
+ public Response getChain(@PathParam("id") String caIDString);
+
+ @GET
+ @Path("{id}/chain")
+ @Produces("application/x-pem-file")
+ @ClientResponseType(entityType=String.class)
+ public Response getChainPEM(@PathParam("id") String caIDString);
+
+ @POST
+ @ClientResponseType(entityType=AuthorityData.class)
+ @AuthMethodMapping("authorities")
+ @ACLMapping("authorities.create")
+ public Response createCA(AuthorityData data);
+
+ /**
+ * Modify a CA (supports partial updates).
+ *
+ * isHostEnabled, authorityID, authorityParentID and DN are
+ * immutable; differences in these values are ignored.
+ *
+ * Other values, if null, are ignored, otherwise they are
+ * set to the new value. To remove the description, use an
+ * empty string.
+ */
+ @PUT
+ @Path("{id}")
+ @ClientResponseType(entityType=AuthorityData.class)
+ @AuthMethodMapping("authorities")
+ @ACLMapping("authorities.modify")
+ public Response modifyCA(
+ @PathParam("id") String caIDString,
+ AuthorityData data);
+
+ @POST
+ @Path("{id}/enable")
+ @ClientResponseType(entityType=AuthorityData.class)
+ @AuthMethodMapping("authorities")
+ @ACLMapping("authorities.modify")
+ public Response enableCA(@PathParam("id") String caIDString);
+
+ @POST
+ @Path("{id}/disable")
+ @ClientResponseType(entityType=AuthorityData.class)
+ @AuthMethodMapping("authorities")
+ @ACLMapping("authorities.modify")
+ public Response disableCA(@PathParam("id") String caIDString);
+
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/AuthorityID.java b/base/common/src/com/netscape/certsrv/ca/AuthorityID.java
new file mode 100644
index 000000000..daac587b7
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/AuthorityID.java
@@ -0,0 +1,36 @@
+package com.netscape.certsrv.ca;
+
+import java.util.UUID;
+
+/**
+ * Identifier for a CertificateAuthority.
+ */
+public class AuthorityID implements Comparable<AuthorityID> {
+
+ protected UUID uuid;
+
+ /**
+ * Parse a AuthorityID from the given string
+ */
+ public AuthorityID(String s) {
+ if (s == null)
+ throw new IllegalArgumentException("null AuthorityID string");
+ uuid = UUID.fromString(s);
+ }
+
+ /**
+ * Construct a random AuthorityID
+ */
+ public AuthorityID() {
+ uuid = UUID.randomUUID();
+ }
+
+ public String toString() {
+ return uuid.toString();
+ }
+
+ public int compareTo(AuthorityID aid) {
+ return uuid.compareTo(aid.uuid);
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/CADisabledException.java b/base/common/src/com/netscape/certsrv/ca/CADisabledException.java
new file mode 100644
index 000000000..9b3f16b90
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/CADisabledException.java
@@ -0,0 +1,15 @@
+package com.netscape.certsrv.ca;
+
+/**
+ * Exception to throw when a (sub-)CA cannot perform an operation
+ * because it is disabled.
+ */
+public class CADisabledException extends ECAException {
+
+ private static final long serialVersionUID = -8827509070155037699L;
+
+ public CADisabledException(String msgFormat) {
+ super(msgFormat);
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/CANotFoundException.java b/base/common/src/com/netscape/certsrv/ca/CANotFoundException.java
new file mode 100644
index 000000000..f292077ec
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/CANotFoundException.java
@@ -0,0 +1,14 @@
+package com.netscape.certsrv.ca;
+
+/**
+ * Exception to throw when a (sub-)CA cannot be found.
+ */
+public class CANotFoundException extends ECAException {
+
+ private static final long serialVersionUID = -4618887355685066120L;
+
+ public CANotFoundException(String msgFormat) {
+ super(msgFormat);
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/CATypeException.java b/base/common/src/com/netscape/certsrv/ca/CATypeException.java
new file mode 100644
index 000000000..19eb680e8
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/CATypeException.java
@@ -0,0 +1,16 @@
+package com.netscape.certsrv.ca;
+
+/**
+ * Exception to throw when an operation cannot be completed
+ * because the CA is the wrong type (e.g., an operation that
+ * only applies to lightweight CAs).
+ */
+public class CATypeException extends ECAException {
+
+ private static final long serialVersionUID = -6004456461295692150L;
+
+ public CATypeException(String msgFormat) {
+ super(msgFormat);
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/ICAService.java b/base/common/src/com/netscape/certsrv/ca/ICAService.java
index 1d179e076..a4b4a6303 100644
--- a/base/common/src/com/netscape/certsrv/ca/ICAService.java
+++ b/base/common/src/com/netscape/certsrv/ca/ICAService.java
@@ -23,6 +23,7 @@ import netscape.security.x509.X509CertInfo;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ca.AuthorityID;
import com.netscape.certsrv.connector.IConnector;
import com.netscape.certsrv.request.IRequest;
@@ -59,13 +60,15 @@ public interface ICAService {
* Issues certificate base on enrollment information,
* creates certificate record, and stores all necessary data.
*
+ * @param caID CA ID
* @param certi information obtain from revocation request
+ * @param profileId Name of profile used
+ * @param rid Request ID
* @exception EBaseException failed to issue certificate or create certificate record
*/
- public X509CertImpl issueX509Cert(X509CertInfo certi)
- throws EBaseException;
-
- public X509CertImpl issueX509Cert(X509CertInfo certi, String profileId, String rid)
+ public X509CertImpl issueX509Cert(
+ AuthorityID aid, X509CertInfo certi,
+ String profileId, String rid)
throws EBaseException;
/**
diff --git a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
index f87f15420..31d5c9277 100644
--- a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
+++ b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
@@ -18,6 +18,7 @@
package com.netscape.certsrv.ca;
import java.util.Enumeration;
+import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
@@ -515,4 +516,71 @@ public interface ICertificateAuthority extends ISubsystem {
public CertificateIssuerName getIssuerObj();
public CertificateSubjectName getSubjectObj();
+
+ /**
+ * Enumerate all authorities, including host authority.
+ */
+ public List<ICertificateAuthority> getCAs();
+
+ /**
+ * Return whether this CA is the host authority (not a
+ * lightweight authority).
+ */
+ public boolean isHostAuthority();
+
+ /**
+ * Get the AuthorityID of this CA.
+ */
+ public AuthorityID getAuthorityID();
+
+ /**
+ * Get the AuthorityID of this CA's parent CA, if available.
+ */
+ public AuthorityID getAuthorityParentID();
+
+ /**
+ * Return CA description. May be null.
+ */
+ public boolean getAuthorityEnabled();
+
+ /**
+ * Return CA description. May be null.
+ */
+ public String getAuthorityDescription();
+
+ /**
+ * Get the CA by ID. Returns null if CA not found.
+ */
+ public ICertificateAuthority getCA(AuthorityID aid);
+
+ /**
+ * Get the CA by DN. Returns null if CA not found.
+ */
+ public ICertificateAuthority getCA(X500Name dn);
+
+ /**
+ * Create a new sub-CA under the specified parent CA.
+ */
+ public ICertificateAuthority createCA(
+ String dn, AuthorityID parentAID, String desc)
+ throws EBaseException;
+
+ /**
+ * Create a new sub-CA IMMEDIATELY beneath this one.
+ *
+ * This method DOES NOT add the new CA to caMap; it is the
+ * caller's responsibility.
+ */
+ public ICertificateAuthority createSubCA(
+ String dn, String desc)
+ throws EBaseException;
+
+ /**
+ * Update authority configurables.
+ *
+ * @param enabled Whether CA is enabled or disabled
+ * @param desc Description; null or empty removes it
+ */
+ public void modifyAuthority(Boolean enabled, String desc)
+ throws EBaseException;
}
diff --git a/base/common/src/com/netscape/certsrv/ca/IssuerUnavailableException.java b/base/common/src/com/netscape/certsrv/ca/IssuerUnavailableException.java
new file mode 100644
index 000000000..75bf88251
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/ca/IssuerUnavailableException.java
@@ -0,0 +1,15 @@
+package com.netscape.certsrv.ca;
+
+/**
+ * Exception to throw during CA creation when requested CA
+ * (issuer DN) already exists.
+ */
+public class IssuerUnavailableException extends ECAException {
+
+ private static final long serialVersionUID = -6247493607604418446L;
+
+ public IssuerUnavailableException(String msgFormat) {
+ super(msgFormat);
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
index 69a39d7e2..12667120e 100644
--- a/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
+++ b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
@@ -175,6 +175,11 @@ public interface IEnrollProfile extends IProfile {
public static final String REQUEST_ALGORITHM_PARAMS = "req_algorithm_params";
/**
+ * ID of requested certificate authority (absense implies host authority)
+ */
+ public static final String REQUEST_AUTHORITY_ID = "req_authority_id";
+
+ /**
* Set Default X509CertInfo in the request.
*
* @param request profile-based certificate request.
diff --git a/base/common/src/com/netscape/certsrv/security/ISigningUnit.java b/base/common/src/com/netscape/certsrv/security/ISigningUnit.java
index 34d2a5109..a5d641e93 100644
--- a/base/common/src/com/netscape/certsrv/security/ISigningUnit.java
+++ b/base/common/src/com/netscape/certsrv/security/ISigningUnit.java
@@ -17,6 +17,7 @@
// --- END COPYRIGHT BLOCK ---
package com.netscape.certsrv.security;
+import java.security.PrivateKey;
import java.security.PublicKey;
import netscape.security.x509.X509CertImpl;
@@ -161,4 +162,11 @@ public interface ISigningUnit {
* @return public key
*/
public PublicKey getPublicKey();
+
+ /**
+ * Retrieves the private key associated in this unit.
+ *
+ * @return public key
+ */
+ public PrivateKey getPrivateKey();
}