1 /*	$Id: test-cert.c,v 1.3 2019/08/22 21:31:48 bluhm 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 <sys/socket.h>
19 #include <arpa/inet.h>
20 
21 #include <assert.h>
22 #include <err.h>
23 #include <inttypes.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 
29 #include <openssl/err.h>
30 #include <openssl/evp.h>
31 #include <openssl/x509v3.h>
32 
33 #include "extern.h"
34 
35 int verbose;
36 
37 static void
38 cert_print(const struct cert *p)
39 {
40 	size_t	 i;
41 	char	 buf1[64], buf2[64];
42 	int	 sockt;
43 
44 	assert(p != NULL);
45 
46 	printf("Manifest: %s\n", p->mft);
47 	if (p->crl != NULL)
48 		printf("Revocation list: %s\n", p->crl);
49 	printf("Subject key identifier: %s\n", p->ski);
50 	if (p->aki != NULL)
51 		printf("Authority key identifier: %s\n", p->aki);
52 
53 	for (i = 0; i < p->asz; i++)
54 		switch (p->as[i].type) {
55 		case CERT_AS_ID:
56 			printf("%5zu: AS: %"
57 				PRIu32 "\n", i + 1, p->as[i].id);
58 			break;
59 		case CERT_AS_INHERIT:
60 			printf("%5zu: AS: inherit\n", i + 1);
61 			break;
62 		case CERT_AS_RANGE:
63 			printf("%5zu: AS: %"
64 				PRIu32 "--%" PRIu32 "\n", i + 1,
65 				p->as[i].range.min, p->as[i].range.max);
66 			break;
67 		}
68 
69 	for (i = 0; i < p->ipsz; i++)
70 		switch (p->ips[i].type) {
71 		case CERT_IP_INHERIT:
72 			printf("%5zu: IP: inherit\n", i + 1);
73 			break;
74 		case CERT_IP_ADDR:
75 			ip_addr_print(&p->ips[i].ip,
76 				p->ips[i].afi, buf1, sizeof(buf1));
77 			printf("%5zu: IP: %s\n", i + 1, buf1);
78 			break;
79 		case CERT_IP_RANGE:
80 			sockt = (p->ips[i].afi == AFI_IPV4) ?
81 				AF_INET : AF_INET6;
82 			inet_ntop(sockt, p->ips[i].min, buf1, sizeof(buf1));
83 			inet_ntop(sockt, p->ips[i].max, buf2, sizeof(buf2));
84 			printf("%5zu: IP: %s--%s\n", i + 1, buf1, buf2);
85 			break;
86 		}
87 }
88 
89 int
90 main(int argc, char *argv[])
91 {
92 	int		 c, i, verb = 0, ta = 0;
93 	X509		*xp = NULL;
94 	struct cert	*p;
95 
96 	ERR_load_crypto_strings();
97 	OpenSSL_add_all_ciphers();
98 	OpenSSL_add_all_digests();
99 
100 	while ((c = getopt(argc, argv, "tv")) != -1)
101 		switch (c) {
102 		case 't':
103 			ta = 1;
104 			break;
105 		case 'v':
106 			verb++;
107 			break;
108 		default:
109 			errx(1, "bad argument %c", c);
110 		}
111 
112 	argv += optind;
113 	argc -= optind;
114 
115 	if (argc == 0)
116 		errx(1, "argument missing");
117 
118 	for (i = 0; i < argc; i++) {
119 		p = ta ?
120 			ta_parse(&xp, argv[i], NULL, 0) :
121 			cert_parse(&xp, argv[i], NULL);
122 		if (p == NULL)
123 			break;
124 		if (verb)
125 			cert_print(p);
126 		cert_free(p);
127 		X509_free(xp);
128 	}
129 
130 	EVP_cleanup();
131 	CRYPTO_cleanup_all_ex_data();
132 	ERR_remove_state(0);
133 	ERR_free_strings();
134 
135 	if (i < argc)
136 		errx(1, "test failed for %s", argv[i]);
137 
138 	printf("OK\n");
139 	return 0;
140 }
141