gt:             ais = new ASN1InputStream(dos.getOctets());
context: /*
   * Copyright 2007-2014 Anestis Georgiadis
   *  
   * Licensed 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 net.sf.dsig.verify;
  
  import org.apache.commons.httpclient.*;
  import org.apache.commons.httpclient.methods.GetMethod;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.bouncycastle.asn1.ASN1InputStream;
  import org.bouncycastle.asn1.DEROctetString;
  import org.bouncycastle.asn1.DERSequence;
  import org.bouncycastle.asn1.DERString;
  import org.bouncycastle.asn1.x509.*;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.security.cert.*;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.Map;
  
  /**
   * A helper class that encapsulates CRL checking logic
   * 
   * @author <a href="mailto:mranest@iname.com">Anestis Georgiadis</a>
   */
  public class X509CRLHelper {
  
      private static final String OID_CRLDISTRIBUTIONPOINTS = "2.5.29.31";
      
      private static final Log logger = LogFactory.getLog(X509CRLHelper.class);
      
      /** A map from URI to LastModified String, for use in cached CRL lists */
      Map uriNextUpdateMap = new HashMap();
      
      /** A map from URI to CRL list */
      Map uriX509CrlMap = new HashMap();
      
      // Two previous maps are package-scoped, in order to facilitate unit tests
      
      private String proxyHost;
      
      public void setProxyHost(String proxyHost) {
          this.proxyHost = proxyHost;
      }
      
      private int proxyPort = -1;
      
      public void setProxyPort(int proxyPort) {
          this.proxyPort = proxyPort;
      }
      
      private String defaultCrlDistributionPoint = null;;
      
      public void setDefaultCrlDistributionPoint(String defaultCrlDistributionPoint) {
          this.defaultCrlDistributionPoint = defaultCrlDistributionPoint;
      }
      
      private HostConfiguration getHostConfiguration() {
          HostConfiguration config = new HostConfiguration();
          
          if (proxyHost != null && proxyPort != -1) {
              logger.debug("Setting proxy" + 
                      "; proxyHost=" + proxyHost +
                      "; proxyPort=" + proxyPort);
              config.setProxy(proxyHost, proxyPort);
          }
          
          return config;
      }
  
      /**
       * Validate a certificate using the CRL
       * 
       * @param certificate an {@link X509Certificate} object
       * @return true if the certificate is valid; false otherwise
       * @throws NetworkAccessException when any network access issues occur
       * @throws VerificationException when an error occurs while parsing the CRL
       */
      public boolean isValid(X509Certificate certificate) 
      throws NetworkAccessException, VerificationException {
          
          // First try finding the CRL distribution point in the X.509 certificate
          String uriAsString = X509CRLHelper.getCRLDistributionPointUri(certificate);
          
          // If not found, try falling back to the default
          if (uriAsString == null) {
              uriAsString = defaultCrlDistributionPoint;
          }
          
          // If still null, bail out
          if (uriAsString == null) {
              throw new ConfigurationException("CRL DistributionPoint not found on certificate, and no default set");
          }
          
          return !getX509CRL(uriAsString).isRevoked(certificate);
      }
      
      // default timeout: 5sec
      private int timeoutMillis = 5*1000;
  
      public void setTimeoutMillis(int timeoutMillis) {
          this.timeoutMillis = timeoutMillis;
      }
  
      // default connection timeout: 5sec
      private int connectionManagerTimeoutMillis = 5*1000;
  
      public void setConnectionManagerTimeoutMillis(int connectionManagerTimeoutMillis) {
          this.connectionManagerTimeoutMillis = connectionManagerTimeoutMillis;
      }
  
      private HttpConnectionManager getConnectionManager() {
          MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
          connectionManager.getParams().setSoTimeout(timeoutMillis);
          connectionManager.getParams().setConnectionTimeout(timeoutMillis);
  
          return connectionManager;
      }
  
      private HttpClient httpClient;
  
      private HttpClient getHttpClient() {
          if (httpClient == null) {
              httpClient = new HttpClient(getConnectionManager());
              httpClient.getParams().setConnectionManagerTimeout(connectionManagerTimeoutMillis);
          }
  
          return httpClient;
      }
  
      private Object mutex = new Object();
  
      /**
       * Retrieve the CRL
       * 
       * @param distributionPointUriAsString the distribution point URI
       * @return the {@link X509CRL} object
       * @throws NetworkAccessException when any network access issues occur
       * @throws VerificationException when an error occurs while parsing the CRL
       */
      public X509CRL getX509CRL(String distributionPointUriAsString) 
      throws NetworkAccessException, VerificationException {
          synchronized (mutex) {
              Date nextUpdate = (Date) uriNextUpdateMap.get(distributionPointUriAsString);
              if (    nextUpdate != null &&
                      nextUpdate.after(new Date())) {
                  logger.debug("Returning cached X509CRL" +
                          "; distributionPoint=" + distributionPointUriAsString +
                          ", nextUpdate=" + nextUpdate);
                  return (X509CRL) uriX509CrlMap.get(distributionPointUriAsString);
              }
  
              HostConfiguration config = getHostConfiguration();
              
              GetMethod get = new GetMethod(distributionPointUriAsString);
              try {
                  getHttpClient().executeMethod(config, get);
                  
                  logger.debug("HTTP GET executed" + 
                          "; distributionPointUri=" + distributionPointUriAsString +
                          ", statusLine=" + get.getStatusLine());
                          
                  if (get.getStatusCode() != HttpStatus.SC_OK) {
                      throw new NetworkAccessException("HTTP GET failed; statusLine=" + get.getStatusLine());
                  }
                  
                  
                  X509CRL crl = null;
                  byte[] responseBodyBytes = get.getResponseBody();
                  try {
                      crl = (X509CRL) CertificateFactory.getInstance("X.509").generateCRL(
                              new ByteArrayInputStream(responseBodyBytes));
                  } catch (CertificateException e) {
                      throw new ConfigurationException("X.509 certificate factory missing");
                  }
                  
                  uriNextUpdateMap.put(
                          distributionPointUriAsString, 
                          crl.getNextUpdate());
                  uriX509CrlMap.put(
                          distributionPointUriAsString, 
                          crl);
                  
                  return crl;
              } catch (IOException e) {
                  throw new NetworkAccessException("I/O error occured", e);
              } catch (CRLException e) {
                  throw new VerificationException("Error while following CRL protocol", e);
              } finally {
                  get.releaseConnection();
              }
          }
      }
      
      /**
       * Retrieve the CRL URI distribution point from an X.509 certificate, using
       * the 2.5.29.31 extension value
       * 
       * @param certificate an {@link X509Certificate} object
       * @return a String containing the URI of the CRL distribution point, or
       * null if none can be found
       */
      public static String getCRLDistributionPointUri(X509Certificate certificate) {
          byte[] derCdpBytes = certificate.getExtensionValue(OID_CRLDISTRIBUTIONPOINTS);
  
          if (derCdpBytes == null) {
              return null;
          }
          
          try {
              ASN1InputStream ais = new ASN1InputStream(derCdpBytes);
              DEROctetString dos = (DEROctetString) ais.readObject();
              ais.close();
              
  