// --- BEGIN COPYRIGHT BLOCK ---
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// (C) 2007 Red Hat, Inc.
// All rights reserved.
// --- END COPYRIGHT BLOCK ---
package com.netscape.cms.servlet.cert;
import java.io.IOException;
import java.math.BigInteger;
import java.security.PublicKey;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import netscape.security.provider.RSAPublicKey;
import netscape.security.x509.CRLExtensions;
import netscape.security.x509.CRLReasonExtension;
import netscape.security.x509.CertificateX509Key;
import netscape.security.x509.Extension;
import netscape.security.x509.X500Name;
import netscape.security.x509.X509CertImpl;
import netscape.security.x509.X509Key;
import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.authorization.AuthzToken;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IArgBlock;
import com.netscape.certsrv.ca.ICertificateAuthority;
import com.netscape.certsrv.dbs.certdb.ICertRecord;
import com.netscape.certsrv.dbs.certdb.ICertRecordList;
import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
import com.netscape.certsrv.dbs.certdb.IRevocationInfo;
import com.netscape.certsrv.logging.ILogger;
import com.netscape.cms.servlet.base.CMSServlet;
import com.netscape.cms.servlet.common.CMSRequest;
import com.netscape.cms.servlet.common.CMSTemplate;
import com.netscape.cms.servlet.common.CMSTemplateParams;
import com.netscape.cms.servlet.common.ECMSGWException;
/**
* Retrieve a paged list of certs matching the specified query
*
* @version $Revision$, $Date$
*/
public class ListCerts extends CMSServlet {
/**
*
*/
private static final long serialVersionUID = -3568155814023099576L;
private final static String TPL_FILE = "queryCert.template";
private final static String INFO = "ListCerts";
private final static BigInteger MINUS_ONE = new BigInteger("-1");
private final static String CURRENT_TIME = "currentTime";
private final static String USE_CLIENT_FILTER = "useClientFilter";
private final static String ALLOWED_CLIENT_FILTERS = "allowedClientFilters";
private ICertificateRepository mCertDB = null;
private X500Name mAuthName = null;
private String mFormPath = null;
private boolean mReverse = false;
private boolean mHardJumpTo = false; //jump to the end
private String mDirection = null;
private boolean mUseClientFilter = false;
private Vector mAllowedClientFilters = new Vector();
private int mMaxReturns = 2000;
/**
* Constructs query key servlet.
*/
public ListCerts() {
super();
}
/**
* initialize the servlet. This servlet uses the template file
* "queryCert.template" to render the response
*
* @param sc servlet configuration, read from the web.xml file
*/
public void init(ServletConfig sc) throws ServletException {
super.init(sc);
// override success to render own template.
mTemplates.remove(CMSRequest.SUCCESS);
if (mAuthority instanceof ICertificateAuthority) {
ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
mCertDB = ca.getCertificateRepository();
mAuthName = ca.getX500Name();
}
mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
if (mOutputTemplatePath != null)
mFormPath = mOutputTemplatePath;
try {
mMaxReturns = Integer.parseInt(sc.getInitParameter("maxResults"));
} catch (Exception e) {
/* do nothing, just use the default if integer parsing failed */
}
/* useClientFilter should be off by default. We keep
this parameter around so that we do not break
the client applications that submits raw LDAP
filter into this servlet. */
if (sc.getInitParameter(USE_CLIENT_FILTER) != null &&
sc.getInitParameter(USE_CLIENT_FILTER).equalsIgnoreCase("true")) { mUseClientFilter = true;
}
if (sc.getInitParameter(ALLOWED_CLIENT_FILTERS) == null || sc.getInitParameter(ALLOWED_CLIENT_FILTERS).equals("")) {
mAllowedClientFilters.addElement("(certStatus=*)");
mAllowedClientFilters.addElement("(certStatus=VALID)");
mAllowedClientFilters.addElement("(|(certStatus=VALID)(certStatus=INVALID)(certStatus=EXPIRED))");
mAllowedClientFilters.addElement("(|(certStatus=VALID)(certStatus=REVOKED))");
} else {
StringTokenizer st = new StringTokenizer(sc.getInitParameter(ALLOWED_CLIENT_FILTERS), ",");
while (st.hasMoreTokens()) {
mAllowedClientFilters.addElement(st.nextToken());
}
}
}
public String buildFilter(HttpServletRequest req)
{
String queryCertFilter = req.getParameter("queryCertFilter");
com.netscape.certsrv.apps.CMS.debug("client queryCertFilter=" + queryCertFilter);
if (mUseClientFilter) {
com.netscape.certsrv.apps.CMS.debug("useClientFilter=true");
Enumeration filters = mAllowedClientFilters.elements();
// check to see if the filter is allowed
while (filters.hasMoreElements()) {
String filter = (String)filters.nextElement();
com.netscape.certsrv.apps.CMS.debug("Comparing filter=" + filter + " queryCertFilter=" + queryCertFilter);
if (filter.equals(queryCertFilter)) {
return queryCertFilter;
}
}
com.netscape.certsrv.apps.CMS.debug("Requested filter '" + queryCertFilter + "' is not allowed. Please check the " + ALLOWED_CLIENT_FILTERS + "parameter");
return null;
} else {
com.netscape.certsrv.apps.CMS.debug("useClientFilter=false");
}
boolean skipRevoked = false;
boolean skipNonValid = false;
if (req.getParameter("skipRevoked") != null &&
req.getParameter("skipRevoked").equals("on")) {
skipRevoked = true;
}
if (req.getParameter("skipNonValid") != null &&
req.getParameter("skipNonValid").equals("on")) {
skipNonValid = true;
}
if (!skipRevoked && !skipNonValid) {
queryCertFilter = "(certStatus=*)";
} else if (skipRevoked && skipNonValid) {
queryCertFilter = "(certStatus=VALID)";
} else if (skipRevoked) {
queryCertFilter = "(|(certStatus=VALID)(certStatus=INVALID)(certStatus=EXPIRED))";
} else if (skipNonValid) {
queryCertFilter = "(|(certStatus=VALID)(certStatus=REVOKED))";
}
return queryCertFilter;
}
/**
* Process the HTTP request.
*
* - http.param maxCount Number of certificates to show
*
- http.param queryFilter and ldap style filter specifying the
* certificates to show
*
- http.param querySentinelDown the serial number of the first certificate to show (default decimal, or hex if prefixed with 0x) when paging down
*
- http.param querySentinelUp the serial number of the first certificate to show (default decimal, or hex if prefixed with 0x) when paging up
*
- http.param direction "up", "down", "begin", or "end"
*
*/
public void process(CMSRequest cmsReq) throws EBaseException {
HttpServletRequest req = cmsReq.getHttpReq();
HttpServletResponse resp = cmsReq.getHttpResp();
IAuthToken authToken = authenticate(cmsReq);
AuthzToken authzToken = null;
try {
authzToken = authorize(mAclMethod, authToken,
mAuthzResourceName, "list");
} catch (Exception e) {
}
if (authzToken == null) {
cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
return;
}
String revokeAll = null;
EBaseException error = null;
int maxCount = -1;
BigInteger sentinel = new BigInteger("0");
IArgBlock header = com.netscape.certsrv.apps.CMS.createArgBlock();
IArgBlock ctx = com.netscape.certsrv.apps.CMS.createArgBlock();
CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
CMSTemplate form = null;
Locale[] locale = new Locale[1];
try {
form = getTemplate(mFormPath, req, locale);
} catch (IOException e) {
log(ILogger.LL_FAILURE,
com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
throw new ECMSGWException(
com.netscape.certsrv.apps.CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
}
mHardJumpTo = false;
try {
if (req.getParameter("direction") != null) {
mDirection = req.getParameter("direction").trim();
mReverse = mDirection.equals("up");
if (mReverse)
com.netscape.certsrv.apps.CMS.debug("reverse is true");
else
com.netscape.certsrv.apps.CMS.debug("reverse is false");
}
if (req.getParameter("maxCount") != null) {
maxCount = Integer.parseInt(req.getParameter("maxCount"));
}
if (maxCount == -1 || maxCount > mMaxReturns) {
com.netscape.certsrv.apps.CMS.debug("Resetting page size from " + maxCount + " to " + mMaxReturns);
maxCount = mMaxReturns;
}
String sentinelStr = "";
if (mReverse) {
sentinelStr = req.getParameter("querySentinelUp");
} else if (mDirection.equals("end")) {
// this servlet will figure out the end
sentinelStr = "0";
mReverse = true;
mHardJumpTo = true;
} else if (mDirection.equals("down")) {
sentinelStr = req.getParameter("querySentinelDown");
} else
sentinelStr = "0";
//begin and non-specified have sentinel default "0"
if (sentinelStr != null) {
if (sentinelStr.trim().startsWith("0x")) {
sentinel = new BigInteger(sentinelStr.trim().substring(2), 16);
} else {
sentinel = new BigInteger(sentinelStr, 10);
}
}
revokeAll = req.getParameter("revokeAll");
if (mAuthority instanceof ICertificateAuthority) {
X509CertImpl caCert = ((ICertificateAuthority) mAuthority).getSigningUnit().getCertImpl();
//if (isCertFromCA(caCert))
header.addStringValue("caSerialNumber",
caCert.getSerialNumber().toString(16));
}
// constructs the ldap filter on the server side
String queryCertFilter = buildFilter(req);
if (queryCertFilter == null) {
cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
return;
}
com.netscape.certsrv.apps.CMS.debug("queryCertFilter=" + queryCertFilter);
int totalRecordCount = -1;
try {
totalRecordCount = Integer.parseInt(req.getParameter("totalRecordCount"));
} catch (Exception e) {
}
processCertFilter(argSet, header, maxCount,
sentinel,
totalRecordCount,
req.getParameter("serialTo"),
queryCertFilter,
req, resp, revokeAll, locale[0]);
} catch (NumberFormatException e) {
log(ILogger.LL_FAILURE, com.netscape.certsrv.apps.CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
error = new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
} catch (EBaseException e) {
error = e;
}
ctx.addIntegerValue("maxCount", maxCount);
try {
ServletOutputStream out = resp.getOutputStream();
if (error == null) {
String xmlOutput = req.getParameter("xml");
if (xmlOutput != null && xmlOutput.equals("true")) {
outputXML(resp, argSet);
} else {
cmsReq.setStatus(CMSRequest.SUCCESS);
resp.setContentType("text/html");
form.renderOutput(out, argSet);
}
} else {
cmsReq.setStatus(CMSRequest.ERROR);
cmsReq.setError(error);
}
} catch (IOException e) {
log(ILogger.LL_FAILURE,
com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
throw new ECMSGWException(
com.netscape.certsrv.apps.CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
}
}
private void processCertFilter(CMSTemplateParams argSet,
IArgBlock header,
int maxCount,
BigInteger sentinel,
int totalRecordCount,
String serialTo,
String filter,
HttpServletRequest req,
HttpServletResponse resp,
String revokeAll,
Locale locale
) throws EBaseException {
BigInteger serialToVal = MINUS_ONE;
try {
if (serialTo != null) {
serialTo = serialTo.trim();
if (serialTo.startsWith("0x")) {
serialToVal = new BigInteger
(serialTo.substring(2), 16);
serialTo = serialToVal.toString();
} else {
serialToVal = new BigInteger(serialTo);
}
}
} catch (Exception e) {
}
String jumpTo = sentinel.toString();
int pSize = 0;
if (mReverse) {
if (!mHardJumpTo) //reverse gets one more
pSize = -1*maxCount-1;
else
pSize = -1*maxCount;
} else
pSize = maxCount;
ICertRecordList list = (ICertRecordList) mCertDB.findCertRecordsInList(
filter, (String[]) null, jumpTo, mHardJumpTo, "serialno",
pSize);
// retrive maxCount + 1 entries
Enumeration e = list.getCertRecords(0, maxCount);
ICertRecordList tolist = null;
int toCurIndex = 0;
if (!serialToVal.equals(MINUS_ONE)) {
// if user specify a range, we need to
// calculate the totalRecordCount
tolist = (ICertRecordList) mCertDB.findCertRecordsInList(
filter,
(String[]) null, serialTo,
"serialno", maxCount);
Enumeration en = tolist.getCertRecords(0, 0);
if (en == null || (!en.hasMoreElements())) {
toCurIndex = list.getSize() - 1;
} else {
toCurIndex = tolist.getCurrentIndex();
ICertRecord rx = (ICertRecord) en.nextElement();
BigInteger curToSerial = rx.getSerialNumber();
if (curToSerial.compareTo(serialToVal) == -1) {
toCurIndex = list.getSize() - 1;
} else {
if (!rx.getSerialNumber().toString().equals(serialTo.trim())) {
toCurIndex = toCurIndex - 1;
}
}
}
}
int curIndex = list.getCurrentIndex();
int count = 0;
BigInteger firstSerial = new BigInteger("0");
BigInteger curSerial = new BigInteger("0");
ICertRecord[] recs = new ICertRecord[maxCount];
int rcount = 0;
if (e != null) {
/* in reverse (page up), because the sentinel is the one after the
* last item to be displayed, we need to skip it
*/
while ((count < ((mReverse &&!mHardJumpTo)? (maxCount+1):maxCount)) && e.hasMoreElements()) {
ICertRecord rec = (ICertRecord) e.nextElement();
if (rec == null) {
com.netscape.certsrv.apps.CMS.debug("record "+count+" is null");
break;
}
curSerial = rec.getSerialNumber();
com.netscape.certsrv.apps.CMS.debug("record "+count+" is serial#"+curSerial);
if (count == 0) {
firstSerial = curSerial;
if (mReverse && !mHardJumpTo) {//reverse got one more, skip
count++;
continue;
}
}
// DS has a problem where last record will be returned
// even though the filter is not matched.
/*cfu - is this necessary? it breaks when paging up
if (curSerial.compareTo(sentinel) == -1) {
com.netscape.certsrv.apps.CMS.debug("curSerial compare sentinel -1 break...");
break;
}
*/
if (!serialToVal.equals(MINUS_ONE)) {
// check if we go over the limit
if (curSerial.compareTo(serialToVal) == 1) {
com.netscape.certsrv.apps.CMS.debug("curSerial compare serialToVal 1 breaking...");
break;
}
}
if (mReverse) {
recs[rcount++] = rec;
} else {
IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
fillRecordIntoArg(rec, rarg);
argSet.addRepeatRecord(rarg);
}
count++;
}
} else {
com.netscape.certsrv.apps.CMS.debug(
"ListCerts::processCertFilter() - no Cert Records found!" );
return;
}
if (mReverse) {
// fill records into arg block and argSet
for (int ii = rcount-1; ii>= 0; ii--) {
if (recs[ii] != null) {
IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
//com.netscape.certsrv.apps.CMS.debug("item "+ii+" is serial # "+ recs[ii].getSerialNumber());
fillRecordIntoArg(recs[ii], rarg);
argSet.addRepeatRecord(rarg);
}
}
}
// peek ahead
ICertRecord nextRec = null;
if (e.hasMoreElements()) {
nextRec = (ICertRecord) e.nextElement();
}
header.addStringValue("op", req.getParameter("op"));
if (revokeAll != null)
header.addStringValue("revokeAll", revokeAll);
if (mAuthName != null)
header.addStringValue("issuerName", mAuthName.toString());
if (!serialToVal.equals(MINUS_ONE))
header.addStringValue("serialTo", serialToVal.toString());
header.addStringValue("serviceURL", req.getRequestURI());
header.addStringValue("queryCertFilter", filter);
header.addStringValue("templateName", "queryCert");
header.addStringValue("queryFilter", filter);
header.addIntegerValue("maxCount", maxCount);
if (totalRecordCount == -1) {
if (!serialToVal.equals(MINUS_ONE)) {
totalRecordCount = toCurIndex - curIndex + 1;
com.netscape.certsrv.apps.CMS.debug("totalRecordCount="+totalRecordCount);
} else {
totalRecordCount = list.getSize() -
list.getCurrentIndex();
com.netscape.certsrv.apps.CMS.debug("totalRecordCount="+totalRecordCount);
}
}
header.addIntegerValue("totalRecordCount", totalRecordCount);
header.addIntegerValue("currentRecordCount", list.getSize() -
list.getCurrentIndex());
String qs = "";
if (mReverse)
qs = "querySentinelUp";
else
qs = "querySentinelDown";
if (mHardJumpTo) {
com.netscape.certsrv.apps.CMS.debug("curSerial added to querySentinelUp:"+ curSerial.toString());
header.addStringValue("querySentinelUp", curSerial.toString());
} else {
if (nextRec == null) {
header.addStringValue(qs, null);
com.netscape.certsrv.apps.CMS.debug("nextRec is null");
if (mReverse) {
com.netscape.certsrv.apps.CMS.debug("curSerial added to querySentinelUp:"+ curSerial.toString());
header.addStringValue("querySentinelUp", curSerial.toString());
}
} else {
BigInteger nextRecNo = nextRec.getSerialNumber();
if (serialToVal.equals(MINUS_ONE)) {
header.addStringValue(
qs, nextRecNo.toString());
} else {
if (nextRecNo.compareTo(serialToVal) <= 0) {
header.addStringValue(
qs, nextRecNo.toString());
} else {
header.addStringValue(qs,
null);
}
}
com.netscape.certsrv.apps.CMS.debug("querySentinel "+qs+" = "+nextRecNo.toString());
}
} // !mHardJumpto
header.addStringValue(!mReverse? "querySentinelUp":"querySentinelDown",
firstSerial.toString());
}
/**
* Process the key search.
*/
private void process(CMSTemplateParams argSet, IArgBlock header,
int maxCount, int sentinel,
String filter, HttpServletRequest req,
HttpServletResponse resp,
String revokeAll, Locale locale)
throws EBaseException {
try {
if (filter.indexOf(CURRENT_TIME, 0) > -1) {
filter = insertCurrentTime(filter);
}
if (revokeAll != null && revokeAll.indexOf(CURRENT_TIME, 0) > -1) {
revokeAll = insertCurrentTime(revokeAll);
}
// xxx the filter includes serial number range???
ICertRecordList list =
(ICertRecordList) mCertDB.findCertRecordsInList(filter, null, maxCount);
// sentinel is the index on the list now, not serial number
Enumeration e =
list.getCertRecords(sentinel, sentinel + maxCount - 1);
int count = 0;
while (e != null && e.hasMoreElements()) {
ICertRecord rec = (ICertRecord) e.nextElement();
count++;
IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
fillRecordIntoArg(rec, rarg);
argSet.addRepeatRecord(rarg);
}
header.addStringValue("op", req.getParameter("op"));
if (revokeAll != null)
header.addStringValue("revokeAll", revokeAll);
if (mAuthName != null)
header.addStringValue("issuerName", mAuthName.toString());
header.addStringValue("serviceURL", req.getRequestURI());
header.addStringValue("templateName", "queryCert");
header.addStringValue("queryFilter", filter);
header.addIntegerValue("maxCount", maxCount);
header.addIntegerValue("totalRecordCount", list.getSize());
if ((sentinel + count) < list.getSize())
header.addIntegerValue("querySentinelDown", sentinel + count);
else
header.addStringValue("querySentinelDown", null);
} catch (EBaseException e) {
log(ILogger.LL_FAILURE, com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERROR_LISTCERTS", e.toString()));
throw e;
}
return;
}
private String insertCurrentTime(String filter) {
Date now = null;
StringBuffer newFilter = new StringBuffer();
int k = 0;
int i = filter.indexOf(CURRENT_TIME, k);
while (i > -1) {
if (now == null) now = new Date();
if (newFilter.length() == 0) {
newFilter.append(filter.substring(k, i));
newFilter.append(now.getTime());
} else {
newFilter.append(filter.substring(k, i));
newFilter.append(now.getTime());
}
k = i + CURRENT_TIME.length();
i = filter.indexOf(CURRENT_TIME, k);
}
if (k > 0) {
newFilter.append(filter.substring(k, filter.length()));
}
return newFilter.toString();
}
/**
* Fills cert record into argument block.
*/
private void fillRecordIntoArg(ICertRecord rec, IArgBlock rarg)
throws EBaseException {
X509CertImpl xcert = rec.getCertificate();
if (xcert != null) {
fillX509RecordIntoArg(rec, rarg);
}
}
private void fillX509RecordIntoArg(ICertRecord rec, IArgBlock rarg)
throws EBaseException {
X509CertImpl cert = rec.getCertificate();
rarg.addIntegerValue("version", cert.getVersion());
rarg.addStringValue("serialNumber", cert.getSerialNumber().toString(16));
rarg.addStringValue("serialNumberDecimal", cert.getSerialNumber().toString());
if (cert.getSubjectDN().toString().equals("")) {
rarg.addStringValue("subject", " ");
} else
rarg.addStringValue("subject", cert.getSubjectDN().toString());
rarg.addStringValue("type", "X.509");
try {
PublicKey pKey = cert.getPublicKey();
X509Key key = null;
if (pKey instanceof CertificateX509Key) {
CertificateX509Key certKey = (CertificateX509Key) pKey;
key = (X509Key) certKey.get(CertificateX509Key.KEY);
}
if (pKey instanceof X509Key) {
key = (X509Key) pKey;
}
rarg.addStringValue("subjectPublicKeyAlgorithm", key.getAlgorithmId().getOID().toString());
if (key.getAlgorithmId().toString().equalsIgnoreCase("RSA")) {
RSAPublicKey rsaKey = new RSAPublicKey(key.getEncoded());
rarg.addIntegerValue("subjectPublicKeyLength", rsaKey.getKeySize());
}
} catch (Exception e) {
rarg.addStringValue("subjectPublicKeyAlgorithm", null);
rarg.addIntegerValue("subjectPublicKeyLength", 0);
}
rarg.addLongValue("validNotBefore", cert.getNotBefore().getTime() / 1000);
rarg.addLongValue("validNotAfter", cert.getNotAfter().getTime() / 1000);
rarg.addStringValue("signatureAlgorithm", cert.getSigAlgOID());
String issuedBy = rec.getIssuedBy();
if (issuedBy == null) issuedBy = "";
rarg.addStringValue("issuedBy", issuedBy); // cert.getIssuerDN().toString()
rarg.addLongValue("issuedOn", rec.getCreateTime().getTime() / 1000);
rarg.addStringValue("revokedBy",
((rec.getRevokedBy() == null) ? "" : rec.getRevokedBy()));
if (rec.getRevokedOn() == null) {
rarg.addStringValue("revokedOn", null);
} else {
rarg.addLongValue("revokedOn", rec.getRevokedOn().getTime() / 1000);
IRevocationInfo revocationInfo = rec.getRevocationInfo();
if (revocationInfo != null) {
CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
if (crlExts != null) {
Enumeration enum1 = crlExts.getElements();
int reason = 0;
while (enum1.hasMoreElements()) {
Extension ext = (Extension) enum1.nextElement();
if (ext instanceof CRLReasonExtension) {
reason = ((CRLReasonExtension) ext).getReason().toInt();
break;
}
}
rarg.addIntegerValue("revocationReason", reason);
}
}
}
}
}