[prev in list] [next in list] [prev in thread] [next in thread]
List: openbsd-tech
Subject: rpki-client: make ASPA AFI-agnostic
From: Job Snijders <job () openbsd ! org>
Date: 2023-06-07 12:21:23
Message-ID: ZIB2Q5y_-O1EZXhH () anton ! sobornost ! net
[Download RAW message or body]
Dear all,
To simplify the concept of RPKI ASPAs, the sidrops@ group came to
consensus on removing the notion of 'afiLimit'. This means that going
forward, ASPA will be AFI-agnostic.
Advantages to operators are that by creating just one ASPA they'll be
prepared for a IPv4+IPv6 dual-stack future (no need to update the ASPA
when IPv6 BGP sessions are added at a later point in time), and for BGP
implementers the cachability of the AS_PATH attribute is restored to its
former glory.
New ASPA profile definition is pending review here: https://github.com/QratorLabs/ASPA/pull/15/files
A test object reachable via RIPE NCC TAL is available here:
rsync://chloe.sobornost.net/rpki/RIPE-nljobsnijders/5m80fwYws_3FiFD7JiQjAqZ1RYQ.asa
Feedback?
Kind regards,
Job
Index: aspa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/aspa.c,v
retrieving revision 1.18
diff -u -p -r1.18 aspa.c
--- aspa.c 7 Jun 2023 10:46:34 -0000 1.18
+++ aspa.c 7 Jun 2023 12:15:08 -0000
@@ -47,32 +47,15 @@ extern ASN1_OBJECT *aspa_oid;
*/
typedef struct {
- ASN1_INTEGER *providerASID;
- ASN1_OCTET_STRING *afiLimit;
-} ProviderAS;
-
-DECLARE_STACK_OF(ProviderAS);
-
-#ifndef DEFINE_STACK_OF
-#define sk_ProviderAS_num(sk) SKM_sk_num(ProviderAS, (sk))
-#define sk_ProviderAS_value(sk, i) SKM_sk_value(ProviderAS, (sk), (i))
-#endif
-
-ASN1_SEQUENCE(ProviderAS) = {
- ASN1_SIMPLE(ProviderAS, providerASID, ASN1_INTEGER),
- ASN1_OPT(ProviderAS, afiLimit, ASN1_OCTET_STRING),
-} ASN1_SEQUENCE_END(ProviderAS);
-
-typedef struct {
ASN1_INTEGER *version;
ASN1_INTEGER *customerASID;
- STACK_OF(ProviderAS) *providers;
+ STACK_OF(ASN1_INTEGER) *providers;
} ASProviderAttestation;
ASN1_SEQUENCE(ASProviderAttestation) = {
ASN1_EXP_OPT(ASProviderAttestation, version, ASN1_INTEGER, 0),
ASN1_SIMPLE(ASProviderAttestation, customerASID, ASN1_INTEGER),
- ASN1_SEQUENCE_OF(ASProviderAttestation, providers, ProviderAS),
+ ASN1_SEQUENCE_OF(ASProviderAttestation, providers, ASN1_INTEGER),
} ASN1_SEQUENCE_END(ASProviderAttestation);
DECLARE_ASN1_FUNCTIONS(ASProviderAttestation);
@@ -83,13 +66,13 @@ IMPLEMENT_ASN1_FUNCTIONS(ASProviderAttes
* Return zero on failure, non-zero on success.
*/
static int
-aspa_parse_providers(struct parse *p, const STACK_OF(ProviderAS) *providers)
+aspa_parse_providers(struct parse *p, const STACK_OF(ASN1_INTEGER) *providers)
{
- ProviderAS *pa;
- struct aspa_provider provider;
+ const ASN1_INTEGER *pa;
+ uint32_t provider;
size_t providersz, i;
- if ((providersz = sk_ProviderAS_num(providers)) == 0) {
+ if ((providersz = sk_ASN1_INTEGER_num(providers)) == 0) {
warnx("%s: ASPA: ProviderASSet needs at least one entry",
p->fn);
return 0;
@@ -106,39 +89,33 @@ aspa_parse_providers(struct parse *p, co
err(1, NULL);
for (i = 0; i < providersz; i++) {
- pa = sk_ProviderAS_value(providers, i);
+ pa = sk_ASN1_INTEGER_value(providers, i);
memset(&provider, 0, sizeof(provider));
- if (!as_id_parse(pa->providerASID, &provider.as)) {
+ if (!as_id_parse(pa, &provider)) {
warnx("%s: ASPA: malformed ProviderAS", p->fn);
return 0;
}
- if (p->res->custasid == provider.as) {
+ if (p->res->custasid == provider) {
warnx("%s: ASPA: CustomerASID can't also be Provider",
p->fn);
return 0;
}
if (i > 0) {
- if (p->res->providers[i - 1].as > provider.as) {
+ if (p->res->providers[i - 1] > provider) {
warnx("%s: ASPA: invalid ProviderASSet order",
p->fn);
return 0;
}
- if (p->res->providers[i - 1].as == provider.as) {
+ if (p->res->providers[i - 1] == provider) {
warnx("%s: ASPA: duplicate ProviderAS", p->fn);
return 0;
}
}
- if (pa->afiLimit != NULL && !ip_addr_afi_parse(p->fn,
- pa->afiLimit, &provider.afi)) {
- warnx("%s: ASPA: invalid afiLimit", p->fn);
- return 0;
- }
-
p->res->providers[p->res->providersz++] = provider;
}
@@ -161,7 +138,7 @@ aspa_parse_econtent(const unsigned char
goto out;
}
- if (!valid_econtent_version(p->fn, aspa->version, 0))
+ if (!valid_econtent_version(p->fn, aspa->version, 1))
goto out;
if (!as_id_parse(aspa->customerASID, &p->res->custasid)) {
@@ -314,8 +291,7 @@ aspa_read(struct ibuf *b)
io_read_buf(b, &p->expires, sizeof(p->expires));
io_read_buf(b, &p->providersz, sizeof(size_t));
- if ((p->providers = calloc(p->providersz,
- sizeof(struct aspa_provider))) == NULL)
+ if ((p->providers = calloc(p->providersz, sizeof(uint32_t))) == NULL)
err(1, NULL);
io_read_buf(b, p->providers, p->providersz * sizeof(p->providers[0]));
@@ -328,12 +304,12 @@ aspa_read(struct ibuf *b)
}
/*
- * Insert a new aspa_provider at index idx in the struct vap v.
+ * Insert a new uint32_t at index idx in the struct vap v.
* All elements in the provider array from idx are moved up by one
* to make space for the new element.
*/
static void
-insert_vap(struct vap *v, uint32_t idx, struct aspa_provider *p)
+insert_vap(struct vap *v, uint32_t idx, uint32_t *p)
{
if (idx < v->providersz)
memmove(v->providers + idx + 1, v->providers + idx,
@@ -391,21 +367,15 @@ aspa_insert_vaps(struct vap_tree *tree,
*/
for (i = 0, j = 0; i < aspa->providersz; ) {
if (j == v->providersz ||
- aspa->providers[i].as < v->providers[j].as) {
+ aspa->providers[i] < v->providers[j]) {
/* merge provider from aspa into v */
repo_stat_inc(rp, v->talid, RTYPE_ASPA,
- STYPE_BOTH + aspa->providers[i].afi);
+ STYPE_BOTH + aspa->providers[i]);
insert_vap(v, j, &aspa->providers[i]);
i++;
- } else if (aspa->providers[i].as == v->providers[j].as) {
- /* duplicate provider, merge afi */
- if (v->providers[j].afi != aspa->providers[i].afi) {
- repo_stat_inc(rp, v->talid, RTYPE_ASPA,
- STYPE_BOTH + aspa->providers[i].afi);
- v->providers[j].afi = 0;
- }
+ } else if (aspa->providers[i] == v->providers[j])
i++;
- }
+
if (j < v->providersz)
j++;
}
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.184
diff -u -p -r1.184 extern.h
--- extern.h 7 Jun 2023 10:46:34 -0000 1.184
+++ extern.h 7 Jun 2023 12:15:09 -0000
@@ -351,11 +351,6 @@ struct gbr {
int talid; /* TAL the GBR is chained up to */
};
-struct aspa_provider {
- uint32_t as;
- enum afi afi;
-};
-
/*
* A single ASPA record
*/
@@ -367,7 +362,7 @@ struct aspa {
char *sia; /* SIA signedObject */
char *ski; /* SKI */
uint32_t custasid; /* the customerASID */
- struct aspa_provider *providers; /* the providers */
+ uint32_t *providers; /* the providers */
size_t providersz; /* number of providers */
time_t signtime; /* CMS signing-time attribute */
time_t notbefore; /* EE cert's Not Before */
@@ -382,7 +377,7 @@ struct aspa {
struct vap {
RB_ENTRY(vap) entry;
uint32_t custasid;
- struct aspa_provider *providers;
+ uint32_t *providers;
size_t providersz;
time_t expires;
int talid;
Index: output-bgpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/output-bgpd.c,v
retrieving revision 1.27
diff -u -p -r1.27 output-bgpd.c
--- output-bgpd.c 19 Apr 2023 19:26:26 -0000 1.27
+++ output-bgpd.c 7 Jun 2023 12:15:09 -0000
@@ -63,18 +63,8 @@ output_bgpd(FILE *out, struct vrp_tree *
(long long)vap->expires) < 0)
return -1;
for (i = 0; i < vap->providersz; i++) {
- if (fprintf(out, "%u", vap->providers[i].as) < 0)
+ if (fprintf(out, "%u", vap->providers[i]) < 0)
return -1;
- switch (vap->providers[i].afi) {
- case AFI_IPV4:
- if (fprintf(out, " inet") < 0)
- return -1;
- break;
- case AFI_IPV6:
- if (fprintf(out, " inet6") < 0)
- return -1;
- break;
- }
if (i + 1 < vap->providersz)
if (fprintf(out, ", ") < 0)
return -1;
Index: output-json.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/output-json.c,v
retrieving revision 1.39
diff -u -p -r1.39 output-json.c
--- output-json.c 5 Jun 2023 14:19:13 -0000 1.39
+++ output-json.c 7 Jun 2023 12:15:09 -0000
@@ -82,24 +82,18 @@ outputheader_json(struct stats *st)
}
static void
-print_vap(struct vap *v, enum afi afi)
+print_vap(struct vap *v)
{
size_t i;
- int found = 0;
json_do_object("aspa", 1);
json_do_int("customer_asid", v->custasid);
json_do_int("expires", v->expires);
json_do_array("providers");
- for (i = 0; i < v->providersz; i++) {
- if (v->providers[i].afi != 0 && v->providers[i].afi != afi)
- continue;
- found = 1;
- json_do_int("provider", v->providers[i].as);
- }
- if (!found)
- json_do_int("provider", 0);
+ for (i = 0; i < v->providersz; i++)
+ json_do_int("provider", v->providers[i]);
+
json_do_end();
}
@@ -108,18 +102,9 @@ output_aspa(struct vap_tree *vaps)
{
struct vap *v;
- json_do_object("provider_authorizations", 0);
-
- json_do_array("ipv4");
- RB_FOREACH(v, vap_tree, vaps) {
- print_vap(v, AFI_IPV4);
- }
- json_do_end();
-
- json_do_array("ipv6");
- RB_FOREACH(v, vap_tree, vaps) {
- print_vap(v, AFI_IPV6);
- }
+ json_do_array("provider_authorizations");
+ RB_FOREACH(v, vap_tree, vaps)
+ print_vap(v);
json_do_end();
}
Index: print.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/print.c,v
retrieving revision 1.40
diff -u -p -r1.40 print.c
--- print.c 5 Jun 2023 14:19:13 -0000 1.40
+++ print.c 7 Jun 2023 12:15:09 -0000
@@ -613,59 +613,23 @@ rsc_print(const X509 *x, const struct rs
}
static void
-aspa_provider(uint32_t as, enum afi afi)
+aspa_provider(uint32_t as)
{
if (outformats & FORMAT_JSON) {
json_do_object("aspa", 1);
json_do_uint("asid", as);
- if (afi == AFI_IPV4)
- json_do_string("afi_limit", "ipv4");
- if (afi == AFI_IPV6)
- json_do_string("afi_limit", "ipv6");
json_do_end();
} else {
printf("AS: %u", as);
- if (afi == AFI_IPV4)
- printf(" (IPv4 only)");
- if (afi == AFI_IPV6)
- printf(" (IPv6 only)");
printf("\n");
}
}
-static void
-aspa_providers(const struct aspa *a)
-{
- size_t i;
- int hasv4 = 0, hasv6 = 0;
-
- for (i = 0; i < a->providersz; i++) {
- if ((outformats & FORMAT_JSON) == 0 && i > 0)
- printf("%26s", "");
- aspa_provider(a->providers[i].as, a->providers[i].afi);
-
- switch (a->providers[i].afi) {
- case AFI_IPV4:
- hasv4 = 1;
- break;
- case AFI_IPV6:
- hasv6 = 1;
- break;
- default:
- hasv4 = hasv6 = 1;
- break;
- }
- }
-
- if (!hasv4)
- aspa_provider(0, AFI_IPV4);
- if (!hasv6)
- aspa_provider(0, AFI_IPV6);
-}
-
void
aspa_print(const X509 *x, const struct aspa *p)
{
+ size_t i;
+
if (outformats & FORMAT_JSON) {
json_do_string("type", "aspa");
json_do_string("ski", pretty_key_id(p->ski));
@@ -697,7 +661,11 @@ aspa_print(const X509 *x, const struct a
printf("Provider set: ");
}
- aspa_providers(p);
+ for (i = 0; i < p->providersz; i++) {
+ if ((outformats & FORMAT_JSON) == 0 && i > 0)
+ printf("%26s", "");
+ aspa_provider(p->providers[i]);
+ }
if (outformats & FORMAT_JSON)
json_do_end();
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic