summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2016-03-16 16:48:43 +1100
committerFraser Tweedale <ftweedal@redhat.com>2016-04-14 16:07:17 +1000
commit8f93e60e0057b0706c5d5ad762d7ff7ce20b7b39 (patch)
treebe9830bd2da459a955050b240bfc10e52c010e8d
parent28bc4ed903bc9e2618390ec412602d889e28354b (diff)
downloadpki-8f93e60e0057b0706c5d5ad762d7ff7ce20b7b39.tar.gz
pki-8f93e60e0057b0706c5d5ad762d7ff7ce20b7b39.tar.xz
pki-8f93e60e0057b0706c5d5ad762d7ff7ce20b7b39.zip
Lightweight CAs: indicate when CA does not yet have keys
When a lightweight CA is created, clones will initialise a local object when the LDAP replication takes place, however, the signing keys will not yet have been replicated. Therefore, indicate CA readiness in authority data and respond appropriately (HTTP 503) when signing operations are attempted. Part of: https://fedorahosted.org/pki/ticket/1625
-rw-r--r--base/ca/src/com/netscape/ca/CertificateAuthority.java24
-rw-r--r--base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java12
-rw-r--r--base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java5
-rw-r--r--base/common/src/com/netscape/certsrv/authority/AuthorityData.java17
-rw-r--r--base/common/src/com/netscape/certsrv/base/ServiceUnavailableException.java17
-rw-r--r--base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java10
-rw-r--r--base/java-tools/src/com/netscape/cmstools/authority/AuthorityCLI.java1
-rw-r--r--base/java-tools/src/com/netscape/cmstools/authority/AuthorityCreateCLI.java2
-rw-r--r--base/java-tools/src/com/netscape/cmstools/authority/AuthorityDisableCLI.java2
-rw-r--r--base/java-tools/src/com/netscape/cmstools/authority/AuthorityEnableCLI.java2
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java5
11 files changed, 79 insertions, 18 deletions
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java
index 60f6b3621..d96b88414 100644
--- a/base/ca/src/com/netscape/ca/CertificateAuthority.java
+++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java
@@ -363,9 +363,20 @@ public class CertificateAuthority
return hostCA == this;
}
- private void ensureEnabled() throws CADisabledException {
+ public void ensureReady()
+ throws ECAException {
if (!authorityEnabled)
throw new CADisabledException("Authority is disabled");
+ if (!isReady()) {
+ if (signingUnitException != null)
+ throw signingUnitException;
+ else
+ throw new CAMissingKeyException("Authority does not yet have signing key and cert in local NSSDB");
+ }
+ }
+
+ public boolean isReady() {
+ return hasKeys;
}
public boolean getAuthorityEnabled() {
@@ -1191,7 +1202,7 @@ public class CertificateAuthority
*/
public X509CRLImpl sign(X509CRLImpl crl, String algname)
throws EBaseException {
- ensureEnabled();
+ ensureReady();
X509CRLImpl signedcrl = null;
IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
@@ -1264,7 +1275,7 @@ public class CertificateAuthority
*/
public X509CertImpl sign(X509CertInfo certInfo, String algname)
throws EBaseException {
- ensureEnabled();
+ ensureReady();
X509CertImpl signedcert = null;
@@ -1349,7 +1360,7 @@ public class CertificateAuthority
*/
public byte[] sign(byte[] data, String algname)
throws EBaseException {
- ensureEnabled();
+ ensureReady();
return mSigningUnit.sign(data, algname);
}
@@ -2261,7 +2272,7 @@ public class CertificateAuthority
}
private BasicOCSPResponse sign(ResponseData rd) throws EBaseException {
- ensureEnabled();
+ ensureReady();
try (DerOutputStream out = new DerOutputStream()) {
DerOutputStream tmp = new DerOutputStream();
@@ -2490,8 +2501,7 @@ public class CertificateAuthority
String subjectDN, String description)
throws EBaseException {
- if (!authorityEnabled)
- throw new CADisabledException("Parent CA is disabled");
+ ensureReady();
// check requested DN
X500Name subjectX500Name = null;
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java b/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java
index fa9e1038b..582248d4c 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/AuthorityService.java
@@ -43,9 +43,12 @@ import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.ForbiddenException;
import com.netscape.certsrv.base.PKIException;
import com.netscape.certsrv.base.ResourceNotFoundException;
+import com.netscape.certsrv.base.ServiceUnavailableException;
import com.netscape.certsrv.ca.AuthorityID;
import com.netscape.certsrv.ca.CAEnabledException;
import com.netscape.certsrv.ca.CADisabledException;
+import com.netscape.certsrv.ca.CAMissingCertException;
+import com.netscape.certsrv.ca.CAMissingKeyException;
import com.netscape.certsrv.ca.CANotFoundException;
import com.netscape.certsrv.ca.CANotLeafException;
import com.netscape.certsrv.ca.CATypeException;
@@ -207,6 +210,8 @@ public class AuthorityService extends PKIService implements AuthorityResource {
auditParams.put("exception", e.toString());
audit(ILogger.FAILURE, OpDef.OP_ADD, "<unknown>", auditParams);
throw new ConflictingOperationException(e.toString());
+ } catch (CAMissingCertException | CAMissingKeyException e) {
+ throw new ServiceUnavailableException(e.toString());
} catch (Exception e) {
CMS.debug(e);
auditParams.put("exception", e.toString());
@@ -261,14 +266,14 @@ public class AuthorityService extends PKIService implements AuthorityResource {
public Response enableCA(String aidString) {
return modifyCA(
aidString,
- new AuthorityData(null, null, null, null, true, null));
+ new AuthorityData(null, null, null, null, true, null, null));
}
@Override
public Response disableCA(String aidString) {
return modifyCA(
aidString,
- new AuthorityData(null, null, null, null, false, null));
+ new AuthorityData(null, null, null, null, false, null, null));
}
@Override
@@ -322,7 +327,8 @@ public class AuthorityService extends PKIService implements AuthorityResource {
ca.getAuthorityID().toString(),
parentAID != null ? parentAID.toString() : null,
ca.getAuthorityEnabled(),
- ca.getAuthorityDescription()
+ ca.getAuthorityDescription(),
+ ca.isReady()
);
}
diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
index cddbeb1ba..80aaf6f78 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
@@ -43,9 +43,12 @@ import com.netscape.certsrv.base.ConflictingOperationException;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.PKIException;
import com.netscape.certsrv.base.ResourceNotFoundException;
+import com.netscape.certsrv.base.ServiceUnavailableException;
import com.netscape.certsrv.base.UnauthorizedException;
import com.netscape.certsrv.ca.AuthorityID;
import com.netscape.certsrv.ca.CADisabledException;
+import com.netscape.certsrv.ca.CAMissingCertException;
+import com.netscape.certsrv.ca.CAMissingKeyException;
import com.netscape.certsrv.ca.ICertificateAuthority;
import com.netscape.certsrv.cert.CertEnrollmentRequest;
import com.netscape.certsrv.cert.CertRequestInfo;
@@ -252,6 +255,8 @@ public class CertRequestService extends PKIService implements CertRequestResourc
} catch (CADisabledException e) {
CMS.debug("changeRequestState: CA disabled: " + e);
throw new ConflictingOperationException(e.toString());
+ } catch (CAMissingCertException | CAMissingKeyException e) {
+ throw new ServiceUnavailableException(e.toString());
} catch (EPropertyException e) {
CMS.debug("changeRequestState: execution error " + e);
throw new PKIException(CMS.getUserMessage(getLocale(headers),
diff --git a/base/common/src/com/netscape/certsrv/authority/AuthorityData.java b/base/common/src/com/netscape/certsrv/authority/AuthorityData.java
index 2312c3989..84679567e 100644
--- a/base/common/src/com/netscape/certsrv/authority/AuthorityData.java
+++ b/base/common/src/com/netscape/certsrv/authority/AuthorityData.java
@@ -95,6 +95,19 @@ public class AuthorityData {
}
+ /**
+ * Whether the CA is ready to perform signing operations.
+ *
+ * This is a read-only attribute; it cannot be set by the user.
+ */
+ @XmlAttribute
+ protected Boolean ready;
+
+ public Boolean getReady() {
+ return ready;
+ }
+
+
protected Link link;
public Link getLink() {
@@ -111,13 +124,15 @@ public class AuthorityData {
public AuthorityData(
Boolean isHostAuthority,
String dn, String id, String parentID,
- Boolean enabled, String description) {
+ Boolean enabled, String description,
+ Boolean ready) {
this.isHostAuthority = isHostAuthority;
this.dn = dn;
this.id = id;
this.parentID = parentID;
this.enabled = enabled;
this.description = description;
+ this.ready = ready;
}
}
diff --git a/base/common/src/com/netscape/certsrv/base/ServiceUnavailableException.java b/base/common/src/com/netscape/certsrv/base/ServiceUnavailableException.java
new file mode 100644
index 000000000..0ee9c8a08
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/base/ServiceUnavailableException.java
@@ -0,0 +1,17 @@
+package com.netscape.certsrv.base;
+
+import javax.ws.rs.core.Response;
+
+public class ServiceUnavailableException extends PKIException {
+
+ private static final long serialVersionUID = -9160776882517621347L;
+
+ public ServiceUnavailableException(String message) {
+ super(Response.Status.SERVICE_UNAVAILABLE, message);
+ }
+
+ public ServiceUnavailableException(String message, Throwable cause) {
+ super(Response.Status.SERVICE_UNAVAILABLE, message, cause);
+ }
+
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
index 6d83e6d07..dd0d1b085 100644
--- a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
+++ b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java
@@ -545,6 +545,16 @@ public interface ICertificateAuthority extends ISubsystem {
public boolean getAuthorityEnabled();
/**
+ * Return whether CA is ready to perform signing operations.
+ */
+ public boolean isReady();
+
+ /**
+ * Throw an exception if CA is not ready to perform signing operations.
+ */
+ public void ensureReady() throws ECAException;
+
+ /**
* Return CA description. May be null.
*/
public String getAuthorityDescription();
diff --git a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCLI.java b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCLI.java
index 4fbcfef76..ac06ea24c 100644
--- a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCLI.java
@@ -45,6 +45,7 @@ public class AuthorityCLI extends CLI {
if (parentAID != null)
System.out.println(" Parent ID: " + data.getParentID());
System.out.println(" Enabled: " + data.getEnabled());
+ System.out.println(" Ready to sign: " + data.getReady());
String desc = data.getDescription();
if (desc != null)
System.out.println(" Description: " + desc);
diff --git a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCreateCLI.java b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCreateCLI.java
index d1688fbd1..3c36ac756 100644
--- a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCreateCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityCreateCLI.java
@@ -81,7 +81,7 @@ public class AuthorityCreateCLI extends CLI {
String dn = cmdArgs[0];
AuthorityData data = new AuthorityData(
- null, dn, null, parentAIDString, true /* enabled */, desc);
+ null, dn, null, parentAIDString, true /* enabled */, desc, null);
AuthorityData newData = authorityCLI.authorityClient.createCA(data);
AuthorityCLI.printAuthorityData(newData);
}
diff --git a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityDisableCLI.java b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityDisableCLI.java
index fc4cbf30b..85b38f081 100644
--- a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityDisableCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityDisableCLI.java
@@ -48,7 +48,7 @@ public class AuthorityDisableCLI extends CLI {
}
AuthorityData data = new AuthorityData(
- null, null, cmdArgs[0], null, false, null);
+ null, null, cmdArgs[0], null, false, null, null);
data = authorityCLI.authorityClient.modifyCA(data);
AuthorityCLI.printAuthorityData(data);
}
diff --git a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityEnableCLI.java b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityEnableCLI.java
index f6fdab12f..936edca59 100644
--- a/base/java-tools/src/com/netscape/cmstools/authority/AuthorityEnableCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/authority/AuthorityEnableCLI.java
@@ -48,7 +48,7 @@ public class AuthorityEnableCLI extends CLI {
}
AuthorityData data = new AuthorityData(
- null, null, cmdArgs[0], null, true, null);
+ null, null, cmdArgs[0], null, true, null, null);
data = authorityCLI.authorityClient.modifyCA(data);
AuthorityCLI.printAuthorityData(data);
}
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
index 8558ec23f..b92ffb1d7 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
@@ -37,7 +37,6 @@ import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.EPropertyNotFound;
import com.netscape.certsrv.base.IConfigStore;
import com.netscape.certsrv.ca.AuthorityID;
-import com.netscape.certsrv.ca.CADisabledException;
import com.netscape.certsrv.ca.CANotFoundException;
import com.netscape.certsrv.ca.ICertificateAuthority;
import com.netscape.certsrv.cert.CertReviewResponse;
@@ -350,9 +349,7 @@ public class RequestProcessor extends CertProcessor {
if (ca == null)
// this shouldn't happen because request was already accepted
throw new CANotFoundException("Unknown CA: " + aidString);
- if (!ca.getAuthorityEnabled())
- // authority was disabled after request was accepted
- throw new CADisabledException("CA '" + aidString + "' is disabled");
+ ca.ensureReady();
}
/**