Index | Thread | Search

From:
Job Snijders <job@bsd.nl>
Subject:
Re: rpki-client: fix printing of ccr hashes in filemode
To:
Theo Buehler <tb@theobuehler.org>
Cc:
tech@openbsd.org
Date:
Tue, 30 Dec 2025 08:36:11 +0000

Download raw body.

Thread
On Tue, Dec 30, 2025 at 05:30:27AM +0100, Theo Buehler wrote:
> On Mon, Dec 29, 2025 at 11:16:18PM +0000, Job Snijders wrote:
> > 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:
> 
> I think the cleaner approach is changing validate_asn1_hash() to
> use base64_encode_asn1_string() instead of hex_encode_asn1_string().
> Then the printing function can just dump the members directly without
> reencoding.

Ah yes, good suggestion.

Index: ccr.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/ccr.c,v
diff -u -p -r1.31 ccr.c
--- ccr.c	5 Dec 2025 07:26:42 -0000	1.31
+++ ccr.c	30 Dec 2025 08:35:15 -0000
@@ -237,7 +237,7 @@ validate_asn1_hash(const char *fn, const
     const ASN1_OCTET_STRING *hash, const ASN1_ITEM *it, void *val)
 {
 	ASN1_OCTET_STRING *astr = NULL;
-	char *hex = NULL;
+	char *b64 = NULL;
 
 	if ((astr = ASN1_OCTET_STRING_new()) == NULL)
 		errx(1, "ASN1_OCTET_STRING_new");
@@ -249,10 +249,12 @@ validate_asn1_hash(const char *fn, const
 		goto out;
 	}
 
-	hex = hex_encode_asn1_string(hash);
+	if (!base64_encode_asn1_string(astr, &b64))
+		errx(1, "base64_encode_asn1_string");
+
  out:
 	ASN1_OCTET_STRING_free(astr);
-	return hex;
+	return b64;
 }
 
 static void
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	30 Dec 2025 08:35:15 -0000
@@ -861,21 +861,17 @@ 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");
-
 	if (outformats & FORMAT_JSON) {
 		json_do_object("manifest_state", 0);
 		json_do_int("most_recent_update", ccr->most_recent_update);
-		json_do_string("hash", hash);
+		json_do_string("hash", ccr->mfts_hash);
 		json_do_array("mft_instances");
 	} else {
-		printf("Manifest state hash:      %s\n", hash);
+		printf("Manifest state hash:      %s\n", ccr->mfts_hash);
 		printf("Manifest last update:     %s\n",
 		    time2str(ccr->most_recent_update));
 		printf("Manifest instances:\n");
 	}
-	free(hash);
 
 	RB_FOREACH(ccr_mft, ccr_mft_tree, &ccr->mfts) {
 		if (base64_encode(ccr_mft->hash, SHA256_DIGEST_LENGTH, &hash)
@@ -939,21 +935,17 @@ print_ccr_mftstate(struct ccr *ccr)
 static void
 print_ccr_roastate(struct ccr *ccr)
 {
-	char buf[64], *hash;
+	char buf[64];
 	struct vrp *vrp;
 
-	if (base64_encode(ccr->vrps_hash, SHA256_DIGEST_LENGTH, &hash) == -1)
-		errx(1, "base64_encode");
-
 	if (outformats & FORMAT_JSON) {
 		json_do_object("roapayload_state", 0);
-		json_do_string("hash", hash);
+		json_do_string("hash", ccr->vrps_hash);
 		json_do_array("vrps");
 	} else {
-		printf("ROA payload state hash:   %s\n", hash);
+		printf("ROA payload state hash:   %s\n", ccr->vrps_hash);
 		printf("ROA payload entries:\n");
 	}
-	free(hash);
 
 	RB_FOREACH(vrp, ccr_vrp_tree, &ccr->vrps) {
 		ip_addr_print(&vrp->addr, vrp->afi, buf, sizeof(buf));
@@ -982,22 +974,17 @@ print_ccr_roastate(struct ccr *ccr)
 static void
 print_ccr_aspastate(struct ccr *ccr)
 {
-	char *hash;
 	struct vap *vap;
 	size_t i;
 
-	if (base64_encode(ccr->vaps_hash, SHA256_DIGEST_LENGTH, &hash) == -1)
-		errx(1, "base64_encode");
-
 	if (outformats & FORMAT_JSON) {
 		json_do_object("aspapayload_state", 0);
-		json_do_string("hash", hash);
+		json_do_string("hash", ccr->vaps_hash);
 		json_do_array("vaps");
 	} else {
-		printf("ASPA payload state hash:  %s\n", hash);
+		printf("ASPA payload state hash:  %s\n", ccr->vaps_hash);
 		printf("ASPA payload entries:\n");
 	}
-	free(hash);
 
 	RB_FOREACH(vap, vap_tree, &ccr->vaps) {
 		if (outformats & FORMAT_JSON) {
@@ -1034,24 +1021,19 @@ print_ccr_aspastate(struct ccr *ccr)
 static void
 print_ccr_tastate(struct ccr *ccr)
 {
-	char *hash, *ski;
+	char *ski;
 	struct ccr_tas_ski *cts;
 	int i = 0;
 
-	if (base64_encode(ccr->tas_hash, SHA256_DIGEST_LENGTH, &hash) == -1)
-		errx(1, "base64_encode");
-
 	if (outformats & FORMAT_JSON) {
 		json_do_object("trustanchor_state", 0);
-		json_do_string("hash", hash);
+		json_do_string("hash", ccr->tas_hash);
 		json_do_array("skis");
 	} else {
-		printf("Trust anchor state hash:  %s\n", hash);
+		printf("Trust anchor state hash:  %s\n", ccr->tas_hash);
 		printf("Trust anchor keyids:      ");
 	}
 
-	free(hash);
-
 	RB_FOREACH(cts, ccr_tas_tree, &ccr->tas) {
 		ski = hex_encode(cts->keyid, sizeof(cts->keyid));
 
@@ -1077,15 +1059,11 @@ print_ccr_tastate(struct ccr *ccr)
 static void
 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");
-
 	if (outformats & FORMAT_JSON) {
 		json_do_object("routerkey_state", 0);
-		json_do_string("hash", hash);
+		json_do_string("hash", ccr->brks_hash);
 		json_do_array("routerkeys");
 		RB_FOREACH(brk, brk_tree, &ccr->brks) {
 			json_do_object("brk", 0);
@@ -1097,7 +1075,7 @@ print_ccr_rkstate(struct ccr *ccr)
 		json_do_end(); /* routerkeys */
 		json_do_end(); /* routerkey_state */
 	} else {
-		printf("Router key state hash:    %s\n", hash);
+		printf("Router key state hash:    %s\n", ccr->brks_hash);
 		printf("Router keys:\n");
 		RB_FOREACH(brk, brk_tree, &ccr->brks) {
 			printf("%26s", "");
@@ -1106,8 +1084,6 @@ print_ccr_rkstate(struct ccr *ccr)
 			printf("pubkey:%s\n", brk->pubkey);
 		}
 	}
-
-	free(hash);
 }
 
 void