/* JarFile.java - Representation of a jar file
   Copyright (C) 2000, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util.jar;

import gnu.java.io.Base64InputStream;
import gnu.java.security.OID;
import gnu.java.security.pkcs.PKCS7SignedData;
import gnu.java.security.pkcs.SignerInfo;
import gnu.java.security.provider.Gnu;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CRLException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

/**
 * Representation of a jar file.
 * <p>
 * Note that this class is not a subclass of java.io.File but a subclass of
 * java.util.zip.ZipFile and you can only read JarFiles with it (although
 * there are constructors that take a File object).
 *
 * @since 1.2
 * @author Mark Wielaard (mark@klomp.org)
 * @author Casey Marshall (csm@gnu.org) wrote the certificate and entry
 *  verification code.
 */
public class JarFile extends ZipFile
{
  // Fields

  /** The name of the manifest entry: META-INF/MANIFEST.MF */
  public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";

  /** The META-INF directory entry. */
  private static final String META_INF = "META-INF/";

  /** The suffix for PKCS7 DSA signature entries. */
  private static final String PKCS7_DSA_SUFFIX = ".DSA";

  /** The suffix for PKCS7 RSA signature entries. */
  private static final String PKCS7_RSA_SUFFIX = ".RSA";

  /** The suffix for digest attributes. */
  private static final String DIGEST_KEY_SUFFIX = "-Digest";

  /** The suffix for signature files. */
  private static final String SF_SUFFIX = ".SF";

  /**
   * The security provider to use for signature verification.
   * We need a known fallback to be able to read any signed jar file
   * (which might contain the user selected security provider).
   * This is package-private to avoid accessor methods for inner classes.
   */
  static final Gnu provider = new Gnu();

  // Signature OIDs.
  private static final OID MD2_OID = new OID("1.2.840.113549.2.2");
  private static final OID MD4_OID = new OID("1.2.840.113549.2.4");
  private static final OID MD5_OID = new OID("1.2.840.113549.2.5");
  private static final OID SHA1_OID = new OID("1.3.14.3.2.26");
  private static final OID DSA_ENCRYPTION_OID = new OID("1.2.840.10040.4.1");
  private static final OID RSA_ENCRYPTION_OID = new OID("1.2.840.113549.1.1.1");

  /**
   * The manifest of this file, if any, otherwise null.
   * Read when first needed.
   */
  private Manifest manifest;

  /** Whether to verify the manifest and all entries. */
  boolean verify;

  /** Whether the has already been loaded. */
  private boolean manifestRead = false;

  /** Whether the signature files have been loaded. */
  boolean signaturesRead = false;

  /**
   * A map between entry names and booleans, signaling whether or
   * not that entry has been verified.
   * Only be accessed with lock on this JarFile*/
  HashMap verified = new HashMap();

  /**
   * A mapping from entry name to certificates, if any.
   * Only accessed with lock on this JarFile.
   */
  HashMap entryCerts;

  /**
   * A {@link Map} of message digest algorithm names to their implementation.
   * Used to reduce object (algorithm implementation) instantiation.
   */
  private HashMap digestAlgorithms = new HashMap();

  static boolean DEBUG = false;
  static void debug(Object msg)
  {
    System.err.print(JarFile.class.getName());
    System.err.print(" >>> ");
    System.err.println(msg);
  }

  // Constructors

  /**
   * Creates a new JarFile. All jar entries are verified (when a Manifest file
   * for this JarFile exists). You need to actually open and read the complete
   * jar entry (with <code>getInputStream()</code>) to check its signature.
   *
   * @param fileName the name of the file to open
   * @exception FileNotFoundException if the fileName cannot be found
   * @exception IOException if another IO exception occurs while reading
   */
  public JarFile(String fileName) throws FileNotFoundException, IOException
  {
    this(fileName, true);
  }

  /**
   * Creates a new JarFile. If verify is true then all jar entries are
   * verified (when a Manifest file for this JarFile exists). You need to
   * actually open and read the complete jar entry
   * (with <code>getInputStream()</code>) to check its signature.
   *
   * @param fileName the name of the file to open
   * @param verify checks manifest and entries when true and a manifest
   * exists, when false no checks are made
   * @exception FileNotFoundException if the fileName cannot be found
   * @exception IOException if another IO exception occurs while reading
   */
  public JarFile(String fileName, boolean verify) throws
    FileNotFoundException, IOException
  {
    super(fileName);
    if (verify)
      {
	manifest = readManifest();
	verify();
      }
  }

