Index | Thread | Search

From:
Job Snijders <job@bsd.nl>
Subject:
rpki-client: remove support for validating Geofeed data
To:
tech@openbsd.org
Date:
Tue, 13 Jan 2026 17:33:20 +0000

Download raw body.

Thread
Sadly, I've come to suspect RFC 9632 RPKI-based Geofeed authentication
was a bit of a ruse to pass IESG review. The authors of the spec don't
appear to have any plan to encourage the ecosystem to adopt RFC 9632.
None of the RIRs currently support signing Geofeed data or have any
plans to do so. Also, operators tend to follow the path of least
resistance ... and this authenticator is both optional & hard to use.

Time to take it behind the barn.

OK?

ps. Draft-ietf-opsawg-prefix-lengths comes from the same stock, so I'm
not gonna spend any time on that one.

Index: usr.sbin/rpki-client/Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/Makefile,v
diff -u -p -r1.38 Makefile
--- usr.sbin/rpki-client/Makefile	13 Nov 2025 15:18:53 -0000	1.38
+++ usr.sbin/rpki-client/Makefile	13 Jan 2026 17:16:00 -0000
@@ -11,7 +11,6 @@ SRCS+=	constraints.c
 SRCS+=	crl.c
 SRCS+=	encoding.c
 SRCS+=	filemode.c
-SRCS+=	geofeed.c
 SRCS+=	http.c
 SRCS+=	io.c
 SRCS+=	ip.c
