Re: rpki-client: add ASPA profile-10 support
On Sat, Aug 13, 2022 at 01:06:38AM +, Job Snijders wrote: > Dear all, > > The below changeset extends rpki-client(8) to validate and emit > Autonomous System Provider Authorizations (ASPAs) in JSON format for > consumption in other routing stacks. > > The ASPA CMS protected content type is specified here: > https://datatracker.ietf.org/doc/html/draft-ietf-sidrops-aspa-profile > > How to verify BGP UPDATES using ASPA objects is described here: > https://datatracker.ietf.org/doc/html/draft-ietf-sidrops-aspa-verification > (Note: aspa-profile and aspa-verification really are two different beasts) > > A test suite to generate conforming and non-conforming ASPA objects is > available at: https://github.com/benmaddison/rpki-aspa-test-data > Another testbed was outlined here: > https://mailarchive.ietf.org/arch/msg/sidrops/DvRqMbOXkhiBDdUCTJU89L4q6LY > > The rpki-client(8) '-j' (/var/db/rpki-client/json) output is formatted > such that transformation into draft-ietf-sidrops-8210bis § 5.12 > RPKI-To-Router PDUs should be easy. However, for future direct > disk-to-bgpd(8) dissemination of ASPA objects; we probably can come up > with something more efficient :-) This brings me to one very basic question for which I couldn't find an answer in the above links: how will ASPAs usually be distributed? > Example output from "rpki-client -f": > > File: > rpki.example.net/rpki/TA/ca-case-multi-afi-true/2338bd30cba1ff30fe3cf930824f39b45569d458de356729cb0121400ee3616a.asa > Hash identifier: P+IG54iYS6VLlZmnIacSks0bZwHxItkIHPt5YjI4y58= > Subject key identifier: > CB:B8:19:D8:E0:FD:8E:0E:10:83:D6:11:6B:2C:CD:92:28:8F:F8:C9 > Certificate serial: 01 > Authority key identifier: > 3C:E8:78:93:CE:9C:7F:41:53:0D:D0:E8:BB:CA:B0:03:7F:69:43:74 > Authority info access: > rsync://rpki.example.net/rpki/TA/ca-case-multi-afi-true.cer > Customer AS: 65004 > Provider Set: > 1: AS: 65005 > 2: AS: 65006 (IPv4 only) > 3: AS: 65007 (IPv6 only) > Validation: OK > > OK? Feedback? Could you please rebase your diff on top of -current so that you won't undo recent pledge and unveil changes to main.c? This looks pretty good already. I have many comments inline that should all be easy to address. Two points up front so they don't get lost in the noise: 1) what will need more work are aspa_insert_vaps() and insert_vap(). Looking up the same two struct vap (depending on the AFI) using RB_INSERT(), walking the array of providers, and reallocating() over and over again is not ideal. Probably aspa_insert_vaps() should fill two arrays (one for each AFI) of size providersz with the respective providerASes up front. Then we can shrink them to their actual sizes and hang them off the two vap for this customer AS. If there is more than one ASPA for that customer AS, then this gets a bit trickier, but this is fine as it should rarely happen. Another approach would be to use some linked list gymnastics. I'm fine with keeping things mostly as they are for now and address this in tree. 2) bikeshed material: the use of AFI_BOTH = 3 as part of enum afi. This is a bit of an ugly hack: according to IANA, AFI number 3 is NSAP. We use enum afi to check the on-the-wire AFIs, so this squatting is not ideal. Since AFI_BOTH isn't really used anyway, I think it would be acceptable to treat 0 implicitly as AFI_BOTH: don't set aspa_p.afi to AFI_BOTH in aspa_parse_providers() and replace "case AFI_BOTH:" with "default:" in aspa_insert_vaps() as you already do in aspa_print(). This matches the semantics in the draft: if the afi isn't explicitly set to IPv4 or IPv6, it applies to both. > > Kind regards, > > Job > > Index: Makefile > === > RCS file: /cvs/src/usr.sbin/rpki-client/Makefile,v > retrieving revision 1.25 > diff -u -p -r1.25 Makefile > --- Makefile 9 May 2022 17:02:34 - 1.25 > +++ Makefile 13 Aug 2022 00:24:24 - > @@ -1,8 +1,8 @@ > #$OpenBSD: Makefile,v 1.25 2022/05/09 17:02:34 job Exp $ > > PROG=rpki-client > -SRCS=as.c cert.c cms.c crl.c encoding.c filemode.c gbr.c http.c io.c > ip.c \ > - log.c main.c mft.c mkdir.c output.c output-bgpd.c output-bird.c \ > +SRCS=as.c aspa.c cert.c cms.c crl.c encoding.c filemode.c gbr.c > http.c io.c \ > + ip.c log.c main.c mft.c mkdir.c output.c output-bgpd.c output-bird.c \ > output-csv.c output-json.c parser.c print.c repo.c roa.c rrdp.c \ > rrdp_delta.c rrdp_notification.c rrdp_snapshot.c rrdp_util.c \ > rsc.c rsync.c tal.c validate.c x509.c > Index: aspa.c > === > RCS file: aspa.c > diff -N aspa.c > --- /dev/null 1 Jan 1970 00:00:00 - > +++ aspa.c13 Aug 2022 00:24:24 - > @@ -0,0 +1,447 @@ > +/* $OpenBSD: aspa.c,v 1.16 2022/05/11 21:19:06 job Exp $ */ > +/* > + * Copyright (c) 2022 Job Snijders You've copied and adapted
rpki-client: add ASPA profile-10 support
Dear all, The below changeset extends rpki-client(8) to validate and emit Autonomous System Provider Authorizations (ASPAs) in JSON format for consumption in other routing stacks. The ASPA CMS protected content type is specified here: https://datatracker.ietf.org/doc/html/draft-ietf-sidrops-aspa-profile How to verify BGP UPDATES using ASPA objects is described here: https://datatracker.ietf.org/doc/html/draft-ietf-sidrops-aspa-verification (Note: aspa-profile and aspa-verification really are two different beasts) A test suite to generate conforming and non-conforming ASPA objects is available at: https://github.com/benmaddison/rpki-aspa-test-data Another testbed was outlined here: https://mailarchive.ietf.org/arch/msg/sidrops/DvRqMbOXkhiBDdUCTJU89L4q6LY The rpki-client(8) '-j' (/var/db/rpki-client/json) output is formatted such that transformation into draft-ietf-sidrops-8210bis § 5.12 RPKI-To-Router PDUs should be easy. However, for future direct disk-to-bgpd(8) dissemination of ASPA objects; we probably can come up with something more efficient :-) Example output from "rpki-client -f": File: rpki.example.net/rpki/TA/ca-case-multi-afi-true/2338bd30cba1ff30fe3cf930824f39b45569d458de356729cb0121400ee3616a.asa Hash identifier: P+IG54iYS6VLlZmnIacSks0bZwHxItkIHPt5YjI4y58= Subject key identifier: CB:B8:19:D8:E0:FD:8E:0E:10:83:D6:11:6B:2C:CD:92:28:8F:F8:C9 Certificate serial: 01 Authority key identifier: 3C:E8:78:93:CE:9C:7F:41:53:0D:D0:E8:BB:CA:B0:03:7F:69:43:74 Authority info access: rsync://rpki.example.net/rpki/TA/ca-case-multi-afi-true.cer Customer AS: 65004 Provider Set: 1: AS: 65005 2: AS: 65006 (IPv4 only) 3: AS: 65007 (IPv6 only) Validation: OK OK? Feedback? Kind regards, Job Index: Makefile === RCS file: /cvs/src/usr.sbin/rpki-client/Makefile,v retrieving revision 1.25 diff -u -p -r1.25 Makefile --- Makefile9 May 2022 17:02:34 - 1.25 +++ Makefile13 Aug 2022 00:24:24 - @@ -1,8 +1,8 @@ # $OpenBSD: Makefile,v 1.25 2022/05/09 17:02:34 job Exp $ PROG= rpki-client -SRCS= as.c cert.c cms.c crl.c encoding.c filemode.c gbr.c http.c io.c ip.c \ - log.c main.c mft.c mkdir.c output.c output-bgpd.c output-bird.c \ +SRCS= as.c aspa.c cert.c cms.c crl.c encoding.c filemode.c gbr.c http.c io.c \ + ip.c log.c main.c mft.c mkdir.c output.c output-bgpd.c output-bird.c \ output-csv.c output-json.c parser.c print.c repo.c roa.c rrdp.c \ rrdp_delta.c rrdp_notification.c rrdp_snapshot.c rrdp_util.c \ rsc.c rsync.c tal.c validate.c x509.c Index: aspa.c === RCS file: aspa.c diff -N aspa.c --- /dev/null 1 Jan 1970 00:00:00 - +++ aspa.c 13 Aug 2022 00:24:24 - @@ -0,0 +1,447 @@ +/* $OpenBSD: aspa.c,v 1.16 2022/05/11 21:19:06 job Exp $ */ +/* + * Copyright (c) 2022 Job Snijders + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "extern.h" + +/* + * Parse results and data of the ASPA object. + */ +struct parse { + const char *fn; /* ASPA file name */ + struct aspa *res; /* results */ +}; + +extern ASN1_OBJECT *aspa_oid; + +/* + * Types and templates for ASPA eContent draft-ietf-sidrops-aspa-profile-08 + */ + +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; +} ASProviderAttestation; + +ASN1_SEQUENCE(ASProviderAttestation) = { + ASN1_IMP_OPT(ASProviderAttestation,