📄 dercoder.java
字号:
package com.ca.commons.security.asn1;
import java.math.BigInteger;
import java.util.StringTokenizer;
/**
* This class provides the facilities of encoding and decoding ASN1Objects
* using Distinguished Encoding Rules (DER). The class is only used in this
* package.
* @see iss.security.asn1.ASN1Object
*/
public class DERCoder implements java.io.Serializable
{
/**
* Default constructor.
*/
public DERCoder()
{}
/********************************/
/* DER Encoding */
/********************************/
/**
* DER encoding -- encodes an ASN1Object to a byte array
* @param input the ASN1Object to be encoded
* @return the encoded byte array
* @exception iss.security.asn1.ASN1Exception if any error
* occurred in the encoding process
*/
public byte [] encode(ASN1Object input) throws ASN1Exception
{
int length;
byte [] buffer = new byte[8192];
try
{
length = encode(input, buffer, 0);
}
catch(ArrayIndexOutOfBoundsException e)
{
throw new ASN1Exception("ASN.1 Object too big");
}
byte [] result = new byte[length];
for (int i = 0; i < length; i++)
{
result[length-i-1] = buffer[i];
}
return result;
}
/**
* DER encoding -- encodes an ASN1Object to a byte array
* @param input the ASN1Object to be encoded
* @param buffer the buffer to hold the encoded byte array
* @param offset the starting index of the buffer
* @return the length of the encoded bytes
* @exception iss.security.asn1.ASN1Exception if any error
* occurred in the encoding process
*/
public int encode(ASN1Object input, byte [] buffer, int offset)
throws ASN1Exception
{
/* call different method for different ASN.1 type */
int tag = input.getASN1Type().getTag();
switch (tag)
{
case 1:
return encodeBOOLEAN(input, buffer, offset);
case 2:
return encodeINTEGER(input, buffer, offset);
case 3:
return encodeBITSTRING(input, buffer, offset);
case 4:
return encodeOCTETSTRING(input, buffer, offset);
case 5:
return encodeNULL(input, buffer, offset);
case 6:
return encodeOBJECTID(input, buffer, offset);
case 10:
return encodeENUMERATED(input,buffer,offset);
case 19:
return encodePrintableString(input, buffer, offset);
case 20:
// case 20: return encodeT61String(input, buffer, offset);
case 22:
return encodeIA5String(input, buffer, offset);
case 23:
return encodeUTCTime(input, buffer, offset);
case 24:
return encodeGeneralizedTime(input, buffer, offset);
case 28:
return encodeUniversalString(input, buffer, offset);
case 30:
return encodeBMPSTRING(input, buffer, offset);
case 48:
case 49:
return encodeSEQUENCE((Sequence)input, buffer, offset);
// case 49: return encodeSET(input, buffer, offset);
case 128:
return encodeCONTEXT(input, buffer, offset);
}
throw new ASN1Exception(input.getASN1Type().toString() +
" -- Unknown type");
}
/**
* Encodes the length.
*/
private int encodeLength(int length, byte [] stream, int offset)
{
if (length >= 0 && length <= 127)
{
stream[offset++] = (byte) length;
}
else
{
int count = 0;
while (length != 0)
{
stream[offset++] = (byte) length;
length >>>= 8;
count++;
}
stream[offset++] = (byte) ((count)|0x80);
}
return offset;
}
/**
* Encodes BOOLEAN.
*/
private int encodeBOOLEAN(ASN1Object o, byte [] stream, int offset)
{
boolean v = ((Boolean) o.getValue()).booleanValue();
stream[offset++] = (byte) (v?1:0);
stream[offset++] = 1;
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes INTEGER.
*/
private int encodeINTEGER(ASN1Object o, byte [] stream, int offset)
{
BigInteger v = (BigInteger) (o.getValue());
byte [] content = v.toByteArray();
for (int i = content.length - 1; i >= 0; i--)
{
stream[offset++] = content[i];
}
offset = encodeLength(content.length, stream, offset);
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes ENUMERATED
*/
private int encodeENUMERATED(ASN1Object o, byte [] stream, int offset)
{
BigInteger v = (BigInteger) (o.getValue());
byte [] content = v.toByteArray();
for (int i = content.length - 1; i >= 0; i--)
{
stream[offset++] = content[i];
}
offset = encodeLength(content.length, stream, offset);
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes SEQUENCE.
*/
private int encodeSEQUENCE(ASN1Object o, byte [] stream, int offset)
throws ASN1Exception
{
int start = offset;
for (int i = o.size() - 1; i >= 0; i--)
{
offset = encode(o.getComponent(i), stream, offset);
}
offset = encodeLength(offset - start, stream, offset);
stream[offset++] = (byte) (o.getASN1Type().getTag());
return offset;
}
/**
* Encodes BITSTRING.
*/
private int encodeBITSTRING(ASN1Object o, byte [] stream, int offset)
{
byte [] content = (byte []) (o.getValue());
for (int i = content.length - 1; i >= 0; i--)
{
stream[offset++] = content[i];
}
stream[offset++] = 0;
offset = encodeLength(content.length + 1, stream, offset);
stream[offset++] = (byte) (o.getASN1Type().getTag());
return offset;
}
/**
* Encodes OCTETSTRING.
*/
private int encodeOCTETSTRING(ASN1Object o, byte [] stream, int offset)
{
byte [] content = (byte []) (o.getValue());
for (int i = content.length - 1; i >= 0;i--)
{
stream[offset++] = content[i];
}
offset = encodeLength(content.length, stream, offset);
stream[offset++] = (byte) (o.getASN1Type().getTag());
return offset;
}
/**
* Encodes UniversalString.
*/
private int encodeUniversalString(ASN1Object o, byte [] stream, int offset)
{
byte [] content = (byte []) (o.getValue());
for (int i = content.length - 1; i >= 0;i--)
{
stream[offset++] = content[i];
}
offset = encodeLength(content.length, stream, offset);
stream[offset++] = (byte) (o.getASN1Type().getTag());
return offset;
}
/**
* Encodes BMPSTRING.
*/
private int encodeBMPSTRING(ASN1Object o, byte [] stream, int offset)
{
byte [] content = (byte []) (o.getValue());
for (int i = content.length - 1; i >= 0;i--)
{
stream[offset++] = content[i];
}
offset = encodeLength(content.length, stream, offset);
stream[offset++] = (byte) (o.getASN1Type().getTag());
return offset;
}
/**
* Encodes OBJECT IDENTIFIER. OID is represented as string of fields
* seperated by space.
*/
private int encodeOBJECTID(ASN1Object o, byte [] stream, int offset)
{
String id = (String) (o.getValue());
StringTokenizer st = new StringTokenizer(id, " ");
String [] subid = new String[st.countTokens()];
int 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;
}
/**
* Encodes UTCTime.
*/
private int encodeUTCTime(ASN1Object o, byte [] stream, int offset)
{
String time = (String) (o.getValue());
byte [] t = time.getBytes();
for (int i = t.length - 1; i >= 0; i--)
{
stream[offset++] = t[i];
}
offset = encodeLength(t.length, stream, offset);
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes GeneralizedTime.
*/
private int encodeGeneralizedTime(ASN1Object o, byte[] stream, int offset)
{
String time = (String) (o.getValue());
byte [] t = time.getBytes();
for (int i = t.length - 1; i >= 0; i--)
{
stream[offset++] = t[i];
}
offset = encodeLength(t.length, stream, offset);
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes PrintableString.
*/
private int encodePrintableString(ASN1Object o, byte [] stream,
int offset)
{
String s = (String) (o.getValue());
byte [] content = s.getBytes();
for (int i = content.length - 1; i >= 0; i--)
{
stream[offset++] = content[i];
}
offset = encodeLength(content.length, stream, offset);
stream[offset++] = (byte) o.getASN1Type().getTag();
return offset;
}
/**
* Encodes IA5String.
*/
private int encodeIA5String(ASN1Object o, byte [] stream,
int offset)
{
String s = (String) (o.getValue());
byte [] content = s.getBytes();
for (int i = content.length - 1; i >= 0; i--)
{
stream[offset++] = content[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -