📄 derdecoder.java
字号:
}
// ASN1InputStream abstract methods implementation
// ........................................................................
/**
* Initialises this instance to decode from the designated input stream.
*
* @param is the designated input stream to decode.
* @exception IllegalStateException if this instance is already initialised
* with an input stream. Caller should close the previous stream before
* invoking this method again on a new input stream.
*/
public void open(InputStream is) {
if (in != null)
throw new IllegalStateException();
this.in = is instanceof BufferedInputStream
? (BufferedInputStream) is
: new BufferedInputStream(is, 10240);
}
/**
* Decodes an ANY from the input stream.
*
* @param name the optional user-defined ASN.1 type name.
* @return the concrete object decoded from the underlying input stream.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public IType decodeAny(String name) throws IOException {
cat.debug("==> decodeAny("+name+")");
Tag tag = null;
try {
tag = readTag();
} catch (EOFException x) {
throw new ElementNotFoundException("???");
}
int length = readLength();
byte[] buffer = new byte[length];
int actualLength = read(buffer);
if (actualLength == -1)
throw new EOFException();
if (actualLength != length)
throw new DerLengthMismatchException(actualLength, length);
IType result = null;
ArrayList values;
DerDecoder local;
if (tag.getClazz() == Tag.UNIVERSAL)
switch (tag.getValue()) {
case Tag.BOOLEAN:
result = new ASNBoolean(name, tag, toBoolean(buffer));
break;
case Tag.INTEGER:
result = new ASNInteger(name, tag, new BigInteger(1, buffer));
break;
case Tag.BIT_STRING:
result = new BitString(name, tag, buffer);
break;
case Tag.OCTET_STRING:
result = new OctetString(name, tag, buffer);
break;
case Tag.NULL:
toNull(buffer); // throws an exception if malformed
result = new Null(name, tag, new Object());
break;
case Tag.OBJECT_IDENTIFIER:
result = new ObjectIdentifier(name, tag, toOID(buffer));
break;
case Tag.NUMERIC_STRING:
result = new NumericString(name, tag, new String(buffer, "ASCII"));
break;
case Tag.PRINTABLE_STRING:
result = new PrintableString(name, tag, new String(buffer, "ASCII"));
break;
case Tag.T61_STRING:
result = new TeletexString(name, tag, new String(buffer, "ASCII"));
break;
case Tag.VIDEOTEX_STRING:
result = new VideotexString(name, tag, new String(buffer, "ASCII"));
break;
case Tag.IA5_STRING:
result = new IA5String(name, tag, new String(buffer, "ASCII"));
break;
case Tag.GRAPHIC_STRING:
result = new GraphicString(name, tag, new String(buffer, "UTF8"));
break;
case Tag.ISO646_STRING:
result = new VisibleString(name, tag, new String(buffer, "UTF8"));
break;
case Tag.GENERAL_STRING:
result = new GeneralString(name, tag, new String(buffer, "UTF8"));
break;
case Tag.UNIVERSAL_STRING:
result = new UniversalString(name, tag, new String(buffer, "UTF8"));
break;
case Tag.BMP_STRING:
result = new BMPString(name, tag, new String(buffer, "UTF8"));
break;
case Tag.UTC_TIME:
result = new UTCTime(name, tag, toDate(buffer));
break;
case Tag.GENERALIZED_TIME:
result = new GeneralizedTime(name, tag, toFullDate(buffer));
break;
case Tag.SEQUENCE:
// case Tag.SEQUENCE_OF:
case Tag.SET:
// case Tag.SET_OF:
values = new ArrayList();
local = new DerDecoder(buffer);
try {
while (true)
values.add(local.decodeAny("seq"));
} catch (IOException ignored) {
}
result = new Any(name, tag, values);
break;
default:
cat.warn("Unable to parse an ANY; tag="+String.valueOf(tag));
result = new Any(name, tag, buffer);
}
else if (tag.getClazz() == Tag.CONTEXT) {
if (tag.isExplicit()) {
// buffer contains a DER triplet (TLV)
DerDecoder embedded = new DerDecoder(buffer);
result = new Any(name, tag, embedded.decodeAny("xxx"));
// result = new Any(name, tag, embedded.decodeAny("xxx").getValue());
} else {
// buffer contains a DER value as a byte[]
result = new Any(name, tag, buffer);
}
} else
result = new Any(name, tag, buffer);
cat.debug("<== decodeAny() --> "+result);
return result;
}
/**
* Decodes an OBJECT IDENTIFIER from the input stream.
*
* @param obj the element to decode.
* @return a String representation of the OID decoded from the stream.
* @exception TagMismatchException if the element in the stream has a
* different tag to the designated one.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public String decodeObjectIdentifier(IType obj) throws IOException {
cat.debug("==> decodeObjectIdentifier()");
Tag tag = obj.tag();
byte[] buffer = readRaw(tag, Tag.OBJECT_IDENTIFIER);
String result = toOID(buffer);
cat.debug("<== decodeObjectIdentifier() --> "+result);
return result;
}
/**
* Decodes a NULL from the input stream.
*
* @param obj the element to decode.
* @exception TagMismatchException if the element in the stream has a
* different tag to the designated one.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception DerInvalidLengthException if a mismatch between the expected
* and parsed size of the element's encoding is detected.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public void decodeNull(IType obj) throws IOException {
cat.debug("==> decodeNull()");
Tag tag = obj.tag();
byte[] buffer = readRaw(tag, Tag.NULL);
toNull(buffer);
cat.debug("<== decodeNull()");
}
/**
* Decodes a BOOLEAN from the input stream.
*
* @param obj the element to decode.
* @return the concrete value of this ASN.1 type.
* @exception TagMismatchException if the element in the stream has a
* different tag to the designated one.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception DerInvalidLengthException if a mismatch between the expected
* and parsed size of the element's encoding is detected.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public Boolean decodeBoolean(IType obj) throws IOException {
cat.debug("==> decodeBoolean()");
Tag tag = obj.tag();
byte[] buffer = readRaw(tag, Tag.BOOLEAN);
Boolean result = toBoolean(buffer);
cat.debug("<== decodeBoolean() --> "+result);
return result;
}
/**
* Decodes an INTEGER from the input stream.
*
* @param obj the element to decode.
* @return the concrete value of this ASN.1 type.
* @exception TagMismatchException if the element in the stream has a
* different tag to the designated one.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception DerInvalidLengthException if a mismatch between the expected
* and parsed size of the element's encoding is detected.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public BigInteger decodeInteger(IType obj) throws IOException {
cat.debug("==> decodeInteger()");
Tag tag = obj.tag();
byte[] buffer = readRaw(tag, Tag.INTEGER);
BigInteger result = new BigInteger(1, buffer);
cat.debug("<== decodeInteger() --> "+result);
return result;
}
/**
* Decodes a PrintableString from the input stream.
*
* @param tagValue the value of a Tag constant to differentiate between
* the different types of strings.
* @param obj the element to decode.
* @return the concrete value of this ASN.1 type.
* @exception TagMismatchException if the element in the stream has a
* different tag to the designated one.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception DerInvalidLengthException if a mismatch between the expected
* and parsed size of the element's encoding is detected.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public String decodeString(int tagValue, IType obj) throws IOException {
cat.debug("==> decodeString("+tagValue+")");
Tag tag = obj.tag();
byte[] buffer = readRaw(tag, tagValue);
String result = new String(buffer, "UTF8");
cat.debug("<== decodeString() --> \""+result+"\"");
return result;
}
/**
* Decodes a BIT STRING from the input stream.
*
* @param obj the element to decode.
* @return the concrete value of this ASN.1 type.
* @exception TagMismatchException if the element in the stream has a
* different tag to the designated one.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception DerInvalidLengthException if a mismatch between the expected
* and parsed size of the element's encoding is detected.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public byte[] decodeBitString(IType obj) throws IOException {
cat.debug("==> decodeBitString()");
Tag tag = obj.tag();
byte[] tmp = readRaw(tag, Tag.BIT_STRING);
cat.warn("Truncating "+String.valueOf(tmp[0])+" unused leftmost bit(s) from a BIT STRING");
byte[] result = new byte[tmp.length-1];
System.arraycopy(tmp, 1, result, 0, result.length);
cat.debug("<== decodeBitString() --> 0x"+(new BigInteger(1, result).toString(16)));
return result;
}
/**
* Decodes an OCTET STRING from the input stream.
*
* @param obj the element to decode.
* @return the concrete value of this ASN.1 type.
* @exception TagMismatchException if the element in the stream has a
* different tag to the designated one.
* @exception DerObjectTooLargeException if the DER value of the length part
* exceeds 32-bit.
* @exception DerInvalidLengthException if a mismatch between the expected
* and parsed size of the element's encoding is detected.
* @exception EOFException if the end-of-stream was encountered while
* decoding the element.
* @exception IOException if any other I/O related exception has occured.
*/
public byte[] decodeOctetString(IType obj) throws IOException {
cat.debug("==> decodeOctetString()");
Tag tag = obj.tag();
byte[] result = readRaw(tag, Tag.OCTET_STRING);
cat.debug("<== decodeOctetString() --> 0x"+(new BigInteger(1, result).toString(16)));
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -