1*00aa7573Stb /* $OpenBSD: asn1object.c,v 1.14 2024/05/29 17:23:05 tb Exp $ */
259af3462Sjsing /*
359af3462Sjsing * Copyright (c) 2017, 2021, 2022 Joel Sing <jsing@openbsd.org>
459af3462Sjsing *
559af3462Sjsing * Permission to use, copy, modify, and distribute this software for any
659af3462Sjsing * purpose with or without fee is hereby granted, provided that the above
759af3462Sjsing * copyright notice and this permission notice appear in all copies.
859af3462Sjsing *
959af3462Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1059af3462Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1159af3462Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1259af3462Sjsing * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1359af3462Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1459af3462Sjsing * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1559af3462Sjsing * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1659af3462Sjsing */
1759af3462Sjsing
1859af3462Sjsing #include <openssl/asn1.h>
1959af3462Sjsing #include <openssl/err.h>
20e23a4dcfStb #include <openssl/objects.h>
2159af3462Sjsing
2259af3462Sjsing #include <err.h>
2359af3462Sjsing #include <stdio.h>
2459af3462Sjsing #include <string.h>
2559af3462Sjsing
26c9675a23Stb #include "asn1_local.h"
2759af3462Sjsing
2859af3462Sjsing static void
hexdump(const unsigned char * buf,int len)29bd9c0476Stb hexdump(const unsigned char *buf, int len)
3059af3462Sjsing {
31bd9c0476Stb int i;
32bd9c0476Stb
33bd9c0476Stb if (len <= 0) {
34bd9c0476Stb fprintf(stderr, "<negative length %d>\n", len);
35bd9c0476Stb return;
36bd9c0476Stb }
3759af3462Sjsing
3859af3462Sjsing for (i = 1; i <= len; i++)
3959af3462Sjsing fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
4059af3462Sjsing
4159af3462Sjsing fprintf(stderr, "\n");
4259af3462Sjsing }
4359af3462Sjsing
4459af3462Sjsing static int
asn1_compare_bytes(const char * label,const unsigned char * d1,int len1,const unsigned char * d2,int len2)4559af3462Sjsing asn1_compare_bytes(const char *label, const unsigned char *d1, int len1,
4659af3462Sjsing const unsigned char *d2, int len2)
4759af3462Sjsing {
4859af3462Sjsing if (len1 != len2) {
4959af3462Sjsing fprintf(stderr, "FAIL: %s - byte lengths differ "
507bb1a6cfStb "(%d != %d)\n", label, len1, len2);
5159af3462Sjsing fprintf(stderr, "Got:\n");
5259af3462Sjsing hexdump(d1, len1);
5359af3462Sjsing fprintf(stderr, "Want:\n");
5459af3462Sjsing hexdump(d2, len2);
5559af3462Sjsing return 0;
5659af3462Sjsing }
5759af3462Sjsing if (memcmp(d1, d2, len1) != 0) {
5859af3462Sjsing fprintf(stderr, "FAIL: %s - bytes differ\n", label);
5959af3462Sjsing fprintf(stderr, "Got:\n");
6059af3462Sjsing hexdump(d1, len1);
6159af3462Sjsing fprintf(stderr, "Want:\n");
6259af3462Sjsing hexdump(d2, len2);
6359af3462Sjsing return 0;
6459af3462Sjsing }
6559af3462Sjsing return 1;
6659af3462Sjsing }
6759af3462Sjsing
6859af3462Sjsing struct asn1_object_test {
6959af3462Sjsing const char *oid;
7059af3462Sjsing const char *txt;
7159af3462Sjsing const uint8_t content[255];
7259af3462Sjsing size_t content_len;
7359af3462Sjsing const uint8_t der[255];
7459af3462Sjsing size_t der_len;
7559af3462Sjsing int want_error;
7659af3462Sjsing };
7759af3462Sjsing
7859af3462Sjsing struct asn1_object_test asn1_object_tests[] = {
7959af3462Sjsing {
80566d66a5Sjsing .oid = "2.5",
81566d66a5Sjsing .txt = "directory services (X.500)",
82566d66a5Sjsing .content = {
83566d66a5Sjsing 0x55,
84566d66a5Sjsing },
85566d66a5Sjsing .content_len = 1,
86566d66a5Sjsing .der = {
87566d66a5Sjsing 0x06, 0x01, 0x55,
88566d66a5Sjsing },
89566d66a5Sjsing .der_len = 3,
90566d66a5Sjsing },
91566d66a5Sjsing {
92566d66a5Sjsing .oid = "2.5.4",
93566d66a5Sjsing .txt = "X509",
94566d66a5Sjsing .content = {
95566d66a5Sjsing 0x55, 0x04,
96566d66a5Sjsing },
97566d66a5Sjsing .content_len = 2,
98566d66a5Sjsing .der = {
99566d66a5Sjsing 0x06, 0x02, 0x55, 0x04,
100566d66a5Sjsing },
101566d66a5Sjsing .der_len = 4,
102566d66a5Sjsing },
103566d66a5Sjsing {
10459af3462Sjsing .oid = "2.5.4.10",
10559af3462Sjsing .txt = "organizationName",
10659af3462Sjsing .content = {
10759af3462Sjsing 0x55, 0x04, 0x0a,
10859af3462Sjsing },
10959af3462Sjsing .content_len = 3,
11059af3462Sjsing .der = {
11159af3462Sjsing 0x06, 0x03, 0x55, 0x04, 0x0a,
11259af3462Sjsing },
11359af3462Sjsing .der_len = 5,
11459af3462Sjsing },
11559af3462Sjsing {
11659af3462Sjsing .oid = "2 5 4 10",
11759af3462Sjsing .txt = "organizationName",
11859af3462Sjsing .content = {
11959af3462Sjsing 0x55, 0x04, 0x0a,
12059af3462Sjsing },
12159af3462Sjsing .content_len = 3,
12259af3462Sjsing .der = {
12359af3462Sjsing 0x06, 0x03, 0x55, 0x04, 0x0a,
12459af3462Sjsing },
12559af3462Sjsing .der_len = 5,
12659af3462Sjsing },
12759af3462Sjsing {
128566d66a5Sjsing .oid = "2.5.0.0",
129566d66a5Sjsing .txt = "2.5.0.0",
130566d66a5Sjsing .content = {
131566d66a5Sjsing 0x55, 0x00, 0x00,
132566d66a5Sjsing },
133566d66a5Sjsing .content_len = 3,
134566d66a5Sjsing .der = {
135566d66a5Sjsing 0x06, 0x03, 0x55, 0x00, 0x00,
136566d66a5Sjsing },
137566d66a5Sjsing .der_len = 5,
138566d66a5Sjsing },
139566d66a5Sjsing {
140566d66a5Sjsing .oid = "0.0.0.0",
141566d66a5Sjsing .txt = "0.0.0.0",
142566d66a5Sjsing .content = {
143566d66a5Sjsing 0x00, 0x00, 0x00,
144566d66a5Sjsing },
145566d66a5Sjsing .content_len = 3,
146566d66a5Sjsing .der = {
147566d66a5Sjsing 0x06, 0x03, 0x00, 0x00, 0x00,
148566d66a5Sjsing },
149566d66a5Sjsing .der_len = 5,
150566d66a5Sjsing },
151566d66a5Sjsing {
15259af3462Sjsing .oid = "1.3.6.1.4.1.11129.2.4.5",
15359af3462Sjsing .txt = "CT Certificate SCTs",
15459af3462Sjsing .content = {
15559af3462Sjsing 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02,
15659af3462Sjsing 0x04, 0x05,
15759af3462Sjsing },
15859af3462Sjsing .content_len = 10,
15959af3462Sjsing .der = {
16059af3462Sjsing 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
16159af3462Sjsing 0x79, 0x02, 0x04, 0x05,
16259af3462Sjsing },
16359af3462Sjsing .der_len = 12,
16459af3462Sjsing },
16559af3462Sjsing {
166566d66a5Sjsing .oid = "2.00005.0000000000004.10",
167d612c80bSjsing .want_error = ASN1_R_INVALID_NUMBER,
168566d66a5Sjsing },
169566d66a5Sjsing {
17059af3462Sjsing .oid = "2..5.4.10",
171d612c80bSjsing .want_error = ASN1_R_INVALID_NUMBER,
17259af3462Sjsing },
17359af3462Sjsing {
17459af3462Sjsing .oid = "2.5..4.10",
175d612c80bSjsing .want_error = ASN1_R_INVALID_NUMBER,
17659af3462Sjsing },
17759af3462Sjsing {
17859af3462Sjsing .oid = "2.5.4..10",
179d612c80bSjsing .want_error = ASN1_R_INVALID_NUMBER,
18059af3462Sjsing },
18159af3462Sjsing {
18259af3462Sjsing .oid = "2.5.4.10.",
183d612c80bSjsing .want_error = ASN1_R_INVALID_NUMBER,
18459af3462Sjsing },
18559af3462Sjsing {
18659af3462Sjsing .oid = "3.5.4.10",
18759af3462Sjsing .want_error = ASN1_R_FIRST_NUM_TOO_LARGE,
18859af3462Sjsing },
18959af3462Sjsing {
190566d66a5Sjsing .oid = "0.40.4.10",
191566d66a5Sjsing .want_error = ASN1_R_SECOND_NUMBER_TOO_LARGE,
192566d66a5Sjsing },
193566d66a5Sjsing {
194566d66a5Sjsing .oid = "1.40.4.10",
195566d66a5Sjsing .want_error = ASN1_R_SECOND_NUMBER_TOO_LARGE,
196566d66a5Sjsing },
197566d66a5Sjsing {
19859af3462Sjsing .oid = "2",
19959af3462Sjsing .want_error = ASN1_R_MISSING_SECOND_NUMBER,
20059af3462Sjsing },
20159af3462Sjsing {
202d612c80bSjsing .oid = "2.5 4.10",
203d612c80bSjsing .want_error = ASN1_R_INVALID_SEPARATOR,
204d612c80bSjsing },
205d612c80bSjsing {
20659af3462Sjsing .oid = "2,5,4,10",
20759af3462Sjsing .want_error = ASN1_R_INVALID_SEPARATOR,
20859af3462Sjsing },
209566d66a5Sjsing {
210566d66a5Sjsing .oid = "2.5,4.10",
211566d66a5Sjsing .want_error = ASN1_R_INVALID_DIGIT,
212566d66a5Sjsing },
213566d66a5Sjsing {
214537fbc0eSjsing .oid = "2a.5.4.10",
215537fbc0eSjsing .want_error = ASN1_R_INVALID_SEPARATOR,
216537fbc0eSjsing },
217537fbc0eSjsing {
218566d66a5Sjsing .oid = "2.5a.4.10",
219566d66a5Sjsing .want_error = ASN1_R_INVALID_DIGIT,
220566d66a5Sjsing },
22159af3462Sjsing };
22259af3462Sjsing
22359af3462Sjsing #define N_ASN1_OBJECT_TESTS \
22459af3462Sjsing (sizeof(asn1_object_tests) / sizeof(*asn1_object_tests))
22559af3462Sjsing
22659af3462Sjsing static int
do_asn1_object_test(struct asn1_object_test * aot)22759af3462Sjsing do_asn1_object_test(struct asn1_object_test *aot)
22859af3462Sjsing {
22959af3462Sjsing ASN1_OBJECT *aobj = NULL;
23059af3462Sjsing uint8_t buf[1024];
23159af3462Sjsing const uint8_t *p;
232bd9c0476Stb uint8_t *der = NULL;
23359af3462Sjsing uint8_t *q;
23459af3462Sjsing int err, ret;
23559af3462Sjsing int failed = 1;
23659af3462Sjsing
23759af3462Sjsing ERR_clear_error();
23859af3462Sjsing
239566d66a5Sjsing ret = a2d_ASN1_OBJECT(NULL, 0, aot->oid, -1);
240566d66a5Sjsing if (ret < 0 || (size_t)ret != aot->content_len) {
241566d66a5Sjsing fprintf(stderr, "FAIL: a2d_ASN1_OBJECT('%s') = %d, want %zu\n",
242566d66a5Sjsing aot->oid, ret, aot->content_len);
243566d66a5Sjsing goto failed;
244566d66a5Sjsing }
24559af3462Sjsing ret = a2d_ASN1_OBJECT(buf, sizeof(buf), aot->oid, -1);
24659af3462Sjsing if (ret < 0 || (size_t)ret != aot->content_len) {
247566d66a5Sjsing fprintf(stderr, "FAIL: a2d_ASN1_OBJECT('%s') = %d, want %zu\n",
248566d66a5Sjsing aot->oid, ret, aot->content_len);
24959af3462Sjsing goto failed;
25059af3462Sjsing }
25159af3462Sjsing if (aot->content_len == 0) {
25259af3462Sjsing err = ERR_peek_error();
25359af3462Sjsing if (ERR_GET_REASON(err) != aot->want_error) {
254566d66a5Sjsing fprintf(stderr, "FAIL: a2d_ASN1_OBJECT('%s') - got "
255566d66a5Sjsing "error reason %d, want %d\n", aot->oid,
256566d66a5Sjsing ERR_GET_REASON(err), aot->want_error);
25759af3462Sjsing goto failed;
25859af3462Sjsing }
25959af3462Sjsing goto done;
26059af3462Sjsing }
26159af3462Sjsing
262566d66a5Sjsing if (!asn1_compare_bytes("ASN1_OBJECT content", buf, ret, aot->content,
263566d66a5Sjsing aot->content_len))
264566d66a5Sjsing goto failed;
265566d66a5Sjsing
26659af3462Sjsing p = aot->content;
26759af3462Sjsing if ((aobj = c2i_ASN1_OBJECT(NULL, &p, aot->content_len)) == NULL) {
26859af3462Sjsing fprintf(stderr, "FAIL: c2i_ASN1_OBJECT() failed\n");
26959af3462Sjsing goto failed;
27059af3462Sjsing }
27159af3462Sjsing
27259af3462Sjsing q = buf;
27359af3462Sjsing ret = i2d_ASN1_OBJECT(aobj, &q);
27459af3462Sjsing if (!asn1_compare_bytes("ASN1_OBJECT DER", buf, ret, aot->der,
27559af3462Sjsing aot->der_len))
27659af3462Sjsing goto failed;
27759af3462Sjsing
278bd9c0476Stb der = NULL;
279bd9c0476Stb ret = i2d_ASN1_OBJECT(aobj, &der);
280bd9c0476Stb if (!asn1_compare_bytes("ASN1_OBJECT DER", der, ret, aot->der,
281bd9c0476Stb aot->der_len))
282bd9c0476Stb goto failed;
283bd9c0476Stb
284bd9c0476Stb free(der);
285bd9c0476Stb der = NULL;
286bd9c0476Stb
28759af3462Sjsing ASN1_OBJECT_free(aobj);
28859af3462Sjsing aobj = NULL;
28959af3462Sjsing
29059af3462Sjsing p = aot->der;
29159af3462Sjsing if ((aobj = d2i_ASN1_OBJECT(NULL, &p, aot->der_len)) == NULL) {
29259af3462Sjsing fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed\n");
29359af3462Sjsing goto failed;
29459af3462Sjsing }
295dac92472Stb if (p != aot->der + aot->der_len) {
296dac92472Stb fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() p = %p, want %p\n",
297dac92472Stb p, aot->der + aot->der_len);
298dac92472Stb goto failed;
299dac92472Stb }
30059af3462Sjsing
30159af3462Sjsing if (aot->txt != NULL) {
30259af3462Sjsing ret = i2t_ASN1_OBJECT(buf, sizeof(buf), aobj);
30359af3462Sjsing if (ret <= 0 || (size_t)ret >= sizeof(buf)) {
30459af3462Sjsing fprintf(stderr, "FAIL: i2t_ASN1_OBJECT() failed\n");
30559af3462Sjsing goto failed;
30659af3462Sjsing }
30759af3462Sjsing if (strcmp(aot->txt, buf) != 0) {
30859af3462Sjsing fprintf(stderr, "FAIL: i2t_ASN1_OBJECT() = '%s', "
30959af3462Sjsing "want '%s'\n", buf, aot->txt);
31059af3462Sjsing goto failed;
31159af3462Sjsing }
31259af3462Sjsing }
31359af3462Sjsing
31459af3462Sjsing done:
31559af3462Sjsing failed = 0;
31659af3462Sjsing
31759af3462Sjsing failed:
31859af3462Sjsing ASN1_OBJECT_free(aobj);
319bd9c0476Stb free(der);
32059af3462Sjsing
32159af3462Sjsing return failed;
32259af3462Sjsing }
32359af3462Sjsing
32459af3462Sjsing static int
asn1_object_test(void)32559af3462Sjsing asn1_object_test(void)
32659af3462Sjsing {
32759af3462Sjsing int failed = 0;
32859af3462Sjsing size_t i;
32959af3462Sjsing
33059af3462Sjsing for (i = 0; i < N_ASN1_OBJECT_TESTS; i++)
33159af3462Sjsing failed |= do_asn1_object_test(&asn1_object_tests[i]);
33259af3462Sjsing
33359af3462Sjsing return failed;
33459af3462Sjsing }
33559af3462Sjsing
33659af3462Sjsing const uint8_t asn1_object_bad_content1[] = {
33759af3462Sjsing 0x55, 0x80, 0x04, 0x0a,
33859af3462Sjsing };
33959af3462Sjsing const uint8_t asn1_object_bad_content2[] = {
34059af3462Sjsing 0x55, 0x04, 0x8a,
34159af3462Sjsing };
34259af3462Sjsing
34359af3462Sjsing static int
asn1_object_bad_content_test(void)34459af3462Sjsing asn1_object_bad_content_test(void)
34559af3462Sjsing {
34659af3462Sjsing ASN1_OBJECT *aobj = NULL;
34759af3462Sjsing const uint8_t *p;
34859af3462Sjsing size_t len;
34959af3462Sjsing int failed = 1;
35059af3462Sjsing
35159af3462Sjsing p = asn1_object_bad_content1;
35259af3462Sjsing len = sizeof(asn1_object_bad_content1);
35359af3462Sjsing if ((aobj = c2i_ASN1_OBJECT(NULL, &p, len)) != NULL) {
35459af3462Sjsing fprintf(stderr, "FAIL: c2i_ASN1_OBJECT() succeeded with bad "
35559af3462Sjsing "content 1\n");
35659af3462Sjsing goto failed;
35759af3462Sjsing }
35859af3462Sjsing
35959af3462Sjsing p = asn1_object_bad_content2;
36059af3462Sjsing len = sizeof(asn1_object_bad_content2);
36159af3462Sjsing if ((aobj = c2i_ASN1_OBJECT(NULL, &p, len)) != NULL) {
36259af3462Sjsing fprintf(stderr, "FAIL: c2i_ASN1_OBJECT() succeeded with bad "
36359af3462Sjsing "content 2\n");
36459af3462Sjsing goto failed;
36559af3462Sjsing }
36659af3462Sjsing
36759af3462Sjsing failed = 0;
36859af3462Sjsing
36959af3462Sjsing failed:
37059af3462Sjsing ASN1_OBJECT_free(aobj);
37159af3462Sjsing
37259af3462Sjsing return failed;
37359af3462Sjsing }
37459af3462Sjsing
37559af3462Sjsing static int
asn1_object_txt_test(void)37659af3462Sjsing asn1_object_txt_test(void)
37759af3462Sjsing {
378a4cc8787Sjsing const char *obj_txt = "organizationName";
37959af3462Sjsing ASN1_OBJECT *aobj = NULL;
38059af3462Sjsing uint8_t small_buf[2];
38159af3462Sjsing const uint8_t *p;
38259af3462Sjsing int err, len, ret;
383a4cc8787Sjsing BIO *bio = NULL;
384a4cc8787Sjsing char *data;
385a4cc8787Sjsing long data_len;
38659af3462Sjsing int failed = 1;
38759af3462Sjsing
38859af3462Sjsing ERR_clear_error();
38959af3462Sjsing
39059af3462Sjsing ret = a2d_ASN1_OBJECT(small_buf, sizeof(small_buf), "1.2.3.4", -1);
39159af3462Sjsing if (ret != 0) {
39259af3462Sjsing fprintf(stderr, "FAIL: a2d_ASN1_OBJECT() with small buffer "
39359af3462Sjsing "returned %d, want %d\n", ret, 0);
39459af3462Sjsing goto failed;
39559af3462Sjsing }
39659af3462Sjsing err = ERR_peek_error();
39759af3462Sjsing if (ERR_GET_REASON(err) != ASN1_R_BUFFER_TOO_SMALL) {
39859af3462Sjsing fprintf(stderr, "FAIL: Got error reason %d, want %d\n",
39959af3462Sjsing ERR_GET_REASON(err), ASN1_R_BUFFER_TOO_SMALL);
40059af3462Sjsing goto failed;
40159af3462Sjsing }
40259af3462Sjsing
403566d66a5Sjsing p = &asn1_object_tests[2].der[0];
404566d66a5Sjsing len = asn1_object_tests[2].der_len;
40559af3462Sjsing aobj = d2i_ASN1_OBJECT(NULL, &p, len);
40659af3462Sjsing if (aobj == NULL) {
40759af3462Sjsing fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed\n");
40859af3462Sjsing goto failed;
40959af3462Sjsing }
41059af3462Sjsing ret = i2t_ASN1_OBJECT(small_buf, sizeof(small_buf), aobj);
411a4cc8787Sjsing if (ret < 0 || (unsigned long)ret != strlen(obj_txt)) {
41259af3462Sjsing fprintf(stderr, "FAIL: i2t_ASN1_OBJECT() with small buffer "
41334929b0aStb "returned %d, want %zu\n", ret, strlen(obj_txt));
414a4cc8787Sjsing goto failed;
415a4cc8787Sjsing }
416a4cc8787Sjsing
417a4cc8787Sjsing if ((bio = BIO_new(BIO_s_mem())) == NULL) {
418a4cc8787Sjsing fprintf(stderr, "FAIL: BIO_new() returned NULL\n");
419a4cc8787Sjsing goto failed;
420a4cc8787Sjsing }
421a4cc8787Sjsing ret = i2a_ASN1_OBJECT(bio, NULL);
422a4cc8787Sjsing if (ret != 4) {
423a4cc8787Sjsing fprintf(stderr, "FAIL: i2a_ASN1_OBJECT(_, NULL) returned %d, "
424a4cc8787Sjsing "want 4\n", ret);
425a4cc8787Sjsing goto failed;
426a4cc8787Sjsing }
427a4cc8787Sjsing data_len = BIO_get_mem_data(bio, &data);
428a4cc8787Sjsing if (ret != data_len || memcmp("NULL", data, data_len) != 0) {
429a4cc8787Sjsing fprintf(stderr, "FAIL: i2a_ASN1_OBJECT(_, NULL) did not return "
430a4cc8787Sjsing "'NULL'\n");
431a4cc8787Sjsing goto failed;
432a4cc8787Sjsing }
433a4cc8787Sjsing
4344141bb4bStb if ((ret = BIO_reset(bio)) <= 0) {
4354141bb4bStb fprintf(stderr, "FAIL: BIO_reset failed: ret = %d\n", ret);
4364141bb4bStb goto failed;
4374141bb4bStb }
438a4cc8787Sjsing ret = i2a_ASN1_OBJECT(bio, aobj);
439a4cc8787Sjsing if (ret < 0 || (unsigned long)ret != strlen(obj_txt)) {
440a4cc8787Sjsing fprintf(stderr, "FAIL: i2a_ASN1_OBJECT() returned %d, "
44134929b0aStb "want %zu\n", ret, strlen(obj_txt));
442a4cc8787Sjsing goto failed;
443a4cc8787Sjsing }
444a4cc8787Sjsing data_len = BIO_get_mem_data(bio, &data);
445a4cc8787Sjsing if (ret != data_len || memcmp(obj_txt, data, data_len) != 0) {
446a4cc8787Sjsing fprintf(stderr, "FAIL: i2a_ASN1_OBJECT() did not return "
447a4cc8787Sjsing "'%s'\n", obj_txt);
44859af3462Sjsing goto failed;
44959af3462Sjsing }
45059af3462Sjsing
45159af3462Sjsing failed = 0;
45259af3462Sjsing
45359af3462Sjsing failed:
45459af3462Sjsing ASN1_OBJECT_free(aobj);
455a4cc8787Sjsing BIO_free(bio);
45659af3462Sjsing
45759af3462Sjsing return failed;
45859af3462Sjsing }
45959af3462Sjsing
46059af3462Sjsing const uint8_t asn1_large_oid_der[] = {
46159af3462Sjsing 0x06, 0x26,
46259af3462Sjsing 0x2b, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46359af3462Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46459af3462Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46559af3462Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46659af3462Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
46759af3462Sjsing };
46859af3462Sjsing
46959af3462Sjsing static int
asn1_object_large_oid_test(void)47059af3462Sjsing asn1_object_large_oid_test(void)
47159af3462Sjsing {
47259af3462Sjsing ASN1_OBJECT *aobj = NULL;
47359af3462Sjsing uint8_t buf[1024];
47459af3462Sjsing const uint8_t *p;
475bd9c0476Stb uint8_t *der = NULL;
47659af3462Sjsing uint8_t *q;
47759af3462Sjsing int ret;
47859af3462Sjsing int failed = 1;
47959af3462Sjsing
48059af3462Sjsing p = asn1_large_oid_der;
48159af3462Sjsing aobj = d2i_ASN1_OBJECT(NULL, &p, sizeof(asn1_large_oid_der));
48259af3462Sjsing if (aobj == NULL) {
48359af3462Sjsing fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed with "
48459af3462Sjsing "large oid\n");
48559af3462Sjsing goto failed;
48659af3462Sjsing }
48759af3462Sjsing
48859af3462Sjsing q = buf;
48959af3462Sjsing ret = i2d_ASN1_OBJECT(aobj, &q);
49059af3462Sjsing if (!asn1_compare_bytes("ASN1_OBJECT DER", buf, ret, asn1_large_oid_der,
49159af3462Sjsing sizeof(asn1_large_oid_der)))
49259af3462Sjsing goto failed;
49359af3462Sjsing
494bd9c0476Stb der = NULL;
495bd9c0476Stb ret = i2d_ASN1_OBJECT(aobj, &der);
496bd9c0476Stb if (!asn1_compare_bytes("ASN1_OBJECT DER", der, ret, asn1_large_oid_der,
497bd9c0476Stb sizeof(asn1_large_oid_der)))
498bd9c0476Stb goto failed;
499bd9c0476Stb
50006a01064Stb failed = 0;
50106a01064Stb
50259af3462Sjsing failed:
50359af3462Sjsing ASN1_OBJECT_free(aobj);
504bd9c0476Stb free(der);
50559af3462Sjsing
50659af3462Sjsing return failed;
50759af3462Sjsing }
50859af3462Sjsing
509e23a4dcfStb static int
asn1_object_i2d_errors(void)510e23a4dcfStb asn1_object_i2d_errors(void)
511e23a4dcfStb {
512e23a4dcfStb ASN1_OBJECT *aobj = NULL;
513e23a4dcfStb int ret;
514e23a4dcfStb int failed = 1;
515e23a4dcfStb
516e23a4dcfStb if ((ret = i2d_ASN1_OBJECT(NULL, NULL)) > 0) {
517e23a4dcfStb fprintf(stderr, "FAIL: i2d_ASN1_OBJECT(NULL, NULL) returned %d, "
518e23a4dcfStb "want <= 0\n", ret);
519e23a4dcfStb goto failed;
520e23a4dcfStb }
521e23a4dcfStb
522e23a4dcfStb if ((aobj = OBJ_nid2obj(NID_undef)) == NULL) {
523e23a4dcfStb fprintf(stderr, "FAIL: OBJ_nid2obj() failed\n");
524e23a4dcfStb goto failed;
525e23a4dcfStb }
526e23a4dcfStb
527e23a4dcfStb if (OBJ_get0_data(aobj) != NULL) {
528e23a4dcfStb fprintf(stderr, "FAIL: undefined obj didn't have NULL data\n");
529e23a4dcfStb goto failed;
530e23a4dcfStb }
531e23a4dcfStb
532e23a4dcfStb if ((ret = i2d_ASN1_OBJECT(aobj, NULL)) > 0) {
533e23a4dcfStb fprintf(stderr, "FAIL: i2d_ASN1_OBJECT() succeeded on undefined "
534e23a4dcfStb "object\n");
535e23a4dcfStb goto failed;
536e23a4dcfStb }
537e23a4dcfStb
538e23a4dcfStb failed = 0;
539e23a4dcfStb
540e23a4dcfStb failed:
541e23a4dcfStb ASN1_OBJECT_free(aobj);
542e23a4dcfStb
543e23a4dcfStb return failed;
544e23a4dcfStb }
545e23a4dcfStb
54659af3462Sjsing int
main(int argc,char ** argv)54759af3462Sjsing main(int argc, char **argv)
54859af3462Sjsing {
54959af3462Sjsing int failed = 0;
55059af3462Sjsing
55159af3462Sjsing failed |= asn1_object_test();
55259af3462Sjsing failed |= asn1_object_bad_content_test();
55359af3462Sjsing failed |= asn1_object_txt_test();
55459af3462Sjsing failed |= asn1_object_large_oid_test();
555e23a4dcfStb failed |= asn1_object_i2d_errors();
55659af3462Sjsing
55759af3462Sjsing return (failed);
55859af3462Sjsing }
559