aboutsummaryrefslogtreecommitdiff
path: root/rcynic/rcynic.c
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2008-06-19 02:54:04 +0000
committerRob Austein <sra@hactrn.net>2008-06-19 02:54:04 +0000
commit867a4803f1e63f6aba5c274df40f8309615af710 (patch)
tree97c1d870f190a0c66c4cca98beb9d4fa4404f9a6 /rcynic/rcynic.c
parent61ee561f87ed1e6d8072859e79cd5d46b15a826f (diff)
Checkpoint
svn path=/rcynic/rcynic.c; revision=1904
Diffstat (limited to 'rcynic/rcynic.c')
-rw-r--r--rcynic/rcynic.c101
1 files changed, 100 insertions, 1 deletions
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c
index 3f150b3e..8bf93381 100644
--- a/rcynic/rcynic.c
+++ b/rcynic/rcynic.c
@@ -155,6 +155,10 @@ static const struct {
QQ(current_cert_rejected, "Current certificates rejected") \
QQ(current_crl_accepted, "Current CRLs accepted") \
QQ(current_crl_rejected, "Current CRLs rejected") \
+ QQ(current_manifest_accepted, "Current Manifests accepted") \
+ QQ(current_manifest_rejected, "Current Manifests rejected") \
+ QQ(backup_manifest_accepted, "Backup Manifests accepted") \
+ QQ(backup_manifest_rejected, "Backup Manifests rejected") \
QQ(rsync_failed, "rsync transfers failed") \
QQ(rsync_succeeded, "rsync transfers succeeded") \
QQ(rsync_timed_out, "rsync transfers timed out") \
@@ -256,7 +260,6 @@ ASN1_SEQUENCE(FileAndHash) = {
} ASN1_SEQUENCE_END(FileAndHash)
DECLARE_STACK_OF(FileAndHash)
-DECLARE_ASN1_FUNCTIONS(FileAndHash)
#define sk_FileAndHash_num(st) SKM_sk_num(FileAndHash, (st))
#define sk_FileAndHash_value(st, i) SKM_sk_value(FileAndHash, (st), (i))
@@ -277,6 +280,12 @@ ASN1_SEQUENCE(Manifest) = {
ASN1_SEQUENCE_OF(Manifest, fileList, FileAndHash)
} ASN1_SEQUENCE_END(Manifest)
+DECLARE_ASN1_FUNCTIONS(FileAndHash)
+DECLARE_ASN1_FUNCTIONS(Manifest)
+
+IMPLEMENT_ASN1_FUNCTIONS(FileAndHash)
+IMPLEMENT_ASN1_FUNCTIONS(Manifest)
+
/*
@@ -1000,6 +1009,11 @@ static int rsync_crl(const rcynic_ctx_t *rc, const char *uri)
return rsync(rc, NULL, uri);
}
+static int rsync_manifest(const rcynic_ctx_t *rc, const char *uri)
+{
+ return rsync(rc, NULL, uri);
+}
+
static int rsync_sia(const rcynic_ctx_t *rc, const char *uri)
{
static const char * const rsync_args[] = { "--recursive", "--delete", NULL };
@@ -1327,6 +1341,91 @@ static X509_CRL *check_crl(const rcynic_ctx_t *rc,
+#if 0
+
+/*
+ * Check whether we already have a particular manifest, attempt to fetch it
+ * and check issuer's signature if we don't.
+ */
+
+static Manifest *check_manifest_1(const char *uri,
+ char *path, const int pathlen,
+ const char *prefix,
+ STACK_OF(X509) *certs)
+{
+ CMS_ContentInfo *cms = NULL;
+ STACK_OF(X509) *signers = NULL;
+ STACK_OF(X509_CRL) *crls = NULL;
+ Manifest *result = NULL;
+
+ assert(uri && path && certs);
+
+ if (!uri_to_filename(uri, path, pathlen, prefix) ||
+ (cms = read_cms(path, NULL, 0)) == NULL)
+ goto done;
+
+ if ((signers = CMS_get0_signers(cms)) == NULL || sk_X509_num(signers) != 1 ||
+ (crls = CMS_get0_crls(cms)) == NULL || sk_X509_CRL_num(crls) != 1)
+ goto done;
+
+ /*
+ * Here we have to check the CMS message, extract the manifest from
+ * the eContent, and check the manifest. Unfortunately, the CMS
+ * code wants to receive an X509_STORE, which interferes with the
+ * games we play with a X509_STORE_CTX in check_x509(). This may
+ * require us to disable CMS_verify()'s certificate checking and do
+ * that part of the job ourselves, which, in turn, may require
+ * refactoring to avoid duplicating most of check_x509(). Sigh.
+ */
+
+ done:
+ CMS_ContentInfo_free(cms);
+ sk_X509_free(signers);
+ sk_X509_CRL_free(crls);
+
+ return result;
+}
+
+static Manifest *check_manifest(const rcynic_ctx_t *rc,
+ const char *uri,
+ STACK_OF(X509) *certs)
+{
+ char path[FILENAME_MAX];
+ Manifest *manifest;
+
+ if (uri_to_filename(uri, path, sizeof(path), rc->authenticated) &&
+ (manifest = read_manifest(path, NULL, 0)) != NULL)
+ return manifest;
+
+ logmsg(rc, log_telemetry, "Checking manifest %s", uri);
+
+ rsync_manifest(rc, uri);
+
+ if ((manifest = check_manifest_1(uri, path, sizeof(path),
+ rc->unauthenticated, certs))) {
+ install_object(rc, uri, path, 5);
+ mib_increment(rc, uri, current_manifest_accepted);
+ return manifest;
+ } else if (!access(path, F_OK)) {
+ mib_increment(rc, uri, current_manifest_rejected);
+ }
+
+ if ((manifest = check_manifest_1(uri, path, sizeof(path),
+ rc->old_authenticated, certs))) {
+ install_object(rc, uri, path, 5);
+ mib_increment(rc, uri, backup_manifest_accepted);
+ return manifest;
+ } else if (!access(path, F_OK)) {
+ mib_increment(rc, uri, backup_manifest_rejected);
+ }
+
+ return NULL;
+}
+
+#endif
+
+
+
/*
* Check a certificate, including all the crypto, path validation,
* and checks for conformance to the RPKI certificate profile.