You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by ve...@apache.org on 2022/06/02 16:42:28 UTC

[synapse] branch master updated: Remove usage of deprecated Bouncycastle OCSP APIs

This is an automated email from the ASF dual-hosted git repository.

veithen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/synapse.git


The following commit(s) were added to refs/heads/master by this push:
     new a6fc0caf4 Remove usage of deprecated Bouncycastle OCSP APIs
a6fc0caf4 is described below

commit a6fc0caf45a5d5528358ae9692cd65c5cfff4fb4
Author: Andreas Veithen <an...@gmail.com>
AuthorDate: Thu Jun 2 16:41:13 2022 +0000

    Remove usage of deprecated Bouncycastle OCSP APIs
---
 modules/transports/core/nhttp/pom.xml              |  4 ++
 .../transport/utils/sslcert/ocsp/OCSPCache.java    |  7 ++-
 .../transport/utils/sslcert/ocsp/OCSPVerifier.java | 47 +++++++++------
 .../transport/utils/sslcert/OCSPVerifierTest.java  | 67 ++++++++++++----------
 pom.xml                                            |  9 ++-
 5 files changed, 82 insertions(+), 52 deletions(-)

diff --git a/modules/transports/core/nhttp/pom.xml b/modules/transports/core/nhttp/pom.xml
index 16a2f4ea2..5a97277a9 100644
--- a/modules/transports/core/nhttp/pom.xml
+++ b/modules/transports/core/nhttp/pom.xml
@@ -164,6 +164,10 @@
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcprov-jdk15on</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk15on</artifactId>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPCache.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPCache.java
index 6cb7e957e..242571a08 100644
--- a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPCache.java
+++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPCache.java
@@ -27,7 +27,10 @@ import org.apache.synapse.transport.utils.sslcert.cache.CacheController;
 import org.apache.synapse.transport.utils.sslcert.cache.CacheManager;
 import org.apache.synapse.transport.utils.sslcert.cache.ManageableCache;
 import org.apache.synapse.transport.utils.sslcert.cache.ManageableCacheValue;
-import org.bouncycastle.ocsp.*;
+import org.bouncycastle.cert.ocsp.BasicOCSPResp;
+import org.bouncycastle.cert.ocsp.OCSPReq;
+import org.bouncycastle.cert.ocsp.OCSPResp;
+import org.bouncycastle.cert.ocsp.SingleResp;
 
 import java.math.BigInteger;
 import java.util.Date;
@@ -119,7 +122,7 @@ public class OCSPCache implements ManageableCache {
             OCSPReq request = cacheValue.request;
             OCSPResp response= ocspVerifier.getOCSPResponse(serviceUrl, request);
 
-            if (OCSPRespStatus.SUCCESSFUL != response.getStatus())
+            if (OCSPResp.SUCCESSFUL != response.getStatus())
                 throw new CertificateVerificationException("OCSP response status not SUCCESSFUL");
 
             BasicOCSPResp basicResponse = (BasicOCSPResp) response.getResponseObject();
diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPVerifier.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPVerifier.java
index 3aed3ba9b..de2434cef 100644
--- a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPVerifier.java
+++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/utils/sslcert/ocsp/OCSPVerifier.java
@@ -24,7 +24,20 @@ import org.apache.commons.logging.LogFactory;
 import org.bouncycastle.asn1.*;
 import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
 import org.bouncycastle.asn1.x509.*;
-import org.bouncycastle.ocsp.*;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.bouncycastle.cert.ocsp.BasicOCSPResp;
+import org.bouncycastle.cert.ocsp.CertificateID;
+import org.bouncycastle.cert.ocsp.CertificateStatus;
+import org.bouncycastle.cert.ocsp.OCSPException;
+import org.bouncycastle.cert.ocsp.OCSPReq;
+import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
+import org.bouncycastle.cert.ocsp.OCSPResp;
+import org.bouncycastle.cert.ocsp.RevokedStatus;
+import org.bouncycastle.cert.ocsp.SingleResp;
+import org.bouncycastle.cert.ocsp.UnknownStatus;
+import org.bouncycastle.operator.DigestCalculator;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
 import org.apache.synapse.transport.utils.sslcert.*;
 
 import java.io.*;
@@ -32,10 +45,10 @@ import java.math.BigInteger;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.security.Security;
+import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Vector;
 
 /**
  * Used to check if a Certificate is revoked or not by its CA using Online Certificate
@@ -83,7 +96,7 @@ public class OCSPVerifier implements RevocationVerifier {
             SingleResp[] responses;
             try {
                 OCSPResp ocspResponse = getOCSPResponse(serviceUrl, request);
-                if (OCSPRespStatus.SUCCESSFUL != ocspResponse.getStatus()) {
+                if (OCSPResp.SUCCESSFUL != ocspResponse.getStatus()) {
                     continue; // Server didn't give the response right.
                 }
 
@@ -106,12 +119,12 @@ public class OCSPVerifier implements RevocationVerifier {
     }
 
     private RevocationStatus getRevocationStatus(SingleResp resp) throws CertificateVerificationException {
-        Object status = resp.getCertStatus();
+        CertificateStatus status = resp.getCertStatus();
         if (status == CertificateStatus.GOOD) {
             return RevocationStatus.GOOD;
-        } else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) {
+        } else if (status instanceof RevokedStatus) {
             return RevocationStatus.REVOKED;
-        } else if (status instanceof org.bouncycastle.ocsp.UnknownStatus) {
+        } else if (status instanceof UnknownStatus) {
             return RevocationStatus.UNKNOWN;
         }
         throw new CertificateVerificationException("Cant recognize Certificate Status");
@@ -181,27 +194,23 @@ public class OCSPVerifier implements RevocationVerifier {
             //  CertID structure is used to uniquely identify certificates that are the subject of
             // an OCSP request or response and has an ASN.1 definition. CertID structure is defined
             // in RFC 2560
-            CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber);
+            DigestCalculator digestCalculator = new JcaDigestCalculatorProviderBuilder().build().get(CertificateID.HASH_SHA1);
+            CertificateID id = new CertificateID(digestCalculator, new JcaX509CertificateHolder(issuerCert), serialNumber);
 
             // basic request generation with nonce
-            OCSPReqGenerator generator = new OCSPReqGenerator();
-            generator.addRequest(id);
+            OCSPReqBuilder builder = new OCSPReqBuilder();
+            builder.addRequest(id);
 
             // create details for nonce extension. The nonce extension is used to bind
             // a request to a response to prevent replay attacks. As the name implies,
             // the nonce value is something that the client should only use once within a reasonably
             // small period.
             BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
-            Vector<ASN1ObjectIdentifier> objectIdentifiers = new Vector<ASN1ObjectIdentifier>();
-            Vector<X509Extension> values = new Vector<X509Extension>();
-
-            //to create the request Extension
-            objectIdentifiers.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
-            values.add(new X509Extension(false, new DEROctetString(nonce.toByteArray())));
-            generator.setRequestExtensions(new X509Extensions(objectIdentifiers, values));
-
-            return generator.generate();
-        } catch (OCSPException e) {
+            Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(new DEROctetString(nonce.toByteArray()).getEncoded()));
+            builder.setRequestExtensions(new Extensions(new Extension[]{ext}));
+        
+            return builder.build();
+        } catch (OCSPException | OperatorCreationException | CertificateEncodingException | IOException e) {
             throw new CertificateVerificationException("Cannot generate OCSP Request with the " +
                     "given certificate", e);
         }
diff --git a/modules/transports/core/nhttp/src/test/java/org/apache/synapse/transport/utils/sslcert/OCSPVerifierTest.java b/modules/transports/core/nhttp/src/test/java/org/apache/synapse/transport/utils/sslcert/OCSPVerifierTest.java
index 3577082e7..d66c0722e 100644
--- a/modules/transports/core/nhttp/src/test/java/org/apache/synapse/transport/utils/sslcert/OCSPVerifierTest.java
+++ b/modules/transports/core/nhttp/src/test/java/org/apache/synapse/transport/utils/sslcert/OCSPVerifierTest.java
@@ -21,12 +21,30 @@ package org.apache.synapse.transport.utils.sslcert;
 import junit.framework.TestCase;
 import org.apache.synapse.transport.utils.sslcert.ocsp.OCSPCache;
 import org.apache.synapse.transport.utils.sslcert.ocsp.OCSPVerifier;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
 import org.bouncycastle.asn1.x509.CRLReason;
-import org.bouncycastle.asn1.x509.X509Extension;
-import org.bouncycastle.asn1.x509.X509Extensions;
-import org.bouncycastle.ocsp.*;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.bouncycastle.cert.ocsp.BasicOCSPResp;
+import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.CertificateID;
+import org.bouncycastle.cert.ocsp.CertificateStatus;
+import org.bouncycastle.cert.ocsp.OCSPException;
+import org.bouncycastle.cert.ocsp.OCSPReq;
+import org.bouncycastle.cert.ocsp.OCSPResp;
+import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.Req;
+import org.bouncycastle.cert.ocsp.RevokedStatus;
+import org.bouncycastle.cert.ocsp.SingleResp;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.DigestCalculator;
+import org.bouncycastle.operator.DigestCalculatorProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
 import org.bouncycastle.x509.X509V3CertificateGenerator;
 
 import java.lang.reflect.Method;
@@ -71,7 +89,8 @@ public class OCSPVerifierTest extends TestCase {
         OCSPReq request = getOCSPRequest(caCert, revokedSerialNumber);
 
         //Create OCSP response saying that certificate with given serialNumber is revoked.
-        CertificateID revokedID = new CertificateID(CertificateID.HASH_SHA1, caCert,
+        DigestCalculator digestCalculator = new JcaDigestCalculatorProviderBuilder().build().get(CertificateID.HASH_SHA1);
+        CertificateID revokedID = new CertificateID(digestCalculator, new JcaX509CertificateHolder(caCert),
                 revokedSerialNumber);
         OCSPResp response = generateOCSPResponse(request, caKeyPair.getPrivate(),
                 caKeyPair.getPublic(), revokedID);
@@ -127,30 +146,20 @@ public class OCSPVerifierTest extends TestCase {
      * @return the created OCSP response by the fake CA.
      * @throws NoSuchProviderException
      * @throws OCSPException
+     * @throws OperatorCreationException
      */
     private OCSPResp generateOCSPResponse(OCSPReq request, PrivateKey caPrivateKey,
                                           PublicKey caPublicKey,
                                           CertificateID revokedID) throws
-            NoSuchProviderException, OCSPException {
-
-        BasicOCSPRespGenerator basicOCSPRespGenerator = new BasicOCSPRespGenerator(caPublicKey);
-        X509Extensions requestExtensions = request.getRequestExtensions();
-
-        if (requestExtensions != null) {
-
-            X509Extension extension = requestExtensions.getExtension(OCSPObjectIdentifiers
-                    .id_pkix_ocsp_nonce);
-
-            if (extension != null) {
-
-                Vector<ASN1ObjectIdentifier> oids = new Vector<ASN1ObjectIdentifier>();
-                Vector<X509Extension> values = new Vector<X509Extension>();
-
-                oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
-                values.add(extension);
-
-                basicOCSPRespGenerator.setResponseExtensions(new X509Extensions(oids, values));
-            }
+            NoSuchProviderException, OCSPException, OperatorCreationException {
+
+        JcaDigestCalculatorProviderBuilder digestCalculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder();
+        DigestCalculatorProvider digestCalculatorProvider = digestCalculatorProviderBuilder.build();
+        DigestCalculator digestCalculator = digestCalculatorProvider.get(CertificateID.HASH_SHA1);
+        BasicOCSPRespBuilder basicOCSPRespGenerator = new BasicOCSPRespBuilder(new SubjectPublicKeyInfo(CertificateID.HASH_SHA1, caPublicKey.getEncoded()), digestCalculator);
+        Extension extension = request.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
+        if (extension != null) {
+            basicOCSPRespGenerator.setResponseExtensions(new Extensions(new Extension[]{ extension }));
         }
 
         Req[] requests = request.getRequestList();
@@ -170,11 +179,11 @@ public class OCSPVerifierTest extends TestCase {
             }
         }
 
-        BasicOCSPResp basicResp = basicOCSPRespGenerator.generate("SHA256WithRSA", caPrivateKey,
-                null, new Date(), "BC");
-        OCSPRespGenerator respGen = new OCSPRespGenerator();
+        ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(caPrivateKey);
+        BasicOCSPResp basicResp = basicOCSPRespGenerator.build(contentSigner, null, new Date());
+        OCSPRespBuilder respBuilder = new OCSPRespBuilder();
 
-        return respGen.generate(OCSPRespGenerator.SUCCESSFUL, basicResp);
+        return respBuilder.build(OCSPRespBuilder.SUCCESSFUL, basicResp);
     }
 
     private X509Certificate generateFakePeerCert(BigInteger serialNumber, PublicKey entityKey,
diff --git a/pom.xml b/pom.xml
index f848d1a56..a2a4acad9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -756,7 +756,12 @@
             <dependency>
                 <groupId>org.bouncycastle</groupId>
                 <artifactId>bcprov-jdk15on</artifactId>
-                <version>${bcprov.nhttp.version}</version>
+                <version>${bouncycastle.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.bouncycastle</groupId>
+                <artifactId>bcpkix-jdk15on</artifactId>
+                <version>${bouncycastle.version}</version>
             </dependency>
 
             <!-- Testing -->
@@ -1140,7 +1145,7 @@
         <snmp4j.version>2.5.4</snmp4j.version>
         <snmp4j.agent.version>2.5.3</snmp4j.agent.version>
         <rabbitmq.version>3.1.2</rabbitmq.version>
-        <bcprov.nhttp.version>1.50</bcprov.nhttp.version>
+        <bouncycastle.version>1.50</bouncycastle.version>
 
         <!-- dependencies of Synapse extensions module -->
         <wso2commons.version>1.2</wso2commons.version>