  /**
   * Creates a new JarFile. All jar entries are verified (when a Manifest file
   * for this JarFile exists). You need to actually open and read the complete
   * jar entry (with <code>getInputStream()</code>) to check its signature.
   *
   * @param file the file to open as a jar file
   * @exception FileNotFoundException if the file does not exits
   * @exception IOException if another IO exception occurs while reading
   */
  public JarFile(File file) throws FileNotFoundException, IOException
  {
    this(file, true);
  }

  /**
   * Creates a new JarFile. If verify is true then all jar entries are
   * verified (when a Manifest file for this JarFile exists). You need to
   * actually open and read the complete jar entry
   * (with <code>getInputStream()</code>) to check its signature.
   *
   * @param file the file to open to open as a jar file
   * @param verify checks manifest and entries when true and a manifest
   * exists, when false no checks are made
   * @exception FileNotFoundException if file does not exist
   * @exception IOException if another IO exception occurs while reading
   */
  public JarFile(File file, boolean verify) throws FileNotFoundException,
    IOException
  {
    super(file);
    if (verify)
      {
	manifest = readManifest();
	verify();
      }
  }

  /**
   * Creates a new JarFile with the indicated mode. If verify is true then
   * all jar entries are verified (when a Manifest file for this JarFile
   * exists). You need to actually open and read the complete jar entry
   * (with <code>getInputStream()</code>) to check its signature.
   * manifest and if the manifest exists and verify is true verfies it.
   *
   * @param file the file to open to open as a jar file
   * @param verify checks manifest and entries when true and a manifest
   * exists, when false no checks are made
   * @param mode either ZipFile.OPEN_READ or
   *             (ZipFile.OPEN_READ | ZipFile.OPEN_DELETE)
   * @exception FileNotFoundException if the file does not exist
   * @exception IOException if another IO exception occurs while reading
   * @exception IllegalArgumentException when given an illegal mode
   * 
   * @since 1.3
   */
  public JarFile(File file, boolean verify, int mode) throws
    FileNotFoundException, IOException, IllegalArgumentException
  {
    super(file, mode);
    if (verify)
      {
	manifest = readManifest();
	verify();
      }
  }

  // Methods

  /**
   * XXX - should verify the manifest file
   */
  private void verify()
  {
    // only check if manifest is not null
    if (manifest == null)
      {
	verify = false;
	return;
      }

    verify = true;
    // XXX - verify manifest
  }

  /**
   * Parses and returns the manifest if it exists, otherwise returns null.
   */
  private Manifest readManifest()
  {
    try
      {
	ZipEntry manEntry = super.getEntry(MANIFEST_NAME);
	if (manEntry != null)
	  {
	    InputStream in = super.getInputStream(manEntry);
	    manifestRead = true;
	    return new Manifest(in);
	  }
	else
	  {
	    manifestRead = true;
	    return null;
	  }
      }
    catch (IOException ioe)
      {
	manifestRead = true;
	return null;
      }
  }

  /**
   * Returns a enumeration of all the entries in the JarFile.
   * Note that also the Jar META-INF entries are returned.
   *
   * @exception IllegalStateException when the JarFile is already closed
   */
  public Enumeration<JarEntry> entries() throws IllegalStateException
  {
    return new JarEnumeration(super.entries(), this);
  }

  /**
   * Wraps a given Zip Entries Enumeration. For every zip entry a
   * JarEntry is created and the corresponding Attributes are looked up.
   */
  private static class JarEnumeration implements Enumeration<JarEntry>
  {

    private final Enumeration<? extends ZipEntry> entries;
    private final JarFile jarfile;

    JarEnumeration(Enumeration<? extends ZipEntry> e, JarFile f)
    {
      entries = e;
      jarfile = f;
    }

    public boolean hasMoreElements()
    {
      return entries.hasMoreElements();
    }

    public JarEntry nextElement()
    {
      ZipEntry zip = (ZipEntry) entries.nextElement();
      JarEntry jar = new JarEntry(zip);
      Manifest manifest;
      try
	{
	  manifest = jarfile.getManifest();
	}
      catch (IOException ioe)
	{
	  manifest = null;
	}

      if (manifest != null)
	{
	  jar.attr = manifest.getAttributes(jar.getName());
	}

      synchronized(jarfile)
	{
	  if (jarfile.verify && !jarfile.signaturesRead)
	    try
	      {
		jarfile.readSignatures();
	      }
	    catch (IOException ioe)
	      {
		if (JarFile.DEBUG)
		  {
		    JarFile.debug(ioe);
		    ioe.printStackTrace();
		  }
		jarfile.signaturesRead = true; // fudge it.
	      }
	}
      jar.jarfile = jarfile;
      return jar;
    }
  }

