From 4c0aa7ccd717034bc7528ac2e8487869ef4d9bcb Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Mon, 29 Jan 2024 22:11:43 -0600 Subject: [PATCH] Refactor CertificateAuthority.validate() --- .../com/netscape/ca/CertificateAuthority.java | 147 +++++++----------- .../org/dogtagpki/server/ca/CAEngine.java | 70 ++++++++- 2 files changed, 122 insertions(+), 95 deletions(-) diff --git a/base/ca/src/main/java/com/netscape/ca/CertificateAuthority.java b/base/ca/src/main/java/com/netscape/ca/CertificateAuthority.java index 2921c7408c8..475ba334be1 100644 --- a/base/ca/src/main/java/com/netscape/ca/CertificateAuthority.java +++ b/base/ca/src/main/java/com/netscape/ca/CertificateAuthority.java @@ -32,10 +32,11 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateParsingException; import java.security.interfaces.RSAKey; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; -import java.util.Vector; +import java.util.List; import org.dogtagpki.server.ca.CAConfig; import org.dogtagpki.server.ca.CAEngine; @@ -84,7 +85,6 @@ import com.netscape.cmscore.apps.CMS; import com.netscape.cmscore.dbs.CertRecord; import com.netscape.cmscore.dbs.CertificateRepository; -import com.netscape.cmscore.util.StatsSubsystem; import com.netscape.cmsutil.crypto.CryptoUtil; import com.netscape.cmsutil.ocsp.BasicOCSPResponse; import com.netscape.cmsutil.ocsp.CertID; @@ -92,11 +92,8 @@ import com.netscape.cmsutil.ocsp.GoodInfo; import com.netscape.cmsutil.ocsp.KeyHashID; import com.netscape.cmsutil.ocsp.NameID; -import com.netscape.cmsutil.ocsp.OCSPResponse; -import com.netscape.cmsutil.ocsp.OCSPResponseStatus; import com.netscape.cmsutil.ocsp.Request; import com.netscape.cmsutil.ocsp.ResponderID; -import com.netscape.cmsutil.ocsp.ResponseBytes; import com.netscape.cmsutil.ocsp.ResponseData; import com.netscape.cmsutil.ocsp.RevokedInfo; import com.netscape.cmsutil.ocsp.SingleResponse; @@ -785,6 +782,10 @@ public long getOCSPRequestTotalTime() { return mTotalTime; } + public void incOCSPRequestTotalTime(long time) { + mTotalTime += time; + } + /** * Returns the total data signed * for OCSP requests. @@ -844,112 +845,69 @@ public ResponderID getResponderIDByHash() { return new KeyHashID(new OCTET_STRING(digested)); } - public OCSPResponse validate(TBSRequest tbsReq)throws EBaseException { + public SingleResponse[] getCertStatus(TBSRequest tbsRequest) throws EBaseException { - logger.debug("CertificateAuthority: validating OCSP request"); + long lookupStartTime = new Date().getTime(); mNumOCSPRequest++; - StatsSubsystem statsSub = (StatsSubsystem) engine.getSubsystem(StatsSubsystem.ID); - long startTime = new Date().getTime(); - - try { - //logger.info("start OCSP request"); - - // (3) look into database to check the - // certificate's status - Vector singleResponses = new Vector<>(); - - if (statsSub != null) { - statsSub.startTiming("lookup"); - } - - long lookupStartTime = new Date().getTime(); - - for (int i = 0; i < tbsReq.getRequestCount(); i++) { - Request req = tbsReq.getRequestAt(i); - SingleResponse sr = processRequest(req); - singleResponses.addElement(sr); - } - long lookupEndTime = new Date().getTime(); - mLookupTime += lookupEndTime - lookupStartTime; + List responses = new ArrayList<>(); - if (statsSub != null) { - statsSub.endTiming("lookup"); - } - - if (statsSub != null) { - statsSub.startTiming("build_response"); - } + // (3) look into database to check the + // certificate's status - SingleResponse res[] = new SingleResponse[singleResponses.size()]; - singleResponses.copyInto(res); - - ResponderID rid = null; + for (int i = 0; i < tbsRequest.getRequestCount(); i++) { + Request request = tbsRequest.getRequestAt(i); + SingleResponse sr = processRequest(request); + responses.add(sr); + } - if (ocspResponderByName) { - if (mResponderIDByName == null) { - mResponderIDByName = getResponderIDByName(); - } - rid = mResponderIDByName; - } else { - if (mResponderIDByHash == null) { - mResponderIDByHash = getResponderIDByHash(); - } - rid = mResponderIDByHash; - } + SingleResponse[] certStatus = new SingleResponse[responses.size()]; + responses.toArray(certStatus); - Extension nonce[] = null; + long lookupEndTime = new Date().getTime(); + mLookupTime += lookupEndTime - lookupStartTime; - for (int j = 0; j < tbsReq.getExtensionsCount(); j++) { - Extension thisExt = tbsReq.getRequestExtensionAt(j); + return certStatus; + } - if (thisExt.getExtnId().equals(OCSP_NONCE)) { - nonce = new Extension[1]; - nonce[0] = thisExt; - } - } + public ResponseData buildOCSPResponse( + TBSRequest tbsReq, + boolean getResponderIDByName, + SingleResponse[] certStatus) { - ResponseData rd = new ResponseData(rid, - new GeneralizedTime(new Date()), res, nonce); + ResponderID rid = null; - if (statsSub != null) { - statsSub.endTiming("build_response"); + if (getResponderIDByName) { + if (mResponderIDByName == null) { + mResponderIDByName = getResponderIDByName(); } + rid = mResponderIDByName; - if (statsSub != null) { - statsSub.startTiming("signing"); + } else { + if (mResponderIDByHash == null) { + mResponderIDByHash = getResponderIDByHash(); } + rid = mResponderIDByHash; + } - long signStartTime = new Date().getTime(); - - BasicOCSPResponse basicRes = sign(rd); + Extension[] nonce = null; - long signEndTime = new Date().getTime(); - mSignTime += signEndTime - signStartTime; + for (int j = 0; j < tbsReq.getExtensionsCount(); j++) { + Extension requestExtension = tbsReq.getRequestExtensionAt(j); - if (statsSub != null) { - statsSub.endTiming("signing"); + if (requestExtension.getExtnId().equals(OCSP_NONCE)) { + nonce = new Extension[1]; + nonce[0] = requestExtension; } - - OCSPResponse response = new OCSPResponse( - OCSPResponseStatus.SUCCESSFUL, - new ResponseBytes(ResponseBytes.OCSP_BASIC, - new OCTET_STRING(ASN1Util.encode(basicRes)))); - - //logger.info("done OCSP request"); - long endTime = new Date().getTime(); - mTotalTime += endTime - startTime; - - return response; - - } catch (EBaseException e) { - logger.error(CMS.getLogMessage("CMSCORE_CA_CA_OCSP_REQUEST", e.toString()), e); - throw e; } + + return new ResponseData(rid, new GeneralizedTime(new Date()), certStatus, nonce); } - private BasicOCSPResponse sign(ResponseData rd) throws EBaseException { + public BasicOCSPResponse signOCSPResponse(ResponseData rd) throws EBaseException { + + long signStartTime = new Date().getTime(); CAEngine engine = CAEngine.getInstance(); ensureReady(); @@ -979,14 +937,11 @@ private BasicOCSPResponse sign(ResponseData rd) throws EBaseException { tmpChain.putDerValue(new DerValue(chains[i].getEncoded())); } tmp1.write(DerValue.tag_Sequence, tmpChain); - tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), - tmp1); + tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), tmp1); out.write(DerValue.tag_Sequence, tmp); - BasicOCSPResponse response = new BasicOCSPResponse(out.toByteArray()); - - return response; + return new BasicOCSPResponse(out.toByteArray()); } catch (NoSuchAlgorithmException e) { logger.error(CMS.getLogMessage("OPERATION_ERROR", e.toString()), e); @@ -1000,6 +955,10 @@ private BasicOCSPResponse sign(ResponseData rd) throws EBaseException { } catch (Exception e) { logger.error(CMS.getLogMessage("CMSCORE_CA_CA_OCSP_SIGN", e.toString()), e); throw new EBaseException(e); + + } finally { + long signEndTime = new Date().getTime(); + mSignTime += signEndTime - signStartTime; } } diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/CAEngine.java b/base/ca/src/main/java/org/dogtagpki/server/ca/CAEngine.java index 1a051cf35c9..a26f98f4f65 100644 --- a/base/ca/src/main/java/org/dogtagpki/server/ca/CAEngine.java +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/CAEngine.java @@ -33,6 +33,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; @@ -56,6 +57,8 @@ import org.mozilla.jss.NicknameConflictException; import org.mozilla.jss.NotInitializedException; import org.mozilla.jss.UserCertConflictException; +import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; @@ -154,10 +157,15 @@ import com.netscape.cmscore.util.StatsSubsystem; import com.netscape.cmsutil.crypto.CryptoUtil; import com.netscape.cmsutil.ldap.LDAPPostReadControl; +import com.netscape.cmsutil.ocsp.BasicOCSPResponse; import com.netscape.cmsutil.ocsp.CertID; import com.netscape.cmsutil.ocsp.OCSPRequest; import com.netscape.cmsutil.ocsp.OCSPResponse; +import com.netscape.cmsutil.ocsp.OCSPResponseStatus; import com.netscape.cmsutil.ocsp.Request; +import com.netscape.cmsutil.ocsp.ResponseBytes; +import com.netscape.cmsutil.ocsp.ResponseData; +import com.netscape.cmsutil.ocsp.SingleResponse; import com.netscape.cmsutil.ocsp.TBSRequest; import netscape.ldap.LDAPAttribute; @@ -2748,7 +2756,67 @@ public OCSPResponse validate( } } - return ca.validate(tbsRequest); + return validate(ca, tbsRequest); + } + + public OCSPResponse validate( + CertificateAuthority ca, + TBSRequest tbsRequest) + throws EBaseException { + + logger.debug("CAEngine: validating OCSP request"); + + StatsSubsystem statsSub = (StatsSubsystem) subsystems.get(StatsSubsystem.ID); + long startTime = new Date().getTime(); + + try { + //logger.info("start OCSP request"); + + if (statsSub != null) { + statsSub.startTiming("lookup"); + } + + SingleResponse[] certStatus = ca.getCertStatus(tbsRequest); + + if (statsSub != null) { + statsSub.endTiming("lookup"); + } + + if (statsSub != null) { + statsSub.startTiming("build_response"); + } + + ResponseData rd = ca.buildOCSPResponse(tbsRequest, getOCSPResponderByName(), certStatus); + + if (statsSub != null) { + statsSub.endTiming("build_response"); + } + + if (statsSub != null) { + statsSub.startTiming("signing"); + } + + BasicOCSPResponse basicResponse = ca.signOCSPResponse(rd); + + if (statsSub != null) { + statsSub.endTiming("signing"); + } + + OCSPResponse response = new OCSPResponse( + OCSPResponseStatus.SUCCESSFUL, + new ResponseBytes(ResponseBytes.OCSP_BASIC, + new OCTET_STRING(ASN1Util.encode(basicResponse)))); + + //logger.info("done OCSP request"); + long endTime = new Date().getTime(); + ca.incOCSPRequestTotalTime(endTime - startTime); + + return response; + + } catch (EBaseException e) { + logger.error(CMS.getLogMessage("CMSCORE_CA_CA_OCSP_REQUEST", e.toString()), e); + throw e; + } } /**