1*254fd372Sclaudio /* $OpenBSD: print.c,v 1.6 2022/03/21 10:39:51 claudio Exp $ */ 2714f4e3fSclaudio /* 3714f4e3fSclaudio * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> 4714f4e3fSclaudio * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> 5714f4e3fSclaudio * 6714f4e3fSclaudio * Permission to use, copy, modify, and distribute this software for any 7714f4e3fSclaudio * purpose with or without fee is hereby granted, provided that the above 8714f4e3fSclaudio * copyright notice and this permission notice appear in all copies. 9714f4e3fSclaudio * 10714f4e3fSclaudio * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11714f4e3fSclaudio * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12714f4e3fSclaudio * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13714f4e3fSclaudio * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14714f4e3fSclaudio * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15714f4e3fSclaudio * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16714f4e3fSclaudio * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17714f4e3fSclaudio */ 18714f4e3fSclaudio 19714f4e3fSclaudio #include <sys/types.h> 20714f4e3fSclaudio #include <sys/socket.h> 21714f4e3fSclaudio #include <arpa/inet.h> 22714f4e3fSclaudio 23714f4e3fSclaudio #include <err.h> 24714f4e3fSclaudio #include <stdio.h> 25714f4e3fSclaudio #include <string.h> 26714f4e3fSclaudio #include <time.h> 27714f4e3fSclaudio 28714f4e3fSclaudio #include "extern.h" 29714f4e3fSclaudio 30714f4e3fSclaudio static const char * 31*254fd372Sclaudio pretty_key_id(const char *hex) 32714f4e3fSclaudio { 33714f4e3fSclaudio static char buf[128]; /* bigger than SHA_DIGEST_LENGTH * 3 */ 34714f4e3fSclaudio size_t i; 35714f4e3fSclaudio 36714f4e3fSclaudio for (i = 0; i < sizeof(buf) && *hex != '\0'; i++) { 37*254fd372Sclaudio if (i % 3 == 2) 38714f4e3fSclaudio buf[i] = ':'; 39714f4e3fSclaudio else 40714f4e3fSclaudio buf[i] = *hex++; 41714f4e3fSclaudio } 42714f4e3fSclaudio if (i == sizeof(buf)) 43714f4e3fSclaudio memcpy(buf + sizeof(buf) - 4, "...", 4); 44*254fd372Sclaudio else 45*254fd372Sclaudio buf[i] = '\0'; 46714f4e3fSclaudio return buf; 47714f4e3fSclaudio } 48714f4e3fSclaudio 49220c707cSclaudio char * 50220c707cSclaudio time2str(time_t t) 51220c707cSclaudio { 52220c707cSclaudio static char buf[64]; 53220c707cSclaudio struct tm tm; 54220c707cSclaudio 55220c707cSclaudio if (gmtime_r(&t, &tm) == NULL) 56220c707cSclaudio return "could not convert time"; 57220c707cSclaudio 58220c707cSclaudio strftime(buf, sizeof(buf), "%h %d %T %Y %Z", &tm); 59220c707cSclaudio return buf; 60220c707cSclaudio } 61220c707cSclaudio 62714f4e3fSclaudio void 63714f4e3fSclaudio tal_print(const struct tal *p) 64714f4e3fSclaudio { 65714f4e3fSclaudio size_t i; 66714f4e3fSclaudio 67714f4e3fSclaudio for (i = 0; i < p->urisz; i++) 68714f4e3fSclaudio printf("%5zu: URI: %s\n", i + 1, p->uri[i]); 69714f4e3fSclaudio } 70714f4e3fSclaudio 71714f4e3fSclaudio void 72714f4e3fSclaudio cert_print(const struct cert *p) 73714f4e3fSclaudio { 74714f4e3fSclaudio size_t i; 75714f4e3fSclaudio char buf1[64], buf2[64]; 76714f4e3fSclaudio int sockt; 77714f4e3fSclaudio char tbuf[21]; 78714f4e3fSclaudio 79714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 80714f4e3fSclaudio if (p->aki != NULL) 81714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 82714f4e3fSclaudio if (p->aia != NULL) 83714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 84714f4e3fSclaudio if (p->mft != NULL) 85714f4e3fSclaudio printf("Manifest: %s\n", p->mft); 86714f4e3fSclaudio if (p->repo != NULL) 87714f4e3fSclaudio printf("caRepository: %s\n", p->repo); 88714f4e3fSclaudio if (p->notify != NULL) 89714f4e3fSclaudio printf("Notify URL: %s\n", p->notify); 90714f4e3fSclaudio if (p->pubkey != NULL) 91714f4e3fSclaudio printf("BGPsec P-256 ECDSA public key: %s\n", p->pubkey); 92714f4e3fSclaudio strftime(tbuf, sizeof(tbuf), "%FT%TZ", gmtime(&p->expires)); 93714f4e3fSclaudio printf("Valid until: %s\n", tbuf); 94714f4e3fSclaudio 95714f4e3fSclaudio printf("Subordinate Resources:\n"); 96714f4e3fSclaudio 97714f4e3fSclaudio for (i = 0; i < p->asz; i++) 98714f4e3fSclaudio switch (p->as[i].type) { 99714f4e3fSclaudio case CERT_AS_ID: 100714f4e3fSclaudio printf("%5zu: AS: %u\n", i + 1, p->as[i].id); 101714f4e3fSclaudio break; 102714f4e3fSclaudio case CERT_AS_INHERIT: 103714f4e3fSclaudio printf("%5zu: AS: inherit\n", i + 1); 104714f4e3fSclaudio break; 105714f4e3fSclaudio case CERT_AS_RANGE: 106714f4e3fSclaudio printf("%5zu: AS: %u -- %u\n", i + 1, 107714f4e3fSclaudio p->as[i].range.min, p->as[i].range.max); 108714f4e3fSclaudio break; 109714f4e3fSclaudio } 110714f4e3fSclaudio 111714f4e3fSclaudio for (i = 0; i < p->ipsz; i++) 112714f4e3fSclaudio switch (p->ips[i].type) { 113714f4e3fSclaudio case CERT_IP_INHERIT: 114714f4e3fSclaudio printf("%5zu: IP: inherit\n", i + 1); 115714f4e3fSclaudio break; 116714f4e3fSclaudio case CERT_IP_ADDR: 117714f4e3fSclaudio ip_addr_print(&p->ips[i].ip, 118714f4e3fSclaudio p->ips[i].afi, buf1, sizeof(buf1)); 119714f4e3fSclaudio printf("%5zu: IP: %s\n", i + 1, buf1); 120714f4e3fSclaudio break; 121714f4e3fSclaudio case CERT_IP_RANGE: 122714f4e3fSclaudio sockt = (p->ips[i].afi == AFI_IPV4) ? 123714f4e3fSclaudio AF_INET : AF_INET6; 124714f4e3fSclaudio inet_ntop(sockt, p->ips[i].min, buf1, sizeof(buf1)); 125714f4e3fSclaudio inet_ntop(sockt, p->ips[i].max, buf2, sizeof(buf2)); 126714f4e3fSclaudio printf("%5zu: IP: %s -- %s\n", i + 1, buf1, buf2); 127714f4e3fSclaudio break; 128714f4e3fSclaudio } 129714f4e3fSclaudio 130714f4e3fSclaudio } 131714f4e3fSclaudio 132714f4e3fSclaudio void 133220c707cSclaudio crl_print(const struct crl *p) 134220c707cSclaudio { 135220c707cSclaudio STACK_OF(X509_REVOKED) *revlist; 136220c707cSclaudio X509_REVOKED *rev; 1377cdd491fSclaudio ASN1_INTEGER *crlnum; 138220c707cSclaudio int i; 1397cdd491fSclaudio char *serial; 140220c707cSclaudio time_t t; 141220c707cSclaudio 142220c707cSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 1437cdd491fSclaudio 1447cdd491fSclaudio crlnum = X509_CRL_get_ext_d2i(p->x509_crl, NID_crl_number, NULL, NULL); 1457cdd491fSclaudio serial = x509_convert_seqnum(__func__, crlnum); 1467cdd491fSclaudio if (serial != NULL) 1477cdd491fSclaudio printf("CRL Serial Number: %s\n", serial); 1487cdd491fSclaudio free(serial); 1497cdd491fSclaudio ASN1_INTEGER_free(crlnum); 1507cdd491fSclaudio 151220c707cSclaudio printf("CRL valid since: %s\n", time2str(p->issued)); 152220c707cSclaudio printf("CRL valid until: %s\n", time2str(p->expires)); 153220c707cSclaudio 154220c707cSclaudio revlist = X509_CRL_get_REVOKED(p->x509_crl); 155220c707cSclaudio for (i = 0; i < sk_X509_REVOKED_num(revlist); i++) { 156220c707cSclaudio if (i == 0) 157220c707cSclaudio printf("Revoked Certificates:\n"); 158220c707cSclaudio rev = sk_X509_REVOKED_value(revlist, i); 1597cdd491fSclaudio 1607cdd491fSclaudio serial = x509_convert_seqnum(__func__, 1617cdd491fSclaudio X509_REVOKED_get0_serialNumber(rev)); 162220c707cSclaudio x509_get_time(X509_REVOKED_get0_revocationDate(rev), &t); 1637cdd491fSclaudio if (serial != NULL) 1647cdd491fSclaudio printf(" Serial: %8s Revocation Date: %s\n", 1657cdd491fSclaudio serial, time2str(t)); 1667cdd491fSclaudio free(serial); 167220c707cSclaudio } 168220c707cSclaudio if (i == 0) 169220c707cSclaudio printf("No Revoked Certificates\n"); 170220c707cSclaudio } 171220c707cSclaudio 172220c707cSclaudio void 173714f4e3fSclaudio mft_print(const struct mft *p) 174714f4e3fSclaudio { 175714f4e3fSclaudio size_t i; 176714f4e3fSclaudio char *hash; 177714f4e3fSclaudio 178714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 179714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 180714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 181714f4e3fSclaudio printf("Manifest Number: %s\n", p->seqnum); 182714f4e3fSclaudio for (i = 0; i < p->filesz; i++) { 183714f4e3fSclaudio if (base64_encode(p->files[i].hash, sizeof(p->files[i].hash), 184714f4e3fSclaudio &hash) == -1) 185714f4e3fSclaudio errx(1, "base64_encode failure"); 186714f4e3fSclaudio printf("%5zu: %s\n", i + 1, p->files[i].file); 187714f4e3fSclaudio printf("\thash %s\n", hash); 188714f4e3fSclaudio free(hash); 189714f4e3fSclaudio } 190714f4e3fSclaudio } 191714f4e3fSclaudio 192714f4e3fSclaudio void 193714f4e3fSclaudio roa_print(const struct roa *p) 194714f4e3fSclaudio { 195714f4e3fSclaudio char buf[128]; 196714f4e3fSclaudio size_t i; 197714f4e3fSclaudio 198714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 199714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 200714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 201220c707cSclaudio printf("ROA valid until: %s\n", time2str(p->expires)); 202714f4e3fSclaudio 203714f4e3fSclaudio printf("asID: %u\n", p->asid); 204714f4e3fSclaudio for (i = 0; i < p->ipsz; i++) { 205714f4e3fSclaudio ip_addr_print(&p->ips[i].addr, 206714f4e3fSclaudio p->ips[i].afi, buf, sizeof(buf)); 207b6884e9fSclaudio printf("%5zu: %s maxlen: %hhu\n", i + 1, 208714f4e3fSclaudio buf, p->ips[i].maxlength); 209714f4e3fSclaudio } 210714f4e3fSclaudio } 211714f4e3fSclaudio 212714f4e3fSclaudio void 213714f4e3fSclaudio gbr_print(const struct gbr *p) 214714f4e3fSclaudio { 215714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 216714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 217714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 218714f4e3fSclaudio printf("vcard:\n%s", p->vcard); 219714f4e3fSclaudio } 220