From 6259ba064f4c17b7f6891fcb61501103348936be Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Wed, 23 Jan 2013 12:10:52 -0600 Subject: Session-based nonces. 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 --- .../com/netscape/cms/servlet/cert/CertService.java | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'base/common/src/com/netscape/cms/servlet/cert/CertService.java') diff --git a/base/common/src/com/netscape/cms/servlet/cert/CertService.java b/base/common/src/com/netscape/cms/servlet/cert/CertService.java index e049710cb..69856751d 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/CertService.java +++ b/base/common/src/com/netscape/cms/servlet/cert/CertService.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.List; +import java.util.Map; import java.util.Random; import netscape.security.pkcs.ContentInfo; @@ -44,7 +45,6 @@ import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.BadRequestException; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.ICertPrettyPrint; -import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.base.PKIException; import com.netscape.certsrv.base.UnauthorizedException; import com.netscape.certsrv.ca.ICertificateAuthority; @@ -80,7 +80,6 @@ public class CertService extends PKIService implements CertResource { ICertificateAuthority authority; ICertificateRepository repo; Random random; - Nonces nonces; public final static int DEFAULT_SIZE = 20; @@ -88,7 +87,6 @@ public class CertService extends PKIService implements CertResource { authority = (ICertificateAuthority) CMS.getSubsystem("ca"); if (authority.noncesEnabled()) { random = new Random(); - nonces = authority.getNonces(); } repo = authority.getCertificateRepository(); } @@ -195,7 +193,11 @@ public class CertService extends PKIService implements CertResource { } } - processor.validateNonce(clientCert, request.getNonce()); + if (authority.noncesEnabled() && + !processor.isMemberOfSubsystemGroup(clientCert)) { + processor.validateNonce(servletRequest, "cert-revoke", id.toBigInteger(), request.getNonce()); + + } // Find target cert record if different from client cert. ICertRecord targetRecord = id.equals(clientSerialNumber) ? clientRecord : processor.getCertificateRecord(id); @@ -470,12 +472,14 @@ public class CertService extends PKIService implements CertResource { certData.setStatus(record.getStatus()); - if (generateNonce && nonces != null) { + if (authority.noncesEnabled() && generateNonce) { + // generate nonce long n = random.nextLong(); - long m = nonces.addNonce(n, Processor.getSSLClientCertificate(servletRequest)); - if (n + m != 0) { - certData.setNonce(m); - } + // store nonce in session + Map nonces = authority.getNonces(servletRequest, "cert-revoke"); + nonces.put(certId.toBigInteger(), n); + // return nonce to client + certData.setNonce(n); } URI uri = uriInfo.getBaseUriBuilder().path(CertResource.class).path("{id}").build(certId.toHexString()); -- cgit