1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
package model.asn1;
import model.asn1.exceptions.ParseException;
import model.asn1.parsing.BytesReader;
import org.junit.jupiter.api.Test;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import static org.junit.jupiter.api.Assertions.*;
public class ASN1ObjectTest {
@Test
void testParseType() throws ParseException {
assertEquals(Bool.class,
ASN1Object.parse(new BytesReader(new Bool(Bool.TAG, null, true).encodeDER()),
false).getClass());
assertEquals(Int.class,
ASN1Object.parse(new BytesReader(new Int(Int.TAG, null, 1).encodeDER()),
false).getClass());
assertEquals(BitString.class,
ASN1Object.parse(new BytesReader(new BitString(BitString.TAG,
null, 0, new Byte[]{1}).encodeDER()),
false).getClass());
assertEquals(OctetString.class,
ASN1Object.parse(new BytesReader(new OctetString(OctetString.TAG, null, new Byte[]{1}).encodeDER()),
false).getClass());
assertEquals(Null.class,
ASN1Object.parse(new BytesReader(new Null(Null.TAG, null).encodeDER()),
false).getClass());
assertEquals(ObjectIdentifier.class,
ASN1Object.parse(new BytesReader(new ObjectIdentifier(ObjectIdentifier.TAG, null,
new Integer[]{1, 2, 3}).encodeDER()),
false).getClass());
assertEquals(UTF8String.class,
ASN1Object.parse(new BytesReader(new UTF8String(UTF8String.TAG, null,
"qwq").encodeDER()),
false).getClass());
assertEquals(PrintableString.class,
ASN1Object.parse(new BytesReader(new PrintableString(PrintableString.TAG, null,
"qwq").encodeDER()),
false).getClass());
assertEquals(IA5String.class,
ASN1Object.parse(new BytesReader(new IA5String(IA5String.TAG, null,
"qwq").encodeDER()),
false).getClass());
assertEquals(UtcTime.class,
ASN1Object.parse(new BytesReader(new UtcTime(UtcTime.TAG, null,
ZonedDateTime.now(ZoneId.of("UTC"))).encodeDER()),
false).getClass());
assertEquals(GeneralizedTime.class,
ASN1Object.parse(new BytesReader(new GeneralizedTime(GeneralizedTime.TAG, null,
ZonedDateTime.now(ZoneId.of("UTC"))).encodeDER()),
false).getClass());
assertEquals(ASN1Object.class,
ASN1Object.parse(new BytesReader(new Byte[]{0x30, 1, 0x0}), false)
.getClass());
}
@Test
void testConstructor() {
assertEquals(0, new ASN1Object(Null.TAG, null).getLength());
assertNull(new ASN1Object(Null.TAG, null).encodeValueDER());
assertEquals(0x5,
new ASN1Object(new Tag(TagClass.UNIVERSAL, false, 0x5),
null).getTag().getNumber());
assertEquals(0x6,
new ASN1Object(new Tag(TagClass.UNIVERSAL, false, 0x5),
new Tag(TagClass.UNIVERSAL, false, 0x6)).getParentTag().getNumber());
}
@Test
void testParseSuccess() throws ParseException {
// No parent tag
assertEquals(0x5,
new ASN1Object(new BytesReader(new Byte[]{0x5, 0x0}), false)
.getTag().getNumber());
assertEquals(TagClass.UNIVERSAL,
new ASN1Object(new BytesReader(new Byte[]{0x5, 0x0}), false)
.getTag().getCls());
assertFalse(new ASN1Object(new BytesReader(new Byte[]{0x5, 0x0}), false)
.getTag().isConstructive());
assertNull(new ASN1Object(new BytesReader(new Byte[]{0x5, 0x0}), false)
.getParentTag());
assertEquals(0, new ASN1Object(new BytesReader(new Byte[]{0x5, 0x0}), false)
.encodeValueDER().length);
assertEquals(0, new ASN1Object(new BytesReader(new Byte[]{0x5, 0x0}), false)
.getLength());
// With parent tag
// -95 is the 2's complement represent of 0b10100001
assertEquals(0x5,
new ASN1Object(new BytesReader(new Byte[]{-95, 2, 0x5, 0x0}), true)
.getTag().getNumber());
assertEquals(TagClass.UNIVERSAL,
new ASN1Object(new BytesReader(new Byte[]{-95, 2, 0x5, 0x0}), true)
.getTag().getCls());
assertFalse(new ASN1Object(new BytesReader(new Byte[]{-95, 2, 0x5, 0x0}), true)
.getTag().isConstructive());
assertEquals(0x1,
new ASN1Object(new BytesReader(new Byte[]{-95, 2, 0x5, 0x0}), true)
.getParentTag().getNumber());
assertEquals(TagClass.CONTEXT_SPECIFIC,
new ASN1Object(new BytesReader(new Byte[]{-95, 2, 0x5, 0x0}), true)
.getParentTag().getCls());
assertTrue(new ASN1Object(new BytesReader(new Byte[]{-95, 2, 0x5, 0x0}), true)
.getParentTag().isConstructive());
// Test index
BytesReader reader = new BytesReader(new Byte[]{0xE, 5, 1, 2, 3, 4, 5});
ASN1Object obj = new ASN1Object(reader, false);
// Contents should not be read.
assertEquals(2, reader.getIndex());
// But is copied
assertArrayEquals(new Byte[]{1, 2, 3, 4, 5}, obj.encodeValueDER());
// If we parse an unknown type
reader = new BytesReader(new Byte[]{0xE, 5, 1, 2, 3, 4, 5});
obj = ASN1Object.parse(reader, false);
// Contents should be read now
assertEquals(7, reader.getIndex());
}
@Test
void testParseFail() {
// Value early EOF
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{0x5, 0x1}), false));
// Tag early EOF
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{-95, 2}), true));
// Length not found
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{0x5}), false));
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{-95, 2, 0x5}), true));
// Parent tag is not CONTEXT_SPECIFIC
// UNIVERSAL
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{33, 2, 0x5, 0x0}), true));
// APPLICATION
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{97, 2, 0x5, 0x0}), true));
// PRIVATE
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{-31, 2, 0x5, 0x0}), true));
// Parent tag is not constructive
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{-127, 2, 0x5, 0x0}), true));
// Parent tag length incorrect
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{-95, 0, 0x5, 0x0}), true));
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{-95, 1, 0x5, 0x0}), true));
assertThrows(ParseException.class, () ->
new ASN1Object(new BytesReader(new Byte[]{-95, 3, 0x5, 0x0}), true));
}
@Test
void testEncode() {
// No parent tag
assertArrayEquals(new Byte[]{
0x5, 0x0
}, new Null(Null.TAG, null).encodeDER());
// Custom tag
assertArrayEquals(new Byte[]{
0x72, 0x0
}, new Null(new Tag(TagClass.APPLICATION, true, 0x12), null)
.encodeDER());
// With parent tag
assertArrayEquals(new Byte[]{
-95, 2,
0x72, 0x0
}, new Null(new Tag(TagClass.APPLICATION, true, 0x12),
new Tag(TagClass.CONTEXT_SPECIFIC, true, 0x1))
.encodeDER());
}
}
|