001: /*
002: * Copyright 1996-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.jar;
027:
028: import java.io.*;
029: import java.util.*;
030: import java.util.zip.*;
031: import java.util.jar.*;
032: import java.security.cert.Certificate;
033: import java.security.AccessController;
034: import java.security.cert.X509Certificate;
035: import java.security.Identity;
036: import java.security.PublicKey;
037: import java.security.Principal;
038: import sun.security.provider.SystemIdentity;
039:
040: /**
041: * This is OBSOLETE. DO NOT USE THIS. Use
042: * java.util.jar.JarEntry.getCertificates instead. It has to stay here
043: * because some apps (namely HJ and HJV) call directly into it.
044: *
045: * This class is stripped down greatly from JDK 1.1.x.
046: *
047: * @version 1.58 05/05/07
048: * @author Roland Schemers
049: */
050: public class JarVerifierStream extends ZipInputStream {
051:
052: private JarEntry current;
053: private Hashtable verified = new Hashtable();
054: private JarInputStream jis;
055: private sun.tools.jar.Manifest man = null;
056:
057: /**
058: * construct a JarVerfierStream from an input stream.
059: */
060: public JarVerifierStream(InputStream is) throws IOException {
061: super (is);
062: jis = new JarInputStream(is);
063: }
064:
065: public void close() throws IOException {
066: jis.close();
067: }
068:
069: public void closeEntry() throws IOException {
070: jis.closeEntry();
071: }
072:
073: /**
074: * This method scans to see which entry we're parsing and
075: * keeps various state information depending on what type of
076: * file is being parsed. Files it treats specially are: <ul>
077: *
078: * <li>Manifest files. At any point, this stream can be queried
079: * for a manifest. If it is present, a Manifest object will be
080: * returned.
081: *
082: * <li>Block Signature file. Like with the manifest, the stream
083: * can be queried at any time for all blocks parsed thus far.
084: *
085: * </ul>
086: */
087: public synchronized ZipEntry getNextEntry() throws IOException {
088: current = (JarEntry) jis.getNextEntry();
089: return current;
090: }
091:
092: /**
093: * read a single byte.
094: */
095: public int read() throws IOException {
096: int n = jis.read();
097: if (n == -1) {
098: addIds();
099: }
100: return n;
101: }
102:
103: /**
104: * read an array of bytes.
105: */
106: public int read(byte[] b, int off, int len) throws IOException {
107: int n = jis.read(b, off, len);
108: if (n == -1) {
109: addIds();
110: }
111: return n;
112: }
113:
114: private void addIds() {
115:
116: if (current != null) {
117: Certificate[] certs = current.getCertificates();
118: if (certs != null) {
119: Vector ids = getIds(certs);
120: if (ids != null) {
121: verified.put(current.getName(), ids);
122: }
123: }
124: }
125: }
126:
127: /**
128: * Returns a Hashtable mapping filenames to vectors of identities.
129: */
130: public Hashtable getVerifiedSignatures() {
131: /* we may want to return a copy of this at some point.
132: For now we simply trust the caller */
133: if (verified.isEmpty())
134: return null;
135: else
136: return verified;
137: }
138:
139: /**
140: * Returns an enumeration of PKCS7 blocks. This looks bogus,
141: * but Hotjava just checks to see if enumeration is not null
142: * to see if anything was signed!
143: */
144: public Enumeration getBlocks() {
145: if (verified.isEmpty()) {
146: return null;
147: } else {
148: return new Enumeration() {
149: public boolean hasMoreElements() {
150: return false;
151: }
152:
153: public Object nextElement() {
154: return null;
155: }
156: };
157: }
158: }
159:
160: /**
161: * This method used to be called by various versions of
162: * AppletResourceLoader, even though they didn't do anything with
163: * the result. We leave them and return null for backwards compatability.
164: */
165: public Hashtable getNameToHash() {
166: return null;
167: }
168:
169: /**
170: * Convert java.util.jar.Manifest object to a sun.tools.jar.Manifest
171: * object.
172: */
173:
174: public sun.tools.jar.Manifest getManifest() {
175: if (man == null) {
176: try {
177: java.util.jar.Manifest jman = jis.getManifest();
178: if (jman == null)
179: return null;
180: ByteArrayOutputStream baos = new ByteArrayOutputStream();
181: jman.write(baos);
182: byte[] data = baos.toByteArray();
183: man = new sun.tools.jar.Manifest(data);
184: } catch (IOException ioe) {
185: // return null
186: }
187: }
188: return man;
189: }
190:
191: static class CertCache {
192: Certificate[] certs;
193: Vector ids;
194:
195: boolean equals(Certificate[] certs) {
196: if (this .certs == null) {
197: if (certs != null)
198: return false;
199: else
200: return true;
201: }
202:
203: if (certs == null)
204: return false;
205:
206: boolean match;
207:
208: for (int i = 0; i < certs.length; i++) {
209: match = false;
210: for (int j = 0; j < this .certs.length; j++) {
211: if (certs[i].equals(this .certs[j])) {
212: match = true;
213: break;
214: }
215: }
216: if (!match)
217: return false;
218: }
219:
220: for (int i = 0; i < this .certs.length; i++) {
221: match = false;
222: for (int j = 0; j < certs.length; j++) {
223: if (this .certs[i].equals(certs[j])) {
224: match = true;
225: break;
226: }
227: }
228: if (!match)
229: return false;
230: }
231: return true;
232: }
233: }
234:
235: private ArrayList certCache = null;
236:
237: /**
238: * Returns the Identity vector for the given array of Certificates
239: */
240: protected Vector getIds(Certificate[] certs) {
241: if (certs == null)
242: return null;
243:
244: if (certCache == null)
245: certCache = new ArrayList();
246: CertCache cc;
247: for (int i = 0; i < certCache.size(); i++) {
248: cc = (CertCache) certCache.get(i);
249: if (cc.equals(certs)) {
250: return cc.ids;
251: }
252: }
253: cc = new CertCache();
254: cc.certs = certs;
255:
256: if (certs.length > 0) {
257: for (int i = 0; i < certs.length; i++) {
258: try {
259: X509Certificate cert = (X509Certificate) certs[i];
260: Principal tmpName = cert.getSubjectDN();
261: final SystemIdentity id = new SystemIdentity(
262: tmpName.getName(), null);
263:
264: byte[] encoded = cert.getEncoded();
265: final java.security.Certificate oldC = new sun.security.x509.X509Cert(
266: encoded);
267: try {
268: AccessController
269: .doPrivileged(new java.security.PrivilegedExceptionAction() {
270: public Object run()
271: throws java.security.KeyManagementException {
272: id.addCertificate(oldC);
273: return null;
274: }
275: });
276: } catch (java.security.PrivilegedActionException pae) {
277: throw (java.security.KeyManagementException) pae
278: .getException();
279: }
280: if (cc.ids == null)
281: cc.ids = new Vector();
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: }
|