Skip to content

Commit

Permalink
Add expiry validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Akila94 committed Jan 3, 2024
1 parent df9913b commit 86bf9da
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Enumeration;
Expand All @@ -45,14 +47,14 @@
* Manager class responsible for verifying certificates. This class will use the available verifiers according to
* a predefined policy.
*/
public class RevocationVerificationManager {
public class CertificateVerificationManager {

private int cacheSize = Constants.CACHE_DEFAULT_ALLOCATED_SIZE;
private int cacheDelayMins = Constants.CACHE_DEFAULT_DELAY_MINS;
private boolean isFullCertChainValidationEnabled = false;
private static final Log log = LogFactory.getLog(RevocationVerificationManager.class);
private static final Log log = LogFactory.getLog(CertificateVerificationManager.class);

public RevocationVerificationManager(Integer cacheAllocatedSize, Integer cacheDelayMins) {
public CertificateVerificationManager(Integer cacheAllocatedSize, Integer cacheDelayMins) {

if (cacheAllocatedSize != null && cacheAllocatedSize > Constants.CACHE_MIN_ALLOCATED_SIZE
&& cacheAllocatedSize < Constants.CACHE_MAX_ALLOCATED_SIZE) {
Expand All @@ -64,8 +66,8 @@ public RevocationVerificationManager(Integer cacheAllocatedSize, Integer cacheDe
}
}

public RevocationVerificationManager(Integer cacheAllocatedSize, Integer cacheDelayMins,
boolean isFullCertChainValidationEnabled) {
public CertificateVerificationManager(Integer cacheAllocatedSize, Integer cacheDelayMins,
boolean isFullCertChainValidationEnabled) {

if (cacheAllocatedSize != null && cacheAllocatedSize > Constants.CACHE_MIN_ALLOCATED_SIZE
&& cacheAllocatedSize < Constants.CACHE_MAX_ALLOCATED_SIZE) {
Expand Down Expand Up @@ -157,11 +159,8 @@ public void verifyRevocationStatus(javax.security.cert.X509Certificate[] peerCer
}
break;
} catch (SignatureException | CertificateException | NoSuchAlgorithmException |
InvalidKeyException |
NoSuchProviderException e) {
InvalidKeyException | NoSuchProviderException e) {
// Unable to verify the signature. Check with the next certificate.
//todo: change this to a debug log after testing.
log.error("Unable to verify the signature, checking with the next certificate...");
}
}
} else {
Expand All @@ -171,8 +170,8 @@ public void verifyRevocationStatus(javax.security.cert.X509Certificate[] peerCer
} catch (SignatureException | CertificateException | NoSuchAlgorithmException |
InvalidKeyException |
NoSuchProviderException e) {
// Unable to verify the signature. Check with the next certificate.
log.error("Signature not matching for alias validate with next cert");
// Unable to verify the signature.
throw new CertificateVerificationException("Unable to verify the signature of the certificate.");
}
}
}
Expand Down Expand Up @@ -238,4 +237,29 @@ private X509Certificate[] convert(javax.security.cert.X509Certificate[] certs)
}
return certChain;
}

/**
* Checks whether a provided certificate is expired or not at the time it is validated.
*
* @param certificates
* @throws CertificateNotYetValidException
* @throws CertificateExpiredException
* @throws CertificateVerificationException
*/
public void isExpired(javax.security.cert.X509Certificate[] certificates) throws CertificateVerificationException {

X509Certificate[] convertedCertificates = convert(certificates);

for (X509Certificate cert : convertedCertificates) {
try {
cert.checkValidity();
} catch (CertificateExpiredException e) {
String msg = "Peer certificate is expired";
throw new CertificateVerificationException(msg);
} catch (CertificateNotYetValidException e) {
String msg = "Peer certificate is not valid yet";
throw new CertificateVerificationException(msg);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.apache.http.nio.reactor.IOSession;
import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationException;
import org.apache.synapse.transport.certificatevalidation.RevocationVerificationManager;
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationManager;

public class ClientSSLSetupHandler implements SSLSetupHandler {

Expand Down Expand Up @@ -139,10 +139,10 @@ public void verify(
};

private final X509HostnameVerifier hostnameVerifier;
private final RevocationVerificationManager verificationManager;
private final CertificateVerificationManager verificationManager;

public ClientSSLSetupHandler(final X509HostnameVerifier hostnameVerifier,
final RevocationVerificationManager verificationManager) {
final CertificateVerificationManager verificationManager) {
this.hostnameVerifier = hostnameVerifier != null ? hostnameVerifier : DEFAULT;
this.verificationManager = verificationManager;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,32 @@
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.security.cert.X509Certificate;

import org.apache.http.nio.reactor.IOSession;
import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationException;
import org.apache.synapse.transport.certificatevalidation.RevocationVerificationManager;
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationManager;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.util.Arrays;
import java.util.List;

public class ServerSSLSetupHandler implements SSLSetupHandler {

private final SSLClientAuth clientAuth;
/** Enabled SSL handshake protocols (e.g. SSLv3, TLSv1) */
private final String[] httpsProtocols;
private RevocationVerificationManager verificationManager;
private CertificateVerificationManager verificationManager;
/** Ciphers enabled in axis2.xml, enabled all if null*/
private final String[] preferredCiphers;

public ServerSSLSetupHandler(final SSLClientAuth clientAuth, final String[] httpsProtocols,
final RevocationVerificationManager verificationManager, final String[] preferredCiphers) {
final CertificateVerificationManager verificationManager, final String[] preferredCiphers) {
this.clientAuth = clientAuth;
this.httpsProtocols = httpsProtocols;
this.verificationManager = verificationManager;
Expand Down Expand Up @@ -78,7 +83,9 @@ public void verify(

if (verificationManager != null) {
try {
verificationManager.verifyRevocationStatus(sslsession.getPeerCertificateChain());
X509Certificate[] peerCertChain = sslsession.getPeerCertificateChain();
verificationManager.isExpired(peerCertChain);
verificationManager.verifyRevocationStatus(peerCertChain);
} catch (CertificateVerificationException e) {
SocketAddress remoteAddress = iosession.getRemoteAddress();
String address;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.params.HttpParams;
import org.apache.synapse.transport.certificatevalidation.RevocationVerificationManager;
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationManager;
import org.apache.synapse.transport.exceptions.InvalidConfigurationException;
import org.apache.synapse.transport.http.conn.ClientConnFactory;
import org.apache.synapse.transport.http.conn.ClientSSLSetupHandler;
Expand Down Expand Up @@ -129,7 +129,7 @@ public ClientConnFactoryBuilder parseSSL() throws AxisFault {
final Parameter cvp = transportOut.getParameter("CertificateRevocationVerifier");
final String cvEnable = cvp != null ?
cvp.getParameterElement().getAttribute(new QName("enable")).getAttributeValue() : null;
RevocationVerificationManager revocationVerifier = null;
CertificateVerificationManager revocationVerifier = null;

if ("true".equalsIgnoreCase(cvEnable)) {
String cacheSizeString = cvp.getParameterElement().getFirstChildWithName(new QName("CacheSize")).getText();
Expand All @@ -142,7 +142,7 @@ public ClientConnFactoryBuilder parseSSL() throws AxisFault {
cacheDelay = new Integer(cacheDelayString);
} catch (NumberFormatException e) {
}
revocationVerifier = new RevocationVerificationManager(cacheSize, cacheDelay);
revocationVerifier = new CertificateVerificationManager(cacheSize, cacheDelay);
}

// Process HttpProtocols
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHost;
import org.apache.http.params.HttpParams;
import org.apache.synapse.transport.certificatevalidation.RevocationVerificationManager;
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationManager;
import org.apache.synapse.transport.http.conn.SSLClientAuth;
import org.apache.synapse.transport.http.conn.SSLContextDetails;
import org.apache.synapse.transport.http.conn.ServerConnFactory;
Expand Down Expand Up @@ -73,6 +73,7 @@ public class ServerConnFactoryBuilder {
protected SSLContextDetails ssl;
private Map<InetSocketAddress, SSLContextDetails> sslByIPMap = null;
private ConfigurationContext configurationContext;
CertificateVerificationManager certificateVerifier = null;

public ServerConnFactoryBuilder(final TransportInDescription transportIn, final HttpHost host,
ConfigurationContext configurationContext) {
Expand All @@ -94,7 +95,7 @@ protected SSLContextDetails createSSLContext(
final OMElement cientAuthEl,
final OMElement httpsProtocolsEl,
final OMElement preferredCiphersEl,
final RevocationVerificationManager verificationManager,
final CertificateVerificationManager verificationManager,
final String sslProtocol) throws AxisFault {

SecretResolver secretResolver;
Expand All @@ -114,7 +115,7 @@ protected SSLContextDetails createSSLContext(
final OMElement cientAuthEl,
final OMElement httpsProtocolsEl,
final OMElement preferredCiphersEl,
final RevocationVerificationManager verificationManager,
final CertificateVerificationManager verificationManager,
final String sslProtocol, final SecretResolver secretResolver) throws AxisFault {

KeyManager[] keymanagers = null;
Expand Down Expand Up @@ -307,7 +308,6 @@ public ServerConnFactoryBuilder parseSSL() throws AxisFault {
final Parameter cvp = transportIn.getParameter("CertificateRevocationVerifier");
final String cvEnable = cvp != null ?
cvp.getParameterElement().getAttribute(new QName("enable")).getAttributeValue() : null;
RevocationVerificationManager revocationVerifier = null;

if ("true".equalsIgnoreCase(cvEnable)) {
String cacheSizeString = cvp.getParameterElement().getFirstChildWithName(new QName("CacheSize")).getText();
Expand All @@ -332,12 +332,12 @@ public ServerConnFactoryBuilder parseSSL() throws AxisFault {
isFullCertChainValidationEnabled = false;
}

revocationVerifier = new RevocationVerificationManager(cacheSize, cacheDelay,
certificateVerifier = new CertificateVerificationManager(cacheSize, cacheDelay,
isFullCertChainValidationEnabled);
}

ssl = createSSLContext(keyStoreEl, trustStoreEl, clientAuthEl, httpsProtocolsEl, preferredCiphersEl,
revocationVerifier, sslProtocol);
certificateVerifier, sslProtocol);
return this;
}

Expand All @@ -351,7 +351,6 @@ public ServerConnFactoryBuilder parseMultiProfileSSL() throws AxisFault {
OMElement profilesEl = profileParam.getParameterElement();
SecretResolver secretResolver = SecretResolverFactory.create(profilesEl, true);
Iterator<?> profiles = profilesEl.getChildrenWithName(new QName("profile"));
RevocationVerificationManager revocationVerifier = null;

while (profiles.hasNext()) {
OMElement profileEl = (OMElement) profiles.next();
Expand Down Expand Up @@ -406,12 +405,12 @@ public ServerConnFactoryBuilder parseMultiProfileSSL() throws AxisFault {
isFullCertChainValidationEnabled = false;
}

revocationVerifier = new RevocationVerificationManager(cacheSize, cacheDelay,
certificateVerifier = new CertificateVerificationManager(cacheSize, cacheDelay,
isFullCertChainValidationEnabled);
}

SSLContextDetails ssl = createSSLContext(keyStoreEl, trustStoreEl, clientAuthEl, httpsProtocolsEl,
preferredCiphersEl, revocationVerifier, sslProtocol, secretResolver);
preferredCiphersEl, certificateVerifier, sslProtocol, secretResolver);
if (sslByIPMap == null) {
sslByIPMap = new HashMap<InetSocketAddress, SSLContextDetails>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@

import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.TransportInDescription;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHost;
import org.apache.synapse.transport.certificatevalidation.RevocationVerificationManager;
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationManager;
import org.apache.synapse.transport.nhttp.config.ServerConnFactoryBuilder;

import javax.xml.namespace.QName;
Expand All @@ -46,7 +45,7 @@ public ServerConnFactoryBuilder parseSSL(OMElement keyStoreEl, OMElement trustSt
AxisFault {
final String cvEnable = cvp != null ?
cvp.getAttribute(new QName("enable")).getAttributeValue() : null;
RevocationVerificationManager revocationVerifier = null;
CertificateVerificationManager revocationVerifier = null;

if ("true".equalsIgnoreCase(cvEnable)) {
Iterator iterator = cvp.getChildElements();
Expand All @@ -70,7 +69,7 @@ public ServerConnFactoryBuilder parseSSL(OMElement keyStoreEl, OMElement trustSt
} catch (NumberFormatException e) {
log.error("Please specify correct Integer numbers for CacheDelay and CacheSize");
}
revocationVerifier = new RevocationVerificationManager(cacheSize, cacheDelay, true);
revocationVerifier = new CertificateVerificationManager(cacheSize, cacheDelay);
}
ssl = createSSLContext(keyStoreEl, trustStoreEl, clientAuthEl, httpsProtocolsEl, preferredCiphers,
revocationVerifier,
Expand Down

0 comments on commit 86bf9da

Please sign in to comment.