use of com.github.zhenwei.core.asn1.ocsp.CertID in project snowflake-jdbc by snowflakedb.
the class SFTrustManager method executeOneRevocationStatusCheck.
/**
* Executes a single revocation status check
*
* @param pairIssuerSubject a pair of issuer and subject certificate
* @param currentTimeSecond the current timestamp
* @throws CertificateException if certificate exception is raised.
*/
private void executeOneRevocationStatusCheck(SFPair<Certificate, Certificate> pairIssuerSubject, long currentTimeSecond, String peerHost) throws CertificateException {
OCSPReq req;
OcspResponseCacheKey keyOcspResponse;
try {
req = createRequest(pairIssuerSubject);
CertID cid = req.getRequestList()[0].getCertID().toASN1Primitive();
keyOcspResponse = new OcspResponseCacheKey(cid.getIssuerNameHash().getEncoded(), cid.getIssuerKeyHash().getEncoded(), cid.getSerialNumber().getValue());
} catch (IOException ex) {
throw new CertificateException(ex.getMessage(), ex);
}
long sleepTime = INITIAL_SLEEPING_TIME_IN_MILLISECONDS;
DecorrelatedJitterBackoff backoff = new DecorrelatedJitterBackoff(sleepTime, MAX_SLEEPING_TIME_IN_MILLISECONDS);
CertificateException error;
boolean success = false;
String ocspLog;
OCSPTelemetryData telemetryData = new OCSPTelemetryData();
telemetryData.setSfcPeerHost(peerHost);
telemetryData.setCertId(encodeCacheKey(keyOcspResponse));
telemetryData.setCacheEnabled(useOCSPResponseCacheServer());
telemetryData.setOCSPMode(ocspMode);
Throwable cause = null;
try {
final int maxRetryCounter = isOCSPFailOpen() ? 1 : 2;
for (int retry = 0; retry < maxRetryCounter; ++retry) {
try {
if (ssdManager.getSSDSupportStatus()) {
// Look for Host Specific SSD in SSD Cache
success = checkSSD(keyOcspResponse, peerHost);
if (success) {
break;
}
}
SFPair<Long, String> value0 = OCSP_RESPONSE_CACHE.get(keyOcspResponse);
OCSPResp ocspResp;
try {
try {
if (value0 == null) {
telemetryData.setCacheHit(false);
ocspResp = fetchOcspResponse(pairIssuerSubject, req, encodeCacheKey(keyOcspResponse), peerHost, telemetryData);
OCSP_RESPONSE_CACHE.put(keyOcspResponse, SFPair.of(currentTimeSecond, ocspResponseToB64(ocspResp)));
WAS_CACHE_UPDATED.set(true);
value0 = SFPair.of(currentTimeSecond, ocspResponseToB64(ocspResp));
} else {
telemetryData.setCacheHit(true);
}
} catch (Throwable ex) {
LOGGER.debug("Exception occurred while trying to fetch OCSP Response - {}", ex.getMessage());
throw new SFOCSPException(OCSPErrorCode.OCSP_RESPONSE_FETCH_FAILURE, "Exception occurred while trying to fetch OCSP Response", ex);
}
LOGGER.debug("validating. {}", CertificateIDToString(req.getRequestList()[0].getCertID()));
try {
validateRevocationStatusMain(pairIssuerSubject, value0.right);
success = true;
break;
} catch (SFOCSPException ex) {
if (ex.getErrorCode() != OCSPErrorCode.REVOCATION_CHECK_FAILURE) {
throw ex;
}
if (ssdManager.getSSDSupportStatus() && this.processOCSPBypassSSD(value0.right, keyOcspResponse, peerHost)) {
// Failed processing OCSP response. Try processing cache value as SSD
success = true;
break;
} else {
throw new CertificateException(ex.getMessage(), ex);
}
}
} catch (SFOCSPException ex) {
if (ex.getErrorCode() == OCSPErrorCode.CERTIFICATE_STATUS_REVOKED) {
throw ex;
} else {
throw new CertificateException(ex.getMessage(), ex);
}
}
} catch (CertificateException ex) {
WAS_CACHE_UPDATED.set(OCSP_RESPONSE_CACHE.remove(keyOcspResponse) != null);
if (WAS_CACHE_UPDATED.get()) {
LOGGER.debug("deleting the invalid OCSP cache.");
}
cause = ex;
LOGGER.debug("Retrying {}/{} after sleeping {}(ms)", retry + 1, maxRetryCounter, sleepTime);
try {
if (retry + 1 < maxRetryCounter) {
Thread.sleep(sleepTime);
sleepTime = backoff.nextSleepTime(sleepTime);
}
} catch (InterruptedException ex0) {
// nop
}
}
}
} catch (SFOCSPException ex) {
// Revoked Certificate
error = new CertificateException(ex);
ocspLog = telemetryData.generateTelemetry(SF_OCSP_EVENT_TYPE_REVOKED_CERTIFICATE_ERROR, error);
LOGGER.error(ocspLog);
throw error;
}
if (!success) {
if (// cause is set in the above catch block
cause != null) {
error = new CertificateException("Certificate Revocation check failed. Could not retrieve OCSP Response.", cause);
LOGGER.debug(cause.getMessage());
} else {
error = new CertificateException("Certificate Revocation check failed. Could not retrieve OCSP Response.");
LOGGER.debug(error.getMessage());
}
ocspLog = telemetryData.generateTelemetry(SF_OCSP_EVENT_TYPE_VALIDATION_ERROR, error);
if (isOCSPFailOpen()) {
// Log includes fail-open warning.
LOGGER.error(generateFailOpenLog(ocspLog));
} else {
// still not success, raise an error.
LOGGER.debug(ocspLog);
throw error;
}
}
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project snowflake-jdbc by snowflakedb.
the class SFTrustManager method isCached.
/**
* Is OCSP Response cached?
*
* @param pairIssuerSubjectList a list of pair of issuer and subject certificates
* @return true if all of OCSP response are cached else false
*/
private boolean isCached(List<SFPair<Certificate, Certificate>> pairIssuerSubjectList) {
long currentTimeSecond = new Date().getTime() / 1000L;
boolean isCached = true;
try {
for (SFPair<Certificate, Certificate> pairIssuerSubject : pairIssuerSubjectList) {
OCSPReq req = createRequest(pairIssuerSubject);
CertificateID certificateId = req.getRequestList()[0].getCertID();
LOGGER.debug(CertificateIDToString(certificateId));
CertID cid = certificateId.toASN1Primitive();
OcspResponseCacheKey k = new OcspResponseCacheKey(cid.getIssuerNameHash().getEncoded(), cid.getIssuerKeyHash().getEncoded(), cid.getSerialNumber().getValue());
SFPair<Long, String> res = OCSP_RESPONSE_CACHE.get(k);
if (res == null) {
LOGGER.debug("Not all OCSP responses for the certificate is in the cache.");
isCached = false;
break;
} else if (currentTimeSecond - CACHE_EXPIRATION_IN_SECONDS > res.left) {
LOGGER.debug("Cache for CertID expired.");
isCached = false;
break;
} else {
try {
validateRevocationStatusMain(pairIssuerSubject, res.right);
} catch (SFOCSPException ex) {
LOGGER.debug("Cache includes invalid OCSPResponse. " + "Will download the OCSP cache from Snowflake OCSP server");
isCached = false;
}
}
}
} catch (IOException ex) {
LOGGER.debug("Failed to encode CertID.");
}
return isCached;
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project xipki by xipki.
the class AbstractOcspRequestor method ask.
@Override
public OCSPResp ask(X509Certificate issuerCert, BigInteger[] serialNumbers, URL responderUrl, RequestOptions requestOptions, RequestResponseDebug debug) throws OcspResponseException, OcspRequestorException {
ParamUtil.requireNonNull("issuerCert", issuerCert);
ParamUtil.requireNonNull("requestOptions", requestOptions);
ParamUtil.requireNonNull("responderUrl", responderUrl);
byte[] nonce = null;
if (requestOptions.isUseNonce()) {
nonce = nextNonce(requestOptions.getNonceLen());
}
OCSPRequest ocspReq = buildRequest(issuerCert, serialNumbers, nonce, requestOptions);
byte[] encodedReq;
try {
encodedReq = ocspReq.getEncoded();
} catch (IOException ex) {
throw new OcspRequestorException("could not encode OCSP request: " + ex.getMessage(), ex);
}
RequestResponsePair msgPair = null;
if (debug != null) {
msgPair = new RequestResponsePair();
debug.add(msgPair);
if (debug.saveRequest()) {
msgPair.setRequest(encodedReq);
}
}
byte[] encodedResp;
try {
encodedResp = send(encodedReq, responderUrl, requestOptions);
} catch (IOException ex) {
throw new ResponderUnreachableException("IOException: " + ex.getMessage(), ex);
}
if (msgPair != null && debug.saveResponse()) {
msgPair.setResponse(encodedResp);
}
OCSPResp ocspResp;
try {
ocspResp = new OCSPResp(encodedResp);
} catch (IOException ex) {
throw new InvalidOcspResponseException("IOException: " + ex.getMessage(), ex);
}
Object respObject;
try {
respObject = ocspResp.getResponseObject();
} catch (OCSPException ex) {
throw new InvalidOcspResponseException("responseObject is invalid");
}
if (ocspResp.getStatus() != 0) {
return ocspResp;
}
if (!(respObject instanceof BasicOCSPResp)) {
return ocspResp;
}
BasicOCSPResp basicOcspResp = (BasicOCSPResp) respObject;
if (nonce != null) {
Extension nonceExtn = basicOcspResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
if (nonceExtn == null) {
throw new OcspNonceUnmatchedException(nonce, null);
}
byte[] receivedNonce = nonceExtn.getExtnValue().getOctets();
if (!Arrays.equals(nonce, receivedNonce)) {
throw new OcspNonceUnmatchedException(nonce, receivedNonce);
}
}
SingleResp[] singleResponses = basicOcspResp.getResponses();
if (singleResponses == null || singleResponses.length == 0) {
String msg = StringUtil.concat("response with no singleResponse is returned, expected is ", Integer.toString(serialNumbers.length));
throw new OcspTargetUnmatchedException(msg);
}
final int countSingleResponses = singleResponses.length;
if (countSingleResponses != serialNumbers.length) {
String msg = StringUtil.concat("response with ", Integer.toString(countSingleResponses), " singleResponse", (countSingleResponses > 1 ? "s" : ""), " is returned, expected is ", Integer.toString(serialNumbers.length));
throw new OcspTargetUnmatchedException(msg);
}
Request reqAt0 = Request.getInstance(ocspReq.getTbsRequest().getRequestList().getObjectAt(0));
CertID certId = reqAt0.getReqCert();
ASN1ObjectIdentifier issuerHashAlg = certId.getHashAlgorithm().getAlgorithm();
byte[] issuerKeyHash = certId.getIssuerKeyHash().getOctets();
byte[] issuerNameHash = certId.getIssuerNameHash().getOctets();
if (serialNumbers.length == 1) {
SingleResp singleResp = singleResponses[0];
CertificateID cid = singleResp.getCertID();
boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
if (!issuerMatch) {
throw new OcspTargetUnmatchedException("the issuer is not requested");
}
BigInteger serialNumber = cid.getSerialNumber();
if (!serialNumbers[0].equals(serialNumber)) {
throw new OcspTargetUnmatchedException("the serialNumber is not requested");
}
} else {
List<BigInteger> tmpSerials1 = Arrays.asList(serialNumbers);
List<BigInteger> tmpSerials2 = new ArrayList<>(tmpSerials1);
for (int i = 0; i < countSingleResponses; i++) {
SingleResp singleResp = singleResponses[i];
CertificateID cid = singleResp.getCertID();
boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
if (!issuerMatch) {
throw new OcspTargetUnmatchedException("the issuer specified in singleResponse[" + i + "] is not requested");
}
BigInteger serialNumber = cid.getSerialNumber();
if (!tmpSerials2.remove(serialNumber)) {
if (tmpSerials1.contains(serialNumber)) {
throw new OcspTargetUnmatchedException("serialNumber " + LogUtil.formatCsn(serialNumber) + "is contained in at least two singleResponses");
} else {
throw new OcspTargetUnmatchedException("serialNumber " + LogUtil.formatCsn(serialNumber) + " specified in singleResponse[" + i + "] is not requested");
}
}
}
// end for
}
return ocspResp;
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project jruby-openssl by jruby.
the class OCSPSingleResponse method certid.
@JRubyMethod(name = "certid")
public IRubyObject certid(ThreadContext context) {
Ruby runtime = context.runtime;
CertID bcCertId = bcSingleResponse.getCertID();
OCSPCertificateId rubyCertId = new OCSPCertificateId(runtime);
try {
rubyCertId.initialize(context, RubyString.newString(runtime, bcCertId.getEncoded()));
} catch (IOException e) {
throw newOCSPError(runtime, e);
}
return rubyCertId;
}
use of com.github.zhenwei.core.asn1.ocsp.CertID in project jruby-openssl by jruby.
the class OCSPBasicResponse method add_status.
@JRubyMethod(name = "add_status", rest = true)
public OCSPBasicResponse add_status(final ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.getRuntime();
Arity.checkArgumentCount(runtime, args, 7, 7);
IRubyObject certificateId = args[0];
IRubyObject status = args[1];
IRubyObject reason = args[2];
IRubyObject revocation_time = args[3];
IRubyObject this_update = args[4];
IRubyObject next_update = args[5];
IRubyObject extensions = args[6];
CertStatus certStatus = null;
switch(RubyFixnum.fix2int((RubyFixnum) status)) {
case 0:
certStatus = new CertStatus();
break;
case 1:
ASN1GeneralizedTime revTime = rubyIntOrTimeToGenTime(revocation_time);
RevokedInfo revokedInfo = new RevokedInfo(revTime, CRLReason.lookup(RubyFixnum.fix2int((RubyFixnum) reason)));
certStatus = new CertStatus(revokedInfo);
break;
case 2:
certStatus = new CertStatus(2, DERNull.INSTANCE);
break;
default:
break;
}
ASN1GeneralizedTime thisUpdate = rubyIntOrTimeToGenTime(this_update);
ASN1GeneralizedTime nextUpdate = rubyIntOrTimeToGenTime(next_update);
Extensions singleExtensions = convertRubyExtensions(extensions);
CertID certID = ((OCSPCertificateId) certificateId).getCertID();
SingleResponse ocspSingleResp = new SingleResponse(certID, certStatus, thisUpdate, nextUpdate, singleExtensions);
OCSPSingleResponse rubySingleResp = new OCSPSingleResponse(runtime);
try {
rubySingleResp.initialize(context, RubyString.newString(runtime, ocspSingleResp.getEncoded()));
singleResponses.add(rubySingleResp);
} catch (IOException e) {
throw newOCSPError(runtime, e);
}
return this;
}
Aggregations