  /**
   * XXX
   * It actually returns a JarEntry not a zipEntry
   * @param name XXX
   */
  public synchronized ZipEntry getEntry(String name)
  {
    ZipEntry entry = super.getEntry(name);
    if (entry != null)
      {
	JarEntry jarEntry = new JarEntry(entry);
	Manifest manifest;
	try
	  {
	    manifest = getManifest();
	  }
	catch (IOException ioe)
	  {
	    manifest = null;
	  }

	if (manifest != null)
	  {
	    jarEntry.attr = manifest.getAttributes(name);
          }

	if (verify && !signaturesRead)
	  try
	    {
	      readSignatures();
	    }
	  catch (IOException ioe)
	    {
	      if (DEBUG)
		{
		  debug(ioe);
		  ioe.printStackTrace();
		}
	      signaturesRead = true;
	    }
        jarEntry.jarfile = this;
	return jarEntry;
      }
    return null;
  }

  /**
   * Returns an input stream for the given entry. If configured to
   * verify entries, the input stream returned will verify them while
   * the stream is read, but only on the first time.
   *
   * @param entry The entry to get the input stream for.
   * @exception ZipException XXX
   * @exception IOException XXX
   */
  public synchronized InputStream getInputStream(ZipEntry entry) throws
    ZipException, IOException
  {
    // If we haven't verified the hash, do it now.
    if (!verified.containsKey(entry.getName()) && verify)
      {
        if (DEBUG)
          debug("reading and verifying " + entry);
        return new EntryInputStream(entry, super.getInputStream(entry), this);
      }
    else
      {
        if (DEBUG)
          debug("reading already verified entry " + entry);
        if (verify && verified.get(entry.getName()) == Boolean.FALSE)
          throw new ZipException("digest for " + entry + " is invalid");
        return super.getInputStream(entry);
      }
  }

  /**
   * Returns the JarEntry that belongs to the name if such an entry
   * exists in the JarFile. Returns null otherwise
   * Convenience method that just casts the result from <code>getEntry</code>
   * to a JarEntry.
   *
   * @param name the jar entry name to look up
   * @return the JarEntry if it exists, null otherwise
   */
  public JarEntry getJarEntry(String name)
  {
    return (JarEntry) getEntry(name);
  }

  /**
   * Returns the manifest for this JarFile or null when the JarFile does not
   * contain a manifest file.
   */
  public synchronized Manifest getManifest() throws IOException
  {
    if (!manifestRead)
      manifest = readManifest();

    return manifest;
  }

