From: Alberto Leiva Popper Date: Mon, 31 May 2021 18:58:54 +0000 (-0500) Subject: draft-ietf-sidrops-rpki-rsc-03: First implementation prototype X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fdraft-ietf-sidrops-rpki-rsc;p=thirdparty%2FFORT-validator.git draft-ietf-sidrops-rpki-rsc-03: First implementation prototype 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. --- diff --git a/src/Makefile.am b/src/Makefile.am index ef6dfa1f..95f08e3c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 00000000..14ce8fd2 --- /dev/null +++ b/src/asn1/asn1c/AsList.c @@ -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 index 00000000..eebbbe82 --- /dev/null +++ b/src/asn1/asn1c/AsList.h @@ -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 index 00000000..e528299f --- /dev/null +++ b/src/asn1/asn1c/FileNameAndHash.c @@ -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 index 00000000..ffb70c33 --- /dev/null +++ b/src/asn1/asn1c/FileNameAndHash.h @@ -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 index 00000000..1e7dc488 --- /dev/null +++ b/src/asn1/asn1c/IPAddressFamilyItem.c @@ -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 index 00000000..3260ab2a --- /dev/null +++ b/src/asn1/asn1c/IPAddressFamilyItem.h @@ -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 index 00000000..2904bdda --- /dev/null +++ b/src/asn1/asn1c/IPList.c @@ -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 index 00000000..21cbde9b --- /dev/null +++ b/src/asn1/asn1c/IPList.h @@ -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" diff --git a/src/asn1/asn1c/Makefile.include b/src/asn1/asn1c/Makefile.include index 9d606b59..d51eaf42 100644 --- a/src/asn1/asn1c/Makefile.include +++ b/src/asn1/asn1c/Makefile.include @@ -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 index 00000000..12b5b2fe --- /dev/null +++ b/src/asn1/asn1c/ResourceBlock.c @@ -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 index 00000000..a09a4855 --- /dev/null +++ b/src/asn1/asn1c/ResourceBlock.h @@ -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 index 00000000..759c3fe7 --- /dev/null +++ b/src/asn1/asn1c/RpkiSignedChecklist.c @@ -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 index 00000000..bf0537b0 --- /dev/null +++ b/src/asn1/asn1c/RpkiSignedChecklist.h @@ -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" diff --git a/src/asn1/content_info.c b/src/asn1/content_info.c index 8c122551..3c0c9a82 100644 --- a/src/asn1/content_info.c +++ b/src/asn1/content_info.c @@ -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; diff --git a/src/asn1/content_info.h b/src/asn1/content_info.h index ce7e93a4..9524ac97 100644 --- a/src/asn1/content_info.h +++ b/src/asn1/content_info.h @@ -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_ */ diff --git a/src/asn1/oid.h b/src/asn1/oid.h index b013d809..082b5421 100644 --- a/src/asn1/oid.h +++ b/src/asn1/oid.h @@ -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 *); diff --git a/src/asn1/signed_data.c b/src/asn1/signed_data.c index 16e36b00..7f16982c 100644 --- a/src/asn1/signed_data.c +++ b/src/asn1/signed_data.c @@ -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; diff --git a/src/asn1/signed_data.h b/src/asn1/signed_data.h index d627def8..ccc4a656 100644 --- a/src/asn1/signed_data.h +++ b/src/asn1/signed_data.h @@ -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 { diff --git a/src/certificate_refs.c b/src/certificate_refs.c index 7fb617cf..346db089 100644 --- a/src/certificate_refs.c +++ b/src/certificate_refs.c @@ -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); +} diff --git a/src/certificate_refs.h b/src/certificate_refs.h index 17b8384f..e3f81395 100644 --- a/src/certificate_refs.h +++ b/src/certificate_refs.h @@ -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_ */ diff --git a/src/config.c b/src/config.c index 5194e288..ae1c8c04 100644 --- a/src/config.c +++ b/src/config.c @@ -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 = "|" + }, { + .id = 1007, + .name = "rsc", + .type = >_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 = "" }, { .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) { diff --git a/src/config.h b/src/config.h index 9e4c1dcf..e7e96386 100644 --- a/src/config.h +++ b/src/config.h @@ -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); diff --git a/src/object/certificate.c b/src/object/certificate.c index 9f5fb0db..2e9144a5 100644 --- a/src/object/certificate.c +++ b/src/object/certificate.c @@ -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); diff --git a/src/object/certificate.h b/src/object/certificate.h index d5bad771..d22e04c1 100644 --- a/src/object/certificate.h +++ b/src/object/certificate.h @@ -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 diff --git a/src/object/crl.c b/src/object/crl.c index 7a746585..f58c81ed 100644 --- a/src/object/crl.c +++ b/src/object/crl.c @@ -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 }, diff --git a/src/object/ghostbusters.c b/src/object/ghostbusters.c index b9372c9e..f43ac65b 100644 --- a/src/object/ghostbusters.c +++ b/src/object/ghostbusters.c @@ -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); diff --git a/src/object/manifest.c b/src/object/manifest.c index 327fe528..e96c4e7b 100644 --- a/src/object/manifest.c +++ b/src/object/manifest.c @@ -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; diff --git a/src/object/name.c b/src/object/name.c index fd64bb42..bbd5e108 100644 --- a/src/object/name.c +++ b/src/object/name.c @@ -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; diff --git a/src/object/roa.c b/src/object/roa.c index 77c1cab1..48904d41 100644 --- a/src/object/roa.c +++ b/src/object/roa.c @@ -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 index 00000000..c857f513 --- /dev/null +++ b/src/object/rsc.c @@ -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 index 00000000..b0a45f08 --- /dev/null +++ b/src/object/rsc.h @@ -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_ */ diff --git a/src/object/signed_object.c b/src/object/signed_object.c index 539f5c79..3c8bcf51 100644 --- a/src/object/signed_object.c +++ b/src/object/signed_object.c @@ -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; diff --git a/src/object/signed_object.h b/src/object/signed_object.h index 41404d74..b8898276 100644 --- a/src/object/signed_object.h +++ b/src/object/signed_object.h @@ -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 *); diff --git a/src/object/tal.c b/src/object/tal.c index 2bc6ba04..efb39602 100644 --- a/src/object/tal.c +++ b/src/object/tal.c @@ -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(); diff --git a/src/resource.c b/src/resource.c index 228b255a..7fd200e9 100644 --- a/src/resource.c +++ b/src/resource.c @@ -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) { diff --git a/src/resource.h b/src/resource.h index 450c8c2e..7db4310d 100644 --- a/src/resource.h +++ b/src/resource.h @@ -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); diff --git a/src/rpp.c b/src/rpp.c index f7bdd34d..4a482fed 100644 --- 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); diff --git a/src/state.c b/src/state.c index 6a962b6a..d48da734 100644 --- a/src/state.c +++ b/src/state.c @@ -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; +} diff --git a/src/state.h b/src/state.h index 5fceca30..4a0b86db 100644 --- a/src/state.h +++ b/src/state.h @@ -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_ */ diff --git a/src/uri.c b/src/uri.c index 392515ba..f8c5890c 100644 --- 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(); diff --git a/src/uri.h b/src/uri.h index 6e2d7c1f..a6b4d7a3 100644 --- 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_ */ diff --git a/src/visited_uris.c b/src/visited_uris.c index 987c7357..957fd13c 100644 --- a/src/visited_uris.c +++ b/src/visited_uris.c @@ -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; }