Index: usr.sbin/rpki-client/cert.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
diff -u -p -r1.209 cert.c
--- usr.sbin/rpki-client/cert.c	12 Jan 2026 10:56:16 -0000	1.209
+++ usr.sbin/rpki-client/cert.c	13 Jan 2026 17:16:00 -0000
@@ -1704,16 +1704,13 @@ cert_parse_extensions(const char *fn, st
 
 	if (sia == 0) {
 		/*
-		 * Allow two special snowflakes to omit the SIA in EE certs
+		 * Allow one special snowflake to omit the SIA in EE certs
 		 * even though this extension is mandated by RFC 6487, 4.8.8.2.
 		 * RFC 9323, 2 clarifies: it is because RSCs are not distributed
-		 * through the RPKI repository system. Same goes for Geofeed.
-		 * RFC 9092 had an EE cert sporting an rpkiNotify SIA (!).
-		 * RFC 9632 fixed this and pleads the Fifth on SIAs...
+		 * through the RPKI repository system.
 		 */
 		if (filemode && cert->purpose == CERT_PURPOSE_EE) {
-			if (rtype_from_file_extension(fn) != RTYPE_GEOFEED &&
-			    rtype_from_file_extension(fn) != RTYPE_RSC) {
+			if (rtype_from_file_extension(fn) != RTYPE_RSC) {
 				warnx("%s: RFC 6487, 4.8.8: cert without SIA",
 				    fn);
 				goto out;
Index: usr.sbin/rpki-client/extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
diff -u -p -r1.268 extern.h
--- usr.sbin/rpki-client/extern.h	18 Nov 2025 14:04:45 -0000	1.268
+++ usr.sbin/rpki-client/extern.h	13 Jan 2026 17:16:00 -0000
@@ -200,7 +200,6 @@ enum rtype {
 	RTYPE_RSC,
 	RTYPE_ASPA,
 	RTYPE_TAK,
-	RTYPE_GEOFEED,
 	RTYPE_SPL,
 	RTYPE_CCR,
 };
@@ -343,25 +342,6 @@ struct tak {
 };
 
 /*
- * A single geofeed record
- */
-struct geoip {
-	struct cert_ip	*ip;
-	char		*loc;
-};
-
-/*
- * A geofeed file
- */
-struct geofeed {
-	struct geoip	*geoips; /* Prefix + location entry in the CSV */
-	size_t		 num_geoips;
-	time_t		 signtime; /* CMS signing-time attribute */
-	time_t		 expires; /* when the signature path expires */
-	int		 valid; /* all resources covered */
-};
-
-/*
  * A single ASPA record
  */
 struct aspa {
@@ -708,7 +688,6 @@ extern ASN1_OBJECT *sign_time_oid;
 extern ASN1_OBJECT *rsc_oid;
 extern ASN1_OBJECT *aspa_oid;
 extern ASN1_OBJECT *tak_oid;
-extern ASN1_OBJECT *geofeed_oid;
 extern ASN1_OBJECT *spl_oid;
 extern ASN1_OBJECT *ccr_oid;
 
@@ -771,10 +750,6 @@ struct spl	*spl_read(struct ibuf *);
 void		 spl_insert_vsps(struct vsp_tree *, struct spl *,
 		    struct repo *);
 
-void		 geofeed_free(struct geofeed *);
-struct geofeed	*geofeed_parse(struct cert **, const char *, int, char *,
-		    size_t);
-
 void		 rsc_free(struct rsc *);
 struct rsc	*rsc_parse(struct cert **, const char *, int,
 		    const unsigned char *, size_t);
@@ -814,7 +789,6 @@ int		 valid_rsc(const char *, struct cer
 int		 valid_econtent_version(const char *, const ASN1_INTEGER *,
 		    uint64_t);
 int		 valid_aspa(const char *, struct cert *, struct aspa *);
-int		 valid_geofeed(const char *, struct cert *, struct geofeed *);
 int		 valid_uuid(const char *);
 int		 valid_spl(const char *, struct cert *, struct spl *);
 
@@ -998,7 +972,6 @@ void		 roa_print(const struct cert *, co
 void		 rsc_print(const struct cert *, const struct rsc *);
 void		 aspa_print(const struct cert *, const struct aspa *);
 void		 tak_print(const struct cert *, const struct tak *);
-void		 geofeed_print(const struct cert *, const struct geofeed *);
 void		 spl_print(const struct cert *, const struct spl *);
 
 /* Missing RFC 3779 API */
Index: usr.sbin/rpki-client/filemode.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
diff -u -p -r1.74 filemode.c
--- usr.sbin/rpki-client/filemode.c	31 Dec 2025 09:31:56 -0000	1.74
+++ usr.sbin/rpki-client/filemode.c	13 Jan 2026 17:16:00 -0000
@@ -396,9 +396,9 @@ rtype_from_der(const char *fn, const uns
 	}
 
 	/*
-	 * We could add some heuristics for recognizing TALs and geofeed by
-	 * looking for things like "rsync://" and "MII" or "RPKI Signature"
-	 * using memmem(3). If we do this, we should also rename the function.
+	 * We could add some heuristics for recognizing TALs by looking for
+	 * things like "rsync://" and "MII" or "RPKI Signature" using memmem(3).
+	 * If we do this, we should also rename the function.
 	 */
 
  out:
@@ -421,7 +421,6 @@ proc_parser_file(char *file, unsigned ch
 	struct cert *cert = NULL;
 	struct ccr *ccr = NULL;
 	struct crl *crl = NULL;
-	struct geofeed *geofeed = NULL;
 	struct mft *mft = NULL;
 	struct roa *roa = NULL;
 	struct rsc *rsc = NULL;
@@ -519,15 +518,6 @@ proc_parser_file(char *file, unsigned ch
 		notbefore = &mft->thisupdate;
 		notafter = &mft->nextupdate;
 		break;
-	case RTYPE_GEOFEED:
-		geofeed = geofeed_parse(&cert, file, -1, buf, len);
-		if (geofeed == NULL)
-			break;
-		aia = cert->aia;
-		expires = &geofeed->expires;
-		notbefore = &cert->notbefore;
-		notafter = &cert->notafter;
-		break;
 	case RTYPE_ROA:
 		roa = roa_parse(&cert, file, -1, buf, len);
 		if (roa == NULL)
@@ -585,9 +575,6 @@ proc_parser_file(char *file, unsigned ch
 			case RTYPE_ASPA:
 				status = aspa->valid;
 				break;
-			case RTYPE_GEOFEED:
-				status = geofeed->valid;
-				break;
 			case RTYPE_ROA:
 				status = roa->valid;
 				break;
@@ -638,9 +625,6 @@ proc_parser_file(char *file, unsigned ch
 		case RTYPE_CER:
 			cert_print(cert);
 			break;
-		case RTYPE_GEOFEED:
-			geofeed_print(cert, geofeed);
-			break;
 		case RTYPE_MFT:
 			mft_print(cert, mft);
 			break;
@@ -721,7 +705,6 @@ proc_parser_file(char *file, unsigned ch
 	cert_free(cert);
 	ccr_free(ccr);
 	crl_free(crl);
-	geofeed_free(geofeed);
 	mft_free(mft);
 	roa_free(roa);
 	rsc_free(rsc);
Index: usr.sbin/rpki-client/mft.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
diff -u -p -r1.134 mft.c
--- usr.sbin/rpki-client/mft.c	2 Dec 2025 06:54:08 -0000	1.134
+++ usr.sbin/rpki-client/mft.c	13 Jan 2026 17:16:00 -0000
@@ -87,8 +87,6 @@ rtype_from_file_extension(const char *fn
 		return RTYPE_ASPA;
 	if (strcasecmp(fn + sz - 4, ".tak") == 0)
 		return RTYPE_TAK;
-	if (strcasecmp(fn + sz - 4, ".csv") == 0)
-		return RTYPE_GEOFEED;
 	if (strcasecmp(fn + sz - 4, ".spl") == 0)
 		return RTYPE_SPL;
 	if (strcasecmp(fn + sz - 4, ".ccr") == 0)
Index: usr.sbin/rpki-client/print.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/print.c,v
diff -u -p -r1.72 print.c
--- usr.sbin/rpki-client/print.c	30 Dec 2025 09:04:09 -0000	1.72
+++ usr.sbin/rpki-client/print.c	13 Jan 2026 17:16:01 -0000
@@ -802,58 +802,6 @@ tak_print(const struct cert *c, const st
 		json_do_end();
 }
 
-void
-geofeed_print(const struct cert *c, const struct geofeed *p)
-{
-	char	 buf[128];
-	size_t	 i;
-
-	if (outformats & FORMAT_JSON) {
-		json_do_string("type", "geofeed");
-		json_do_string("ski", c->ski);
-		x509_print(c->x509);
-		json_do_string("aki", c->aki);
-		json_do_string("aia", c->aia);
-		json_do_int("signing_time", p->signtime);
-		json_do_int("valid_since", c->notbefore);
-		json_do_int("valid_until", c->notafter);
-		if (p->expires)
-			json_do_int("expires", p->expires);
-		json_do_array("records");
-	} else {
-		printf("Subject key identifier:   %s\n", pretty_key_id(c->ski));
-		x509_print(c->x509);
-		printf("Authority key identifier: %s\n", pretty_key_id(c->aki));
-		printf("Authority info access:    %s\n", c->aia);
-		printf("Signing time:             %s\n", time2str(p->signtime));
-		printf("Geofeed not before:       %s\n",
-		    time2str(c->notbefore));
-		printf("Geofeed not after:        %s\n", time2str(c->notafter));
-		printf("Geofeed CSV records:      ");
-	}
-
-	for (i = 0; i < p->num_geoips; i++) {
-		if (p->geoips[i].ip->type != CERT_IP_ADDR)
-			continue;
-
-		ip_addr_print(&p->geoips[i].ip->ip, p->geoips[i].ip->afi, buf,
-		    sizeof(buf));
-		if (outformats & FORMAT_JSON) {
-			json_do_object("geoip", 1);
-			json_do_string("prefix", buf);
-			json_do_string("location", p->geoips[i].loc);
-			json_do_end();
-		} else {
-			if (i > 0)
-				printf("%26s", "");
-			printf("IP: %s (%s)\n", buf, p->geoips[i].loc);
-		}
-	}
-
-	if (outformats & FORMAT_JSON)
-		json_do_end();
-}
-
 static void
 print_ccr_mftstate(struct ccr *ccr)
 {
Index: usr.sbin/rpki-client/rpki-client.8
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/rpki-client.8,v
diff -u -p -r1.134 rpki-client.8
--- usr.sbin/rpki-client/rpki-client.8	2 Dec 2025 12:21:39 -0000	1.134
+++ usr.sbin/rpki-client/rpki-client.8	13 Jan 2026 17:16:01 -0000
@@ -416,11 +416,6 @@ This facility is experimental and is sti
 .Re
 .Pp
 .Rs
-.%T Finding and Using Geofeed Data
-.%R RFC 9632
-.Re
-.Pp
-.Rs
 .%T Same-Origin Policy for the RRDP
 .%R RFC 9674
 .Re
Index: usr.sbin/rpki-client/validate.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
diff -u -p -r1.81 validate.c
--- usr.sbin/rpki-client/validate.c	24 Aug 2025 11:52:20 -0000	1.81
+++ usr.sbin/rpki-client/validate.c	13 Jan 2026 17:16:01 -0000
@@ -520,31 +520,6 @@ valid_aspa(const char *fn, struct cert *
 }
 
 /*
- * Validate Geofeed prefixes: check that the prefixes are contained.
- * Returns 1 if valid, 0 otherwise.
- */
-int
-valid_geofeed(const char *fn, struct cert *cert, struct geofeed *g)
-{
-	size_t	 i;
-	char	 buf[64];
-
-	for (i = 0; i < g->num_geoips; i++) {
-		if (ip_addr_check_covered(g->geoips[i].ip->afi,
-		    g->geoips[i].ip->min, g->geoips[i].ip->max, cert->ips,
-		    cert->num_ips) > 0)
-			continue;
-
-		ip_addr_print(&g->geoips[i].ip->ip, g->geoips[i].ip->afi, buf,
-		    sizeof(buf));
-		warnx("%s: Geofeed: uncovered IP: %s", fn, buf);
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
  * Validate whether a given string is a valid UUID.
  * Returns 1 if valid, 0 otherwise.
  */
Index: usr.sbin/rpki-client/x509.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
diff -u -p -r1.125 x509.c
--- usr.sbin/rpki-client/x509.c	2 Dec 2025 12:21:39 -0000	1.125
+++ usr.sbin/rpki-client/x509.c	13 Jan 2026 17:16:01 -0000
@@ -45,7 +45,6 @@ ASN1_OBJECT	*sign_time_oid;	/* pkcs-9 id
 ASN1_OBJECT	*rsc_oid;	/* id-ct-signedChecklist */
 ASN1_OBJECT	*aspa_oid;	/* id-ct-ASPA */
 ASN1_OBJECT	*tak_oid;	/* id-ct-SignedTAL */
-ASN1_OBJECT	*geofeed_oid;	/* id-ct-geofeedCSVwithCRLF */
 ASN1_OBJECT	*spl_oid;	/* id-ct-signedPrefixList */
 ASN1_OBJECT	*ccr_oid;	/* CanonicalCacheRepresentation PEN OID */
 
@@ -100,10 +99,6 @@ static const struct {
 	{
 		.oid = "1.2.840.113549.1.9.5",
 		.ptr = &sign_time_oid,
-	},
-	{
-		.oid = "1.2.840.113549.1.9.16.1.47",
-		.ptr = &geofeed_oid,
 	},
 	{
 		.oid = "1.2.840.113549.1.9.16.1.48",
Index: regress/usr.sbin/rpki-client/Makefile.inc
===================================================================
RCS file: /cvs/src/regress/usr.sbin/rpki-client/Makefile.inc,v
diff -u -p -r1.44 Makefile.inc
--- regress/usr.sbin/rpki-client/Makefile.inc	13 Nov 2025 15:18:53 -0000	1.44
+++ regress/usr.sbin/rpki-client/Makefile.inc	13 Jan 2026 17:16:01 -0000
@@ -7,7 +7,6 @@ CFLAGS += -Werror
 
 PROGS += test-ip
 PROGS += test-cert
-PROGS += test-geofeed
 PROGS += test-mft
 PROGS += test-roa
 PROGS += test-rsc
@@ -23,7 +22,7 @@ REGRESS_TARGETS += run-regress-$p
 .endfor
 
 CFLAGS+=	-I${.CURDIR}/.. -I${.CURDIR}/../../../../usr.sbin/rpki-client
-LDADD+=		-lcrypto -lutil -lpthread
+LDADD+=		-lcrypto -lutil -lpthread -lz
 DPADD+=		${LIBCRYPTO} ${LIBUTIL} ${LIBPTHREAD}
 
 CLEANFILES+=	*.out *.err *.txt
@@ -60,10 +59,6 @@ SRCS_test-rsc+=	test-rsc.c rsc.c ${TEST_
 
 run-regress-test-rsc: test-rsc
 	./test-rsc -v ${.CURDIR}/../rsc/*.sig
-
-SRCS_test-geofeed+=	test-geofeed.c geofeed.c ${TEST_COMMON}
-run-regress-test-geofeed: test-geofeed
-	./test-geofeed -v ${.CURDIR}/../geofeed/*.csv
 
 SRCS_test-tal+=	test-tal.c tal.c ${TEST_COMMON}
 run-regress-test-tal: test-tal
Index: regress/usr.sbin/rpki-client/geofeed/geofeed.csv
===================================================================
RCS file: regress/usr.sbin/rpki-client/geofeed/geofeed.csv
diff -N regress/usr.sbin/rpki-client/geofeed/geofeed.csv
--- regress/usr.sbin/rpki-client/geofeed/geofeed.csv	17 Nov 2025 13:05:27 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,32 +0,0 @@
-2001:67c:208c::/48,NL,NL-NH,Amsterdam,
-# RPKI Signature: 2001:67c:208c::/48
-# MIIGBQYJKoZIhvcNAQcCoIIF9jCCBfICAQMxDTALBglghkgBZQMEAgEwDQYLKoZIhvcNAQkQ
-# AS+gggQfMIIEGzCCAwOgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAzMTEwLwYDVQQDEyhjYWE4
-# MDVkYmFjMzY0NzQ5YjliMTE1NTkwYWI2ZWYwZjk3MGNkYmQ4MB4XDTI1MTExNzEzMDEzNloX
-# DTI2MTExNzEzMDEzNlowDTELMAkGA1UEAxMCRUUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-# ggEKAoIBAQDOm7fb1HhRuHKqNuELcv2PzqM4a7i9mTTOFZrSVHhWrF4S/5yYuv2cQsJ6ZP4L
-# VhsF6jMAQjZOTpmmnHdmD9N3qHseAKALbpyVmenldsq01S9PtFlFV9wxELo+KO9JJCNhpu5O
-# PaadEn1TWPBME4Lu/7nGYEzxJ5yCPqReyyflBEyAhgG/XLQSfX0WarTbl6FcW+3PyCpvSadj
-# Kz8F3BC1xuCk4lcn9XbWn64Yrukx73JVVGyoS+pdbRMYCWztW7d9ulkgK9M3l0mGV3wdKjHJ
-# 4uVBp62CyY0MsVvX2R0+q5h+4sbNw1pmbP+AtKfm4DbLwB4aVTaRzF69sYn/ClvVAgMBAAGj
-# ggFeMIIBWjAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFA0Z3l9RwsjhnY+wA0Rng1g8noVi
-# MB8GA1UdIwQYMBaAFMqoBdusNkdJubEVWQq27w+XDNvYMBgGA1UdIAEB/wQOMAwwCgYIKwYB
-# BQUHDgIwIgYIKwYBBQUHAQcBAf8EEzARMA8EAgACMAkDBwAgAQZ8IIwwZAYIKwYBBQUHAQEE
-# WDBWMFQGCCsGAQUFBzAChkhyc3luYzovL3Jwa2kucmlwZS5uZXQvcmVwb3NpdG9yeS9ERUZB
-# VUxUL3lxZ0YyNncyUjBtNXNSVlpDcmJ2RDVjTTI5Zy5jZXIwZAYDVR0fBF0wWzBZoFegVYZT
-# cnN5bmM6Ly9jaGxvZS5zb2Jvcm5vc3QubmV0L3Jwa2kvUklQRS1ubGpvYnNuaWpkZXJzL3lx
-# Z0YyNncyUjBtNXNSVlpDcmJ2RDVjTTI5Zy5jcmwwDQYJKoZIhvcNAQELBQADggEBAFUMmbtH
-# QGJI1+pv9Uc65VwkTrt8wcOhFYAa3rB7dRn47kr16DrrfO13cI5HHb89LR1NZwTeJNAnMq1s
-# hCq8lHo7io1Zz/8Fpw02zgxtmsRhp5xCai5mE+OiwNCG1XEhLNQIv8GU+BKY9yg2mH2BbgnZ
-# cXjT+WatvwmXLCxc+SUvwJAaaB+Dxp8UxYAO5iAKyNAGSQXPr6hEN+G3boXVguFLknEjQaxm
-# NtqxgDMXwz643CcsaSF2M1yjxDgG6Fcm0z3dUAkLUTY8RRKHUjl2lgw/r9D7ODEPY5V8sPVZ
-# L9KHGG1a+Neu5Nmyl0nXqTaLA3Xpgo6J/jI5A76pCICTTlAxggGqMIIBpgIBA4AUDRneX1HC
-# yOGdj7ADRGeDWDyehWIwCwYJYIZIAWUDBAIBoGswGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJ
-# EAEvMBwGCSqGSIb3DQEJBTEPFw0yNTExMTcxMzAxMzZaMC8GCSqGSIb3DQEJBDEiBCCY9XhR
-# Yzvj+pM/b0lZoc+ZapOfmX5IuOFoPcym0ogh6DANBgkqhkiG9w0BAQEFAASCAQAEFmRnDi5e
-# A4R+rlc3VRSxEMffRhsrDGxvnTjea0uHvf8172ScwV+TK7M31KNBrAaiyiB5jA+scgO/schf
-# +8I2ABWBpmWPmGLxiVQNZpEuYrapvzYrLFNCoZ1ewX0xQSWajln02meR6b13iBMVnZubiBTc
-# RmVOXigAdFk3v+ed3KvSmwRoh/GCsQkhCfOTS6RCbRWj0zCZTh8fsTWa/9zcpE8YCY6j++gc
-# t2e6uFR9kBJknXiMoG1lC4B7y1e/JD5U0wShWNNW9/ZedBnUjYtm3GDHH9ga/gNW5BX3MgZk
-# amcY6E189ShNevRmHQFfsJLB7B1cAjH6ZF7XNhCo0Xos
-# End Signature: 2001:67c:208c::/48