]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
draft-ietf-sidrops-rpki-rsc-03: First implementation prototype draft-ietf-sidrops-rpki-rsc
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Mon, 31 May 2021 18:58:54 +0000 (13:58 -0500)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Mon, 31 May 2021 19:23:57 +0000 (14:23 -0500)
It does pretty much everything, but the CA lookup is very dumb.
It performs a full tree traversal.

Also, it's not documented yet.

Recommended usage:

fort --tal tal/ripe-ncc.tal \
--local-repository /path/to/cache \
--rsc /path/to/checklist.sig

Awaiting feedback.

43 files changed:
src/Makefile.am
src/asn1/asn1c/AsList.c [new file with mode: 0644]
src/asn1/asn1c/AsList.h [new file with mode: 0644]
src/asn1/asn1c/FileNameAndHash.c [new file with mode: 0644]
src/asn1/asn1c/FileNameAndHash.h [new file with mode: 0644]
src/asn1/asn1c/IPAddressFamilyItem.c [new file with mode: 0644]
src/asn1/asn1c/IPAddressFamilyItem.h [new file with mode: 0644]
src/asn1/asn1c/IPList.c [new file with mode: 0644]
src/asn1/asn1c/IPList.h [new file with mode: 0644]
src/asn1/asn1c/Makefile.include
src/asn1/asn1c/ResourceBlock.c [new file with mode: 0644]
src/asn1/asn1c/ResourceBlock.h [new file with mode: 0644]
src/asn1/asn1c/RpkiSignedChecklist.c [new file with mode: 0644]
src/asn1/asn1c/RpkiSignedChecklist.h [new file with mode: 0644]
src/asn1/content_info.c
src/asn1/content_info.h
src/asn1/oid.h
src/asn1/signed_data.c
src/asn1/signed_data.h
src/certificate_refs.c
src/certificate_refs.h
src/config.c
src/config.h
src/object/certificate.c
src/object/certificate.h
src/object/crl.c
src/object/ghostbusters.c
src/object/manifest.c
src/object/name.c
src/object/roa.c
src/object/rsc.c [new file with mode: 0644]
src/object/rsc.h [new file with mode: 0644]
src/object/signed_object.c
src/object/signed_object.h
src/object/tal.c
src/resource.c
src/resource.h
src/rpp.c
src/state.c
src/state.h
src/uri.c
src/uri.h
src/visited_uris.c

index ef6dfa1fa039d55ee7145e48a5a5c7055ca85fa9..95f08e3cd0dbdeb78f874e1ec971a819870f0d7a 100644 (file)
@@ -81,6 +81,7 @@ fort_SOURCES += object/manifest.h object/manifest.c
 fort_SOURCES += object/name.h object/name.c
 fort_SOURCES += object/roa.h object/roa.c
 fort_SOURCES += object/router_key.c object/router_key.h
+fort_SOURCES += object/rsc.h object/rsc.c
 fort_SOURCES += object/signed_object.h object/signed_object.c
 fort_SOURCES += object/tal.h object/tal.c
 fort_SOURCES += object/vcard.h object/vcard.c
