aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2008-06-19 18:55:10 +0000
committerRob Austein <sra@hactrn.net>2008-06-19 18:55:10 +0000
commitefe50ba9189d99975a36741c3d70a13fc6f0a60c (patch)
tree3f7cfd2a92355d4d2f9c65182914d16379766e0a
parent867a4803f1e63f6aba5c274df40f8309615af710 (diff)
Checkpoint
svn path=/rcynic/rcynic.c; revision=1905
-rw-r--r--rcynic/rcynic.c112
1 files changed, 83 insertions, 29 deletions
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c
index 8bf93381..69b1f2a2 100644
--- a/rcynic/rcynic.c
+++ b/rcynic/rcynic.c
@@ -1247,6 +1247,8 @@ static void parse_cert(X509 *x, certinfo_t *c, const char *uri)
c->ca = X509_check_ca(x) == 1;
+ if (uri == NULL)
+ uri = "";
assert(strlen(uri) < sizeof(c->uri));
strcpy(c->uri, uri);
@@ -1341,44 +1343,90 @@ 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,
+static int check_x509_cb(int ok, X509_STORE_CTX *ctx);
+
+static Manifest *check_manifest_1(const rcynic_ctx_t *rc,
+ const char *uri,
+ char *path,
+ const int pathlen,
const char *prefix,
- STACK_OF(X509) *certs)
+ STACK_OF(X509) *certs,
+ X509_CRL *crl)
{
CMS_ContentInfo *cms = NULL;
STACK_OF(X509) *signers = NULL;
STACK_OF(X509_CRL) *crls = NULL;
- Manifest *result = NULL;
+ Manifest *manifest = NULL, *result = NULL;
+ BIO *bio = NULL;
+ rcynic_x509_store_ctx_t rctx;
+ certinfo_t certinfo;
- assert(uri && path && certs);
+ assert(rc && uri && path && prefix && certs);
- if (!uri_to_filename(uri, path, pathlen, prefix) ||
+ if (!uri_to_filename(uri, path, pathlen, prefix) ||
(cms = read_cms(path, NULL, 0)) == NULL)
- goto done;
+ goto done1;
- 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;
+ if ((signers = CMS_get0_signers(cms)) == NULL || sk_X509_num(signers) != 1)
+ goto done1;
+
+ if ((crls = sk_X509_CRL_new_null()) == NULL || !sk_X509_CRL_push(crls, crl))
+ goto done1;
+
+ if (!X509_STORE_CTX_init(&rctx.ctx, rc->x509_store, sk_X509_value(signers, 0), NULL))
+ goto done1;
+
+ parse_cert(sk_X509_value(signers, 0), &certinfo, NULL);
+
+ rctx.rc = rc;
+ rctx.subj = &certinfo;
+
+ X509_STORE_CTX_trusted_stack(&rctx.ctx, certs);
+ X509_STORE_CTX_set0_crls(&rctx.ctx, crls);
+ X509_STORE_CTX_set_verify_cb(&rctx.ctx, check_x509_cb);
+
+ X509_VERIFY_PARAM_set_flags(rctx.ctx.param,
+ X509_V_FLAG_CRL_CHECK |
+ X509_V_FLAG_POLICY_CHECK |
+ X509_V_FLAG_EXPLICIT_POLICY |
+ X509_V_FLAG_X509_STRICT);
+
+ X509_VERIFY_PARAM_add0_policy(rctx.ctx.param,
+ /* {0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0xe, 0x2} */
+ OBJ_txt2obj("1.3.6.1.5.5.7.14.2", 0));
+
+ if (X509_verify_cert(&rctx.ctx) <= 0) {
+ logmsg(rc, log_data_err, "Validation failure for CMS EE certificate");
+ goto done2;
+ }
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ goto done2;
+
+ if (CMS_verify(cms, NULL, NULL, NULL, bio, CMS_NO_SIGNER_CERT_VERIFY) <= 0) {
+ logmsg(rc, log_data_err, "Validation failure for CMS message");
+ goto done2;
+ }
+
+ if ((manifest = ASN1_item_d2i_bio(ASN1_ITEM_rptr(Manifest), bio, NULL)) == NULL) {
+ logmsg(rc, log_data_err, "Failure decoding manifest");
+ goto done2;
+ }
/*
- * 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.
+ * Still need to check manifest internals for sanity (dates, etc).
*/
- done:
+ done2:
+ X509_STORE_CTX_cleanup(&rctx.ctx);
+ BIO_free(bio);
+
+ done1:
CMS_ContentInfo_free(cms);
sk_X509_free(signers);
sk_X509_CRL_free(crls);
@@ -1388,21 +1436,29 @@ static Manifest *check_manifest_1(const char *uri,
static Manifest *check_manifest(const rcynic_ctx_t *rc,
const char *uri,
- STACK_OF(X509) *certs)
+ STACK_OF(X509) *certs,
+ X509_CRL *crl)
{
char path[FILENAME_MAX];
Manifest *manifest;
+#if 0
+ /*
+ * This snippet should just read a manifest that's already been
+ * checked, without verifying it. We could write such a function,
+ * but let's see if we need it first....
+ */
if (uri_to_filename(uri, path, sizeof(path), rc->authenticated) &&
(manifest = read_manifest(path, NULL, 0)) != NULL)
return manifest;
+#endif
logmsg(rc, log_telemetry, "Checking manifest %s", uri);
rsync_manifest(rc, uri);
- if ((manifest = check_manifest_1(uri, path, sizeof(path),
- rc->unauthenticated, certs))) {
+ if ((manifest = check_manifest_1(rc, uri, path, sizeof(path),
+ rc->unauthenticated, certs, crl))) {
install_object(rc, uri, path, 5);
mib_increment(rc, uri, current_manifest_accepted);
return manifest;
@@ -1410,8 +1466,8 @@ static Manifest *check_manifest(const rcynic_ctx_t *rc,
mib_increment(rc, uri, current_manifest_rejected);
}
- if ((manifest = check_manifest_1(uri, path, sizeof(path),
- rc->old_authenticated, certs))) {
+ if ((manifest = check_manifest_1(rc, uri, path, sizeof(path),
+ rc->old_authenticated, certs, crl))) {
install_object(rc, uri, path, 5);
mib_increment(rc, uri, backup_manifest_accepted);
return manifest;
@@ -1422,8 +1478,6 @@ static Manifest *check_manifest(const rcynic_ctx_t *rc,
return NULL;
}
-#endif
-
/*
@@ -1431,7 +1485,7 @@ static Manifest *check_manifest(const rcynic_ctx_t *rc,
* and checks for conformance to the RPKI certificate profile.
*/
-static int check_cert_cb(int ok, X509_STORE_CTX *ctx)
+static int check_x509_cb(int ok, X509_STORE_CTX *ctx)
{
rcynic_x509_store_ctx_t *rctx = (rcynic_x509_store_ctx_t *) ctx;
@@ -1535,7 +1589,7 @@ static int check_x509(const rcynic_ctx_t *rc,
X509_STORE_CTX_trusted_stack(&rctx.ctx, certs);
X509_STORE_CTX_set0_crls(&rctx.ctx, crls);
- X509_STORE_CTX_set_verify_cb(&rctx.ctx, check_cert_cb);
+ X509_STORE_CTX_set_verify_cb(&rctx.ctx, check_x509_cb);
X509_VERIFY_PARAM_set_flags(rctx.ctx.param,
X509_V_FLAG_CRL_CHECK |