📄 dercoder.java
字号:
}
offset = encodeLength(content.length, stream, offset);
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes NULL.
*/
private int encodeNULL(ASN1Object o, byte [] stream, int offset)
{
stream[offset++] = 0;
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes ContextSpecific.
*/
private int encodeCONTEXT(ASN1Object o, byte [] stream, int offset)
throws ASN1Exception
{
ASN1Object v = (ASN1Object) (o.getValue());
int start = offset;
//System.out.println("TYPE:" + v.getASN1Type().getName());
if (o.implicit())
{
if ((o.getTag() & 0x20) == 0)
{
byte[] data = null;
if ( v.getASN1Type().equals(ASN1Type.BOOLEAN))
{
boolean b = ((Boolean) v.getValue()).booleanValue();
stream[offset++] = (byte) (b?1:0);
stream[offset++] = 1;
}
if ( v.getASN1Type().equals(ASN1Type.OCTET_STRING))
{
data = (byte []) (v.getValue());
for (int i = data.length - 1; i >= 0; i--)
{
stream[offset++] = data[i];
}
offset = encodeLength(data.length, stream, offset);
}
if ( v.getASN1Type().equals(ASN1Type.IA5String))
{
String s = (String) (v.getValue());
data = s.getBytes();
for (int i = data.length - 1; i >= 0; i--)
{
stream[offset++] = data[i];
}
offset = encodeLength(data.length, stream, offset);
}
if ( v.getASN1Type().equals(ASN1Type.INTEGER))
{
BigInteger tmp = (BigInteger) v.getValue();
data = tmp.toByteArray();
for (int i = data.length - 1; i >= 0; i--)
{
stream[offset++] = data[i];
}
offset = encodeLength(data.length, stream, offset);
}
if (v.getASN1Type().equals(ASN1Type.UTCTime))
{
String time = (String) (v.getValue());
//System.out.println("time:" + time);
byte [] t = time.getBytes();
for (int i = t.length - 1; i >= 0; i--)
{
stream[offset++] = t[i];
}
offset = encodeLength(t.length, stream, offset);
} // End of IF ... UTCTime
if ( v.getASN1Type().equals(ASN1Type.GENERALIZEDTIME))
{
String time = (String) (v.getValue());
//System.out.println("time:" + time);
byte [] t = time.getBytes();
for (int i = t.length - 1; i >= 0; i--)
{
stream[offset++] = t[i];
}
offset = encodeLength(t.length, stream, offset);
}
if ( v.getASN1Type().equals(ASN1Type.BIT_STRING))
{
byte [] content = (byte []) (v.getValue());
for (int i = content.length - 1; i >= 0; i--)
{
stream[offset++] = content[i];
}
stream[offset++] = 0;
offset = encodeLength(content.length + 1, stream, offset);
}
if ( v.getASN1Type().equals(ASN1Type.ENUMERATED))
{
BigInteger tmp = (BigInteger) v.getValue();
data = tmp.toByteArray();
for (int i = data.length - 1; i >= 0; i--)
{
stream[offset++] = data[i];
}
offset = encodeLength(data.length, stream, offset);
}
if ( v.getASN1Type().equals(ASN1Type.OBJECT_ID))
{
String id = (String) (v.getValue());
StringTokenizer st = new StringTokenizer(id, " ");
String [] subid = new String[st.countTokens()];
//start = offset;
for (int i = 0; i < subid.length; i++)
{
subid[i] = st.nextToken();
}
for (int i = subid.length - 1; i > 1; i--)
{
long s = Long.parseLong(subid[i]);
stream[offset++] = (byte) (s & 0x7f);
s >>>= 7;
while (s != 0)
{
stream[offset++] = (byte) (s | 0x80);
s >>>= 7;
}
}
long l = Long.parseLong(subid[0]) * 40 + Long.parseLong(subid[1]);
stream[offset++] = (byte) l;
offset = encodeLength(offset - start, stream, offset);
//stream[offset++] = (byte) o.getASN1Type().getTag();
//return offset;
}
if ( (v.getASN1Type().equals(ASN1Type.SEQUENCE)== true) ||
( v.getASN1Type().equals(ASN1Type.SET) == true) )
{
start = offset;
//System.out.println("SIZE:" + v.size());
for (int i = v.size() - 1; i >= 0; i--)
{
offset = encode(v.getComponent(i), stream, offset);
}
offset = encodeLength(offset - start, stream, offset);
stream[offset++] = (byte) (0xa0 | o.getTag());
return offset;
} // End of IF ... sequence
stream[offset++] = (byte) (0x80 | o.getTag()); // For all other types
}
else
{
offset = encode(v, stream, offset);
stream[offset - 1] = (byte) (0xa0 | o.getTag());
}
}
else
{
offset = encode(v, stream, offset);
offset = encodeLength(offset - start, stream, offset);
stream[offset++] = (byte) (0xa0 | o.getTag());
}
return offset;
}
/********************************/
/* DER Decoding */
/********************************/
/**
* DER decoding -- decodes a byte array to an ASN1Object
* @param buffer the byte array to be decoded
* @return the decoded ASN1Object
* @exception iss.security.asn1.ASN1Exception if any error
* occurred in the decoding process
*/
public ASN1Object decode(byte [] buffer)
throws ASN1Exception
{
int [] offset = new int [1];
offset[0] = 0;
return decode(buffer, offset);
}
/**
* DER decoding -- decodes a byte array to an ASN1Object
* @param buffer the byte array to be decoded
* @param offset the starting index of the buffer
* @return the decoded ASN1Object
* @exception iss.security.asn1.ASN1Exception if any error
* occurred in the decoding process
*/
public ASN1Object decode(byte [] buffer, int [] offset)
throws ASN1Exception
{
int start = offset[0];
int tag = buffer[offset[0]++];
int oldTag = 0;
if ((tag & 0x80) != 0 && (tag & 0x40) == 0)
{// context-specific tag
oldTag = tag;
tag = 0x80;
}
ASN1Type type = new ASN1Type(tag);
ASN1Object object = ASN1Object.create(type);
int length = decodeLength(buffer, offset);
if (length < 0 && length != -1)
{
throw new ASN1Exception(
"Invalid object length (" + length + ")");
}
switch (tag)
{
case 1:
decodeBOOLEAN(object, buffer, offset, length);
break;
case 2:
decodeINTEGER(object, buffer, offset, length);
break;
case 3:
decodeBITSTRING(object, buffer, offset, length);
break;
case 4:
decodeOCTETSTRING(object, buffer, offset, length);
break;
case 5:
decodeNULL(object, buffer, offset, length);
break;
case 6:
decodeOBJECTID(object, buffer, offset, length);
break;
case 10:
decodeENUMERATED(object, buffer, offset, length);
break;
case 19:
decodePrintableString(object, buffer, offset, length);
break;
case 20:
// case 20: decodeT61String(object, buffer, offset, length);
// break;
case 22:
decodeIA5String(object, buffer, offset, length);
break;
case 23:
decodeUTCTime(object, buffer, offset, length);
break;
case 24:
decodeGeneralizedTime(object, buffer, offset, length);
break;
case 28:
decodeUniversalString(object, buffer, offset, length);
break;
case 30:
decodeBMPSTRING(object, buffer, offset, length);
break;
case 48:
case 49:
decodeSEQUENCE(object, buffer, offset, length);
break;
// case 49: decodeSET(object, buffer, offset, length);
// break;
case 128:
decodeCONTEXT(object, buffer, offset, length, oldTag);
break;
default:
throw new ASN1Exception("Unknow ASN.1 tag --" + tag);
}
// offset[0] = offset[0] + length;
byte [] der = new byte[offset[0]-start];
System.arraycopy(buffer, start, der, 0, offset[0] - start);
object.setByteArray(der);
return object;
}
/**
* Decodes the length.
*/
private int decodeLength(byte [] stream, int [] offset)
throws ASN1Exception
{
int length = stream[offset[0]++] & 0xff;
if ((length & 0x80) != 0)
{
int count = length & 0x7f;
if (count > 4)
{
throw new ASN1Exception("ASN.1 Object too large");
}
if (count == 0)
{ // indefinite length
return -1;
}
length = stream[offset[0]++] & 0xff;
for (int i = 1; i < count; i++)
{
length <<= 8;
length |= (stream[offset[0]++] & 0xff);
}
}
return length;
}
/**
* Decodes BOOLEAN. Definite-length only.
*/
private void decodeBOOLEAN(ASN1Object o, byte [] stream, int [] offset,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -