xref: /openbsd-src/usr.sbin/rpki-client/extern.h (revision 29bf64ca9b984c45cb3416a0bc49cef8859122f1)
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