blob: 5485bfaded9969b082171ba8d0c0ec34a6272ed8 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1996-2004 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
26package sun.tools.jar;
27
28import java.io.*;
29import java.util.*;
30import java.util.zip.*;
31import java.util.jar.*;
32import java.security.cert.Certificate;
33import java.security.AccessController;
34import java.security.cert.X509Certificate;
35import java.security.Identity;
36import java.security.PublicKey;
37import java.security.Principal;
38import sun.security.provider.SystemIdentity;
39
40/**
41 * This is OBSOLETE. DO NOT USE THIS. Use
42 * java.util.jar.JarEntry.getCertificates instead. It has to stay here
43 * because some apps (namely HJ and HJV) call directly into it.
44 *
45 * This class is stripped down greatly from JDK 1.1.x.
46 *
47 * @author Roland Schemers
48 */
49public class JarVerifierStream extends ZipInputStream {
50
51 private JarEntry current;
52 private Hashtable verified = new Hashtable();
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 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 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 = null;
233
234
235 /**
236 * Returns the Identity vector for the given array of Certificates
237 */
238 protected Vector getIds(Certificate[] certs) {
239 if (certs == null)
240 return null;
241
242 if (certCache == null)
243 certCache = new ArrayList();
244 CertCache cc;
245 for (int i = 0; i < certCache.size(); i++) {
246 cc = (CertCache) 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() {
269 public Object 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();
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}