derinputstream.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 583 行 · 第 1/2 页
JAVA
583 行
return readVector(startLen); } /** * Return a set of encoded entities. ASN.1 sets are unordered, * though DER may specify an order for some kinds of sets (such * as the attributes in an X.500 relative distinguished name) * to facilitate binary comparisons of encoded values. * * @param startLen guess about how large the set will be * (used to initialize an auto-growing data structure) * @param implicit if true tag is assumed implicit. * @return array of the values in the sequence */ public DerValue[] getSet(int startLen, boolean implicit) throws IOException { tag = (byte)buffer.read(); if (!implicit) { if (tag != DerValue.tag_Set) { throw new IOException("Set tag error"); } } return (readVector(startLen)); } /* * Read a "vector" of values ... set or sequence have the * same encoding, except for the initial tag, so both use * this same helper routine. */ protected DerValue[] readVector(int startLen) throws IOException { DerInputStream newstr; byte lenByte = (byte)buffer.read(); int len = getLength((lenByte & 0xff), buffer); if (len == -1) { // indefinite length encoding found int readLen = buffer.available(); int offset = 2; // for tag and length bytes byte[] indefData = new byte[readLen + offset]; indefData[0] = tag; indefData[1] = lenByte; DataInputStream dis = new DataInputStream(buffer); dis.readFully(indefData, offset, readLen); dis.close(); DerIndefLenConverter derIn = new DerIndefLenConverter(); buffer = new DerInputBuffer(derIn.convert(indefData)); if (tag != buffer.read()) { throw new IOException("Indefinite length encoding" + " not supported"); } len = DerInputStream.getLength(buffer); } if (len == 0) // return empty array instead of null, which should be // used only for missing optionals return new DerValue[0]; /* * Create a temporary stream from which to read the data, * unless it's not really needed. */ if (buffer.available() == len) { newstr = this; } else { newstr = subStream(len, true); } /* * Pull values out of the stream. */ Vector vec = new Vector(startLen); DerValue value; do { value = new DerValue(newstr.buffer); vec.addElement(value); } while (newstr.available() > 0); if (newstr.available() != 0) { throw new IOException("extra data at end of vector"); } /* * Now stick them into the array we're returning. */ int i, max = vec.size(); DerValue[] retval = new DerValue[max]; for (i = 0; i < max; i++) { retval[i] = (DerValue)vec.elementAt(i); } return retval; } /** * Get a single DER-encoded value from the input stream. * It can often be useful to pull a value from the stream * and defer parsing it. For example, you can pull a nested * sequence out with one call, and only examine its elements * later when you really need to. */ public DerValue getDerValue() throws IOException { return new DerValue(buffer); } /** * Read a string that was encoded as a UTF8String DER value. */ public String getUTF8String() throws IOException { return readString(DerValue.tag_UTF8String, "UTF-8", "UTF-8"); } /** * Read a string that was encoded as a PrintableString DER value. */ public String getPrintableString() throws IOException { return readString(DerValue.tag_PrintableString, "Printable", "US_ASCII"); } /** * Read a string that was encoded as a T61String DER value. */ public String getT61String() throws IOException { /* * Works for common characters between T61 and ASCII. */ return readString(DerValue.tag_T61String, "T61", "ISO-8859-1"); } /** * Read a string that was encoded as a IA5tring DER value. */ public String getIA5String() throws IOException { return readString(DerValue.tag_IA5String, "IA5", "US_ASCII"); } /** * Read a string that was encoded as a BMPString DER value. */ public String getBMPString() throws IOException { return readString(DerValue.tag_BMPString, "BMP", "UnicodeBigUnmarked"); } /** * Read a string that was encoded as a GeneralString DER value. */ public String getGeneralString() throws IOException { return readString(DerValue.tag_GeneralString, "General", "US_ASCII"); } /** * Private helper routine to read an encoded string from the input * stream. * @param stringTag the tag for the type of string to read * @param stringName a name to display in error messages * @param enc the encoder to use to interpret the data. Should * correspond to the stringTag above. */ private String readString(byte stringTag, String stringName, String enc) throws IOException { if (buffer.read() != stringTag) { throw new IOException("DER input not a " + stringName + " string"); } int length = getLength(buffer); byte[] retval = new byte[length]; if ((length != 0) && (buffer.read(retval) != length)) { throw new IOException("short read of DER " + stringName + " string"); } return new String(retval, enc); } /** * Get a UTC encoded time value from the input stream. */ public Date getUTCTime() throws IOException { if (buffer.read() != DerValue.tag_UtcTime) { throw new IOException("DER input, UTCtime tag invalid "); } return buffer.getUTCTime(getLength(buffer)); } /** * Get a Generalized encoded time value from the input stream. */ public Date getGeneralizedTime() throws IOException { if (buffer.read() != DerValue.tag_GeneralizedTime) { throw new IOException("DER input, GeneralizedTime tag invalid "); } return buffer.getGeneralizedTime(getLength(buffer)); } /* * Get a byte from the input stream. */ // package private int getByte() throws IOException { return (0x00ff & buffer.read()); } public int peekByte() throws IOException { return buffer.peek(); } // package private int getLength() throws IOException { return getLength(buffer); } /* * Get a length from the input stream, allowing for at most 32 bits of * encoding to be used. (Not the same as getting a tagged integer!) * * @return the length or -1 if indefinite length found. * @exception IOException on parsing error or unsupported lengths. */ static int getLength(InputStream in) throws IOException { return getLength(in.read(), in); } /** * Get a length from the input stream, allowing for at most 32 bits of * encoding to be used. (Not the same as getting a tagged integer!) * * @return the length or -1 if indefinite length found. * @exception IOException on parsing error or unsupported lengths. */ static int getLength(int lenByte, InputStream in) throws IOException { int value, tmp; tmp = lenByte; if ((tmp & 0x080) == 0x00) { // short form, 1 byte datum value = tmp; } else { // long form or indefinite tmp &= 0x07f; /* * NOTE: tmp == 0 indicates indefinite length encoded data. * tmp > 4 indicates more than 4Gb of data. */ if (tmp == 0) { return -1; } if (tmp < 0 || tmp > 4) { throw new IOException("DerInputStream.getLength(): lengthTag=" + tmp + ", " + ((tmp < 0) ? "incorrect DER encoding." : "too big.")); } for (value = 0; tmp > 0; tmp --) { value <<= 8; value += 0x0ff & in.read(); } } return value; } /** * Mark the current position in the buffer, so that * a later call to <code>reset</code> will return here. */ public void mark(int value) { buffer.mark(value); } /** * Return to the position of the last <code>mark</code> * call. A mark is implicitly set at the beginning of * the stream when it is created. */ public void reset() { buffer.reset(); } /** * Returns the number of bytes available for reading. * This is most useful for testing whether the stream is * empty. */ public int available() { return buffer.available(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?