diff options
Diffstat (limited to 'base/common/src/com/netscape/cms')
12 files changed, 178 insertions, 147 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java b/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java index 72ced2c53..744a000e3 100644 --- a/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java +++ b/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java @@ -226,6 +226,7 @@ public abstract class CMSServlet extends HttpServlet { // the authority, RA, CA, KRA this servlet is serving. protected IAuthority mAuthority = null; + protected ICertificateAuthority certAuthority; protected IRequestQueue mRequestQueue = null; // system logger. @@ -301,9 +302,11 @@ public abstract class CMSServlet extends HttpServlet { authority = sc.getInitParameter(PROP_AUTHORITYID); } - if (authority != null) - mAuthority = (IAuthority) - CMS.getSubsystem(authority); + if (authority != null) { + mAuthority = (IAuthority) CMS.getSubsystem(authority); + if (mAuthority instanceof ICertificateAuthority) + certAuthority = (ICertificateAuthority) mAuthority; + } if (mAuthority != null) mRequestQueue = mAuthority.getRequestQueue(); diff --git a/base/common/src/com/netscape/cms/servlet/cert/CertRequestDAO.java b/base/common/src/com/netscape/cms/servlet/cert/CertRequestDAO.java index 4d0fc38b2..d4785e957 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/CertRequestDAO.java +++ b/base/common/src/com/netscape/cms/servlet/cert/CertRequestDAO.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Random; import javax.servlet.ServletException; @@ -29,7 +30,6 @@ import javax.ws.rs.core.UriInfo; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; -import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.cert.CertEnrollmentRequest; import com.netscape.certsrv.cert.CertRequestInfo; @@ -54,7 +54,6 @@ public class CertRequestDAO extends CMSRequestDAO { private IRequestQueue queue; private ICertificateAuthority ca; IProfileSubsystem ps; - private Nonces nonces = null; private Random random = null; public static final String ATTR_SERIALNO = "serialNumber"; @@ -65,7 +64,6 @@ public class CertRequestDAO extends CMSRequestDAO { queue = ca.getRequestQueue(); if (ca.noncesEnabled()) { random = new Random(); - nonces = ca.getNonces(); } ps = (IProfileSubsystem) CMS.getSubsystem(IProfileSubsystem.ID); } @@ -141,20 +139,19 @@ public class CertRequestDAO extends CMSRequestDAO { String profileId = request.getExtDataInString("profileId"); IProfile profile = ps.getProfile(profileId); CertReviewResponse info = CertReviewResponseFactory.create(request, profile, uriInfo, locale); - if (ca.noncesEnabled()) { - addNonce(info, servletRequest); - } - return info; - } - private void addNonce(CertReviewResponse info, HttpServletRequest servletRequest) throws EBaseException { - if (nonces != null) { + if (ca.noncesEnabled()) { + // generate nonce long n = random.nextLong(); - long m = nonces.addNonce(n, Processor.getSSLClientCertificate(servletRequest)); - if ((n + m) != 0) { - info.setNonce(Long.toString(m)); - } + + // store nonce in session + Map<Object, Long> nonces = ca.getNonces(servletRequest, "cert-request"); + nonces.put(info.getRequestId().toBigInteger(), n); + + // return nonce to client + info.setNonce(Long.toString(n)); } + return info; } /** diff --git a/base/common/src/com/netscape/cms/servlet/cert/CertReviewResponseFactory.java b/base/common/src/com/netscape/cms/servlet/cert/CertReviewResponseFactory.java index 97611eb94..a7d76a469 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/CertReviewResponseFactory.java +++ b/base/common/src/com/netscape/cms/servlet/cert/CertReviewResponseFactory.java @@ -26,7 +26,6 @@ import javax.ws.rs.core.UriInfo; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IArgBlock; -import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.cert.CertReviewResponse; import com.netscape.certsrv.profile.EProfileException; import com.netscape.certsrv.profile.IPolicyDefault; @@ -128,7 +127,8 @@ public class CertReviewResponseFactory { return ret; } - public static CertReviewResponse create(CMSRequest cmsReq, IProfile profile, Nonces nonces, Locale locale) + public static CertReviewResponse create( + CMSRequest cmsReq, IProfile profile, boolean noncesEnabled, Locale locale) throws EPropertyException, EProfileException { HttpServletRequest req = cmsReq.getHttpReq(); IRequest ireq = cmsReq.getIRequest(); @@ -139,7 +139,7 @@ public class CertReviewResponseFactory { ret.setRequestNotes(req.getParameter("requestNotes")); ret.setRequestId(ireq.getRequestId()); - if (nonces != null) { + if (noncesEnabled) { ret.setNonce(req.getParameter(Processor.ARG_REQUEST_NONCE)); } 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<Object, Long> 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()); 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); diff --git a/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java b/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java index 5b9cd7741..75e732676 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java +++ b/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java @@ -18,8 +18,10 @@ package com.netscape.cms.servlet.cert; import java.io.IOException; +import java.util.ArrayList; import java.util.Enumeration; import java.util.Locale; +import java.util.Map; import java.util.Random; import javax.servlet.ServletConfig; @@ -30,13 +32,14 @@ import javax.servlet.http.HttpServletResponse; import netscape.security.x509.X509CertImpl; +import org.apache.commons.lang.StringUtils; + import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.authentication.IAuthToken; import com.netscape.certsrv.authorization.AuthzToken; import com.netscape.certsrv.authorization.EAuthzAccessDenied; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IArgBlock; -import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.certdb.ICertRecord; import com.netscape.certsrv.dbs.certdb.ICertificateRepository; @@ -65,7 +68,6 @@ public class ReasonToRevoke extends CMSServlet { private String mFormPath = null; private ICertificateAuthority mCA = null; private Random mRandom = null; - private Nonces mNonces = null; private int mTimeLimits = 30; /* in seconds */ public ReasonToRevoke() { @@ -88,7 +90,6 @@ public class ReasonToRevoke extends CMSServlet { if (mCA != null && mCA.noncesEnabled()) { mRandom = new Random(); - mNonces = mCA.getNonces(); } mTemplates.remove(CMSRequest.SUCCESS); @@ -222,14 +223,6 @@ public class ReasonToRevoke extends CMSServlet { header.addStringValue("revokeAll", revokeAll); header.addIntegerValue("totalRecordCount", totalRecordCount); - if (mNonces != null) { - long n = mRandom.nextLong(); - long m = mNonces.addNonce(n, getSSLClientCertificate(req)); - if ((n + m) != 0) { - header.addStringValue("nonce", Long.toString(m)); - } - } - try { if (mCA != null) { X509CertImpl caCert = mCA.getSigningUnit().getCertImpl(); @@ -248,6 +241,7 @@ public class ReasonToRevoke extends CMSServlet { Enumeration<ICertRecord> e = mCertDB.searchCertificates(revokeAll, totalRecordCount, mTimeLimits); + ArrayList<String> noncesList = new ArrayList<String>(); int count = 0; while (e != null && e.hasMoreElements()) { @@ -258,6 +252,17 @@ public class ReasonToRevoke extends CMSServlet { X509CertImpl xcert = rec.getCertificate(); if (xcert != null) + + if (mCA != null && mCA.noncesEnabled()) { + // generate nonce + long n = mRandom.nextLong(); + // store nonce in session + Map<Object, Long> nonces = mCA.getNonces(req, "cert-revoke"); + nonces.put(xcert.getSerialNumber(), n); + // store serial number and nonce + noncesList.add(xcert.getSerialNumber()+":"+n); + } + if (!(rec.getStatus().equals(ICertRecord.STATUS_REVOKED))) { count++; IArgBlock rarg = CMS.createArgBlock(); @@ -278,6 +283,11 @@ public class ReasonToRevoke extends CMSServlet { header.addIntegerValue("verifiedRecordCount", count); + if (mCA != null && mCA.noncesEnabled()) { + // return serial numbers and nonces to client + header.addStringValue("nonce", StringUtils.join(noncesList.toArray(), ",")); + } + } catch (EBaseException e) { log(ILogger.LL_FAILURE, "Error " + e); throw e; diff --git a/base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java b/base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java index 508cd72c1..fbfe9ceda 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java +++ b/base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java @@ -17,7 +17,6 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.cert; -import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; @@ -33,6 +32,7 @@ import com.netscape.certsrv.authentication.IAuthToken; import com.netscape.certsrv.authorization.AuthzToken; import com.netscape.certsrv.authorization.EAuthzException; import com.netscape.certsrv.base.BadRequestDataException; +import com.netscape.certsrv.base.BadRequestException; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.EPropertyNotFound; import com.netscape.certsrv.base.IConfigStore; @@ -71,7 +71,8 @@ public class RequestProcessor extends CertProcessor { String profileId = ireq.getExtDataInString("profileId"); IProfile profile = ps.getProfile(profileId); - CertReviewResponse data = CertReviewResponseFactory.create(cmsReq, profile, nonces, locale); + CertReviewResponse data = CertReviewResponseFactory.create( + cmsReq, profile, authority.noncesEnabled(), locale); processRequest(req, data, request, op); return data; @@ -99,41 +100,27 @@ public class RequestProcessor extends CertProcessor { throw new EAuthzException(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR")); } - if (nonces != null) { + if (authority.noncesEnabled()) { + Object id = data.getRequestId().toBigInteger(); + String requestNonce = data.getNonce(); - boolean nonceVerified = false; - if (requestNonce != null) { - long nonce = 0L; - try { - nonce = Long.parseLong(requestNonce.trim()); - } catch (NumberFormatException e) { - } - X509Certificate cert1 = nonces.getCertificate(nonce); - X509Certificate cert2 = getSSLClientCertificate(request); - if (cert1 == null) { - CMS.debug("CertRequestExecutor: Unknown nonce"); - } else if (cert1 != null && cert2 != null && cert1.equals(cert2)) { - nonceVerified = true; - nonces.removeNonce(nonce); - } - } else { - CMS.debug("CertRequestExecutor: Missing nonce"); - } - CMS.debug("CertRequestExecutor: nonceVerified=" + nonceVerified); - if (!nonceVerified) { - CMS.debug("nonce not verified"); - throw new EAuthzException(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR")); + if (requestNonce == null) { + CMS.debug("RequestProcessor: Missing nonce"); + throw new BadRequestException("Missing nonce."); } + + Long nonce = new Long(requestNonce.trim()); + validateNonce(request, "cert-request", id, nonce); } - CMS.debug("CertRequestExecutor: processRequest: start serving"); + CMS.debug("RequestProcessor: processRequest: start serving"); RequestId requestId = data.getRequestId(); if (requestId == null || requestId.equals("")) { CMS.debug(CMS.getUserMessage(locale, "CMS_REQUEST_ID_NOT_FOUND")); throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_REQUEST_ID_NOT_FOUND")); } - CMS.debug("CertRequestExecutor: requestId=" + requestId); + CMS.debug("RequestProcessor: requestId=" + requestId); // check if the request is in one of the terminal states if (!req.getRequestStatus().equals(RequestStatus.PENDING)) { @@ -147,10 +134,10 @@ public class RequestProcessor extends CertProcessor { String profileId = req.getExtDataInString("profileId"); if (profileId == null || profileId.equals("")) { - CMS.debug("CertRequestExecutor: Profile Id not found in request"); + CMS.debug("RequestProcessor: Profile Id not found in request"); throw new EBaseException(CMS.getUserMessage(locale, "CMS_PROFILE_ID_NOT_FOUND")); } - CMS.debug("CertRequestExecutor: profileId=" + profileId); + CMS.debug("RequestProcessor: profileId=" + profileId); IProfile profile = ps.getProfile(profileId); if (profile == null) { @@ -158,7 +145,7 @@ public class RequestProcessor extends CertProcessor { throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId)); } if (!ps.isProfileEnable(profileId)) { - CMS.debug("CertRequestExecutor: Profile " + profileId + " not enabled"); + CMS.debug("RequestProcessor: Profile " + profileId + " not enabled"); throw new BadRequestDataException("Profile " + profileId + " not enabled"); } @@ -168,7 +155,7 @@ public class RequestProcessor extends CertProcessor { // assigned owner if (owner != null && owner.length() > 0) { if (!grantPermission(req, authToken)) { - CMS.debug("CertRequestExecutor: Permission not granted to assign request."); + CMS.debug("RequestProcessor: Permission not granted to assign request."); throw new EAuthzException(CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION")); } } @@ -197,7 +184,7 @@ public class RequestProcessor extends CertProcessor { req.setRequestOwner(""); } } else { - CMS.debug("CertRequestExecutor: Permission not granted to approve/reject/cancel/update/validate/unassign request."); + CMS.debug("RequestProcessor: Permission not granted to approve/reject/cancel/update/validate/unassign request."); throw new EAuthzException(CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION")); } } @@ -211,6 +198,7 @@ public class RequestProcessor extends CertProcessor { } } endTiming("approval"); + } finally { endAllEvents(); } diff --git a/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java b/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java index 341314887..e555d1ac6 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java +++ b/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java @@ -26,7 +26,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Locale; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import com.netscape.certsrv.authorization.EAuthzException; import netscape.security.x509.CRLExtensions; import netscape.security.x509.CRLReasonExtension; import netscape.security.x509.InvalidityDateExtension; @@ -39,6 +44,7 @@ import com.netscape.certsrv.base.BadRequestException; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.EPropertyNotFound; import com.netscape.certsrv.base.ForbiddenException; +import com.netscape.certsrv.base.PKIException; import com.netscape.certsrv.base.UnauthorizedException; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.certdb.CertId; @@ -188,47 +194,24 @@ public class RevocationProcessor extends CertProcessor { return request; } - public void validateNonce(X509Certificate clientCert, Long nonce) { + public boolean isMemberOfSubsystemGroup(X509Certificate clientCert) { - if (nonces != null) { - boolean nonceVerified = false; - boolean skipNonceVerification = false; + if (clientCert == null) { + return false; + } - if (clientCert != null) { - X509Certificate certChain[] = new X509Certificate[1]; - certChain[0] = clientCert; - IUser user = null; - try { - user = ul.locateUser(new Certificates(certChain)); - } catch (Exception e) { - CMS.debug("RevocationProcessor: Failed to map certificate '" + - clientCert.getSubjectDN().getName() + "' to user."); - } - if (ug.isMemberOf(user, "Subsystem Group")) { - skipNonceVerification = true; - } - } + try { + X509Certificate certChain[] = new X509Certificate[1]; + certChain[0] = clientCert; - if (nonce != null) { - X509Certificate storedCert = nonces.getCertificate(nonce); - if (storedCert == null) { - CMS.debug("RevocationProcessor: Unknown nonce"); + IUser user = ul.locateUser(new Certificates(certChain)); + return ug.isMemberOf(user, "Subsystem Group"); - } else if (clientCert != null && storedCert.equals(clientCert)) { - nonceVerified = true; - nonces.removeNonce(nonce); - } - } else { - CMS.debug("RevocationProcessor: Missing nonce"); - } - - CMS.debug("RevocationProcessor: nonceVerified=" + nonceVerified); - CMS.debug("RevocationProcessor: skipNonceVerification=" + skipNonceVerification); - if ((!nonceVerified) && (!skipNonceVerification)) { - throw new ForbiddenException("Invalid nonce."); - } + } catch (Exception e) { + CMS.debug("RevocationProcessor: Failed to map certificate '" + + clientCert.getSubjectDN().getName() + "' to user."); + return false; } - } public void validateCertificateToRevoke(String subjectDN, ICertRecord targetRecord, boolean revokingCACert) { diff --git a/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java b/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java index 4c4f7e9e0..d136c5ff9 100644 --- a/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java +++ b/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java @@ -23,6 +23,7 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Enumeration; import java.util.Locale; +import java.util.Map; import java.util.Random; import javax.servlet.ServletConfig; @@ -42,7 +43,6 @@ import com.netscape.certsrv.authorization.AuthzToken; import com.netscape.certsrv.authorization.EAuthzAccessDenied; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IArgBlock; -import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.certdb.ICertRecord; import com.netscape.certsrv.dbs.certdb.ICertificateRepository; @@ -82,7 +82,6 @@ public class RevocationServlet extends CMSServlet { private boolean mRevokeByDN = true; private Random mRandom = null; - private Nonces mNonces = null; public RevocationServlet() { super(); @@ -109,7 +108,6 @@ public class RevocationServlet extends CMSServlet { if (mAuthority instanceof ICertificateAuthority) { if (((ICertificateAuthority) mAuthority).noncesEnabled()) { - mNonces = ((ICertificateAuthority) mAuthority).getNonces(); mRandom = new Random(); } } @@ -207,18 +205,21 @@ public class RevocationServlet extends CMSServlet { // header.addLongValue("validNotBefore", old_cert.getNotBefore().getTime()/1000); // header.addLongValue("validNotAfter", old_cert.getNotAfter().getTime()/1000); - if (mNonces != null) { - long n = mRandom.nextLong(); - long m = mNonces.addNonce(n, old_cert); - if ((n + m) != 0) { - header.addStringValue("nonce", Long.toString(m)); - } - } - boolean noInfo = false; X509CertImpl[] certsToRevoke = null; if (mAuthority instanceof ICertificateAuthority) { + + if (certAuthority.noncesEnabled()) { + // generate nonce + long n = mRandom.nextLong(); + // store nonce in session + Map<Object, Long> nonces = certAuthority.getNonces(cmsReq.getHttpReq(), "cert-revoke"); + nonces.put(old_serial_no, n); + // return serial number and nonce to client + header.addStringValue("nonce", old_serial_no+":"+n); + } + certsToRevoke = ((ICertificateAuthority) mAuthority).getCertificateRepository().getX509Certificates( old_cert.getSubjectDN().toString(), ICertificateRepository.ALL_UNREVOKED_CERTS); diff --git a/base/common/src/com/netscape/cms/servlet/processors/Processor.java b/base/common/src/com/netscape/cms/servlet/processors/Processor.java index 423d1bed5..2349b48ea 100644 --- a/base/common/src/com/netscape/cms/servlet/processors/Processor.java +++ b/base/common/src/com/netscape/cms/servlet/processors/Processor.java @@ -28,6 +28,7 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Locale; +import java.util.Map; import java.util.Map.Entry; import java.util.StringTokenizer; @@ -40,12 +41,13 @@ import com.netscape.certsrv.authentication.AuthToken; import com.netscape.certsrv.authentication.IAuthToken; import com.netscape.certsrv.authorization.AuthzToken; import com.netscape.certsrv.authorization.IAuthzSubsystem; +import com.netscape.certsrv.base.BadRequestException; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.EPropertyNotFound; +import com.netscape.certsrv.base.ForbiddenException; import com.netscape.certsrv.base.IArgBlock; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.base.MetaInfo; -import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.base.SessionContext; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.certdb.ICertRecord; @@ -138,7 +140,6 @@ public class Processor { protected String authzResourceName; protected String authMgr; protected String getClientCert = "false"; - protected Nonces nonces; protected Locale locale; // subsystems @@ -179,10 +180,6 @@ public class Processor { throw new EBaseException("CertProcessor: authority is null"); } - if (authority.noncesEnabled()) { - nonces = authority.getNonces(); - } - queue = authority.getRequestQueue(); if (queue == null) { throw new EBaseException("CertProcessor: cannot get request queue"); @@ -1237,4 +1234,30 @@ public class Processor { return ILogger.SIGNED_AUDIT_EMPTY_VALUE; } } + + public void validateNonce( + HttpServletRequest servletRequest, + String name, + Object id, + Long nonce) throws EBaseException { + + if (nonce == null) { + throw new BadRequestException("Missing nonce."); + } + + Map<Object, Long> nonces = authority.getNonces(servletRequest, name); + + Long storedNonce = nonces.get(id); + if (storedNonce == null) { + throw new BadRequestException("Nonce for "+name+" "+id+" does not exist."); + } + + if (!nonce.equals(storedNonce)) { + throw new ForbiddenException("Invalid nonce"); + } + + nonces.remove(id); + + CMS.debug("Processor: Nonce verified"); + } } diff --git a/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java index dcde4b019..4b5ef292d 100644 --- a/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java +++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java @@ -29,6 +29,7 @@ import com.netscape.certsrv.authentication.EAuthException; import com.netscape.certsrv.authorization.EAuthzException; import com.netscape.certsrv.base.BadRequestDataException; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.ForbiddenException; import com.netscape.certsrv.cert.CertReviewResponse; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.profile.EDeferException; @@ -106,6 +107,11 @@ public class ProfileProcessServlet extends ProfileServlet { CertReviewResponse data = null; try { data = processor.processRequest(cmsReq, req, op); + + } catch (ForbiddenException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString())); + setError(args, e.getMessage(), request, response); + return; } catch (EAuthException e) { log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString())); setError(args, e.getMessage(), request, response); diff --git a/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java index 61a04a630..2b3ef83bb 100644 --- a/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java +++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileReviewServlet.java @@ -19,6 +19,7 @@ package com.netscape.cms.servlet.profile; import java.util.Enumeration; import java.util.Locale; +import java.util.Map; import java.util.Random; import javax.servlet.ServletConfig; @@ -29,11 +30,9 @@ import javax.servlet.http.HttpServletResponse; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.authentication.IAuthToken; -import com.netscape.certsrv.authority.IAuthority; import com.netscape.certsrv.authorization.AuthzToken; import com.netscape.certsrv.authorization.EAuthzAccessDenied; import com.netscape.certsrv.base.EBaseException; -import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.profile.EProfileException; @@ -68,8 +67,8 @@ public class ProfileReviewServlet extends ProfileServlet { private static final String PROP_AUTHORITY_ID = "authorityId"; private String mAuthorityId = null; + ICertificateAuthority authority = null; private Random mRandom = null; - private Nonces mNonces = null; public ProfileReviewServlet() { } @@ -84,12 +83,10 @@ public class ProfileReviewServlet extends ProfileServlet { super.init(sc); mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID); - ICertificateAuthority authority = null; if (mAuthorityId != null) authority = (ICertificateAuthority) CMS.getSubsystem(mAuthorityId); if (authority != null && authority.noncesEnabled()) { - mNonces = authority.getNonces(); mRandom = new Random(); } } @@ -168,7 +165,6 @@ public class ProfileReviewServlet extends ProfileServlet { } // retrieve request - IAuthority authority = (IAuthority) CMS.getSubsystem(mAuthorityId); if (authority == null) { CMS.debug("ProfileReviewServlet: Authority " + mAuthorityId + @@ -253,12 +249,11 @@ public class ProfileReviewServlet extends ProfileServlet { } } - if (mNonces != null) { + if (authority != null && authority.noncesEnabled()) { long n = mRandom.nextLong(); - long m = mNonces.addNonce(n, getSSLClientCertificate(request)); - if ((n + m) != 0) { - args.set(ARG_REQUEST_NONCE, Long.toString(m)); - } + Map<Object, Long> nonces = authority.getNonces(request, "cert-request"); + nonces.put(req.getRequestId().toBigInteger(), n); + args.set(ARG_REQUEST_NONCE, Long.toString(n)); } args.set(ARG_REQUEST_ID, req.getRequestId().toString()); |