151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.jar; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URL; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.*; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.CertificateException; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.zip.ZipEntry; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.ManifestDigester; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.ManifestEntryVerifier; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.SignatureFileVerifier; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.Debug; 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Roland Schemers 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass JarVerifier { 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Are we debugging ? */ 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final Debug debug = Debug.getInstance("jar"); 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* a table mapping names to code signers, for jar entries that have 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski had their actual hashes verified */ 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Hashtable verifiedSigners; 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* a table mapping names to code signers, for jar entries that have 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski passed the .SF/.DSA/.EC -> MANIFEST check */ 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Hashtable sigFileSigners; 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* a hash table to hold .SF bytes */ 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Hashtable sigFileData; 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** "queue" of pending PKCS7 blocks that we couldn't parse 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * until we parsed the .SF file */ 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ArrayList pendingBlocks; 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* cache of CodeSigner objects */ 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ArrayList signerCache; 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Are we parsing a block? */ 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean parsingBlockOrSF = false; 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Are we done parsing META-INF entries? */ 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean parsingMeta = true; 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Are there are files to verify? */ 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean anyToVerify = true; 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* The output stream to use when keeping track of files we are interested 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in */ 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ByteArrayOutputStream baos; 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** The ManifestDigester object */ 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile ManifestDigester manDig; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** the bytes for the manDig object */ 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte manifestRawBytes[] = null; 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** controls eager signature validation */ 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean eagerValidation; 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** makes code source singleton instances unique to us */ 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object csdomain = new Object(); 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** collect -DIGEST-MANIFEST values for blacklist */ 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private List manifestDigests; 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarVerifier(byte rawBytes[]) { 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manifestRawBytes = rawBytes; 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigFileSigners = new Hashtable(); 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verifiedSigners = new Hashtable(); 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigFileData = new Hashtable(11); 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pendingBlocks = new ArrayList(); 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski baos = new ByteArrayOutputStream(); 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manifestDigests = new ArrayList(); 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method scans to see which entry we're parsing and 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * keeps various state information depending on what type of 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file is being parsed. 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void beginEntry(JarEntry je, ManifestEntryVerifier mev) 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (je == null) 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) { 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski debug.println("beginEntry "+je.getName()); 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = je.getName(); 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Assumptions: 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1. The manifest should be the first entry in the META-INF directory. 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2. The .SF/.DSA/.EC files follow the manifest, before any normal entries 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3. Any of the following will throw a SecurityException: 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a. digest mismatch between a manifest section and 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the SF section. 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * b. digest mismatch between the actual jar entry and the manifest 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (parsingMeta) { 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String uname = name.toUpperCase(Locale.ENGLISH); 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((uname.startsWith("META-INF/") || 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uname.startsWith("/META-INF/"))) { 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (je.isDirectory()) { 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev.setEntry(null, je); 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (SignatureFileVerifier.isBlockOrSF(uname)) { 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* We parse only DSA, RSA or EC PKCS7 blocks. */ 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parsingBlockOrSF = true; 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski baos.reset(); 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev.setEntry(null, je); 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (parsingMeta) { 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski doneWithMeta(); 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (je.isDirectory()) { 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev.setEntry(null, je); 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // be liberal in what you accept. If the name starts with ./, remove 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // it as we internally canonicalize it with out the ./. 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.startsWith("./")) 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = name.substring(2); 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // be liberal in what you accept. If the name starts with /, remove 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // it as we internally canonicalize it with out the /. 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.startsWith("/")) 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = name.substring(1); 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // only set the jev object for entries that have a signature 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sigFileSigners.get(name) != null) { 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev.setEntry(name, je); 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // don't compute the digest for this entry 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev.setEntry(null, je); 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * update a single byte. 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void update(int b, ManifestEntryVerifier mev) 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (b != -1) { 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (parsingBlockOrSF) { 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski baos.write(b); 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev.update((byte)b); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski processEntry(mev); 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * update an array of bytes. 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void update(int n, byte[] b, int off, int len, 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ManifestEntryVerifier mev) 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n != -1) { 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (parsingBlockOrSF) { 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski baos.write(b, off, n); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev.update(b, off, n); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski processEntry(mev); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called when we reach the end of entry in one of the read() methods. 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void processEntry(ManifestEntryVerifier mev) 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!parsingBlockOrSF) { 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry je = mev.getEntry(); 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((je != null) && (je.signers == null)) { 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski je.signers = mev.verify(verifiedSigners, sigFileSigners); 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski je.certs = mapSignersToCertArray(je.signers); 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parsingBlockOrSF = false; 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) { 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski debug.println("processEntry: processing block"); 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String uname = mev.getEntry().getName() 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski .toUpperCase(Locale.ENGLISH); 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (uname.endsWith(".SF")) { 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String key = uname.substring(0, uname.length()-3); 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte bytes[] = baos.toByteArray(); 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add to sigFileData in case future blocks need it 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigFileData.put(key, bytes); 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check pending blocks, we can now process 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // anyone waiting for this .SF file 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Iterator it = pendingBlocks.iterator(); 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (it.hasNext()) { 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SignatureFileVerifier sfv = 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (SignatureFileVerifier) it.next(); 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sfv.needSignatureFile(key)) { 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) { 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski debug.println( 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "processEntry: processing pending block"); 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sfv.setSignatureFile(bytes); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sfv.process(sigFileSigners, manifestDigests); 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // now we are parsing a signature block file 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String key = uname.substring(0, uname.lastIndexOf(".")); 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signerCache == null) 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signerCache = new ArrayList(); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manDig == null) { 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(manifestRawBytes) { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manDig == null) { 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manDig = new ManifestDigester(manifestRawBytes); 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manifestRawBytes = null; 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SignatureFileVerifier sfv = 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new SignatureFileVerifier(signerCache, 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manDig, uname, baos.toByteArray()); 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sfv.needSignatureFileBytes()) { 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // see if we have already parsed an external .SF file 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] bytes = (byte[]) sigFileData.get(key); 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bytes == null) { 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // put this block on queue for later processing 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // since we don't have the .SF bytes yet 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // (uname, block); 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) { 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski debug.println("adding pending block"); 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pendingBlocks.add(sfv); 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sfv.setSignatureFile(bytes); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sfv.process(sigFileSigners, manifestDigests); 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // e.g. sun.security.pkcs.ParsingException 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) debug.println("processEntry caught: "+ioe); 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ignore and treat as unsigned 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (SignatureException se) { 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) debug.println("processEntry caught: "+se); 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ignore and treat as unsigned 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NoSuchAlgorithmException nsae) { 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) debug.println("processEntry caught: "+nsae); 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ignore and treat as unsigned 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (CertificateException ce) { 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (debug != null) debug.println("processEntry caught: "+ce); 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ignore and treat as unsigned 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return an array of java.security.cert.Certificate objects for 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the given file in the jar. 3289e78cee3f3edf84254174717f475605d712aad1cNarayan Kamath * @deprecated Deprecated. 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 3309e78cee3f3edf84254174717f475605d712aad1cNarayan Kamath @Deprecated // Android-changed added "Deprecated." 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public java.security.cert.Certificate[] getCerts(String name) 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return mapSignersToCertArray(getCodeSigners(name)); 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public java.security.cert.Certificate[] getCerts(JarFile jar, JarEntry entry) 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return mapSignersToCertArray(getCodeSigners(jar, entry)); 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return an array of CodeSigner objects for 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the given file in the jar. this array is not cloned. 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CodeSigner[] getCodeSigners(String name) 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (CodeSigner[])verifiedSigners.get(name); 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CodeSigner[] getCodeSigners(JarFile jar, JarEntry entry) 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = entry.getName(); 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (eagerValidation && sigFileSigners.get(name) != null) { 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Force a read of the entry data to generate the 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * verification hash. 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InputStream s = jar.getInputStream(entry); 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] buffer = new byte[1024]; 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = buffer.length; 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (n != -1) { 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = s.read(buffer, 0, buffer.length); 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.close(); 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getCodeSigners(name); 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Convert an array of signers into an array of concatenated certificate 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * arrays. 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static java.security.cert.Certificate[] mapSignersToCertArray( 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSigner[] signers) { 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signers != null) { 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ArrayList certChains = new ArrayList(); 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < signers.length; i++) { 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski certChains.addAll( 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signers[i].getSignerCertPath().getCertificates()); 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Convert into a Certificate[] 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (java.security.cert.Certificate[]) 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski certChains.toArray( 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new java.security.cert.Certificate[certChains.size()]); 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returns true if there no files to verify. 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * should only be called after all the META-INF entries 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have been processed. 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean nothingToVerify() 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (anyToVerify == false); 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called to let us know we have processed all the 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * META-INF entries, and if we re-read one of them, don't 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * re-process it. Also gets rid of any data structures 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * we needed when parsing META-INF entries. 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void doneWithMeta() 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski parsingMeta = false; 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski anyToVerify = !sigFileSigners.isEmpty(); 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski baos = null; 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigFileData = null; 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pendingBlocks = null; 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signerCache = null; 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manDig = null; 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // MANIFEST.MF is always treated as signed and verified, 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // move its signers from sigFileSigners to verifiedSigners. 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sigFileSigners.containsKey(JarFile.MANIFEST_NAME)) { 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verifiedSigners.put(JarFile.MANIFEST_NAME, 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sigFileSigners.remove(JarFile.MANIFEST_NAME)); 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static class VerifierStream extends java.io.InputStream { 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private InputStream is; 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private JarVerifier jv; 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ManifestEntryVerifier mev; 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private long numLeft; 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski VerifierStream(Manifest man, 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry je, 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InputStream is, 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarVerifier jv) throws IOException 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 4406dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath // Android changed : Added to make sure inputs are not null. This allows to 4416dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath // use is == null to detect closed verifier streams. 4426dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath if (is == null) { 4436dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath throw new NullPointerException("is == null"); 4446dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath } 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.is = is; 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.jv = jv; 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.mev = new ManifestEntryVerifier(man); 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.jv.beginEntry(je, mev); 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.numLeft = je.getSize(); 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (this.numLeft == 0) 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.jv.update(-1, this.mev); 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read() throws IOException 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 4566dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath // Android added. 4576dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath if (is == null) { 4586dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath throw new IOException("stream closed"); 4596dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath } 4606dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (numLeft > 0) { 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int b = is.read(); 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(b, mev); 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numLeft--; 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (numLeft == 0) 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(-1, mev); 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return b; 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(byte b[], int off, int len) throws IOException { 4746dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath // Android added. 4756dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath if (is == null) { 4766dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath throw new IOException("stream closed"); 4776dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath } 4786dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((numLeft > 0) && (numLeft < len)) { 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len = (int)numLeft; 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (numLeft > 0) { 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = is.read(b, off, len); 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(n, b, off, len, mev); 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numLeft -= n; 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (numLeft == 0) 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(-1, b, off, len, mev); 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (is != null) 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski is.close(); 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski is = null; 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev = null; 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv = null; 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int available() throws IOException { 5066dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath // Android added. 5076dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath if (is == null) { 5086dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath throw new IOException("stream closed"); 5096dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath } 5106dddb4c2136efba05ffc06f34e6bfed51c9f8ea1Narayan Kamath 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return is.available(); 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Extended JavaUtilJarAccess CodeSource API Support 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Map urlToCodeSourceMap = new HashMap(); 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Map signerToCodeSource = new HashMap(); 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private URL lastURL; 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Map lastURLMap; 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Create a unique mapping from codeSigner cache entries to CodeSource. 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In theory, multiple URLs origins could map to a single locally cached 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and shared JAR file although in practice there will be a single URL in use. 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private synchronized CodeSource mapSignersToCodeSource(URL url, CodeSigner[] signers) { 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map map; 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (url == lastURL) { 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski map = lastURLMap; 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski map = (Map) urlToCodeSourceMap.get(url); 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (map == null) { 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski map = new HashMap(); 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski urlToCodeSourceMap.put(url, map); 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastURLMap = map; 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastURL = url; 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSource cs = (CodeSource) map.get(signers); 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cs == null) { 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cs = new VerifierCodeSource(csdomain, url, signers); 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signerToCodeSource.put(signers, cs); 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cs; 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private CodeSource[] mapSignersToCodeSources(URL url, List signers, boolean unsigned) { 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List sources = new ArrayList(); 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < signers.size(); i++) { 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sources.add(mapSignersToCodeSource(url, (CodeSigner[]) signers.get(i))); 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (unsigned) { 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sources.add(mapSignersToCodeSource(url, null)); 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (CodeSource[]) sources.toArray(new CodeSource[sources.size()]); 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private CodeSigner[] emptySigner = new CodeSigner[0]; 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Match CodeSource to a CodeSigner[] in the signer cache. 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private CodeSigner[] findMatchingSigners(CodeSource cs) { 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cs instanceof VerifierCodeSource) { 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski VerifierCodeSource vcs = (VerifierCodeSource) cs; 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (vcs.isSameDomain(csdomain)) { 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((VerifierCodeSource) cs).getPrivateSigners(); 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In practice signers should always be optimized above 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * but this handles a CodeSource of any type, just in case. 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true); 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List sourceList = new ArrayList(); 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < sources.length; i++) { 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sourceList.add(sources[i]); 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int j = sourceList.indexOf(cs); 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (j != -1) { 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSigner[] match; 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski match = ((VerifierCodeSource) sourceList.get(j)).getPrivateSigners(); 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (match == null) { 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski match = emptySigner; 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return match; 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Instances of this class hold uncopied references to internal 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * signing data that can be compared by object reference identity. 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class VerifierCodeSource extends CodeSource { 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URL vlocation; 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSigner[] vsigners; 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski java.security.cert.Certificate[] vcerts; 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object csdomain; 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski VerifierCodeSource(Object csdomain, URL location, CodeSigner[] signers) { 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(location, signers); 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.csdomain = csdomain; 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlocation = location; 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vsigners = signers; // from signerCache 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski VerifierCodeSource(Object csdomain, URL location, java.security.cert.Certificate[] certs) { 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(location, certs); 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.csdomain = csdomain; 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vlocation = location; 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vcerts = certs; // from signerCache 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All VerifierCodeSource instances are constructed based on 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * singleton signerCache or signerCacheCert entries for each unique signer. 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * No CodeSigner<->Certificate[] conversion is required. 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * We use these assumptions to optimize equality comparisons. 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean equals(Object obj) { 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj == this) { 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (obj instanceof VerifierCodeSource) { 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski VerifierCodeSource that = (VerifierCodeSource) obj; 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Only compare against other per-signer singletons constructed 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on behalf of the same JarFile instance. Otherwise, compare 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * things the slower way. 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isSameDomain(that.csdomain)) { 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (that.vsigners != this.vsigners 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || that.vcerts != this.vcerts) { 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (that.vlocation != null) { 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return that.vlocation.equals(this.vlocation); 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (this.vlocation != null) { 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this.vlocation.equals(that.vlocation); 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { // both null 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.equals(obj); 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isSameDomain(Object csdomain) { 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this.csdomain == csdomain; 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private CodeSigner[] getPrivateSigners() { 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return vsigners; 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private java.security.cert.Certificate[] getPrivateCertificates() { 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return vcerts; 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Map signerMap; 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private synchronized Map signerMap() { 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signerMap == null) { 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Snapshot signer state so it doesn't change on us. We care 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * only about the asserted signatures. Verification of 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * signature validity happens via the JarEntry apis. 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signerMap = new HashMap(verifiedSigners.size() + sigFileSigners.size()); 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signerMap.putAll(verifiedSigners); 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signerMap.putAll(sigFileSigners); 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return signerMap; 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized Enumeration<String> entryNames(JarFile jar, final CodeSource[] cs) { 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Map map = signerMap(); 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Iterator itor = map.entrySet().iterator(); 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean matchUnsigned = false; 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Grab a single copy of the CodeSigner arrays. Check 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to see if we can optimize CodeSigner equality test. 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List req = new ArrayList(cs.length); 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < cs.length; i++) { 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSigner[] match = findMatchingSigners(cs[i]); 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (match != null) { 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (match.length > 0) { 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski req.add(match); 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski matchUnsigned = true; 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final List signersReq = req; 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Enumeration enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration; 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new Enumeration<String>() { 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name; 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name != null) { 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (itor.hasNext()) { 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map.Entry e = (Map.Entry) itor.next(); 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signersReq.contains((CodeSigner[]) e.getValue())) { 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = (String) e.getKey(); 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (enum2.hasMoreElements()) { 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = (String) enum2.nextElement(); 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String nextElement() { 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasMoreElements()) { 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String value = name; 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = null; 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return value; 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Like entries() but screens out internal JAR mechanism entries 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and includes signed entries with no ZIP data. 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration e) { 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Map map = new HashMap(); 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski map.putAll(signerMap()); 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Enumeration enum_ = e; 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new Enumeration<JarEntry>() { 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Enumeration signers = null; 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry entry; 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (entry != null) { 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (enum_.hasMoreElements()) { 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry ze = (ZipEntry) enum_.nextElement(); 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.isSigningRelated(ze.getName())) { 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entry = jar.newEntry(ze); 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signers == null) { 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signers = Collections.enumeration(map.keySet()); 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (signers.hasMoreElements()) { 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = (String) signers.nextElement(); 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entry = jar.newEntry(new ZipEntry(name)); 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Any map entries left? 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarEntry nextElement() { 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasMoreElements()) { 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry je = entry; 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski map.remove(je.getName()); 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entry = null; 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return je; 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Enumeration emptyEnumeration = new Enumeration<String>() { 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String nextElement() { 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // true if file is part of the signature mechanism itself 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static boolean isSigningRelated(String name) { 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = name.toUpperCase(Locale.ENGLISH); 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!name.startsWith("META-INF/")) { 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = name.substring(9); 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.indexOf('/') != -1) { 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.endsWith(".DSA") 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || name.endsWith(".RSA") 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || name.endsWith(".SF") 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || name.endsWith(".EC") 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || name.startsWith("SIG-") 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || name.equals("MANIFEST.MF")) { 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Enumeration<String> unsignedEntryNames(JarFile jar) { 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Map map = signerMap(); 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Enumeration entries = jar.entries(); 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new Enumeration<String>() { 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name; 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Grab entries from ZIP directory but screen out 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * metadata. 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name != null) { 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (entries.hasMoreElements()) { 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String value; 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry e = (ZipEntry) entries.nextElement(); 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = e.getName(); 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (e.isDirectory() || isSigningRelated(value)) { 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (map.get(value) == null) { 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = value; 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String nextElement() { 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasMoreElements()) { 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String value = name; 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = null; 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return value; 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private List jarCodeSigners; 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private synchronized List getJarCodeSigners() { 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSigner[] signers; 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jarCodeSigners == null) { 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HashSet set = new HashSet(); 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.addAll(signerMap().values()); 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jarCodeSigners = new ArrayList(); 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jarCodeSigners.addAll(set); 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jarCodeSigners; 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized CodeSource[] getCodeSources(JarFile jar, URL url) { 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean hasUnsigned = unsignedEntryNames(jar).hasMoreElements(); 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return mapSignersToCodeSources(url, getJarCodeSigners(), hasUnsigned); 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CodeSource getCodeSource(URL url, String name) { 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSigner[] signers; 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signers = (CodeSigner[]) signerMap().get(name); 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return mapSignersToCodeSource(url, signers); 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CodeSource getCodeSource(URL url, JarFile jar, JarEntry je) { 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSigner[] signers; 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return mapSignersToCodeSource(url, getCodeSigners(jar, je)); 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void setEagerValidation(boolean eager) { 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski eagerValidation = eager; 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized List getManifestDigests() { 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableList(manifestDigests); 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static CodeSource getUnsignedCS(URL url) { 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new VerifierCodeSource(null, url, (java.security.cert.Certificate[]) null); 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 905