manifestdigester.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 257 行

JAVA
257
字号
/* * @(#)ManifestDigester.java	1.21 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package sun.security.util;import java.security.*;import java.util.HashMap;/** * This class is used to compute digests on sections of the Manifest. */public class ManifestDigester {    /** the raw bytes of the manifest */    byte rawBytes[];    /** the offset/length pair for a section */    HashMap entries;    /** state returned by findSection */    static class Position {	int endOfFirstLine; // not including newline character	int endOfSection; // end of section, not including the blank line			  // between sections	int startOfNext;  // the start of the next section    }    /**     * find a section in the manifest.     *     * @param offset should point to the starting offset with in the     * raw bytes of the next section.     *     * @pos set by     *     * @returns false if end of bytes has been reached, otherwise returns     *          true     */    private boolean findSection(int offset, Position pos)    {	int i = offset, len = rawBytes.length;	int last = offset;	int next;	boolean allBlank = true;	pos.endOfFirstLine = -1;	while (i < len) {	    byte b = rawBytes[i];	    switch(b) {	    case '\r':		if (pos.endOfFirstLine == -1)		    pos.endOfFirstLine = i-1;		if ((i < len) &&  (rawBytes[i+1] == '\n'))		    i++;	    case '\n':		if (pos.endOfFirstLine == -1)		    pos.endOfFirstLine = i-1;		if (allBlank || (i == len-1)) {		    if (i == len-1)			pos.endOfSection = i;		    else			pos.endOfSection = last;		    pos.startOfNext = i+1;		    return true;		}		else {		    // start of a new line		    last = i;		    allBlank = true;		}		break;	    default:		allBlank = false;		break;	    }	    i++;	}	return false;    }    public ManifestDigester(byte bytes[])    {	rawBytes = bytes;	entries = new HashMap();	// first skip the main attributes	Position pos = new Position();	if (!findSection(0, pos))	    return; // exception?	int start = pos.startOfNext;	while(findSection(start, pos)) {	    int len = pos.endOfFirstLine-start+1;	    int sectionLen = pos.endOfSection-start+1;	    int sectionLenWithBlank = pos.startOfNext-start;	    if (len > 6) {		if (isNameAttr(bytes, start)) {		    StringBuffer nameBuf = new StringBuffer();		    nameBuf.append(new String(bytes, start+6, len-6));		    int i = start + len;		    if ((i-start) < sectionLen) {			if (bytes[i] == '\r') {			    i += 2;			} else {			    i += 1;			}		    }		    while ((i-start) < sectionLen) {			if (bytes[i++] == ' ') {			    // name is wrapped			    int wrapStart = i;			    while (((i-start) < sectionLen)				   && (bytes[i++] != '\n'));			    if (bytes[i-1] != '\n')				return; // exception?			    int wrapLen;			    if (bytes[i-2] == '\r')				wrapLen = i-wrapStart-2;			    else				wrapLen = i-wrapStart-1;			    nameBuf.append(new String(bytes, wrapStart,						      wrapLen));			} else {			    break;			}		    }		    String name = nameBuf.toString();		    entries.put(name, new Entry(start, sectionLen,						sectionLenWithBlank,						rawBytes));		}	    }	    start = pos.startOfNext;	}    }    private boolean isNameAttr(byte bytes[], int start)    {	return ((bytes[start] == 'N') || (bytes[start] == 'n')) &&               ((bytes[start+1] == 'a') || (bytes[start+1] == 'A')) &&               ((bytes[start+2] == 'm') || (bytes[start+2] == 'M')) &&               ((bytes[start+3] == 'e') || (bytes[start+3] == 'E')) &&               (bytes[start+4] == ':') &&               (bytes[start+5] == ' ');    }    public static class Entry {	int offset;	int length;	int lengthWithBlankLine;	byte[] rawBytes;	boolean oldStyle;	public Entry(int offset, int length,		     int lengthWithBlankLine, byte[] rawBytes)	{	    this.offset = offset;	    this.length = length;	    this.lengthWithBlankLine = lengthWithBlankLine;	    this.rawBytes = rawBytes;	}	public byte[] digest(MessageDigest md)	{	    md.reset();	    if (oldStyle) {		doOldStyle(md,rawBytes, offset, lengthWithBlankLine);	    } else {		md.update(rawBytes, offset, lengthWithBlankLine);	    }	    return md.digest();	}	private void doOldStyle(MessageDigest md,				byte[] bytes,				int offset,				int length)	{	    // this is too gross to even document, but here goes	    // the 1.1 jar verification code ignored spaces at the	    // end of lines when calculating digests, so that is	    // what this code does. It only gets called if we	    // are parsing a 1.1 signed signature file	    int i = offset;	    int start = offset;	    int max = offset + length;	    int prev = -1;	    while(i <max) {		if ((bytes[i] == '\r') && (prev == ' ')) {		    md.update(bytes, start, i-start-1);		    start = i;		}		prev = bytes[i];		i++;	    }	    md.update(bytes, start, i-start);	}	/** Netscape doesn't include the new line. Others do. */	public byte[] digestWorkaround(MessageDigest md)	{	    md.reset();	    md.update(rawBytes, offset, length);	    return md.digest();	}    }    public Entry get(String name, boolean oldStyle) {	Entry e = (Entry)  entries.get(name);	if (e != null)	    e.oldStyle = oldStyle;	return e;    }    public byte[] manifestDigest(MessageDigest md)	{	    md.reset();	    md.update(rawBytes, 0, rawBytes.length);	    return md.digest();	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?