aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rcynic/rcynic.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c
index 9f145218..3cdd2190 100644
--- a/rcynic/rcynic.c
+++ b/rcynic/rcynic.c
@@ -612,6 +612,10 @@ static int NID_ct_rpkiGhostbusters;
static int NID_cp_ipAddr_asNumber;
#endif
+#ifndef NID_id_kp_bgpsec_router
+static int NID_id_kp_bgpsec_router;
+#endif
+
/**
* Missing NIDs, if any.
*/
@@ -643,7 +647,11 @@ static const struct {
#endif
#ifndef NID_cp_ipAddr_asNumber
- {&NID_cp_ipAddr_asNumber, "1.3.6.1.5.5.7.14.2", "id-cp-ipAddr-asNumber", "RPKI Certificate Policy"}
+ {&NID_cp_ipAddr_asNumber, "1.3.6.1.5.5.7.14.2", "id-cp-ipAddr-asNumber", "RPKI Certificate Policy"},
+#endif
+
+#ifndef NID_id_kp_bgpsec_router
+ {&NID_id_kp_bgpsec_router, "1.3.6.1.5.5.7.3.30", "id-kp-bgpsec-router", "BGPSEC Router Certificate"},
#endif
};
@@ -3603,10 +3611,11 @@ static int check_x509(rcynic_ctx_t *rc,
STACK_OF(POLICYINFO) *policies = NULL;
ASN1_BIT_STRING *ski_pubkey = NULL;
STACK_OF(DIST_POINT) *crldp = NULL;
+ EXTENDED_KEY_USAGE *eku = NULL;
BASIC_CONSTRAINTS *bc = NULL;
hashbuf_t ski_hashbuf;
unsigned ski_hashlen, afi;
- int i, ok, crit, loc, ex_count, ret = 0;
+ int i, ok, crit, loc, ex_count, routercert = 0, ret = 0;
assert(rc && wsk && w && uri && x && w->cert);
@@ -3704,6 +3713,16 @@ static int check_x509(rcynic_ctx_t *rc,
goto done;
}
+ if ((eku = X509_get_ext_d2i(x, NID_ext_key_usage, &crit, NULL)) != NULL) {
+ ex_count--;
+ if (crit || certinfo->ca || !endswith(uri->s, ".cer") || sk_ASN1_OBJECT_num(eku) == 0) {
+ log_validation_status(rc, uri, inappropriate_eku_extension, generation);
+ goto done;
+ }
+ for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++)
+ routercert |= OBJ_obj2nid(sk_ASN1_OBJECT_value(eku, i)) == NID_id_kp_bgpsec_router;
+ }
+
if ((sia = X509_get_ext_d2i(x, NID_sinfo_access, NULL, NULL)) != NULL) {
int got_caDirectory, got_rpkiManifest, got_signedObject;
int n_caDirectory = 0, n_rpkiManifest = 0, n_signedObject = 0;
@@ -3731,7 +3750,7 @@ static int check_x509(rcynic_ctx_t *rc,
} else if (certinfo->ca || !rc->allow_ee_without_signedObject) {
log_validation_status(rc, uri, sia_extension_missing, generation);
goto done;
- } else {
+ } else if (!routercert) {
log_validation_status(rc, uri, sia_extension_missing_from_ee, generation);
}
@@ -3829,14 +3848,6 @@ static int check_x509(rcynic_ctx_t *rc,
}
ex_count--;
- if (X509_get_ext_by_NID(x, NID_ext_key_usage, -1) >= 0) {
- ex_count--;
- if (certinfo->ca || !endswith(uri->s, ".cer")) {
- log_validation_status(rc, uri, inappropriate_eku_extension, generation);
- goto done;
- }
- }
-
if (x->rfc3779_addr) {
ex_count--;
if ((loc = X509_get_ext_by_NID(x, NID_sbgp_ipAddrBlock, -1)) < 0 ||
@@ -3898,8 +3909,8 @@ static int check_x509(rcynic_ctx_t *rc,
ok = BN_num_bits(subject_pkey->pkey.rsa->n) == 2048;
break;
- case NID_X9_62_id_ecPublicKey: /* See draft-ietf-sidr-bgpsec-algs */
- ok = !certinfo->ca; /* All I know how to test for now */
+ case NID_X9_62_id_ecPublicKey:
+ ok = !certinfo->ca && routercert;
break;
default:
@@ -4026,6 +4037,7 @@ static int check_x509(rcynic_ctx_t *rc,
sk_ACCESS_DESCRIPTION_pop_free(aia, ACCESS_DESCRIPTION_free);
sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
+ sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
return ret;
}