diff --git a/jans-auth-server/client/pom.xml b/jans-auth-server/client/pom.xml
index 14a8f49a6c9..3deea71d6a7 100644
--- a/jans-auth-server/client/pom.xml
+++ b/jans-auth-server/client/pom.xml
@@ -237,11 +237,11 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on
org.testng
diff --git a/jans-auth-server/common/pom.xml b/jans-auth-server/common/pom.xml
index c050308b70f..ce88f413208 100644
--- a/jans-auth-server/common/pom.xml
+++ b/jans-auth-server/common/pom.xml
@@ -163,11 +163,11 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on
com.nimbusds
diff --git a/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/CRLCertificateVerifier.java b/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/CRLCertificateVerifier.java
index d2fb0a66079..22e1e038685 100644
--- a/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/CRLCertificateVerifier.java
+++ b/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/CRLCertificateVerifier.java
@@ -6,36 +6,12 @@
package io.jans.as.common.cert.validation;
-import com.google.common.base.Preconditions;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import io.jans.as.common.cert.validation.model.ValidationStatus;
-import io.jans.util.security.SecurityProviderUtility;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.input.BoundedInputStream;
-import org.bouncycastle.asn1.ASN1InputStream;
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERIA5String;
-import org.bouncycastle.asn1.x509.CRLDistPoint;
-import org.bouncycastle.asn1.x509.DistributionPoint;
-import org.bouncycastle.asn1.x509.DistributionPointName;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.asn1.x509.GeneralNames;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
import java.net.URL;
import java.security.NoSuchProviderException;
import java.security.Principal;
@@ -50,6 +26,37 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.BoundedInputStream;
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x509.CRLDistPoint;
+import org.bouncycastle.asn1.x509.DistributionPoint;
+import org.bouncycastle.asn1.x509.DistributionPointName;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.X509Extensions;
+import org.bouncycastle.x509.NoSuchParserException;
+import org.bouncycastle.x509.util.StreamParsingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+import io.jans.as.common.cert.validation.model.ValidationStatus;
+import io.jans.as.common.cert.validation.model.ValidationStatus.CertificateValidity;
+import io.jans.as.common.cert.validation.model.ValidationStatus.ValidatorSourceType;
+import io.jans.as.model.util.CertUtils;
+import io.jans.util.security.SecurityProviderUtility;
+
/**
* Certificate verifier based on CRL
*
@@ -58,231 +65,239 @@
*/
public class CRLCertificateVerifier implements CertificateVerifier {
- private static final Logger log = LoggerFactory.getLogger(CRLCertificateVerifier.class);
-
- private final int maxCrlSize;
-
- private final LoadingCache crlCache;
-
- public CRLCertificateVerifier(final int maxCrlSize) {
- SecurityProviderUtility.installBCProvider(true);
-
- this.maxCrlSize = maxCrlSize;
-
- CacheLoader checkedLoader = new CacheLoader() {
- public X509CRL load(String crlURL) throws CertificateException, CRLException, NoSuchProviderException, IOException, ExecutionException {
- X509CRL result = requestCRL(crlURL);
- Preconditions.checkNotNull(result);
-
- return result;
- }
- };
-
- this.crlCache = CacheBuilder.newBuilder().maximumSize(10).expireAfterWrite(60, TimeUnit.MINUTES).build(checkedLoader);
- }
-
- /**
- * @param certificate the certificate from which we need the ExtensionValue
- * @param oid the Object Identifier value for the extension.
- * @return the extension value as an ASN1Primitive object
- * @throws IOException
- */
- private static ASN1Primitive getExtensionValue(X509Certificate certificate, String oid) throws IOException {
- byte[] bytes = certificate.getExtensionValue(oid);
- if (bytes == null) {
- return null;
- }
- ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes));
- ASN1OctetString octs = (ASN1OctetString) aIn.readObject();
- aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets()));
- return aIn.readObject();
- }
-
- @Override
- public ValidationStatus validate(X509Certificate certificate, List issuers, Date validationDate) {
- X509Certificate issuer = issuers.get(0);
- ValidationStatus status = new ValidationStatus(certificate, issuer, validationDate, ValidationStatus.ValidatorSourceType.CRL, ValidationStatus.CertificateValidity.UNKNOWN);
-
- try {
- Principal subjectX500Principal = certificate.getSubjectX500Principal();
-
- String crlURL = getCrlUri(certificate);
- if (crlURL == null) {
- log.error("CRL's URL for '" + subjectX500Principal + "' is empty");
- return status;
- }
-
- log.debug("CRL's URL for '" + subjectX500Principal + "' is '" + crlURL + "'");
-
- X509CRL x509crl = getCrl(crlURL);
- if (!validateCRL(x509crl, certificate, issuer, validationDate)) {
- log.error("The CRL is not valid!");
- status.setValidity(ValidationStatus.CertificateValidity.INVALID);
- return status;
- }
-
- X509CRLEntry crlEntry = x509crl.getRevokedCertificate(certificate.getSerialNumber());
- if (crlEntry == null) {
- log.debug("CRL status is valid for '" + subjectX500Principal + "'");
- status.setValidity(ValidationStatus.CertificateValidity.VALID);
- } else if (crlEntry.getRevocationDate().after(validationDate)) {
- log.warn("CRL revocation time after the validation date, the certificate '" + subjectX500Principal + "' was valid at " + validationDate);
- status.setRevocationObjectIssuingTime(x509crl.getThisUpdate());
- status.setValidity(ValidationStatus.CertificateValidity.VALID);
- } else {
- log.info("CRL for certificate '" + subjectX500Principal + "' is revoked since " + crlEntry.getRevocationDate());
- status.setRevocationObjectIssuingTime(x509crl.getThisUpdate());
- status.setRevocationDate(crlEntry.getRevocationDate());
- status.setValidity(ValidationStatus.CertificateValidity.REVOKED);
- }
- } catch (Exception ex) {
- log.error("CRL exception: ", ex);
- }
-
- return status;
- }
-
- private boolean validateCRL(X509CRL x509crl, X509Certificate certificate, X509Certificate issuerCertificate, Date validationDate) {
- Principal subjectX500Principal = certificate.getSubjectX500Principal();
-
- if (x509crl == null) {
- log.error("No CRL found for certificate '" + subjectX500Principal + "'");
- return false;
- }
-
- if (log.isTraceEnabled()) {
- try {
- log.trace("CRL number: " + getCrlNumber(x509crl));
- } catch (IOException ex) {
- log.error("Failed to get CRL number", ex);
- }
- }
-
- if (!x509crl.getIssuerX500Principal().equals(issuerCertificate.getSubjectX500Principal())) {
- log.error("The CRL must be signed by the issuer '" + subjectX500Principal + "' but instead is signed by '"
- + x509crl.getIssuerX500Principal() + "'");
- return false;
- }
-
- try {
- x509crl.verify(issuerCertificate.getPublicKey());
- } catch (Exception ex) {
- log.error("The signature verification for CRL cannot be performed", ex);
- return false;
- }
-
- log.debug("CRL validationDate: " + validationDate);
- log.debug("CRL nextUpdate: " + x509crl.getThisUpdate());
- log.debug("CRL thisUpdate: " + x509crl.getNextUpdate());
-
- if (x509crl.getNextUpdate() != null && validationDate.after(x509crl.getNextUpdate())) {
- log.error("CRL is too old");
- return false;
- }
-
- if (issuerCertificate.getKeyUsage() == null) {
- log.error("There is no KeyUsage extension for certificate '" + subjectX500Principal + "'");
- return false;
- }
-
- if (!issuerCertificate.getKeyUsage()[6]) {
- log.error("cRLSign bit is not set for CRL certificate'" + subjectX500Principal + "'");
- return false;
- }
-
- return true;
-
- }
-
- private X509CRL getCrl(String url) throws ExecutionException {
- if (!(url.startsWith("http://") || url.startsWith("https://"))) {
- log.error("It's possible to download CRL via HTTP and HTTPS only");
- return null;
- }
-
- String cacheKey = url.toLowerCase();
- return crlCache.get(cacheKey);
- }
-
- public X509CRL requestCRL(String url) throws IOException, CertificateException, CRLException {
- HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
- try {
- con.setUseCaches(false);
-
- InputStream in = new BoundedInputStream(con.getInputStream(), maxCrlSize);
- try {
- CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
- X509CRL crl = (X509CRL) certificateFactory.generateCRL(in);
- log.debug("CRL size: " + crl.getEncoded().length + " bytes");
-
- return crl;
- } finally {
- IOUtils.closeQuietly(in);
- }
- } catch (IOException ex) {
- log.error("Failed to download CRL from '" + url + "'", ex);
- } finally {
- if (con != null) {
- con.disconnect();
- }
- }
-
- return null;
- }
-
- @SuppressWarnings({"deprecation", "resource"})
- private BigInteger getCrlNumber(X509CRL crl) throws IOException {
- byte[] crlNumberExtensionValue = crl.getExtensionValue(Extension.cRLNumber.getId());
- if (crlNumberExtensionValue == null) {
- return null;
- }
-
- ASN1OctetString octetString = (ASN1OctetString) (new ASN1InputStream(new ByteArrayInputStream(crlNumberExtensionValue)).readObject());
- byte[] octets = octetString.getOctets();
- ASN1Integer integer = (ASN1Integer) new ASN1InputStream(octets).readObject();
- return integer.getPositiveValue();
- }
-
- public String getCrlUri(X509Certificate certificate) throws IOException {
- ASN1Primitive obj;
- try {
- obj = getExtensionValue(certificate, Extension.cRLDistributionPoints.getId());
- } catch (IOException ex) {
- log.error("Failed to get CRL URL", ex);
- return null;
- }
-
- if (obj == null) {
- return null;
- }
-
- CRLDistPoint distPoint = CRLDistPoint.getInstance(obj);
-
- DistributionPoint[] distributionPoints = distPoint.getDistributionPoints();
- for (DistributionPoint distributionPoint : distributionPoints) {
- DistributionPointName distributionPointName = distributionPoint.getDistributionPoint();
- if (DistributionPointName.FULL_NAME != distributionPointName.getType()) {
- continue;
- }
-
- GeneralNames generalNames = (GeneralNames) distributionPointName.getName();
- GeneralName[] names = generalNames.getNames();
- for (GeneralName name : names) {
- if (name.getTagNo() != GeneralName.uniformResourceIdentifier) {
- continue;
- }
-
- DERIA5String derStr = DERIA5String.getInstance((ASN1TaggedObject) name.toASN1Primitive(), false);
- return derStr.getString();
- }
- }
-
- return null;
- }
-
- @Override
- public void destroy() {
- crlCache.cleanUp();
- }
+ private static final Logger log = LoggerFactory.getLogger(CRLCertificateVerifier.class);
+
+ private int maxCrlSize;
+
+ private LoadingCache crlCache;
+
+ public CRLCertificateVerifier(final int maxCrlSize) {
+ SecurityProviderUtility.installBCProvider(true);
+
+ this.maxCrlSize = maxCrlSize;
+
+ CacheLoader checkedLoader = new CacheLoader() {
+ public X509CRL load(String crlURL) throws CertificateException, CRLException, NoSuchProviderException, NoSuchParserException, StreamParsingException, MalformedURLException, IOException, ExecutionException {
+ X509CRL result = requestCRL(crlURL);
+ Preconditions.checkNotNull(result);
+
+ return result;
+ }
+ };
+
+ this.crlCache = CacheBuilder.newBuilder().maximumSize(10).expireAfterWrite(60, TimeUnit.MINUTES).build(checkedLoader);
+ }
+
+ @Override
+ public ValidationStatus validate(X509Certificate certificate, List issuers, Date validationDate) {
+
+ X509Certificate issuer = CertUtils.getIssuer(certificate, issuers);
+ ValidationStatus status = new ValidationStatus(certificate, issuer, validationDate, ValidatorSourceType.CRL, CertificateValidity.UNKNOWN);
+
+ try {
+ Principal subjectX500Principal = certificate.getSubjectX500Principal();
+
+ String crlURL = getCrlUri(certificate);
+ if (crlURL == null) {
+ log.error("CRL's URL for '" + subjectX500Principal + "' is empty");
+ return status;
+ }
+
+ log.debug("CRL's URL for '" + subjectX500Principal + "' is '" + crlURL + "'");
+
+ X509CRL x509crl = getCrl(crlURL);
+ if (!validateCRL(x509crl, certificate, issuer, validationDate)) {
+ log.error("The CRL is not valid!");
+ status.setValidity(CertificateValidity.INVALID);
+ return status;
+ }
+
+ X509CRLEntry crlEntry = x509crl.getRevokedCertificate(certificate.getSerialNumber());
+ if (crlEntry == null) {
+ log.debug("CRL status is valid for '" + subjectX500Principal + "'");
+ status.setValidity(CertificateValidity.VALID);
+ } else if (crlEntry.getRevocationDate().after(validationDate)) {
+ log.warn("CRL revocation time after the validation date, the certificate '" + subjectX500Principal + "' was valid at " + validationDate);
+ status.setRevocationObjectIssuingTime(x509crl.getThisUpdate());
+ status.setValidity(CertificateValidity.VALID);
+ } else {
+ log.info("CRL for certificate '" + subjectX500Principal + "' is revoked since " + crlEntry.getRevocationDate());
+ status.setRevocationObjectIssuingTime(x509crl.getThisUpdate());
+ status.setRevocationDate(crlEntry.getRevocationDate());
+ status.setValidity(CertificateValidity.REVOKED);
+ }
+ } catch (Exception ex) {
+ log.error("CRL exception: ", ex);
+ }
+
+ return status;
+ }
+
+ private boolean validateCRL(X509CRL x509crl, X509Certificate certificate, X509Certificate issuerCertificate, Date validationDate) {
+ Principal subjectX500Principal = certificate.getSubjectX500Principal();
+
+ if (x509crl == null) {
+ log.error("No CRL found for certificate '" + subjectX500Principal + "'");
+ return false;
+ }
+
+ if (log.isTraceEnabled()) {
+ try {
+ log.trace("CRL number: " + getCrlNumber(x509crl));
+ } catch (IOException ex) {
+ log.error("Failed to get CRL number", ex);
+ }
+ }
+
+ if (!x509crl.getIssuerX500Principal().equals(issuerCertificate.getSubjectX500Principal())) {
+ log.error("The CRL must be signed by the issuer '" + subjectX500Principal + "' but instead is signed by '"
+ + x509crl.getIssuerX500Principal() + "'");
+ return false;
+ }
+
+ try {
+ x509crl.verify(issuerCertificate.getPublicKey());
+ } catch (Exception ex) {
+ log.error("The signature verification for CRL cannot be performed", ex);
+ return false;
+ }
+
+ log.debug("CRL validationDate: " + validationDate);
+ log.debug("CRL nextUpdate: " + x509crl.getThisUpdate());
+ log.debug("CRL thisUpdate: " + x509crl.getNextUpdate());
+
+ if (x509crl.getNextUpdate() != null && validationDate.after(x509crl.getNextUpdate())) {
+ log.error("CRL is too old");
+ return false;
+ }
+
+ if (issuerCertificate.getKeyUsage() == null) {
+ log.error("There is no KeyUsage extension for certificate '" + subjectX500Principal + "'");
+ return false;
+ }
+
+ if (!issuerCertificate.getKeyUsage()[6]) {
+ log.error("cRLSign bit is not set for CRL certificate'" + subjectX500Principal + "'");
+ return false;
+ }
+
+ return true;
+
+ }
+
+ private X509CRL getCrl(String url) throws CertificateException, CRLException, NoSuchProviderException, NoSuchParserException, StreamParsingException,
+ MalformedURLException, IOException, ExecutionException {
+ if (!(url.startsWith("http://") || url.startsWith("https://"))) {
+ log.error("It's possible to download CRL via HTTP and HTTPS only");
+ return null;
+ }
+
+ String cacheKey = url.toLowerCase();
+ X509CRL crl = crlCache.get(cacheKey);
+
+ return crl;
+ }
+
+ public X509CRL requestCRL(String url) throws IOException, MalformedURLException, CertificateException, CRLException {
+ HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
+ try {
+ con.setUseCaches(false);
+
+ InputStream in = new BoundedInputStream(con.getInputStream(), maxCrlSize);
+ try {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+ X509CRL crl = (X509CRL) certificateFactory.generateCRL(in);
+ log.debug("CRL size: " + crl.getEncoded().length + " bytes");
+
+ return crl;
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ } catch (IOException ex) {
+ log.error("Failed to download CRL from '" + url + "'", ex);
+ } finally {
+ if (con != null) {
+ con.disconnect();
+ }
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings({ "deprecation", "resource" })
+ private BigInteger getCrlNumber(X509CRL crl) throws IOException {
+ byte[] crlNumberExtensionValue = crl.getExtensionValue(X509Extensions.CRLNumber.getId());
+ if (crlNumberExtensionValue == null) {
+ return null;
+ }
+
+ ASN1OctetString octetString = (ASN1OctetString) (new ASN1InputStream(new ByteArrayInputStream(crlNumberExtensionValue)).readObject());
+ byte[] octets = octetString.getOctets();
+ ASN1Integer integer = (ASN1Integer) new ASN1InputStream(octets).readObject();
+ BigInteger crlNumber = integer.getPositiveValue();
+
+ return crlNumber;
+ }
+
+ public String getCrlUri(X509Certificate certificate) throws IOException {
+ ASN1Primitive obj;
+ try {
+ obj = getExtensionValue(certificate, Extension.cRLDistributionPoints.getId());
+ } catch (IOException ex) {
+ log.error("Failed to get CRL URL", ex);
+ return null;
+ }
+
+ if (obj == null) {
+ return null;
+ }
+
+ CRLDistPoint distPoint = CRLDistPoint.getInstance(obj);
+
+ DistributionPoint[] distributionPoints = distPoint.getDistributionPoints();
+ for (DistributionPoint distributionPoint : distributionPoints) {
+ DistributionPointName distributionPointName = distributionPoint.getDistributionPoint();
+ if (DistributionPointName.FULL_NAME != distributionPointName.getType()) {
+ continue;
+ }
+
+ GeneralNames generalNames = (GeneralNames) distributionPointName.getName();
+ GeneralName[] names = generalNames.getNames();
+ for (GeneralName name : names) {
+ if (name.getTagNo() != GeneralName.uniformResourceIdentifier) {
+ continue;
+ }
+
+ DERIA5String derStr = (DERIA5String) DERIA5String.getInstance((DERTaggedObject) name.toASN1Primitive(), false);
+ return derStr.getString();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param certificate
+ * the certificate from which we need the ExtensionValue
+ * @param oid
+ * the Object Identifier value for the extension.
+ * @return the extension value as an ASN1Primitive object
+ * @throws IOException
+ */
+ private static ASN1Primitive getExtensionValue(X509Certificate certificate, String oid) throws IOException {
+ byte[] bytes = certificate.getExtensionValue(oid);
+ if (bytes == null) {
+ return null;
+ }
+ ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes));
+ ASN1OctetString octs = (ASN1OctetString) aIn.readObject();
+ aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets()));
+ return aIn.readObject();
+ }
+
+ @Override
+ public void destroy() {
+ crlCache.cleanUp();
+ }
}
diff --git a/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/OCSPCertificateVerifier.java b/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/OCSPCertificateVerifier.java
index 8c844e021a6..3ea7e22f67c 100644
--- a/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/OCSPCertificateVerifier.java
+++ b/jans-auth-server/common/src/main/java/io/jans/as/common/cert/validation/OCSPCertificateVerifier.java
@@ -22,8 +22,8 @@
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x509.AccessDescription;
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.Extension;
@@ -60,188 +60,188 @@
*/
public class OCSPCertificateVerifier implements CertificateVerifier {
- private static final Logger log = LoggerFactory.getLogger(OCSPCertificateVerifier.class);
-
- public OCSPCertificateVerifier() {
- SecurityProviderUtility.installBCProvider(true);
- }
-
- /**
- * @param certificate
- * the certificate from which we need the ExtensionValue
- * @param oid
- * the Object Identifier value for the extension.
- * @return the extension value as an ASN1Primitive object
- * @throws IOException
- */
- private static ASN1Primitive getExtensionValue(X509Certificate certificate, String oid) throws IOException {
- byte[] bytes = certificate.getExtensionValue(oid);
- if (bytes == null) {
- return null;
- }
- ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes));
- ASN1OctetString octs = (ASN1OctetString) aIn.readObject();
- aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets()));
- return aIn.readObject();
- }
-
- @Override
- public ValidationStatus validate(X509Certificate certificate, List issuers, Date validationDate) {
-
- X509Certificate issuer = CertUtils.getIssuer(certificate, issuers);
- ValidationStatus status = new ValidationStatus(certificate, issuer, validationDate, ValidatorSourceType.OCSP, CertificateValidity.UNKNOWN);
-
- try {
- Principal subjectX500Principal = certificate.getSubjectX500Principal();
-
- String ocspUrl = getOCSPUrl(certificate);
- if (ocspUrl == null) {
- log.error("OCSP URL for '" + subjectX500Principal + "' is empty");
- return status;
- }
-
- log.debug("OCSP URL for '" + subjectX500Principal + "' is '" + ocspUrl + "'");
-
- DigestCalculator digestCalculator = new JcaDigestCalculatorProviderBuilder().build().get(CertificateID.HASH_SHA1);
- CertificateID certificateId = new CertificateID(digestCalculator, new JcaX509CertificateHolder(issuer), certificate.getSerialNumber());
-
- // Generate OCSP request
- OCSPReq ocspReq = generateOCSPRequest(certificateId);
-
- // Get OCSP response from server
- OCSPResp ocspResp = requestOCSPResponse(ocspUrl, ocspReq);
- if (ocspResp.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
- log.error("OCSP response is invalid!");
- status.setValidity(CertificateValidity.INVALID);
- return status;
- }
-
- boolean foundResponse = false;
- BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResp.getResponseObject();
- SingleResp[] singleResps = basicOCSPResp.getResponses();
- for (SingleResp singleResp : singleResps) {
- CertificateID responseCertificateId = singleResp.getCertID();
- if (!certificateId.equals(responseCertificateId)) {
- continue;
- }
-
- foundResponse = true;
-
- log.debug("OCSP validationDate: " + validationDate);
- log.debug("OCSP thisUpdate: " + singleResp.getThisUpdate());
- log.debug("OCSP nextUpdate: " + singleResp.getNextUpdate());
-
- status.setRevocationObjectIssuingTime(basicOCSPResp.getProducedAt());
-
- Object certStatus = singleResp.getCertStatus();
- if (certStatus == CertificateStatus.GOOD) {
- log.debug("OCSP status is valid for '" + certificate.getSubjectX500Principal() + "'");
- status.setValidity(CertificateValidity.VALID);
- } else {
- if (singleResp.getCertStatus() instanceof RevokedStatus) {
- log.warn("OCSP status is revoked for: " + subjectX500Principal);
- if (validationDate.before(((RevokedStatus) singleResp.getCertStatus()).getRevocationTime())) {
- log.warn("OCSP revocation time after the validation date, the certificate '" + subjectX500Principal + "' was valid at " + validationDate);
- status.setValidity(CertificateValidity.VALID);
- } else {
- Date revocationDate = ((RevokedStatus) singleResp.getCertStatus()).getRevocationTime();
- log.info("OCSP for certificate '" + subjectX500Principal + "' is revoked since " + revocationDate);
- status.setRevocationDate(revocationDate);
- status.setRevocationObjectIssuingTime(singleResp.getThisUpdate());
- status.setValidity(CertificateValidity.REVOKED);
- }
- }
- }
- }
-
- if (!foundResponse) {
- log.error("There is no matching OCSP response entries");
- }
- } catch (Exception ex) {
- log.error("OCSP exception: ", ex);
- }
-
- return status;
- }
-
- private OCSPReq generateOCSPRequest(CertificateID certificateId) throws OCSPException, OperatorCreationException, CertificateEncodingException {
- OCSPReqBuilder ocspReqGenerator = new OCSPReqBuilder();
-
- ocspReqGenerator.addRequest(certificateId);
-
- OCSPReq ocspReq = ocspReqGenerator.build();
- return ocspReq;
- }
-
- @SuppressWarnings({ "deprecation", "resource" })
- private String getOCSPUrl(X509Certificate certificate) throws IOException {
- ASN1Primitive obj;
- try {
- obj = getExtensionValue(certificate, Extension.authorityInfoAccess.getId());
- } catch (IOException ex) {
- log.error("Failed to get OCSP URL", ex);
- return null;
- }
-
- if (obj == null) {
- return null;
- }
-
- AuthorityInformationAccess authorityInformationAccess = AuthorityInformationAccess.getInstance(obj);
-
- AccessDescription[] accessDescriptions = authorityInformationAccess.getAccessDescriptions();
- for (AccessDescription accessDescription : accessDescriptions) {
- boolean correctAccessMethod = accessDescription.getAccessMethod().equals((Object)X509ObjectIdentifiers.ocspAccessMethod);
- if (!correctAccessMethod) {
- continue;
- }
-
- GeneralName name = accessDescription.getAccessLocation();
- if (name.getTagNo() != GeneralName.uniformResourceIdentifier) {
- continue;
- }
-
- DERIA5String derStr = DERIA5String.getInstance((ASN1TaggedObject) name.toASN1Primitive(), false);
- return derStr.getString();
- }
-
- return null;
-
- }
-
- public OCSPResp requestOCSPResponse(String url, OCSPReq ocspReq) throws IOException, MalformedURLException {
- byte[] ocspReqData = ocspReq.getEncoded();
-
- HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
- try {
- con.setRequestProperty("Content-Type", "application/ocsp-request");
- con.setRequestProperty("Accept", "application/ocsp-response");
-
- con.setDoInput(true);
- con.setDoOutput(true);
- con.setUseCaches(false);
-
- OutputStream out = con.getOutputStream();
- try {
- IOUtils.write(ocspReqData, out);
- out.flush();
- } finally {
- IOUtils.closeQuietly(out);
- }
-
- byte[] responseBytes = IOUtils.toByteArray(con.getInputStream());
- OCSPResp ocspResp = new OCSPResp(responseBytes);
-
- return ocspResp;
- } finally {
- if (con != null) {
- con.disconnect();
- }
- }
- }
-
- @Override
- public void destroy() {
- }
+ private static final Logger log = LoggerFactory.getLogger(OCSPCertificateVerifier.class);
+
+ public OCSPCertificateVerifier() {
+ SecurityProviderUtility.installBCProvider(true);
+ }
+
+ @Override
+ public ValidationStatus validate(X509Certificate certificate, List issuers, Date validationDate) {
+
+ X509Certificate issuer = CertUtils.getIssuer(certificate, issuers);
+ ValidationStatus status = new ValidationStatus(certificate, issuer, validationDate, ValidatorSourceType.OCSP, CertificateValidity.UNKNOWN);
+
+ try {
+ Principal subjectX500Principal = certificate.getSubjectX500Principal();
+
+ String ocspUrl = getOCSPUrl(certificate);
+ if (ocspUrl == null) {
+ log.error("OCSP URL for '" + subjectX500Principal + "' is empty");
+ return status;
+ }
+
+ log.debug("OCSP URL for '" + subjectX500Principal + "' is '" + ocspUrl + "'");
+
+ DigestCalculator digestCalculator = new JcaDigestCalculatorProviderBuilder().build().get(CertificateID.HASH_SHA1);
+ CertificateID certificateId = new CertificateID(digestCalculator, new JcaX509CertificateHolder(issuer), certificate.getSerialNumber());
+
+ // Generate OCSP request
+ OCSPReq ocspReq = generateOCSPRequest(certificateId);
+
+ // Get OCSP response from server
+ OCSPResp ocspResp = requestOCSPResponse(ocspUrl, ocspReq);
+ if (ocspResp.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
+ log.error("OCSP response is invalid!");
+ status.setValidity(CertificateValidity.INVALID);
+ return status;
+ }
+
+ boolean foundResponse = false;
+ BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResp.getResponseObject();
+ SingleResp[] singleResps = basicOCSPResp.getResponses();
+ for (SingleResp singleResp : singleResps) {
+ CertificateID responseCertificateId = singleResp.getCertID();
+ if (!certificateId.equals(responseCertificateId)) {
+ continue;
+ }
+
+ foundResponse = true;
+
+ log.debug("OCSP validationDate: " + validationDate);
+ log.debug("OCSP thisUpdate: " + singleResp.getThisUpdate());
+ log.debug("OCSP nextUpdate: " + singleResp.getNextUpdate());
+
+ status.setRevocationObjectIssuingTime(basicOCSPResp.getProducedAt());
+
+ Object certStatus = singleResp.getCertStatus();
+ if (certStatus == CertificateStatus.GOOD) {
+ log.debug("OCSP status is valid for '" + certificate.getSubjectX500Principal() + "'");
+ status.setValidity(CertificateValidity.VALID);
+ } else {
+ if (singleResp.getCertStatus() instanceof RevokedStatus) {
+ log.warn("OCSP status is revoked for: " + subjectX500Principal);
+ if (validationDate.before(((RevokedStatus) singleResp.getCertStatus()).getRevocationTime())) {
+ log.warn("OCSP revocation time after the validation date, the certificate '" + subjectX500Principal + "' was valid at " + validationDate);
+ status.setValidity(CertificateValidity.VALID);
+ } else {
+ Date revocationDate = ((RevokedStatus) singleResp.getCertStatus()).getRevocationTime();
+ log.info("OCSP for certificate '" + subjectX500Principal + "' is revoked since " + revocationDate);
+ status.setRevocationDate(revocationDate);
+ status.setRevocationObjectIssuingTime(singleResp.getThisUpdate());
+ status.setValidity(CertificateValidity.REVOKED);
+ }
+ }
+ }
+ }
+
+ if (!foundResponse) {
+ log.error("There is no matching OCSP response entries");
+ }
+ } catch (Exception ex) {
+ log.error("OCSP exception: ", ex);
+ }
+
+ return status;
+ }
+
+ private OCSPReq generateOCSPRequest(CertificateID certificateId) throws OCSPException, OperatorCreationException, CertificateEncodingException {
+ OCSPReqBuilder ocspReqGenerator = new OCSPReqBuilder();
+
+ ocspReqGenerator.addRequest(certificateId);
+
+ OCSPReq ocspReq = ocspReqGenerator.build();
+ return ocspReq;
+ }
+
+ @SuppressWarnings({ "deprecation", "resource" })
+ private String getOCSPUrl(X509Certificate certificate) throws IOException {
+ ASN1Primitive obj;
+ try {
+ obj = getExtensionValue(certificate, Extension.authorityInfoAccess.getId());
+ } catch (IOException ex) {
+ log.error("Failed to get OCSP URL", ex);
+ return null;
+ }
+
+ if (obj == null) {
+ return null;
+ }
+
+ AuthorityInformationAccess authorityInformationAccess = AuthorityInformationAccess.getInstance(obj);
+
+ AccessDescription[] accessDescriptions = authorityInformationAccess.getAccessDescriptions();
+ for (AccessDescription accessDescription : accessDescriptions) {
+ boolean correctAccessMethod = accessDescription.getAccessMethod().equals((Object)X509ObjectIdentifiers.ocspAccessMethod);
+ if (!correctAccessMethod) {
+ continue;
+ }
+
+ GeneralName name = accessDescription.getAccessLocation();
+ if (name.getTagNo() != GeneralName.uniformResourceIdentifier) {
+ continue;
+ }
+
+ DERIA5String derStr = (DERIA5String) DERIA5String.getInstance((DERTaggedObject) name.toASN1Primitive(), false);
+ return derStr.getString();
+ }
+
+ return null;
+
+ }
+
+ public OCSPResp requestOCSPResponse(String url, OCSPReq ocspReq) throws IOException, MalformedURLException {
+ byte[] ocspReqData = ocspReq.getEncoded();
+
+ HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
+ try {
+ con.setRequestProperty("Content-Type", "application/ocsp-request");
+ con.setRequestProperty("Accept", "application/ocsp-response");
+
+ con.setDoInput(true);
+ con.setDoOutput(true);
+ con.setUseCaches(false);
+
+ OutputStream out = con.getOutputStream();
+ try {
+ IOUtils.write(ocspReqData, out);
+ out.flush();
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+
+ byte[] responseBytes = IOUtils.toByteArray(con.getInputStream());
+ OCSPResp ocspResp = new OCSPResp(responseBytes);
+
+ return ocspResp;
+ } finally {
+ if (con != null) {
+ con.disconnect();
+ }
+ }
+ }
+
+ /**
+ * @param certificate
+ * the certificate from which we need the ExtensionValue
+ * @param oid
+ * the Object Identifier value for the extension.
+ * @return the extension value as an ASN1Primitive object
+ * @throws IOException
+ */
+ private static ASN1Primitive getExtensionValue(X509Certificate certificate, String oid) throws IOException {
+ byte[] bytes = certificate.getExtensionValue(oid);
+ if (bytes == null) {
+ return null;
+ }
+ ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes));
+ ASN1OctetString octs = (ASN1OctetString) aIn.readObject();
+ aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets()));
+ return aIn.readObject();
+ }
+
+ @Override
+ public void destroy() {
+ }
}
diff --git a/jans-auth-server/model/pom.xml b/jans-auth-server/model/pom.xml
index f24aa5ca6b2..af7793f4263 100644
--- a/jans-auth-server/model/pom.xml
+++ b/jans-auth-server/model/pom.xml
@@ -140,12 +140,12 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
provided
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on
provided
diff --git a/jans-auth-server/server-fips/pom.xml b/jans-auth-server/server-fips/pom.xml
index 3c4426db36f..df696e38163 100644
--- a/jans-auth-server/server-fips/pom.xml
+++ b/jans-auth-server/server-fips/pom.xml
@@ -87,10 +87,10 @@
- WEB-INF/lib/bcpkix-jdk15on-*.jar,
- WEB-INF/lib/bcprov-jdk15on-*.jar,
- WEB-INF/lib/bcutil-jdk15on-*.jar,
- WEB-INF/lib/bcmail-jdk15on-*.jar
+ WEB-INF/lib/bcpkix-jdk18on-*.jar,
+ WEB-INF/lib/bcprov-jdk18on-*.jar,
+ WEB-INF/lib/bcutil-jdk18on-*.jar,
+ WEB-INF/lib/bcmail-jdk18on-*.jar
diff --git a/jans-auth-server/server/pom.xml b/jans-auth-server/server/pom.xml
index 71bdaa01ab3..2ca1612627f 100644
--- a/jans-auth-server/server/pom.xml
+++ b/jans-auth-server/server/pom.xml
@@ -459,11 +459,11 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on
diff --git a/jans-auth-server/test-model/pom.xml b/jans-auth-server/test-model/pom.xml
index 9cf702066f4..d485a74ddc7 100644
--- a/jans-auth-server/test-model/pom.xml
+++ b/jans-auth-server/test-model/pom.xml
@@ -123,12 +123,12 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
provided
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on
provided
diff --git a/jans-bom/pom.xml b/jans-bom/pom.xml
index c455cb26130..690a888d8fb 100644
--- a/jans-bom/pom.xml
+++ b/jans-bom/pom.xml
@@ -56,7 +56,7 @@
1.12.448
2.21.13
- 1.70
+ 1.78
5.9.2
5.1.1
@@ -276,17 +276,17 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
${bc.version}
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on
${bc.version}
org.bouncycastle
- bcmail-jdk15on
+ bcmail-jdk18on
${bc.version}
diff --git a/jans-casa/app/pom.xml b/jans-casa/app/pom.xml
index 2876a98870e..777467b6fd0 100644
--- a/jans-casa/app/pom.xml
+++ b/jans-casa/app/pom.xml
@@ -337,10 +337,10 @@
- WEB-INF/lib/bcpkix-jdk15on-*.jar,
- WEB-INF/lib/bcprov-jdk15on-*.jar,
- WEB-INF/lib/bcutil-jdk15on-*.jar,
- WEB-INF/lib/bcmail-jdk15on-*.jar
+ WEB-INF/lib/bcpkix-jdk18on-*.jar,
+ WEB-INF/lib/bcprov-jdk18on-*.jar,
+ WEB-INF/lib/bcutil-jdk18on-*.jar,
+ WEB-INF/lib/bcmail-jdk18on-*.jar
diff --git a/jans-config-api/server-fips/pom.xml b/jans-config-api/server-fips/pom.xml
index b498b368962..bebc4b2c4c0 100644
--- a/jans-config-api/server-fips/pom.xml
+++ b/jans-config-api/server-fips/pom.xml
@@ -87,10 +87,10 @@
- WEB-INF/lib/bcpkix-jdk15on-*.jar,
- WEB-INF/lib/bcprov-jdk15on-*.jar,
- WEB-INF/lib/bcutil-jdk15on-*.jar,
- WEB-INF/lib/bcmail-jdk15on-*.jar
+ WEB-INF/lib/bcpkix-jdk18on-*.jar,
+ WEB-INF/lib/bcprov-jdk18on-*.jar,
+ WEB-INF/lib/bcutil-jdk18on-*.jar,
+ WEB-INF/lib/bcmail-jdk18on-*.jar
diff --git a/jans-core/service/pom.xml b/jans-core/service/pom.xml
index afb0ee51e4e..49ae4dbcd11 100644
--- a/jans-core/service/pom.xml
+++ b/jans-core/service/pom.xml
@@ -183,15 +183,15 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on
org.bouncycastle
- bcmail-jdk15on
+ bcmail-jdk18on
diff --git a/jans-fido2/client/pom.xml b/jans-fido2/client/pom.xml
index 4547bd27ea8..768a22a0006 100644
--- a/jans-fido2/client/pom.xml
+++ b/jans-fido2/client/pom.xml
@@ -93,7 +93,7 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
diff --git a/jans-fido2/server-fips/pom.xml b/jans-fido2/server-fips/pom.xml
index e11b450ce47..641466efab9 100644
--- a/jans-fido2/server-fips/pom.xml
+++ b/jans-fido2/server-fips/pom.xml
@@ -87,10 +87,10 @@
- WEB-INF/lib/bcpkix-jdk15on-*.jar,
- WEB-INF/lib/bcprov-jdk15on-*.jar,
- WEB-INF/lib/bcutil-jdk15on-*.jar,
- WEB-INF/lib/bcmail-jdk15on-*.jar
+ WEB-INF/lib/bcpkix-jdk18on-*.jar,
+ WEB-INF/lib/bcprov-jdk18on-*.jar,
+ WEB-INF/lib/bcutil-jdk18on-*.jar,
+ WEB-INF/lib/bcmail-jdk18on-*.jar
diff --git a/jans-link/server-fips/pom.xml b/jans-link/server-fips/pom.xml
index 0c06d802cb7..4f96ae35af4 100644
--- a/jans-link/server-fips/pom.xml
+++ b/jans-link/server-fips/pom.xml
@@ -87,10 +87,10 @@
- WEB-INF/lib/bcpkix-jdk15on-*.jar,
- WEB-INF/lib/bcprov-jdk15on-*.jar,
- WEB-INF/lib/bcutil-jdk15on-*.jar,
- WEB-INF/lib/bcmail-jdk15on-*.jar
+ WEB-INF/lib/bcpkix-jdk18on-*.jar,
+ WEB-INF/lib/bcprov-jdk18on-*.jar,
+ WEB-INF/lib/bcutil-jdk18on-*.jar,
+ WEB-INF/lib/bcmail-jdk18on-*.jar
diff --git a/jans-lock/server-fips/pom.xml b/jans-lock/server-fips/pom.xml
index 8a6a600fb6d..b816f911caf 100644
--- a/jans-lock/server-fips/pom.xml
+++ b/jans-lock/server-fips/pom.xml
@@ -87,10 +87,10 @@
- WEB-INF/lib/bcpkix-jdk15on-*.jar,
- WEB-INF/lib/bcprov-jdk15on-*.jar,
- WEB-INF/lib/bcutil-jdk15on-*.jar,
- WEB-INF/lib/bcmail-jdk15on-*.jar
+ WEB-INF/lib/bcpkix-jdk18on-*.jar,
+ WEB-INF/lib/bcprov-jdk18on-*.jar,
+ WEB-INF/lib/bcutil-jdk18on-*.jar,
+ WEB-INF/lib/bcmail-jdk18on-*.jar
diff --git a/jans-scim/client/pom.xml b/jans-scim/client/pom.xml
index 4c00658912d..b6c7cca945c 100644
--- a/jans-scim/client/pom.xml
+++ b/jans-scim/client/pom.xml
@@ -77,7 +77,7 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
diff --git a/jans-scim/server-fips/pom.xml b/jans-scim/server-fips/pom.xml
index 51b0d996af2..357baafc56f 100644
--- a/jans-scim/server-fips/pom.xml
+++ b/jans-scim/server-fips/pom.xml
@@ -87,10 +87,10 @@
- WEB-INF/lib/bcpkix-jdk15on-*.jar,
- WEB-INF/lib/bcprov-jdk15on-*.jar,
- WEB-INF/lib/bcutil-jdk15on-*.jar,
- WEB-INF/lib/bcmail-jdk15on-*.jar
+ WEB-INF/lib/bcpkix-jdk18on-*.jar,
+ WEB-INF/lib/bcprov-jdk18on-*.jar,
+ WEB-INF/lib/bcutil-jdk18on-*.jar,
+ WEB-INF/lib/bcmail-jdk18on-*.jar
diff --git a/jans-scim/server/pom.xml b/jans-scim/server/pom.xml
index a55553f873c..225f7e2211d 100644
--- a/jans-scim/server/pom.xml
+++ b/jans-scim/server/pom.xml
@@ -117,11 +117,11 @@
org.bouncycastle
- bcprov-jdk15on
+ bcprov-jdk18on
org.bouncycastle
- bcpkix-jdk15on
+ bcpkix-jdk18on