summaryrefslogtreecommitdiffstats
path: root/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2013-01-23 12:10:52 -0600
committerEndi Sukma Dewata <edewata@redhat.com>2013-01-30 20:06:13 -0500
commitef116695021d2b46755e3c8aecd1c1e5284216aa (patch)
treebd970ba33cbea1119e80eae4bea94b9304e9a89a /base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
parent855eb0d8b30f6834810a8273ef450b7c8cbb183f (diff)
downloadpki-ef116695021d2b46755e3c8aecd1c1e5284216aa.tar.gz
pki-ef116695021d2b46755e3c8aecd1c1e5284216aa.tar.xz
pki-ef116695021d2b46755e3c8aecd1c1e5284216aa.zip
Session-based nonces.ticket-474-4
Previously nonces were stored in a global map which might not scale well due to some issues: 1. The map uses the nonces as map keys. There were possible nonce collisions which required special handling. 2. The collision handling code was not thread safe. There were possible race conditions during concurrent modifications. 3. The map was shared and size limited. If there were a lot of users using the system, valid nonces could get pruned. 4. The map maps the nonces to client certificates. This limits the possible authentication methods that can be supported. Now the code has been modified such that each user has a private map in the user's session to store the nonces. Additional locking has been implemented to protect against concurrent modifications. The map now uses the target of the operation as the map key, eliminating possible collisions and allowing the use of other authentication methods. Since this is a private map, it's not affected by the number of users using the system. Ticket #474
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java')
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java43
1 files changed, 32 insertions, 11 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java b/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
index 5d33bf2bc..8f88e0c09 100644
--- a/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
+++ b/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
+import java.util.Hashtable;
import java.util.Locale;
import java.util.Vector;
@@ -46,10 +47,10 @@ import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.authority.ICertAuthority;
import com.netscape.certsrv.authorization.AuthzToken;
import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.authorization.EAuthzException;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.ForbiddenException;
import com.netscape.certsrv.base.IArgBlock;
-import com.netscape.certsrv.base.Nonces;
import com.netscape.certsrv.base.PKIException;
import com.netscape.certsrv.ca.ICRLIssuingPoint;
import com.netscape.certsrv.ca.ICertificateAuthority;
@@ -87,7 +88,6 @@ public class DoRevoke extends CMSServlet {
private ICertificateRepository mCertDB = null;
private String mFormPath = null;
private IPublisherProcessor mPublisherProcessor = null;
- private Nonces mNonces = null;
private int mTimeLimits = 30; /* in seconds */
private IUGSubsystem mUG = null;
private ICertUserLocator mUL = null;
@@ -111,9 +111,6 @@ public class DoRevoke extends CMSServlet {
if (mAuthority instanceof ICertificateAuthority) {
mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
- if (((ICertificateAuthority) mAuthority).noncesEnabled()) {
- mNonces = ((ICertificateAuthority) mAuthority).getNonces();
- }
}
if (mAuthority instanceof ICertAuthority) {
mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
@@ -401,14 +398,27 @@ public class DoRevoke extends CMSServlet {
processor.setInvalidityDate(invalidityDate);
processor.setComments(comments);
+ Hashtable<BigInteger, Long> nonceMap = new Hashtable<BigInteger, Long>();
+ X509Certificate clientCert = getSSLClientCertificate(req);
+
if (mAuthority instanceof ICertificateAuthority) {
- processor.setAuthority((ICertificateAuthority)mAuthority);
- }
+ processor.setAuthority(certAuthority);
- X509Certificate clientCert = getSSLClientCertificate(req);
- String requestedNonce = req.getParameter("nonce");
- Long nonce = requestedNonce == null ? null : new Long(requestedNonce.trim());
- processor.validateNonce(clientCert, nonce);
+ if (certAuthority.noncesEnabled()) {
+ String nonces = req.getParameter("nonce");
+ if (nonces == null) {
+ throw new ForbiddenException("Missing nonce.");
+ }
+
+ // parse serial numbers and nonces
+ for (String s : nonces.split(",")) {
+ String[] elements = s.split(":");
+ BigInteger serialNumber = new BigInteger(elements[0].trim());
+ Long nonce = new Long(elements[1].trim());
+ nonceMap.put(serialNumber, nonce);
+ }
+ }
+ }
try {
processor.createCRLExtension();
@@ -437,6 +447,14 @@ public class DoRevoke extends CMSServlet {
rarg.addStringValue("serialNumber", targetCert.getSerialNumber().toString(16));
try {
+ if (mAuthority instanceof ICertificateAuthority &&
+ certAuthority.noncesEnabled() &&
+ !processor.isMemberOfSubsystemGroup(clientCert)) {
+ // validate nonce for each certificate
+ Long nonce = nonceMap.get(targetRecord.getSerialNumber());
+ processor.validateNonce(req, "cert-revoke", targetRecord.getSerialNumber(), nonce);
+ }
+
processor.validateCertificateToRevoke(eeSubjectDN, targetRecord, false);
processor.addCertificateToRevoke(targetCert);
rarg.addStringValue("error", null);
@@ -543,6 +561,9 @@ public class DoRevoke extends CMSServlet {
processor.auditChangeRequest(ILogger.SUCCESS);
+ } catch (ForbiddenException e) {
+ throw new EAuthzException(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR"));
+
} catch (CertificateException e) {
processor.log(ILogger.LL_FAILURE, "Error " + e);
processor.auditChangeRequest(ILogger.FAILURE);