1*220c707cSclaudio /* $OpenBSD: print.c,v 1.4 2022/02/10 15:33:47 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 * 31714f4e3fSclaudio pretty_key_id(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++) { 37714f4e3fSclaudio if (i % 3 == 2 && *hex != '\0') 38714f4e3fSclaudio buf[i] = ':'; 39714f4e3fSclaudio else 40714f4e3fSclaudio buf[i] = *hex++; 41714f4e3fSclaudio } 42714f4e3fSclaudio if (i == sizeof(buf)) 43714f4e3fSclaudio memcpy(buf + sizeof(buf) - 4, "...", 4); 44714f4e3fSclaudio return buf; 45714f4e3fSclaudio } 46714f4e3fSclaudio 47*220c707cSclaudio char * 48*220c707cSclaudio time2str(time_t t) 49*220c707cSclaudio { 50*220c707cSclaudio static char buf[64]; 51*220c707cSclaudio struct tm tm; 52*220c707cSclaudio 53*220c707cSclaudio if (gmtime_r(&t, &tm) == NULL) 54*220c707cSclaudio return "could not convert time"; 55*220c707cSclaudio 56*220c707cSclaudio strftime(buf, sizeof(buf), "%h %d %T %Y %Z", &tm); 57*220c707cSclaudio return buf; 58*220c707cSclaudio } 59*220c707cSclaudio 60714f4e3fSclaudio void 61714f4e3fSclaudio tal_print(const struct tal *p) 62714f4e3fSclaudio { 63714f4e3fSclaudio size_t i; 64714f4e3fSclaudio 65714f4e3fSclaudio for (i = 0; i < p->urisz; i++) 66714f4e3fSclaudio printf("%5zu: URI: %s\n", i + 1, p->uri[i]); 67714f4e3fSclaudio } 68714f4e3fSclaudio 69714f4e3fSclaudio void 70714f4e3fSclaudio cert_print(const struct cert *p) 71714f4e3fSclaudio { 72714f4e3fSclaudio size_t i; 73714f4e3fSclaudio char buf1[64], buf2[64]; 74714f4e3fSclaudio int sockt; 75714f4e3fSclaudio char tbuf[21]; 76714f4e3fSclaudio 77714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 78714f4e3fSclaudio if (p->aki != NULL) 79714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 80714f4e3fSclaudio if (p->aia != NULL) 81714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 82714f4e3fSclaudio if (p->mft != NULL) 83714f4e3fSclaudio printf("Manifest: %s\n", p->mft); 84714f4e3fSclaudio if (p->repo != NULL) 85714f4e3fSclaudio printf("caRepository: %s\n", p->repo); 86714f4e3fSclaudio if (p->notify != NULL) 87714f4e3fSclaudio printf("Notify URL: %s\n", p->notify); 88714f4e3fSclaudio if (p->pubkey != NULL) 89714f4e3fSclaudio printf("BGPsec P-256 ECDSA public key: %s\n", p->pubkey); 90714f4e3fSclaudio strftime(tbuf, sizeof(tbuf), "%FT%TZ", gmtime(&p->expires)); 91714f4e3fSclaudio printf("Valid until: %s\n", tbuf); 92714f4e3fSclaudio 93714f4e3fSclaudio printf("Subordinate Resources:\n"); 94714f4e3fSclaudio 95714f4e3fSclaudio for (i = 0; i < p->asz; i++) 96714f4e3fSclaudio switch (p->as[i].type) { 97714f4e3fSclaudio case CERT_AS_ID: 98714f4e3fSclaudio printf("%5zu: AS: %u\n", i + 1, p->as[i].id); 99714f4e3fSclaudio break; 100714f4e3fSclaudio case CERT_AS_INHERIT: 101714f4e3fSclaudio printf("%5zu: AS: inherit\n", i + 1); 102714f4e3fSclaudio break; 103714f4e3fSclaudio case CERT_AS_RANGE: 104714f4e3fSclaudio printf("%5zu: AS: %u -- %u\n", i + 1, 105714f4e3fSclaudio p->as[i].range.min, p->as[i].range.max); 106714f4e3fSclaudio break; 107714f4e3fSclaudio } 108714f4e3fSclaudio 109714f4e3fSclaudio for (i = 0; i < p->ipsz; i++) 110714f4e3fSclaudio switch (p->ips[i].type) { 111714f4e3fSclaudio case CERT_IP_INHERIT: 112714f4e3fSclaudio printf("%5zu: IP: inherit\n", i + 1); 113714f4e3fSclaudio break; 114714f4e3fSclaudio case CERT_IP_ADDR: 115714f4e3fSclaudio ip_addr_print(&p->ips[i].ip, 116714f4e3fSclaudio p->ips[i].afi, buf1, sizeof(buf1)); 117714f4e3fSclaudio printf("%5zu: IP: %s\n", i + 1, buf1); 118714f4e3fSclaudio break; 119714f4e3fSclaudio case CERT_IP_RANGE: 120714f4e3fSclaudio sockt = (p->ips[i].afi == AFI_IPV4) ? 121714f4e3fSclaudio AF_INET : AF_INET6; 122714f4e3fSclaudio inet_ntop(sockt, p->ips[i].min, buf1, sizeof(buf1)); 123714f4e3fSclaudio inet_ntop(sockt, p->ips[i].max, buf2, sizeof(buf2)); 124714f4e3fSclaudio printf("%5zu: IP: %s -- %s\n", i + 1, buf1, buf2); 125714f4e3fSclaudio break; 126714f4e3fSclaudio } 127714f4e3fSclaudio 128714f4e3fSclaudio } 129714f4e3fSclaudio 130714f4e3fSclaudio void 131*220c707cSclaudio crl_print(const struct crl *p) 132*220c707cSclaudio { 133*220c707cSclaudio STACK_OF(X509_REVOKED) *revlist; 134*220c707cSclaudio X509_REVOKED *rev; 135*220c707cSclaudio int i; 136*220c707cSclaudio long serial; 137*220c707cSclaudio time_t t; 138*220c707cSclaudio 139*220c707cSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 140*220c707cSclaudio printf("CRL valid since: %s\n", time2str(p->issued)); 141*220c707cSclaudio printf("CRL valid until: %s\n", time2str(p->expires)); 142*220c707cSclaudio 143*220c707cSclaudio revlist = X509_CRL_get_REVOKED(p->x509_crl); 144*220c707cSclaudio for (i = 0; i < sk_X509_REVOKED_num(revlist); i++) { 145*220c707cSclaudio if (i == 0) 146*220c707cSclaudio printf("Revoked Certificates:\n"); 147*220c707cSclaudio rev = sk_X509_REVOKED_value(revlist, i); 148*220c707cSclaudio serial = ASN1_INTEGER_get(X509_REVOKED_get0_serialNumber(rev)); 149*220c707cSclaudio x509_get_time(X509_REVOKED_get0_revocationDate(rev), &t); 150*220c707cSclaudio printf(" Serial: %8lx\tRevocation Date: %s\n", serial, 151*220c707cSclaudio time2str(t)); 152*220c707cSclaudio } 153*220c707cSclaudio if (i == 0) 154*220c707cSclaudio printf("No Revoked Certificates\n"); 155*220c707cSclaudio } 156*220c707cSclaudio 157*220c707cSclaudio void 158714f4e3fSclaudio mft_print(const struct mft *p) 159714f4e3fSclaudio { 160714f4e3fSclaudio size_t i; 161714f4e3fSclaudio char *hash; 162714f4e3fSclaudio 163714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 164714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 165714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 166714f4e3fSclaudio printf("Manifest Number: %s\n", p->seqnum); 167714f4e3fSclaudio for (i = 0; i < p->filesz; i++) { 168714f4e3fSclaudio if (base64_encode(p->files[i].hash, sizeof(p->files[i].hash), 169714f4e3fSclaudio &hash) == -1) 170714f4e3fSclaudio errx(1, "base64_encode failure"); 171714f4e3fSclaudio printf("%5zu: %s\n", i + 1, p->files[i].file); 172714f4e3fSclaudio printf("\thash %s\n", hash); 173714f4e3fSclaudio free(hash); 174714f4e3fSclaudio } 175714f4e3fSclaudio } 176714f4e3fSclaudio 177714f4e3fSclaudio void 178714f4e3fSclaudio roa_print(const struct roa *p) 179714f4e3fSclaudio { 180714f4e3fSclaudio char buf[128]; 181714f4e3fSclaudio size_t i; 182714f4e3fSclaudio 183714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 184714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 185714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 186*220c707cSclaudio printf("ROA valid until: %s\n", time2str(p->expires)); 187714f4e3fSclaudio 188714f4e3fSclaudio printf("asID: %u\n", p->asid); 189714f4e3fSclaudio for (i = 0; i < p->ipsz; i++) { 190714f4e3fSclaudio ip_addr_print(&p->ips[i].addr, 191714f4e3fSclaudio p->ips[i].afi, buf, sizeof(buf)); 192b6884e9fSclaudio printf("%5zu: %s maxlen: %hhu\n", i + 1, 193714f4e3fSclaudio buf, p->ips[i].maxlength); 194714f4e3fSclaudio } 195714f4e3fSclaudio } 196714f4e3fSclaudio 197714f4e3fSclaudio void 198714f4e3fSclaudio gbr_print(const struct gbr *p) 199714f4e3fSclaudio { 200714f4e3fSclaudio printf("Subject key identifier: %s\n", pretty_key_id(p->ski)); 201714f4e3fSclaudio printf("Authority key identifier: %s\n", pretty_key_id(p->aki)); 202714f4e3fSclaudio printf("Authority info access: %s\n", p->aia); 203714f4e3fSclaudio printf("vcard:\n%s", p->vcard); 204714f4e3fSclaudio } 205