| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.synapse.transport.utils.sslcert; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.synapse.transport.utils.sslcert.crl.CRLCache; |
| import org.apache.synapse.transport.utils.sslcert.crl.CRLVerifier; |
| import org.apache.synapse.transport.utils.sslcert.ocsp.OCSPCache; |
| import org.apache.synapse.transport.utils.sslcert.ocsp.OCSPVerifier; |
| import org.apache.synapse.transport.utils.sslcert.pathvalidation.CertificatePathValidator; |
| |
| import java.io.ByteArrayInputStream; |
| import java.security.cert.X509Certificate; |
| |
| /** |
| * Manager class responsible for verifying certificates. This class will use the available |
| * verifiers according to a predefined policy. |
| */ |
| public class RevocationVerificationManager { |
| |
| private int cacheSize = Constants.CACHE_DEFAULT_ALLOCATED_SIZE; |
| private int cacheDurationMins = Constants.CACHE_DEFAULT_DURATION_MINS; |
| private static final Log log = LogFactory.getLog(RevocationVerificationManager.class); |
| |
| public RevocationVerificationManager(Integer cacheAllocatedSize, Integer cacheDurationMins) { |
| |
| if (cacheAllocatedSize != null && cacheAllocatedSize > Constants.CACHE_MIN_ALLOCATED_SIZE |
| && cacheAllocatedSize < Constants.CACHE_MAX_ALLOCATED_SIZE) { |
| this.cacheSize = cacheAllocatedSize; |
| } |
| if (cacheDurationMins != null && cacheDurationMins > Constants.CACHE_MIN_DURATION_MINS |
| && cacheDurationMins < Constants.CACHE_MAX_DURATION_MINS) { |
| this.cacheDurationMins = cacheDurationMins; |
| } |
| } |
| |
| /** |
| * This method first tries to verify the given certificate chain using OCSP since OCSP |
| * verification is faster. If that fails it tries to do the verification using CRL. |
| * |
| * @param peerCertificates javax.security.cert.X509Certificate[] array of peer |
| * certificate chain from peer/client. |
| * @throws CertificateVerificationException |
| */ |
| public void verifyRevocationStatus(javax.security.cert.X509Certificate[] peerCertificates) |
| throws CertificateVerificationException { |
| |
| X509Certificate[] convertedCertificates = convert(peerCertificates); |
| |
| long start = System.currentTimeMillis(); |
| |
| OCSPCache ocspCache = OCSPCache.getCache(); |
| ocspCache.init(cacheSize, cacheDurationMins); |
| CRLCache crlCache = CRLCache.getCache(); |
| crlCache.init(cacheSize, cacheDurationMins); |
| |
| RevocationVerifier[] verifiers = {new OCSPVerifier(ocspCache), new CRLVerifier(crlCache)}; |
| |
| for (RevocationVerifier verifier : verifiers) { |
| try { |
| CertificatePathValidator pathValidator = new CertificatePathValidator( |
| convertedCertificates, verifier); |
| pathValidator.validatePath(); |
| log.info("Path verification Successful with " + verifier.getClass().getSimpleName() + |
| ". Took " + (System.currentTimeMillis() - start) + " ms."); |
| return; |
| } catch (Exception e) { |
| if (log.isDebugEnabled()) { |
| log.debug("Certificate verification with " + verifier.getClass().getSimpleName() + |
| " failed. ", e); |
| } |
| } |
| } |
| throw new CertificateVerificationException("Path Verification Failed for both OCSP and CRL"); |
| } |
| |
| /** |
| * @param certs array of javax.security.cert.X509Certificate[] s. |
| * @return the converted array of java.security.cert.X509Certificate[] s. |
| * @throws CertificateVerificationException |
| */ |
| private X509Certificate[] convert(javax.security.cert.X509Certificate[] certs) |
| throws CertificateVerificationException { |
| X509Certificate[] certChain = new X509Certificate[certs.length]; |
| Throwable exceptionThrown; |
| for (int i = 0; i < certs.length; i++) { |
| try { |
| byte[] encoded = certs[i].getEncoded(); |
| ByteArrayInputStream bis = new ByteArrayInputStream(encoded); |
| java.security.cert.CertificateFactory cf |
| = java.security.cert.CertificateFactory.getInstance("X.509"); |
| certChain[i]=((X509Certificate)cf.generateCertificate(bis)); |
| continue; |
| } catch (java.security.cert.CertificateEncodingException e) { |
| exceptionThrown = e; |
| } catch (javax.security.cert.CertificateEncodingException e) { |
| exceptionThrown = e; |
| } catch (java.security.cert.CertificateException e) { |
| exceptionThrown = e; |
| } |
| throw new CertificateVerificationException("Cant Convert certificates from " + |
| "javax to java", exceptionThrown); |
| } |
| return certChain; |
| } |
| } |