< prev index next >

src/java.base/share/classes/java/util/zip/ZipFile.java

Print this page

        

@@ -342,13 +342,42 @@
      * @throws ZipException if a ZIP format error has occurred
      * @throws IOException if an I/O error has occurred
      * @throws IllegalStateException if the zip file has been closed
      */
     public InputStream getInputStream(ZipEntry entry) throws IOException {
+        return getInputStream(entry, null);
+    }
+
+    /**
+     * Returns an input stream for reading the contents of the specified
+     * zip file entry.
+     *
+     * <p> Closing this ZIP file will, in turn, close all input
+     * streams that have been returned by invocations of this method.
+     *
+     * @param entry the zip file entry
+     * @param zipCryption instance of ZipCryption
+     * @return the input stream for reading the contents of the specified
+     * zip file entry.
+     * @throws ZipException if a ZIP format error has occurred
+     * @throws IOException if an I/O error has occurred
+     * @throws IllegalStateException if the zip file has been closed
+     */
+    public InputStream getInputStream(ZipEntry entry, ZipCryption zipCryption)
+                                                            throws IOException {
         if (entry == null) {
             throw new NullPointerException("entry");
         }
+
+        if ((entry.flag & 1) == 1) {
+            if (zipCryption == null) {
+                throw new ZipException("Passphrase is required.");
+            } else {
+                zipCryption.reset();
+            }
+        }
+
         long jzentry = 0;
         ZipFileInputStream in = null;
         synchronized (this) {
             ensureOpen();
             if (!zc.isUTF8() && (entry.flag & EFS) != 0) {

@@ -357,24 +386,48 @@
                 jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
             }
             if (jzentry == 0) {
                 return null;
             }
-            in = new ZipFileInputStream(jzentry);
+            in = new ZipFileInputStream(jzentry, zipCryption);
 
             switch (getEntryMethod(jzentry)) {
             case STORED:
+
+                if ((entry.flag & 1) == 1) {
+                    byte[] encryptionHeader =
+                                new byte[zipCryption.getEncryptionHeaderSize()];
+                    in.readRaw(encryptionHeader, 0, encryptionHeader.length);
+                    zipCryption.decryptBytes(encryptionHeader);
+
+                    if (!zipCryption.isValid(entry, encryptionHeader)) {
+                        throw new ZipException("possibly incorrect passphrase");
+                    }
+                }
+
                 synchronized (streams) {
                     streams.put(in, null);
                 }
                 return in;
             case DEFLATED:
                 // MORE: Compute good size for inflater stream:
                 long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
                 if (size > 65536) size = 8192;
                 if (size <= 0) size = 4096;
                 Inflater inf = getInflater();
+
+                if ((entry.flag & 1) == 1) {
+                    byte[] encryptionHeader =
+                                new byte[zipCryption.getEncryptionHeaderSize()];
+                    in.readRaw(encryptionHeader, 0, encryptionHeader.length);
+                    zipCryption.decryptBytes(encryptionHeader);
+
+                    if (!zipCryption.isValid(entry, encryptionHeader)) {
+                        throw new ZipException("possibly incorrect passphrase");
+                    }
+                }
+
                 InputStream is =
                     new ZipFileInflaterInputStream(in, inf, (int)size);
                 synchronized (streams) {
                     streams.put(is, inf);
                 }

@@ -694,19 +747,31 @@
         private volatile boolean zfisCloseRequested = false;
         protected long jzentry; // address of jzentry data
         private   long pos;     // current position within entry data
         protected long rem;     // number of remaining bytes within entry
         protected long size;    // uncompressed size of this entry
+        private ZipCryption zipCryption; // ZIP encrypt/decrypt engine
 
-        ZipFileInputStream(long jzentry) {
+        ZipFileInputStream(long jzentry, ZipCryption zipCryption) {
             pos = 0;
             rem = getEntryCSize(jzentry);
             size = getEntrySize(jzentry);
             this.jzentry = jzentry;
+            this.zipCryption = zipCryption;
         }
 
         public int read(byte b[], int off, int len) throws IOException {
+            len = readRaw(b, off, len);
+
+            if (zipCryption != null) {
+                zipCryption.decryptBytes(b, off, len);
+            }
+
+            return len;
+        }
+
+        public int readRaw(byte b[], int off, int len) throws IOException {
             synchronized (ZipFile.this) {
                 long rem = this.rem;
                 long pos = this.pos;
                 if (rem == 0) {
                     return -1;
< prev index next >