  // Only called with lock on this JarFile.
  // Package private for use in inner classes.
  void readSignatures() throws IOException
  {
    Map pkcs7Dsa = new HashMap();
    Map pkcs7Rsa = new HashMap();
    Map sigFiles = new HashMap();

    // Phase 1: Read all signature files. These contain the user
    // certificates as well as the signatures themselves.
    for (Enumeration e = super.entries(); e.hasMoreElements(); )
      {
        ZipEntry ze = (ZipEntry) e.nextElement();
        String name = ze.getName();
        if (name.startsWith(META_INF))
          {
            String alias = name.substring(META_INF.length());
            if (alias.lastIndexOf('.') >= 0)
              alias = alias.substring(0, alias.lastIndexOf('.'));

            if (name.endsWith(PKCS7_DSA_SUFFIX) || name.endsWith(PKCS7_RSA_SUFFIX))
              {
                if (DEBUG)
                  debug("reading PKCS7 info from " + name + ", alias=" + alias);
                PKCS7SignedData sig = null;
                try
                  {
                    sig = new PKCS7SignedData(super.getInputStream(ze));
                  }
                catch (CertificateException ce)
                  {
                    IOException ioe = new IOException("certificate parsing error");
                    ioe.initCause(ce);
                    throw ioe;
                  }
                catch (CRLException crle)
                  {
                    IOException ioe = new IOException("CRL parsing error");
                    ioe.initCause(crle);
                    throw ioe;
                  }
                if (name.endsWith(PKCS7_DSA_SUFFIX))
                  pkcs7Dsa.put(alias, sig);
                else if (name.endsWith(PKCS7_RSA_SUFFIX))
                  pkcs7Rsa.put(alias, sig);
              }
            else if (name.endsWith(SF_SUFFIX))
              {
                if (DEBUG)
                  debug("reading signature file for " + alias + ": " + name);
                Manifest sf = new Manifest(super.getInputStream(ze));
                sigFiles.put(alias, sf);
                if (DEBUG)
                  debug("result: " + sf);
              }
          }
      }

    // Phase 2: verify the signatures on any signature files.
    Set validCerts = new HashSet();
    Map entryCerts = new HashMap();
    for (Iterator it = sigFiles.entrySet().iterator(); it.hasNext(); )
      {
        int valid = 0;
        Map.Entry e = (Map.Entry) it.next();
        String alias = (String) e.getKey();

        PKCS7SignedData sig = (PKCS7SignedData) pkcs7Dsa.get(alias);
        if (sig != null)
          {
            Certificate[] certs = sig.getCertificates();
            Set signerInfos = sig.getSignerInfos();
            for (Iterator it2 = signerInfos.iterator(); it2.hasNext(); )
              verify(certs, (SignerInfo) it2.next(), alias, validCerts);
          }

        sig = (PKCS7SignedData) pkcs7Rsa.get(alias);
        if (sig != null)
          {
            Certificate[] certs = sig.getCertificates();
            Set signerInfos = sig.getSignerInfos();
            for (Iterator it2 = signerInfos.iterator(); it2.hasNext(); )
              verify(certs, (SignerInfo) it2.next(), alias, validCerts);
          }

        // It isn't a signature for anything. Punt it.
        if (validCerts.isEmpty())
          {
            it.remove();
            continue;
          }

        entryCerts.put(e.getValue(), new HashSet(validCerts));
        validCerts.clear();
      }

    // Read the manifest into a HashMap (String fileName, String entry)
    // The fileName might be split into multiple lines in the manifest.
    // Such additional lines will start with a space.
    InputStream in = super.getInputStream(super.getEntry(MANIFEST_NAME));
    ByteArrayOutputStream baStream = new ByteArrayOutputStream();
    byte[] ba = new byte[1024];
    while (true)
      {
        int len = in.read(ba);
        if (len < 0)
          break;
        baStream.write(ba, 0, len);
      }
    in.close();

    HashMap hmManifestEntries = new HashMap();
    Pattern p = Pattern.compile("Name: (.+?\r?\n(?: .+?\r?\n)*)"
                                + ".+?-Digest: .+?\r?\n\r?\n");
    Matcher m = p.matcher(baStream.toString());
    while (m.find())
      {
        String fileName = m.group(1).replaceAll("\r?\n ?", "");
        hmManifestEntries.put(fileName, m.group());
      }

    // Phase 3: verify the signature file signatures against the manifest,
    // mapping the entry name to the target certificates.
    this.entryCerts = new HashMap();
    for (Iterator it = entryCerts.entrySet().iterator(); it.hasNext(); )
      {
        Map.Entry e = (Map.Entry) it.next();
        Manifest sigfile = (Manifest) e.getKey();
        Map entries = sigfile.getEntries();
        Set certificates = (Set) e.getValue();

        for (Iterator it2 = entries.entrySet().iterator(); it2.hasNext(); )
          {
            Map.Entry e2 = (Map.Entry) it2.next();
            String entryname = String.valueOf(e2.getKey());
            Attributes attr = (Attributes) e2.getValue();
            if (verifyHashes(entryname, attr, hmManifestEntries))
              {
                if (DEBUG)
                  debug("entry " + entryname + " has certificates " + certificates);
                Set s = (Set) this.entryCerts.get(entryname);
                if (s != null)
                  s.addAll(certificates);
                else
                  this.entryCerts.put(entryname, new HashSet(certificates));
              }
          }
      }

    signaturesRead = true;
  }