diff --git a/src/asn1/asn1c/AsList.c b/src/asn1/asn1c/AsList.c
new file mode 100644 (file)
index 0000000..14ce8fd
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#include "AsList.h"
+
+static asn_oer_constraints_t asn_OER_type_AsList_constr_1 CC_NOTUSED = {
+       { 0, 0 },
+       -1      /* (SIZE(1..MAX)) */};
+asn_TYPE_member_t asn_MBR_AsList_1[] = {
+       { ATF_POINTER, 0, 0,
+               -1 /* Ambiguous tag (CHOICE?) */,
+               0,
+               &asn_DEF_ASIdOrRange,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               ""
+               },
+};
+static const ber_tlv_tag_t asn_DEF_AsList_tags_1[] = {
+       (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+asn_SET_OF_specifics_t asn_SPC_AsList_specs_1 = {
+       sizeof(struct AsList),
+       offsetof(struct AsList, _asn_ctx),
+       2,      /* XER encoding is XMLValueList */
+};
+asn_TYPE_descriptor_t asn_DEF_AsList = {
+       "AsList",
+       "AsList",
+       &asn_OP_SEQUENCE_OF,
+       asn_DEF_AsList_tags_1,
+       sizeof(asn_DEF_AsList_tags_1)
+               /sizeof(asn_DEF_AsList_tags_1[0]), /* 1 */
+       asn_DEF_AsList_tags_1,  /* Same as above */
+       sizeof(asn_DEF_AsList_tags_1)
+               /sizeof(asn_DEF_AsList_tags_1[0]), /* 1 */
+       { &asn_OER_type_AsList_constr_1, 0, SEQUENCE_OF_constraint },
+       asn_MBR_AsList_1,
+       1,      /* Single element */
+       &asn_SPC_AsList_specs_1 /* Additional specs */
+};
+
diff --git a/src/asn1/asn1c/AsList.h b/src/asn1/asn1c/AsList.h
new file mode 100644 (file)
index 0000000..eebbbe8
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#ifndef        _AsList_H_
+#define        _AsList_H_
+
+
+#include "asn1/asn1c/asn_application.h"
+
+/* Including external dependencies */
+#include "asn1/asn1c/asn_SEQUENCE_OF.h"
+#include "asn1/asn1c/constr_SEQUENCE_OF.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+struct ASIdOrRange;
+
+/* AsList */
+typedef struct AsList {
+       A_SEQUENCE_OF(struct ASIdOrRange) list;
+       
+       /* Context for parsing across buffer boundaries */
+       asn_struct_ctx_t _asn_ctx;
+} AsList_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_AsList;
+extern asn_SET_OF_specifics_t asn_SPC_AsList_specs_1;
+extern asn_TYPE_member_t asn_MBR_AsList_1[1];
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Referred external types */
+#include "ASIdOrRange.h"
+
+#endif /* _AsList_H_ */
+#include "asn1/asn1c/asn_internal.h"
diff --git a/src/asn1/asn1c/FileNameAndHash.c b/src/asn1/asn1c/FileNameAndHash.c
new file mode 100644 (file)
index 0000000..e528299
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#include "FileNameAndHash.h"
+
+asn_TYPE_member_t asn_MBR_FileNameAndHash_1[] = {
+       { ATF_POINTER, 1, offsetof(struct FileNameAndHash, fileName),
+               (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)),
+               0,
+               &asn_DEF_IA5String,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               "fileName"
+               },
+       { ATF_NOFLAGS, 0, offsetof(struct FileNameAndHash, hash),
+               (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+               0,
+               &asn_DEF_OCTET_STRING,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               "hash"
+               },
+};
+static const int asn_MAP_FileNameAndHash_oms_1[] = { 0 };
+static const ber_tlv_tag_t asn_DEF_FileNameAndHash_tags_1[] = {
+       (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_FileNameAndHash_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* hash */
+    { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)), 0, 0, 0 } /* fileName */
+};
+asn_SEQUENCE_specifics_t asn_SPC_FileNameAndHash_specs_1 = {
+       sizeof(struct FileNameAndHash),
+       offsetof(struct FileNameAndHash, _asn_ctx),
+       asn_MAP_FileNameAndHash_tag2el_1,
+       2,      /* Count of tags in the map */
+       asn_MAP_FileNameAndHash_oms_1,  /* Optional members */
+       1, 0,   /* Root/Additions */
+       -1,     /* First extension addition */
+};
+asn_TYPE_descriptor_t asn_DEF_FileNameAndHash = {
+       "FileNameAndHash",
+       "FileNameAndHash",
+       &asn_OP_SEQUENCE,
+       asn_DEF_FileNameAndHash_tags_1,
+       sizeof(asn_DEF_FileNameAndHash_tags_1)
+               /sizeof(asn_DEF_FileNameAndHash_tags_1[0]), /* 1 */
+       asn_DEF_FileNameAndHash_tags_1, /* Same as above */
+       sizeof(asn_DEF_FileNameAndHash_tags_1)
+               /sizeof(asn_DEF_FileNameAndHash_tags_1[0]), /* 1 */
+       { 0, 0, SEQUENCE_constraint },
+       asn_MBR_FileNameAndHash_1,
+       2,      /* Elements count */
+       &asn_SPC_FileNameAndHash_specs_1        /* Additional specs */
+};
+
diff --git a/src/asn1/asn1c/FileNameAndHash.h b/src/asn1/asn1c/FileNameAndHash.h
new file mode 100644 (file)
index 0000000..ffb70c3
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#ifndef        _FileNameAndHash_H_
+#define        _FileNameAndHash_H_
+
+
+#include "asn1/asn1c/asn_application.h"
+
+/* Including external dependencies */
+#include "asn1/asn1c/IA5String.h"
+#include "asn1/asn1c/OCTET_STRING.h"
+#include "asn1/asn1c/constr_SEQUENCE.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* FileNameAndHash */
+typedef struct FileNameAndHash {
+       IA5String_t     *fileName       /* OPTIONAL */;
+       OCTET_STRING_t   hash;
+       
+       /* Context for parsing across buffer boundaries */
+       asn_struct_ctx_t _asn_ctx;
+} FileNameAndHash_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_FileNameAndHash;
+extern asn_SEQUENCE_specifics_t asn_SPC_FileNameAndHash_specs_1;
+extern asn_TYPE_member_t asn_MBR_FileNameAndHash_1[2];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FileNameAndHash_H_ */
+#include "asn1/asn1c/asn_internal.h"
diff --git a/src/asn1/asn1c/IPAddressFamilyItem.c b/src/asn1/asn1c/IPAddressFamilyItem.c
new file mode 100644 (file)
index 0000000..1e7dc48
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#include "IPAddressFamilyItem.h"
+
+static int
+memb_addressFamily_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr,
+                       asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+       const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+       size_t size;
+       
+       if(!sptr) {
+               ASN__CTFAIL(app_key, td, sptr,
+                       "%s: value not given (%s:%d)",
+                       td->name, __FILE__, __LINE__);
+               return -1;
+       }
+       
+       size = st->size;
+       
+       if((size >= 2 && size <= 3)) {
+               /* Constraint check succeeded */
+               return 0;
+       } else {
+               ASN__CTFAIL(app_key, td, sptr,
+                       "%s: constraint failed (%s:%d)",
+                       td->name, __FILE__, __LINE__);
+               return -1;
+       }
+}
+
+static asn_oer_constraints_t asn_OER_memb_addressFamily_constr_2 CC_NOTUSED = {
+       { 0, 0 },
+       -1      /* (SIZE(2..3)) */};
+asn_TYPE_member_t asn_MBR_IPAddressFamilyItem_1[] = {
+       { ATF_NOFLAGS, 0, offsetof(struct IPAddressFamilyItem, addressFamily),
+               (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+               0,
+               &asn_DEF_OCTET_STRING,
+               0,
+               { &asn_OER_memb_addressFamily_constr_2, 0,  memb_addressFamily_constraint_1 },
+               0, 0, /* No default value */
+               "addressFamily"
+               },
+       { ATF_NOFLAGS, 0, offsetof(struct IPAddressFamilyItem, iPAddressOrRange),
+               -1 /* Ambiguous tag (CHOICE?) */,
+               0,
+               &asn_DEF_IPAddressOrRange,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               "iPAddressOrRange"
+               },
+};
+static const ber_tlv_tag_t asn_DEF_IPAddressFamilyItem_tags_1[] = {
+       (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_IPAddressFamilyItem_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)), 1, 0, 0 }, /* addressPrefix */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, 0, 0 }, /* addressFamily */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 } /* addressRange */
+};
+asn_SEQUENCE_specifics_t asn_SPC_IPAddressFamilyItem_specs_1 = {
+       sizeof(struct IPAddressFamilyItem),
+       offsetof(struct IPAddressFamilyItem, _asn_ctx),
+       asn_MAP_IPAddressFamilyItem_tag2el_1,
+       3,      /* Count of tags in the map */
+       0, 0, 0,        /* Optional elements (not needed) */
+       -1,     /* First extension addition */
+};
+asn_TYPE_descriptor_t asn_DEF_IPAddressFamilyItem = {
+       "IPAddressFamilyItem",
+       "IPAddressFamilyItem",
+       &asn_OP_SEQUENCE,
+       asn_DEF_IPAddressFamilyItem_tags_1,
+       sizeof(asn_DEF_IPAddressFamilyItem_tags_1)
+               /sizeof(asn_DEF_IPAddressFamilyItem_tags_1[0]), /* 1 */
+       asn_DEF_IPAddressFamilyItem_tags_1,     /* Same as above */
+       sizeof(asn_DEF_IPAddressFamilyItem_tags_1)
+               /sizeof(asn_DEF_IPAddressFamilyItem_tags_1[0]), /* 1 */
+       { 0, 0, SEQUENCE_constraint },
+       asn_MBR_IPAddressFamilyItem_1,
+       2,      /* Elements count */
+       &asn_SPC_IPAddressFamilyItem_specs_1    /* Additional specs */
+};
+
diff --git a/src/asn1/asn1c/IPAddressFamilyItem.h b/src/asn1/asn1c/IPAddressFamilyItem.h
new file mode 100644 (file)
index 0000000..3260ab2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#ifndef        _IPAddressFamilyItem_H_
+#define        _IPAddressFamilyItem_H_
+
+
+#include "asn1/asn1c/asn_application.h"
+
+/* Including external dependencies */
+#include "asn1/asn1c/OCTET_STRING.h"
+#include "IPAddressOrRange.h"
+#include "asn1/asn1c/constr_SEQUENCE.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IPAddressFamilyItem */
+typedef struct IPAddressFamilyItem {
+       OCTET_STRING_t   addressFamily;
+       IPAddressOrRange_t       iPAddressOrRange;
+       
+       /* Context for parsing across buffer boundaries */
+       asn_struct_ctx_t _asn_ctx;
+} IPAddressFamilyItem_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_IPAddressFamilyItem;
+extern asn_SEQUENCE_specifics_t asn_SPC_IPAddressFamilyItem_specs_1;
+extern asn_TYPE_member_t asn_MBR_IPAddressFamilyItem_1[2];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IPAddressFamilyItem_H_ */
+#include "asn1/asn1c/asn_internal.h"
diff --git a/src/asn1/asn1c/IPList.c b/src/asn1/asn1c/IPList.c
new file mode 100644 (file)
index 0000000..2904bdd
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#include "IPList.h"
+
+static asn_oer_constraints_t asn_OER_type_IPList_constr_1 CC_NOTUSED = {
+       { 0, 0 },
+       -1      /* (SIZE(1..MAX)) */};
+asn_TYPE_member_t asn_MBR_IPList_1[] = {
+       { ATF_POINTER, 0, 0,
+               (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+               0,
+               &asn_DEF_IPAddressFamilyItem,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               ""
+               },
+};
+static const ber_tlv_tag_t asn_DEF_IPList_tags_1[] = {
+       (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+asn_SET_OF_specifics_t asn_SPC_IPList_specs_1 = {
+       sizeof(struct IPList),
+       offsetof(struct IPList, _asn_ctx),
+       0,      /* XER encoding is XMLDelimitedItemList */
+};
+asn_TYPE_descriptor_t asn_DEF_IPList = {
+       "IPList",
+       "IPList",
+       &asn_OP_SEQUENCE_OF,
+       asn_DEF_IPList_tags_1,
+       sizeof(asn_DEF_IPList_tags_1)
+               /sizeof(asn_DEF_IPList_tags_1[0]), /* 1 */
+       asn_DEF_IPList_tags_1,  /* Same as above */
+       sizeof(asn_DEF_IPList_tags_1)
+               /sizeof(asn_DEF_IPList_tags_1[0]), /* 1 */
+       { &asn_OER_type_IPList_constr_1, 0, SEQUENCE_OF_constraint },
+       asn_MBR_IPList_1,
+       1,      /* Single element */
+       &asn_SPC_IPList_specs_1 /* Additional specs */
+};
+
diff --git a/src/asn1/asn1c/IPList.h b/src/asn1/asn1c/IPList.h
new file mode 100644 (file)
index 0000000..21cbde9
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#ifndef        _IPList_H_
+#define        _IPList_H_
+
+
+#include "asn1/asn1c/asn_application.h"
+
+/* Including external dependencies */
+#include "asn1/asn1c/asn_SEQUENCE_OF.h"
+#include "asn1/asn1c/constr_SEQUENCE_OF.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+struct IPAddressFamilyItem;
+
+/* IPList */
+typedef struct IPList {
+       A_SEQUENCE_OF(struct IPAddressFamilyItem) list;
+       
+       /* Context for parsing across buffer boundaries */
+       asn_struct_ctx_t _asn_ctx;
+} IPList_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_IPList;
+extern asn_SET_OF_specifics_t asn_SPC_IPList_specs_1;
+extern asn_TYPE_member_t asn_MBR_IPList_1[1];
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Referred external types */
+#include "IPAddressFamilyItem.h"
+
+#endif /* _IPList_H_ */
+#include "asn1/asn1c/asn_internal.h"
index 9d606b594d6bb9959cad8b1f0c0aa3f0c7868e43..d51eaf42972ce8d896acce063ac6d5cfd498e835 100644 (file)
@@ -1,4 +1,10 @@
 ASN_MODULE_SRCS=       \
+       asn1/asn1c/RpkiSignedChecklist.c        \
+       asn1/asn1c/FileNameAndHash.c    \
+       asn1/asn1c/ResourceBlock.c      \
+       asn1/asn1c/AsList.c     \
+       asn1/asn1c/IPList.c     \
+       asn1/asn1c/IPAddressFamilyItem.c        \
        asn1/asn1c/IPAddrBlocks.c       \
        asn1/asn1c/IPAddressFamily.c    \
        asn1/asn1c/IPAddressChoice.c    \
@@ -63,6 +69,12 @@ ASN_MODULE_SRCS=     \
        asn1/asn1c/BinaryTime.c
 
 ASN_MODULE_HDRS=       \
+       asn1/asn1c/RpkiSignedChecklist.h        \
+       asn1/asn1c/FileNameAndHash.h    \
+       asn1/asn1c/ResourceBlock.h      \
+       asn1/asn1c/AsList.h     \
+       asn1/asn1c/IPList.h     \
+       asn1/asn1c/IPAddressFamilyItem.h        \
        asn1/asn1c/IPAddrBlocks.h       \
        asn1/asn1c/IPAddressFamily.h    \
        asn1/asn1c/IPAddressChoice.h    \
diff --git a/src/asn1/asn1c/ResourceBlock.c b/src/asn1/asn1c/ResourceBlock.c
new file mode 100644 (file)
index 0000000..12b5b2f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#include "ResourceBlock.h"
+
+static asn_oer_constraints_t asn_OER_type_ResourceBlock_constr_1 CC_NOTUSED = {
+       { 0, 0 },
+       -1};
+asn_TYPE_member_t asn_MBR_ResourceBlock_1[] = {
+       { ATF_POINTER, 2, offsetof(struct ResourceBlock, asID),
+               (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+               +1,     /* EXPLICIT tag at current level */
+               &asn_DEF_AsList,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               "asID"
+               },
+       { ATF_POINTER, 1, offsetof(struct ResourceBlock, ipAddrBlocks),
+               (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+               +1,     /* EXPLICIT tag at current level */
+               &asn_DEF_IPList,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               "ipAddrBlocks"
+               },
+};
+static const int asn_MAP_ResourceBlock_oms_1[] = { 0, 1 };
+static const ber_tlv_tag_t asn_DEF_ResourceBlock_tags_1[] = {
+       (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_ResourceBlock_tag2el_1[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* asID */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* ipAddrBlocks */
+};
+asn_SEQUENCE_specifics_t asn_SPC_ResourceBlock_specs_1 = {
+       sizeof(struct ResourceBlock),
+       offsetof(struct ResourceBlock, _asn_ctx),
+       asn_MAP_ResourceBlock_tag2el_1,
+       2,      /* Count of tags in the map */
+       asn_MAP_ResourceBlock_oms_1,    /* Optional members */
+       2, 0,   /* Root/Additions */
+       -1,     /* First extension addition */
+};
+asn_TYPE_descriptor_t asn_DEF_ResourceBlock = {
+       "ResourceBlock",
+       "ResourceBlock",
+       &asn_OP_SEQUENCE,
+       asn_DEF_ResourceBlock_tags_1,
+       sizeof(asn_DEF_ResourceBlock_tags_1)
+               /sizeof(asn_DEF_ResourceBlock_tags_1[0]), /* 1 */
+       asn_DEF_ResourceBlock_tags_1,   /* Same as above */
+       sizeof(asn_DEF_ResourceBlock_tags_1)
+               /sizeof(asn_DEF_ResourceBlock_tags_1[0]), /* 1 */
+       { &asn_OER_type_ResourceBlock_constr_1, 0, SEQUENCE_constraint },
+       asn_MBR_ResourceBlock_1,
+       2,      /* Elements count */
+       &asn_SPC_ResourceBlock_specs_1  /* Additional specs */
+};
+
diff --git a/src/asn1/asn1c/ResourceBlock.h b/src/asn1/asn1c/ResourceBlock.h
new file mode 100644 (file)
index 0000000..a09a485
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#ifndef        _ResourceBlock_H_
+#define        _ResourceBlock_H_
+
+
+#include "asn1/asn1c/asn_application.h"
+
+/* Including external dependencies */
+#include "asn1/asn1c/constr_SEQUENCE.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+struct AsList;
+struct IPList;
+
+/* ResourceBlock */
+typedef struct ResourceBlock {
+       struct AsList   *asID   /* OPTIONAL */;
+       struct IPList   *ipAddrBlocks   /* OPTIONAL */;
+       
+       /* Context for parsing across buffer boundaries */
+       asn_struct_ctx_t _asn_ctx;
+} ResourceBlock_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_ResourceBlock;
+extern asn_SEQUENCE_specifics_t asn_SPC_ResourceBlock_specs_1;
+extern asn_TYPE_member_t asn_MBR_ResourceBlock_1[2];
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Referred external types */
+#include "AsList.h"
+#include "IPList.h"
+
+#endif /* _ResourceBlock_H_ */
+#include "asn1/asn1c/asn_internal.h"
diff --git a/src/asn1/asn1c/RpkiSignedChecklist.c b/src/asn1/asn1c/RpkiSignedChecklist.c
new file mode 100644 (file)
index 0000000..759c3fe
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#include "RpkiSignedChecklist.h"
+
+static int
+memb_checkList_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr,
+                       asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+       size_t size;
+       
+       if(!sptr) {
+               ASN__CTFAIL(app_key, td, sptr,
+                       "%s: value not given (%s:%d)",
+                       td->name, __FILE__, __LINE__);
+               return -1;
+       }
+       
+       /* Determine the number of elements */
+       size = _A_CSEQUENCE_FROM_VOID(sptr)->count;
+       
+       if((size >= 1)) {
+               /* Perform validation of the inner elements */
+               return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
+       } else {
+               ASN__CTFAIL(app_key, td, sptr,
+                       "%s: constraint failed (%s:%d)",
+                       td->name, __FILE__, __LINE__);
+               return -1;
+       }
+}
+
+static asn_oer_constraints_t asn_OER_type_checkList_constr_5 CC_NOTUSED = {
+       { 0, 0 },
+       -1      /* (SIZE(1..MAX)) */};
+static asn_oer_constraints_t asn_OER_memb_checkList_constr_5 CC_NOTUSED = {
+       { 0, 0 },
+       -1      /* (SIZE(1..MAX)) */};
+static int asn_DFL_2_cmp_0(const void *sptr) {
+       const INTEGER_t *st = sptr;
+       
+       if(!st) {
+               return -1; /* No value is not a default value */
+       }
+       
+       /* Test default value 0 */
+       long value;
+       if(asn_INTEGER2long(st, &value))
+               return -1;
+       return (value != 0);
+}
+static int asn_DFL_2_set_0(void **sptr) {
+       INTEGER_t *st = *sptr;
+       
+       if(!st) {
+               st = (*sptr = CALLOC(1, sizeof(*st)));
+               if(!st) return -1;
+       }
+       
+       /* Install default value 0 */
+       return asn_long2INTEGER(st, 0);
+}
+static asn_TYPE_member_t asn_MBR_checkList_5[] = {
+       { ATF_POINTER, 0, 0,
+               (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+               0,
+               &asn_DEF_FileNameAndHash,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               ""
+               },
+};
+static const ber_tlv_tag_t asn_DEF_checkList_tags_5[] = {
+       (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_SET_OF_specifics_t asn_SPC_checkList_specs_5 = {
+       sizeof(struct RpkiSignedChecklist__checkList),
+       offsetof(struct RpkiSignedChecklist__checkList, _asn_ctx),
+       0,      /* XER encoding is XMLDelimitedItemList */
+};
+static /* Use -fall-defs-global to expose */
+asn_TYPE_descriptor_t asn_DEF_checkList_5 = {
+       "checkList",
+       "checkList",
+       &asn_OP_SEQUENCE_OF,
+       asn_DEF_checkList_tags_5,
+       sizeof(asn_DEF_checkList_tags_5)
+               /sizeof(asn_DEF_checkList_tags_5[0]), /* 1 */
+       asn_DEF_checkList_tags_5,       /* Same as above */
+       sizeof(asn_DEF_checkList_tags_5)
+               /sizeof(asn_DEF_checkList_tags_5[0]), /* 1 */
+       { &asn_OER_type_checkList_constr_5, 0, SEQUENCE_OF_constraint },
+       asn_MBR_checkList_5,
+       1,      /* Single element */
+       &asn_SPC_checkList_specs_5      /* Additional specs */
+};
+
+static asn_TYPE_member_t asn_MBR_RpkiSignedChecklist_1[] = {
+       { ATF_POINTER, 1, offsetof(struct RpkiSignedChecklist, version),
+               (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+               +1,     /* EXPLICIT tag at current level */
+               &asn_DEF_INTEGER,
+               0,
+               { 0, 0, 0 },
+               &asn_DFL_2_cmp_0,       /* Compare DEFAULT 0 */
+               &asn_DFL_2_set_0,       /* Set DEFAULT 0 */
+               "version"
+               },
+       { ATF_NOFLAGS, 0, offsetof(struct RpkiSignedChecklist, resources),
+               (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+               0,
+               &asn_DEF_ResourceBlock,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               "resources"
+               },
+       { ATF_NOFLAGS, 0, offsetof(struct RpkiSignedChecklist, digestAlgorithm),
+               (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+               0,
+               &asn_DEF_DigestAlgorithmIdentifier,
+               0,
+               { 0, 0, 0 },
+               0, 0, /* No default value */
+               "digestAlgorithm"
+               },
+       { ATF_NOFLAGS, 0, offsetof(struct RpkiSignedChecklist, checkList),
+               (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+               0,
+               &asn_DEF_checkList_5,
+               0,
+               { &asn_OER_memb_checkList_constr_5, 0,  memb_checkList_constraint_1 },
+               0, 0, /* No default value */
+               "checkList"
+               },
+};
+static const int asn_MAP_RpkiSignedChecklist_oms_1[] = { 0 };
+static const ber_tlv_tag_t asn_DEF_RpkiSignedChecklist_tags_1[] = {
+       (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static const asn_TYPE_tag2member_t asn_MAP_RpkiSignedChecklist_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 2 }, /* resources */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 2, -1, 1 }, /* digestAlgorithm */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 3, -2, 0 }, /* checkList */
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 } /* version */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_RpkiSignedChecklist_specs_1 = {
+       sizeof(struct RpkiSignedChecklist),
+       offsetof(struct RpkiSignedChecklist, _asn_ctx),
+       asn_MAP_RpkiSignedChecklist_tag2el_1,
+       4,      /* Count of tags in the map */
+       asn_MAP_RpkiSignedChecklist_oms_1,      /* Optional members */
+       1, 0,   /* Root/Additions */
+       -1,     /* First extension addition */
+};
+asn_TYPE_descriptor_t asn_DEF_RpkiSignedChecklist = {
+       "RpkiSignedChecklist",
+       "RpkiSignedChecklist",
+       &asn_OP_SEQUENCE,
+       asn_DEF_RpkiSignedChecklist_tags_1,
+       sizeof(asn_DEF_RpkiSignedChecklist_tags_1)
+               /sizeof(asn_DEF_RpkiSignedChecklist_tags_1[0]), /* 1 */
+       asn_DEF_RpkiSignedChecklist_tags_1,     /* Same as above */
+       sizeof(asn_DEF_RpkiSignedChecklist_tags_1)
+               /sizeof(asn_DEF_RpkiSignedChecklist_tags_1[0]), /* 1 */
+       { 0, 0, SEQUENCE_constraint },
+       asn_MBR_RpkiSignedChecklist_1,
+       4,      /* Elements count */
+       &asn_SPC_RpkiSignedChecklist_specs_1    /* Additional specs */
+};
+
diff --git a/src/asn1/asn1c/RpkiSignedChecklist.h b/src/asn1/asn1c/RpkiSignedChecklist.h
new file mode 100644 (file)
index 0000000..bf0537b
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
+ * From ASN.1 module "RpkiSignedChecklist-2021"
+ *     found in "draft-ietf-sidrops-rpki-rsc.asn1"
+ *     `asn1c -Werror -fcompound-names -fwide-types -D asn1/asn1c -no-gen-PER -no-gen-example`
+ */
+
+#ifndef        _RpkiSignedChecklist_H_
+#define        _RpkiSignedChecklist_H_
+
+
+#include "asn1/asn1c/asn_application.h"
+
+/* Including external dependencies */
+#include "asn1/asn1c/INTEGER.h"
+#include "ResourceBlock.h"
+#include "DigestAlgorithmIdentifier.h"
+#include "asn1/asn1c/asn_SEQUENCE_OF.h"
+#include "asn1/asn1c/constr_SEQUENCE_OF.h"
+#include "asn1/asn1c/constr_SEQUENCE.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+struct FileNameAndHash;
+
+/* RpkiSignedChecklist */
+typedef struct RpkiSignedChecklist {
+       INTEGER_t       *version        /* DEFAULT 0 */;
+       ResourceBlock_t  resources;
+       DigestAlgorithmIdentifier_t      digestAlgorithm;
+       struct RpkiSignedChecklist__checkList {
+               A_SEQUENCE_OF(struct FileNameAndHash) list;
+               
+               /* Context for parsing across buffer boundaries */
+               asn_struct_ctx_t _asn_ctx;
+       } checkList;
+       
+       /* Context for parsing across buffer boundaries */
+       asn_struct_ctx_t _asn_ctx;
+} RpkiSignedChecklist_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_RpkiSignedChecklist;
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Referred external types */
+#include "FileNameAndHash.h"
+
+#endif /* _RpkiSignedChecklist_H_ */
+#include "asn1/asn1c/asn_internal.h"
index 8c1225516815cf5e2fddc421b5201c43cbb01723..3c0c9a82b9dbceeaa26a274f4f0998727fb042fe 100644 (file)
@@ -50,12 +50,12 @@ decode(struct file_contents *fc, struct ContentInfo **result)
 }
 
 int
-content_info_load(struct rpki_uri *uri, struct ContentInfo **result)
+content_info_load(char const *luri, struct ContentInfo **result)
 {
        struct file_contents fc;
        int error;
 
-       error = file_load(uri_get_local(uri), &fc);
+       error = file_load(luri, &fc);
        if (error)
                return error;
 
index ce7e93a444cc249c3fd36895b8bb8e3671891e13..9524ac975e3a6cf97b9da6d6b736af82f3fa5b02 100644 (file)
@@ -6,7 +6,7 @@
 #include "uri.h"
 #include "asn1/asn1c/ContentInfo.h"
 
-int content_info_load(struct rpki_uri *, struct ContentInfo **);
+int content_info_load(char const *, struct ContentInfo **);
 void content_info_free(struct ContentInfo *);
 
 #endif /* SRC_CONTENT_INFO_H_ */
index b013d80989e7ab6fbd7735675aa1955ca682b9f0..082b5421f2456e8af1f91ea13e34c95f66a9f1f8 100644 (file)
@@ -38,6 +38,7 @@ typedef asn_oid_arc_t OID[];
 #define OID_ROA                      { 1, 2, 840, 113549, 1, 9, 16, 1, 24 }
 #define OID_MANIFEST                 { 1, 2, 840, 113549, 1, 9, 16, 1, 26 }
 #define OID_GHOSTBUSTERS             { 1, 2, 840, 113549, 1, 9, 16, 1, 35 }
+#define OID_SIGNED_CHECKLIST         { 1, 2, 840, 113549, 1, 9, 16, 1, 48 }
 
 int oid2arcs(OBJECT_IDENTIFIER_t *, struct oid_arcs *);
 
index 16e36b00248ff6869640adf6e085cdc920240aec..7f16982c18f6677857dd17705d7d129878304712 100644 (file)
@@ -22,7 +22,6 @@ static const OID oid_bsta = OID_BINARY_SIGNING_TIME_ATTR;
 
 int
 signed_object_args_init(struct signed_object_args *args,
-    struct rpki_uri *uri,
     STACK_OF(X509_CRL) *crls,
     bool force_inherit)
 {
@@ -30,7 +29,7 @@ signed_object_args_init(struct signed_object_args *args,
        if (args->res == NULL)
                return pr_enomem();
 
-       args->uri = uri;
+       args->cert_type = EE;
        args->crls = crls;
        memset(&args->refs, 0, sizeof(args->refs));
        return 0;
@@ -95,13 +94,25 @@ handle_sdata_certificate(ANY_t *cert_encoded, struct signed_object_args *args,
        error = certificate_validate_chain(cert, args->crls);
        if (error)
                goto end2;
-       error = certificate_validate_rfc6487(cert, EE);
+       error = certificate_validate_rfc6487(cert, args->cert_type);
        if (error)
                goto end2;
-       error = certificate_validate_extensions_ee(cert, sid, &args->refs,
-           &policy);
+
+       switch (args->cert_type) {
+       case EE:
+               error = certificate_validate_extensions_ee(cert, sid,
+                   &args->refs, &policy);
+               break;
+       case EE_CHECKLIST:
+               error = certificate_validate_extensions_ee_checklist(cert, sid,
+                   &args->refs, &policy);
+               break;
+       default:
+               error = pr_val_err("Certificate type is not EE, even though we're validating a Signed Object.");
+       }
        if (error)
                goto end2;
+
        error = certificate_validate_aia(args->refs.caIssuers, cert);
        if (error)
                goto end2;
@@ -110,7 +121,7 @@ handle_sdata_certificate(ANY_t *cert_encoded, struct signed_object_args *args,
                goto end2;
 
        resources_set_policy(args->res, policy);
-       error = certificate_get_resources(cert, args->res, EE);
+       error = certificate_get_resources(cert, args->res, args->cert_type);
        if (error)
                goto end2;
 
index d627def8ed60e7c52d347c8dc58b1d2cfbb014cf..ccc4a65686c8650d24bcc63e56596fb5626440fd 100644 (file)
@@ -14,8 +14,8 @@
  * signed objects anymore.
  */
 struct signed_object_args {
-       /** Location of the signed object. */
-       struct rpki_uri *uri;
+       /** Type of the embedded EE certificate. */
+       enum cert_type cert_type;
        /** CRL that might or might not revoke the embedded certificate. */
        STACK_OF(X509_CRL) *crls;
        /** A copy of the resources carried by the embedded certificate. */
@@ -27,8 +27,8 @@ struct signed_object_args {
        struct certificate_refs refs;
 };
 
-int signed_object_args_init(struct signed_object_args *, struct rpki_uri *,
-    STACK_OF(X509_CRL) *, bool);
+int signed_object_args_init(struct signed_object_args *, STACK_OF(X509_CRL) *,
+    bool);
 void signed_object_args_cleanup(struct signed_object_args *);
 
 struct signed_data {
index 7fb617cfafee8ad676c96671d4453b38fe68291a..346db0897f664ad64b476eccbd519d72c558bc47 100644 (file)
@@ -102,3 +102,9 @@ refs_validate_ee(struct certificate_refs *refs, struct rpp const *pp,
 
        return validate_signedObject(refs, uri);
 }
+
+int
+refs_validate_ee_checklist(struct certificate_refs *refs, struct rpp const *pp)
+{
+       return validate_cdp(refs, pp);
+}
index 17b8384f5ab852cf98d4a4cdea5708c64149128b..e3f81395627cc5c4596f5faeb047bdd2552a8980 100644 (file)
@@ -41,5 +41,6 @@ void refs_cleanup(struct certificate_refs *);
 int refs_validate_ca(struct certificate_refs *, struct rpp const *);
 int refs_validate_ee(struct certificate_refs *, struct rpp const *,
     struct rpki_uri *);
+int refs_validate_ee_checklist(struct certificate_refs *, struct rpp const *);
 
 #endif /* SRC_CERTIFICATE_REFS_H_ */
index 5194e288c12625839d526bd750968bfff2ce031b..ae1c8c0466f49caef918f681834ae6becfbe1962 100644 (file)
@@ -55,6 +55,12 @@ struct rpki_config {
        unsigned int maximum_certificate_depth;
        /** File or directory where the .slurm file(s) is(are) located */
        char *slurm;
+       /**
+        * .sig file. If not null, triggers RCS validation
+        * (draft-ietf-sidrops-rpki-rsc), which replaces the normal RPKI
+        * validation.
+        */
+       char *rsc;
        /* Run as RTR server or standalone validation */
        enum mode mode;
        /*
@@ -325,6 +331,13 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, slurm),
                .doc = "Path to the SLURM file or SLURMs directory (files must have the extension .slurm)",
                .arg_doc = "<file>|<directory>"
+       }, {
+               .id = 1007,
+               .name = "rsc",
+               .type = &gt_string,
+               .offset = offsetof(struct rpki_config, rsc),
+               .doc = "Path to .sig file. Triggers RCS validation (draft-ietf-sidrops-rpki-rsc), which replaces the normal RPKI validation. Implies --mode standalone.",
+               .arg_doc = "<file>"
        }, {
                .id = 1004,
                .name = "mode",
@@ -980,6 +993,7 @@ set_default_values(void)
 
        rpki_config.tal = NULL;
        rpki_config.slurm = NULL;
+       rpki_config.rsc = NULL;
 
        rpki_config.local_repository = strdup("/tmp/fort/repository");
        if (rpki_config.local_repository == NULL) {
@@ -1140,7 +1154,11 @@ validate_config(void)
 
        if (rpki_config.slurm != NULL &&
            !valid_file_or_dir(rpki_config.slurm, true, true, __pr_op_err))
-               return pr_op_err("Invalid slurm location.");
+               return -EINVAL;
+
+       if (rpki_config.rsc != NULL &&
+           !valid_file_or_dir(rpki_config.rsc, true, false, __pr_op_err))
+               return -EINVAL;
 
        /* FIXME (later) Remove when sync-strategy is fully deprecated */
        if (!rpki_config.rsync.enabled)
@@ -1286,6 +1304,10 @@ get_option_metadatas(void)
 enum mode
 config_get_mode(void)
 {
+       /* TODO meh, kinda rude. */
+       if (rpki_config.rsc != NULL)
+               return STANDALONE;
+
        return rpki_config.mode;
 }
 
@@ -1338,6 +1360,12 @@ config_get_slurm(void)
        return rpki_config.slurm;
 }
 
+char const *
+config_get_rsc(void)
+{
+       return rpki_config.rsc;
+}
+
 char const *
 config_get_tal(void)
 {
index 9e4c1dcfb46ddbba91b2493a79d6b88930f9f646..e7e96386a307a7d36e8013425725fbc5cac6deef 100644 (file)
@@ -25,6 +25,7 @@ unsigned int config_get_interval_refresh(void);
 unsigned int config_get_interval_retry(void);
 unsigned int config_get_interval_expire(void);
 char const *config_get_slurm(void);
+char const *config_get_rsc(void);
 
 char const *config_get_tal(void);
 char const *config_get_local_repository(void);
index 9f5fb0db0ccfe0be07b52e1948f37e75f4787e28..2e9144a5979491e0312357d6e19e084084474883 100644 (file)
@@ -23,6 +23,7 @@
 #include "object/bgpsec.h"
 #include "object/name.h"
 #include "object/manifest.h"
+#include "object/rsc.h"
 #include "object/signed_object.h"
 #include "rrdp/rrdp_loader.h"
 #include "rsync/rsync.h"
@@ -128,7 +129,7 @@ validate_signature_algorithm(X509 *cert)
 }
 
 static int
-validate_issuer(X509 *cert, bool is_ta)
+validate_issuer(X509 *cert, enum cert_type type)
 {
        X509_NAME *issuer;
        struct rfc5280_name *name;
@@ -136,7 +137,7 @@ validate_issuer(X509 *cert, bool is_ta)
 
        issuer = X509_get_issuer_name(cert);
 
-       if (!is_ta)
+       if (type != TA)
                return validate_issuer_name("Certificate", issuer);
 
        /* TODO wait. Shouldn't we check subject == issuer? */
@@ -209,7 +210,7 @@ cert_from_signed_object(struct rpki_uri *uri, uint8_t **result, int *size)
        unsigned char *tmp;
        int error;
 
-       error = signed_object_decode(&sobj, uri);
+       error = signed_object_decode(&sobj, uri_get_local(uri));
        if (error)
                return error;
 
@@ -531,7 +532,7 @@ certificate_validate_rfc6487(X509 *cert, enum cert_type type)
                return error;
 
        /* rfc6487#section-4.4 */
-       error = validate_issuer(cert, type == TA);
+       error = validate_issuer(cert, type);
        if (error)
                return error;
 
@@ -1071,7 +1072,7 @@ end:
 
 static int
 handle_asn_extension(X509_EXTENSION *ext, struct resources *resources,
-    bool allow_inherit)
+    enum cert_type type)
 {
        ASN1_OCTET_STRING *string;
        struct ASIdentifiers *ids;
@@ -1083,7 +1084,7 @@ handle_asn_extension(X509_EXTENSION *ext, struct resources *resources,
        if (error)
                return error;
 
-       error = resources_add_asn(resources, ids, allow_inherit);
+       error = resources_add_asn(resources, ids, type);
 
        ASN_STRUCT_FREE(asn_DEF_ASIdentifiers, ids);
        return error;
@@ -1092,7 +1093,7 @@ handle_asn_extension(X509_EXTENSION *ext, struct resources *resources,
 static int
 __certificate_get_resources(X509 *cert, struct resources *resources,
     int addr_nid, int asn_nid, int bad_addr_nid, int bad_asn_nid,
-    char const *policy_rfc, char const *bad_ext_rfc, bool allow_asn_inherit)
+    char const *policy_rfc, char const *bad_ext_rfc, enum cert_type type)
 {
        X509_EXTENSION *ext;
        int nid;
@@ -1129,8 +1130,7 @@ __certificate_get_resources(X509 *cert, struct resources *resources,
                                return pr_val_err("The AS extension is not marked as critical.");
 
                        pr_val_debug("ASN {");
-                       error = handle_asn_extension(ext, resources,
-                           allow_asn_inherit);
+                       error = handle_asn_extension(ext, resources, type);
                        pr_val_debug("}");
                        asn_ext_found = true;
 
@@ -1148,6 +1148,8 @@ __certificate_get_resources(X509 *cert, struct resources *resources,
 
        if (!ip_ext_found && !asn_ext_found)
                return pr_val_err("Certificate lacks both IP and AS extension.");
+       if (type == EE_CHECKLIST && !ip_ext_found)
+               return pr_val_err("Certificate lacks an IP extension.");
 
        return 0;
 }
@@ -1164,12 +1166,12 @@ certificate_get_resources(X509 *cert, struct resources *resources,
                return __certificate_get_resources(cert, resources,
                    NID_sbgp_ipAddrBlock, NID_sbgp_autonomousSysNum,
                    nid_ipAddrBlocksv2(), nid_autonomousSysIdsv2(),
-                   "6484", "8360", type != BGPSEC);
+                   "6484", "8360", type);
        case RPKI_POLICY_RFC8360:
                return __certificate_get_resources(cert, resources,
                    nid_ipAddrBlocksv2(), nid_autonomousSysIdsv2(),
                    NID_sbgp_ipAddrBlock, NID_sbgp_autonomousSysNum,
-                   "8360", "6484", type != BGPSEC);
+                   "8360", "6484", type);
        }
 
        pr_crit("Unknown policy: %u", policy);
@@ -1537,10 +1539,11 @@ handle_ad(char const *ia_name, SIGNATURE_INFO_ACCESS *ia,
     char const *ad_name, int ad_nid, int uri_flags, bool required,
     int (*cb)(struct rpki_uri *, uint8_t, void *), void *arg)
 {
-# define AD_METHOD ((uri_flags & URI_VALID_RSYNC) == URI_VALID_RSYNC ? \
+#define AD_METHOD ((uri_flags & URI_VALID_RSYNC) == URI_VALID_RSYNC ? \
        "RSYNC" : \
        (((uri_flags & URI_VALID_HTTPS) == URI_VALID_HTTPS) ? \
        "HTTPS" : "RSYNC/HTTPS"))
+
        ACCESS_DESCRIPTION *ad;
        struct rpki_uri *uri;
        bool found = false;
@@ -1890,6 +1893,34 @@ certificate_validate_extensions_ee(X509 *cert, OCTET_STRING_t *sid,
        return handle_extensions(handlers, X509_get0_extensions(cert));
 }
 
+int
+certificate_validate_extensions_ee_checklist(X509 *cert, OCTET_STRING_t *sid,
+    struct certificate_refs *refs, enum rpki_policy *policy)
+{
+       struct ski_arguments ski_args;
+       struct extension_handler handlers[] = {
+          /* ext        reqd   handler        arg       */
+           { ext_ski(), true,  handle_ski_ee, &ski_args },
+           { ext_aki(), true,  handle_aki,              },
+           { ext_ku(),  true,  handle_ku_ee,            },
+           { ext_cdp(), true,  handle_cdp,    refs      },
+           { ext_aia(), true,  handle_aia,    refs      },
+           { ext_cp(),  true,  handle_cp,     policy    },
+           { ext_ir(),  false, handle_ir,               },
+           { ext_ar(),  false, handle_ar,               },
+           { ext_ir2(), false, handle_ir,               },
+           { ext_ar2(), false, handle_ar,               },
+           { NULL },
+       };
+
+       ski_args.cert = cert;
+       ski_args.sid = sid;
+
+       /* TODO (RSC) make sure SIA does not exist. */
+
+       return handle_extensions(handlers, X509_get0_extensions(cert));
+}
+
 static enum cert_type
 get_certificate_type(X509 *cert, bool is_ta)
 {
@@ -2399,6 +2430,31 @@ end:
        return 0;
 }
 
+struct rsc_args {
+       struct rpp *pp;
+       struct rpki_uri *cert_uri;
+};
+
+static int
+check_rsc_uri(struct rpki_uri const *rsc_uri, void *_args)
+{
+       struct rsc_args *args = _args;
+
+       if (uri_equals(rsc_uri, args->cert_uri))
+               exit(rsc_traverse(args->pp));
+
+       return 0;
+}
+
+static void
+handle_rsc(struct validation *state, struct rpp *pp, struct rpki_uri *cert_uri)
+{
+       struct rsc_args args;
+       args.pp = pp;
+       args.cert_uri = cert_uri;
+       validation_foreach_rsc(state, check_rsc_uri, &args);
+}
+
 /** Boilerplate code for CA certificate validation and recursive traversal. */
 int
 certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
@@ -2464,6 +2520,7 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
                pr_val_debug("Type: BGPsec EE");
                break;
        case EE:
+       case EE_CHECKLIST:
                pr_val_debug("Type: unexpected, validated as CA");
                break;
        }
@@ -2574,6 +2631,9 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
                goto revert_uris;
        }
 
+       if (config_get_rsc() != NULL)
+               handle_rsc(state, pp, cert_uri);
+
        /* -- Validate & traverse the RPP (@pp) described by the manifest -- */
        rpp_traverse(pp);
 
index d5bad7716585b71f170fb292ab528a77e4769795..d22e04c1bec8d4fe158da00580e862cc35f2ee03 100644 (file)
@@ -15,7 +15,8 @@ enum cert_type {
        TA,             /* Trust Anchor */
        CA,             /* Certificate Authority */
        BGPSEC,         /* BGPsec certificates */
-       EE,             /* End Entity certificates */
+       EE,             /* End Entity certificates (Except Signed Checklist) */
+       EE_CHECKLIST,   /* End Entity certificate inside of Signed Checklist */
 };
 
 int certificate_load(struct rpki_uri *, X509 **);
@@ -52,6 +53,9 @@ int certificate_get_resources(X509 *, struct resources *, enum cert_type);
  */
 int certificate_validate_extensions_ee(X509 *, OCTET_STRING_t *,
     struct certificate_refs *, enum rpki_policy *);
+int certificate_validate_extensions_ee_checklist(X509 *cert,
+    OCTET_STRING_t *sid, struct certificate_refs *refs,
+    enum rpki_policy *policy);
 
 /*
  * Specific validation of AIA (rfc6487#section-4.8.7) extension, public so that
index 7a746585e347537d18541f739666c7d7a707b5a7..f58c81ed126d0a6313545aa46c606c0bda0f4a03 100644 (file)
@@ -114,7 +114,7 @@ static int
 validate_extensions(X509_CRL *crl)
 {
        struct extension_handler handlers[] = {
-          /* ext   reqd   handler        arg */
+          /* ext        reqd   handler        arg */
            { ext_aki(), true,  handle_aki,              },
            { ext_cn(),  true,  handle_crlnum,           },
            { NULL },
index b9372c9ef736bce42bf37cab2ff2bc9e313d0ca3..f43ac65b6d794c5dac0ffd00d98ca08fef42babf 100644 (file)
@@ -29,7 +29,7 @@ ghostbusters_traverse(struct rpki_uri *uri, struct rpp *pp)
        fnstack_push_uri(uri);
 
        /* Decode */
-       error = signed_object_decode(&sobj, uri);
+       error = signed_object_decode(&sobj, uri_get_local(uri));
        if (error)
                goto revert_log;
 
@@ -37,7 +37,7 @@ ghostbusters_traverse(struct rpki_uri *uri, struct rpp *pp)
        error = rpp_crl(pp, &crl);
        if (error)
                goto revert_sobj;
-       error = signed_object_args_init(&sobj_args, uri, crl, true);
+       error = signed_object_args_init(&sobj_args, crl, true);
        if (error)
                goto revert_sobj;
 
@@ -48,7 +48,7 @@ ghostbusters_traverse(struct rpki_uri *uri, struct rpp *pp)
        error = handle_vcard(&sobj);
        if (error)
                goto revert_args;
-       error = refs_validate_ee(&sobj_args.refs, pp, sobj_args.uri);
+       error = refs_validate_ee(&sobj_args.refs, pp, uri);
 
 revert_args:
        signed_object_args_cleanup(&sobj_args);
index 327fe52886e4c7a000cd308bf6f54ae84d63dbec..e96c4e7b5c369642c1064a38f6e3ecbeff9ee00d 100644 (file)
@@ -245,7 +245,7 @@ handle_manifest(struct rpki_uri *uri, bool rrdp_workspace, struct rpp **pp)
        fnstack_push_uri(uri);
 
        /* Decode */
-       error = signed_object_decode(&sobj, uri);
+       error = signed_object_decode(&sobj, uri_get_local(uri));
        if (error)
                goto revert_log;
        error = decode_manifest(&sobj, &mft);
@@ -261,7 +261,7 @@ handle_manifest(struct rpki_uri *uri, bool rrdp_workspace, struct rpp **pp)
        error = rpp_crl(*pp, &crl);
        if (error)
                goto revert_rpp;
-       error = signed_object_args_init(&sobj_args, uri, crl, false);
+       error = signed_object_args_init(&sobj_args, crl, false);
        if (error)
                goto revert_rpp;
 
index fd64bb422d268ecea8584c720f110d16d8d27919..bbd5e108ed0bc7324b073c6ff8989ed4872eda32 100644 (file)
@@ -202,11 +202,11 @@ end:      x509_name_put(parent_subject);
 void
 x509_name_pr_debug(const char *prefix, X509_NAME *name)
 {
+       struct rfc5280_name *printable;
+
        if (!log_val_enabled(LOG_DEBUG))
                return;
 
-       struct rfc5280_name *printable;
-
        if (name == NULL) {
                pr_val_debug("%s: (null)", prefix);
                return;
index 77c1cab1ad151f5021bc8750ddb8ea14eb09fa59..48904d41f678b94714dc2e40537d10e6dbe8c070 100644 (file)
@@ -259,7 +259,7 @@ roa_traverse(struct rpki_uri *uri, struct rpp *pp)
        fnstack_push_uri(uri);
 
        /* Decode */
-       error = signed_object_decode(&sobj, uri);
+       error = signed_object_decode(&sobj, uri_get_local(uri));
        if (error)
                goto revert_log;
        error = decode_roa(&sobj, &roa);
@@ -270,7 +270,7 @@ roa_traverse(struct rpki_uri *uri, struct rpp *pp)
        error = rpp_crl(pp, &crl);
        if (error)
                goto revert_roa;
-       error = signed_object_args_init(&sobj_args, uri, crl, false);
+       error = signed_object_args_init(&sobj_args, crl, false);
        if (error)
                goto revert_roa;
 
@@ -281,7 +281,7 @@ roa_traverse(struct rpki_uri *uri, struct rpp *pp)
        error = __handle_roa(roa, sobj_args.res);
        if (error)
                goto revert_args;
-       error = refs_validate_ee(&sobj_args.refs, pp, sobj_args.uri);
+       error = refs_validate_ee(&sobj_args.refs, pp, uri);
 
 revert_args:
        signed_object_args_cleanup(&sobj_args);
diff --git a/src/object/rsc.c b/src/object/rsc.c
new file mode 100644 (file)
index 0000000..c857f51
--- /dev/null
@@ -0,0 +1,509 @@
+#include "object/rsc.h"
+
+#include "algorithm.h"
+#include "log.h"
+#include "thread_var.h"
+#include "asn1/oid.h"
+#include "asn1/decode.h"
+#include "asn1/asn1c/RpkiSignedChecklist.h"
+#include "object/signed_object.h"
+
+/* Returns @sobj's EE certificate. */
+static int
+get_certificate(struct signed_object *sobj, X509 **result)
+{
+       struct SignedData *decoded_object;
+       ANY_t *encoded_certificate;
+       X509 *decoded_certificate;
+       const unsigned char *tmp;
+
+       *result = NULL; /* Warning shutupper */
+       decoded_object = sobj->sdata.decoded;
+
+       if (decoded_object->certificates == NULL)
+               return pr_val_err("The SignedData does not contain certificates.");
+       if (decoded_object->certificates->list.count != 1) {
+               return pr_val_err("The SignedData contains %d certificates, one expected.",
+                   decoded_object->certificates->list.count);
+       }
+
+       encoded_certificate = decoded_object->certificates->list.array[0];
+
+       /*
+        * "If the call is successful *in is incremented to the byte following
+        * the parsed data."
+        * (https://www.openssl.org/docs/man1.0.2/crypto/d2i_X509_fp.html)
+        * We definitely don't want @any->buf to be modified, so use a dummy
+        * pointer.
+        */
+       tmp = (const unsigned char *) encoded_certificate->buf;
+
+       decoded_certificate = d2i_X509(NULL, &tmp, encoded_certificate->size);
+       if (decoded_certificate == NULL)
+               return val_crypto_err("Signed object's 'certificate' element does not decode into a Certificate");
+
+       *result = decoded_certificate;
+       return 0;
+}
+
+/* "Find (and return) the Authority Information Access extension" */
+static int
+find_aia(STACK_OF(X509_EXTENSION) const *extensions,
+    AUTHORITY_INFO_ACCESS **result)
+{
+       int e;
+       X509_EXTENSION *ext;
+       int nid;
+       AUTHORITY_INFO_ACCESS *aia;
+
+       for (e = 0; e < sk_X509_EXTENSION_num(extensions); e++) {
+               ext = sk_X509_EXTENSION_value(extensions, e);
+               nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext));
+               if (nid == NID_info_access) {
+                       aia = X509V3_EXT_d2i(ext);
+                       if (aia == NULL)
+                               return pr_val_err("Embedded EE certificate's Authority Information Access extension seems to be malformed.");
+                       *result = aia;
+                       return 0;
+               }
+       }
+
+       return pr_val_err("Embedded EE certificate appears to have no Authority Information Access extension.");
+}
+
+/* "Store Acess Descriptors" (in the validation state) */
+static int
+store_ads(AUTHORITY_INFO_ACCESS *aia)
+{
+       struct validation *state;
+       unsigned int ad;
+
+       struct rpki_uri **rsc_uris;
+       unsigned int uri;
+
+       int error;
+
+       rsc_uris = calloc(sk_ACCESS_DESCRIPTION_num(aia),
+           sizeof(struct rpki_uri *));
+       if (rsc_uris == NULL)
+               return pr_enomem();
+       uri = 0;
+
+       for (ad = 0; ad < sk_ACCESS_DESCRIPTION_num(aia); ad++) {
+               error = uri_create_ad(&rsc_uris[uri],
+                   sk_ACCESS_DESCRIPTION_value(aia, ad),
+                   URI_VALID_RSYNC | URI_VALID_HTTPS);
+               if (error == ENOTSUPPORTED)
+                       continue; /* Unknown; whatever. */
+               if (error)
+                       goto revert;
+
+               pr_val_info("Found AIA: %s\n",
+                   uri_val_get_printable(rsc_uris[uri]));
+               uri++;
+       }
+
+       state = state_retrieve();
+       if (!state) {
+               error = -EINVAL;
+               goto revert;
+       }
+
+       /* TODO (RSC) this is not being freed. Probably not important. */
+       validation_set_rsc_uris(state, rsc_uris, uri);
+       return 0;
+
+revert:
+       for (ad = 0; ad < sk_ACCESS_DESCRIPTION_num(aia); ad++)
+               if (rsc_uris[uri] != NULL)
+                       uri_refput(rsc_uris[uri]);
+       free(rsc_uris);
+       return error;
+}
+
+int
+rsc_store_aias(void)
+{
+       char const *rsc_uri;
+       struct signed_object sobj;
+       X509 *certificate;
+       AUTHORITY_INFO_ACCESS *aia;
+       int error;
+
+       rsc_uri = config_get_rsc();
+
+       /* Prepare */
+       pr_val_debug("Signed Checklist '%s' {", rsc_uri);
+       fnstack_push(rsc_uri);
+
+       /* Decode */
+       error = signed_object_decode(&sobj, rsc_uri);
+       if (error)
+               goto revert_log;
+
+       error = get_certificate(&sobj, &certificate);
+       if (error)
+               goto revert_decode;
+
+       error = find_aia(X509_get0_extensions(certificate), &aia);
+       if (error)
+               goto revert_certificate;
+
+       error = store_ads(aia);
+
+       AUTHORITY_INFO_ACCESS_free(aia);
+
+revert_certificate:
+       X509_free(certificate);
+revert_decode:
+       signed_object_cleanup(&sobj);
+revert_log:
+       pr_val_debug("}");
+       fnstack_pop();
+       return error;
+}
+
+static int
+decode_checklist(struct signed_object *sobj,
+    struct RpkiSignedChecklist **result)
+{
+       return asn1_decode_octet_string(
+               sobj->sdata.decoded->encapContentInfo.eContent,
+               &asn_DEF_RpkiSignedChecklist,
+               (void **) result,
+               true,
+               false
+       );
+}
+
+static bool
+is_portable_character(uint8_t chara)
+{
+       if (0x20 <= chara && chara <= 0x7E)
+               return true;
+       if (0x07 <= chara && chara <= 0x0D)
+               return true;
+       return chara == 0;
+}
+
+static int
+validate_filename(IA5String_t *filename)
+{
+       size_t i;
+
+       if (filename == NULL)
+               return 0;
+       if (filename->buf == NULL)
+               return pr_val_err("fileName contains a NULL buffer.");
+
+       for (i = 0; i < filename->size; i++)
+               if (!is_portable_character(filename->buf[i]))
+                       return pr_val_err("fileName contains invalid character %u.", filename->buf[i]);
+
+       return 0;
+}
+
+static int
+print_checklist(struct RpkiSignedChecklist *rsc)
+{
+       struct FileNameAndHash *fnah;
+       int error;
+       int i;
+
+       if (rsc->checkList.list.array == NULL)
+               return pr_val_err("RSC's checklist is a NULL array.");
+
+       for (i = 0; i < rsc->checkList.list.count; i++) {
+               fnah = rsc->checkList.list.array[i];
+               error = validate_filename(fnah->fileName);
+               if (error)
+                       return error;
+               if (asn_fprint(stdout, &asn_DEF_FileNameAndHash, fnah) != 0) {
+                       error = errno;
+                       return pr_val_errno(error,
+                           "Error printing FileNameAndHash");
+               }
+       }
+
+       return 0;
+}
+
+static int
+validate_resources_asID(struct resources *parent, struct AsList *asid)
+{
+       return 0;
+       /* TODO (RSC) ? */
+
+//     struct ASIdOrRange *aor;
+//     int a;
+//
+//     if (asid == NULL)
+//             return 0;
+//     if (asid->list.array == NULL)
+//             return pr_val_err("rsc->resources.asID contains a NULL array.");
+//
+//     for (a = 0; a < asid->list.count; a++) {
+//             aor = asid->list.array[a];
+//
+//             switch (aor->choice) {
+//             case ASIdOrRange_PR_NOTHING:
+//                     return pr_val_err("ASIdOrRange is neither id nor range.");
+//             case ASIdOrRange_PR_id:
+//                     // aor->choice.id;
+//                     break;
+//             case ASIdOrRange_PR_range:
+//
+//             }
+//     }
+}
+
+static int
+validate_prefix4(struct resources *parent, struct IPAddressFamilyItem *iafi)
+{
+       struct ipv4_prefix prefix;
+       int error;
+
+       error = prefix4_decode(&iafi->iPAddressOrRange.choice.addressPrefix,
+           &prefix);
+       if (error)
+               return error;
+
+       if (!resources_contains_ipv4(parent, &prefix)) {
+               return pr_val_err("RSC is not allowed to contain %s/%u.",
+                   v4addr2str(&prefix.addr), prefix.len);
+       }
+
+       pr_val_debug("%s/%u: Approved.", v4addr2str(&prefix.addr), prefix.len);
+       return 0;
+}
+
+static int
+validate_prefix6(struct resources *parent, struct IPAddressFamilyItem *iafi)
+{
+       struct ipv6_prefix prefix;
+       int error;
+
+       error = prefix6_decode(&iafi->iPAddressOrRange.choice.addressPrefix,
+           &prefix);
+       if (error)
+               return error;
+
+       if (!resources_contains_ipv6(parent, &prefix)) {
+               return pr_val_err("RSC is not allowed to contain %s/%u.",
+                   v6addr2str(&prefix.addr), prefix.len);
+       }
+
+       pr_val_debug("%s/%u: Approved.", v6addr2str(&prefix.addr), prefix.len);
+       return 0;
+}
+
+static int
+validate_range4(struct resources *parent, struct IPAddressFamilyItem *iafi)
+{
+       struct ipv4_range range;
+       int error;
+
+       error = range4_decode(&iafi->iPAddressOrRange.choice.addressRange,
+           &range);
+       if (error)
+               return error;
+
+       if (!resources_contains_range4(parent, &range)) {
+               return pr_val_err("RSC is not allowed to contain %s-%s.",
+                   v4addr2str(&range.min), v4addr2str2(&range.max));
+       }
+
+       pr_val_debug("%s-%s: Approved.", v4addr2str(&range.min),
+           v4addr2str2(&range.max));
+       return 0;
+}
+
+static int
+validate_range6(struct resources *parent, struct IPAddressFamilyItem *iafi)
+{
+       struct ipv6_range range;
+       int error;
+
+       error = range6_decode(&iafi->iPAddressOrRange.choice.addressRange,
+           &range);
+       if (error)
+               return error;
+
+       if (!resources_contains_range6(parent, &range)) {
+               return pr_val_err("RSC is not allowed to contain %s-%s.",
+                   v6addr2str(&range.min), v6addr2str2(&range.max));
+       }
+
+       pr_val_debug("%s-%s: Approved.", v6addr2str(&range.min),
+           v6addr2str2(&range.max));
+       return 0;
+}
+
+static int
+validate_resources_ipAddrBlocks(struct resources *parent, struct IPList *ips)
+{
+       struct IPAddressFamilyItem *iafi;
+       int error;
+       int i;
+
+       if (ips == NULL)
+               return 0;
+       if (ips->list.array == NULL)
+               return pr_val_err("rsc->resources.ipAddrBlocks contains a NULL array.");
+
+       error = 0;
+       for (i = 0; i < ips->list.count; i++) {
+               iafi = ips->list.array[i];
+
+               if (iafi == NULL)
+                       return pr_val_err("IPAddressFamilyItem array element is NULL.");
+
+               if (iafi->addressFamily.size != 2)
+                       goto family_error;
+               if (iafi->addressFamily.buf[0] != 0)
+                       goto family_error;
+
+               /* TODO (RSC) what about resources->policy? */
+               switch (iafi->addressFamily.buf[1]) {
+               case 1:
+                       switch (iafi->iPAddressOrRange.present) {
+                       case IPAddressOrRange_PR_addressPrefix:
+                               error = validate_prefix4(parent, iafi);
+                               break;
+                       case IPAddressOrRange_PR_addressRange:
+                               error = validate_range4(parent, iafi);
+                               break;
+                       case IPAddressOrRange_PR_NOTHING:
+                               goto pr_nothing;
+                       }
+                       break;
+               case 2:
+                       switch (iafi->iPAddressOrRange.present) {
+                       case IPAddressOrRange_PR_addressPrefix:
+                               error = validate_prefix6(parent, iafi);
+                               break;
+                       case IPAddressOrRange_PR_addressRange:
+                               error = validate_range6(parent, iafi);
+                               break;
+                       case IPAddressOrRange_PR_NOTHING:
+                               goto pr_nothing;
+                       }
+                       break;
+               default:
+                       goto family_error;
+               }
+       }
+
+       return error;
+
+family_error:
+       return pr_val_err("IPAddressFamilyItem's IP family is not v4 or v6.");
+pr_nothing:
+       return pr_val_err("IPAddressFamilyItem has neither a prefix nor a range.");
+}
+
+static int
+__handle_checklist(struct RpkiSignedChecklist *rsc, struct resources *parent)
+{
+       unsigned long version;
+       int error;
+
+       pr_val_debug("eContent {");
+       if (rsc->version != NULL) {
+               error = asn_INTEGER2ulong(rsc->version, &version);
+               if (error) {
+                       if (errno)
+                               pr_val_errno(errno, "Error casting RSC's version");
+                       error = pr_val_err("The RSC's version isn't a valid long");
+                       goto end;
+               }
+               /* draft#section-4.1 */
+               if (version != 0) {
+                       error = pr_val_err("RSC's version (%lu) is nonzero.",
+                           version);
+                       goto end;
+               }
+       }
+
+       /* draft#section-4.2 */
+       error = validate_resources_asID(parent, rsc->resources.asID);
+       if (error)
+               goto end;
+       error = validate_resources_ipAddrBlocks(parent,
+           rsc->resources.ipAddrBlocks);
+       if (error)
+               goto end;
+
+       /* draft#section-4.3 */
+       error = validate_cms_hashing_algorithm(&rsc->digestAlgorithm,
+           "digestAlgorithm");
+       if (error)
+               return error;
+
+       /* draft#section-4.4 */
+       error = print_checklist(rsc);
+       /* Fall through */
+
+end:
+       pr_val_debug("}");
+       return error;
+}
+
+void
+rsc_traverse(struct rpp *pp)
+{
+       static OID oid = OID_SIGNED_CHECKLIST;
+       struct oid_arcs arcs = OID2ARCS("signed checklist", oid);
+       char const *rsc_uri;
+       struct signed_object sobj;
+       struct signed_object_args sobj_args;
+       struct RpkiSignedChecklist *checklist;
+       STACK_OF(X509_CRL) *crl;
+       int error;
+
+       rsc_uri = config_get_rsc();
+
+       /* Prepare */
+       pr_val_debug("Signed Checklist '%s' {", rsc_uri);
+       fnstack_push(rsc_uri);
+
+       /* Decode */
+       error = signed_object_decode(&sobj, rsc_uri);
+       if (error)
+               goto revert_log;
+       error = decode_checklist(&sobj, &checklist);
+       if (error)
+               goto revert_sobj;
+
+       /* Prepare validation arguments */
+       error = rpp_crl(pp, &crl);
+       if (error)
+               goto revert_checklist;
+       error = signed_object_args_init(&sobj_args, crl, false);
+       if (error)
+               goto revert_checklist;
+       sobj_args.cert_type = EE_CHECKLIST;
+
+       /* Validate everything */
+       error = signed_object_validate(&sobj, &arcs, &sobj_args);
+       if (error)
+               goto revert_args;
+       error = __handle_checklist(checklist, sobj_args.res);
+       if (error)
+               goto revert_args;
+       /*
+        * TODO (RSC) why is this validated last? The hashes were already
+        * printed.
+        */
+       error = refs_validate_ee_checklist(&sobj_args.refs, pp);
+
+revert_args:
+       signed_object_args_cleanup(&sobj_args);
+revert_checklist:
+       ASN_STRUCT_FREE(asn_DEF_RpkiSignedChecklist, checklist);
+revert_sobj:
+       signed_object_cleanup(&sobj);
+revert_log:
+       fnstack_pop();
+       pr_val_debug("}");
+}
diff --git a/src/object/rsc.h b/src/object/rsc.h
new file mode 100644 (file)
index 0000000..b0a45f0
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef SRC_OBJECT_RSC_H_
+#define SRC_OBJECT_RSC_H_
+
+#include "rpp.h"
+
+int rsc_store_aias(void);
+void rsc_traverse(struct rpp *);
+
+#endif /* SRC_OBJECT_RSC_H_ */
index 539f5c79aded08ebee82040bc3212340b5164f26..3c8bcf51abb5cc21b6e8be4bfa822338bea3dfed 100644 (file)
@@ -5,11 +5,11 @@
 #include "asn1/content_info.h"
 
 int
-signed_object_decode(struct signed_object *sobj, struct rpki_uri *uri)
+signed_object_decode(struct signed_object *sobj, char const *luri)
 {
        int error;
 
-       error = content_info_load(uri, &sobj->cinfo);
+       error = content_info_load(luri, &sobj->cinfo);
        if (error)
                return error;
 
index 41404d74e30cee402dd0b792f348385d1236a742..b88982767dda30c1499d4032af3a137dabab61cc 100644 (file)
@@ -9,7 +9,7 @@ struct signed_object {
        struct signed_data sdata;
 };
 
-int signed_object_decode(struct signed_object *, struct rpki_uri *);
+int signed_object_decode(struct signed_object *, char const *);
 int signed_object_validate(struct signed_object *, struct oid_arcs const *,
     struct signed_object_args *);
 void signed_object_cleanup(struct signed_object *);
index 2bc6ba049220a57c62391299b8042b36fc89c110..efb3960213ed8901af0d24661fd65bdf941c8be2 100644 (file)
@@ -29,6 +29,8 @@
 #include "rtr/db/vrps.h"
 #include "rrdp/db/db_rrdp.h"
 
+#include "object/rsc.h" /* TODO (RSC) delete */
+
 #define TAL_FILE_EXTENSION     ".tal"
 typedef int (*foreach_uri_cb)(struct tal *, struct rpki_uri *, void *);
 
@@ -528,6 +530,13 @@ handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg)
        if (error)
                return ENSURE_NEGATIVE(error);
 
+       /* TODO (RSC) dumb hack; move this. */
+       if (config_get_rsc() != NULL) {
+               error = rsc_store_aias();
+               if (error)
+                       goto end;
+       }
+
        if (thread_arg->sync_files) {
                if (uri_is_rsync(uri)) {
                        if (!config_get_rsync_enabled()) {
@@ -767,6 +776,7 @@ perform_standalone_validation(struct thread_pool *pool, struct db_table *table)
        struct validation_thread *thread;
        int error, t_error;
 
+       /* TODO why is this stored in the heap? */
        param = malloc(sizeof(struct tal_param));
        if (param == NULL)
                return pr_enomem();
index 228b255a222daa1fc8f59145f760f7b3db1608e6..7fd200e9748a9791e94857f136155411bc2d92d1 100644 (file)
@@ -535,7 +535,7 @@ add_asiors(struct resources *resources, struct ASIdentifiers *ids)
 
 int
 resources_add_asn(struct resources *resources, struct ASIdentifiers *ids,
-    bool allow_inherit)
+    enum cert_type type)
 {
        if (ids->asnum == NULL)
                return pr_val_err("ASN extension lacks 'asnum' element.");
@@ -544,7 +544,7 @@ resources_add_asn(struct resources *resources, struct ASIdentifiers *ids,
 
        switch (ids->asnum->present) {
        case ASIdentifierChoice_PR_inherit:
-               if (!allow_inherit)
+               if (type == BGPSEC)
                        return pr_val_err("ASIdentifierChoice %u isn't allowed",
                            ids->asnum->present);
                return inherit_asiors(resources);
@@ -583,6 +583,18 @@ resources_contains_ipv6(struct resources *res, struct ipv6_prefix *prefix)
        return res6_contains_prefix(res->ip6s, prefix);
 }
 
+bool
+resources_contains_range4(struct resources *res, struct ipv4_range *range)
+{
+       return res4_contains_range(res->ip4s, range);
+}
+
+bool
+resources_contains_range6(struct resources *res, struct ipv6_range *range)
+{
+       return res6_contains_range(res->ip6s, range);
+}
+
 enum rpki_policy
 resources_get_policy(struct resources *res)
 {
index 450c8c2ed55f0e68dd3b1f75392c28c2ccc12031..7db4310d3d81d013dedbe45567e45664b84f5d5e 100644 (file)
@@ -28,12 +28,16 @@ struct resources *resources_create(bool);
 void resources_destroy(struct resources *);
 
 int resources_add_ip(struct resources *, struct IPAddressFamily *);
-int resources_add_asn(struct resources *, struct ASIdentifiers *, bool);
+enum cert_type;
+int resources_add_asn(struct resources *, struct ASIdentifiers *,
+    enum cert_type);
 
 bool resources_empty(struct resources *);
 bool resources_contains_asn(struct resources *, unsigned long);
 bool resources_contains_ipv4(struct resources *, struct ipv4_prefix *);
 bool resources_contains_ipv6(struct resources *, struct ipv6_prefix *);
+bool resources_contains_range4(struct resources *, struct ipv4_range *);
+bool resources_contains_range6(struct resources *, struct ipv6_range *);
 
 enum rpki_policy resources_get_policy(struct resources *);
 void resources_set_policy(struct resources *, enum rpki_policy);
index f7bdd34d832f9507042616495e8fed947704b7e0..4a482fede4aae40b548856076880d12d6a95d7a3 100644 (file)
--- a/src/rpp.c
+++ b/src/rpp.c
@@ -266,6 +266,9 @@ rpp_traverse(struct rpp *pp)
         */
        __cert_traverse(pp);
 
+       if (config_get_rsc() != NULL)
+               return; /* In RSC runs, ROAs and Ghostbusters don't matter. */
+
        /* Validate ROAs, apply validation_handler on them. */
        ARRAYLIST_FOREACH(&pp->roas, uri, i)
                roa_traverse(*uri, pp);
index 6a962b6a013d19908d7160377d7b20ed950fdd43..d48da734d66b05a3262e51438c9de4c2801bd1eb 100644 (file)
@@ -45,6 +45,17 @@ struct validation {
        char addr_buffer2[INET6_ADDRSTRLEN];
 
        struct validation_handler validation_handler;
+
+       /**
+        * URI pointer array. If RSC validation is enabled, these are the Signed
+        * Checklist's EE certificate's AIA URLs. Otherwise NULL.
+        *
+        * Fort needs to look for a CA certificate that matches one of these
+        * URIs.
+        */
+       struct rpki_uri **rsc_uris;
+       /** Size of the rsc_uris array. */
+       unsigned int rsc_uris_size;
 };
 
 /*
@@ -229,3 +240,26 @@ validation_get_rrdp_workspace(struct validation *state)
 {
        return state->rrdp_workspace;
 }
+
+int
+validation_foreach_rsc(struct validation *state, foreach_rsc_cb cb, void *arg)
+{
+       unsigned int i;
+       int status;
+
+       for (i = 0; i < state->rsc_uris_size; i++) {
+               status = cb(state->rsc_uris[i], arg);
+               if (status != 0)
+                       return status;
+       }
+
+       return 0;
+}
+
+void
+validation_set_rsc_uris(struct validation *state, struct rpki_uri **uris,
+    unsigned int count)
+{
+       state->rsc_uris = uris;
+       state->rsc_uris_size = count;
+}
index 5fceca3086930d26558679556dca79bfb146a7da..4a0b86db14a53a526d81972ec4ab87761f36d2aa 100644 (file)
@@ -38,4 +38,9 @@ validation_get_validation_handler(struct validation *);
 struct db_rrdp_uri *validation_get_rrdp_uris(struct validation *);
 char const *validation_get_rrdp_workspace(struct validation *);
 
+typedef int (*foreach_rsc_cb)(struct rpki_uri const *, void *);
+int validation_foreach_rsc(struct validation *, foreach_rsc_cb, void *);
+void validation_set_rsc_uris(struct validation *, struct rpki_uri **,
+    unsigned int);
+
 #endif /* SRC_STATE_H_ */
index 392515ba6558de6c8ca47d5eda0d69d60fe3a68e..f8c5890c37d904411d6a499f7d515bda0b5be2a8 100644 (file)
--- a/src/uri.c
+++ b/src/uri.c
@@ -494,32 +494,32 @@ uri_refput(struct rpki_uri *uri)
 }
 
 char const *
-uri_get_global(struct rpki_uri *uri)
+uri_get_global(struct rpki_uri const *uri)
 {
        return uri->global;
 }
 
 char const *
-uri_get_local(struct rpki_uri *uri)
+uri_get_local(struct rpki_uri const *uri)
 {
        return uri->local;
 }
 
 size_t
-uri_get_global_len(struct rpki_uri *uri)
+uri_get_global_len(struct rpki_uri const *uri)
 {
        return uri->global_len;
 }
 
 bool
-uri_equals(struct rpki_uri *u1, struct rpki_uri *u2)
+uri_equals(struct rpki_uri const *u1, struct rpki_uri const *u2)
 {
        return strcmp(u1->global, u2->global) == 0;
 }
 
 /* @ext must include the period. */
 bool
-uri_has_extension(struct rpki_uri *uri, char const *ext)
+uri_has_extension(struct rpki_uri const *uri, char const *ext)
 {
        size_t ext_len;
        int cmp;
@@ -533,13 +533,13 @@ uri_has_extension(struct rpki_uri *uri, char const *ext)
 }
 
 bool
-uri_is_certificate(struct rpki_uri *uri)
+uri_is_certificate(struct rpki_uri const *uri)
 {
        return uri_has_extension(uri, ".cer");
 }
 
 bool
-uri_is_rsync(struct rpki_uri *uri)
+uri_is_rsync(struct rpki_uri const *uri)
 {
        return uri->type == URI_RSYNC;
 }
@@ -552,7 +552,7 @@ get_filename(char const *file_path)
 }
 
 static char const *
-uri_get_printable(struct rpki_uri *uri, enum filename_format format)
+uri_get_printable(struct rpki_uri const *uri, enum filename_format format)
 {
        switch (format) {
        case FNF_GLOBAL:
@@ -568,7 +568,7 @@ uri_get_printable(struct rpki_uri *uri, enum filename_format format)
 }
 
 char const *
-uri_val_get_printable(struct rpki_uri *uri) {
+uri_val_get_printable(struct rpki_uri const *uri) {
        enum filename_format format;
 
        format = config_get_val_log_filename_format();
@@ -576,7 +576,7 @@ uri_val_get_printable(struct rpki_uri *uri) {
 }
 
 char const *
-uri_op_get_printable(struct rpki_uri *uri) {
+uri_op_get_printable(struct rpki_uri const *uri) {
        enum filename_format format;
 
        format = config_get_op_log_filename_format();
index 6e2d7c1f43b1ff2c2127969e9a80af568719494c..a6b4d7a35bfbbabb159886e6a135e4ac517bb0d4 100644 (file)
--- a/src/uri.h
+++ b/src/uri.h
@@ -29,16 +29,16 @@ void uri_refput(struct rpki_uri *);
  * Note that, if you intend to print some URI, you're likely supposed to use
  * uri_get_printable() instead.
  */
-char const *uri_get_global(struct rpki_uri *);
-char const *uri_get_local(struct rpki_uri *);
-size_t uri_get_global_len(struct rpki_uri *);
+char const *uri_get_global(struct rpki_uri const *);
+char const *uri_get_local(struct rpki_uri const *);
+size_t uri_get_global_len(struct rpki_uri const *);
 
-bool uri_equals(struct rpki_uri *, struct rpki_uri *);
-bool uri_has_extension(struct rpki_uri *, char const *);
-bool uri_is_certificate(struct rpki_uri *);
-bool uri_is_rsync(struct rpki_uri *);
+bool uri_equals(struct rpki_uri const *, struct rpki_uri const *);
+bool uri_has_extension(struct rpki_uri const *, char const *);
+bool uri_is_certificate(struct rpki_uri const *);
+bool uri_is_rsync(struct rpki_uri const *);
 
-char const *uri_val_get_printable(struct rpki_uri *);
-char const *uri_op_get_printable(struct rpki_uri *);
+char const *uri_val_get_printable(struct rpki_uri const *);
+char const *uri_op_get_printable(struct rpki_uri const *);
 
 #endif /* SRC_URI_H_ */
index 987c73575a2276bf34ed63a5de0cdf1960aaa167..957fd13cfaebd78c8d43053446b3b4431e02952a 100644 (file)
@@ -175,18 +175,15 @@ visited_uris_delete_local(struct visited_uris *uris, char const *workspace)
 
        error = visited_uris_to_arr(uris, &roots);
        if (error)
-               goto err;
+               goto end;
 
        if (roots.len == 0)
-               goto success;
+               goto end; /* success */
 
        error = delete_dir_daemon_start(roots.array, roots.len, workspace);
-       if (error)
-               goto err;
-success:
-       uris_roots_cleanup(&roots, uris_root_destroy);
-       return 0;
-err:
+       /* Fall through*/
+
+end:
        uris_roots_cleanup(&roots, uris_root_destroy);
        return error;
 }