aboutsummaryrefslogtreecommitdiff
path: root/src/test/model/asn1/ASN1ObjectTest.java
blob: ea765e6ce38ba5c9ffb98dabf475e9f46d38e2bb (plain)
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
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());
    }
}