  /**
   * Tell if the given signer info is over the given alias's signature file,
   * given one of the certificates specified.
   */
  private void verify(Certificate[] certs, SignerInfo signerInfo,
                      String alias, Set validCerts)
  {
    Signature sig = null;
    try
      {
        OID alg = signerInfo.getDigestEncryptionAlgorithmId();
        if (alg.equals(DSA_ENCRYPTION_OID))
          {
            if (!signerInfo.getDigestAlgorithmId().equals(SHA1_OID))
              return;
            sig = Signature.getInstance("SHA1withDSA", provider);
          }
        else if (alg.equals(RSA_ENCRYPTION_OID))
          {
            OID hash = signerInfo.getDigestAlgorithmId();
            if (hash.equals(MD2_OID))
              sig = Signature.getInstance("md2WithRsaEncryption", provider);
            else if (hash.equals(MD4_OID))
              sig = Signature.getInstance("md4WithRsaEncryption", provider);
            else if (hash.equals(MD5_OID))
              sig = Signature.getInstance("md5WithRsaEncryption", provider);
            else if (hash.equals(SHA1_OID))
              sig = Signature.getInstance("sha1WithRsaEncryption", provider);
            else
              return;
          }
        else
          {
            if (DEBUG)
              debug("unsupported signature algorithm: " + alg);
            return;
          }
      }
    catch (NoSuchAlgorithmException nsae)
      {
        if (DEBUG)
          {
            debug(nsae);
            nsae.printStackTrace();
          }
        return;
      }
    ZipEntry sigFileEntry = super.getEntry(META_INF + alias + SF_SUFFIX);
    if (sigFileEntry == null)
      return;
    for (int i = 0; i < certs.length; i++)
      {
        if (!(certs[i] instanceof X509Certificate))
          continue;
        X509Certificate cert = (X509Certificate) certs[i];
        if (!cert.getIssuerX500Principal().equals(signerInfo.getIssuer()) ||
            !cert.getSerialNumber().equals(signerInfo.getSerialNumber()))
          continue;
        try
          {
            sig.initVerify(cert.getPublicKey());
            InputStream in = super.getInputStream(sigFileEntry);
            if (in == null)
              continue;
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = in.read(buf)) != -1)
              sig.update(buf, 0, len);
            if (sig.verify(signerInfo.getEncryptedDigest()))
              {
                if (DEBUG)
                  debug("signature for " + cert.getSubjectDN() + " is good");
                validCerts.add(cert);
              }
          }
        catch (IOException ioe)
          {
            continue;
          }
        catch (InvalidKeyException ike)
          {
            continue;
          }
        catch (SignatureException se)
          {
            continue;
          }
      }
  }

  /**
   * Verifies that the digest(s) in a signature file were, in fact, made over
   * the manifest entry for ENTRY.
   * 
   * @param entry The entry name.
   * @param attr The attributes from the signature file to verify.
   * @param hmManifestEntries Mappings of Jar file entry names to their manifest
   *          entry text; i.e. the base-64 encoding of their 
   */
  private boolean verifyHashes(String entry, Attributes attr,
                               HashMap hmManifestEntries)
  {
    int verified = 0;

    String stringEntry = (String) hmManifestEntries.get(entry);
    if (stringEntry == null)
      {
        if (DEBUG)
          debug("could not find " + entry + " in manifest");
        return false;
      }
    // The bytes for ENTRY's manifest entry, which are signed in the
    // signature file.
    byte[] entryBytes = stringEntry.getBytes();

    for (Iterator it = attr.entrySet().iterator(); it.hasNext(); )
      {
        Map.Entry e = (Map.Entry) it.next();
        String key = String.valueOf(e.getKey());
        if (!key.endsWith(DIGEST_KEY_SUFFIX))
          continue;
        String alg = key.substring(0, key.length() - DIGEST_KEY_SUFFIX.length());
        try
          {
            byte[] hash = Base64InputStream.decode((String) e.getValue());
            MessageDigest md = (MessageDigest) digestAlgorithms.get(alg);
            if (md == null)
              {
                md = MessageDigest.getInstance(alg, provider);
                digestAlgorithms.put(alg, md);
              }
            md.reset();
            byte[] hash2 = md.digest(entryBytes);
            if (DEBUG)
              debug("verifying SF entry " + entry + " alg: " + md.getAlgorithm()
                    + " expect=" + new java.math.BigInteger(hash).toString(16)
                    + " comp=" + new java.math.BigInteger(hash2).toString(16));
            if (!Arrays.equals(hash, hash2))
              return false;
            verified++;
          }
        catch (IOException ioe)
          {
            if (DEBUG)
              {
                debug(ioe);
                ioe.printStackTrace();
              }
            return false;
          }
        catch (NoSuchAlgorithmException nsae)
          {
            if (DEBUG)
              {
                debug(nsae);
                nsae.printStackTrace();
              }
            return false;
          }
      }

    // We have to find at least one valid digest.
    return verified > 0;
  }

  /**
   * A utility class that verifies jar entries as they are read.
   */
  private static class EntryInputStream extends FilterInputStream
  {
    private final JarFile jarfile;
    private final long length;
    private long pos;
    private final ZipEntry entry;
    private final byte[][] hashes;
    private final MessageDigest[] md;
    private boolean checked;

    EntryInputStream(final ZipEntry entry,
		     final InputStream in,
		     final JarFile jar)
      throws IOException
    {
      super(in);
      this.entry = entry;
      this.jarfile = jar;

      length = entry.getSize();
      pos = 0;
      checked = false;

      Attributes attr;
      Manifest manifest = jarfile.getManifest();
      if (manifest != null)
	attr = manifest.getAttributes(entry.getName());
      else
	attr = null;
      if (DEBUG)
        debug("verifying entry " + entry + " attr=" + attr);
      if (attr == null)
        {
          hashes = new byte[0][];
          md = new MessageDigest[0];
        }
      else
        {
          List hashes = new LinkedList();
          List md = new LinkedList();
          for (Iterator it = attr.entrySet().iterator(); it.hasNext(); )
            {
              Map.Entry e = (Map.Entry) it.next();
              String key = String.valueOf(e.getKey());
              if (key == null)
                continue;
              if (!key.endsWith(DIGEST_KEY_SUFFIX))
                continue;
              hashes.add(Base64InputStream.decode((String) e.getValue()));
              try
                {
                  int length = key.length() - DIGEST_KEY_SUFFIX.length();
                  String alg = key.substring(0, length);
                  md.add(MessageDigest.getInstance(alg, provider));
                }
              catch (NoSuchAlgorithmException nsae)
                {
                  IOException ioe = new IOException("no such message digest: " + key);
                  ioe.initCause(nsae);
                  throw ioe;
                }
            }
          if (DEBUG)
            debug("digests=" + md);
          this.hashes = (byte[][]) hashes.toArray(new byte[hashes.size()][]);
          this.md = (MessageDigest[]) md.toArray(new MessageDigest[md.size()]);
        }
    }

    public boolean markSupported()
    {
      return false;
    }

    public void mark(int readLimit)
    {
    }

    public void reset()
    {
    }

    public int read() throws IOException
    {
      int b = super.read();
      if (b == -1)
        {
          eof();
          return -1;
        }
      for (int i = 0; i < md.length; i++)
        md[i].update((byte) b);
      pos++;
      if (length > 0 && pos >= length)
        eof();
      return b;
    }

    public int read(byte[] buf, int off, int len) throws IOException
    {
      int count = super.read(buf, off, (int) Math.min(len, (length != 0
                                                            ? length - pos
                                                            : Integer.MAX_VALUE)));
      if (count == -1 || (length > 0 && pos >= length))
        {
          eof();
          return -1;
        }
      for (int i = 0; i < md.length; i++)
        md[i].update(buf, off, count);
      pos += count;
      if (length != 0 && pos >= length)
        eof();
      return count;
    }

    public int read(byte[] buf) throws IOException
    {
      return read(buf, 0, buf.length);
    }

    public long skip(long bytes) throws IOException
    {
      byte[] b = new byte[1024];
      long amount = 0;
      while (amount < bytes)
        {
          int l = read(b, 0, (int) Math.min(b.length, bytes - amount));
          if (l == -1)
            break;
          amount += l;
        }
      return amount;
    }

    private void eof() throws IOException
    {
      if (checked)
        return;
      checked = true;
      for (int i = 0; i < md.length; i++)
        {
          byte[] hash = md[i].digest();
          if (DEBUG)
            debug("verifying " + md[i].getAlgorithm() + " expect="
                  + new java.math.BigInteger(hashes[i]).toString(16)
                  + " comp=" + new java.math.BigInteger(hash).toString(16));
          if (!Arrays.equals(hash, hashes[i]))
            {
	      synchronized(jarfile)
		{
		  if (DEBUG)
		    debug(entry + " could NOT be verified");
		  jarfile.verified.put(entry.getName(), Boolean.FALSE);
		}
	      return;
	      // XXX ??? what do we do here?
	      // throw new ZipException("message digest mismatch");
            }
        }

      synchronized(jarfile)
	{
	  if (DEBUG)
	    debug(entry + " has been VERIFIED");
	  jarfile.verified.put(entry.getName(), Boolean.TRUE);
	}
    }
  }
}
