jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java
changeset 4422 ade55a65b0f2
parent 4421 fcbbd4d49581
parent 4408 80dcc8ac5696
child 4423 4061c66ba1af
equal deleted inserted replaced
4421:fcbbd4d49581 4422:ade55a65b0f2
     1 /*
       
     2  * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package sun.tools.jar;
       
    27 
       
    28 import java.io.*;
       
    29 import java.util.*;
       
    30 import java.util.zip.*;
       
    31 import java.util.jar.*;
       
    32 import java.security.cert.Certificate;
       
    33 import java.security.AccessController;
       
    34 import java.security.cert.X509Certificate;
       
    35 import java.security.PublicKey;
       
    36 import java.security.Principal;
       
    37 import sun.security.provider.SystemIdentity;
       
    38 
       
    39 /**
       
    40  * This is OBSOLETE. DO NOT USE THIS. Use
       
    41  * java.util.jar.JarEntry.getCertificates instead. It has to stay here
       
    42  * because some apps (namely HJ and HJV) call directly into it.
       
    43  *
       
    44  * This class is stripped down greatly from JDK 1.1.x.
       
    45  *
       
    46  * @author Roland Schemers
       
    47  */
       
    48 public class JarVerifierStream extends ZipInputStream {
       
    49 
       
    50     private JarEntry current;
       
    51     private Hashtable<String, Vector<SystemIdentity>> verified
       
    52         = new Hashtable<String, Vector<SystemIdentity>>();
       
    53     private JarInputStream jis;
       
    54     private sun.tools.jar.Manifest man = null;
       
    55 
       
    56     /**
       
    57      * construct a JarVerfierStream from an input stream.
       
    58      */
       
    59     public JarVerifierStream(InputStream is)
       
    60          throws IOException
       
    61     {
       
    62         super(is);
       
    63         jis = new JarInputStream(is);
       
    64     }
       
    65 
       
    66     public void close()
       
    67         throws IOException
       
    68     {
       
    69         jis.close();
       
    70     }
       
    71 
       
    72     public void closeEntry() throws IOException {
       
    73         jis.closeEntry();
       
    74     }
       
    75 
       
    76     /**
       
    77      * This method scans to see which entry we're parsing and
       
    78      * keeps various state information depending on what type of
       
    79      * file is being parsed. Files it treats specially are: <ul>
       
    80      *
       
    81      * <li>Manifest files. At any point, this stream can be queried
       
    82      * for a manifest. If it is present, a Manifest object will be
       
    83      * returned.
       
    84      *
       
    85      * <li>Block Signature file. Like with the manifest, the stream
       
    86      * can be queried at any time for all blocks parsed thus far.
       
    87      *
       
    88      * </ul>
       
    89      */
       
    90     public synchronized ZipEntry getNextEntry() throws IOException {
       
    91         current = (JarEntry) jis.getNextEntry();
       
    92         return current;
       
    93     }
       
    94 
       
    95     /**
       
    96      * read a single byte.
       
    97      */
       
    98     public int read() throws IOException {
       
    99         int n = jis.read();
       
   100         if (n == -1) {
       
   101             addIds();
       
   102         }
       
   103         return n;
       
   104     }
       
   105 
       
   106     /**
       
   107      * read an array of bytes.
       
   108      */
       
   109     public int read(byte[] b, int off, int len) throws IOException {
       
   110         int n = jis.read(b, off, len);
       
   111         if (n == -1) {
       
   112             addIds();
       
   113         }
       
   114         return n;
       
   115     }
       
   116 
       
   117     private void addIds()
       
   118     {
       
   119 
       
   120         if (current != null) {
       
   121             Certificate[] certs = current.getCertificates();
       
   122             if (certs != null) {
       
   123                 Vector<SystemIdentity> ids = getIds(certs);
       
   124                 if (ids != null) {
       
   125                     verified.put(current.getName(), ids);
       
   126                 }
       
   127             }
       
   128         }
       
   129     }
       
   130 
       
   131     /**
       
   132      * Returns a Hashtable mapping filenames to vectors of identities.
       
   133      */
       
   134     public Hashtable getVerifiedSignatures() {
       
   135         /* we may want to return a copy of this at some point.
       
   136            For now we simply trust the caller */
       
   137         if (verified.isEmpty())
       
   138             return null;
       
   139         else
       
   140             return verified;
       
   141     }
       
   142 
       
   143     /**
       
   144      * Returns an enumeration of PKCS7 blocks. This looks bogus,
       
   145      * but Hotjava just checks to see if enumeration is not null
       
   146      * to see if anything was signed!
       
   147      */
       
   148     public Enumeration getBlocks() {
       
   149         if (verified.isEmpty()) {
       
   150             return null;
       
   151         } else {
       
   152             return new Enumeration() {
       
   153                 public boolean hasMoreElements() { return false; }
       
   154                 public Object nextElement() { return null; }
       
   155             };
       
   156         }
       
   157     }
       
   158 
       
   159     /**
       
   160      * This method used to be called by various versions of
       
   161      * AppletResourceLoader, even though they didn't do anything with
       
   162      * the result. We leave them and return null for backwards compatability.
       
   163      */
       
   164     public Hashtable getNameToHash() {
       
   165         return null;
       
   166     }
       
   167 
       
   168     /**
       
   169      * Convert java.util.jar.Manifest object to a sun.tools.jar.Manifest
       
   170      * object.
       
   171      */
       
   172 
       
   173     public sun.tools.jar.Manifest getManifest() {
       
   174         if (man == null) {
       
   175             try {
       
   176                 java.util.jar.Manifest jman = jis.getManifest();
       
   177                 if (jman == null)
       
   178                     return null;
       
   179                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
       
   180                 jman.write(baos);
       
   181                 byte[] data = baos.toByteArray();
       
   182                 man = new sun.tools.jar.Manifest(data);
       
   183             } catch (IOException ioe) {
       
   184                 // return null
       
   185             }
       
   186         }
       
   187         return man;
       
   188     }
       
   189 
       
   190     static class CertCache {
       
   191         Certificate [] certs;
       
   192         Vector<SystemIdentity> ids;
       
   193 
       
   194         boolean equals(Certificate[] certs) {
       
   195                 if (this.certs == null) {
       
   196                     if (certs!= null)
       
   197                         return false;
       
   198                     else
       
   199                         return true;
       
   200                 }
       
   201 
       
   202                 if (certs == null)
       
   203                     return false;
       
   204 
       
   205                 boolean match;
       
   206 
       
   207                 for (int i = 0; i < certs.length; i++) {
       
   208                     match = false;
       
   209                     for (int j = 0; j < this.certs.length; j++) {
       
   210                         if (certs[i].equals(this.certs[j])) {
       
   211                             match = true;
       
   212                             break;
       
   213                         }
       
   214                     }
       
   215                     if (!match) return false;
       
   216                 }
       
   217 
       
   218                 for (int i = 0; i < this.certs.length; i++) {
       
   219                     match = false;
       
   220                     for (int j = 0; j < certs.length; j++) {
       
   221                         if (this.certs[i].equals(certs[j])) {
       
   222                             match = true;
       
   223                             break;
       
   224                         }
       
   225                     }
       
   226                     if (!match) return false;
       
   227                 }
       
   228                 return true;
       
   229         }
       
   230     }
       
   231 
       
   232     private ArrayList<CertCache> certCache = null;
       
   233 
       
   234 
       
   235     /**
       
   236      * Returns the Identity vector for the given array of Certificates
       
   237      */
       
   238     protected Vector<SystemIdentity> getIds(Certificate[] certs) {
       
   239         if (certs == null)
       
   240             return null;
       
   241 
       
   242         if (certCache == null)
       
   243             certCache = new ArrayList<CertCache>();
       
   244         CertCache cc;
       
   245         for (int i = 0; i < certCache.size(); i++) {
       
   246             cc = certCache.get(i);
       
   247             if (cc.equals(certs)) {
       
   248                 return cc.ids;
       
   249             }
       
   250         }
       
   251         cc = new CertCache();
       
   252         cc.certs = certs;
       
   253 
       
   254         if (certs.length > 0) {
       
   255             for (int i=0; i<certs.length; i++) {
       
   256                 try {
       
   257                     X509Certificate cert = (X509Certificate) certs[i];
       
   258                     Principal tmpName = cert.getSubjectDN();
       
   259                     final SystemIdentity id = new SystemIdentity(
       
   260                                                            tmpName.getName(),
       
   261                                                            null);
       
   262 
       
   263                     byte[] encoded = cert.getEncoded();
       
   264                     final java.security.Certificate oldC =
       
   265                         new sun.security.x509.X509Cert(encoded);
       
   266                     try {
       
   267                         AccessController.doPrivileged(
       
   268                          new java.security.PrivilegedExceptionAction<Void>() {
       
   269                             public Void run()
       
   270                                 throws java.security.KeyManagementException
       
   271                             {
       
   272                                 id.addCertificate(oldC);
       
   273                                 return null;
       
   274                             }
       
   275                         });
       
   276                     } catch (java.security.PrivilegedActionException pae) {
       
   277                         throw (java.security.KeyManagementException)
       
   278                             pae.getException();
       
   279                     }
       
   280                     if (cc.ids == null)
       
   281                         cc.ids = new Vector<SystemIdentity>();
       
   282                     cc.ids.addElement(id);
       
   283                 } catch (java.security.KeyManagementException kme) {
       
   284                     // ignore if we can't create Identity
       
   285                 } catch (IOException ioe) {
       
   286                     // ignore if we can't parse
       
   287                 } catch (java.security.cert.CertificateEncodingException cee) {
       
   288                     // ignore if we can't encode
       
   289                 }
       
   290             }
       
   291         }
       
   292         certCache.add(cc);
       
   293         return cc.ids;
       
   294     }
       
   295 }