1
10package org.jstk.asn1;
11
12import java.io.IOException;
13import java.util.logging.Logger;
14
15public abstract class ASN1Type {
16 public static final byte UNIVERSAL = 0;
18 public static final byte APPLICATION = 0x40;
19 public static final byte CONTEXT = (byte)0x80;
20 public static final byte PRIVATE = (byte)0xc0;
21
22 public static final byte CLASSBITS = (byte)0xc0;
24 public static final byte TAGBITS = 0x1f;
25
26 public static final byte PRIMITIVE = 0;
28 public static final byte CONSTRUCTED = 0x20;
29
30 public static final int NONE = 0;
32 public static final int IMPLICIT = 1;
33 public static final int EXPLICIT = 2;
34
35 public static final int ANY = 0;
37 public static final int BOOLEAN = 1;
38 public static final int INTEGER = 2;
39 public static final int BIT_STRING = 3;
40 public static final int OCTET_STRING = 4;
41 public static final int NULL = 5;
42 public static final int OID = 6;
43 public static final int SEQUENCE = 16;
44 public static final int SET = 17;
45 public static final int PrintableString = 19;
46 public static final int T61String = 20;
47 public static final int IA5String = 22;
48 public static final int UTCTime = 23;
49
50 public static final Logger logger = Logger.getLogger("org.jstk.asn1");
51 protected byte tagClass;
53 protected int taggingMethod;
54 protected int tagNumber;
55 protected byte consMask = PRIMITIVE;
56 protected int type;
57 protected int length;
58
59 protected boolean optional = false;
61 protected byte[] defvalue = null;
62
63 protected byte[] value;
64 public ASN1Type(byte tagClass, int taggingMethod, int tagNumber, int type){
65 this.tagClass = tagClass;
66 this.taggingMethod = taggingMethod;
67 this.tagNumber = tagNumber;
68 this.type = type;
69 }
70
71 public void setTagClass(byte tagClass){
72 this.tagClass = tagClass;
73 }
74 public byte getTagClass(){
75 return tagClass;
76 }
77
78 public void setTaggingMethod(int taggingMethod){
79 this.taggingMethod = taggingMethod;
80 }
81 public int getTaggingMethod(){
82 return taggingMethod;
83 }
84
85 public void setTagNumber(int tagNumber){
86 this.tagNumber = tagNumber;
87 }
88 public int getTagNumber(){
89 return tagNumber;
90 }
91
92 public void setType(int type){
93 this.type = type;
94 }
95 public int getType(){
96 return type;
97 }
98
99 public void setConsMask(byte consMask){
00 this.consMask = consMask;
01 }
02 public int getConsMask(){
03 return consMask;
04 }
05
06 public void setOptional(boolean flag){
07 this.optional = flag;
08 }
09
10 public byte[] getValue(){
11 return value;
12 }
13 public void setValue(byte[] value){
14 this.value = value;
15 this.length = (value != null ? value.length : 0);
16 }
17
18 public void setLength(int length){
19 this.length = length;
20 }
21
22 public void decode(ASN1PullParser parser) throws ASN1PullParserException, IOException {
23 logger.entering(getClass().getName(), "decode");
24 boolean processEvent = true;
25 int event = parser.next();
26 length = parser.getLength();
27 logger.fine("[ASN1Type.decode()] event = " + event + ", off = " + parser.getOffset() +
28 ", len = " + length);
29
30 if ((event != tagNumber) || (parser.getTagClass() != tagClass)){
31 if (optional || (defvalue != null)){
32 parser.prev(); processEvent = false;
34 length = 0;
35 logger.fine("skipping ..." +
36 (optional ? "optional tag not found" : "assuming default value"));
37 } else {
38 throw new ASN1PullParserException("unexpected type");
39 }
40 }
41 consMask = parser.getConsMask();
42 if (processEvent)
43 value = parser.getContent();
44 logger.exiting(getClass().getName(), "decode");
45 }
46
47 protected byte[] encodeLen(int length){
48 int len = length;
49 int lenOctets = 0;
50 if (len > 127){
51 while (len != 0){
52 ++lenOctets;
53 len = (len >> 8);
54 }
55 }
56 byte[] bytes = new byte[1 + lenOctets];
57 len = length;
58 if (len > 127){
59 bytes[0] = (byte)(0x80 | lenOctets);
60 while (lenOctets > 0){
61 bytes[lenOctets] = (byte)(len & 0x000000ff);
62 len = (len >> 8);
63 --lenOctets;
64 }
65 } else {
66 bytes[0] = (byte)len;
67 }
68 return bytes;
69 }
70
71 protected byte[] encode1(){
73 if ((optional || defvalue != null) && (length == 0))
74 return null;
75 byte idOctet = (byte)(tagClass | consMask | tagNumber);
76 byte[] lenEncoding = encodeLen(length);
77 int len = 0;
78 if (value != null)
79 len = value.length;
80 byte[] bytes = new byte[1 + lenEncoding.length + len];
81 bytes[0] = idOctet;
82 for (int i = 0; i < lenEncoding.length; i++){
83 bytes[1 + i] = lenEncoding[i];
84 }
85 for (int i = 0; i < len; i++){
86 bytes[1 + lenEncoding.length + i] = value[i];
87 }
88 logger.fine("[ASN1Type.encode1()] idOctet = " + Integer.toHexString(idOctet) +
89 ", #lenOctets = " + lenEncoding.length + ", length = " + length + ", len = " + len);
90 return bytes;
91 }
92 public byte[] encode(){
93 logger.entering(getClass().getName(), "encode");
94 byte[] bytes = encode1();
95 logger.exiting(getClass().getName(), "encode");
96 return bytes;
97 }
98}