xref: /openbsd-src/regress/lib/libcrypto/objects/objectstest.c (revision cf62a661e0b23961a0695468d168b962fe3e33e3)
1*cf62a661Stb /* $OpenBSD: objectstest.c,v 1.8 2023/05/23 11:06:52 tb Exp $ */
23f4089c4Sjsing /*
33f4089c4Sjsing  * Copyright (c) 2017, 2022 Joel Sing <jsing@openbsd.org>
43f4089c4Sjsing  *
53f4089c4Sjsing  * Permission to use, copy, modify, and distribute this software for any
63f4089c4Sjsing  * purpose with or without fee is hereby granted, provided that the above
73f4089c4Sjsing  * copyright notice and this permission notice appear in all copies.
83f4089c4Sjsing  *
93f4089c4Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
103f4089c4Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
113f4089c4Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
123f4089c4Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
133f4089c4Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
143f4089c4Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
153f4089c4Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
163f4089c4Sjsing  */
173f4089c4Sjsing 
183f4089c4Sjsing #include <openssl/objects.h>
193f4089c4Sjsing 
203f4089c4Sjsing #include <err.h>
213f4089c4Sjsing #include <stdio.h>
223f4089c4Sjsing #include <string.h>
233f4089c4Sjsing 
243f4089c4Sjsing static void
hexdump(const unsigned char * buf,size_t len)253f4089c4Sjsing hexdump(const unsigned char *buf, size_t len)
263f4089c4Sjsing {
273f4089c4Sjsing 	size_t i;
283f4089c4Sjsing 
293f4089c4Sjsing 	for (i = 1; i <= len; i++)
303f4089c4Sjsing 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
313f4089c4Sjsing 
323f4089c4Sjsing 	fprintf(stderr, "\n");
333f4089c4Sjsing }
343f4089c4Sjsing 
353f4089c4Sjsing static int
obj_compare_bytes(const char * label,const unsigned char * d1,int len1,const unsigned char * d2,int len2)363f4089c4Sjsing obj_compare_bytes(const char *label, const unsigned char *d1, int len1,
373f4089c4Sjsing     const unsigned char *d2, int len2)
383f4089c4Sjsing {
393f4089c4Sjsing 	if (len1 != len2) {
403f4089c4Sjsing 		fprintf(stderr, "FAIL: %s - byte lengths differ "
417bb1a6cfStb 		    "(%d != %d)\n", label, len1, len2);
423f4089c4Sjsing 		fprintf(stderr, "Got:\n");
433f4089c4Sjsing 		hexdump(d1, len1);
443f4089c4Sjsing 		fprintf(stderr, "Want:\n");
453f4089c4Sjsing 		hexdump(d2, len2);
463f4089c4Sjsing 		return 0;
473f4089c4Sjsing 	}
483f4089c4Sjsing 	if (memcmp(d1, d2, len1) != 0) {
493f4089c4Sjsing 		fprintf(stderr, "FAIL: %s - bytes differ\n", label);
503f4089c4Sjsing 		fprintf(stderr, "Got:\n");
513f4089c4Sjsing 		hexdump(d1, len1);
523f4089c4Sjsing 		fprintf(stderr, "Want:\n");
533f4089c4Sjsing 		hexdump(d2, len2);
543f4089c4Sjsing 		return 0;
553f4089c4Sjsing 	}
563f4089c4Sjsing 	return 1;
573f4089c4Sjsing }
583f4089c4Sjsing 
593f4089c4Sjsing struct obj_test {
603f4089c4Sjsing 	const char *oid;
613f4089c4Sjsing 	const char *sn;
623f4089c4Sjsing 	const char *ln;
633f4089c4Sjsing 	int nid;
643f4089c4Sjsing 	uint8_t data[255];
653f4089c4Sjsing 	size_t data_len;
663f4089c4Sjsing };
673f4089c4Sjsing 
683f4089c4Sjsing struct obj_test obj_tests[] = {
693f4089c4Sjsing 	{
703f4089c4Sjsing 		.oid = NULL,
713f4089c4Sjsing 		.sn = "UNDEF",
723f4089c4Sjsing 		.ln = "undefined",
733f4089c4Sjsing 		.nid = NID_undef,
743f4089c4Sjsing 	},
753f4089c4Sjsing 	{
763f4089c4Sjsing 		.oid = "2.5.4.10",
773f4089c4Sjsing 		.sn = "O",
783f4089c4Sjsing 		.ln = "organizationName",
793f4089c4Sjsing 		.nid = NID_organizationName,
803f4089c4Sjsing 		.data = {
813f4089c4Sjsing 			0x55, 0x04, 0x0a,
823f4089c4Sjsing 		},
833f4089c4Sjsing 		.data_len = 3,
843f4089c4Sjsing 	},
853f4089c4Sjsing 	{
863f4089c4Sjsing 		.oid = "2.5.4.8",
873f4089c4Sjsing 		.sn = "ST",
883f4089c4Sjsing 		.ln = "stateOrProvinceName",
893f4089c4Sjsing 		.nid = NID_stateOrProvinceName,
903f4089c4Sjsing 		.data = {
913f4089c4Sjsing 			0x55, 0x04, 0x08,
923f4089c4Sjsing 		},
933f4089c4Sjsing 		.data_len = 3,
943f4089c4Sjsing 	},
953f4089c4Sjsing 	{
96c6a90018Sjsing 		.oid = "2.23.43.1",
97c6a90018Sjsing 		.sn = "wap-wsg",
98c6a90018Sjsing 		.nid = NID_wap_wsg,
99c6a90018Sjsing 		.data = {
100c6a90018Sjsing 			0x67, 0x2b, 0x01,
101c6a90018Sjsing 		},
102c6a90018Sjsing 		.data_len = 3,
103c6a90018Sjsing 	},
104c6a90018Sjsing 	{
1053f4089c4Sjsing 		.oid = "1.3.6.1.4.1.11129.2.4.5",
1063f4089c4Sjsing 		.sn = "ct_cert_scts",
1073f4089c4Sjsing 		.ln = "CT Certificate SCTs",
1083f4089c4Sjsing 		.nid = NID_ct_cert_scts,
1093f4089c4Sjsing 		.data = {
1103f4089c4Sjsing 			0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02,
1113f4089c4Sjsing 			0x04, 0x05,
1123f4089c4Sjsing 		},
1133f4089c4Sjsing 		.data_len = 10,
1143f4089c4Sjsing 	},
1153f4089c4Sjsing 	{
1163f4089c4Sjsing 		.oid = "1.3.6.1.4.1",
1173f4089c4Sjsing 		.sn = "enterprises",
1183f4089c4Sjsing 		.ln = "Enterprises",
1193f4089c4Sjsing 		.nid = NID_Enterprises,
1203f4089c4Sjsing 		.data = {
1213f4089c4Sjsing 			0x2b, 0x06, 0x01, 0x04, 0x01,
1223f4089c4Sjsing 		},
1233f4089c4Sjsing 		.data_len = 5,
1243f4089c4Sjsing 	},
1253f4089c4Sjsing 	{
1263f4089c4Sjsing 		.oid = "1.3.6.1.4.1.5454.1.70.6.11.2",
1273f4089c4Sjsing 		.nid = NID_undef,
1283f4089c4Sjsing 		.data = {
1293f4089c4Sjsing 			0x2b, 0x06, 0x01, 0x04, 0x01, 0xaa, 0x4e, 0x01,
1303f4089c4Sjsing 			0x46, 0x06, 0x0b, 0x02,
1313f4089c4Sjsing 		},
1323f4089c4Sjsing 		.data_len = 12,
1333f4089c4Sjsing 	},
1343f4089c4Sjsing 	{
1353f4089c4Sjsing 		.oid = "1.3.6.1.4.1.890.1.5.8.60.102.2",
1363f4089c4Sjsing 		.nid = NID_undef,
1373f4089c4Sjsing 		.data = {
1383f4089c4Sjsing 			0x2b, 0x06, 0x01, 0x04, 0x01, 0x86, 0x7a, 0x01,
1393f4089c4Sjsing 			0x05, 0x08, 0x3c, 0x66, 0x02,
1403f4089c4Sjsing 		},
1413f4089c4Sjsing 		.data_len = 13,
1423f4089c4Sjsing 	},
1433f4089c4Sjsing 	{
1443f4089c4Sjsing 		.oid = "1.3.6.1.4.1.173.7.3.4.1.1.26",
1453f4089c4Sjsing 		.nid = NID_undef,
1463f4089c4Sjsing 		.data = {
1473f4089c4Sjsing 			0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x2d, 0x07,
1483f4089c4Sjsing 			0x03, 0x04, 0x01, 0x01, 0x1a,
1493f4089c4Sjsing 		},
1503f4089c4Sjsing 		.data_len = 13,
1513f4089c4Sjsing 	},
1523f4089c4Sjsing };
1533f4089c4Sjsing 
1543f4089c4Sjsing #define N_OBJ_TESTS (sizeof(obj_tests) / sizeof(*obj_tests))
1553f4089c4Sjsing 
1563f4089c4Sjsing static int
obj_name_test(struct obj_test * ot)1573f4089c4Sjsing obj_name_test(struct obj_test *ot)
1583f4089c4Sjsing {
1593f4089c4Sjsing 	const char *ln, *sn;
1603f4089c4Sjsing 	int nid;
1613f4089c4Sjsing 	int failed = 1;
1623f4089c4Sjsing 
1633f4089c4Sjsing 	if (ot->ln != NULL) {
1643f4089c4Sjsing 		if ((nid = OBJ_ln2nid(ot->ln)) != ot->nid) {
1653f4089c4Sjsing 			fprintf(stderr, "FAIL: OBJ_ln2nid() for '%s' = %d, "
1663f4089c4Sjsing 			    "want %d\n", ot->ln, nid, ot->nid);
1673f4089c4Sjsing 			goto failed;
1683f4089c4Sjsing 		}
1693f4089c4Sjsing 		if ((ln = OBJ_nid2ln(ot->nid)) == NULL) {
1703f4089c4Sjsing 			fprintf(stderr, "FAIL: OBJ_nid2ln() for '%s' returned "
1713f4089c4Sjsing 			    "NULL\n", ot->oid);
1723f4089c4Sjsing 			goto failed;
1733f4089c4Sjsing 		}
1743f4089c4Sjsing 		if (strcmp(ln, ot->ln) != 0) {
1753f4089c4Sjsing 			fprintf(stderr, "FAIL: OBJ_nid2ln() for '%s' = '%s', "
1763f4089c4Sjsing 			    "want '%s'\n", ot->oid, ln, ot->ln);
1773f4089c4Sjsing 			goto failed;
1783f4089c4Sjsing 		}
1793f4089c4Sjsing 	}
1803f4089c4Sjsing 	if (ot->sn != NULL) {
1813f4089c4Sjsing 		if ((nid = OBJ_sn2nid(ot->sn)) != ot->nid) {
1823f4089c4Sjsing 			fprintf(stderr, "FAIL: OBJ_sn2nid() for '%s' = %d, "
1833f4089c4Sjsing 			    "want %d\n", ot->sn, nid, ot->nid);
1843f4089c4Sjsing 			goto failed;
1853f4089c4Sjsing 		}
1863f4089c4Sjsing 		if ((sn = OBJ_nid2sn(ot->nid)) == NULL) {
1873f4089c4Sjsing 			fprintf(stderr, "FAIL: OBJ_nid2sn() for '%s' returned "
1883f4089c4Sjsing 			    "NULL\n", ot->oid);
1893f4089c4Sjsing 			goto failed;
1903f4089c4Sjsing 		}
1913f4089c4Sjsing 		if (strcmp(sn, ot->sn) != 0) {
1923f4089c4Sjsing 			fprintf(stderr, "FAIL: OBJ_nid2sn() for '%s' = '%s', "
1933f4089c4Sjsing 			    "want '%s'\n", ot->oid, sn, ot->sn);
1943f4089c4Sjsing 			goto failed;
1953f4089c4Sjsing 		}
1963f4089c4Sjsing 	}
1973f4089c4Sjsing 
1983f4089c4Sjsing 	failed = 0;
1993f4089c4Sjsing 
2003f4089c4Sjsing  failed:
2013f4089c4Sjsing 	return failed;
2023f4089c4Sjsing }
2033f4089c4Sjsing 
2043f4089c4Sjsing static int
obj_name_tests(void)2053f4089c4Sjsing obj_name_tests(void)
2063f4089c4Sjsing {
2073f4089c4Sjsing 	int failed = 0;
2083f4089c4Sjsing 	size_t i;
2093f4089c4Sjsing 
2103f4089c4Sjsing 	for (i = 0; i < N_OBJ_TESTS; i++)
2113f4089c4Sjsing 		failed |= obj_name_test(&obj_tests[i]);
2123f4089c4Sjsing 
2133f4089c4Sjsing 	return failed;
2143f4089c4Sjsing }
2153f4089c4Sjsing 
2163f4089c4Sjsing static int
obj_nid_test(struct obj_test * ot)2173f4089c4Sjsing obj_nid_test(struct obj_test *ot)
2183f4089c4Sjsing {
2193f4089c4Sjsing 	ASN1_OBJECT *obj = NULL;
2203f4089c4Sjsing 	int nid;
2213f4089c4Sjsing 	int failed = 1;
2223f4089c4Sjsing 
2235829123cSjsing 	if (ot->nid == NID_undef && ot->oid != NULL)
2243f4089c4Sjsing 		return 0;
2253f4089c4Sjsing 
2263f4089c4Sjsing 	if ((obj = OBJ_nid2obj(ot->nid)) == NULL) {
2273f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_nid2obj() failed for '%s' (NID %d)\n",
2283f4089c4Sjsing 		    ot->oid, ot->nid);
2293f4089c4Sjsing 		goto failed;
2303f4089c4Sjsing 	}
2313f4089c4Sjsing 	if ((nid = OBJ_obj2nid(obj)) != ot->nid) {
2323f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2nid() failed for '%s' - got %d, "
2333f4089c4Sjsing 		    "want %d\n", ot->oid ? ot->oid : "undef", nid, ot->nid);
2343f4089c4Sjsing 		goto failed;
2353f4089c4Sjsing 	}
2363f4089c4Sjsing 
2373f4089c4Sjsing 	failed = 0;
2383f4089c4Sjsing 
2393f4089c4Sjsing  failed:
2403f4089c4Sjsing 	ASN1_OBJECT_free(obj);
2413f4089c4Sjsing 
2423f4089c4Sjsing 	return failed;
2433f4089c4Sjsing }
2443f4089c4Sjsing 
2453f4089c4Sjsing static int
obj_nid_tests(void)2463f4089c4Sjsing obj_nid_tests(void)
2473f4089c4Sjsing {
2483f4089c4Sjsing 	int failed = 0;
2493f4089c4Sjsing 	size_t i;
2503f4089c4Sjsing 
2513f4089c4Sjsing 	for (i = 0; i < N_OBJ_TESTS; i++)
2523f4089c4Sjsing 		failed |= obj_nid_test(&obj_tests[i]);
2533f4089c4Sjsing 
2543f4089c4Sjsing 	return failed;
2553f4089c4Sjsing }
2563f4089c4Sjsing 
2573f4089c4Sjsing static int
obj_oid_test(struct obj_test * ot)2583f4089c4Sjsing obj_oid_test(struct obj_test *ot)
2593f4089c4Sjsing {
2603f4089c4Sjsing 	ASN1_OBJECT *obj = NULL;
2613f4089c4Sjsing 	char buf[1024];
2623f4089c4Sjsing 	int len, nid;
2633f4089c4Sjsing 	int failed = 1;
2643f4089c4Sjsing 
2653f4089c4Sjsing 	if (ot->oid == NULL)
2663f4089c4Sjsing 		return 0;
2673f4089c4Sjsing 
268c6a90018Sjsing 	if ((obj = OBJ_txt2obj(ot->oid, 0)) == NULL) {
2693f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n", ot->oid);
2703f4089c4Sjsing 		goto failed;
2713f4089c4Sjsing 	}
2723f4089c4Sjsing 	if ((nid = OBJ_txt2nid(ot->oid)) != ot->nid) {
2733f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_txt2nid() failed for '%s', got %d "
2743f4089c4Sjsing 		    "want %d\n", ot->oid, nid, ot->nid);
2753f4089c4Sjsing 		goto failed;
2763f4089c4Sjsing 	}
2773f4089c4Sjsing 
2783f4089c4Sjsing 	if (!obj_compare_bytes("object data", OBJ_get0_data(obj), OBJ_length(obj),
2793f4089c4Sjsing 	    ot->data, ot->data_len))
2803f4089c4Sjsing 		goto failed;
2813f4089c4Sjsing 
2823f4089c4Sjsing 	len = OBJ_obj2txt(buf, sizeof(buf), obj, 1);
2833f4089c4Sjsing 	if (len <= 0 || (size_t)len >= sizeof(buf)) {
2843f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() failed for '%s'\n", ot->oid);
2853f4089c4Sjsing 		goto failed;
2863f4089c4Sjsing 	}
2873f4089c4Sjsing 	if (strcmp(buf, ot->oid) != 0) {
2883f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() returned '%s', want '%s'\n",
2893f4089c4Sjsing 		    buf, ot->oid);
2903f4089c4Sjsing 		goto failed;
2913f4089c4Sjsing 	}
2923f4089c4Sjsing 
293bf20c6a4Sjsing 	if ((OBJ_obj2txt(NULL, 0, obj, 1) != len)) {
294bf20c6a4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() with NULL buffer != %d\n",
295bf20c6a4Sjsing 		    len);
296bf20c6a4Sjsing 		goto failed;
297bf20c6a4Sjsing 	}
298bf20c6a4Sjsing 	if ((OBJ_obj2txt(buf, 3, obj, 1) != len)) {
299bf20c6a4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() with short buffer != %d\n",
300bf20c6a4Sjsing 		    len);
301bf20c6a4Sjsing 		goto failed;
302bf20c6a4Sjsing 	}
303bf20c6a4Sjsing 
3043f4089c4Sjsing 	failed = 0;
3053f4089c4Sjsing 
3063f4089c4Sjsing  failed:
3073f4089c4Sjsing 	ASN1_OBJECT_free(obj);
3083f4089c4Sjsing 
3093f4089c4Sjsing 	return failed;
3103f4089c4Sjsing }
3113f4089c4Sjsing 
3123f4089c4Sjsing static int
obj_oid_tests(void)3133f4089c4Sjsing obj_oid_tests(void)
3143f4089c4Sjsing {
3153f4089c4Sjsing 	int failed = 0;
3163f4089c4Sjsing 	size_t i;
3173f4089c4Sjsing 
3183f4089c4Sjsing 	for (i = 0; i < N_OBJ_TESTS; i++)
3193f4089c4Sjsing 		failed |= obj_oid_test(&obj_tests[i]);
3203f4089c4Sjsing 
3213f4089c4Sjsing 	return failed;
3223f4089c4Sjsing }
3233f4089c4Sjsing 
324c6a90018Sjsing static int
obj_txt_test(struct obj_test * ot)325c6a90018Sjsing obj_txt_test(struct obj_test *ot)
326c6a90018Sjsing {
327c6a90018Sjsing 	ASN1_OBJECT *obj = NULL;
328c6a90018Sjsing 	const char *want;
329c6a90018Sjsing 	char buf[1024];
330c6a90018Sjsing 	int len, nid;
331c6a90018Sjsing 	int failed = 1;
332c6a90018Sjsing 
333c6a90018Sjsing 	if (ot->oid == NULL)
334c6a90018Sjsing 		return 0;
335c6a90018Sjsing 
336c6a90018Sjsing 	if (ot->sn != NULL) {
337c6a90018Sjsing 		if ((obj = OBJ_txt2obj(ot->sn, 0)) == NULL) {
338c6a90018Sjsing 			fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n",
339c6a90018Sjsing 			    ot->sn);
340c6a90018Sjsing 			goto failed;
341c6a90018Sjsing 		}
342c6a90018Sjsing 		if ((nid = OBJ_obj2nid(obj)) != ot->nid) {
343c6a90018Sjsing 			fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s', "
344c6a90018Sjsing 			    "got nid %d want %d\n", ot->sn, nid, ot->nid);
345c6a90018Sjsing 			goto failed;
346c6a90018Sjsing 		}
347c6a90018Sjsing 		ASN1_OBJECT_free(obj);
348c6a90018Sjsing 		obj = NULL;
349c6a90018Sjsing 	}
350c6a90018Sjsing 	if (ot->ln != NULL) {
351c6a90018Sjsing 		if ((obj = OBJ_txt2obj(ot->ln, 0)) == NULL) {
352c6a90018Sjsing 			fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n",
353c6a90018Sjsing 			    ot->ln);
354c6a90018Sjsing 			goto failed;
355c6a90018Sjsing 		}
356c6a90018Sjsing 		if ((nid = OBJ_obj2nid(obj)) != ot->nid) {
357c6a90018Sjsing 			fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s', "
358c6a90018Sjsing 			    "got nid %d want %d\n", ot->ln, nid, ot->nid);
359c6a90018Sjsing 			goto failed;
360c6a90018Sjsing 		}
361c6a90018Sjsing 		ASN1_OBJECT_free(obj);
362c6a90018Sjsing 		obj = NULL;
363c6a90018Sjsing 	}
364c6a90018Sjsing 
365c6a90018Sjsing 	if ((obj = OBJ_txt2obj(ot->oid, 0)) == NULL) {
366c6a90018Sjsing 		fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s'\n", ot->oid);
367c6a90018Sjsing 		goto failed;
368c6a90018Sjsing 	}
369c6a90018Sjsing 	if ((nid = OBJ_obj2nid(obj)) != ot->nid) {
370c6a90018Sjsing 		fprintf(stderr, "FAIL: OBJ_txt2obj() failed for '%s', "
371c6a90018Sjsing 		    "got nid %d want %d\n", ot->oid, nid, ot->nid);
372c6a90018Sjsing 		goto failed;
373c6a90018Sjsing 	}
374c6a90018Sjsing 
375c6a90018Sjsing 	len = OBJ_obj2txt(buf, sizeof(buf), obj, 0);
376c6a90018Sjsing 	if (len <= 0 || (size_t)len >= sizeof(buf)) {
377c6a90018Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() failed for '%s'\n", ot->oid);
378c6a90018Sjsing 		goto failed;
379c6a90018Sjsing 	}
380c6a90018Sjsing 	want = ot->ln;
381c6a90018Sjsing 	if (want == NULL)
382c6a90018Sjsing 		want = ot->sn;
383c6a90018Sjsing 	if (want == NULL)
384c6a90018Sjsing 		want = ot->oid;
385c6a90018Sjsing 	if (strcmp(buf, want) != 0) {
386c6a90018Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() returned '%s', want '%s'\n",
387c6a90018Sjsing 		    buf, want);
388c6a90018Sjsing 		goto failed;
389c6a90018Sjsing 	}
390c6a90018Sjsing 
391c6a90018Sjsing 	failed = 0;
392c6a90018Sjsing 
393c6a90018Sjsing  failed:
394c6a90018Sjsing 	ASN1_OBJECT_free(obj);
395c6a90018Sjsing 
396c6a90018Sjsing 	return failed;
397c6a90018Sjsing }
398c6a90018Sjsing 
399c6a90018Sjsing static int
obj_txt_early_nul_test(void)4006183aea1Stb obj_txt_early_nul_test(void)
4016183aea1Stb {
4026183aea1Stb 	ASN1_OBJECT *obj = NULL;
4036183aea1Stb 	char buf[2];
4046183aea1Stb 	int failed = 1;
4056183aea1Stb 
4066183aea1Stb 	buf[0] = 'x';
4076183aea1Stb 	buf[1] = '\0';
4086183aea1Stb 
4096183aea1Stb 	if (OBJ_obj2txt(buf, sizeof(buf), NULL, 1) != 0) {
4106183aea1Stb 		fprintf(stderr, "FAIL: OBJ_obj2txt(NULL) succeded\n");
4116183aea1Stb 		goto failed;
4126183aea1Stb 	}
4136183aea1Stb 	if (buf[0] != '\0') {
4146183aea1Stb 		fprintf(stderr, "FAIL: OBJ_obj2txt(NULL) did not NUL terminate\n");
4156183aea1Stb 		goto failed;
4166183aea1Stb 	}
4176183aea1Stb 
4186183aea1Stb 	if ((obj = ASN1_OBJECT_new()) == NULL)
4196183aea1Stb 		errx(1, "ASN1_OBJECT_new");
4206183aea1Stb 
4216183aea1Stb 	buf[0] = 'x';
4226183aea1Stb 	buf[1] = '\0';
4236183aea1Stb 
4246183aea1Stb 	if (OBJ_obj2txt(buf, sizeof(buf), obj, 1) != 0) {
4256183aea1Stb 		fprintf(stderr, "FAIL: OBJ_obj2txt(obj) succeeded\n");
4266183aea1Stb 		goto failed;
4276183aea1Stb 	}
4286183aea1Stb 	if (buf[0] != '\0') {
4296183aea1Stb 		fprintf(stderr, "FAIL: OBJ_obj2txt(obj) did not NUL terminate\n");
4306183aea1Stb 		goto failed;
4316183aea1Stb 	}
4326183aea1Stb 
4336183aea1Stb 	failed = 0;
434*cf62a661Stb 
4356183aea1Stb  failed:
4366183aea1Stb 	ASN1_OBJECT_free(obj);
4376183aea1Stb 
4386183aea1Stb 	return failed;
4396183aea1Stb }
4406183aea1Stb 
4416183aea1Stb static int
obj_txt_tests(void)442c6a90018Sjsing obj_txt_tests(void)
443c6a90018Sjsing {
444c6a90018Sjsing 	int failed = 0;
445c6a90018Sjsing 	size_t i;
446c6a90018Sjsing 
447c6a90018Sjsing 	for (i = 0; i < N_OBJ_TESTS; i++)
448c6a90018Sjsing 		failed |= obj_txt_test(&obj_tests[i]);
449c6a90018Sjsing 
4506183aea1Stb 	failed |= obj_txt_early_nul_test();
4516183aea1Stb 
452c6a90018Sjsing 	return failed;
453c6a90018Sjsing }
454c6a90018Sjsing 
4553f4089c4Sjsing /* OID 1.3.18446744073709551615 (64 bits). */
4563f4089c4Sjsing const uint8_t asn1_large_oid1[] = {
4573f4089c4Sjsing 	0x06, 0x0b,
4583f4089c4Sjsing 	0x2b, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4593f4089c4Sjsing 	0xff, 0xff, 0x7f,
4603f4089c4Sjsing };
4613f4089c4Sjsing 
4623f4089c4Sjsing /* OID 1.3.18446744073709551616 (65 bits). */
4633f4089c4Sjsing const uint8_t asn1_large_oid2[] = {
4643f4089c4Sjsing 	0x06, 0x0b,
4653f4089c4Sjsing 	0x2b, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
4663f4089c4Sjsing 	0x80, 0x80, 0x00,
4673f4089c4Sjsing };
4683f4089c4Sjsing 
4693f4089c4Sjsing /* OID 1.3.340282366920938463463374607431768211455 (128 bits). */
4703f4089c4Sjsing const uint8_t asn1_large_oid3[] = {
4713f4089c4Sjsing 	0x06, 0x14,
4723f4089c4Sjsing 	0x2b, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4733f4089c4Sjsing 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4743f4089c4Sjsing 	0xff, 0xff, 0xff, 0x7f,
4753f4089c4Sjsing };
4763f4089c4Sjsing 
4773f4089c4Sjsing /* OID 1.3.115792089237316195423570985008687907853269984665640564039457584007913129639935 (256 bits). */
4783f4089c4Sjsing const uint8_t asn1_large_oid4[] = {
4793f4089c4Sjsing 	0x06, 0x26,
4803f4089c4Sjsing 	0x2b, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4813f4089c4Sjsing 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4823f4089c4Sjsing 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4833f4089c4Sjsing 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4843f4089c4Sjsing 	0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
4853f4089c4Sjsing };
4863f4089c4Sjsing 
4873f4089c4Sjsing struct oid_large_test {
4883f4089c4Sjsing 	const char *oid;
4893f4089c4Sjsing 	const uint8_t *asn1_der;
4903f4089c4Sjsing 	size_t asn1_der_len;
4913f4089c4Sjsing 	int obj2txt;
4923f4089c4Sjsing };
4933f4089c4Sjsing 
4943f4089c4Sjsing struct oid_large_test oid_large_tests[] = {
4953f4089c4Sjsing 	{
4963f4089c4Sjsing 		.oid = "1.3.18446744073709551615",
4973f4089c4Sjsing 		.asn1_der = asn1_large_oid1,
4983f4089c4Sjsing 		.asn1_der_len = sizeof(asn1_large_oid1),
4993f4089c4Sjsing 		.obj2txt = 1,
5003f4089c4Sjsing 	},
5013f4089c4Sjsing 	{
5023f4089c4Sjsing 		.oid = "1.3.18446744073709551616",
5033f4089c4Sjsing 		.asn1_der = asn1_large_oid2,
5043f4089c4Sjsing 		.asn1_der_len = sizeof(asn1_large_oid2),
5056aa8ab87Sjsing 		.obj2txt = 0,
5063f4089c4Sjsing 	},
5073f4089c4Sjsing 	{
5083f4089c4Sjsing 		.oid = "1.3.340282366920938463463374607431768211455",
5093f4089c4Sjsing 		.asn1_der = asn1_large_oid3,
5103f4089c4Sjsing 		.asn1_der_len = sizeof(asn1_large_oid3),
5116aa8ab87Sjsing 		.obj2txt = 0,
5123f4089c4Sjsing 	},
5133f4089c4Sjsing 	{
5143f4089c4Sjsing 		.oid = "1.3.115792089237316195423570985008687907853269984665640"
5153f4089c4Sjsing 		    "564039457584007913129639935",
5163f4089c4Sjsing 		.asn1_der = asn1_large_oid4,
5173f4089c4Sjsing 		.asn1_der_len = sizeof(asn1_large_oid4),
5186aa8ab87Sjsing 		.obj2txt = 0,
5193f4089c4Sjsing 	},
5203f4089c4Sjsing };
5213f4089c4Sjsing 
5223f4089c4Sjsing #define N_OID_LARGE_TESTS (sizeof(oid_large_tests) / sizeof(*oid_large_tests))
5233f4089c4Sjsing 
5243f4089c4Sjsing static int
obj_oid_large_test(size_t test_no,struct oid_large_test * olt)5253f4089c4Sjsing obj_oid_large_test(size_t test_no, struct oid_large_test *olt)
5263f4089c4Sjsing {
5273f4089c4Sjsing 	ASN1_OBJECT *obj = NULL;
5283f4089c4Sjsing 	const uint8_t *p;
5293f4089c4Sjsing 	char buf[1024];
5303f4089c4Sjsing 	int len;
5313f4089c4Sjsing 	int failed = 1;
5323f4089c4Sjsing 
5333f4089c4Sjsing 	p = olt->asn1_der;
5343f4089c4Sjsing 	if ((obj = d2i_ASN1_OBJECT(NULL, &p, olt->asn1_der_len)) == NULL) {
5353f4089c4Sjsing 		fprintf(stderr, "FAIL: d2i_ASN1_OBJECT() failed for large "
5363f4089c4Sjsing 		    "oid %zu\n", test_no);
5373f4089c4Sjsing 		goto failed;
5383f4089c4Sjsing 	}
5393f4089c4Sjsing 	len = OBJ_obj2txt(buf, sizeof(buf), obj, 1);
5403f4089c4Sjsing 	if (len < 0 || (size_t)len >= sizeof(buf)) {
5413f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() failed for large "
5423f4089c4Sjsing 		    "oid %zu\n", test_no);
5433f4089c4Sjsing 		goto failed;
5443f4089c4Sjsing 	}
5453f4089c4Sjsing 	if ((len != 0) != olt->obj2txt) {
5463f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() failed for large "
5473f4089c4Sjsing 		    "oid %zu\n", test_no);
5483f4089c4Sjsing 		goto failed;
5493f4089c4Sjsing 	}
5503f4089c4Sjsing 	if (len != 0 && strcmp(buf, olt->oid) != 0) {
5513f4089c4Sjsing 		fprintf(stderr, "FAIL: OBJ_obj2txt() returned '%s', want '%s'\n",
5523f4089c4Sjsing 		    buf, olt->oid);
5533f4089c4Sjsing 		goto failed;
5543f4089c4Sjsing 	}
5553f4089c4Sjsing 
5563f4089c4Sjsing 	failed = 0;
5573f4089c4Sjsing 
5583f4089c4Sjsing  failed:
5593f4089c4Sjsing 	ASN1_OBJECT_free(obj);
5603f4089c4Sjsing 
5613f4089c4Sjsing 	return failed;
5623f4089c4Sjsing }
5633f4089c4Sjsing 
5643f4089c4Sjsing static int
obj_oid_large_tests(void)5653f4089c4Sjsing obj_oid_large_tests(void)
5663f4089c4Sjsing {
5673f4089c4Sjsing 	int failed = 0;
5683f4089c4Sjsing 	size_t i;
5693f4089c4Sjsing 
5703f4089c4Sjsing 	for (i = 0; i < N_OID_LARGE_TESTS; i++)
5713f4089c4Sjsing 		failed |= obj_oid_large_test(i, &oid_large_tests[i]);
5723f4089c4Sjsing 
5733f4089c4Sjsing 	return failed;
5743f4089c4Sjsing }
5753f4089c4Sjsing 
5763f4089c4Sjsing int
main(int argc,char ** argv)5773f4089c4Sjsing main(int argc, char **argv)
5783f4089c4Sjsing {
5793f4089c4Sjsing 	int failed = 0;
5803f4089c4Sjsing 
5813f4089c4Sjsing 	failed |= obj_name_tests();
5823f4089c4Sjsing 	failed |= obj_nid_tests();
5833f4089c4Sjsing 	failed |= obj_oid_tests();
584c6a90018Sjsing 	failed |= obj_txt_tests();
5853f4089c4Sjsing 	failed |= obj_oid_large_tests();
5863f4089c4Sjsing 
5873f4089c4Sjsing 	return (failed);
5883f4089c4Sjsing }
589