From: Job Snijders Subject: rpki-client: fix printing of ccr hashes in filemode To: tech@openbsd.org Date: Mon, 29 Dec 2025 23:16:18 +0000 Filemode should print CCR hashes in the same way main(), outputheader(), and outputheader_json() do. Use a small helper function to improve readability. With this diff hash strings are aligned as follows: $ rpki-client -f /var/db/rpki-client/rpki.ccr | grep -m3 'state hash' Manifest state hash: W0lidu8QgzMy7RfIv/TFJ16Xf14YbEfLFLZ0ExL2uF0= ROA payload state hash: wpqndTCP7sGgfip24Ngbjvtudk0pOF4hEg4bS5etEXQ= ASPA payload state hash: ccFQDpZc+pRyMtWT1s4IpQdnfVo1L0OixR8ExHLhQkQ= $ grep hash: /var/db/rpki-client/openbgpd # CCR manifest hash: W0lidu8QgzMy7RfIv/TFJ16Xf14YbEfLFLZ0ExL2uF0= # CCR validated ROA payloads hash: wpqndTCP7sGgfip24Ngbjvtudk0pOF4hEg4bS5etEXQ= # CCR validated ASPA payloads hash: ccFQDpZc+pRyMtWT1s4IpQdnfVo1L0OixR8ExHLhQkQ= OK? Index: print.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/print.c,v diff -u -p -r1.71 print.c --- print.c 13 Nov 2025 15:18:53 -0000 1.71 +++ print.c 29 Dec 2025 22:54:30 -0000 @@ -84,6 +84,25 @@ purpose2str(enum cert_purpose purpose) } } +/* + * Convert a hex-encoded SHA256 into a Base64-encoded string. + * Returned string needs to be freed by the caller. + */ +static char * +hex2b64(char *hex) +{ + char data[SHA256_DIGEST_LENGTH]; + char *buf; + + if (hex_decode(hex, data, sizeof(data)) != 0) + errx(1, "hex_decode"); + + if (base64_encode(data, sizeof(data), &buf) == -1) + errx(1, "base64_encode"); + + return buf; +} + char * time2str(time_t t) { @@ -861,8 +880,7 @@ print_ccr_mftstate(struct ccr *ccr) struct ccr_mft *ccr_mft; struct ccr_mft_sub_ski *sub; - if (base64_encode(ccr->mfts_hash, SHA256_DIGEST_LENGTH, &hash) == -1) - errx(1, "base64_encode"); + hash = hex2b64(ccr->mfts_hash); if (outformats & FORMAT_JSON) { json_do_object("manifest_state", 0); @@ -942,8 +960,7 @@ print_ccr_roastate(struct ccr *ccr) char buf[64], *hash; struct vrp *vrp; - if (base64_encode(ccr->vrps_hash, SHA256_DIGEST_LENGTH, &hash) == -1) - errx(1, "base64_encode"); + hash = hex2b64(ccr->vrps_hash); if (outformats & FORMAT_JSON) { json_do_object("roapayload_state", 0); @@ -986,8 +1003,7 @@ print_ccr_aspastate(struct ccr *ccr) struct vap *vap; size_t i; - if (base64_encode(ccr->vaps_hash, SHA256_DIGEST_LENGTH, &hash) == -1) - errx(1, "base64_encode"); + hash = hex2b64(ccr->vaps_hash); if (outformats & FORMAT_JSON) { json_do_object("aspapayload_state", 0); @@ -1038,8 +1054,7 @@ print_ccr_tastate(struct ccr *ccr) struct ccr_tas_ski *cts; int i = 0; - if (base64_encode(ccr->tas_hash, SHA256_DIGEST_LENGTH, &hash) == -1) - errx(1, "base64_encode"); + hash = hex2b64(ccr->tas_hash); if (outformats & FORMAT_JSON) { json_do_object("trustanchor_state", 0); @@ -1080,8 +1095,7 @@ print_ccr_rkstate(struct ccr *ccr) char *hash; struct brk *brk; - if (base64_encode(ccr->brks_hash, SHA256_DIGEST_LENGTH, &hash) == -1) - errx(1, "base64_encode"); + hash = hex2b64(ccr->brks_hash); if (outformats & FORMAT_JSON) { json_do_object("routerkey_state", 0);