151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.security.util; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.*; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.HashMap; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.ByteArrayOutputStream; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class is used to compute digests on sections of the Manifest. 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class ManifestDigester { 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String MF_MAIN_ATTRS = "Manifest-Main-Attributes"; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** the raw bytes of the manifest */ 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte rawBytes[]; 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** the offset/length pair for a section */ 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private HashMap<String, Entry> entries; // key is a UTF-8 string 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** state returned by findSection */ 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static class Position { 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int endOfFirstLine; // not including newline character 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int endOfSection; // end of section, not including the blank line 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // between sections 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int startOfNext; // the start of the next section 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * find a section in the manifest. 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param offset should point to the starting offset with in the 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * raw bytes of the next section. 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @pos set by 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @returns false if end of bytes has been reached, otherwise returns 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * true 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean findSection(int offset, Position pos) 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = offset, len = rawBytes.length; 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int last = offset; 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int next; 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean allBlank = true; 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.endOfFirstLine = -1; 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (i < len) { 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte b = rawBytes[i]; 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch(b) { 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '\r': 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pos.endOfFirstLine == -1) 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.endOfFirstLine = i-1; 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((i < len) && (rawBytes[i+1] == '\n')) 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i++; 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case '\n': 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (pos.endOfFirstLine == -1) 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.endOfFirstLine = i-1; 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (allBlank || (i == len-1)) { 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i == len-1) 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.endOfSection = i; 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.endOfSection = last; 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos.startOfNext = i+1; 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else { 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // start of a new line 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski last = i; 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski allBlank = true; 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski allBlank = false; 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i++; 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ManifestDigester(byte bytes[]) 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rawBytes = bytes; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries = new HashMap<String, Entry>(); 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ByteArrayOutputStream baos = new ByteArrayOutputStream(); 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Position pos = new Position(); 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!findSection(0, pos)) 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; // XXX: exception? 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // create an entry for main attributes 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries.put(MF_MAIN_ATTRS, 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new Entry(0, pos.endOfSection + 1, pos.startOfNext, rawBytes)); 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int start = pos.startOfNext; 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while(findSection(start, pos)) { 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len = pos.endOfFirstLine-start+1; 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int sectionLen = pos.endOfSection-start+1; 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int sectionLenWithBlank = pos.startOfNext-start; 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (len > 6) { 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isNameAttr(bytes, start)) { 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StringBuilder nameBuf = new StringBuilder(sectionLen); 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameBuf.append( 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new String(bytes, start+6, len-6, "UTF8")); 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = start + len; 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((i-start) < sectionLen) { 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bytes[i] == '\r') { 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i += 2; 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i += 1; 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while ((i-start) < sectionLen) { 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bytes[i++] == ' ') { 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // name is wrapped 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int wrapStart = i; 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (((i-start) < sectionLen) 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski && (bytes[i++] != '\n')); 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bytes[i-1] != '\n') 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; // XXX: exception? 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int wrapLen; 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bytes[i-2] == '\r') 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski wrapLen = i-wrapStart-2; 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski wrapLen = i-wrapStart-1; 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nameBuf.append(new String(bytes, wrapStart, 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski wrapLen, "UTF8")); 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entries.put(nameBuf.toString(), 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new Entry(start, sectionLen, sectionLenWithBlank, 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rawBytes)); 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (java.io.UnsupportedEncodingException uee) { 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalStateException( 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "UTF8 not available on platform"); 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start = pos.startOfNext; 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isNameAttr(byte bytes[], int start) 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((bytes[start] == 'N') || (bytes[start] == 'n')) && 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((bytes[start+1] == 'a') || (bytes[start+1] == 'A')) && 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((bytes[start+2] == 'm') || (bytes[start+2] == 'M')) && 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((bytes[start+3] == 'e') || (bytes[start+3] == 'E')) && 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (bytes[start+4] == ':') && 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (bytes[start+5] == ' '); 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static class Entry { 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int offset; 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int length; 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lengthWithBlankLine; 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] rawBytes; 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean oldStyle; 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Entry(int offset, int length, 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lengthWithBlankLine, byte[] rawBytes) 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.offset = offset; 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.length = length; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.lengthWithBlankLine = lengthWithBlankLine; 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.rawBytes = rawBytes; 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] digest(MessageDigest md) 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.reset(); 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oldStyle) { 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski doOldStyle(md,rawBytes, offset, lengthWithBlankLine); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.update(rawBytes, offset, lengthWithBlankLine); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return md.digest(); 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void doOldStyle(MessageDigest md, 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] bytes, 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int offset, 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int length) 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this is too gross to even document, but here goes 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the 1.1 jar verification code ignored spaces at the 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // end of lines when calculating digests, so that is 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // what this code does. It only gets called if we 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // are parsing a 1.1 signed signature file 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = offset; 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int start = offset; 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int max = offset + length; 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int prev = -1; 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while(i <max) { 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((bytes[i] == '\r') && (prev == ' ')) { 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.update(bytes, start, i-start-1); 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski start = i; 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski prev = bytes[i]; 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i++; 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.update(bytes, start, i-start); 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Netscape doesn't include the new line. Intel and JavaSoft do */ 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] digestWorkaround(MessageDigest md) 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.reset(); 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.update(rawBytes, offset, length); 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return md.digest(); 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Entry get(String name, boolean oldStyle) { 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Entry e = entries.get(name); 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (e != null) 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski e.oldStyle = oldStyle; 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return e; 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public byte[] manifestDigest(MessageDigest md) 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.reset(); 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md.update(rawBytes, 0, rawBytes.length); 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return md.digest(); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 270