1*29bf64caSjob /* $OpenBSD: extern.h,v 1.236 2025/01/03 10:14:32 job Exp $ */ 29a7e9e7fSjob /* 39a7e9e7fSjob * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> 49a7e9e7fSjob * 59a7e9e7fSjob * Permission to use, copy, modify, and distribute this software for any 69a7e9e7fSjob * purpose with or without fee is hereby granted, provided that the above 79a7e9e7fSjob * copyright notice and this permission notice appear in all copies. 89a7e9e7fSjob * 99a7e9e7fSjob * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 109a7e9e7fSjob * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 119a7e9e7fSjob * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 129a7e9e7fSjob * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 139a7e9e7fSjob * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 149a7e9e7fSjob * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 159a7e9e7fSjob * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 169a7e9e7fSjob */ 179a7e9e7fSjob #ifndef EXTERN_H 189a7e9e7fSjob #define EXTERN_H 199a7e9e7fSjob 20eae58378Sclaudio #include <sys/queue.h> 21a382efa2Sclaudio #include <sys/tree.h> 22b0404f1fSderaadt #include <sys/time.h> 23a382efa2Sclaudio 240102fb1bSclaudio #include <openssl/x509.h> 2533e36affStb #include <openssl/x509v3.h> 260102fb1bSclaudio 270bc420b9Sclaudio #define CTASSERT(x) extern char _ctassert[(x) ? 1 : -1 ] \ 280bc420b9Sclaudio __attribute__((__unused__)) 290bc420b9Sclaudio 30b5fa5d51Sclaudio #define MAX_MSG_SIZE (50 * 1024 * 1024) 31b5fa5d51Sclaudio 329a7e9e7fSjob enum cert_as_type { 339a7e9e7fSjob CERT_AS_ID, /* single identifier */ 34335482abStb CERT_AS_INHERIT, /* inherit from issuer */ 359a7e9e7fSjob CERT_AS_RANGE, /* range of identifiers */ 369a7e9e7fSjob }; 379a7e9e7fSjob 389a7e9e7fSjob /* 399a7e9e7fSjob * An AS identifier range. 409a7e9e7fSjob * The maximum AS identifier is an unsigned 32 bit integer (RFC 6793). 419a7e9e7fSjob */ 429a7e9e7fSjob struct cert_as_range { 439a7e9e7fSjob uint32_t min; /* minimum non-zero */ 449a7e9e7fSjob uint32_t max; /* maximum */ 459a7e9e7fSjob }; 469a7e9e7fSjob 479a7e9e7fSjob /* 489a7e9e7fSjob * An autonomous system (AS) object. 499a7e9e7fSjob * AS identifiers are unsigned 32 bit integers (RFC 6793). 509a7e9e7fSjob */ 519a7e9e7fSjob struct cert_as { 529a7e9e7fSjob enum cert_as_type type; /* type of AS specification */ 539a7e9e7fSjob union { 549a7e9e7fSjob uint32_t id; /* singular identifier */ 559a7e9e7fSjob struct cert_as_range range; /* range */ 569a7e9e7fSjob }; 579a7e9e7fSjob }; 589a7e9e7fSjob 599a7e9e7fSjob /* 609a7e9e7fSjob * AFI values are assigned by IANA. 619a7e9e7fSjob * In rpki-client, we only accept the IPV4 and IPV6 AFI values. 629a7e9e7fSjob */ 639a7e9e7fSjob enum afi { 6422bf1969Sclaudio AFI_IPV4 = 1, 6522bf1969Sclaudio AFI_IPV6 = 2 669a7e9e7fSjob }; 679a7e9e7fSjob 689a7e9e7fSjob /* 699a7e9e7fSjob * An IP address as parsed from RFC 3779, section 2.2.3.8. 709a7e9e7fSjob * This is either in a certificate or an ROA. 719a7e9e7fSjob * It may either be IPv4 or IPv6. 729a7e9e7fSjob */ 739a7e9e7fSjob struct ip_addr { 749a7e9e7fSjob unsigned char addr[16]; /* binary address prefix */ 7522bf1969Sclaudio unsigned char prefixlen; /* number of valid bits in address */ 769a7e9e7fSjob }; 779a7e9e7fSjob 789a7e9e7fSjob /* 799a7e9e7fSjob * An IP address (IPv4 or IPv6) range starting at the minimum and making 809a7e9e7fSjob * its way to the maximum. 819a7e9e7fSjob */ 829a7e9e7fSjob struct ip_addr_range { 839a7e9e7fSjob struct ip_addr min; /* minimum ip */ 849a7e9e7fSjob struct ip_addr max; /* maximum ip */ 859a7e9e7fSjob }; 869a7e9e7fSjob 879a7e9e7fSjob enum cert_ip_type { 889a7e9e7fSjob CERT_IP_ADDR, /* IP address range w/shared prefix */ 899a7e9e7fSjob CERT_IP_INHERIT, /* inherited IP address */ 909a7e9e7fSjob CERT_IP_RANGE /* range of IP addresses */ 919a7e9e7fSjob }; 929a7e9e7fSjob 939a7e9e7fSjob /* 949a7e9e7fSjob * A single IP address family (AFI, address or range) as defined in RFC 959a7e9e7fSjob * 3779, 2.2.3.2. 969a7e9e7fSjob * The RFC specifies multiple address or ranges per AFI; this structure 979a7e9e7fSjob * encodes both the AFI and a single address or range. 989a7e9e7fSjob */ 999a7e9e7fSjob struct cert_ip { 1009a7e9e7fSjob enum afi afi; /* AFI value */ 1019a7e9e7fSjob enum cert_ip_type type; /* type of IP entry */ 1029a7e9e7fSjob unsigned char min[16]; /* full range minimum */ 1039a7e9e7fSjob unsigned char max[16]; /* full range maximum */ 1049a7e9e7fSjob union { 1059a7e9e7fSjob struct ip_addr ip; /* singular address */ 1069a7e9e7fSjob struct ip_addr_range range; /* range */ 1079a7e9e7fSjob }; 1089a7e9e7fSjob }; 1099a7e9e7fSjob 110fdfddccfSjob enum cert_purpose { 1116b83d8e3Sjob CERT_PURPOSE_INVALID, 1126468d235Stb CERT_PURPOSE_TA, 1136b83d8e3Sjob CERT_PURPOSE_CA, 1146468d235Stb CERT_PURPOSE_EE, 1156468d235Stb CERT_PURPOSE_BGPSEC_ROUTER, 116fdfddccfSjob }; 117fdfddccfSjob 1189a7e9e7fSjob /* 1199a7e9e7fSjob * Parsed components of a validated X509 certificate stipulated by RFC 1209a7e9e7fSjob * 6847 and further (within) by RFC 3779. 1219a7e9e7fSjob * All AS numbers are guaranteed to be non-overlapping and properly 1229a7e9e7fSjob * inheriting. 1239a7e9e7fSjob */ 1249a7e9e7fSjob struct cert { 1259a7e9e7fSjob struct cert_ip *ips; /* list of IP address ranges */ 126381ee599Stb size_t num_ips; 127381ee599Stb struct cert_as *ases; /* list of AS numbers and ranges */ 128381ee599Stb size_t num_ases; 129dc508150Sclaudio int talid; /* cert is covered by which TAL */ 1300bc420b9Sclaudio int certid; 131c94cf448Sclaudio unsigned int repoid; /* repository of this cert file */ 13284c20e47Sclaudio char *repo; /* CA repository (rsync:// uri) */ 1339a7e9e7fSjob char *mft; /* manifest (rsync:// uri) */ 1343d81c3dfSclaudio char *notify; /* RRDP notify (https:// uri) */ 1359a7e9e7fSjob char *crl; /* CRL location (rsync:// or NULL) */ 136ebd55816Sjob char *aia; /* AIA (or NULL, for trust anchor) */ 1379a7e9e7fSjob char *aki; /* AKI (or NULL, for trust anchor) */ 1389a7e9e7fSjob char *ski; /* SKI */ 139dc508150Sclaudio enum cert_purpose purpose; /* BGPSec or CA */ 14017304ed1Sjob char *pubkey; /* Subject Public Key Info */ 141cbcd0d1aSbenno X509 *x509; /* the cert */ 142f5999ddfSjob time_t notbefore; /* cert's Not Before */ 1439f544822Sjob time_t notafter; /* cert's Not After */ 144894936b4Sjob time_t expires; /* when the signature path expires */ 1459a7e9e7fSjob }; 1469a7e9e7fSjob 1479a7e9e7fSjob /* 1489a7e9e7fSjob * The TAL file conforms to RFC 7730. 1499a7e9e7fSjob * It is the top-level structure of RPKI and defines where we can find 1509a7e9e7fSjob * certificates for TAs (trust anchors). 1519a7e9e7fSjob * It also includes the public key for verifying those trust anchor 1529a7e9e7fSjob * certificates. 1539a7e9e7fSjob */ 1549a7e9e7fSjob struct tal { 1559a7e9e7fSjob char **uri; /* well-formed rsync URIs */ 15630a08502Stb size_t num_uris; 1579a7e9e7fSjob unsigned char *pkey; /* DER-encoded public key */ 1589a7e9e7fSjob size_t pkeysz; /* length of pkey */ 159a382efa2Sclaudio char *descr; /* basename of tal file */ 160dc508150Sclaudio int id; /* ID of this TAL */ 1619a7e9e7fSjob }; 1629a7e9e7fSjob 1639a7e9e7fSjob /* 16422cec6c4Stb * Resource types specified by the RPKI profiles. 16522cec6c4Stb * There might be others we don't consider. 16622cec6c4Stb */ 16722cec6c4Stb enum rtype { 16822cec6c4Stb RTYPE_INVALID, 16922cec6c4Stb RTYPE_TAL, 17022cec6c4Stb RTYPE_MFT, 17122cec6c4Stb RTYPE_ROA, 17222cec6c4Stb RTYPE_CER, 17322cec6c4Stb RTYPE_CRL, 17422cec6c4Stb RTYPE_GBR, 17522cec6c4Stb RTYPE_REPO, 17622cec6c4Stb RTYPE_FILE, 17704834fbdSjob RTYPE_RSC, 178a29ddfd5Sjob RTYPE_ASPA, 179ee2a33daSjob RTYPE_TAK, 180ef3f6f56Sjob RTYPE_GEOFEED, 181d4be4cdeSjob RTYPE_SPL, 18222cec6c4Stb }; 18322cec6c4Stb 184df512fbcSclaudio enum location { 185df512fbcSclaudio DIR_UNKNOWN, 186df512fbcSclaudio DIR_TEMP, 187df512fbcSclaudio DIR_VALID, 188df512fbcSclaudio }; 189df512fbcSclaudio 19022cec6c4Stb /* 1919a7e9e7fSjob * Files specified in an MFT have their bodies hashed with SHA256. 1929a7e9e7fSjob */ 1939a7e9e7fSjob struct mftfile { 1949a7e9e7fSjob char *file; /* filename (CER/ROA/CRL, no path) */ 19522cec6c4Stb enum rtype type; /* file type as determined by extension */ 196df512fbcSclaudio enum location location; /* temporary or valid directory */ 1979a7e9e7fSjob unsigned char hash[SHA256_DIGEST_LENGTH]; /* sha256 of body */ 1989a7e9e7fSjob }; 1999a7e9e7fSjob 2009a7e9e7fSjob /* 2019a7e9e7fSjob * A manifest, RFC 6486. 2029a7e9e7fSjob * This consists of a bunch of files found in the same directory as the 2039a7e9e7fSjob * manifest file. 2049a7e9e7fSjob */ 2059a7e9e7fSjob struct mft { 206100ded9eSclaudio char *path; /* relative path to directory of the MFT */ 2079a7e9e7fSjob struct mftfile *files; /* file and hash */ 208ab5c69fdSjob char *seqnum; /* manifestNumber */ 209ebd55816Sjob char *aia; /* AIA */ 2109a7e9e7fSjob char *aki; /* AKI */ 2112cf0e122Sjob char *sia; /* SIA signedObject */ 212ebd55816Sjob char *ski; /* SKI */ 21323bc08f8Sclaudio char *crl; /* CRL file name */ 214c5b5cf9aSjob unsigned char mfthash[SHA256_DIGEST_LENGTH]; 21523bc08f8Sclaudio unsigned char crlhash[SHA256_DIGEST_LENGTH]; 2161bb1e509Sjob time_t signtime; /* CMS signing-time attribute */ 2174dbb22b8Sjob time_t thisupdate; /* from the eContent */ 2184dbb22b8Sjob time_t nextupdate; /* from the eContent */ 219894936b4Sjob time_t expires; /* when the signature path expires */ 220df512fbcSclaudio size_t filesz; /* number of filenames */ 221100ded9eSclaudio unsigned int repoid; 2221fc2657fSclaudio int talid; 2230bc420b9Sclaudio int certid; 224318f0572Sjob int seqnum_gap; /* was there a gap compared to prev mft? */ 2259a7e9e7fSjob }; 2269a7e9e7fSjob 2279a7e9e7fSjob /* 2289a7e9e7fSjob * An IP address prefix for a given ROA. 2299a7e9e7fSjob * This encodes the maximum length, AFI (v6/v4), and address. 2309a7e9e7fSjob * FIXME: are the min/max necessary or just used in one place? 2319a7e9e7fSjob */ 2329a7e9e7fSjob struct roa_ip { 2339a7e9e7fSjob enum afi afi; /* AFI value */ 234b6884e9fSclaudio struct ip_addr addr; /* the address prefix itself */ 2359a7e9e7fSjob unsigned char min[16]; /* full range minimum */ 2369a7e9e7fSjob unsigned char max[16]; /* full range maximum */ 237b6884e9fSclaudio unsigned char maxlength; /* max length or zero */ 2389a7e9e7fSjob }; 2399a7e9e7fSjob 2409a7e9e7fSjob /* 2419a7e9e7fSjob * An ROA, RFC 6482. 2429a7e9e7fSjob * This consists of the concerned ASID and its IP prefixes. 2439a7e9e7fSjob */ 2449a7e9e7fSjob struct roa { 2459a7e9e7fSjob uint32_t asid; /* asID of ROA (if 0, RFC 6483 sec 4) */ 2469a7e9e7fSjob struct roa_ip *ips; /* IP prefixes */ 247381ee599Stb size_t num_ips; 248dc508150Sclaudio int talid; /* ROAs are covered by which TAL */ 2499a7e9e7fSjob int valid; /* validated resources */ 250ebd55816Sjob char *aia; /* AIA */ 2519a7e9e7fSjob char *aki; /* AKI */ 2522cf0e122Sjob char *sia; /* SIA signedObject */ 253ebd55816Sjob char *ski; /* SKI */ 2541bb1e509Sjob time_t signtime; /* CMS signing-time attribute */ 255f5999ddfSjob time_t notbefore; /* EE cert's Not Before */ 2569f544822Sjob time_t notafter; /* EE cert's Not After */ 257894936b4Sjob time_t expires; /* when the signature path expires */ 2589a7e9e7fSjob }; 2599a7e9e7fSjob 26004834fbdSjob struct rscfile { 26104834fbdSjob char *filename; /* an optional filename on the checklist */ 26204834fbdSjob unsigned char hash[SHA256_DIGEST_LENGTH]; /* the digest */ 26304834fbdSjob }; 26404834fbdSjob 26504834fbdSjob /* 26604834fbdSjob * A Signed Checklist (RSC) 26704834fbdSjob */ 26804834fbdSjob struct rsc { 26904834fbdSjob int talid; /* RSC covered by what TAL */ 27004834fbdSjob int valid; /* eContent resources covered by EE's 3779? */ 27104834fbdSjob struct cert_ip *ips; /* IP prefixes */ 272381ee599Stb size_t num_ips; 273381ee599Stb struct cert_as *ases; /* AS resources */ 274381ee599Stb size_t num_ases; 27504834fbdSjob struct rscfile *files; /* FileAndHashes in the RSC */ 27630a08502Stb size_t num_files; 27704834fbdSjob char *aia; /* AIA */ 27804834fbdSjob char *aki; /* AKI */ 27904834fbdSjob char *ski; /* SKI */ 2801bb1e509Sjob time_t signtime; /* CMS signing-time attribute */ 281f5999ddfSjob time_t notbefore; /* EE cert's Not Before */ 2829f544822Sjob time_t notafter; /* Not After of the RSC EE */ 283894936b4Sjob time_t expires; /* when the signature path expires */ 28404834fbdSjob }; 28504834fbdSjob 2869a7e9e7fSjob /* 287d4be4cdeSjob * An IP address prefix in a given SignedPrefixList. 288d4be4cdeSjob */ 289d4be4cdeSjob struct spl_pfx { 290d4be4cdeSjob enum afi afi; 291d4be4cdeSjob struct ip_addr prefix; 292d4be4cdeSjob }; 293d4be4cdeSjob 294d4be4cdeSjob /* 295d4be4cdeSjob * An SPL, draft-ietf-sidrops-rpki-prefixlist 296d4be4cdeSjob * This consists of an ASID and its IP prefixes. 297d4be4cdeSjob */ 298d4be4cdeSjob struct spl { 299d4be4cdeSjob uint32_t asid; 30030a08502Stb struct spl_pfx *prefixes; 30130a08502Stb size_t num_prefixes; 302d4be4cdeSjob int talid; 303d4be4cdeSjob char *aia; 304d4be4cdeSjob char *aki; 305d4be4cdeSjob char *sia; 306d4be4cdeSjob char *ski; 307d4be4cdeSjob time_t signtime; /* CMS signing-time attribute */ 308d4be4cdeSjob time_t notbefore; /* EE cert's Not Before */ 309d4be4cdeSjob time_t notafter; /* EE cert's Not After */ 310d4be4cdeSjob time_t expires; /* when the certification path expires */ 311d4be4cdeSjob int valid; 312d4be4cdeSjob }; 313d4be4cdeSjob 314d4be4cdeSjob /* 315ee2a33daSjob * Datastructure representing the TAKey sequence inside TAKs. 316ee2a33daSjob */ 317ee2a33daSjob struct takey { 318ee2a33daSjob char **comments; /* Comments */ 31930a08502Stb size_t num_comments; 320ee2a33daSjob char **uris; /* CertificateURI */ 32130a08502Stb size_t num_uris; 322ee2a33daSjob unsigned char *pubkey; /* DER encoded SubjectPublicKeyInfo */ 323ee2a33daSjob size_t pubkeysz; 324ee2a33daSjob char *ski; /* hex encoded SubjectKeyIdentifier of pubkey */ 325ee2a33daSjob }; 326ee2a33daSjob 327ee2a33daSjob /* 328ee2a33daSjob * A Signed TAL (TAK) draft-ietf-sidrops-signed-tal-12 329ee2a33daSjob */ 330ee2a33daSjob struct tak { 331ee2a33daSjob int talid; /* TAK covered by what TAL */ 332ee2a33daSjob struct takey *current; 333ee2a33daSjob struct takey *predecessor; 334ee2a33daSjob struct takey *successor; 335ee2a33daSjob char *aia; /* AIA */ 336ee2a33daSjob char *aki; /* AKI */ 3372cf0e122Sjob char *sia; /* SIA signed Object */ 338ee2a33daSjob char *ski; /* SKI */ 3391bb1e509Sjob time_t signtime; /* CMS signing-time attribute */ 340f5999ddfSjob time_t notbefore; /* EE cert's Not Before */ 3419f544822Sjob time_t notafter; /* Not After of the TAK EE */ 342894936b4Sjob time_t expires; /* when the signature path expires */ 343ee2a33daSjob }; 344ee2a33daSjob 345ee2a33daSjob /* 346ef3f6f56Sjob * A single geofeed record 347ef3f6f56Sjob */ 348ef3f6f56Sjob struct geoip { 349ef3f6f56Sjob struct cert_ip *ip; 350ef3f6f56Sjob char *loc; 351ef3f6f56Sjob }; 352ef3f6f56Sjob 353ef3f6f56Sjob /* 354ef3f6f56Sjob * A geofeed file 355ef3f6f56Sjob */ 356ef3f6f56Sjob struct geofeed { 357ef3f6f56Sjob struct geoip *geoips; /* Prefix + location entry in the CSV */ 358381ee599Stb size_t num_geoips; 359ef3f6f56Sjob char *aia; /* AIA */ 360ef3f6f56Sjob char *aki; /* AKI */ 361ef3f6f56Sjob char *ski; /* SKI */ 3621bb1e509Sjob time_t signtime; /* CMS signing-time attribute */ 363f5999ddfSjob time_t notbefore; /* EE cert's Not Before */ 3649f544822Sjob time_t notafter; /* Not After of the Geofeed EE */ 365894936b4Sjob time_t expires; /* when the signature path expires */ 366ef3f6f56Sjob int valid; /* all resources covered */ 367ef3f6f56Sjob }; 368ef3f6f56Sjob 369ef3f6f56Sjob /* 3704be5941aSclaudio * A single Ghostbuster record 3714be5941aSclaudio */ 3724be5941aSclaudio struct gbr { 3734be5941aSclaudio char *vcard; 374ebd55816Sjob char *aia; /* AIA */ 3754be5941aSclaudio char *aki; /* AKI */ 3762cf0e122Sjob char *sia; /* SIA signedObject */ 377ebd55816Sjob char *ski; /* SKI */ 3781bb1e509Sjob time_t signtime; /* CMS signing-time attribute */ 379f5999ddfSjob time_t notbefore; /* EE cert's Not Before */ 3809f544822Sjob time_t notafter; /* Not After of the GBR EE */ 381894936b4Sjob time_t expires; /* when the signature path expires */ 38208ac1330Sjob int talid; /* TAL the GBR is chained up to */ 3834be5941aSclaudio }; 3844be5941aSclaudio 385a29ddfd5Sjob /* 386a29ddfd5Sjob * A single ASPA record 387a29ddfd5Sjob */ 388a29ddfd5Sjob struct aspa { 389335482abStb int valid; /* contained in issuer auth */ 390a29ddfd5Sjob int talid; /* TAL the ASPA is chained up to */ 391a29ddfd5Sjob char *aia; /* AIA */ 392a29ddfd5Sjob char *aki; /* AKI */ 3932cf0e122Sjob char *sia; /* SIA signedObject */ 394a29ddfd5Sjob char *ski; /* SKI */ 395a29ddfd5Sjob uint32_t custasid; /* the customerASID */ 3964b5fc138Sjob uint32_t *providers; /* the providers */ 39730a08502Stb size_t num_providers; 3981bb1e509Sjob time_t signtime; /* CMS signing-time attribute */ 399f5999ddfSjob time_t notbefore; /* EE cert's Not Before */ 4009f544822Sjob time_t notafter; /* notAfter of the ASPA EE cert */ 401894936b4Sjob time_t expires; /* when the signature path expires */ 402a29ddfd5Sjob }; 403a29ddfd5Sjob 404a29ddfd5Sjob /* 405a29ddfd5Sjob * A Validated ASPA Payload (VAP) tree element. 4063a50f0a9Sjmc * To ease transformation, this struct mimics ASPA RTR PDU structure. 407a29ddfd5Sjob */ 408a29ddfd5Sjob struct vap { 409a29ddfd5Sjob RB_ENTRY(vap) entry; 410a29ddfd5Sjob uint32_t custasid; 4114b5fc138Sjob uint32_t *providers; 41230a08502Stb size_t num_providers; 413a29ddfd5Sjob time_t expires; 4141fc2657fSclaudio int talid; 4151fc2657fSclaudio unsigned int repoid; 4167e284d50Stb int overflowed; 417a29ddfd5Sjob }; 418a29ddfd5Sjob 419a29ddfd5Sjob /* 420a29ddfd5Sjob * Tree of VAPs sorted by afi, custasid, and provideras. 421a29ddfd5Sjob */ 422a29ddfd5Sjob RB_HEAD(vap_tree, vap); 423a29ddfd5Sjob RB_PROTOTYPE(vap_tree, vap, entry, vapcmp); 424a29ddfd5Sjob 4254be5941aSclaudio /* 426a382efa2Sclaudio * A single VRP element (including ASID) 427a382efa2Sclaudio */ 428a382efa2Sclaudio struct vrp { 429a382efa2Sclaudio RB_ENTRY(vrp) entry; 430a382efa2Sclaudio struct ip_addr addr; 431a382efa2Sclaudio uint32_t asid; 432a382efa2Sclaudio enum afi afi; 433a382efa2Sclaudio unsigned char maxlength; 434a66158d7Sjob time_t expires; /* transitive expiry moment */ 4351fc2657fSclaudio int talid; /* covered by which TAL */ 4361fc2657fSclaudio unsigned int repoid; 437a382efa2Sclaudio }; 438a382efa2Sclaudio /* 439a382efa2Sclaudio * Tree of VRP sorted by afi, addr, maxlength and asid 440a382efa2Sclaudio */ 441a382efa2Sclaudio RB_HEAD(vrp_tree, vrp); 442a382efa2Sclaudio RB_PROTOTYPE(vrp_tree, vrp, entry, vrpcmp); 443a382efa2Sclaudio 444a382efa2Sclaudio /* 445d4be4cdeSjob * Validated SignedPrefixList Payload 446d4be4cdeSjob * A single VSP element (including ASID) 447d4be4cdeSjob * draft-ietf-sidrops-rpki-prefixlist 448d4be4cdeSjob */ 449d4be4cdeSjob struct vsp { 450d4be4cdeSjob RB_ENTRY(vsp) entry; 451d4be4cdeSjob uint32_t asid; 452d4be4cdeSjob struct spl_pfx *prefixes; 45330a08502Stb size_t num_prefixes; 454d4be4cdeSjob time_t expires; 455d4be4cdeSjob int talid; 456d4be4cdeSjob unsigned int repoid; 457d4be4cdeSjob }; 458d4be4cdeSjob /* 459d4be4cdeSjob * Tree of VSP sorted by asid 460d4be4cdeSjob */ 461d4be4cdeSjob RB_HEAD(vsp_tree, vsp); 462d4be4cdeSjob RB_PROTOTYPE(vsp_tree, vsp, entry, vspcmp); 463d4be4cdeSjob 464d4be4cdeSjob /* 4656b83d8e3Sjob * A single BGPsec Router Key (including ASID) 4666b83d8e3Sjob */ 4676b83d8e3Sjob struct brk { 4686b83d8e3Sjob RB_ENTRY(brk) entry; 4696b83d8e3Sjob uint32_t asid; 470dc508150Sclaudio int talid; /* covered by which TAL */ 47117304ed1Sjob char *ski; /* Subject Key Identifier */ 47217304ed1Sjob char *pubkey; /* Subject Public Key Info */ 4736b83d8e3Sjob time_t expires; /* transitive expiry moment */ 4746b83d8e3Sjob }; 4756b83d8e3Sjob /* 4766b83d8e3Sjob * Tree of BRK sorted by asid 4776b83d8e3Sjob */ 4786b83d8e3Sjob RB_HEAD(brk_tree, brk); 4796b83d8e3Sjob RB_PROTOTYPE(brk_tree, brk, entry, brkcmp); 4806b83d8e3Sjob 4816b83d8e3Sjob /* 48251b3988bSbenno * A single CRL 48351b3988bSbenno */ 48451b3988bSbenno struct crl { 48551b3988bSbenno RB_ENTRY(crl) entry; 486e669621fSclaudio char *aki; 487c207abadSjob char *mftpath; 48851b3988bSbenno X509_CRL *x509_crl; 489c527cc7aSjob time_t thisupdate; /* do not use before */ 4909f544822Sjob time_t nextupdate; /* do not use after */ 49151b3988bSbenno }; 49251b3988bSbenno /* 49351b3988bSbenno * Tree of CRLs sorted by uri 49451b3988bSbenno */ 49551b3988bSbenno RB_HEAD(crl_tree, crl); 49651b3988bSbenno 49751b3988bSbenno /* 4989a7e9e7fSjob * An authentication tuple. 4999a7e9e7fSjob * This specifies a public key and a subject key identifier used to 5009a7e9e7fSjob * verify children nodes in the tree of entities. 5019a7e9e7fSjob */ 5029a7e9e7fSjob struct auth { 503a079bbf8Sclaudio RB_ENTRY(auth) entry; 5049a7e9e7fSjob struct cert *cert; /* owner information */ 505335482abStb struct auth *issuer; /* pointer to issuer or NULL for TA cert */ 506967224c8Stb int any_inherits; 5070bc420b9Sclaudio int depth; 5089a7e9e7fSjob }; 509a079bbf8Sclaudio /* 510a079bbf8Sclaudio * Tree of auth sorted by ski 511a079bbf8Sclaudio */ 512a079bbf8Sclaudio RB_HEAD(auth_tree, auth); 513a079bbf8Sclaudio 5140bc420b9Sclaudio struct auth *auth_find(struct auth_tree *, int); 5150bc420b9Sclaudio struct auth *auth_insert(const char *, struct auth_tree *, struct cert *, 5160bc420b9Sclaudio struct auth *); 5179a7e9e7fSjob 51809b708f5Sclaudio enum http_result { 51909b708f5Sclaudio HTTP_FAILED, /* anything else */ 52009b708f5Sclaudio HTTP_OK, /* 200 OK */ 52109b708f5Sclaudio HTTP_NOT_MOD, /* 304 Not Modified */ 52209b708f5Sclaudio }; 52309b708f5Sclaudio 5240ee5ab88Sderaadt /* 5258ecbadc1Sclaudio * Message types for communication with RRDP process. 5268ecbadc1Sclaudio */ 5278ecbadc1Sclaudio enum rrdp_msg { 5288ecbadc1Sclaudio RRDP_START, 5298ecbadc1Sclaudio RRDP_SESSION, 5308ecbadc1Sclaudio RRDP_FILE, 531264f4ef9Sclaudio RRDP_CLEAR, 5328ecbadc1Sclaudio RRDP_END, 5338ecbadc1Sclaudio RRDP_HTTP_REQ, 5348ecbadc1Sclaudio RRDP_HTTP_INI, 535264f4ef9Sclaudio RRDP_HTTP_FIN, 5364673c683Sclaudio RRDP_ABORT, 5378ecbadc1Sclaudio }; 5388ecbadc1Sclaudio 539b268327aSclaudio /* Maximum number of delta files per RRDP notification file. */ 540b268327aSclaudio #define MAX_RRDP_DELTAS 300 541b268327aSclaudio 5428ecbadc1Sclaudio /* 5438ecbadc1Sclaudio * RRDP session state, needed to pickup at the right spot on next run. 5448ecbadc1Sclaudio */ 5458ecbadc1Sclaudio struct rrdp_session { 5468ecbadc1Sclaudio char *last_mod; 5478ecbadc1Sclaudio char *session_id; 5488ecbadc1Sclaudio long long serial; 549b268327aSclaudio char *deltas[MAX_RRDP_DELTAS]; 5508ecbadc1Sclaudio }; 5518ecbadc1Sclaudio 5528ecbadc1Sclaudio /* 5538ecbadc1Sclaudio * File types used in RRDP_FILE messages. 5548ecbadc1Sclaudio */ 5558ecbadc1Sclaudio enum publish_type { 5568ecbadc1Sclaudio PUB_ADD, 5578ecbadc1Sclaudio PUB_UPD, 5588ecbadc1Sclaudio PUB_DEL, 5598ecbadc1Sclaudio }; 5608ecbadc1Sclaudio 5618ecbadc1Sclaudio /* 562eae58378Sclaudio * An entity (MFT, ROA, certificate, etc.) that needs to be downloaded 563eae58378Sclaudio * and parsed. 564eae58378Sclaudio */ 565eae58378Sclaudio struct entity { 56608df5e84Sclaudio TAILQ_ENTRY(entity) entries; 567100ded9eSclaudio char *path; /* path relative to repository */ 5680c3a2335Sclaudio char *file; /* filename or valid repo path */ 56932c8d2feSjob char *mftaki; /* expected AKI (taken from Manifest) */ 57041edc670Sclaudio unsigned char *data; /* optional data blob */ 57141edc670Sclaudio size_t datasz; /* length of optional data blob */ 572100ded9eSclaudio unsigned int repoid; /* repository identifier */ 573dc508150Sclaudio int talid; /* tal identifier */ 5740bc420b9Sclaudio int certid; 57508df5e84Sclaudio enum rtype type; /* type of entity (not RTYPE_EOF) */ 5763a50f0a9Sjmc enum location location; /* which directory the file lives in */ 577eae58378Sclaudio }; 578eae58378Sclaudio TAILQ_HEAD(entityq, entity); 579eae58378Sclaudio 5804f5f25cbSclaudio enum stype { 5814f5f25cbSclaudio STYPE_OK, 5824f5f25cbSclaudio STYPE_FAIL, 5834f5f25cbSclaudio STYPE_INVALID, 5844f5f25cbSclaudio STYPE_BGPSEC, 5854f5f25cbSclaudio STYPE_TOTAL, 5864f5f25cbSclaudio STYPE_UNIQUE, 5874f5f25cbSclaudio STYPE_DEC_UNIQUE, 58874a82ef4Stb STYPE_PROVIDERS, 5897e284d50Stb STYPE_OVERFLOW, 590318f0572Sjob STYPE_SEQNUM_GAP, 5914f5f25cbSclaudio }; 5924f5f25cbSclaudio 5938ecbadc1Sclaudio struct repo; 5948ecbadc1Sclaudio struct filepath; 5958ecbadc1Sclaudio RB_HEAD(filepath_tree, filepath); 5968ecbadc1Sclaudio 5978ecbadc1Sclaudio 598eae58378Sclaudio /* 5990ee5ab88Sderaadt * Statistics collected during run-time. 6000ee5ab88Sderaadt */ 6011fc2657fSclaudio struct repotalstats { 6024f5f25cbSclaudio uint32_t certs; /* certificates */ 6034f5f25cbSclaudio uint32_t certs_fail; /* invalid certificate */ 6044f5f25cbSclaudio uint32_t mfts; /* total number of manifests */ 605318f0572Sjob uint32_t mfts_gap; /* manifests with sequence gaps */ 6064f5f25cbSclaudio uint32_t mfts_fail; /* failing syntactic parse */ 6074f5f25cbSclaudio uint32_t roas; /* route origin authorizations */ 6084f5f25cbSclaudio uint32_t roas_fail; /* failing syntactic parse */ 6094f5f25cbSclaudio uint32_t roas_invalid; /* invalid resources */ 6104f5f25cbSclaudio uint32_t aspas; /* ASPA objects */ 6114f5f25cbSclaudio uint32_t aspas_fail; /* ASPA objects failing syntactic parse */ 6124f5f25cbSclaudio uint32_t aspas_invalid; /* ASPAs with invalid customerASID */ 6134f5f25cbSclaudio uint32_t brks; /* number of BGPsec Router Key (BRK) certs */ 6144f5f25cbSclaudio uint32_t crls; /* revocation lists */ 6154f5f25cbSclaudio uint32_t gbrs; /* ghostbuster records */ 6164f5f25cbSclaudio uint32_t taks; /* signed TAL objects */ 6174f5f25cbSclaudio uint32_t vaps; /* total number of Validated ASPA Payloads */ 6184f5f25cbSclaudio uint32_t vaps_uniqs; /* total number of unique VAPs */ 6194f5f25cbSclaudio uint32_t vaps_pas; /* total number of providers */ 6207e284d50Stb uint32_t vaps_overflowed; /* VAPs with too many providers */ 6214f5f25cbSclaudio uint32_t vrps; /* total number of Validated ROA Payloads */ 6224f5f25cbSclaudio uint32_t vrps_uniqs; /* number of unique vrps */ 623d4be4cdeSjob uint32_t spls; /* signed prefix list */ 624d4be4cdeSjob uint32_t spls_fail; /* failing syntactic parse */ 625c59859a5Stb uint32_t spls_invalid; /* invalid spls */ 626d4be4cdeSjob uint32_t vsps; /* total number of Validated SPL Payloads */ 627d4be4cdeSjob uint32_t vsps_uniqs; /* number of unique vsps */ 6281fc2657fSclaudio }; 6291fc2657fSclaudio 6301fc2657fSclaudio struct repostats { 6311fc2657fSclaudio uint32_t del_files; /* number of files removed in cleanup */ 6321fc2657fSclaudio uint32_t extra_files; /* number of superfluous files */ 6331fc2657fSclaudio uint32_t del_extra_files;/* number of removed extra files */ 6341fc2657fSclaudio uint32_t del_dirs; /* number of dirs removed in cleanup */ 635a5f50487Sjob uint32_t new_files; /* moved from DIR_TEMP to DIR_VALID */ 6364f5f25cbSclaudio struct timespec sync_time; /* time to sync repo */ 6374f5f25cbSclaudio }; 6384f5f25cbSclaudio 6390ee5ab88Sderaadt struct stats { 6404f5f25cbSclaudio uint32_t tals; /* total number of locators */ 6414f5f25cbSclaudio uint32_t repos; /* repositories */ 6424f5f25cbSclaudio uint32_t rsync_repos; /* synced rsync repositories */ 6434f5f25cbSclaudio uint32_t rsync_fails; /* failed rsync repositories */ 6444f5f25cbSclaudio uint32_t http_repos; /* synced http repositories */ 6454f5f25cbSclaudio uint32_t http_fails; /* failed http repositories */ 6464f5f25cbSclaudio uint32_t rrdp_repos; /* synced rrdp repositories */ 6474f5f25cbSclaudio uint32_t rrdp_fails; /* failed rrdp repositories */ 6484f5f25cbSclaudio uint32_t skiplistentries; /* number of skiplist entries */ 6494f5f25cbSclaudio 6501fc2657fSclaudio struct repotalstats repo_tal_stats; 6514f5f25cbSclaudio struct repostats repo_stats; 65265c1ceceSclaudio struct timespec elapsed_time; 65365c1ceceSclaudio struct timespec user_time; 65465c1ceceSclaudio struct timespec system_time; 6550ee5ab88Sderaadt }; 6560ee5ab88Sderaadt 65708db1177Sclaudio struct ibuf; 6582defcb52Sclaudio struct msgbuf; 65908db1177Sclaudio 6608825d988Sclaudio /* global variables */ 6618825d988Sclaudio extern int verbose; 66281a06611Sclaudio extern int noop; 663f43c4d92Sclaudio extern int filemode; 664acb55ac2Sclaudio extern int excludeaspa; 66581a06611Sclaudio extern int experimental; 666bf5a499bSjob extern int excludeas0; 667dc508150Sclaudio extern const char *tals[]; 668dc508150Sclaudio extern const char *taldescs[]; 6697af68c5cSclaudio extern unsigned int talrepocnt[]; 6701fc2657fSclaudio extern struct repotalstats talstats[]; 671389eb209Sclaudio extern int talsz; 6728825d988Sclaudio 6739a7e9e7fSjob /* Routines for RPKI entities. */ 6749a7e9e7fSjob 67508db1177Sclaudio void tal_buffer(struct ibuf *, const struct tal *); 6769a7e9e7fSjob void tal_free(struct tal *); 67741edc670Sclaudio struct tal *tal_parse(const char *, char *, size_t); 6787eb79a4aSclaudio struct tal *tal_read(struct ibuf *); 6799a7e9e7fSjob 68008db1177Sclaudio void cert_buffer(struct ibuf *, const struct cert *); 6819a7e9e7fSjob void cert_free(struct cert *); 68291176c18Sjob void auth_tree_free(struct auth_tree *); 683891d6bceSjob struct cert *cert_parse_ee_cert(const char *, int, X509 *); 684ba153bd8Sclaudio struct cert *cert_parse_pre(const char *, const unsigned char *, size_t); 685ba153bd8Sclaudio struct cert *cert_parse(const char *, struct cert *); 686ba153bd8Sclaudio struct cert *ta_parse(const char *, struct cert *, const unsigned char *, 687ba153bd8Sclaudio size_t); 6887eb79a4aSclaudio struct cert *cert_read(struct ibuf *); 6896b83d8e3Sjob void cert_insert_brks(struct brk_tree *, struct cert *); 6909a7e9e7fSjob 691df512fbcSclaudio enum rtype rtype_from_file_extension(const char *); 69208db1177Sclaudio void mft_buffer(struct ibuf *, const struct mft *); 6939a7e9e7fSjob void mft_free(struct mft *); 6940636c4d0Stb struct mft *mft_parse(X509 **, const char *, int, const unsigned char *, 695cabf3a3bSclaudio size_t); 6967eb79a4aSclaudio struct mft *mft_read(struct ibuf *); 6971039ba60Stb int mft_compare_issued(const struct mft *, const struct mft *); 698e73085f8Stb int mft_compare_seqnum(const struct mft *, const struct mft *); 699318f0572Sjob int mft_seqnum_gap_present(const struct mft *, const struct mft *); 7009a7e9e7fSjob 70108db1177Sclaudio void roa_buffer(struct ibuf *, const struct roa *); 7029a7e9e7fSjob void roa_free(struct roa *); 7030636c4d0Stb struct roa *roa_parse(X509 **, const char *, int, const unsigned char *, 704cabf3a3bSclaudio size_t); 7057eb79a4aSclaudio struct roa *roa_read(struct ibuf *); 7064f5f25cbSclaudio void roa_insert_vrps(struct vrp_tree *, struct roa *, 7074f5f25cbSclaudio struct repo *); 7089a7e9e7fSjob 709d4be4cdeSjob void spl_buffer(struct ibuf *, const struct spl *); 710d4be4cdeSjob void spl_free(struct spl *); 711d4be4cdeSjob struct spl *spl_parse(X509 **, const char *, int, const unsigned char *, 712d4be4cdeSjob size_t); 713d4be4cdeSjob struct spl *spl_read(struct ibuf *); 714d4be4cdeSjob void spl_insert_vsps(struct vsp_tree *, struct spl *, 715d4be4cdeSjob struct repo *); 716d4be4cdeSjob 7174be5941aSclaudio void gbr_free(struct gbr *); 7180636c4d0Stb struct gbr *gbr_parse(X509 **, const char *, int, const unsigned char *, 719cabf3a3bSclaudio size_t); 7204be5941aSclaudio 721ef3f6f56Sjob void geofeed_free(struct geofeed *); 7220636c4d0Stb struct geofeed *geofeed_parse(X509 **, const char *, int, char *, size_t); 723ef3f6f56Sjob 72404834fbdSjob void rsc_free(struct rsc *); 7250636c4d0Stb struct rsc *rsc_parse(X509 **, const char *, int, const unsigned char *, 72604834fbdSjob size_t); 72704834fbdSjob 728ee2a33daSjob void takey_free(struct takey *); 729ee2a33daSjob void tak_free(struct tak *); 7300636c4d0Stb struct tak *tak_parse(X509 **, const char *, int, const unsigned char *, 731ee2a33daSjob size_t); 732ee2a33daSjob 733a29ddfd5Sjob void aspa_buffer(struct ibuf *, const struct aspa *); 734a29ddfd5Sjob void aspa_free(struct aspa *); 735cd55b6bdSjob void aspa_insert_vaps(char *, struct vap_tree *, struct aspa *, 7364f5f25cbSclaudio struct repo *); 7370636c4d0Stb struct aspa *aspa_parse(X509 **, const char *, int, const unsigned char *, 738a29ddfd5Sjob size_t); 739a29ddfd5Sjob struct aspa *aspa_read(struct ibuf *); 740a29ddfd5Sjob 74151b3988bSbenno /* crl.c */ 7424bd8ba3aStb struct crl *crl_parse(const char *, const unsigned char *, size_t); 743c4a9443cSclaudio struct crl *crl_get(struct crl_tree *, const struct auth *); 744c4a9443cSclaudio int crl_insert(struct crl_tree *, struct crl *); 7454bd8ba3aStb void crl_free(struct crl *); 74691176c18Sjob void crl_tree_free(struct crl_tree *); 7479a7e9e7fSjob 7489a7e9e7fSjob /* Validation of our objects. */ 7499a7e9e7fSjob 75024069af1Sclaudio int valid_cert(const char *, struct auth *, const struct cert *); 75199dbdb7fStb int valid_roa(const char *, struct cert *, struct roa *); 75287c7c78dSclaudio int valid_filehash(int, const char *, size_t); 75323bc08f8Sclaudio int valid_hash(unsigned char *, size_t, const char *, size_t); 754203dfefcStb int valid_filename(const char *, size_t); 7558c2eb288Sclaudio int valid_uri(const char *, size_t, const char *); 75693d9375cSclaudio int valid_origin(const char *, const char *); 757c4a9443cSclaudio int valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *, 758fd7a2857Sclaudio struct crl *, const char **); 75999dbdb7fStb int valid_rsc(const char *, struct cert *, struct rsc *); 760e1686bd7Sjob int valid_econtent_version(const char *, const ASN1_INTEGER *, 761e1686bd7Sjob uint64_t); 762a29ddfd5Sjob int valid_aspa(const char *, struct cert *, struct aspa *); 763ef3f6f56Sjob int valid_geofeed(const char *, struct cert *, struct geofeed *); 76445735addSclaudio int valid_uuid(const char *); 765ae36eebeSjob int valid_ca_pkey(const char *, EVP_PKEY *); 766d4be4cdeSjob int valid_spl(const char *, struct cert *, struct spl *); 7679a7e9e7fSjob 76859470c3fSjob /* Working with CMS. */ 7699a7e9e7fSjob unsigned char *cms_parse_validate(X509 **, const char *, 770cabf3a3bSclaudio const unsigned char *, size_t, 7711bb1e509Sjob const ASN1_OBJECT *, size_t *, time_t *); 772ef3f6f56Sjob int cms_parse_validate_detached(X509 **, const char *, 773ef3f6f56Sjob const unsigned char *, size_t, 7741bb1e509Sjob const ASN1_OBJECT *, BIO *, time_t *); 7759a7e9e7fSjob 7769a7e9e7fSjob /* Work with RFC 3779 IP addresses, prefixes, ranges. */ 7779a7e9e7fSjob 7784f1d4333Sbenno int ip_addr_afi_parse(const char *, const ASN1_OCTET_STRING *, 7794f1d4333Sbenno enum afi *); 7809a7e9e7fSjob int ip_addr_parse(const ASN1_BIT_STRING *, 7819a7e9e7fSjob enum afi, const char *, struct ip_addr *); 7824f1d4333Sbenno void ip_addr_print(const struct ip_addr *, enum afi, char *, 7834f1d4333Sbenno size_t); 7849a7e9e7fSjob int ip_addr_check_overlap(const struct cert_ip *, 785891d6bceSjob const char *, const struct cert_ip *, size_t, int); 7869a7e9e7fSjob int ip_addr_check_covered(enum afi, const unsigned char *, 7879a7e9e7fSjob const unsigned char *, const struct cert_ip *, size_t); 7889a7e9e7fSjob int ip_cert_compose_ranges(struct cert_ip *); 7899a7e9e7fSjob void ip_roa_compose_ranges(struct roa_ip *); 7904032f119Stb void ip_warn(const char *, const char *, const struct cert_ip *); 7919a7e9e7fSjob 792565a9191Stb int sbgp_addr(const char *, struct cert_ip *, size_t *, 793565a9191Stb enum afi, const ASN1_BIT_STRING *); 794565a9191Stb int sbgp_addr_range(const char *, struct cert_ip *, size_t *, 795565a9191Stb enum afi, const IPAddressRange *); 796565a9191Stb 79718c42b30Stb int sbgp_parse_ipaddrblk(const char *, const IPAddrBlocks *, 79818c42b30Stb struct cert_ip **, size_t *); 79918c42b30Stb 8009a7e9e7fSjob /* Work with RFC 3779 AS numbers, ranges. */ 8019a7e9e7fSjob 8029a7e9e7fSjob int as_id_parse(const ASN1_INTEGER *, uint32_t *); 8039a7e9e7fSjob int as_check_overlap(const struct cert_as *, const char *, 804891d6bceSjob const struct cert_as *, size_t, int); 8059a7e9e7fSjob int as_check_covered(uint32_t, uint32_t, 8069a7e9e7fSjob const struct cert_as *, size_t); 8074032f119Stb void as_warn(const char *, const char *, const struct cert_as *); 8089a7e9e7fSjob 809565a9191Stb int sbgp_as_id(const char *, struct cert_as *, size_t *, 810565a9191Stb const ASN1_INTEGER *); 811565a9191Stb int sbgp_as_range(const char *, struct cert_as *, size_t *, 812565a9191Stb const ASRange *); 813565a9191Stb 81418c42b30Stb int sbgp_parse_assysnum(const char *, const ASIdentifiers *, 81518c42b30Stb struct cert_as **, size_t *); 81618c42b30Stb 817891d6bceSjob /* Constraints-specific */ 818891d6bceSjob void constraints_load(void); 819891d6bceSjob void constraints_unload(void); 820891d6bceSjob void constraints_parse(void); 821891d6bceSjob int constraints_validate(const char *, const struct cert *); 822891d6bceSjob 823eae58378Sclaudio /* Parser-specific */ 824eae58378Sclaudio void entity_free(struct entity *); 8257eb79a4aSclaudio void entity_read_req(struct ibuf *, struct entity *); 8268ecbadc1Sclaudio void entityq_flush(struct entityq *, struct repo *); 827eae58378Sclaudio void proc_parser(int) __attribute__((noreturn)); 828c4a9443cSclaudio void proc_filemode(int) __attribute__((noreturn)); 829eae58378Sclaudio 8309a7e9e7fSjob /* Rsync-specific. */ 8319a7e9e7fSjob 832402543e6Sclaudio char *rsync_base_uri(const char *); 833cfc09c7bSclaudio void proc_rsync(char *, char *, int) __attribute__((noreturn)); 8349a7e9e7fSjob 8358ecbadc1Sclaudio /* HTTP and RRDP processes. */ 8361ef5b48aSclaudio 837c4a9443cSclaudio void proc_http(char *, int) __attribute__((noreturn)); 838c4a9443cSclaudio void proc_rrdp(int) __attribute__((noreturn)); 8398ecbadc1Sclaudio 8408ecbadc1Sclaudio /* Repository handling */ 84192360713Sclaudio int filepath_add(struct filepath_tree *, char *, int, time_t, int); 84292360713Sclaudio int filepath_valid(struct filepath_tree *, char *, int); 843264f4ef9Sclaudio void rrdp_clear(unsigned int); 844b268327aSclaudio void rrdp_session_save(unsigned int, struct rrdp_session *); 845b268327aSclaudio void rrdp_session_free(struct rrdp_session *); 846b268327aSclaudio void rrdp_session_buffer(struct ibuf *, 847b268327aSclaudio const struct rrdp_session *); 848b268327aSclaudio struct rrdp_session *rrdp_session_read(struct ibuf *); 849b6884e9fSclaudio int rrdp_handle_file(unsigned int, enum publish_type, char *, 8508ecbadc1Sclaudio char *, size_t, char *, size_t); 8510c3a2335Sclaudio char *repo_basedir(const struct repo *, int); 852100ded9eSclaudio unsigned int repo_id(const struct repo *); 853100ded9eSclaudio const char *repo_uri(const struct repo *); 8544f5f25cbSclaudio void repo_fetch_uris(const struct repo *, const char **, 8554f5f25cbSclaudio const char **); 8564f5f25cbSclaudio int repo_synced(const struct repo *); 857d0837792Sclaudio const char *repo_proto(const struct repo *); 8584f5f25cbSclaudio int repo_talid(const struct repo *); 8597af68c5cSclaudio struct repo *ta_lookup(int, struct tal *); 8607af68c5cSclaudio struct repo *repo_lookup(int, const char *, const char *); 861100ded9eSclaudio struct repo *repo_byid(unsigned int); 8628ecbadc1Sclaudio int repo_queued(struct repo *, struct entity *); 8636cf9bac2Sclaudio void repo_cleanup(struct filepath_tree *, int); 8644f5f25cbSclaudio int repo_check_timeout(int); 865a5f50487Sjob void repostats_new_files_inc(struct repo *, const char *); 8661fc2657fSclaudio void repo_stat_inc(struct repo *, int, enum rtype, enum stype); 8671fc2657fSclaudio void repo_tal_stats_collect(void (*)(const struct repo *, 8681fc2657fSclaudio const struct repotalstats *, void *), int, void *); 8694f5f25cbSclaudio void repo_stats_collect(void (*)(const struct repo *, 8704f5f25cbSclaudio const struct repostats *, void *), void *); 8718ecbadc1Sclaudio void repo_free(void); 8728ecbadc1Sclaudio 873b6884e9fSclaudio void rsync_finish(unsigned int, int); 874b6884e9fSclaudio void http_finish(unsigned int, enum http_result, const char *); 875b6884e9fSclaudio void rrdp_finish(unsigned int, int); 8768ecbadc1Sclaudio 8770c3a2335Sclaudio void rsync_fetch(unsigned int, const char *, const char *, 8780c3a2335Sclaudio const char *); 8790cda9bffSclaudio void rsync_abort(unsigned int); 880b6884e9fSclaudio void http_fetch(unsigned int, const char *, const char *, int); 881b6884e9fSclaudio void rrdp_fetch(unsigned int, const char *, const char *, 8828ecbadc1Sclaudio struct rrdp_session *); 8830cda9bffSclaudio void rrdp_abort(unsigned int); 884b6884e9fSclaudio void rrdp_http_done(unsigned int, enum http_result, const char *); 8851ef5b48aSclaudio 886087c4643Sclaudio /* Encoding functions for hex and base64. */ 887087c4643Sclaudio 8882cfd2d3bSclaudio unsigned char *load_file(const char *, size_t *); 8891aea4e0eSclaudio int base64_decode_len(size_t, size_t *); 89041edc670Sclaudio int base64_decode(const unsigned char *, size_t, 89141edc670Sclaudio unsigned char **, size_t *); 8921aea4e0eSclaudio int base64_encode_len(size_t, size_t *); 8936f704872Sclaudio int base64_encode(const unsigned char *, size_t, char **); 894087c4643Sclaudio char *hex_encode(const unsigned char *, size_t); 895aef00ae0Sclaudio int hex_decode(const char *, char *, size_t); 896087c4643Sclaudio 897087c4643Sclaudio 8989a7e9e7fSjob /* Functions for moving data between processes. */ 8999a7e9e7fSjob 90025f7afeeSclaudio struct ibuf *io_new_buffer(void); 90108db1177Sclaudio void io_simple_buffer(struct ibuf *, const void *, size_t); 90208db1177Sclaudio void io_buf_buffer(struct ibuf *, const void *, size_t); 90308db1177Sclaudio void io_str_buffer(struct ibuf *, const char *); 90425f7afeeSclaudio void io_close_buffer(struct msgbuf *, struct ibuf *); 9057eb79a4aSclaudio void io_read_buf(struct ibuf *, void *, size_t); 9067eb79a4aSclaudio void io_read_str(struct ibuf *, char **); 9077eb79a4aSclaudio void io_read_buf_alloc(struct ibuf *, void **, size_t *); 908929d2bb2Sclaudio struct ibuf *io_parse_hdr(struct ibuf *, void *, int *); 909b5fa5d51Sclaudio struct ibuf *io_buf_get(struct msgbuf *); 9109a7e9e7fSjob 9119a7e9e7fSjob /* X509 helpers. */ 9129a7e9e7fSjob 913de9b6f5dSclaudio void x509_init_oid(void); 914e891962dStb int x509_cache_extensions(X509 *, const char *); 915f999fe57Sclaudio int x509_get_aia(X509 *, const char *, char **); 916f999fe57Sclaudio int x509_get_aki(X509 *, const char *, char **); 9172cf0e122Sjob int x509_get_sia(X509 *, const char *, char **); 918f999fe57Sclaudio int x509_get_ski(X509 *, const char *, char **); 919f5999ddfSjob int x509_get_notbefore(X509 *, const char *, time_t *); 9209f544822Sjob int x509_get_notafter(X509 *, const char *, time_t *); 921f999fe57Sclaudio int x509_get_crl(X509 *, const char *, char **); 92217304ed1Sjob char *x509_get_pubkey(X509 *, const char *); 92323c6f3a2Stb char *x509_pubkey_get_ski(X509_PUBKEY *, const char *); 924fdfddccfSjob enum cert_purpose x509_get_purpose(X509 *, const char *); 925220c707cSclaudio int x509_get_time(const ASN1_TIME *, time_t *); 926904d9c60Stb char *x509_convert_seqnum(const char *, const char *, 927904d9c60Stb const ASN1_INTEGER *); 928904d9c60Stb int x509_valid_seqnum(const char *, const char *, 929904d9c60Stb const ASN1_INTEGER *); 9302b872fe6Stb int x509_location(const char *, const char *, GENERAL_NAME *, 9312b872fe6Stb char **); 9323a363cbdSjob int x509_inherits(X509 *); 933c9e39c95Sjob int x509_any_inherits(X509 *); 9340466b83fStb int x509_valid_name(const char *, const char *, const X509_NAME *); 935534b6674Sjob time_t x509_find_expires(time_t, struct auth *, struct crl_tree *); 9369a7e9e7fSjob 937714f4e3fSclaudio /* printers */ 93878de3577Stb char *nid2str(int); 9393e8d4b7dStb const char *purpose2str(enum cert_purpose); 940220c707cSclaudio char *time2str(time_t); 941530399e8Sjob void x509_print(const X509 *); 942714f4e3fSclaudio void tal_print(const struct tal *); 943714f4e3fSclaudio void cert_print(const struct cert *); 944220c707cSclaudio void crl_print(const struct crl *); 945530399e8Sjob void mft_print(const X509 *, const struct mft *); 946530399e8Sjob void roa_print(const X509 *, const struct roa *); 947530399e8Sjob void gbr_print(const X509 *, const struct gbr *); 94804834fbdSjob void rsc_print(const X509 *, const struct rsc *); 949a29ddfd5Sjob void aspa_print(const X509 *, const struct aspa *); 950ee2a33daSjob void tak_print(const X509 *, const struct tak *); 951ef3f6f56Sjob void geofeed_print(const X509 *, const struct geofeed *); 952d4be4cdeSjob void spl_print(const X509 *, const struct spl *); 953714f4e3fSclaudio 954891d6bceSjob /* Missing RFC 3779 API */ 955891d6bceSjob IPAddrBlocks *IPAddrBlocks_new(void); 956891d6bceSjob void IPAddrBlocks_free(IPAddrBlocks *); 957891d6bceSjob 9589a7e9e7fSjob /* Output! */ 9599a7e9e7fSjob 9601f9a8b94Sderaadt extern int outformats; 9611f9a8b94Sderaadt #define FORMAT_OPENBGPD 0x01 9621f9a8b94Sderaadt #define FORMAT_BIRD 0x02 9631f9a8b94Sderaadt #define FORMAT_CSV 0x04 9641f9a8b94Sderaadt #define FORMAT_JSON 0x08 9654f5f25cbSclaudio #define FORMAT_OMETRIC 0x10 9661f9a8b94Sderaadt 9676b83d8e3Sjob int outputfiles(struct vrp_tree *v, struct brk_tree *b, 968d4be4cdeSjob struct vap_tree *, struct vsp_tree *, struct stats *); 9690ee5ab88Sderaadt int outputheader(FILE *, struct stats *); 9706b83d8e3Sjob int output_bgpd(FILE *, struct vrp_tree *, struct brk_tree *, 971d4be4cdeSjob struct vap_tree *, struct vsp_tree *, struct stats *); 972*29bf64caSjob int output_bird(FILE *, struct vrp_tree *, struct brk_tree *, 973a3ccbae7Sjob struct vap_tree *, struct vsp_tree *, struct stats *); 9746b83d8e3Sjob int output_csv(FILE *, struct vrp_tree *, struct brk_tree *, 975d4be4cdeSjob struct vap_tree *, struct vsp_tree *, struct stats *); 9766b83d8e3Sjob int output_json(FILE *, struct vrp_tree *, struct brk_tree *, 977d4be4cdeSjob struct vap_tree *, struct vsp_tree *, struct stats *); 9784f5f25cbSclaudio int output_ometric(FILE *, struct vrp_tree *, struct brk_tree *, 979d4be4cdeSjob struct vap_tree *, struct vsp_tree *, struct stats *); 9801f9a8b94Sderaadt 9811f9a8b94Sderaadt void logx(const char *fmt, ...) 9821f9a8b94Sderaadt __attribute__((format(printf, 1, 2))); 9832cc3b5f1Sclaudio time_t getmonotime(void); 984d3c630adStb time_t get_current_time(void); 9859a7e9e7fSjob 986809b75d3Sclaudio int mkpath(const char *); 9876cf9bac2Sclaudio int mkpathat(int, const char *); 98861aab7a0Sclaudio 9895b613a61Sclaudio #define RPKI_PATH_OUT_DIR "/var/db/rpki-client" 9905b613a61Sclaudio #define RPKI_PATH_BASE_DIR "/var/cache/rpki-client" 99143dfc6a8Sderaadt 9925a2857b6Sjob #define DEFAULT_SKIPLIST_FILE "/etc/rpki/skiplist" 9935a2857b6Sjob 994d0a27ef8Sjob /* Interval in which random reinitialization to an RRDP snapshot happens. */ 995d0a27ef8Sjob #define RRDP_RANDOM_REINIT_MAX 12 /* weeks */ 996d0a27ef8Sjob 997ba153bd8Sclaudio /* Maximum number of TAL files we'll load. */ 998ba153bd8Sclaudio #define TALSZ_MAX 8 9990bc420b9Sclaudio #define CERTID_MAX 1000000 1000ba153bd8Sclaudio 10018cae3ce1Sjob /* 10028cae3ce1Sjob * Maximum number of elements in the sbgp-ipAddrBlock (IP) and 10038cae3ce1Sjob * sbgp-autonomousSysNum (AS) X.509v3 extension of CA/EE certificates. 10048cae3ce1Sjob */ 10051c699626Sbeck #define MAX_IP_SIZE 200000 10061c699626Sbeck #define MAX_AS_SIZE 200000 10071c699626Sbeck 100886832a4cSclaudio /* Maximum acceptable URI length */ 10091c699626Sbeck #define MAX_URI_LENGTH 2048 10101c699626Sbeck 1011aed5e91bSjob /* Min/Max acceptable file size */ 1012aed5e91bSjob #define MIN_FILE_SIZE 100 10132b6cb12dSjob #define MAX_FILE_SIZE 8000000 10141c699626Sbeck 1015c8913742Stb /* Maximum number of FileNameAndHash entries per RSC checklist. */ 1016c8913742Stb #define MAX_CHECKLIST_ENTRIES 100000 1017c8913742Stb 101886832a4cSclaudio /* Maximum number of FileAndHash entries per manifest. */ 1019ac69bfd2Sjob #define MAX_MANIFEST_ENTRIES 100000 1020ac69bfd2Sjob 1021a29ddfd5Sjob /* Maximum number of Providers per ASPA object. */ 1022a29ddfd5Sjob #define MAX_ASPA_PROVIDERS 10000 1023a29ddfd5Sjob 102486832a4cSclaudio /* Maximum depth of the RPKI tree. */ 102586832a4cSclaudio #define MAX_CERT_DEPTH 12 102686832a4cSclaudio 10276e7e5289Sclaudio /* Maximum number of concurrent http and rsync requests. */ 10286e7e5289Sclaudio #define MAX_HTTP_REQUESTS 64 10296e7e5289Sclaudio #define MAX_RSYNC_REQUESTS 16 103036dac55eSclaudio 1031fcf9359dSjob /* How many seconds to wait for a connection to succeed. */ 10329170c2daSclaudio #define MAX_CONN_TIMEOUT 15 1033fcf9359dSjob 10348cae3ce1Sjob /* How many seconds to wait for IO from a remote server. */ 1035194059d2Sjob #define MAX_IO_TIMEOUT 30 10362778dc25Sjob 10378cae3ce1Sjob /* Maximum number of delegated hosting locations (repositories) for each TAL. */ 10387af68c5cSclaudio #define MAX_REPO_PER_TAL 1000 10397af68c5cSclaudio 10400610060dSjob #define HTTP_PROTO "http://" 10410610060dSjob #define HTTP_PROTO_LEN (sizeof(HTTP_PROTO) - 1) 10420610060dSjob #define HTTPS_PROTO "https://" 10430610060dSjob #define HTTPS_PROTO_LEN (sizeof(HTTPS_PROTO) - 1) 10440610060dSjob #define RSYNC_PROTO "rsync://" 10450610060dSjob #define RSYNC_PROTO_LEN (sizeof(RSYNC_PROTO) - 1) 10460610060dSjob 10479a7e9e7fSjob #endif /* ! EXTERN_H */ 1048