1 #include <winpr/asn1.h>
2 #include <winpr/print.h>
4 static const BYTE boolContent[] = { 0x01, 0x01, 0xFF };
5 static const BYTE badBoolContent[] = { 0x01, 0x04, 0xFF };
7 static const BYTE integerContent[] = { 0x02, 0x01, 0x02 };
8 static const BYTE badIntegerContent[] = { 0x02, 0x04, 0x02 };
9 static const BYTE positiveIntegerContent[] = { 0x02, 0x02, 0x00, 0xff };
10 static const BYTE negativeIntegerContent[] = { 0x02, 0x01, 0xff };
12 static const BYTE seqContent[] = { 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x44,
13 0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x69, 0x67,
14 0x6E, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, 0x72, 0x75,
15 0x73, 0x74, 0x20, 0x43, 0x6F, 0x2E, 0x31 };
17 static const BYTE contextualInteger[] = { 0xA0, 0x03, 0x02, 0x01, 0x02 };
19 static const BYTE oidContent[] = { 0x06, 0x03, 0x55, 0x04, 0x0A };
20 static const BYTE badOidContent[] = { 0x06, 0x89, 0x55, 0x04, 0x0A };
21 static const BYTE oidValue[] = { 0x55, 0x04, 0x0A };
23 static const BYTE ia5stringContent[] = { 0x16, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
24 0x63, 0x70, 0x73, 0x2E, 0x72, 0x6F, 0x6F, 0x74, 0x2D,
25 0x78, 0x31, 0x2E, 0x6C, 0x65, 0x74, 0x73, 0x65, 0x6E,
26 0x63, 0x72, 0x79, 0x70, 0x74, 0x2E, 0x6F, 0x72, 0x67 };
28 static const BYTE utctimeContent[] = { 0x17, 0x0D, 0x32, 0x31, 0x30, 0x33, 0x31, 0x37,
29 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5A };
31 int TestASN1Read(
int argc,
char* argv[])
36 WinPrAsn1_BOOL boolV = 0;
37 WinPrAsn1_INTEGER integerV = 0;
39 WinPrAsn1_IA5STRING ia5stringV = NULL;
41 WinPrAsn1_tag tag = 0;
46 Stream_StaticConstInit(&staticS, integerContent,
sizeof(integerContent));
47 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
48 if (!WinPrAsn1DecReadInteger(&decoder, &integerV))
51 Stream_StaticConstInit(&staticS, positiveIntegerContent,
sizeof(positiveIntegerContent));
52 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
53 if (!WinPrAsn1DecReadInteger(&decoder, &integerV) && integerV != 0xff)
56 Stream_StaticConstInit(&staticS, negativeIntegerContent,
sizeof(negativeIntegerContent));
57 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
58 if (!WinPrAsn1DecReadInteger(&decoder, &integerV) && integerV != -1)
61 Stream_StaticConstInit(&staticS, badIntegerContent,
sizeof(badIntegerContent));
62 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
63 if (WinPrAsn1DecReadInteger(&decoder, &integerV))
67 Stream_StaticConstInit(&staticS, boolContent,
sizeof(boolContent));
68 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
69 if (!WinPrAsn1DecReadBoolean(&decoder, &boolV))
72 Stream_StaticConstInit(&staticS, badBoolContent,
sizeof(badBoolContent));
73 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
74 if (WinPrAsn1DecReadBoolean(&decoder, &boolV))
78 Stream_StaticConstInit(&staticS, oidContent,
sizeof(oidContent));
79 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
80 if (!WinPrAsn1DecReadOID(&decoder, &oidV, TRUE) || oidV.len != 3 ||
81 (memcmp(oidV.data, oidValue, oidV.len) != 0))
83 WinPrAsn1FreeOID(&oidV);
85 Stream_StaticConstInit(&staticS, badOidContent,
sizeof(badOidContent));
86 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
87 if (WinPrAsn1DecReadOID(&decoder, &oidV, TRUE))
89 WinPrAsn1FreeOID(&oidV);
91 Stream_StaticConstInit(&staticS, ia5stringContent,
sizeof(ia5stringContent));
92 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
93 if (!WinPrAsn1DecReadIA5String(&decoder, &ia5stringV) ||
94 (strcmp(ia5stringV,
"http://cps.root-x1.letsencrypt.org") != 0))
99 Stream_StaticConstInit(&staticS, utctimeContent,
sizeof(utctimeContent));
100 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
101 if (!WinPrAsn1DecReadUtcTime(&decoder, &utctimeV) || utctimeV.year != 2021 ||
102 utctimeV.month != 3 || utctimeV.day != 17 || utctimeV.minute != 40 || utctimeV.tz !=
'Z')
106 Stream_StaticConstInit(&staticS, seqContent,
sizeof(seqContent));
107 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
108 if (!WinPrAsn1DecReadSequence(&decoder, &seqDecoder))
111 Stream_StaticConstInit(&staticS, seqContent,
sizeof(seqContent));
112 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
113 if (!WinPrAsn1DecReadTagLenValue(&decoder, &tag, &len, &seqDecoder))
116 if (tag != ER_TAG_SEQUENCE)
119 if (!WinPrAsn1DecPeekTag(&seqDecoder, &tag) || tag != ER_TAG_OBJECT_IDENTIFIER)
123 Stream_StaticConstInit(&staticS, contextualInteger,
sizeof(contextualInteger));
124 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
126 if (!WinPrAsn1DecReadContextualInteger(&decoder, 0, &error, &integerV) || error)
133 WinPrAsn1Decoder_Init(&decoder, WINPR_ASN1_DER, &staticS);
135 if (WinPrAsn1DecReadContextualInteger(&decoder, 1, &error, &integerV) || error)
139 if (!WinPrAsn1DecReadContextualInteger(&decoder, 0, &error, &integerV) || error)
145 static BYTE oid1_val[] = { 1 };
146 static const WinPrAsn1_OID oid1 = {
sizeof(oid1_val), oid1_val };
147 static BYTE oid2_val[] = { 2, 2 };
149 static BYTE oid3_val[] = { 3, 3, 3 };
151 static BYTE oid4_val[] = { 4, 4, 4, 4 };
154 int TestASN1Write(
int argc,
char* argv[])
157 size_t expectedOuputSz = 0;
160 WinPrAsn1_IA5STRING ia5string = NULL;
161 WinPrAsn1Encoder* enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
185 if (!WinPrAsn1EncAppContainer(enc, 3))
190 if (!WinPrAsn1EncSeqContainer(enc))
194 if (WinPrAsn1EncOID(enc, &oid1) != 3)
198 if (WinPrAsn1EncOID(enc, &oid2) != 4)
202 if (WinPrAsn1EncEndContainer(enc) != 9)
207 if (!WinPrAsn1EncSeqContainer(enc))
211 if (WinPrAsn1EncOID(enc, &oid3) != 5)
215 if (WinPrAsn1EncOID(enc, &oid4) != 6)
219 if (WinPrAsn1EncEndContainer(enc) != 13)
224 if (WinPrAsn1EncContextualInteger(enc, 5, 200) != 6)
229 if (!WinPrAsn1EncContextualSeqContainer(enc, 6))
233 if (WinPrAsn1EncEndContainer(enc) != 4)
245 if (WinPrAsn1EncContextualUtcTime(enc, 7, &utcTime) != 17)
251 if (!WinPrAsn1EncContextualContainer(enc, 8))
255 if (WinPrAsn1EncIA5String(enc, ia5string) != 6)
259 if (WinPrAsn1EncEndContainer(enc) != 8)
266 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 9))
270 if (!WinPrAsn1EncSeqContainer(enc))
274 if (WinPrAsn1EncEndContainer(enc) != 2)
278 if (WinPrAsn1EncEndContainer(enc) != 6)
282 expectedOuputSz = 24 + 6 + 4 + 17 + 8 + 6;
284 if (WinPrAsn1EncEndContainer(enc) != expectedOuputSz)
289 s = Stream_New(NULL, 1024);
294 if (!WinPrAsn1EncToStream(enc, s) || Stream_GetPosition(s) != expectedOuputSz)
311 WinPrAsn1Encoder_Reset(enc);
314 for (
size_t i = 0; i < 1000; i++)
316 if (!WinPrAsn1EncSeqContainer(enc))
321 if (WinPrAsn1EncInteger(enc, 2) != 3)
325 for (
size_t i = 0; i < 1000; i++)
327 if (!WinPrAsn1EncEndContainer(enc))
335 Stream_Free(s, TRUE);
336 WinPrAsn1Encoder_Free(&enc);
340 int TestASN1(
int argc,
char* argv[])
342 int ret = TestASN1Read(argc, argv);
346 return TestASN1Write(argc, argv);