xref: /openbsd/usr.sbin/rpki-client/print.c (revision 714f4e3f)
1*714f4e3fSclaudio /*	$OpenBSD: print.c,v 1.1 2021/10/24 17:53:07 claudio Exp $ */
2*714f4e3fSclaudio /*
3*714f4e3fSclaudio  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
4*714f4e3fSclaudio  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
5*714f4e3fSclaudio  *
6*714f4e3fSclaudio  * Permission to use, copy, modify, and distribute this software for any
7*714f4e3fSclaudio  * purpose with or without fee is hereby granted, provided that the above
8*714f4e3fSclaudio  * copyright notice and this permission notice appear in all copies.
9*714f4e3fSclaudio  *
10*714f4e3fSclaudio  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*714f4e3fSclaudio  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*714f4e3fSclaudio  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*714f4e3fSclaudio  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*714f4e3fSclaudio  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*714f4e3fSclaudio  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*714f4e3fSclaudio  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*714f4e3fSclaudio  */
18*714f4e3fSclaudio 
19*714f4e3fSclaudio #include <sys/types.h>
20*714f4e3fSclaudio #include <sys/socket.h>
21*714f4e3fSclaudio #include <arpa/inet.h>
22*714f4e3fSclaudio 
23*714f4e3fSclaudio #include <err.h>
24*714f4e3fSclaudio #include <stdio.h>
25*714f4e3fSclaudio #include <string.h>
26*714f4e3fSclaudio #include <time.h>
27*714f4e3fSclaudio 
28*714f4e3fSclaudio #include "extern.h"
29*714f4e3fSclaudio 
30*714f4e3fSclaudio static const char *
31*714f4e3fSclaudio pretty_key_id(char *hex)
32*714f4e3fSclaudio {
33*714f4e3fSclaudio 	static char buf[128];	/* bigger than SHA_DIGEST_LENGTH * 3 */
34*714f4e3fSclaudio 	size_t i;
35*714f4e3fSclaudio 
36*714f4e3fSclaudio 	for (i = 0; i < sizeof(buf) && *hex != '\0'; i++) {
37*714f4e3fSclaudio 		if  (i % 3 == 2 && *hex != '\0')
38*714f4e3fSclaudio 			buf[i] = ':';
39*714f4e3fSclaudio 		else
40*714f4e3fSclaudio 			buf[i] = *hex++;
41*714f4e3fSclaudio 	}
42*714f4e3fSclaudio 	if (i == sizeof(buf))
43*714f4e3fSclaudio 		memcpy(buf + sizeof(buf) - 4, "...", 4);
44*714f4e3fSclaudio 	return buf;
45*714f4e3fSclaudio }
46*714f4e3fSclaudio 
47*714f4e3fSclaudio void
48*714f4e3fSclaudio tal_print(const struct tal *p)
49*714f4e3fSclaudio {
50*714f4e3fSclaudio 	size_t	 i;
51*714f4e3fSclaudio 
52*714f4e3fSclaudio 	for (i = 0; i < p->urisz; i++)
53*714f4e3fSclaudio 		printf("%5zu: URI: %s\n", i + 1, p->uri[i]);
54*714f4e3fSclaudio }
55*714f4e3fSclaudio 
56*714f4e3fSclaudio void
57*714f4e3fSclaudio cert_print(const struct cert *p)
58*714f4e3fSclaudio {
59*714f4e3fSclaudio 	size_t	 i;
60*714f4e3fSclaudio 	char	 buf1[64], buf2[64];
61*714f4e3fSclaudio 	int	 sockt;
62*714f4e3fSclaudio 	char	 tbuf[21];
63*714f4e3fSclaudio 
64*714f4e3fSclaudio 	printf("Subject key identifier: %s\n", pretty_key_id(p->ski));
65*714f4e3fSclaudio 	if (p->aki != NULL)
66*714f4e3fSclaudio 		printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
67*714f4e3fSclaudio 	if (p->aia != NULL)
68*714f4e3fSclaudio 		printf("Authority info access: %s\n", p->aia);
69*714f4e3fSclaudio 	if (p->mft != NULL)
70*714f4e3fSclaudio 		printf("Manifest: %s\n", p->mft);
71*714f4e3fSclaudio 	if (p->repo != NULL)
72*714f4e3fSclaudio 		printf("caRepository: %s\n", p->repo);
73*714f4e3fSclaudio 	if (p->notify != NULL)
74*714f4e3fSclaudio 		printf("Notify URL: %s\n", p->notify);
75*714f4e3fSclaudio 	if (p->pubkey != NULL)
76*714f4e3fSclaudio 		printf("BGPsec P-256 ECDSA public key: %s\n", p->pubkey);
77*714f4e3fSclaudio 	strftime(tbuf, sizeof(tbuf), "%FT%TZ", gmtime(&p->expires));
78*714f4e3fSclaudio 	printf("Valid until: %s\n", tbuf);
79*714f4e3fSclaudio 
80*714f4e3fSclaudio 	printf("Subordinate Resources:\n");
81*714f4e3fSclaudio 
82*714f4e3fSclaudio 	for (i = 0; i < p->asz; i++)
83*714f4e3fSclaudio 		switch (p->as[i].type) {
84*714f4e3fSclaudio 		case CERT_AS_ID:
85*714f4e3fSclaudio 			printf("%5zu: AS: %u\n", i + 1, p->as[i].id);
86*714f4e3fSclaudio 			break;
87*714f4e3fSclaudio 		case CERT_AS_INHERIT:
88*714f4e3fSclaudio 			printf("%5zu: AS: inherit\n", i + 1);
89*714f4e3fSclaudio 			break;
90*714f4e3fSclaudio 		case CERT_AS_RANGE:
91*714f4e3fSclaudio 			printf("%5zu: AS: %u -- %u\n", i + 1,
92*714f4e3fSclaudio 				p->as[i].range.min, p->as[i].range.max);
93*714f4e3fSclaudio 			break;
94*714f4e3fSclaudio 		}
95*714f4e3fSclaudio 
96*714f4e3fSclaudio 	for (i = 0; i < p->ipsz; i++)
97*714f4e3fSclaudio 		switch (p->ips[i].type) {
98*714f4e3fSclaudio 		case CERT_IP_INHERIT:
99*714f4e3fSclaudio 			printf("%5zu: IP: inherit\n", i + 1);
100*714f4e3fSclaudio 			break;
101*714f4e3fSclaudio 		case CERT_IP_ADDR:
102*714f4e3fSclaudio 			ip_addr_print(&p->ips[i].ip,
103*714f4e3fSclaudio 				p->ips[i].afi, buf1, sizeof(buf1));
104*714f4e3fSclaudio 			printf("%5zu: IP: %s\n", i + 1, buf1);
105*714f4e3fSclaudio 			break;
106*714f4e3fSclaudio 		case CERT_IP_RANGE:
107*714f4e3fSclaudio 			sockt = (p->ips[i].afi == AFI_IPV4) ?
108*714f4e3fSclaudio 				AF_INET : AF_INET6;
109*714f4e3fSclaudio 			inet_ntop(sockt, p->ips[i].min, buf1, sizeof(buf1));
110*714f4e3fSclaudio 			inet_ntop(sockt, p->ips[i].max, buf2, sizeof(buf2));
111*714f4e3fSclaudio 			printf("%5zu: IP: %s -- %s\n", i + 1, buf1, buf2);
112*714f4e3fSclaudio 			break;
113*714f4e3fSclaudio 		}
114*714f4e3fSclaudio 
115*714f4e3fSclaudio }
116*714f4e3fSclaudio 
117*714f4e3fSclaudio void
118*714f4e3fSclaudio mft_print(const struct mft *p)
119*714f4e3fSclaudio {
120*714f4e3fSclaudio 	size_t i;
121*714f4e3fSclaudio 	char *hash;
122*714f4e3fSclaudio 
123*714f4e3fSclaudio 	printf("Subject key identifier: %s\n", pretty_key_id(p->ski));
124*714f4e3fSclaudio 	printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
125*714f4e3fSclaudio 	printf("Authority info access: %s\n", p->aia);
126*714f4e3fSclaudio 	printf("Manifest Number: %s\n", p->seqnum);
127*714f4e3fSclaudio 	for (i = 0; i < p->filesz; i++) {
128*714f4e3fSclaudio 		if (base64_encode(p->files[i].hash, sizeof(p->files[i].hash),
129*714f4e3fSclaudio 		    &hash) == -1)
130*714f4e3fSclaudio 			errx(1, "base64_encode failure");
131*714f4e3fSclaudio 		printf("%5zu: %s\n", i + 1, p->files[i].file);
132*714f4e3fSclaudio 		printf("\thash %s\n", hash);
133*714f4e3fSclaudio 		free(hash);
134*714f4e3fSclaudio 	}
135*714f4e3fSclaudio }
136*714f4e3fSclaudio 
137*714f4e3fSclaudio void
138*714f4e3fSclaudio roa_print(const struct roa *p)
139*714f4e3fSclaudio {
140*714f4e3fSclaudio 	char	 buf[128];
141*714f4e3fSclaudio 	size_t	 i;
142*714f4e3fSclaudio 	char	 tbuf[21];
143*714f4e3fSclaudio 
144*714f4e3fSclaudio 	printf("Subject key identifier: %s\n", pretty_key_id(p->ski));
145*714f4e3fSclaudio 	printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
146*714f4e3fSclaudio 	printf("Authority info access: %s\n", p->aia);
147*714f4e3fSclaudio 	strftime(tbuf, sizeof(tbuf), "%FT%TZ", gmtime(&p->expires));
148*714f4e3fSclaudio 	printf("ROA valid until: %s\n", tbuf);
149*714f4e3fSclaudio 
150*714f4e3fSclaudio 	printf("asID: %u\n", p->asid);
151*714f4e3fSclaudio 	for (i = 0; i < p->ipsz; i++) {
152*714f4e3fSclaudio 		ip_addr_print(&p->ips[i].addr,
153*714f4e3fSclaudio 			p->ips[i].afi, buf, sizeof(buf));
154*714f4e3fSclaudio 		printf("%5zu: %s maxlen: %zu\n", i + 1,
155*714f4e3fSclaudio 			buf, p->ips[i].maxlength);
156*714f4e3fSclaudio 	}
157*714f4e3fSclaudio }
158*714f4e3fSclaudio 
159*714f4e3fSclaudio void
160*714f4e3fSclaudio gbr_print(const struct gbr *p)
161*714f4e3fSclaudio {
162*714f4e3fSclaudio 	char	 buf[128];
163*714f4e3fSclaudio 	size_t	 i;
164*714f4e3fSclaudio 
165*714f4e3fSclaudio 	printf("Subject key identifier: %s\n", pretty_key_id(p->ski));
166*714f4e3fSclaudio 	printf("Authority key identifier: %s\n", pretty_key_id(p->aki));
167*714f4e3fSclaudio 	printf("Authority info access: %s\n", p->aia);
168*714f4e3fSclaudio 	printf("vcard:\n%s", p->vcard);
169*714f4e3fSclaudio }
170