xref: /openbsd-src/regress/lib/libcrypto/asn1/x509_algor.c (revision 00ee6dc427d95fe592c72cbcf5ff01b806355374)
1 /*	$OpenBSD: x509_algor.c,v 1.7 2024/02/29 20:03:47 tb Exp $ */
2 /*
3  * Copyright (c) 2023 Theo Buehler <tb@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <err.h>
19 #include <stdio.h>
20 
21 #include <openssl/asn1.h>
22 #include <openssl/evp.h>
23 #include <openssl/objects.h>
24 #include <openssl/x509.h>
25 
26 int X509_ALGOR_set_evp_md(X509_ALGOR *alg, const EVP_MD *md);
27 
28 static int
x509_algor_new_test(void)29 x509_algor_new_test(void)
30 {
31 	X509_ALGOR *alg = NULL;
32 	const ASN1_OBJECT *aobj;
33 	int failed = 1;
34 
35 	if ((alg = X509_ALGOR_new()) == NULL)
36 		errx(1, "%s: X509_ALGOR_new", __func__);
37 
38 	if ((aobj = OBJ_nid2obj(NID_undef)) == NULL)
39 		errx(1, "%s: OBJ_nid2obj", __func__);
40 
41 	if (alg->algorithm != aobj) {
42 		fprintf(stderr, "FAIL: %s: want NID_undef OID\n", __func__);
43 		goto failure;
44 	}
45 	if (alg->parameter != NULL) {
46 		fprintf(stderr, "FAIL: %s: want NULL parameters\n", __func__);
47 		goto failure;
48 	}
49 
50 	failed = 0;
51 
52  failure:
53 	X509_ALGOR_free(alg);
54 
55 	return failed;
56 }
57 
58 static int
x509_algor_set0_test(void)59 x509_algor_set0_test(void)
60 {
61 	X509_ALGOR *alg = NULL;
62 	ASN1_TYPE *old_parameter;
63 	ASN1_OBJECT *oid;
64 	ASN1_INTEGER *aint = NULL, *aint_ref;
65 	int ret;
66 	int failed = 1;
67 
68 	if ((ret = X509_ALGOR_set0(NULL, NULL, 0, NULL)) != 0) {
69 		fprintf(stderr, "FAIL: %s: X509_ALGOR_set0(NULL, NULL, 0, NULL)"
70 		    ", want: %d, got %d\n", __func__, 0, ret);
71 		goto failure;
72 	}
73 
74 	if ((alg = X509_ALGOR_new()) == NULL)
75 		errx(1, "%s: X509_ALGOR_new", __func__);
76 
77 	/* This sets algorithm to NULL and allocates new parameters. */
78 	if ((ret = X509_ALGOR_set0(alg, NULL, 0, NULL)) != 1) {
79 		fprintf(stderr, "FAIL: %s: X509_ALGOR_set0(alg, NULL, 0, NULL)"
80 		    ", want: %d, got %d\n", __func__, 1, ret);
81 		goto failure;
82 	}
83 	if (alg->algorithm != NULL) {
84 		fprintf(stderr, "FAIL: %s: want NULL algorithm after "
85 		    "X509_ALGOR_set0(alg, NULL, 0, NULL)\n", __func__);
86 		goto failure;
87 	}
88 	if ((old_parameter = alg->parameter) == NULL) {
89 		fprintf(stderr, "FAIL: %s: want non-NULL parameter after "
90 		    "X509_ALGOR_set0(alg, NULL, 0, NULL)\n", __func__);
91 		goto failure;
92 	}
93 	if (alg->parameter->type != V_ASN1_UNDEF) {
94 		fprintf(stderr, "FAIL: %s: want %d parameter type after "
95 		    "X509_ALGOR_set0(alg, NULL, 0, NULL), got %d\n",
96 		    __func__, V_ASN1_UNDEF, alg->parameter->type);
97 		goto failure;
98 	}
99 	if (alg->parameter->value.ptr != NULL) {
100 		fprintf(stderr, "FAIL: %s: want NULL parameter value after "
101 		    "X509_ALGOR_set0(alg, NULL, 0, NULL)\n", __func__);
102 		goto failure;
103 	}
104 
105 	/* This should leave algorithm at NULL and parameters untouched. */
106 	if ((ret = X509_ALGOR_set0(alg, NULL, 0, NULL)) != 1) {
107 		fprintf(stderr, "FAIL: %s: X509_ALGOR_set0(alg, NULL, 0, NULL)"
108 		    ", want: %d, got %d\n", __func__, 1, ret);
109 		goto failure;
110 	}
111 	if (alg->algorithm != NULL) {
112 		fprintf(stderr, "FAIL: %s: want NULL algorithm after second"
113 		    "X509_ALGOR_set0(alg, NULL, 0, NULL)\n", __func__);
114 		goto failure;
115 	}
116 	if (alg->parameter != old_parameter) {
117 		fprintf(stderr, "FAIL: %s: parameter changed after second"
118 		    "X509_ALGOR_set0(alg, NULL, 0, NULL)\n", __func__);
119 		goto failure;
120 	}
121 
122 	/* This ignores pval (old_parameter). */
123 	if ((ret = X509_ALGOR_set0(alg, NULL, 0, old_parameter)) != 1) {
124 		fprintf(stderr, "FAIL: %s: X509_ALGOR_set0(alg, NULL, 0, ptr)"
125 		    ", want: %d, got %d\n", __func__, 1, ret);
126 		goto failure;
127 	}
128 	if (alg->algorithm != NULL) {
129 		fprintf(stderr, "FAIL: %s: want NULL algorithm after "
130 		    "X509_ALGOR_set0(alg, NULL, 0, ptr)\n", __func__);
131 		goto failure;
132 	}
133 	if (alg->parameter == NULL) {
134 		fprintf(stderr, "FAIL: %s: want non-NULL parameter after "
135 		    "X509_ALGOR_set0(alg, NULL, 0, ptr)\n", __func__);
136 		goto failure;
137 	}
138 	if (alg->parameter->type != V_ASN1_UNDEF) {
139 		fprintf(stderr, "FAIL: %s: want %d parameter type after "
140 		    "X509_ALGOR_set0(alg, NULL, 0, ptr), got %d\n",
141 		    __func__, V_ASN1_UNDEF, alg->parameter->type);
142 		goto failure;
143 	}
144 	if (alg->parameter->value.ptr != NULL) {
145 		fprintf(stderr, "FAIL: %s: want NULL parameter value after "
146 		    "X509_ALGOR_set0(alg, NULL, 0, ptr)\n", __func__);
147 		goto failure;
148 	}
149 
150 	old_parameter = NULL;
151 
152 	/* This frees parameters and ignores pval. */
153 	if ((ret = X509_ALGOR_set0(alg, NULL, V_ASN1_UNDEF, NULL)) != 1) {
154 		fprintf(stderr, "FAIL: %s: "
155 		    "X509_ALGOR_set0(alg, NULL, V_ASN1_UNDEF, NULL)"
156 		    ", want: %d, got %d\n", __func__, 1, ret);
157 		goto failure;
158 	}
159 	if (alg->algorithm != NULL) {
160 		fprintf(stderr, "FAIL: %s: want NULL algorithm after "
161 		    "X509_ALGOR_set0(alg, NULL, V_ASN1_UNDEF, NULL)\n", __func__);
162 		goto failure;
163 	}
164 	if (alg->parameter != NULL) {
165 		fprintf(stderr, "FAIL: %s: want NULL parameter after "
166 		    "X509_ALGOR_set0(alg, NULL, V_ASN1_UNDEF, NULL)\n", __func__);
167 		goto failure;
168 	}
169 
170 	/* This frees parameters and ignores "foo". */
171 	if ((ret = X509_ALGOR_set0(alg, NULL, V_ASN1_UNDEF, "foo")) != 1) {
172 		fprintf(stderr, "FAIL: %s: X509_ALGOR_set0(alg, NULL, 0, \"foo\")"
173 		    ", want: %d, got %d\n", __func__, 1, ret);
174 		goto failure;
175 	}
176 	if (alg->algorithm != NULL) {
177 		fprintf(stderr, "FAIL: %s: want NULL algorithm after "
178 		    "X509_ALGOR_set0(alg, NULL, V_ASN1_UNDEF, \"foo\")\n", __func__);
179 		goto failure;
180 	}
181 	if (alg->parameter != NULL) {
182 		fprintf(stderr, "FAIL: %s: want NULL parameter after "
183 		    "X509_ALGOR_set0(alg, NULL, V_ASN1_UNDEF, \"foo\")\n", __func__);
184 		goto failure;
185 	}
186 
187 	if ((oid = OBJ_nid2obj(NID_sha512_224)) == NULL) {
188 		fprintf(stderr, "FAIL: %s: OBJ_nid2obj(NID_sha512_224)\n", __func__);
189 		goto failure;
190 	}
191 	if ((aint = aint_ref = ASN1_INTEGER_new()) == NULL)
192 		errx(1, "%s: ASN1_INTEGER_new()", __func__);
193 	if (!ASN1_INTEGER_set_uint64(aint, 57))
194 		errx(1, "%s: ASN1_INTEGER_set_uint64()", __func__);
195 
196 	if ((ret = X509_ALGOR_set0(alg, oid, V_ASN1_INTEGER, aint)) != 1) {
197 		fprintf(stderr, "Fail: %s: "
198 		    "X509_ALGOR_set0(alg, oid, V_ASN1_INTEGER, aint)"
199 		    ", want: %d, got %d\n", __func__, 1, ret);
200 		goto failure;
201 	}
202 	aint = NULL;
203 	if (alg->algorithm != oid) {
204 		fprintf(stderr, "FAIL: %s: unexpected oid on alg after "
205 		    "X509_ALGOR_set0(alg, oid, V_ASN1_INTEGER, aint)"
206 		    ", want: %d, got %d\n", __func__, 1, ret);
207 		goto failure;
208 	}
209 	if (alg->parameter == NULL) {
210 		fprintf(stderr, "FAIL: %s: expected non-NULL parameter after "
211 		    "X509_ALGOR_set0(alg, oid, V_ASN1_INTEGER, aint)"
212 		    ", want: %d, got %d\n", __func__, 1, ret);
213 		goto failure;
214 	}
215 	if (alg->parameter->type != V_ASN1_INTEGER) {
216 		fprintf(stderr, "FAIL: %s: want %d parameter type after "
217 		    "X509_ALGOR_set0(alg, oid, V_ASN1_INTEGER, aint), got %d\n",
218 		    __func__, V_ASN1_INTEGER, alg->parameter->type);
219 		goto failure;
220 	}
221 	if (alg->parameter->value.asn1_string != aint_ref) {
222 		fprintf(stderr, "FAIL: %s: unexpected parameter value after "
223 		    "X509_ALGOR_set0(alg, oid, V_ASN1_NULL, aint)\n", __func__);
224 		goto failure;
225 	}
226 
227 	failed = 0;
228 
229  failure:
230 	X509_ALGOR_free(alg);
231 	ASN1_INTEGER_free(aint);
232 
233 	return failed;
234 }
235 
236 static int
x509_algor_get0_test(void)237 x509_algor_get0_test(void)
238 {
239 	X509_ALGOR *alg;
240 	const ASN1_OBJECT *aobj = NULL;
241 	int ptype = 0;
242 	const void *pval = NULL;
243 	ASN1_OBJECT *oid;
244 	ASN1_INTEGER *aint = NULL, *aint_ref = NULL;
245 	int ret;
246 	int failed = 1;
247 
248 	if ((alg = X509_ALGOR_new()) == NULL)
249 		errx(1, "%s: X509_ALGOR_new", __func__);
250 
251 	X509_ALGOR_get0(&aobj, NULL, NULL, alg);
252 	if (aobj == NULL) {
253 		fprintf(stderr, "FAIL: %s: expected non-NULL aobj\n", __func__);
254 		goto failure;
255 	}
256 	X509_ALGOR_get0(NULL, &ptype, NULL, alg);
257 	if (ptype != V_ASN1_UNDEF) {
258 		fprintf(stderr, "FAIL: %s: want %d, got %d\n",
259 		    __func__, V_ASN1_UNDEF, ptype);
260 		goto failure;
261 	}
262 
263 	if ((oid = OBJ_nid2obj(NID_ED25519)) == NULL)
264 		errx(1, "%s: OBJ_nid2obj(NID_ED25519)", __func__);
265 	if ((aint = aint_ref = ASN1_INTEGER_new()) == NULL)
266 		errx(1, "%s: ASN1_INTEGER_new()", __func__);
267 	if (!ASN1_INTEGER_set_uint64(aint, 99))
268 		errx(1, "%s: ASN1_INTEGER_set_uint64()", __func__);
269 
270 	if ((ret = X509_ALGOR_set0(alg, oid, V_ASN1_INTEGER, aint)) != 1) {
271 		fprintf(stderr, "Fail: %s: "
272 		    "X509_ALGOR_set0(alg, oid, V_ASN1_INTEGER, aint)"
273 		    ", want: %d, got %d\n", __func__, 1, ret);
274 		goto failure;
275 	}
276 	aint = NULL;
277 
278 	X509_ALGOR_get0(&aobj, NULL, NULL, alg);
279 	if (aobj != oid) {
280 		fprintf(stderr, "FAIL: %s: expected Ed25519 oid\n", __func__);
281 		goto failure;
282 	}
283 	X509_ALGOR_get0(NULL, &ptype, NULL, alg);
284 	if (ptype != V_ASN1_INTEGER) {
285 		fprintf(stderr, "FAIL: %s: expected %d, got %d\n",
286 		    __func__, V_ASN1_INTEGER, ptype);
287 		goto failure;
288 	}
289 	pval = oid;
290 	X509_ALGOR_get0(NULL, NULL, &pval, alg);
291 	if (pval != NULL) {
292 		fprintf(stderr, "FAIL: %s: got non-NULL pval\n", __func__);
293 		goto failure;
294 	}
295 
296 	aobj = NULL;
297 	ptype = V_ASN1_UNDEF;
298 	pval = oid;
299 	X509_ALGOR_get0(&aobj, &ptype, &pval, alg);
300 	if (aobj != oid) {
301 		fprintf(stderr, "FAIL: %s: expected Ed25519 oid 2\n", __func__);
302 		goto failure;
303 	}
304 	if (ptype != V_ASN1_INTEGER) {
305 		fprintf(stderr, "FAIL: %s: expected %d, got %d 2\n",
306 		    __func__, V_ASN1_INTEGER, ptype);
307 		goto failure;
308 	}
309 	if (pval != aint_ref) {
310 		fprintf(stderr, "FAIL: %s: expected ASN.1 integer\n", __func__);
311 		goto failure;
312 	}
313 
314 	failed = 0;
315 
316  failure:
317 	X509_ALGOR_free(alg);
318 	ASN1_INTEGER_free(aint);
319 
320 	return failed;
321 }
322 
323 static int
x509_algor_set_evp_md_test(void)324 x509_algor_set_evp_md_test(void)
325 {
326 	X509_ALGOR *alg = NULL;
327 	const ASN1_OBJECT *aobj;
328 	int ptype = 0, nid = 0;
329 	int failed = 1;
330 
331 	if ((alg = X509_ALGOR_new()) == NULL)
332 		errx(1, "%s: X509_ALGOR_new", __func__);
333 
334 	if (!X509_ALGOR_set_evp_md(alg, EVP_sm3())) {
335 		fprintf(stderr, "%s: X509_ALGOR_set_evp_md to sm3 failed\n",
336 		    __func__);
337 		goto failure;
338 	}
339 	X509_ALGOR_get0(&aobj, &ptype, NULL, alg);
340 	if ((nid = OBJ_obj2nid(aobj)) != NID_sm3) {
341 		fprintf(stderr, "%s: sm3 want %d, got %d\n", __func__,
342 		    NID_sm3, nid);
343 		goto failure;
344 	}
345 	if (ptype != V_ASN1_UNDEF) {
346 		fprintf(stderr, "%s: sm3 want %d, got %d\n", __func__,
347 		    V_ASN1_UNDEF, ptype);
348 		goto failure;
349 	}
350 
351 	/* Preallocate as recommended in the manual. */
352 	if (!X509_ALGOR_set0(alg, NULL, 0, NULL))
353 		errx(1, "%s: X509_ALGOR_set0", __func__);
354 
355 	if (!X509_ALGOR_set_evp_md(alg, EVP_md5())) {
356 		fprintf(stderr, "%s: X509_ALGOR_set_evp_md to md5 failed\n",
357 		    __func__);
358 		goto failure;
359 	}
360 	X509_ALGOR_get0(&aobj, &ptype, NULL, alg);
361 	if ((nid = OBJ_obj2nid(aobj)) != NID_md5) {
362 		fprintf(stderr, "%s: md5 want %d, got %d\n", __func__,
363 		    NID_sm3, nid);
364 		goto failure;
365 	}
366 	if (ptype != V_ASN1_NULL) {
367 		fprintf(stderr, "%s: md5 want %d, got %d\n", __func__,
368 		    V_ASN1_NULL, ptype);
369 		goto failure;
370 	}
371 
372 	failed = 0;
373 
374  failure:
375 	X509_ALGOR_free(alg);
376 
377 	return failed;
378 }
379 
380 int
main(void)381 main(void)
382 {
383 	int failed = 0;
384 
385 	failed |= x509_algor_new_test();
386 	failed |= x509_algor_set0_test();
387 	failed |= x509_algor_get0_test();
388 	failed |= x509_algor_set_evp_md_test();
389 
390 	return failed;
391 }
392