-/* $OpenBSD: cert.c,v 1.110 2023/06/23 07:26:21 tb Exp $ */
+/* $OpenBSD: cert.c,v 1.111 2023/06/23 07:40:28 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2021 Job Snijders <job@openbsd.org>
{
const unsigned char *oder;
int extsz;
- int sia_present = 0;
size_t i;
X509 *x = NULL;
X509_EXTENSION *ext = NULL;
ASN1_OBJECT *obj;
EVP_PKEY *pkey;
struct parse p;
- int nid;
+ int nid, ip, as, sia, cp, crldp, aia, aki, ski,
+ eku, bc, ku;
+
+ nid = ip = as = sia = cp = crldp = aia = aki = ski = eku = bc = ku = 0;
/* just fail for empty buffers, the warning was printed elsewhere */
if (der == NULL)
obj = X509_EXTENSION_get_object(ext);
assert(obj != NULL);
- switch (OBJ_obj2nid(obj)) {
+ switch ((nid = OBJ_obj2nid(obj))) {
case NID_sbgp_ipAddrBlock:
+ if (ip++ >= 1)
+ goto dup;
if (!sbgp_ipaddrblk(&p, ext))
goto out;
break;
case NID_sbgp_autonomousSysNum:
+ if (as++ > 0)
+ goto dup;
if (!sbgp_assysnum(&p, ext))
goto out;
break;
case NID_sinfo_access:
- sia_present = 1;
+ if (sia++ > 0)
+ goto dup;
if (!sbgp_sia(&p, ext))
goto out;
break;
case NID_certificate_policies:
+ if (cp++ > 0)
+ goto dup;
if (!certificate_policies(&p, ext))
goto out;
break;
case NID_crl_distribution_points:
- /* ignored here, handled later */
+ if (crldp++ > 0)
+ goto dup;
break;
case NID_info_access:
+ if (aia++ > 0)
+ goto dup;
break;
case NID_authority_key_identifier:
+ if (aki++ > 0)
+ goto dup;
break;
case NID_subject_key_identifier:
+ if (ski++ > 0)
+ goto dup;
break;
case NID_ext_key_usage:
+ if (eku++ > 0)
+ goto dup;
break;
case NID_basic_constraints:
+ if (bc++ > 0)
+ goto dup;
break;
case NID_key_usage:
+ if (ku++ > 0)
+ goto dup;
break;
default:
/* unexpected extensions warrant investigation */
goto out;
}
}
- if (sia_present) {
+ if (sia) {
warnx("%s: unexpected SIA extension in BGPsec cert",
p.fn);
goto out;
p.res->x509 = x;
return p.res;
-out:
+ dup:
+ warnx("%s: RFC 5280 section 4.2: duplicate %s extension", fn,
+ OBJ_nid2sn(nid));
+ out:
cert_free(p.res);
X509_free(x);
return NULL;