summaryrefslogtreecommitdiffstats
path: root/base/common/src/com/netscape/cms/servlet
diff options
context:
space:
mode:
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet')
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/CertService.java44
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java72
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java54
-rw-r--r--base/common/src/com/netscape/cms/servlet/processors/Processor.java2
4 files changed, 112 insertions, 60 deletions
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 9b7b9d45e..e049710cb 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.Random;
import netscape.security.pkcs.ContentInfo;
import netscape.security.pkcs.PKCS7;
@@ -43,6 +44,7 @@ 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;
@@ -65,6 +67,7 @@ import com.netscape.certsrv.logging.ILogger;
import com.netscape.certsrv.request.IRequest;
import com.netscape.cms.servlet.base.PKIService;
import com.netscape.cms.servlet.processors.Processor;
+import com.netscape.cmscore.realm.PKIPrincipal;
import com.netscape.cmsutil.ldap.LDAPUtil;
import com.netscape.cmsutil.util.Utils;
@@ -76,11 +79,17 @@ public class CertService extends PKIService implements CertResource {
ICertificateAuthority authority;
ICertificateRepository repo;
+ Random random;
+ Nonces nonces;
public final static int DEFAULT_SIZE = 20;
public CertService() {
authority = (ICertificateAuthority) CMS.getSubsystem("ca");
+ if (authority.noncesEnabled()) {
+ random = new Random();
+ nonces = authority.getNonces();
+ }
repo = authority.getCertificateRepository();
}
@@ -92,6 +101,15 @@ public class CertService extends PKIService implements CertResource {
@Override
public CertData getCert(CertId id) {
+ return getCert(id, false);
+ }
+
+ @Override
+ public CertData reviewCert(CertId id) {
+ return getCert(id, true);
+ }
+
+ public CertData getCert(CertId id, boolean generateNonce) {
validateRequest(id);
CertRetrievalRequest data = new CertRetrievalRequest();
@@ -100,13 +118,13 @@ public class CertService extends PKIService implements CertResource {
CertData certData = null;
try {
- certData = getCert(data);
+ certData = getCert(data, generateNonce);
} catch (EDBRecordNotFoundException e) {
throw new CertNotFoundException(id);
} catch (EBaseException e) {
- throw new PKIException("Problem returning certificate: " + id);
+ throw new PKIException(e.getMessage(), e);
} catch (CertificateEncodingException e) {
- throw new PKIException("Problem encoding certificate searched for: " + id);
+ throw new PKIException(e.getMessage(), e);
}
return certData;
@@ -177,12 +195,20 @@ public class CertService extends PKIService implements CertResource {
}
}
+ processor.validateNonce(clientCert, request.getNonce());
+
// Find target cert record if different from client cert.
ICertRecord targetRecord = id.equals(clientSerialNumber) ? clientRecord : processor.getCertificateRecord(id);
X509CertImpl targetCert = targetRecord.getCertificate();
processor.createCRLExtension();
- processor.validateCertificateToRevoke(clientSubjectDN, targetRecord, caCert);
+
+ PKIPrincipal principal = (PKIPrincipal)servletRequest.getUserPrincipal();
+ // TODO: do not hard-code role name
+ String subjectDN = principal.hasRole("Certificate Manager Agents") ?
+ null : clientSubjectDN;
+
+ processor.validateCertificateToRevoke(subjectDN, targetRecord, caCert);
processor.addCertificateToRevoke(targetCert);
processor.createRevocationRequest();
@@ -410,7 +436,7 @@ public class CertService extends PKIService implements CertResource {
return ret;
}
- public CertData getCert(CertRetrievalRequest data) throws EBaseException, CertificateEncodingException {
+ public CertData getCert(CertRetrievalRequest data, boolean generateNonce) throws EBaseException, CertificateEncodingException {
CertId certId = data.getCertId();
//find the cert in question
@@ -444,6 +470,14 @@ public class CertService extends PKIService implements CertResource {
certData.setStatus(record.getStatus());
+ if (generateNonce && nonces != null) {
+ long n = random.nextLong();
+ long m = nonces.addNonce(n, Processor.getSSLClientCertificate(servletRequest));
+ if (n + m != 0) {
+ certData.setNonce(m);
+ }
+ }
+
URI uri = uriInfo.getBaseUriBuilder().path(CertResource.class).path("{id}").build(certId.toHexString());
certData.setLink(new Link("self", uri));
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 f45947e8c..5d33bf2bc 100644
--- a/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
+++ b/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
@@ -47,6 +47,7 @@ import com.netscape.certsrv.authority.ICertAuthority;
import com.netscape.certsrv.authorization.AuthzToken;
import com.netscape.certsrv.authorization.EAuthzAccessDenied;
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;
@@ -62,10 +63,8 @@ import com.netscape.certsrv.ra.IRegistrationAuthority;
import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestStatus;
-import com.netscape.certsrv.usrgrp.Certificates;
import com.netscape.certsrv.usrgrp.ICertUserLocator;
import com.netscape.certsrv.usrgrp.IUGSubsystem;
-import com.netscape.certsrv.usrgrp.IUser;
import com.netscape.cms.servlet.base.CMSServlet;
import com.netscape.cms.servlet.common.CMSRequest;
import com.netscape.cms.servlet.common.CMSTemplate;
@@ -207,47 +206,6 @@ public class DoRevoke extends CMSServlet {
}
revokeAll = req.getParameter("revokeAll");
- if (mNonces != null) {
- boolean nonceVerified = false;
- boolean skipNonceVerification = false;
-
- X509Certificate cert2 = getSSLClientCertificate(req);
- if (cert2 != null) {
- X509Certificate certChain[] = new X509Certificate[1];
- certChain[0] = cert2;
- IUser user = null;
- try {
- user = mUL.locateUser(new Certificates(certChain));
- } catch (Exception e) {
- CMS.debug("DoRevoke: Failed to map certificate '" +
- cert2.getSubjectDN().getName() + "' to user.");
- }
- if (mUG.isMemberOf(user, "Subsystem Group")) {
- skipNonceVerification = true;
- }
- }
-
- String nonceStr = req.getParameter("nonce");
- if (nonceStr != null) {
- long nonce = Long.parseLong(nonceStr.trim());
- X509Certificate cert1 = mNonces.getCertificate(nonce);
- if (cert1 == null) {
- CMS.debug("DoRevoke: Unknown nonce");
- } else if (cert1 != null && cert2 != null && cert1.equals(cert2)) {
- nonceVerified = true;
- mNonces.removeNonce(nonce);
- }
- } else {
- CMS.debug("DoRevoke: Missing nonce");
- }
- CMS.debug("DoRevoke: nonceVerified=" + nonceVerified);
- CMS.debug("DoRevoke: skipNonceVerification=" + skipNonceVerification);
- if ((!nonceVerified) && (!skipNonceVerification)) {
- cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
- return;
- }
- }
-
String comments = req.getParameter(IRequest.REQUESTOR_COMMENTS);
String eeSubjectDN = null;
String eeSerialNumber = null;
@@ -279,11 +237,13 @@ public class DoRevoke extends CMSServlet {
if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
if (authToken != null) {
+ // Request is from agent.
String serialNumber = req.getParameter("serialNumber");
getSSLClientCertificate(req); // throw exception on error
if (serialNumber != null) {
+ // Agent has null subject DN.
eeSerialNumber = serialNumber;
}
@@ -294,7 +254,7 @@ public class DoRevoke extends CMSServlet {
" authenticated by " + authMgr;
}
} else {
- // request is fromUser.
+ // Request is from user.
initiative = AuditFormat.FROMUSER;
String serialNumber = req.getParameter("serialNumber");
@@ -302,7 +262,8 @@ public class DoRevoke extends CMSServlet {
if (serialNumber == null || sslCert == null ||
!(serialNumber.equals(sslCert.getSerialNumber().toString(16)))) {
- authorized = false;
+ throw new ForbiddenException("Invalid serial number.");
+
} else {
eeSubjectDN = sslCert.getSubjectDN().toString();
eeSerialNumber = sslCert.getSerialNumber().toString();
@@ -310,19 +271,21 @@ public class DoRevoke extends CMSServlet {
}
- if (authorized) {
- BigInteger serialNumber = parseSerialNumber(eeSerialNumber);
+ BigInteger serialNumber = parseSerialNumber(eeSerialNumber);
- process(argSet, header, reason, invalidityDate, initiative,
- req, resp, verifiedRecordCount, revokeAll,
- totalRecordCount, serialNumber, eeSubjectDN,
- comments, locale[0]);
- }
+ process(argSet, header, reason, invalidityDate, initiative,
+ req, resp, verifiedRecordCount, revokeAll,
+ totalRecordCount, serialNumber, eeSubjectDN,
+ comments, locale[0]);
} catch (NumberFormatException e) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
error = new EBaseException(CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+
+ } catch (ForbiddenException e) {
+ authorized = false;
+
} catch (EBaseException e) {
error = e;
}
@@ -442,6 +405,11 @@ public class DoRevoke extends CMSServlet {
processor.setAuthority((ICertificateAuthority)mAuthority);
}
+ X509Certificate clientCert = getSSLClientCertificate(req);
+ String requestedNonce = req.getParameter("nonce");
+ Long nonce = requestedNonce == null ? null : new Long(requestedNonce.trim());
+ processor.validateNonce(clientCert, nonce);
+
try {
processor.createCRLExtension();
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 36d00459b..341314887 100644
--- a/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java
+++ b/base/common/src/com/netscape/cms/servlet/cert/RevocationProcessor.java
@@ -38,6 +38,7 @@ import com.netscape.certsrv.apps.CMS;
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.UnauthorizedException;
import com.netscape.certsrv.ca.ICertificateAuthority;
import com.netscape.certsrv.dbs.certdb.CertId;
@@ -50,6 +51,8 @@ import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IRequestQueue;
import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.usrgrp.Certificates;
+import com.netscape.certsrv.usrgrp.IUser;
/**
* @author Endi S. Dewata
@@ -185,14 +188,59 @@ public class RevocationProcessor extends CertProcessor {
return request;
}
- public void validateCertificateToRevoke(String clientSubjectDN, ICertRecord targetRecord, boolean revokingCACert) {
+ public void validateNonce(X509Certificate clientCert, Long nonce) {
+
+ if (nonces != null) {
+ boolean nonceVerified = false;
+ boolean skipNonceVerification = 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;
+ }
+ }
+
+ if (nonce != null) {
+ X509Certificate storedCert = nonces.getCertificate(nonce);
+ if (storedCert == null) {
+ CMS.debug("RevocationProcessor: Unknown nonce");
+
+ } 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.");
+ }
+ }
+
+ }
+
+ public void validateCertificateToRevoke(String subjectDN, ICertRecord targetRecord, boolean revokingCACert) {
X509CertImpl targetCert = targetRecord.getCertificate();
BigInteger targetSerialNumber = targetCert.getSerialNumber();
Principal targetSubjectDN = targetCert.getSubjectDN();
- // Verify client cert's subject DN matches the target cert's subject DN.
- if (clientSubjectDN != null && !clientSubjectDN.equals(targetSubjectDN.toString())) {
+ // Verify the subject DN matches the target cert's subject DN.
+ // Agent has null subject DN so he can revoke any certificate.
+ // Other users can only revoke their own certificate.
+ if (subjectDN != null && !subjectDN.equals(targetSubjectDN.toString())) {
throw new UnauthorizedException(
"Certificate 0x" + targetSerialNumber.toString(16) + " belongs to different subject.");
}
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 fdbc85dd5..423d1bed5 100644
--- a/base/common/src/com/netscape/cms/servlet/processors/Processor.java
+++ b/base/common/src/com/netscape/cms/servlet/processors/Processor.java
@@ -59,6 +59,7 @@ import com.netscape.certsrv.profile.IProfileSubsystem;
import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IRequestQueue;
import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.usrgrp.ICertUserLocator;
import com.netscape.certsrv.usrgrp.IGroup;
import com.netscape.certsrv.usrgrp.IUGSubsystem;
import com.netscape.certsrv.util.IStatsSubsystem;
@@ -144,6 +145,7 @@ public class Processor {
protected ICertificateAuthority authority = (ICertificateAuthority) CMS.getSubsystem("ca");
protected IAuthzSubsystem authz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
protected IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+ protected ICertUserLocator ul = ug.getCertUserLocator();
protected IRequestQueue queue;
protected IProfileSubsystem ps;
protected ICertificateRepository certdb;