aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rcynic/rcynic.c106
1 files changed, 77 insertions, 29 deletions
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c
index 588e94cd..b4dcb340 100644
--- a/rcynic/rcynic.c
+++ b/rcynic/rcynic.c
@@ -2427,7 +2427,7 @@ int main(int argc, char *argv[])
{
int opt_jitter = 0, use_syslog = 0, use_stderr = 0, syslog_facility = 0;
int opt_syslog = 0, opt_stderr = 0, opt_level = 0, prune = 1;
- char *cfg_file = "rcynic.conf", path[FILENAME_MAX];
+ char *cfg_file = "rcynic.conf";
char *lockfile = NULL, *xmlfile = NULL;
int c, i, j, ret = 1, jitter = 600, lockfd = -1;
STACK_OF(CONF_VALUE) *cfg_section = NULL;
@@ -2682,47 +2682,95 @@ int main(int argc, char *argv[])
for (i = 0; i < sk_CONF_VALUE_num(cfg_section); i++) {
CONF_VALUE *val = sk_CONF_VALUE_value(cfg_section, i);
+ char path1[FILENAME_MAX], path2[FILENAME_MAX];
certinfo_t ta_info;
- X509 *x;
+ X509 *x = NULL;
assert(val && val->name && val->value);
- if (name_cmp(val->name, "trust-anchor"))
- continue;
-
- logmsg(&rc, log_telemetry, "Processing trust anchor %s", val->value);
-
- if ((x = read_cert(val->value, NULL, 0)) == NULL) {
- logmsg(&rc, log_usage_err, "Couldn't read trust anchor %s", val->value);
- goto done;
+ if (!name_cmp(val->name, "trust-anchor")) {
+ /*
+ * Old local file trust anchor method.
+ */
+ logmsg(&rc, log_telemetry, "Processing trust anchor from local file %s", val->value);
+ if (strlen(val->value) >= sizeof(path1)) {
+ logmsg(&rc, log_usage_err, "Trust anchor path name too long %s", val->value);
+ goto done;
+ }
+ strcpy(path1, val->value);
+ if ((x = read_cert(path1, NULL, 0)) == NULL) {
+ logmsg(&rc, log_usage_err, "Couldn't read trust anchor %s", path1);
+ goto done;
+ }
+ hash = X509_subject_name_hash(x);
+ for (j = 0; j < INT_MAX; j++) {
+ if (snprintf(path2, sizeof(path2), "%s%lx.%d.cer",
+ rc.authenticated, hash, j) == sizeof(path2)) {
+ logmsg(&rc, log_sys_err,
+ "Couldn't construct path name for trust anchor %s", path1);
+ goto done;
+ }
+ if (access(path2, F_OK))
+ break;
+ }
+ if (j == INT_MAX) {
+ logmsg(&rc, log_sys_err, "Couldn't find a free name for trust anchor %s", path1);
+ goto done;
+ }
}
- hash = X509_subject_name_hash(x);
-
- for (j = 0; j < INT_MAX; j++) {
- if (snprintf(path, sizeof(path), "%s%lx.%d.cer",
- rc.authenticated, hash, j) == sizeof(path)) {
- logmsg(&rc, log_sys_err,
- "Couldn't construct path name for trust anchor %s", val->value);
+ if (!name_cmp(val->name, "trust-anchor-uri-with-key")) {
+ /*
+ * Newfangled URI + public key method.
+ */
+ EVP_PKEY *pkey = NULL, *xpkey = NULL;
+ char uri[URI_MAX];
+ BIO *bio = NULL;
+
+ j = strcspn(val->value, " \t");
+ if (j >= sizeof(uri)) {
+ logmsg(&rc, log_usage_err, "Trust anchor URI too long %s", val->value);
+ goto done;
+ }
+ memcpy(uri, val->value, j);
+ uri[j] = '\0';
+ if (!uri_to_filename(uri, path1, sizeof(path1), rc.unauthenticated)) {
+ logmsg(&rc, log_usage_err, "Couldn't convert trust anchor URI %s to filename", uri);
+ goto done;
+ }
+ logmsg(&rc, log_telemetry, "Processing trust anchor from URI %s", uri);
+ rsync_file(&rc, uri);
+ j += strspn(val->value + j, " \t");
+ bio = BIO_new_file(val->value + j, "rb");
+ if (bio)
+ pkey = d2i_PUBKEY_bio(bio, NULL);
+ BIO_free(bio);
+ if (!pkey) {
+ logmsg(&rc, log_usage_err, "Couldn't read trust anchor public key for %s from %s", uri, val->value + j);
+ goto done;
+ }
+ if ((x = read_cert(path1, NULL, 0)) == NULL)
+ logmsg(&rc, log_data_err, "Couldn't read trust anchor %s", path1);
+ if (x && (xpkey = X509_get_pubkey(x)) == NULL)
+ logmsg(&rc, log_data_err, "Couldn't read public key from trust anchor %s", uri);
+ j = (xpkey && !EVP_PKEY_cmp(pkey, xpkey));
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(xpkey);
+ if (!j) {
+ logmsg(&rc, log_data_err, "Public key did not match trust anchor %s", uri);
goto done;
}
- if (access(path, F_OK))
- break;
}
- if (j == INT_MAX) {
- logmsg(&rc, log_sys_err,
- "Couldn't find a free name for trust anchor %s", val->value);
- goto done;
- }
+ if (!x)
+ continue;
- logmsg(&rc, log_telemetry, "Copying trust anchor %s to %lx.%d.cer",
- val->value, hash, j);
+ logmsg(&rc, log_telemetry, "Copying trust anchor %s to %s", path1, path2);
if (!mkdir_maybe(&rc, rc.authenticated) ||
- !(rc.use_links ? ln(val->value, path) : cp(val->value, path))) {
+ !(rc.use_links ? ln(path1, path2) : cp(path1, path2))) {
logmsg(&rc, log_sys_err, "Couldn't %s trust anchor %s",
- (rc.use_links ? "link" : "copy"), val->value);
+ (rc.use_links ? "link" : "copy"), path1);
goto done;
}
@@ -2731,7 +2779,7 @@ int main(int argc, char *argv[])
sk_X509_push(certs, x);
if (ta_info.crldp[0] && !check_x509(&rc, certs, x, &ta_info)) {
- logmsg(&rc, log_data_err, "Couldn't get CRL for trust anchor %s", val->value);
+ logmsg(&rc, log_data_err, "Couldn't get CRL for trust anchor %s", path1);
} else {
walk_cert(&rc, &ta_info, certs);
}