]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bsnmp/tests/asn1.cc
Merge release 1.14 of bsnmp.
[FreeBSD/FreeBSD.git] / contrib / bsnmp / tests / asn1.cc
1 /*
2  * Copyright (c) 2020
3  *      Hartmut Brandt <harti@freebsd.org>
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * :se ts=4
28  */
29
30 #include "constbuf.h"
31
32 extern "C" {
33 #include "asn1.h"
34 }
35
36 #include "catch.hpp"
37
38 #include <algorithm>
39 #include <cstdarg>
40 #include <cstdint>
41 #include <iostream>
42 #include <string>
43 #include <type_traits>
44
45 using namespace test::literals;
46
47 template<typename T>
48 static std::enable_if_t<!std::is_integral_v<T>, asn_buf>
49 mk_asn_buf(const T &b)
50 {
51         asn_buf abuf;
52
53         abuf.asn_cptr = b.data();
54         abuf.asn_len = b.size();
55
56         return abuf;
57 }
58
59 static asn_buf
60 mk_asn_buf(asn_len_t len)
61 {
62         asn_buf abuf;
63
64         abuf.asn_ptr = new u_char[len];
65         abuf.asn_len = len;
66
67         return abuf;
68 }
69
70 static std::string g_errstr;
71
72 static void
73 save_g_errstr(const struct asn_buf *b, const char *fmt, ...)
74 {
75         va_list ap;
76
77         char sbuf[20000];
78         va_start(ap, fmt);
79         vsprintf(sbuf, fmt, ap);
80         va_end(ap);
81
82         if (b != NULL) {
83                 strcat(sbuf, " at");
84                 for (u_int i = 0; b->asn_len > i; i++)
85                         sprintf(sbuf + strlen(sbuf), " %02x", b->asn_cptr[i]);
86         }
87         strcat(sbuf, "\n");
88
89         g_errstr = sbuf;
90 }
91
92 /**
93  * Encapsulate an ASN.1 parse buffer and the parse header fields.
94  * Constructing parses the header.
95  */
96 struct Asn_value
97 {
98         /** parse buffer */
99         struct asn_buf buf;
100
101         /** error from header parsing */
102         asn_err err;
103
104         /** ASN.1 tag byte */
105         uint8_t type;
106
107         /** value length */
108         asn_len_t alen;
109
110         /**
111          * Construct a parse buffer and parse the header.
112          *
113          * \tparam Tbuf         input buffer type
114          *
115          * \param ibuf          input buffer
116          */
117         template<typename Tbuf>
118         explicit
119         Asn_value(const Tbuf &ibuf)
120           : buf {mk_asn_buf(ibuf)}, err {asn_get_header(&buf, &type, &alen)}
121         {
122         }
123 };
124
125 /**
126  * Parse the ASN.1 header and check the error code. If the error is not
127  * ASN_ERR_OK then check the error string.
128  *
129  * \tparam Tbuf         input buffer type
130  *
131  * \param buf           input buffer
132  * \param err           expected error code (default ASN_ERR_OK)
133  * \param errstr        expected error string (default empty)
134  *
135  * \return the parse buffer
136  */
137 template<typename Tbuf>
138 static auto
139 check_header(const Tbuf &buf, asn_err err = ASN_ERR_OK,
140   std::string_view errstr = {})
141 {
142         g_errstr.clear();
143         auto r = Asn_value(buf);
144         REQUIRE(r.err == err);
145         if (r.err != ASN_ERR_OK)
146                 REQUIRE(g_errstr == errstr);
147         else
148                 REQUIRE(g_errstr == "");
149         return r;
150 }
151
152 /**
153  * Parse the ASN.1 header and expect it not to fail. The check the tag.
154  *
155  * \tparam Tbuf         input buffer type
156  *
157  * \param buf           input buffer
158  * \param tag           expected type tag
159  *
160  * \return the parse buffer
161  */
162 template<typename Tbuf>
163 static auto
164 check_header(const Tbuf &buf, uint8_t type)
165 {
166         auto r = check_header(buf);
167         REQUIRE(r.type == type);
168         return r;
169 }
170
171 /**
172  * Parse the ASN.1 header and expect it not to fail. The check the tag and
173  * the length.
174  *
175  * \tparam Tbuf         input buffer type
176  *
177  * \param buf           input buffer
178  * \param tag           expected type tag
179  * \param alen          expected value length
180  *
181  * \return the parse buffer
182  */
183 template<typename Tbuf>
184 static auto
185 check_header(const Tbuf &buf, uint8_t type, asn_len_t alen)
186 {
187         auto r = check_header(buf);
188         REQUIRE(r.type == type);
189         REQUIRE(r.alen == alen);
190         return r;
191 }
192
193 template<typename Tbuf>
194 static void
195 check_buf(const asn_buf &s, const Tbuf &exp, bool print = false)
196 {
197         if (print) {
198                         for (auto c : exp)
199                                 std::printf(":%02x", c);
200                         std::printf("\n");
201
202                         for (size_t i = 0; i < size(exp); i++)
203                                 std::printf(":%02x", s.asn_ptr[i]);
204                         std::printf("\n");
205         }
206         REQUIRE(std::equal(begin(exp), end(exp), s.asn_ptr));
207 }
208
209 TEST_CASE("ASN.1 header parsing", "[asn1][parse]")
210 {
211         asn_error = save_g_errstr;
212
213         SECTION("empty buffer") {
214                 check_header(std::vector<u_char>{}, ASN_ERR_EOBUF,
215                         "no identifier for header at\n");
216         }
217         SECTION("tag too large") {
218                 check_header("x1f:06:01:7f"_cbuf, ASN_ERR_FAILED,
219                         "tags > 0x1e not supported (0x1f) at 1f 06 01 7f\n");
220         }
221         SECTION("no length field") {
222                 check_header("x46"_cbuf, ASN_ERR_EOBUF, "no length field at\n");
223         }
224         SECTION("indefinite length") {
225                 check_header("x46:80:02:04:06"_cbuf, ASN_ERR_FAILED,
226                         "indefinite length not supported at 02 04 06\n");
227         }
228         SECTION("long length") {
229                 check_header("x46:83:00:00:02:7f:12"_cbuf, ASN_ERR_FAILED,
230                         "long length too long (3) at 00 00 02 7f 12\n");
231         }
232         SECTION("truncated length field") {
233                 check_header("x46:82:00"_cbuf, ASN_ERR_EOBUF,
234                         "long length truncated at 00\n");
235         }
236         SECTION("correct long length") {
237                 check_header("x04:81:00"_cbuf, ASN_TYPE_OCTETSTRING, 0); 
238 #ifndef BOGUS_CVE_2019_5610_FIX
239                 check_header("x04:81:04:00"_cbuf, ASN_TYPE_OCTETSTRING, 4); 
240                 check_header("x04:81:ff:00"_cbuf, ASN_TYPE_OCTETSTRING, 255); 
241 #endif
242                 check_header("x04:82:00:00"_cbuf, ASN_TYPE_OCTETSTRING, 0); 
243 #ifndef BOGUS_CVE_2019_5610_FIX
244                 check_header("x04:82:00:80"_cbuf, ASN_TYPE_OCTETSTRING, 128); 
245                 check_header("x04:82:01:80"_cbuf, ASN_TYPE_OCTETSTRING, 384); 
246                 check_header("x04:82:ff:ff"_cbuf, ASN_TYPE_OCTETSTRING, 65535); 
247 #endif
248         }
249         SECTION("short length") {
250                 check_header("x04:00:00"_cbuf, ASN_TYPE_OCTETSTRING, 0); 
251                 check_header("x04:01:00"_cbuf, ASN_TYPE_OCTETSTRING, 1); 
252 #ifndef BOGUS_CVE_2019_5610_FIX
253                 check_header("x04:40:00"_cbuf, ASN_TYPE_OCTETSTRING, 64); 
254                 check_header("x04:7f:00"_cbuf, ASN_TYPE_OCTETSTRING, 127); 
255 #endif
256         }
257 }
258
259 TEST_CASE("ASN.1 header building", "[asn1][build]")
260 {
261         asn_error = save_g_errstr;
262
263         const auto conv_err = [] (asn_len_t alen, asn_len_t vlen, uint8_t type,
264           asn_err err, std::string_view errstr) {
265                 auto b = mk_asn_buf(alen);
266                 g_errstr.clear();
267                 REQUIRE(asn_put_header(&b, type, vlen) == err);
268                 REQUIRE(g_errstr == errstr);
269         };
270
271         const auto conv = [] (asn_len_t alen, asn_len_t vlen, uint8_t type,
272           const auto &cbuf) {
273                 auto b = mk_asn_buf(alen);
274                 auto t = b;
275                 REQUIRE(asn_put_header(&b, type, vlen) == ASN_ERR_OK);
276                 REQUIRE(b.asn_len == (size_t)0);
277                 check_buf(t, cbuf);
278         };
279
280         SECTION("no space for tag") {
281                 conv_err(0, 0, ASN_TYPE_OCTETSTRING, ASN_ERR_EOBUF, "");
282         }
283         SECTION("no space for length") {
284                 conv_err(1, 0, ASN_TYPE_OCTETSTRING, ASN_ERR_EOBUF, "");
285                 conv_err(2, 128, ASN_TYPE_OCTETSTRING, ASN_ERR_EOBUF, "");
286         }
287         SECTION("bad tag") {
288                 conv_err(2, 0, 0x1f, ASN_ERR_FAILED,
289                   "types > 0x1e not supported (0x1f)\n");
290                 conv_err(2, 0, 0xff, ASN_ERR_FAILED,
291                   "types > 0x1e not supported (0x1f)\n");
292         }
293         SECTION("ok") {
294                 conv(2, 0, ASN_TYPE_OCTETSTRING, "x04:00"_cbuf);
295         }
296 }
297
298 TEST_CASE("Counter64 parsing", "[asn1][parse]")
299 {
300         asn_error = save_g_errstr;
301
302         /**
303          * Sucessfully parse a COUNTER64 value.
304          *
305          * \param buf   buffer to parse
306          * \param xval  expected value
307          */
308         const auto conv = [] (const auto &buf, uint64_t xval) {
309                 auto r = check_header(buf, ASN_APP_COUNTER64 | ASN_CLASS_APPLICATION);
310
311                 uint64_t val;
312                 REQUIRE(asn_get_counter64_raw(&r.buf, r.alen, &val) == ASN_ERR_OK);
313                 REQUIRE(val == xval);
314         };
315
316         /**
317          * Parse COUNTER64 with error.
318          *
319          * \param buf   buffer to parse
320          * \param err   expected error from value parser
321          * \param errstr expected error string
322          */     
323         const auto conv_err = [] (const auto &buf, asn_err err,
324             std::string_view errstr) {
325                 auto r = check_header(buf, ASN_APP_COUNTER64 | ASN_CLASS_APPLICATION);
326
327                 g_errstr.clear();
328                 uint64_t val;
329                 REQUIRE(asn_get_counter64_raw(&r.buf, r.alen, &val) == err);
330                 REQUIRE(g_errstr == errstr);
331         };
332
333         SECTION("correct encoding") {
334
335                 conv("x46:01:00"_cbuf,                                                                             0x0ULL);
336                 conv("x46:01:01"_cbuf,                                                                             0x1ULL);
337                 conv("x46:01:7f"_cbuf,                                                                            0x7fULL);
338
339                 conv("x46:02:00:80"_cbuf,                                                                         0x80ULL);
340                 conv("x46:02:00:ff"_cbuf,                                                                         0xffULL);
341                 conv("x46:02:7f:ff"_cbuf,                                                                       0x7fffULL);
342
343                 conv("x46:03:00:80:00"_cbuf,                                                    0x8000ULL);
344                 conv("x46:03:00:ff:ff"_cbuf,                                                    0xffffULL);
345                 conv("x46:03:7f:ff:ff"_cbuf,                                                      0x7fffffULL);
346
347                 conv("x46:04:00:80:00:00"_cbuf,                                                   0x800000ULL);
348                 conv("x46:04:00:ff:ff:ff"_cbuf,                                                   0xffffffULL);
349                 conv("x46:04:7f:ff:ff:ff"_cbuf,                                                 0x7fffffffULL);
350
351                 conv("x46:05:00:80:00:00:00"_cbuf,                                              0x80000000ULL);
352                 conv("x46:05:00:ff:ff:ff:ff"_cbuf,                                          0xffffffffULL);
353                 conv("x46:05:7f:ff:ff:ff:ff"_cbuf,                                        0x7fffffffffULL);
354
355                 conv("x46:06:00:80:00:00:00:00"_cbuf,                             0x8000000000ULL);
356                 conv("x46:06:00:ff:ff:ff:ff:ff"_cbuf,                             0xffffffffffULL);
357                 conv("x46:06:7f:ff:ff:ff:ff:ff"_cbuf,                           0x7fffffffffffULL);
358
359                 conv("x46:07:00:80:00:00:00:00:00"_cbuf,                    0x800000000000ULL);
360                 conv("x46:07:00:ff:ff:ff:ff:ff:ff"_cbuf,                    0xffffffffffffULL);
361                 conv("x46:07:7f:ff:ff:ff:ff:ff:ff"_cbuf,                  0x7fffffffffffffULL);
362
363                 conv("x46:08:00:80:00:00:00:00:00:00"_cbuf,               0x80000000000000ULL);
364                 conv("x46:08:00:ff:ff:ff:ff:ff:ff:ff"_cbuf,               0xffffffffffffffULL);
365                 conv("x46:08:7f:ff:ff:ff:ff:ff:ff:ff"_cbuf,             0x7fffffffffffffffULL);
366
367                 conv("x46:09:00:80:00:00:00:00:00:00:00"_cbuf,  0x8000000000000000ULL);
368                 conv("x46:09:00:ff:ff:ff:ff:ff:ff:ff:ff"_cbuf,  0xffffffffffffffffULL);
369         }
370
371         SECTION("zero length") {
372                 conv_err("x46:00"_cbuf, ASN_ERR_BADLEN,
373                         "zero-length integer at\n");
374         }
375
376         SECTION("non minimal encoding") {
377                 conv_err("x46:02:00:00"_cbuf, ASN_ERR_BADLEN,
378                     "non-minimal unsigned at 00 00\n");
379                 conv_err("x46:02:00:7f"_cbuf, ASN_ERR_BADLEN,
380                     "non-minimal unsigned at 00 7f\n");
381                 conv_err("x46:03:00:00:80"_cbuf, ASN_ERR_BADLEN,
382                     "non-minimal unsigned at 00 00 80\n");
383                 conv_err("x46:04:00:00:80:00"_cbuf, ASN_ERR_BADLEN,
384                     "non-minimal unsigned at 00 00 80 00\n");
385                 conv_err("x46:0a:00:00:00:00:00:00:00:00:00:00"_cbuf, ASN_ERR_BADLEN,
386                         "non-minimal unsigned at 00 00 00 00 00 00 00 00 00 00\n");
387                 conv_err("x46:0a:00:01:00:00:00:00:00:00:00:00"_cbuf, ASN_ERR_BADLEN,
388                         "non-minimal unsigned at 00 01 00 00 00 00 00 00 00 00\n");
389         }
390
391         SECTION("out of range") {
392                 conv_err("x46:09:01:00:00:00:00:00:00:00:00"_cbuf, ASN_ERR_RANGE,
393                         "unsigned too large or negative at 01 00 00 00 00 00 00 00 00\n");
394                 conv_err("x46:0a:01:00:00:00:00:00:00:00:00:00"_cbuf, ASN_ERR_RANGE,
395                         "unsigned too large or negative at 01 00 00 00 00 00 00 00 00 00\n");
396                 conv_err("x46:01:80"_cbuf, ASN_ERR_RANGE,
397                         "unsigned too large or negative at 80\n");
398                 conv_err("x46:02:80:00"_cbuf, ASN_ERR_RANGE,
399                         "unsigned too large or negative at 80 00\n");
400                 conv_err("x46:03:80:00:00"_cbuf, ASN_ERR_RANGE,
401                         "unsigned too large or negative at 80 00 00\n");
402         }
403
404 #ifndef BOGUS_CVE_2019_5610_FIX
405         SECTION("truncated value") {
406                 conv_err("x46:02:00"_cbuf, ASN_ERR_EOBUF,
407                         "truncated integer at 00\n");
408                 conv_err("x46:09:00:80:00:00:00"_cbuf, ASN_ERR_EOBUF,
409                         "truncated integer at 00 80 00 00 00\n");
410                 conv_err("x46:09:00:ff:ff:ff:ff:ff:ff:ff"_cbuf, ASN_ERR_EOBUF,
411                         "truncated integer at 00 ff ff ff ff ff ff ff\n");
412         }
413 #endif
414 }
415
416 TEST_CASE("Counter64 building", "[asn1][build]")
417 {
418         asn_error = save_g_errstr;
419
420         const auto conv = [] (asn_len_t alen, uint64_t val, const auto &buf) {
421                 auto b = mk_asn_buf(alen);
422                 auto s = b;
423                 REQUIRE(asn_put_counter64(&b, val) == ASN_ERR_OK);
424                 REQUIRE(b.asn_len == (size_t)0);
425                 check_buf(s, buf);
426         };
427
428         const auto conv_err = [] (asn_len_t alen, uint64_t val, asn_err err,
429           std::string_view errstr) {
430                 auto b = mk_asn_buf(alen);
431                 g_errstr.clear();
432                 REQUIRE(asn_put_counter64(&b, val) == err);
433                 REQUIRE(g_errstr == errstr);
434         };
435
436         conv(3,  0x0, "x46:01:00"_cbuf);
437         conv(3,  0x1, "x46:01:01"_cbuf);
438         conv(3, 0x7f, "x46:01:7f"_cbuf);
439
440         conv(4,   0x80, "x46:02:00:80"_cbuf);
441         conv(4,   0xff, "x46:02:00:ff"_cbuf);
442         conv(4, 0x7fff, "x46:02:7f:ff"_cbuf);
443
444         conv(5,   0x8000, "x46:03:00:80:00"_cbuf);
445         conv(5,   0xffff, "x46:03:00:ff:ff"_cbuf);
446         conv(5, 0x7fffff, "x46:03:7f:ff:ff"_cbuf);
447
448         conv(6,   0x800000, "x46:04:00:80:00:00"_cbuf);
449         conv(6,   0xffffff, "x46:04:00:ff:ff:ff"_cbuf);
450         conv(6, 0x7fffffff, "x46:04:7f:ff:ff:ff"_cbuf);
451
452         conv(7,   0x80000000, "x46:05:00:80:00:00:00"_cbuf);
453         conv(7,   0xffffffff, "x46:05:00:ff:ff:ff:ff"_cbuf);
454         conv(7, 0x7fffffffff, "x46:05:7f:ff:ff:ff:ff"_cbuf);
455
456         conv(8,   0x8000000000, "x46:06:00:80:00:00:00:00"_cbuf);
457         conv(8,   0xffffffffff, "x46:06:00:ff:ff:ff:ff:ff"_cbuf);
458         conv(8, 0x7fffffffffff, "x46:06:7f:ff:ff:ff:ff:ff"_cbuf);
459
460         conv(9,   0x800000000000, "x46:07:00:80:00:00:00:00:00"_cbuf);
461         conv(9,   0xffffffffffff, "x46:07:00:ff:ff:ff:ff:ff:ff"_cbuf);
462         conv(9, 0x7fffffffffffff, "x46:07:7f:ff:ff:ff:ff:ff:ff"_cbuf);
463
464         conv(10,   0x80000000000000, "x46:08:00:80:00:00:00:00:00:00"_cbuf);
465         conv(10,   0xffffffffffffff, "x46:08:00:ff:ff:ff:ff:ff:ff:ff"_cbuf);
466         conv(10, 0x7fffffffffffffff, "x46:08:7f:ff:ff:ff:ff:ff:ff:ff"_cbuf);
467
468         conv(11,   0x8000000000000000, "x46:09:00:80:00:00:00:00:00:00:00"_cbuf);
469         conv(11,   0xffffffffffffffff, "x46:09:00:ff:ff:ff:ff:ff:ff:ff:ff"_cbuf);
470
471         SECTION("empty buffer") {
472                 conv_err(0, 0, ASN_ERR_EOBUF, "");
473         }
474         SECTION("buffer too short for length field") {
475                 conv_err(1, 0, ASN_ERR_EOBUF, "");
476         }
477         SECTION("buffer too short") {
478                 conv_err(2, 0, ASN_ERR_EOBUF, "");
479                 conv_err(3, 0x80, ASN_ERR_EOBUF, "");
480                 conv_err(4, 0x8000, ASN_ERR_EOBUF, "");
481                 conv_err(5, 0x800000, ASN_ERR_EOBUF, "");
482                 conv_err(6, 0x80000000, ASN_ERR_EOBUF, "");
483                 conv_err(7, 0x8000000000, ASN_ERR_EOBUF, "");
484                 conv_err(8, 0x800000000000, ASN_ERR_EOBUF, "");
485                 conv_err(9, 0x80000000000000, ASN_ERR_EOBUF, "");
486                 conv_err(10, 0x8000000000000000, ASN_ERR_EOBUF, "");
487         }
488 }
489
490 TEST_CASE("Unsigned32 parsing", "[asn1][parse]")
491 {
492         asn_error = save_g_errstr;
493
494         /**
495          * Sucessfully parse a COUNTER value.
496          *
497          * \param buf   buffer to parse
498          * \param xval  expected value
499          */
500         const auto conv = [] (const auto &buf, uint32_t xval) {
501                 auto r = check_header(buf, ASN_APP_COUNTER | ASN_CLASS_APPLICATION);
502
503                 uint32_t val;
504                 REQUIRE(asn_get_uint32_raw(&r.buf, r.alen, &val) == ASN_ERR_OK);
505                 REQUIRE(val == xval);
506         };
507
508         /**
509          * Parse COUNTER with error.
510          *
511          * \param buf   buffer to parse
512          * \param err   expected error from value parser
513          * \param errstr expected error string
514          */     
515         const auto conv_err = [] (const auto &buf, asn_err err,
516             std::string_view errstr) {
517                 auto r = check_header(buf, ASN_APP_COUNTER | ASN_CLASS_APPLICATION);
518
519                 g_errstr.clear();
520                 uint32_t val;
521                 REQUIRE(asn_get_uint32_raw(&r.buf, r.alen, &val) == err);
522                 REQUIRE(g_errstr == errstr);
523         };
524
525         SECTION("correct encoding") {
526                 conv("x41:01:00"_cbuf,                     0x0U);
527                 conv("x41:01:01"_cbuf,                     0x1U);
528                 conv("x41:01:7f"_cbuf,                     0x7fU);
529
530                 conv("x41:02:00:80"_cbuf,                  0x80U);
531                 conv("x41:02:00:ff"_cbuf,                  0xffU);
532                 conv("x41:02:7f:ff"_cbuf,                  0x7fffU);
533
534                 conv("x41:03:00:80:00"_cbuf,       0x8000U);
535                 conv("x41:03:00:ff:ff"_cbuf,       0xffffU);
536                 conv("x41:03:7f:ff:ff"_cbuf,       0x7fffffU);
537
538                 conv("x41:04:00:80:00:00"_cbuf,    0x800000U);
539                 conv("x41:04:00:ff:ff:ff"_cbuf,    0xffffffU);
540                 conv("x41:04:7f:ff:ff:ff"_cbuf,    0x7fffffffU);
541
542                 conv("x41:05:00:80:00:00:00"_cbuf, 0x80000000U);
543                 conv("x41:05:00:ff:ff:ff:ff"_cbuf, 0xffffffffU);
544         }
545         SECTION("zero length") {
546
547                 conv_err("x41:00"_cbuf, ASN_ERR_BADLEN,
548                         "zero-length integer at\n");
549         }
550
551         SECTION("non minimal encoding") {
552                 conv_err("x41:02:00:00"_cbuf, ASN_ERR_BADLEN,
553                     "non-minimal unsigned at 00 00\n");
554                 conv_err("x41:02:00:7f"_cbuf, ASN_ERR_BADLEN,
555                     "non-minimal unsigned at 00 7f\n");
556                 conv_err("x41:03:00:00:80"_cbuf, ASN_ERR_BADLEN,
557                     "non-minimal unsigned at 00 00 80\n");
558                 conv_err("x41:04:00:00:80:00"_cbuf, ASN_ERR_BADLEN,
559                     "non-minimal unsigned at 00 00 80 00\n");
560                 conv_err("x41:06:00:00:00:00:00:00"_cbuf, ASN_ERR_BADLEN,
561                         "non-minimal unsigned at 00 00 00 00 00 00\n");
562                 conv_err("x41:06:00:01:00:00:00:00"_cbuf, ASN_ERR_BADLEN,
563                         "non-minimal unsigned at 00 01 00 00 00 00\n");
564         }
565
566         SECTION("out of range") {
567                 conv_err("x41:05:01:00:00:00:00"_cbuf,
568                         ASN_ERR_RANGE, "uint32 too large 4294967296 at\n");
569                 conv_err("x41:06:01:00:00:00:00:00"_cbuf,
570                         ASN_ERR_RANGE, "uint32 too large 1099511627776 at\n");
571                 conv_err("x41:01:80"_cbuf,
572                         ASN_ERR_RANGE, "unsigned too large or negative at 80\n");
573                 conv_err("x41:02:80:00"_cbuf,
574                         ASN_ERR_RANGE, "unsigned too large or negative at 80 00\n");
575                 conv_err("x41:03:80:00:00"_cbuf,
576                         ASN_ERR_RANGE, "unsigned too large or negative at 80 00 00\n");
577         }
578
579 #ifndef BOGUS_CVE_2019_5610_FIX
580         SECTION("truncated value") {
581                 conv_err("x41:01"_cbuf, ASN_ERR_EOBUF,
582                         "truncated integer at\n");
583                 conv_err("x41:02:01"_cbuf, ASN_ERR_EOBUF,
584                         "truncated integer at 01\n");
585                 conv_err("x41:05:00:80:"_cbuf, ASN_ERR_EOBUF,
586                         "truncated integer at 00 80\n");
587                 conv_err("x41:05:00:ff:ff:ff"_cbuf, ASN_ERR_EOBUF,
588                         "truncated integer at 00 ff ff ff\n");
589         }
590 #endif
591 }
592
593 TEST_CASE("Unsigned32 building", "[asn1][build]")
594 {
595         asn_error = save_g_errstr;
596
597         const auto conv = [] (asn_len_t alen, uint32_t val, const auto &buf) {
598                 auto b = mk_asn_buf(alen);
599                 auto s = b;
600                 REQUIRE(asn_put_uint32(&b, ASN_APP_COUNTER, val) == ASN_ERR_OK);
601                 REQUIRE(b.asn_len == (size_t)0);
602                 check_buf(s, buf);
603         };
604
605         const auto conv_err = [] (asn_len_t alen, uint32_t val, asn_err err,
606           std::string_view errstr) {
607                 auto b = mk_asn_buf(alen);
608                 g_errstr.clear();
609                 REQUIRE(asn_put_uint32(&b, ASN_APP_COUNTER, val) == err);
610                 REQUIRE(g_errstr == errstr);
611         };
612
613         conv(3,  0x0, "x41:01:00"_cbuf);
614         conv(3,  0x1, "x41:01:01"_cbuf);
615         conv(3, 0x7f, "x41:01:7f"_cbuf);
616
617         conv(4,   0x80, "x41:02:00:80"_cbuf);
618         conv(4,   0xff, "x41:02:00:ff"_cbuf);
619         conv(4, 0x7fff, "x41:02:7f:ff"_cbuf);
620
621         conv(5,   0x8000, "x41:03:00:80:00"_cbuf);
622         conv(5,   0xffff, "x41:03:00:ff:ff"_cbuf);
623         conv(5, 0x7fffff, "x41:03:7f:ff:ff"_cbuf);
624
625         conv(6,   0x800000, "x41:04:00:80:00:00"_cbuf);
626         conv(6,   0xffffff, "x41:04:00:ff:ff:ff"_cbuf);
627         conv(6, 0x7fffffff, "x41:04:7f:ff:ff:ff"_cbuf);
628
629         conv(7,   0x80000000, "x41:05:00:80:00:00:00"_cbuf);
630         conv(7,   0xffffffff, "x41:05:00:ff:ff:ff:ff"_cbuf);
631
632         SECTION("empty buffer") {
633                 conv_err(0, 0, ASN_ERR_EOBUF, "");
634         }
635         SECTION("buffer too short for length field") {
636                 conv_err(1, 0, ASN_ERR_EOBUF, "");
637         }
638         SECTION("buffer too short") {
639                 conv_err(2, 0, ASN_ERR_EOBUF, "");
640                 conv_err(3, 0x80, ASN_ERR_EOBUF, "");
641                 conv_err(4, 0x8000, ASN_ERR_EOBUF, "");
642                 conv_err(5, 0x800000, ASN_ERR_EOBUF, "");
643                 conv_err(6, 0x80000000, ASN_ERR_EOBUF, "");
644         }
645 }
646
647 TEST_CASE("Integer parsing", "[asn1][parse]")
648 {
649         asn_error = save_g_errstr;
650
651         /**
652          * Sucessfully parse a INTEGER value.
653          *
654          * \param buf   buffer to parse
655          * \param xval  expected value
656          */
657         const auto conv = [] (const auto &buf, int32_t xval) {
658                 auto r = check_header(buf, ASN_TYPE_INTEGER);
659
660                 int32_t val;
661                 REQUIRE(asn_get_integer_raw(&r.buf, r.alen, &val) == ASN_ERR_OK);
662                 REQUIRE(val == xval);
663         };
664
665         /**
666          * Parse INTEGER with error.
667          *
668          * \param buf   buffer to parse
669          * \param err   expected error from value parser
670          * \param errstr expected error string
671          */     
672         const auto conv_err = [] (const auto &buf, asn_err err,
673             std::string_view errstr) {
674                 auto r = check_header(buf, ASN_TYPE_INTEGER);
675
676                 g_errstr.clear();
677                 int32_t val;
678                 REQUIRE(asn_get_integer_raw(&r.buf, r.alen, &val) == err);
679                 REQUIRE(g_errstr == errstr);
680         };
681
682         SECTION("correct encoding") {
683                 conv("x02:01:00"_cbuf,                                     0x0);
684                 conv("x02:01:01"_cbuf,                                     0x1);
685                 conv("x02:01:7f"_cbuf,                                    0x7f);
686                 conv("x02:01:ff"_cbuf,                                    -0x1);
687                 conv("x02:01:80"_cbuf,                                   -0x80);
688
689                 conv("x02:02:00:80"_cbuf,                                 0x80);
690                 conv("x02:02:00:ff"_cbuf,                                 0xff);
691                 conv("x02:02:7f:ff"_cbuf,                               0x7fff);
692                 conv("x02:02:ff:7f"_cbuf,                                -0x81);
693                 conv("x02:02:ff:01"_cbuf,                                -0xff);
694                 conv("x02:02:ff:00"_cbuf,                               -0x100);
695                 conv("x02:02:80:00"_cbuf,                          -0x8000);
696
697                 conv("x02:03:00:80:00"_cbuf,                     0x8000);
698                 conv("x02:03:00:ff:ff"_cbuf,                     0xffff);
699                 conv("x02:03:7f:ff:ff"_cbuf,               0x7fffff);
700                 conv("x02:03:ff:7f:ff"_cbuf,                    -0x8001);
701                 conv("x02:03:ff:00:01"_cbuf,                    -0xffff);
702                 conv("x02:03:ff:00:00"_cbuf,               -0x10000);
703                 conv("x02:03:80:00:00"_cbuf,              -0x800000);
704
705                 conv("x02:04:00:80:00:00"_cbuf,            0x800000);
706                 conv("x02:04:00:ff:ff:ff"_cbuf,            0xffffff);
707                 conv("x02:04:7f:ff:ff:ff"_cbuf,          0x7fffffff);
708                 conv("x02:04:ff:7f:ff:ff"_cbuf,           -0x800001);
709                 conv("x02:04:ff:00:00:01"_cbuf,           -0xffffff);
710                 conv("x02:04:ff:00:00:00"_cbuf,          -0x1000000);
711                 conv("x02:04:80:00:00:00"_cbuf,         -0x80000000);
712         }
713
714         SECTION("zero length") {
715                 conv_err("x02:00"_cbuf, ASN_ERR_BADLEN,
716                         "zero-length integer at\n");
717         }
718         SECTION("too long") {
719                 conv_err("x02:05:01:02:03:04:05"_cbuf, ASN_ERR_BADLEN,
720                         "integer too long at\n");
721         }
722
723         SECTION("non minimal encoding") {
724                 conv_err("x02:02:00:00"_cbuf, ASN_ERR_BADLEN,
725                     "non-minimal integer at 00 00\n");
726                 conv_err("x02:02:00:7f"_cbuf, ASN_ERR_BADLEN,
727                     "non-minimal integer at 00 7f\n");
728                 conv_err("x02:03:00:00:80"_cbuf, ASN_ERR_BADLEN,
729                     "non-minimal integer at 00 00 80\n");
730                 conv_err("x02:04:00:00:80:00"_cbuf, ASN_ERR_BADLEN,
731                     "non-minimal integer at 00 00 80 00\n");
732                 conv_err("x02:06:00:00:00:00:00:00"_cbuf, ASN_ERR_BADLEN,
733                         "non-minimal integer at 00 00 00 00 00 00\n");
734                 conv_err("x02:06:00:01:00:00:00:00"_cbuf, ASN_ERR_BADLEN,
735                         "non-minimal integer at 00 01 00 00 00 00\n");
736                 conv_err("x02:02:ff:80"_cbuf, ASN_ERR_BADLEN,
737                     "non-minimal integer at ff 80\n");
738                 conv_err("x02:02:ff:ff"_cbuf, ASN_ERR_BADLEN,
739                     "non-minimal integer at ff ff\n");
740                 conv_err("x02:03:ff:80:00"_cbuf, ASN_ERR_BADLEN,
741                     "non-minimal integer at ff 80 00\n");
742                 conv_err("x02:03:ff:ff:ff"_cbuf, ASN_ERR_BADLEN,
743                     "non-minimal integer at ff ff ff\n");
744                 conv_err("x02:04:ff:80:00:00"_cbuf, ASN_ERR_BADLEN,
745                     "non-minimal integer at ff 80 00 00\n");
746                 conv_err("x02:04:ff:ff:ff:ff"_cbuf, ASN_ERR_BADLEN,
747                     "non-minimal integer at ff ff ff ff\n");
748                 conv_err("x02:06:ff:80:00:00:00:00"_cbuf, ASN_ERR_BADLEN,
749                     "non-minimal integer at ff 80 00 00 00 00\n");
750                 conv_err("x02:06:ff:ff:ff:ff:ff:ff"_cbuf, ASN_ERR_BADLEN,
751                     "non-minimal integer at ff ff ff ff ff ff\n");
752         }
753
754 #ifndef BOGUS_CVE_2019_5610_FIX
755         SECTION("truncated value") {
756                 conv_err("x02:01"_cbuf, ASN_ERR_EOBUF,
757                         "truncated integer at\n");
758                 conv_err("x02:02:ff"_cbuf, ASN_ERR_EOBUF,
759                         "truncated integer at ff\n");
760                 conv_err("x02:05:ff:00:03:01"_cbuf, ASN_ERR_EOBUF,
761                         "truncated integer at ff 00 03 01\n");
762                 conv_err("x02:04:7f:ff:"_cbuf, ASN_ERR_EOBUF,
763                         "truncated integer at 7f ff\n");
764                 conv_err("x02:04:80:00:00"_cbuf, ASN_ERR_EOBUF,
765                         "truncated integer at 80 00 00\n");
766         }
767 #endif
768 }
769
770 TEST_CASE("Integer32 building", "[asn1][build]")
771 {
772         asn_error = save_g_errstr;
773
774         const auto conv = [] (asn_len_t alen, int32_t val, const auto &buf) {
775                 auto b = mk_asn_buf(alen);
776                 auto s = b;
777                 REQUIRE(asn_put_integer(&b, val) == ASN_ERR_OK);
778                 REQUIRE(b.asn_len == (size_t)0);
779                 check_buf(s, buf);
780         };
781
782         const auto conv_err = [] (asn_len_t alen, int32_t val, asn_err err,
783           std::string_view errstr) {
784                 auto b = mk_asn_buf(alen);
785                 g_errstr.clear();
786                 REQUIRE(asn_put_integer(&b, val) == err);
787                 REQUIRE(g_errstr == errstr);
788         };
789
790         conv(3,                  0x0, "x02:01:00"_cbuf);
791         conv(3,                  0x1, "x02:01:01"_cbuf);
792         conv(3,                 0x7f, "x02:01:7f"_cbuf);
793         conv(3,                 -0x1, "x02:01:ff"_cbuf);
794         conv(3,            -0x80, "x02:01:80"_cbuf);
795
796         conv(4,                 0x80, "x02:02:00:80"_cbuf);
797         conv(4,                 0xff, "x02:02:00:ff"_cbuf);
798         conv(4,           0x7fff, "x02:02:7f:ff"_cbuf);
799         conv(4,            -0x81, "x02:02:ff:7f"_cbuf);
800         conv(4,            -0xff, "x02:02:ff:01"_cbuf);
801         conv(4,           -0x100, "x02:02:ff:00"_cbuf);
802         conv(4,          -0x8000, "x02:02:80:00"_cbuf);
803
804         conv(5,          0x8000, "x02:03:00:80:00"_cbuf);
805         conv(5,          0xffff, "x02:03:00:ff:ff"_cbuf);
806         conv(5,    0x7fffff, "x02:03:7f:ff:ff"_cbuf);
807         conv(5,         -0x8001, "x02:03:ff:7f:ff"_cbuf);
808         conv(5,         -0xffff, "x02:03:ff:00:01"_cbuf);
809         conv(5,    -0x10000, "x02:03:ff:00:00"_cbuf);
810         conv(5,   -0x800000, "x02:03:80:00:00"_cbuf);
811
812         conv(6,    0x800000, "x02:04:00:80:00:00"_cbuf);
813         conv(6,    0xffffff, "x02:04:00:ff:ff:ff"_cbuf);
814         conv(6,  0x7fffffff, "x02:04:7f:ff:ff:ff"_cbuf);
815         conv(6,   -0x800001, "x02:04:ff:7f:ff:ff"_cbuf);
816         conv(6,   -0xffffff, "x02:04:ff:00:00:01"_cbuf);
817         conv(6,  -0x1000000, "x02:04:ff:00:00:00"_cbuf);
818         conv(6, -0x80000000, "x02:04:80:00:00:00"_cbuf);
819
820         SECTION("empty buffer") {
821                 conv_err(0, 0, ASN_ERR_EOBUF, "");
822         }
823         SECTION("buffer too short for length field") {
824                 conv_err(1, 0, ASN_ERR_EOBUF, "");
825         }
826         SECTION("buffer too short") {
827                 conv_err(2, 0, ASN_ERR_EOBUF, "");
828                 conv_err(3, 0xff, ASN_ERR_EOBUF, "");
829                 conv_err(4, 0xffff, ASN_ERR_EOBUF, "");
830                 conv_err(5, 0xffffff, ASN_ERR_EOBUF, "");
831                 conv_err(5, 0x7fffffff, ASN_ERR_EOBUF, "");
832                 conv_err(2, -0x80, ASN_ERR_EOBUF, "");
833                 conv_err(3, -0x8000, ASN_ERR_EOBUF, "");
834                 conv_err(4, -0x800000, ASN_ERR_EOBUF, "");
835                 conv_err(5, -0x80000000, ASN_ERR_EOBUF, "");
836         }
837 }
838
839 TEST_CASE("Oid parsing", "[asn1][parse]")
840 {
841         asn_error = save_g_errstr;
842
843         /**
844          * Sucessfully parse a INTEGER value.
845          *
846          * \param buf   buffer to parse
847          * \param xval  expected value
848          */
849         const auto conv = [] (const auto &buf, const asn_oid &xval) {
850                 auto r = check_header(buf, ASN_TYPE_OBJID);
851
852                 struct asn_oid val;
853                 REQUIRE(asn_get_objid_raw(&r.buf, r.alen, &val) == ASN_ERR_OK);
854                 REQUIRE(asn_compare_oid(&val, &xval) == 0);
855         };
856
857         /**
858          * Parse INTEGER with error.
859          *
860          * \param buf   buffer to parse
861          * \param err   expected error from value parser
862          * \param errstr expected error string
863          */     
864         const auto conv_err = [] (const auto &buf, asn_err err,
865             std::string_view errstr) {
866                 auto r = check_header(buf, ASN_TYPE_OBJID);
867
868                 g_errstr.clear();
869                 struct asn_oid val;
870                 REQUIRE(asn_get_objid_raw(&r.buf, r.alen, &val) == err);
871                 REQUIRE(g_errstr == errstr);
872         };
873
874         conv("x06:01:00"_cbuf, asn_oid {2, {0, 0}});
875         conv("x06:01:28"_cbuf, asn_oid {2, {1, 0}});
876         conv("x06:01:50"_cbuf, asn_oid {2, {2, 0}});
877
878         conv("x06:01:27"_cbuf, asn_oid {2, {0, 39}});
879         conv("x06:01:4f"_cbuf, asn_oid {2, {1, 39}});
880         conv("x06:01:7f"_cbuf, asn_oid {2, {2, 47}});
881
882         conv("x06:02:81:00"_cbuf, asn_oid {2, {2, 48}});
883         conv("x06:02:ff:7f"_cbuf, asn_oid {2, {2, 16303}});
884         conv("x06:03:ff:ff:7f"_cbuf, asn_oid {2, {2, 2097071}});
885         conv("x06:04:ff:ff:ff:7f"_cbuf, asn_oid {2, {2, 268435375}});
886         conv("x06:05:8f:ff:ff:ff:7f"_cbuf, asn_oid {2, {2, 4294967215}});
887
888         /* maximum OID */
889         conv("x06:82:02:7b:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f"_cbuf, asn_oid {128, {
890                 2, 4294967215, 4294967295, 4294967295, 
891                 4294967295, 4294967295, 4294967295, 4294967295, 
892                 4294967295, 4294967295, 4294967295, 4294967295, 
893                 4294967295, 4294967295, 4294967295, 4294967295, 
894                 4294967295, 4294967295, 4294967295, 4294967295, 
895                 4294967295, 4294967295, 4294967295, 4294967295, 
896                 4294967295, 4294967295, 4294967295, 4294967295, 
897                 4294967295, 4294967295, 4294967295, 4294967295, 
898                 4294967295, 4294967295, 4294967295, 4294967295, 
899                 4294967295, 4294967295, 4294967295, 4294967295, 
900                 4294967295, 4294967295, 4294967295, 4294967295, 
901                 4294967295, 4294967295, 4294967295, 4294967295, 
902                 4294967295, 4294967295, 4294967295, 4294967295, 
903                 4294967295, 4294967295, 4294967295, 4294967295, 
904                 4294967295, 4294967295, 4294967295, 4294967295, 
905                 4294967295, 4294967295, 4294967295, 4294967295, 
906                 4294967295, 4294967295, 4294967295, 4294967295, 
907                 4294967295, 4294967295, 4294967295, 4294967295, 
908                 4294967295, 4294967295, 4294967295, 4294967295, 
909                 4294967295, 4294967295, 4294967295, 4294967295, 
910                 4294967295, 4294967295, 4294967295, 4294967295, 
911                 4294967295, 4294967295, 4294967295, 4294967295, 
912                 4294967295, 4294967295, 4294967295, 4294967295, 
913                 4294967295, 4294967295, 4294967295, 4294967295, 
914                 4294967295, 4294967295, 4294967295, 4294967295, 
915                 4294967295, 4294967295, 4294967295, 4294967295, 
916                 4294967295, 4294967295, 4294967295, 4294967295, 
917                 4294967295, 4294967295, 4294967295, 4294967295, 
918                 4294967295, 4294967295, 4294967295, 4294967295, 
919                 4294967295, 4294967295, 4294967295, 4294967295, 
920                 4294967295, 4294967295, 4294967295, 4294967295, 
921                 4294967295, 4294967295, 4294967295, 4294967295, 
922         }});
923
924         SECTION("truncated OID") {
925 #ifndef BOGUS_CVE_2019_5610_FIX
926                 conv_err("x06:02:01"_cbuf, ASN_ERR_EOBUF,
927                         "truncated OBJID at 01\n");
928 #endif
929                 conv_err("x06:01:8f"_cbuf, ASN_ERR_EOBUF,
930                         "unterminated subid at\n");
931                 conv_err("x06:04:07:7f:82:8e"_cbuf, ASN_ERR_EOBUF,
932                         "unterminated subid at\n");
933         }
934         SECTION("short OID") {
935                 conv_err("x06:00"_cbuf, ASN_ERR_BADLEN,
936                         "short OBJID at\n");
937         }
938         SECTION("too long") {
939                 conv_err("x06:81:80:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c:7c"_cbuf, ASN_ERR_BADLEN, "OID too long (128) at 7c\n");
940         }
941         SECTION("subid too large") {
942                 conv_err("x06:06:20:90:82:83:84:75"_cbuf, ASN_ERR_RANGE,
943                         "OID subid too larger at 75\n");
944         }
945 }
946
947 TEST_CASE("Objid building", "[asn1][build]")
948 {
949         asn_error = save_g_errstr;
950
951         const auto conv = [] (asn_len_t alen, const asn_oid &val, const auto &buf) {
952                 auto b = mk_asn_buf(alen);
953                 auto s = b;
954                 REQUIRE(asn_put_objid(&b, &val) == ASN_ERR_OK);
955                 REQUIRE(b.asn_len == (size_t)0);
956                 check_buf(s, buf);
957         };
958
959         const auto conv_err = [] (asn_len_t alen, const asn_oid &val, asn_err err,
960           std::string_view errstr) {
961                 auto b = mk_asn_buf(alen);
962                 g_errstr.clear();
963                 REQUIRE(asn_put_objid(&b, &val) == err);
964                 REQUIRE(g_errstr == errstr);
965         };
966
967         conv(3, asn_oid {2, {0, 0}}, "x06:01:00"_cbuf);
968         conv(3, asn_oid {2, {1, 0}}, "x06:01:28"_cbuf);
969         conv(3, asn_oid {2, {2, 0}}, "x06:01:50"_cbuf);
970
971         conv(3, asn_oid {2, {0, 39}}, "x06:01:27"_cbuf);
972         conv(3, asn_oid {2, {1, 39}}, "x06:01:4f"_cbuf);
973         conv(3, asn_oid {2, {2, 47}}, "x06:01:7f"_cbuf);
974
975         conv(4, asn_oid {2, {2, 48}}, "x06:02:81:00"_cbuf);
976         conv(4, asn_oid {2, {2, 16303}}, "x06:02:ff:7f"_cbuf);
977         conv(5, asn_oid {2, {2, 2097071}}, "x06:03:ff:ff:7f"_cbuf);
978         conv(6, asn_oid {2, {2, 268435375}}, "x06:04:ff:ff:ff:7f"_cbuf);
979         conv(7, asn_oid {2, {2, 4294967215}}, "x06:05:8f:ff:ff:ff:7f"_cbuf);
980
981         SECTION("sub-id too large") {
982                 conv_err(3, asn_oid {2, {3, 0}}, ASN_ERR_RANGE,
983                         "oid out of range (3,0)\n");
984                 conv_err(3, asn_oid {2, {0, 40}}, ASN_ERR_RANGE,
985                         "oid out of range (0,40)\n");
986                 conv_err(3, asn_oid {2, {1, 40}}, ASN_ERR_RANGE,
987                         "oid out of range (1,40)\n");
988                 conv_err(3, asn_oid {2, {2, 4294967216}}, ASN_ERR_RANGE,
989                         "oid out of range (2,4294967216)\n");
990         }
991         SECTION("oid too long") {
992                 conv_err(200, asn_oid {129, {}}, ASN_ERR_RANGE,
993                         "oid too long 129\n");
994         }
995         SECTION("oid too short") {
996                 conv_err(3, asn_oid {0, {}}, ASN_ERR_RANGE,
997                         "short oid\n");
998                 conv_err(3, asn_oid {1, {0}}, ASN_ERR_RANGE,
999                         "short oid\n");
1000                 conv_err(3, asn_oid {1, {3}}, ASN_ERR_RANGE,
1001                         "oid[0] too large (3)\n");
1002         }
1003
1004         /* maximum OID */
1005         conv(5 * (128 - 1) + 4, asn_oid {128, {
1006                 2, 4294967215, 4294967295, 4294967295, 
1007                 4294967295, 4294967295, 4294967295, 4294967295, 
1008                 4294967295, 4294967295, 4294967295, 4294967295, 
1009                 4294967295, 4294967295, 4294967295, 4294967295, 
1010                 4294967295, 4294967295, 4294967295, 4294967295, 
1011                 4294967295, 4294967295, 4294967295, 4294967295, 
1012                 4294967295, 4294967295, 4294967295, 4294967295, 
1013                 4294967295, 4294967295, 4294967295, 4294967295, 
1014                 4294967295, 4294967295, 4294967295, 4294967295, 
1015                 4294967295, 4294967295, 4294967295, 4294967295, 
1016                 4294967295, 4294967295, 4294967295, 4294967295, 
1017                 4294967295, 4294967295, 4294967295, 4294967295, 
1018                 4294967295, 4294967295, 4294967295, 4294967295, 
1019                 4294967295, 4294967295, 4294967295, 4294967295, 
1020                 4294967295, 4294967295, 4294967295, 4294967295, 
1021                 4294967295, 4294967295, 4294967295, 4294967295, 
1022                 4294967295, 4294967295, 4294967295, 4294967295, 
1023                 4294967295, 4294967295, 4294967295, 4294967295, 
1024                 4294967295, 4294967295, 4294967295, 4294967295, 
1025                 4294967295, 4294967295, 4294967295, 4294967295, 
1026                 4294967295, 4294967295, 4294967295, 4294967295, 
1027                 4294967295, 4294967295, 4294967295, 4294967295, 
1028                 4294967295, 4294967295, 4294967295, 4294967295, 
1029                 4294967295, 4294967295, 4294967295, 4294967295, 
1030                 4294967295, 4294967295, 4294967295, 4294967295, 
1031                 4294967295, 4294967295, 4294967295, 4294967295, 
1032                 4294967295, 4294967295, 4294967295, 4294967295, 
1033                 4294967295, 4294967295, 4294967295, 4294967295, 
1034                 4294967295, 4294967295, 4294967295, 4294967295, 
1035                 4294967295, 4294967295, 4294967295, 4294967295, 
1036                 4294967295, 4294967295, 4294967295, 4294967295, 
1037                 4294967295, 4294967295, 4294967295, 4294967295, 
1038         }}, "x06:82:02:7b:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f:8f:ff:ff:ff:7f"_cbuf);
1039 }
1040
1041 /* loop tests */