rpki_validator_SOURCES += array_list.h
rpki_validator_SOURCES += certificate_refs.h certificate_refs.c
rpki_validator_SOURCES += common.h common.c
+rpki_validator_SOURCES += config.h config.c
rpki_validator_SOURCES += debug.h debug.c
rpki_validator_SOURCES += file.h file.c
rpki_validator_SOURCES += line_file.h line_file.c
#include <libcmscodec/ContentType.h>
#include <libcmscodec/MessageDigest.h>
+#include "config.h"
#include "log.h"
#include "oid.h"
+#include "thread_var.h"
#include "asn1/decode.h"
#include "crypto/hash.h"
#include "object/certificate.h"
handle_sdata_certificate(ANY_t *any, struct signed_object_args *args,
OCTET_STRING_t *sid)
{
+ struct validation *state;
const unsigned char *tmp;
X509 *cert;
int error;
+ state = state_retrieve();
+ if (state == NULL)
+ return -EINVAL;
+ if (sk_X509_num(validation_certs(state)) >= config_get_max_cert_depth())
+ return pr_err("Certificate chain maximum depth exceeded.");
+
pr_debug_add("EE Certificate (embedded) {");
/*
#include <string.h>
#include "log.h"
-char const *repository;
-size_t repository_len;
int NID_rpkiManifest;
int NID_signedObject;
int NID_rpkiNotify;
*/
#define ENOTRSYNC 3174
-extern char const *repository;
-extern size_t repository_len;
extern int NID_rpkiManifest;
extern int NID_signedObject;
extern int NID_rpkiNotify;
--- /dev/null
+#include "config.h"
+
+static struct rpki_config config;
+
+void
+config_set(struct rpki_config *new)
+{
+ config = *new;
+}
+
+char const *
+config_get_tal(void)
+{
+ return config.tal;
+}
+
+char const *
+config_get_local_repository(void)
+{
+ return config.local_repository;
+}
+
+bool
+config_get_disable_rsync(void)
+{
+ return config.disable_rsync;
+}
+
+bool
+config_get_shuffle_uris(void)
+{
+ return config.shuffle_uris;
+}
+
+unsigned int
+config_get_max_cert_depth(void)
+{
+ return config.maximum_certificate_depth;
+}
--- /dev/null
+#ifndef SRC_CONFIG_H_
+#define SRC_CONFIG_H_
+
+#include <stdbool.h>
+
+struct rpki_config {
+ /* tal file path*/
+ char *tal;
+ /* Local repository path */
+ char *local_repository;
+ /* Disable rsync downloads */
+ bool disable_rsync;
+ /* Shuffle uris in tal */
+ bool shuffle_uris;
+ /*
+ * rfc6487#section-7.2, last paragraph.
+ * Prevents arbitrarily long paths and loops.
+ */
+ unsigned int maximum_certificate_depth;
+};
+
+void config_set(struct rpki_config *);
+
+char const *config_get_tal(void);
+char const *config_get_local_repository(void);
+bool config_get_disable_rsync(void);
+bool config_get_shuffle_uris(void);
+unsigned int config_get_max_cert_depth(void);
+
+#endif /* SRC_CONFIG_H_ */
#include <openssl/objects.h>
#include "common.h"
+#include "config.h"
#include "debug.h"
#include "log.h"
#include "rpp.h"
#include "object/tal.h"
#include "rsync/rsync.h"
-struct rpki_config {
- /* tal file path*/
- char *tal;
- /* Local repository path */
- char *local_repository;
- /* Disable rsync downloads */
- bool disable_rsync;
- /* Shuffle uris in tal */
- bool shuffle_uris;
-};
-
/**
* Registers the RPKI-specific OIDs in the SSL library.
* LibreSSL needs it; not sure about OpenSSL.
}
static int
-handle_args(int argc, char **argv, struct rpki_config *config)
+parse_max_depth(struct rpki_config *config, char *str)
+{
+ /*
+ * It cannot be UINT_MAX, because then the actual number will overflow
+ * and will never be bigger than this.
+ */
+ const unsigned int MAX = UINT_MAX - 1;
+ unsigned long max_depth;
+
+ errno = 0;
+ max_depth = strtoul(str, NULL, 10);
+ if (errno) {
+ return pr_errno(errno,
+ "'%s' is not an unsigned integer, or is too big (max: %u)",
+ str, MAX);
+ }
+
+ if (max_depth > MAX)
+ return pr_err("The number '%s' is too big (max: %u)", str, MAX);
+
+ config->maximum_certificate_depth = max_depth;
+ return 0;
+}
+
+static int
+handle_args(int argc, char **argv)
{
+ struct rpki_config config;
int opt, error = 0;
static struct option long_options[] = {
{0,0,0,}
};
- config->disable_rsync = false;
- config->shuffle_uris = false;
- config->local_repository = NULL;
- config->tal = NULL;
+ config.disable_rsync = false;
+ config.shuffle_uris = false;
+ config.local_repository = NULL;
+ config.tal = NULL;
+ config.maximum_certificate_depth = 32;
- while ((opt = getopt_long(argc, argv, "t:l:rs", long_options, NULL))
+ while ((opt = getopt_long(argc, argv, "t:l:rsm:", long_options, NULL))
!= -1) {
switch (opt) {
case 't' :
- config->tal = optarg;
+ config.tal = optarg;
break;
case 'l' :
- config->local_repository = optarg;
+ config.local_repository = optarg;
break;
case 'r':
- config->disable_rsync = true;
+ config.disable_rsync = true;
break;
case 's':
- config->shuffle_uris = true;
+ config.shuffle_uris = true;
+ break;
+ case 'm':
+ error = parse_max_depth(&config, optarg);
break;
default:
return pr_err("some usage hints.");/* TODO */
}
}
- if (config->tal == NULL) {
+ if (config.tal == NULL) {
fprintf(stderr, "Missing flag --tal <file>\n");
error = -EINVAL;
}
- if(config->local_repository == NULL) {
+ if (config.local_repository == NULL) {
fprintf(stderr, "Missing flag --local_repository <dir>\n");
error = -EINVAL;
}
- pr_debug("TAL file : %s", config->tal);
- pr_debug("Local repository : %s", config->local_repository);
- pr_debug("Disable rsync : %s", config->disable_rsync
+ pr_debug("TAL file : %s", config.tal);
+ pr_debug("Local repository : %s", config.local_repository);
+ pr_debug("Disable rsync : %s", config.disable_rsync
? "true" : "false");
- pr_debug("shuffle uris : %s", config->shuffle_uris
+ pr_debug("shuffle uris : %s", config.shuffle_uris
? "true" : "false");
+ pr_debug("Maximum certificate depth : %u",
+ config.maximum_certificate_depth);
+ if (!error)
+ config_set(&config);
return error;
}
int
main(int argc, char **argv)
{
- struct rpki_config config;
struct tal *tal;
int error;
- error = handle_args(argc, argv, &config);
+ error = handle_args(argc, argv);
if (error)
return error;
print_stack_trace_on_segfault();
- error = rsync_init(!config.disable_rsync);
+ error = rsync_init();
if (error)
return error;
add_rpki_oids();
thvar_init();
fnstack_store();
- fnstack_push(config.tal);
-
- repository = config.local_repository;
- repository_len = strlen(repository);
+ fnstack_push(config_get_tal());
- error = tal_load(config.tal, &tal);
+ error = tal_load(config_get_tal(), &tal);
if (!error) {
- if (config.shuffle_uris)
+ if (config_get_shuffle_uris())
tal_shuffle_uris(tal);
error = foreach_uri(tal, handle_tal_uri);
error = (error >= 0) ? 0 : error;
#include <libcmscodec/IPAddrBlocks.h>
#include "common.h"
+#include "config.h"
#include "log.h"
#include "manifest.h"
#include "thread_var.h"
struct rpp *pp;
int error;
+ state = state_retrieve();
+ if (state == NULL)
+ return -EINVAL;
+ if (sk_X509_num(validation_certs(state)) >= config_get_max_cert_depth())
+ return pr_err("Certificate chain maximum depth exceeded.");
+
pr_debug_add("%s Certificate %s {", is_ta ? "TA" : "CA",
cert_uri->global);
fnstack_push(cert_uri->global);
goto end3;
/* -- Validate the manifest (@mft) pointed by the certificate -- */
- state = state_retrieve();
- if (state == NULL) {
- error = -EINVAL;
- goto end3;
- }
error = validation_push_cert(state, cert_uri, cert, is_ta);
if (error)
goto end3;
return pr_crit("ipAddrBlocks array is NULL.");
for (b = 0; b < roa->ipAddrBlocks.list.count; b++) {
- block = roa->ipAddrBlocks.list.array[0];
+ block = roa->ipAddrBlocks.list.array[b];
if (block == NULL)
return pr_err("Address block array element is NULL.");
#include <unistd.h>
#include "common.h"
+#include "config.h"
#include "log.h"
struct uri {
SLIST_HEAD(uri_list, uri);
static struct uri_list *rsync_uris;
-static bool execute_rsync = true;
static char const *const RSYNC_PREFIX = "rsync://";
//static const char *rsync_command[] = {"rsync", "--recursive", "--delete", "--times", NULL};
int
-rsync_init(bool is_rsync_active)
+rsync_init(void)
{
/* Disabling rsync will forever be a useful debugging feature. */
- if (!is_rsync_active) {
- execute_rsync = is_rsync_active;
+ if (config_get_disable_rsync())
return 0;
- }
rsync_uris = malloc(sizeof(struct uri_list));
if (rsync_uris == NULL)
{
struct uri *uri;
- if (!execute_rsync)
+ if (config_get_disable_rsync())
return;
while (!SLIST_EMPTY(rsync_uris)) {
static int
create_dir_recursive(char *localuri)
{
+ size_t repository_len;
int i, error;
bool exist = false;
if (exist)
return 0;
+ repository_len = strlen(config_get_local_repository());
for (i = 1 + repository_len; localuri[i] != '\0'; i++) {
if (localuri[i] == '/') {
localuri[i] = '\0';
prefix_len = strlen(RSYNC_PREFIX);
- if (!execute_rsync)
+ if (config_get_disable_rsync())
return 0;
if (uri->global_len < prefix_len ||
#include "uri.h"
int download_files(struct rpki_uri const *);
-int rsync_init(bool);
+int rsync_init(void);
void rsync_destroy(void);
#include "uri.h"
#include "common.h"
+#include "config.h"
#include "log.h"
/**
g2l(char const *global, size_t global_len, char **result)
{
static char const *const PREFIX = "rsync://";
+ char const *repository;
char *local;
size_t prefix_len;
+ size_t repository_len;
size_t extra_slash;
size_t offset;
+ repository = config_get_local_repository();
+ repository_len = strlen(repository);
prefix_len = strlen(PREFIX);
if (global_len < prefix_len