diff options
author | Endi Sukma Dewata <edewata@redhat.com> | 2013-01-23 12:10:52 -0600 |
---|---|---|
committer | Endi Sukma Dewata <edewata@redhat.com> | 2013-01-30 20:05:38 -0500 |
commit | 04e55bddea50bfca2c16144efee03bba25c74198 (patch) | |
tree | d05daca8582938810e2ddce22924278628e216c2 /base/ca/src | |
parent | 22234173087d6ca8cc33ef74a2b132d21e9a8849 (diff) | |
download | pki-ticket-474-3.tar.gz pki-ticket-474-3.tar.xz pki-ticket-474-3.zip |
Session-based nonces.ticket-474-3
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/ca/src')
-rw-r--r-- | base/ca/src/CMakeLists.txt | 10 | ||||
-rw-r--r-- | base/ca/src/com/netscape/ca/CertificateAuthority.java | 41 |
2 files changed, 43 insertions, 8 deletions
diff --git a/base/ca/src/CMakeLists.txt b/base/ca/src/CMakeLists.txt index e5ef9e530..74533814a 100644 --- a/base/ca/src/CMakeLists.txt +++ b/base/ca/src/CMakeLists.txt @@ -31,6 +31,14 @@ find_file(JAXRS_API_JAR ${RESTEASY_LIB} ) +find_file(SERVLET_JAR + NAMES + servlet.jar + PATHS + ${JAVA_LIB_INSTALL_DIR} + /usr/share/java +) + # build pki-ca javac(pki-ca-classes SOURCES @@ -39,7 +47,7 @@ javac(pki-ca-classes ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR} ${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR} ${LDAPJDK_JAR} ${JAXRS_API_JAR} - ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR} + ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR} ${SERVLET_JAR} OUTPUT_DIR ${CMAKE_BINARY_DIR}/classes DEPENDS diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java index f8f3d7a9b..50ef503b6 100644 --- a/base/ca/src/com/netscape/ca/CertificateAuthority.java +++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java @@ -29,11 +29,16 @@ import java.security.PublicKey; import java.security.cert.CRLException; import java.security.cert.CertificateException; import java.security.cert.CertificateParsingException; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; +import java.util.Map; import java.util.Vector; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + import netscape.security.util.DerOutputStream; import netscape.security.util.DerValue; import netscape.security.x509.AlgorithmId; @@ -65,6 +70,7 @@ import com.netscape.certsrv.base.EPropertyNotFound; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.base.ISubsystem; import com.netscape.certsrv.base.Nonces; +import com.netscape.certsrv.base.PKIException; import com.netscape.certsrv.ca.ECAException; import com.netscape.certsrv.ca.ICRLIssuingPoint; import com.netscape.certsrv.ca.ICertificateAuthority; @@ -219,7 +225,6 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori private boolean mUseNonces = true; private int mMaxNonces = 100; - private Nonces mNonces = null; /** * Constructs a CA subsystem. @@ -279,8 +284,34 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori return mUseNonces; } - public Nonces getNonces() { - return mNonces; + public Map<Object, Long> getNonces(HttpServletRequest request, String name) { + + // Create a new session or use an existing one. + HttpSession session = request.getSession(true); + if (session == null) { + throw new PKIException("Unable to create session."); + } + + // Lock the session to prevent concurrent access. + // http://yet-another-dev.blogspot.com/2009/08/synchronizing-httpsession.html + + Object lock = request.getSession().getId().intern(); + synchronized (lock) { + + // Find the existing storage in the session. + @SuppressWarnings("unchecked") + Map<Object, Long> nonces = (Map<Object, Long>)session.getAttribute("nonces-"+name); + + if (nonces == null) { + // If not present, create a new storage. + nonces = Collections.synchronizedMap(new Nonces(mMaxNonces)); + + // Put the storage in the session. + session.setAttribute("nonces-"+name, nonces); + } + + return nonces; + } } /** @@ -319,10 +350,6 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori mUseNonces = mConfig.getBoolean("enableNonces", true); mMaxNonces = mConfig.getInteger("maxNumberOfNonces", 100); - if (mUseNonces) { - mNonces = new Nonces(mMaxNonces); - CMS.debug("CertificateAuthority init: Nonces enabled. (" + mNonces.size() + ")"); - } // init request queue and related modules. CMS.debug("CertificateAuthority init: initRequestQueue"); |