xref: /openbsd-src/usr.sbin/rpki-client/validate.c (revision d5abdd01d7a5f24fb6f9b0aab446ef59a9e9067a)
1 /*	$OpenBSD: validate.c,v 1.65 2023/06/07 11:09:08 tb Exp $ */
2 /*
3  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
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 <arpa/inet.h>
19 #include <assert.h>
20 #include <ctype.h>
21 #include <err.h>
22 #include <fcntl.h>
23 #include <inttypes.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 
28 #include "extern.h"
29 
30 extern ASN1_OBJECT	*certpol_oid;
31 
32 /*
33  * Walk up the chain of certificates trying to match our AS number to
34  * one of the allocations in that chain.
35  * Returns 1 if covered or 0 if not.
36  */
37 static int
38 valid_as(struct auth *a, uint32_t min, uint32_t max)
39 {
40 	int	 c;
41 
42 	if (a == NULL)
43 		return 0;
44 
45 	/* Does this certificate cover our AS number? */
46 	c = as_check_covered(min, max, a->cert->as, a->cert->asz);
47 	if (c > 0)
48 		return 1;
49 	else if (c < 0)
50 		return 0;
51 
52 	/* If it inherits, walk up the chain. */
53 	return valid_as(a->parent, min, max);
54 }
55 
56 /*
57  * Walk up the chain of certificates (really just the last one, but in
58  * the case of inheritance, the ones before) making sure that our IP
59  * prefix is covered in the first non-inheriting specification.
60  * Returns 1 if covered or 0 if not.
61  */
62 static int
63 valid_ip(struct auth *a, enum afi afi,
64     const unsigned char *min, const unsigned char *max)
65 {
66 	int	 c;
67 
68 	if (a == NULL)
69 		return 0;
70 
71 	/* Does this certificate cover our IP prefix? */
72 	c = ip_addr_check_covered(afi, min, max, a->cert->ips, a->cert->ipsz);
73 	if (c > 0)
74 		return 1;
75 	else if (c < 0)
76 		return 0;
77 
78 	/* If it inherits, walk up the chain. */
79 	return valid_ip(a->parent, afi, min, max);
80 }
81 
82 /*
83  * Make sure the AKI is the same as the AKI listed on the Manifest,
84  * and that the SKI doesn't already exist.
85  * Return the parent by its AKI, or NULL on failure.
86  */
87 struct auth *
88 valid_ski_aki(const char *fn, struct auth_tree *auths,
89     const char *ski, const char *aki, const char *mftaki)
90 {
91 	struct auth *a;
92 
93 	if (mftaki != NULL) {
94 		if (strcmp(aki, mftaki) != 0) {
95 			warnx("%s: AKI doesn't match Manifest AKI", fn);
96 			return NULL;
97 		}
98 	}
99 
100 	if (auth_find(auths, ski) != NULL) {
101 		warnx("%s: RFC 6487: duplicate SKI", fn);
102 		return NULL;
103 	}
104 
105 	a = auth_find(auths, aki);
106 	if (a == NULL)
107 		warnx("%s: RFC 6487: unknown AKI", fn);
108 
109 	return a;
110 }
111 
112 /*
113  * Validate a trust anchor by making sure that the SKI is unique.
114  * Returns 1 if valid, 0 otherwise.
115  */
116 int
117 valid_ta(const char *fn, struct auth_tree *auths, const struct cert *cert)
118 {
119 	/* SKI must not be a dupe. */
120 	if (auth_find(auths, cert->ski) != NULL) {
121 		warnx("%s: RFC 6487: duplicate SKI", fn);
122 		return 0;
123 	}
124 
125 	return 1;
126 }
127 
128 /*
129  * Validate a non-TA certificate: make sure its IP and AS resources are
130  * fully covered by those in the authority key (which must exist).
131  * Returns 1 if valid, 0 otherwise.
132  */
133 int
134 valid_cert(const char *fn, struct auth *a, const struct cert *cert)
135 {
136 	size_t		 i;
137 	uint32_t	 min, max;
138 	char		 buf1[64], buf2[64];
139 
140 	for (i = 0; i < cert->asz; i++) {
141 		if (cert->as[i].type == CERT_AS_INHERIT)
142 			continue;
143 		min = cert->as[i].type == CERT_AS_ID ?
144 		    cert->as[i].id : cert->as[i].range.min;
145 		max = cert->as[i].type == CERT_AS_ID ?
146 		    cert->as[i].id : cert->as[i].range.max;
147 		if (valid_as(a, min, max))
148 			continue;
149 		warnx("%s: RFC 6487: uncovered AS: "
150 		    "%u--%u", fn, min, max);
151 		return 0;
152 	}
153 
154 	for (i = 0; i < cert->ipsz; i++) {
155 		if (cert->ips[i].type == CERT_IP_INHERIT)
156 			continue;
157 		if (valid_ip(a, cert->ips[i].afi, cert->ips[i].min,
158 		    cert->ips[i].max))
159 			continue;
160 		switch (cert->ips[i].type) {
161 		case CERT_IP_RANGE:
162 			ip_addr_print(&cert->ips[i].range.min,
163 			    cert->ips[i].afi, buf1, sizeof(buf1));
164 			ip_addr_print(&cert->ips[i].range.max,
165 			    cert->ips[i].afi, buf2, sizeof(buf2));
166 			warnx("%s: RFC 6487: uncovered IP: "
167 			    "%s--%s", fn, buf1, buf2);
168 			break;
169 		case CERT_IP_ADDR:
170 			ip_addr_print(&cert->ips[i].ip,
171 			    cert->ips[i].afi, buf1, sizeof(buf1));
172 			warnx("%s: RFC 6487: uncovered IP: "
173 			    "%s", fn, buf1);
174 			break;
175 		case CERT_IP_INHERIT:
176 			warnx("%s: RFC 6487: uncovered IP: "
177 			    "(inherit)", fn);
178 			break;
179 		}
180 		return 0;
181 	}
182 
183 	return 1;
184 }
185 
186 /*
187  * Validate our ROA: check that the prefixes (ipAddrBlocks) are contained.
188  * Returns 1 if valid, 0 otherwise.
189  */
190 int
191 valid_roa(const char *fn, struct cert *cert, struct roa *roa)
192 {
193 	size_t	 i;
194 	char	 buf[64];
195 
196 	for (i = 0; i < roa->ipsz; i++) {
197 		if (ip_addr_check_covered(roa->ips[i].afi, roa->ips[i].min,
198 		    roa->ips[i].max, cert->ips, cert->ipsz) > 0)
199 			continue;
200 
201 		ip_addr_print(&roa->ips[i].addr, roa->ips[i].afi, buf,
202 		    sizeof(buf));
203 		warnx("%s: RFC 6482: uncovered IP: %s", fn, buf);
204 		return 0;
205 	}
206 
207 	return 1;
208 }
209 
210 /*
211  * Validate a file by verifying the SHA256 hash of that file.
212  * The file to check is passed as a file descriptor.
213  * Returns 1 if hash matched, 0 otherwise. Closes fd when done.
214  */
215 int
216 valid_filehash(int fd, const char *hash, size_t hlen)
217 {
218 	SHA256_CTX	ctx;
219 	char		filehash[SHA256_DIGEST_LENGTH];
220 	char		buffer[8192];
221 	ssize_t		nr;
222 
223 	if (hlen != sizeof(filehash))
224 		errx(1, "bad hash size");
225 
226 	if (fd == -1)
227 		return 0;
228 
229 	SHA256_Init(&ctx);
230 	while ((nr = read(fd, buffer, sizeof(buffer))) > 0)
231 		SHA256_Update(&ctx, buffer, nr);
232 	close(fd);
233 	SHA256_Final(filehash, &ctx);
234 
235 	if (memcmp(hash, filehash, sizeof(filehash)) != 0)
236 		return 0;
237 	return 1;
238 }
239 
240 /*
241  * Same as above but with a buffer instead of a fd.
242  */
243 int
244 valid_hash(unsigned char *buf, size_t len, const char *hash, size_t hlen)
245 {
246 	char	filehash[SHA256_DIGEST_LENGTH];
247 
248 	if (hlen != sizeof(filehash))
249 		errx(1, "bad hash size");
250 
251 	if (buf == NULL || len == 0)
252 		return 0;
253 
254 	if (!EVP_Digest(buf, len, filehash, NULL, EVP_sha256(), NULL))
255 		errx(1, "EVP_Digest failed");
256 
257 	if (memcmp(hash, filehash, sizeof(filehash)) != 0)
258 		return 0;
259 	return 1;
260 }
261 
262 /*
263  * Validate that a filename only contains characters from the POSIX portable
264  * filename character set [A-Za-z0-9._-], see IEEE Std 1003.1-2013, 3.278.
265  */
266 int
267 valid_filename(const char *fn, size_t len)
268 {
269 	const unsigned char *c;
270 	size_t i;
271 
272 	for (c = fn, i = 0; i < len; i++, c++)
273 		if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
274 			return 0;
275 	return 1;
276 }
277 
278 /*
279  * Validate a URI to make sure it is pure ASCII and does not point backwards
280  * or doing some other silly tricks. To enforce the protocol pass either
281  * https:// or rsync:// as proto, if NULL is passed no protocol is enforced.
282  * Returns 1 if valid, 0 otherwise.
283  */
284 int
285 valid_uri(const char *uri, size_t usz, const char *proto)
286 {
287 	size_t s;
288 
289 	if (usz > MAX_URI_LENGTH)
290 		return 0;
291 
292 	for (s = 0; s < usz; s++)
293 		if (!isalnum((unsigned char)uri[s]) &&
294 		    !ispunct((unsigned char)uri[s]))
295 			return 0;
296 
297 	if (proto != NULL) {
298 		s = strlen(proto);
299 		if (s >= usz)
300 			return 0;
301 		if (strncasecmp(uri, proto, s) != 0)
302 			return 0;
303 	}
304 
305 	/* do not allow files or directories to start with a '.' */
306 	if (strstr(uri, "/.") != NULL)
307 		return 0;
308 
309 	return 1;
310 }
311 
312 /*
313  * Validate that a URI has the same host as the URI passed in proto.
314  * Returns 1 if valid, 0 otherwise.
315  */
316 int
317 valid_origin(const char *uri, const char *proto)
318 {
319 	const char *to;
320 
321 	/* extract end of host from proto URI */
322 	to = strstr(proto, "://");
323 	if (to == NULL)
324 		return 0;
325 	to += strlen("://");
326 	if ((to = strchr(to, '/')) == NULL)
327 		return 0;
328 
329 	/* compare hosts including the / for the start of the path section */
330 	if (strncasecmp(uri, proto, to - proto + 1) != 0)
331 		return 0;
332 
333 	return 1;
334 }
335 
336 /*
337  * Walk the tree of known valid CA certificates until we find a certificate that
338  * doesn't inherit. Build a chain of intermediates and use the non-inheriting
339  * certificate as a trusted root by virtue of X509_V_FLAG_PARTIAL_CHAIN. The
340  * RFC 3779 path validation needs a non-inheriting trust root to ensure that
341  * all delegated resources are covered.
342  */
343 static void
344 build_chain(const struct auth *a, STACK_OF(X509) **intermediates,
345     STACK_OF(X509) **root)
346 {
347 	*intermediates = NULL;
348 	*root = NULL;
349 
350 	if (a == NULL)
351 		return;
352 
353 	if ((*intermediates = sk_X509_new_null()) == NULL)
354 		err(1, "sk_X509_new_null");
355 	if ((*root = sk_X509_new_null()) == NULL)
356 		err(1, "sk_X509_new_null");
357 	for (; a != NULL; a = a->parent) {
358 		assert(a->cert->x509 != NULL);
359 		if (!a->any_inherits) {
360 			if (!sk_X509_push(*root, a->cert->x509))
361 				errx(1, "sk_X509_push");
362 			break;
363 		}
364 		if (!sk_X509_push(*intermediates, a->cert->x509))
365 			errx(1, "sk_X509_push");
366 	}
367 	assert(sk_X509_num(*root) == 1);
368 }
369 
370 /*
371  * Add the CRL based on the certs SKI value.
372  * No need to insert any other CRL since those were already checked.
373  */
374 static void
375 build_crls(const struct crl *crl, STACK_OF(X509_CRL) **crls)
376 {
377 	*crls = NULL;
378 
379 	if (crl == NULL)
380 		return;
381 	if ((*crls = sk_X509_CRL_new_null()) == NULL)
382 		errx(1, "sk_X509_CRL_new_null");
383 	if (!sk_X509_CRL_push(*crls, crl->x509_crl))
384 		err(1, "sk_X509_CRL_push");
385 }
386 
387 /*
388  * Validate the X509 certificate. Returns 1 for valid certificates,
389  * returns 0 if there is a verify error and sets *errstr to the error
390  * returned by X509_verify_cert_error_string().
391  */
392 int
393 valid_x509(char *file, X509_STORE_CTX *store_ctx, X509 *x509, struct auth *a,
394     struct crl *crl, const char **errstr)
395 {
396 	X509_VERIFY_PARAM	*params;
397 	ASN1_OBJECT		*cp_oid;
398 	STACK_OF(X509)		*intermediates, *root;
399 	STACK_OF(X509_CRL)	*crls = NULL;
400 	unsigned long		 flags;
401 	int			 error;
402 
403 	*errstr = NULL;
404 	build_chain(a, &intermediates, &root);
405 	build_crls(crl, &crls);
406 
407 	assert(store_ctx != NULL);
408 	assert(x509 != NULL);
409 	if (!X509_STORE_CTX_init(store_ctx, NULL, x509, NULL))
410 		cryptoerrx("X509_STORE_CTX_init");
411 
412 	if ((params = X509_STORE_CTX_get0_param(store_ctx)) == NULL)
413 		cryptoerrx("X509_STORE_CTX_get0_param");
414 	if ((cp_oid = OBJ_dup(certpol_oid)) == NULL)
415 		cryptoerrx("OBJ_dup");
416 	if (!X509_VERIFY_PARAM_add0_policy(params, cp_oid))
417 		cryptoerrx("X509_VERIFY_PARAM_add0_policy");
418 	X509_VERIFY_PARAM_set_time(params, get_current_time());
419 
420 	flags = X509_V_FLAG_CRL_CHECK;
421 	flags |= X509_V_FLAG_PARTIAL_CHAIN;
422 	flags |= X509_V_FLAG_POLICY_CHECK;
423 	flags |= X509_V_FLAG_EXPLICIT_POLICY;
424 	flags |= X509_V_FLAG_INHIBIT_MAP;
425 	X509_STORE_CTX_set_flags(store_ctx, flags);
426 	X509_STORE_CTX_set_depth(store_ctx, MAX_CERT_DEPTH);
427 	/*
428 	 * See the comment above build_chain() for details on what's happening
429 	 * here. The nomenclature in this API is dubious and poorly documented.
430 	 */
431 	X509_STORE_CTX_set0_untrusted(store_ctx, intermediates);
432 	X509_STORE_CTX_set0_trusted_stack(store_ctx, root);
433 	X509_STORE_CTX_set0_crls(store_ctx, crls);
434 
435 	if (X509_verify_cert(store_ctx) <= 0) {
436 		error = X509_STORE_CTX_get_error(store_ctx);
437 		*errstr = X509_verify_cert_error_string(error);
438 		X509_STORE_CTX_cleanup(store_ctx);
439 		sk_X509_free(intermediates);
440 		sk_X509_free(root);
441 		sk_X509_CRL_free(crls);
442 		return 0;
443 	}
444 
445 	X509_STORE_CTX_cleanup(store_ctx);
446 	sk_X509_free(intermediates);
447 	sk_X509_free(root);
448 	sk_X509_CRL_free(crls);
449 	return 1;
450 }
451 
452 /*
453  * Validate our RSC: check that all items in the ResourceBlock are contained.
454  * Returns 1 if valid, 0 otherwise.
455  */
456 int
457 valid_rsc(const char *fn, struct cert *cert, struct rsc *rsc)
458 {
459 	size_t		i;
460 	uint32_t	min, max;
461 	char		buf1[64], buf2[64];
462 
463 	for (i = 0; i < rsc->asz; i++) {
464 		min = rsc->as[i].type == CERT_AS_RANGE ? rsc->as[i].range.min
465 		    : rsc->as[i].id;
466 		max = rsc->as[i].type == CERT_AS_RANGE ? rsc->as[i].range.max
467 		    : rsc->as[i].id;
468 
469 		if (as_check_covered(min, max, cert->as, cert->asz) > 0)
470 			continue;
471 
472 		switch (rsc->as[i].type) {
473 		case CERT_AS_ID:
474 			warnx("%s: RSC resourceBlock: uncovered AS Identifier: "
475 			    "%u", fn, rsc->as[i].id);
476 			break;
477 		case CERT_AS_RANGE:
478 			warnx("%s: RSC resourceBlock: uncovered AS Range: "
479 			    "%u--%u", fn, min, max);
480 			break;
481 		default:
482 			break;
483 		}
484 		return 0;
485 	}
486 
487 	for (i = 0; i < rsc->ipsz; i++) {
488 		if (ip_addr_check_covered(rsc->ips[i].afi, rsc->ips[i].min,
489 		    rsc->ips[i].max, cert->ips, cert->ipsz) > 0)
490 			continue;
491 
492 		switch (rsc->ips[i].type) {
493 		case CERT_IP_RANGE:
494 			ip_addr_print(&rsc->ips[i].range.min,
495 			    rsc->ips[i].afi, buf1, sizeof(buf1));
496 			ip_addr_print(&rsc->ips[i].range.max,
497 			    rsc->ips[i].afi, buf2, sizeof(buf2));
498 			warnx("%s: RSC ResourceBlock: uncovered IP Range: "
499 			    "%s--%s", fn, buf1, buf2);
500 			break;
501 		case CERT_IP_ADDR:
502 			ip_addr_print(&rsc->ips[i].ip,
503 			    rsc->ips[i].afi, buf1, sizeof(buf1));
504 			warnx("%s: RSC ResourceBlock: uncovered IP: "
505 			    "%s", fn, buf1);
506 			break;
507 		default:
508 			break;
509 		}
510 		return 0;
511 	}
512 
513 	return 1;
514 }
515 
516 int
517 valid_econtent_version(const char *fn, const ASN1_INTEGER *aint,
518     uint64_t expected)
519 {
520 	uint64_t version;
521 
522 	if (aint == NULL) {
523 		if (expected == 0)
524 			return 1;
525 		warnx("%s: unexpected version 0", fn);
526 		return 0;
527 	}
528 
529 	if (!ASN1_INTEGER_get_uint64(&version, aint)) {
530 		warnx("%s: ASN1_INTEGER_get_uint64 failed", fn);
531 		return 0;
532 	}
533 
534 	if (version == 0) {
535 		warnx("%s: incorrect encoding for version 0", fn);
536 		return 0;
537 	}
538 
539 	if (version != expected) {
540 		warnx("%s: unexpected version (expected %llu, got %llu)", fn,
541 		    (unsigned long long)expected, (unsigned long long)version);
542 		return 0;
543 	}
544 
545 	return 1;
546 }
547 
548 /*
549  * Validate the ASPA: check that the customerASID is contained.
550  * Returns 1 if valid, 0 otherwise.
551  */
552 int
553 valid_aspa(const char *fn, struct cert *cert, struct aspa *aspa)
554 {
555 
556 	if (as_check_covered(aspa->custasid, aspa->custasid,
557 	    cert->as, cert->asz) > 0)
558 		return 1;
559 
560 	warnx("%s: ASPA: uncovered Customer ASID: %u", fn, aspa->custasid);
561 
562 	return 0;
563 }
564 
565 /*
566  * Validate Geofeed prefixes: check that the prefixes are contained.
567  * Returns 1 if valid, 0 otherwise.
568  */
569 int
570 valid_geofeed(const char *fn, struct cert *cert, struct geofeed *g)
571 {
572 	size_t	 i;
573 	char	 buf[64];
574 
575 	for (i = 0; i < g->geoipsz; i++) {
576 		if (ip_addr_check_covered(g->geoips[i].ip->afi,
577 		    g->geoips[i].ip->min, g->geoips[i].ip->max, cert->ips,
578 		    cert->ipsz) > 0)
579 			continue;
580 
581 		ip_addr_print(&g->geoips[i].ip->ip, g->geoips[i].ip->afi, buf,
582 		    sizeof(buf));
583 		warnx("%s: Geofeed: uncovered IP: %s", fn, buf);
584 		return 0;
585 	}
586 
587 	return 1;
588 }
589 
590 /*
591  * Validate whether a given string is a valid UUID.
592  * Returns 1 if valid, 0 otherwise.
593  */
594 int
595 valid_uuid(const char *s)
596 {
597 	int n = 0;
598 
599 	while (1) {
600 		switch (n) {
601 		case 8:
602 		case 13:
603 		case 18:
604 		case 23:
605 			if (s[n] != '-')
606 				return 0;
607 			break;
608 		/* Check UUID is version 4 */
609 		case 14:
610 			if (s[n] != '4')
611 				return 0;
612 			break;
613 		/* Check UUID variant is 1 */
614 		case 19:
615 			if (s[n] != '8' && s[n] != '9' && s[n] != 'a' &&
616 			    s[n] != 'A' && s[n] != 'b' && s[n] != 'B')
617 				return 0;
618 			break;
619 		case 36:
620 			return s[n] == '\0';
621 		default:
622 			if (!isxdigit((unsigned char)s[n]))
623 				return 0;
624 			break;
625 		}
626 		n++;
627 	}
628 }
629 
630 int
631 valid_ca_pkey(const char *fn, EVP_PKEY *pkey)
632 {
633 	RSA		*rsa;
634 	const BIGNUM	*rsa_e;
635 	int		 key_bits;
636 
637 	if (pkey == NULL) {
638 		warnx("%s: failure, pkey is NULL", fn);
639 		return 0;
640 	}
641 
642 	if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
643 		warnx("%s: Expected EVP_PKEY_RSA, got %d", fn,
644 		    EVP_PKEY_base_id(pkey));
645 		return 0;
646 	}
647 
648 	if ((key_bits = EVP_PKEY_bits(pkey)) != 2048) {
649 		warnx("%s: RFC 7935: expected 2048-bit modulus, got %d bits",
650 		    fn, key_bits);
651 		return 0;
652 	}
653 
654 	if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) {
655 		warnx("%s: failed to extract RSA public key", fn);
656 		return 0;
657 	}
658 
659 	if ((rsa_e = RSA_get0_e(rsa)) == NULL) {
660 		warnx("%s: failed to get RSA exponent", fn);
661 		return 0;
662 	}
663 
664 	if (!BN_is_word(rsa_e, 65537)) {
665 		warnx("%s: incorrect exponent (e) in RSA public key", fn);
666 		return 0;
667 	}
668 
669 	return 1;
670 }
671