Source Code Cross Referenced for JarVerifier.java in  » 6.0-JDK-Modules » j2me » java » util » jar » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » java.util.jar 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)JarVerifier.java	1.35 06/10/10
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.  
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  
006:         *   
007:         * This program is free software; you can redistribute it and/or  
008:         * modify it under the terms of the GNU General Public License version  
009:         * 2 only, as published by the Free Software Foundation.   
010:         *   
011:         * This program is distributed in the hope that it will be useful, but  
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of  
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
014:         * General Public License version 2 for more details (a copy is  
015:         * included at /legal/license.txt).   
016:         *   
017:         * You should have received a copy of the GNU General Public License  
018:         * version 2 along with this work; if not, write to the Free Software  
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
020:         * 02110-1301 USA   
021:         *   
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  
023:         * Clara, CA 95054 or visit www.sun.com if you need additional  
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package java.util.jar;
029:
030:        import java.io.*;
031:        import java.util.*;
032:        import java.util.zip.*;
033:        import java.security.*;
034:
035:        import sun.security.util.ManifestDigester;
036:        import sun.security.util.ManifestEntryVerifier;
037:        import sun.security.util.SignatureFileVerifier;
038:        import sun.security.util.Debug;
039:
040:        /**
041:         *
042:         * @version 	1.35, 10/10/06
043:         * @author	Roland Schemers
044:         */
045:        class JarVerifier {
046:
047:            /* Are we debugging ? */
048:            static final Debug debug = Debug.getInstance("jar");
049:
050:            /* a table mapping names to identities for entries that have
051:               had their actual hashes verified */
052:            private Hashtable verifiedCerts;
053:
054:            /* a table mapping names to Certs for entries that have
055:               passed the .SF/.DSA -> MANIFEST check */
056:            private Hashtable sigFileCerts;
057:
058:            /* a hash table to hold .SF bytes */
059:            private Hashtable sigFileData;
060:
061:            /** "queue" of pending PKCS7 blocks that we couldn't parse
062:             *  until we parsed the .SF file */
063:            private ArrayList pendingBlocks;
064:
065:            /* cache of Certificate[] objects */
066:            private ArrayList certCache;
067:
068:            /* Are we parsing a block? */
069:            private boolean parsingBlockOrSF = false;
070:
071:            /* Are we done parsing META-INF entries? */
072:            private boolean parsingMeta = true;
073:
074:            /* Are there are files to verify? */
075:            private boolean anyToVerify = true;
076:
077:            /* The manifest file */
078:            private Manifest manifest;
079:
080:            /* The output stream to use when keeping track of files we are interested
081:               in */
082:            private ByteArrayOutputStream baos;
083:
084:            /** The ManifestDigester object */
085:            private ManifestDigester manDig;
086:
087:            /** the bytes for the manDig object */
088:            byte manifestRawBytes[] = null;
089:
090:            /**
091:             */
092:            public JarVerifier(Manifest manifest, byte rawBytes[]) {
093:                manifestRawBytes = rawBytes;
094:                sigFileCerts = new Hashtable();
095:                verifiedCerts = new Hashtable();
096:                sigFileData = new Hashtable(11);
097:                pendingBlocks = new ArrayList();
098:                baos = new ByteArrayOutputStream();
099:                this .manifest = manifest;
100:            }
101:
102:            /**
103:             * This method scans to see which entry we're parsing and
104:             * keeps various state information depending on what type of
105:             * file is being parsed.
106:             */
107:            public void beginEntry(JarEntry je, ManifestEntryVerifier mev)
108:                    throws IOException {
109:                if (je == null)
110:                    return;
111:
112:                if (debug != null) {
113:                    debug.println("beginEntry " + je.getName());
114:                }
115:
116:                String name = je.getName();
117:
118:                /*
119:                 * Assumptions:
120:                 * 1. The manifest should be the first entry in the META-INF directory.
121:                 * 2. The .SF/.DSA files follow the manifest, before any normal entries
122:                 * 3. Any of the following will throw a SecurityException:
123:                 *    a. digest mismatch between a manifest section and
124:                 *       the SF section.
125:                 *    b. digest mismatch between the actual jar entry and the manifest
126:                 */
127:
128:                if (parsingMeta) {
129:                    String uname = name.toUpperCase(Locale.ENGLISH);
130:                    if ((uname.startsWith("META-INF/") || uname
131:                            .startsWith("/META-INF/"))) {
132:
133:                        if (je.isDirectory()) {
134:                            mev.setEntry(null, je);
135:                            return;
136:                        }
137:
138:                        if (uname.endsWith(".DSA") || uname.endsWith(".RSA")
139:                                || uname.endsWith(".SF")) {
140:                            /* We parse only DSA or RSA PKCS7 blocks. */
141:                            parsingBlockOrSF = true;
142:                            baos.reset();
143:                            mev.setEntry(null, je);
144:                        }
145:                        return;
146:                    }
147:                }
148:
149:                if (parsingMeta) {
150:                    doneWithMeta();
151:                }
152:
153:                if (je.isDirectory()) {
154:                    mev.setEntry(null, je);
155:                    return;
156:                }
157:
158:                // be liberal in what you accept. If the name starts with ./, remove
159:                // it as we internally canonicalize it with out the ./.
160:                if (name.startsWith("./"))
161:                    name = name.substring(2);
162:
163:                // be liberal in what you accept. If the name starts with /, remove
164:                // it as we internally canonicalize it with out the /.
165:                if (name.startsWith("/"))
166:                    name = name.substring(1);
167:
168:                // only set the jev object for entries that have a signature
169:                if (sigFileCerts.get(name) != null) {
170:                    mev.setEntry(name, je);
171:                    return;
172:                }
173:
174:                // don't compute the digest for this entry
175:                mev.setEntry(null, je);
176:
177:                return;
178:            }
179:
180:            /**
181:             * update a single byte.
182:             */
183:
184:            public void update(int b, ManifestEntryVerifier mev)
185:                    throws IOException {
186:                if (b != -1) {
187:                    if (parsingBlockOrSF) {
188:                        baos.write(b);
189:                    } else {
190:                        mev.update((byte) b);
191:                    }
192:                } else {
193:                    processEntry(mev);
194:                }
195:            }
196:
197:            /**
198:             * update an array of bytes.
199:             */
200:
201:            public void update(int n, byte[] b, int off, int len,
202:                    ManifestEntryVerifier mev) throws IOException {
203:                if (n != -1) {
204:                    if (parsingBlockOrSF) {
205:                        baos.write(b, off, n);
206:                    } else {
207:                        mev.update(b, off, n);
208:                    }
209:                } else {
210:                    processEntry(mev);
211:                }
212:            }
213:
214:            /**
215:             * called when we reach the end of entry in one of the read() methods.
216:             */
217:            private void processEntry(ManifestEntryVerifier mev)
218:                    throws IOException {
219:                if (!parsingBlockOrSF) {
220:                    JarEntry je = mev.getEntry();
221:                    if ((je != null) && (je.certs == null)) {
222:                        je.certs = mev.verify(verifiedCerts, sigFileCerts);
223:                    }
224:                } else {
225:
226:                    try {
227:                        parsingBlockOrSF = false;
228:
229:                        if (debug != null) {
230:                            debug.println("processEntry: processing block");
231:                        }
232:
233:                        String uname = mev.getEntry().getName().toUpperCase(
234:                                Locale.ENGLISH);
235:
236:                        if (uname.endsWith(".SF")) {
237:                            String key = uname.substring(0, uname.length() - 3);
238:                            byte bytes[] = baos.toByteArray();
239:                            // add to sigFileData in case future blocks need it
240:                            sigFileData.put(key, bytes);
241:                            // check pending blocks, we can now process
242:                            // anyone waiting for this .SF file
243:                            Iterator it = pendingBlocks.iterator();
244:                            while (it.hasNext()) {
245:                                SignatureFileVerifier sfv = (SignatureFileVerifier) it
246:                                        .next();
247:                                if (sfv.needSignatureFile(key)) {
248:                                    if (debug != null) {
249:                                        debug
250:                                                .println("processEntry: processing pending block");
251:                                    }
252:
253:                                    sfv.setSignatureFile(bytes);
254:                                    sfv.process(sigFileCerts);
255:                                }
256:                            }
257:                            return;
258:                        }
259:
260:                        // now we are parsing a signature block file
261:
262:                        String key = uname.substring(0, uname.lastIndexOf("."));
263:
264:                        if (certCache == null)
265:                            certCache = new ArrayList();
266:
267:                        if (manDig == null) {
268:                            synchronized (manifestRawBytes) {
269:                                if (manDig == null) {
270:                                    manDig = new ManifestDigester(
271:                                            manifestRawBytes);
272:                                    manifestRawBytes = null;
273:                                }
274:                            }
275:                        }
276:
277:                        SignatureFileVerifier sfv = new SignatureFileVerifier(
278:                                certCache, manDig, uname, baos.toByteArray());
279:
280:                        if (sfv.needSignatureFileBytes()) {
281:                            // see if we have already parsed an external .SF file
282:                            byte[] bytes = (byte[]) sigFileData.get(key);
283:
284:                            if (bytes == null) {
285:                                // put this block on queue for later processing
286:                                // since we don't have the .SF bytes yet
287:                                // (uname, block);
288:                                if (debug != null) {
289:                                    debug.println("adding pending block");
290:                                }
291:                                pendingBlocks.add(sfv);
292:                                return;
293:                            } else {
294:                                sfv.setSignatureFile(bytes);
295:                            }
296:                        }
297:                        sfv.process(sigFileCerts);
298:
299:                    } catch (sun.security.pkcs.ParsingException pe) {
300:                        if (debug != null)
301:                            debug.println("processEntry caught: " + pe);
302:                        // ignore and treat as unsigned
303:                    } catch (IOException ioe) {
304:                        if (debug != null)
305:                            debug.println("processEntry caught: " + ioe);
306:                        // ignore and treat as unsigned
307:                    } catch (SignatureException se) {
308:                        if (debug != null)
309:                            debug.println("processEntry caught: " + se);
310:                        // ignore and treat as unsigned
311:                    } catch (NoSuchAlgorithmException nsae) {
312:                        if (debug != null)
313:                            debug.println("processEntry caught: " + nsae);
314:                        // ignore and treat as unsigned
315:                    }
316:                }
317:            }
318:
319:            /**
320:             * return an array of java.security.cert.Certificate objects for
321:             * the given file in the jar. this array is not cloned.
322:             *
323:             */
324:            public java.security.cert.Certificate[] getCerts(String name) {
325:                return (java.security.cert.Certificate[]) verifiedCerts
326:                        .get(name);
327:            }
328:
329:            /**
330:             * returns true if there no files to verify.
331:             * should only be called after all the META-INF entries
332:             * have been processed.
333:             */
334:            boolean nothingToVerify() {
335:                return (anyToVerify == false);
336:            }
337:
338:            /**
339:             * called to let us know we have processed all the
340:             * META-INF entries, and if we re-read one of them, don't
341:             * re-process it. Also gets rid of any data structures
342:             * we needed when parsing META-INF entries.
343:             */
344:            void doneWithMeta() {
345:                parsingMeta = false;
346:                anyToVerify = !sigFileCerts.isEmpty();
347:                baos = null;
348:                sigFileData = null;
349:                pendingBlocks = null;
350:                certCache = null;
351:                manDig = null;
352:            }
353:
354:            static class VerifierStream extends java.io.InputStream {
355:
356:                private InputStream is;
357:                private JarVerifier jv;
358:                private ManifestEntryVerifier mev;
359:                private long numLeft;
360:
361:                VerifierStream(Manifest man, JarEntry je, InputStream is,
362:                        JarVerifier jv) throws IOException {
363:                    this .is = is;
364:                    this .jv = jv;
365:                    this .mev = new ManifestEntryVerifier(man);
366:                    this .jv.beginEntry(je, mev);
367:                    this .numLeft = je.getSize();
368:                    if (this .numLeft == 0)
369:                        this .jv.update(-1, this .mev);
370:                }
371:
372:                public int read() throws IOException {
373:                    if (numLeft > 0) {
374:                        int b = is.read();
375:                        jv.update(b, mev);
376:                        numLeft--;
377:                        if (numLeft == 0)
378:                            jv.update(-1, mev);
379:                        return b;
380:                    } else {
381:                        return -1;
382:                    }
383:                }
384:
385:                public int read(byte b[], int off, int len) throws IOException {
386:                    if ((numLeft > 0) && (numLeft < len)) {
387:                        len = (int) numLeft;
388:                    }
389:
390:                    if (numLeft > 0) {
391:                        int n = is.read(b, off, len);
392:                        jv.update(n, b, off, len, mev);
393:                        numLeft -= n;
394:                        if (numLeft == 0)
395:                            jv.update(-1, b, off, len, mev);
396:                        return n;
397:                    } else {
398:                        return -1;
399:                    }
400:                }
401:
402:                public void close() throws IOException {
403:                    if (is != null)
404:                        is.close();
405:                    is = null;
406:                    mev = null;
407:                    jv = null;
408:                }
409:
410:                public int available() throws IOException {
411:                    return is.available();
412:                }
413:
414:            }
415:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.