-/* $OpenBSD: x509.c,v 1.92 2024/06/04 04:17:18 tb Exp $ */
+/* $OpenBSD: x509.c,v 1.93 2024/06/04 14:17:24 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <assert.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
* (which has to be freed after use).
*/
int
-x509_get_aia(X509 *x, const char *fn, char **aia)
+x509_get_aia(X509 *x, const char *fn, char **out_aia)
{
ACCESS_DESCRIPTION *ad;
AUTHORITY_INFO_ACCESS *info;
int crit, rc = 0;
- *aia = NULL;
+ assert(*out_aia == NULL);
+
info = X509_get_ext_d2i(x, NID_info_access, &crit, NULL);
if (info == NULL) {
if (crit != -1) {
goto out;
}
- if (!x509_location(fn, "AIA: caIssuers", ad->location, aia))
+ if (!x509_location(fn, "AIA: caIssuers", ad->location, out_aia))
goto out;
rc = 1;
-out:
+ out:
AUTHORITY_INFO_ACCESS_free(info);
return rc;
}
* (which has to be freed after use).
*/
int
-x509_get_sia(X509 *x, const char *fn, char **sia)
+x509_get_sia(X509 *x, const char *fn, char **out_sia)
{
ACCESS_DESCRIPTION *ad;
AUTHORITY_INFO_ACCESS *info;
ASN1_OBJECT *oid;
- int i, crit, rsync_found = 0;
+ int i, crit, rc = 0;
- *sia = NULL;
+ assert(*out_sia == NULL);
info = X509_get_ext_d2i(x, NID_sinfo_access, &crit, NULL);
if (info == NULL) {
}
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
+ char *sia;
+
ad = sk_ACCESS_DESCRIPTION_value(info, i);
oid = ad->method;
goto out;
}
- if (!x509_location(fn, "SIA: signedObject", ad->location, sia))
+ sia = NULL;
+ if (!x509_location(fn, "SIA: signedObject", ad->location, &sia))
goto out;
- if (rsync_found)
- continue;
-
- if (strncasecmp(*sia, RSYNC_PROTO, RSYNC_PROTO_LEN) == 0) {
- const char *p = *sia + RSYNC_PROTO_LEN;
+ if (*out_sia == NULL && strncasecmp(sia, RSYNC_PROTO,
+ RSYNC_PROTO_LEN) == 0) {
+ const char *p = sia + RSYNC_PROTO_LEN;
size_t fnlen, plen;
- rsync_found = 1;
-
- if (filemode)
+ if (filemode) {
+ *out_sia = sia;
continue;
+ }
fnlen = strlen(fn);
plen = strlen(p);
if (fnlen < plen || strcmp(p, fn + fnlen - plen) != 0) {
warnx("%s: mismatch between pathname and SIA "
- "(%s)", fn, *sia);
+ "(%s)", fn, sia);
+ free(sia);
goto out;
}
+ *out_sia = sia;
continue;
}
-
- free(*sia);
- *sia = NULL;
+ if (verbose)
+ warnx("%s: RFC 6487 section 4.8.8: SIA: "
+ "ignoring location %s", fn, sia);
+ free(sia);
}
- if (!rsync_found) {
+ if (*out_sia == NULL) {
warnx("%s: RFC 6487 section 4.8.8.2: "
"SIA without rsync accessLocation", fn);
goto out;
}
- AUTHORITY_INFO_ACCESS_free(info);
- return 1;
+ rc = 1;
out:
- free(*sia);
- *sia = NULL;
AUTHORITY_INFO_ACCESS_free(info);
- return 0;
+ return rc;
}
/*
* after use.
*/
int
-x509_get_crl(X509 *x, const char *fn, char **crl)
+x509_get_crl(X509 *x, const char *fn, char **out_crl)
{
CRL_DIST_POINTS *crldp;
DIST_POINT *dp;
GENERAL_NAMES *names;
GENERAL_NAME *name;
- int i, crit, rsync_found = 0;
+ int i, crit, rc = 0;
+
+ assert(*out_crl == NULL);
- *crl = NULL;
crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &crit, NULL);
if (crldp == NULL) {
if (crit != -1) {
names = dp->distpoint->name.fullname;
for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
+ char *crl = NULL;
+
name = sk_GENERAL_NAME_value(names, i);
- if (!x509_location(fn, "CRL distribution point", name, crl))
+ if (!x509_location(fn, "CRL distribution point", name, &crl))
goto out;
- if (strncasecmp(*crl, RSYNC_PROTO, RSYNC_PROTO_LEN) == 0) {
- rsync_found = 1;
- goto out;
+ if (*out_crl == NULL && strncasecmp(crl, RSYNC_PROTO,
+ RSYNC_PROTO_LEN) == 0) {
+ *out_crl = crl;
+ continue;
}
+ if (verbose)
+ warnx("%s: ignoring CRL distribution point %s",
+ fn, crl);
+ free(crl);
+ }
- free(*crl);
- *crl = NULL;
+ if (*out_crl == NULL) {
+ warnx("%s: RFC 6487 section 4.8.6: no rsync URI "
+ "in CRL distributionPoint", fn);
+ goto out;
}
- warnx("%s: RFC 6487 section 4.8.6: no rsync URI "
- "in CRL distributionPoint", fn);
+ rc = 1;
out:
CRL_DIST_POINTS_free(crldp);
- return rsync_found;
+ return rc;
}
/*
{
ASN1_IA5STRING *uri;
+ assert(*out == NULL);
+
if (location->type != GEN_URI) {
warnx("%s: RFC 6487 section 4.8: %s not URI", fn, descr);
return 0;
return 0;
}
- if (*out != NULL) {
- warnx("%s: RFC 6487 section 4.8: multiple %s specified, "
- "using the first one", fn, descr);
- return 1;
- }
-
if ((*out = strndup(uri->data, uri->length)) == NULL)
err(1, NULL);