sync with OpenBSD -current

This commit is contained in:
purplerain 2024-02-21 20:26:06 +00:00
parent 8cf0d7be7c
commit 5f8da13f08
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
27 changed files with 6870 additions and 401 deletions

View File

@ -581,6 +581,7 @@
./usr/include/dev/pci/if_lgereg.h
./usr/include/dev/pci/if_liireg.h
./usr/include/dev/pci/if_mskvar.h
./usr/include/dev/pci/if_mwxreg.h
./usr/include/dev/pci/if_myxreg.h
./usr/include/dev/pci/if_nfereg.h
./usr/include/dev/pci/if_nfevar.h

View File

@ -1,4 +1,4 @@
/* $OpenBSD: trap.c,v 1.104 2024/01/31 06:06:28 guenther Exp $ */
/* $OpenBSD: trap.c,v 1.105 2024/02/21 15:53:07 deraadt Exp $ */
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
/*-
@ -424,7 +424,7 @@ usertrap(struct trapframe *frame)
break;
case T_CP:
sig = SIGILL;
code = (frame->tf_err & 0x7fff) < 4 ? ILL_ILLOPC
code = (frame->tf_err & 0x7fff) < 4 ? ILL_BTCFI
: ILL_BADSTK;
break;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: trap.c,v 1.47 2023/12/26 09:19:15 kettenis Exp $ */
/* $OpenBSD: trap.c,v 1.48 2024/02/21 15:53:07 deraadt Exp $ */
/*-
* Copyright (c) 2014 Andrew Turner
* All rights reserved.
@ -286,7 +286,7 @@ do_el0_sync(struct trapframe *frame)
case EXCP_BRANCH_TGT:
curcpu()->ci_flush_bp();
sv.sival_ptr = (void *)frame->tf_elr;
trapsignal(p, SIGILL, esr, ILL_ILLOPC, sv);
trapsignal(p, SIGILL, esr, ILL_BTCFI, sv);
break;
case EXCP_FPAC:
curcpu()->ci_flush_bp();

View File

@ -1,4 +1,4 @@
/* $OpenBSD: qwxreg.h,v 1.6 2024/02/03 10:03:18 stsp Exp $ */
/* $OpenBSD: qwxreg.h,v 1.7 2024/02/21 14:40:50 kevlo Exp $ */
/*
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
@ -6927,11 +6927,6 @@ enum ath11k_qmi_bdf_type {
#define HAL_SHADOW_REG(sc, x) (HAL_SHADOW_BASE_ADDR(sc) + (4 * (x)))
/* SRNG registers are split into two groups R0 and R2 */
#define HAL_SRNG_REG_GRP_R0 0
#define HAL_SRNG_REG_GRP_R2 1
#define HAL_SRNG_NUM_REG_GRP 2
enum hal_srng_ring_id {
HAL_SRNG_RING_ID_REO2SW1 = 0,
HAL_SRNG_RING_ID_REO2SW2,

View File

@ -1,4 +1,4 @@
# $OpenBSD: files.pci,v 1.363 2023/12/28 17:36:29 stsp Exp $
# $OpenBSD: files.pci,v 1.364 2024/02/21 10:48:10 claudio Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@ -867,5 +867,10 @@ file dev/pci/if_ngbe.c ngbe
attach com at pci with com_pci
file dev/pci/com_pci.c com_pci
# MediaTek MT7921 / MT7922 wifi
device mwx: ifnet, wlan, firmload
attach mwx at pci
file dev/pci/if_mwx.c mwx
include "dev/pci/files.agp"
include "dev/pci/drm/files.drm"

5106
sys/dev/pci/if_mwx.c Normal file

File diff suppressed because it is too large Load Diff

1401
sys/dev/pci/if_mwxreg.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_mbuf.c,v 1.288 2023/10/20 16:25:15 bluhm Exp $ */
/* $OpenBSD: uipc_mbuf.c,v 1.289 2024/02/21 09:28:29 claudio Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@ -550,21 +550,24 @@ int
m_defrag(struct mbuf *m, int how)
{
struct mbuf *m0;
unsigned int adj;
if (m->m_next == NULL)
return (0);
KASSERT(m->m_flags & M_PKTHDR);
adj = mtod(m, unsigned long) & (sizeof(long) - 1);
if ((m0 = m_gethdr(how, m->m_type)) == NULL)
return (ENOBUFS);
if (m->m_pkthdr.len > MHLEN) {
MCLGETL(m0, how, m->m_pkthdr.len);
if (m->m_pkthdr.len + adj > MHLEN) {
MCLGETL(m0, how, m->m_pkthdr.len + adj);
if (!(m0->m_flags & M_EXT)) {
m_free(m0);
return (ENOBUFS);
}
}
m0->m_data += adj;
m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
@ -583,9 +586,9 @@ m_defrag(struct mbuf *m, int how)
memcpy(&m->m_ext, &m0->m_ext, sizeof(struct mbuf_ext));
MCLINITREFERENCE(m);
m->m_flags |= m0->m_flags & (M_EXT|M_EXTWR);
m->m_data = m->m_ext.ext_buf;
m->m_data = m->m_ext.ext_buf + adj;
} else {
m->m_data = m->m_pktdat;
m->m_data = m->m_pktdat + adj;
memcpy(m->m_data, m0->m_data, m0->m_len);
}
m->m_pkthdr.len = m->m_len = m0->m_len;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: mbuf.h,v 1.261 2023/07/16 03:01:31 yasuoka Exp $ */
/* $OpenBSD: mbuf.h,v 1.262 2024/02/21 13:42:06 bluhm Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
@ -234,7 +234,7 @@ struct mbuf {
("\20\1IPV4_CSUM_OUT\2TCP_CSUM_OUT\3UDP_CSUM_OUT\4IPV4_CSUM_IN_OK" \
"\5IPV4_CSUM_IN_BAD\6TCP_CSUM_IN_OK\7TCP_CSUM_IN_BAD\10UDP_CSUM_IN_OK" \
"\11UDP_CSUM_IN_BAD\12ICMP_CSUM_OUT\13ICMP_CSUM_IN_OK\14ICMP_CSUM_IN_BAD" \
"\15IPV6_NODF_OUT" "\16TIMESTAMP" "\17FLOWID")
"\15IPV6_NODF_OUT" "\16TIMESTAMP" "\17FLOWID" "\20TCP_TSO")
#endif
/* mbuf types */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: siginfo.h,v 1.13 2022/10/25 16:08:26 kettenis Exp $ */
/* $OpenBSD: siginfo.h,v 1.14 2024/02/21 15:53:07 deraadt Exp $ */
/*
* Copyright (c) 1997 Theo de Raadt
@ -61,7 +61,8 @@ union sigval {
#define ILL_PRVREG 6 /* privileged register */
#define ILL_COPROC 7 /* co-processor */
#define ILL_BADSTK 8 /* bad stack */
#define NSIGILL 8
#define ILL_BTCFI 9 /* IBT missing on indirect call */
#define NSIGILL 9
#define EMT_TAGOVF 1 /* tag overflow */
#define NSIGEMT 1

View File

@ -1,4 +1,4 @@
/* $OpenBSD: uvm_map.c,v 1.326 2024/01/21 17:21:55 deraadt Exp $ */
/* $OpenBSD: uvm_map.c,v 1.327 2024/02/21 03:28:29 deraadt Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@ -4556,7 +4556,7 @@ uvm_map_clean(struct vm_map *map, vaddr_t start, vaddr_t end, int flags)
struct vm_page *pg;
struct uvm_object *uobj;
vaddr_t cp_start, cp_end;
int refs;
int refs, imut = 0;
int error;
boolean_t rv;
@ -4572,10 +4572,8 @@ uvm_map_clean(struct vm_map *map, vaddr_t start, vaddr_t end, int flags)
/* Make a first pass to check for various conditions. */
for (entry = first; entry != NULL && entry->start < end;
entry = RBT_NEXT(uvm_map_addr, entry)) {
if (entry->etype & UVM_ET_IMMUTABLE) {
vm_map_unlock(map);
return EPERM;
}
if (entry->etype & UVM_ET_IMMUTABLE)
imut = 1;
if (UVM_ET_ISSUBMAP(entry)) {
vm_map_unlock(map);
return EINVAL;
@ -4608,6 +4606,11 @@ uvm_map_clean(struct vm_map *map, vaddr_t start, vaddr_t end, int flags)
if (amap == NULL || (flags & (PGO_DEACTIVATE|PGO_FREE)) == 0)
goto flush_object;
if (imut) {
vm_map_unbusy(map);
return EPERM;
}
cp_start = MAX(entry->start, start);
cp_end = MIN(entry->end, end);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dw.c,v 1.5 2021/10/25 19:54:29 kn Exp $ */
/* $OpenBSD: dw.c,v 1.6 2024/02/21 13:16:14 claudio Exp $ */
/*
* Copyright (c) 2016 Martin Pieuchot
@ -21,6 +21,7 @@
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -184,6 +185,7 @@ const char *
dw_at2name(uint64_t at)
{
static const char *dw_attrs[] = { DW_AT_NAMES };
static char buf[64];
if (at <= nitems(dw_attrs))
return dw_attrs[at - 1];
@ -193,7 +195,8 @@ dw_at2name(uint64_t at)
if (at == DW_AT_hi_user)
return "DW_AT_hi_user";
return NULL;
snprintf(buf, sizeof(buf), "#%llu", at);
return buf;
}
const char *

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dwarf.h,v 1.2 2017/08/11 14:58:56 jasper Exp $ */
/* $OpenBSD: dwarf.h,v 1.3 2024/02/21 13:16:14 claudio Exp $ */
/*
* Copyright (c) 2016 Martin Pieuchot <mpi@openbsd.org>
@ -273,6 +273,7 @@
#define DW_AT_const_expr 0x6c
#define DW_AT_enum_class 0x6d
#define DW_AT_linkage_name 0x6e
#define DW_AT_noreturn 0x87
#define DW_AT_lo_user 0x2000
#define DW_AT_hi_user 0x3fff
@ -413,6 +414,7 @@
"DW_AT_const_expr", \
"DW_AT_enum_class", \
"DW_AT_linkage_name", \
[0x87 - 1] = "DW_AT_noreturn", \
#define DW_FORM_addr 0x01
#define DW_FORM_block2 0x03

View File

@ -1,4 +1,4 @@
/* $OpenBSD: parse.c,v 1.15 2022/12/26 18:43:49 jmc Exp $ */
/* $OpenBSD: parse.c,v 1.19 2024/02/21 13:24:37 claudio Exp $ */
/*
* Copyright (c) 2016-2017 Martin Pieuchot
@ -50,7 +50,11 @@ struct pool it_pool, im_pool, ir_pool;
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define DPRINTF(x...) do { /*printf(x)*/ } while (0)
#ifdef DEBUG
#define DPRINTF(x...) do { printf(x); } while (0)
#else
#define DPRINTF(x...) do { ; } while (0)
#endif
#define VOID_OFFSET 1 /* Fake offset for generating "void" type. */
@ -329,6 +333,11 @@ it_cmp(struct itype *a, struct itype *b)
(diff = (a->it_size - b->it_size) != 0))
return diff;
/* Arrays need to have same number of elements */
if ((a->it_type == CTF_K_ARRAY) &&
(diff = (a->it_nelems - b->it_nelems) != 0))
return diff;
/* Match by name */
if (!(a->it_flags & ITF_ANON) && !(b->it_flags & ITF_ANON))
return strcmp(it_name(a), it_name(b));
@ -341,7 +350,7 @@ it_cmp(struct itype *a, struct itype *b)
if ((a->it_refp != NULL) && (b->it_refp != NULL))
return it_cmp(a->it_refp, b->it_refp);
return 1;
return 0;
}
int
@ -833,7 +842,7 @@ parse_refers(struct dwdie *die, size_t psz, int type)
if (it->it_ref == 0 && (it->it_size == sizeof(void *) ||
type == CTF_K_CONST || type == CTF_K_VOLATILE ||
type == CTF_K_POINTER)) {
type == CTF_K_POINTER || type == CTF_K_TYPEDEF)) {
/* Work around GCC/clang not emiting a type for void */
it->it_flags &= ~ITF_UNRES;
it->it_ref = VOID_OFFSET;
@ -1345,6 +1354,8 @@ dav2val(struct dwaval *dav, size_t psz)
case DW_FORM_sdata:
case DW_FORM_data8:
case DW_FORM_ref8:
case DW_FORM_udata:
case DW_FORM_ref_udata:
val = dav->dav_u64;
break;
case DW_FORM_strp:

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.402 2023/11/24 00:31:30 dtucker Exp $ */
/* $OpenBSD: clientloop.c,v 1.403 2024/02/21 05:57:34 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -508,7 +508,7 @@ send_chaff(struct ssh *ssh)
{
int r;
if ((ssh->kex->flags & KEX_HAS_PING) == 0)
if (ssh->kex == NULL || (ssh->kex->flags & KEX_HAS_PING) == 0)
return 0;
/* XXX probabilistically send chaff? */
/*

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh_config.5,v 1.393 2024/01/10 06:33:13 jmc Exp $
.Dd $Mdocdate: January 10 2024 $
.\" $OpenBSD: ssh_config.5,v 1.394 2024/02/21 06:01:13 djm Exp $
.Dd $Mdocdate: February 21 2024 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@ -144,7 +144,7 @@ The available criteria keywords are:
.Cm localnetwork ,
.Cm host ,
.Cm originalhost ,
.Cm Tag ,
.Cm tagged ,
.Cm user ,
and
.Cm localuser .

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.352 2024/01/10 06:33:13 jmc Exp $
.Dd $Mdocdate: January 10 2024 $
.\" $OpenBSD: sshd_config.5,v 1.355 2024/02/21 06:17:29 djm Exp $
.Dd $Mdocdate: February 21 2024 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -486,7 +486,7 @@ to after authentication.
At session startup
.Xr sshd 8
checks that all components of the pathname are root-owned directories
which are not writable by any other user or group.
which are not writable by group or others.
After the chroot,
.Xr sshd 8
changes the working directory to the user's home directory.
@ -1127,7 +1127,8 @@ DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
Logging with a DEBUG level violates the privacy of users and is not recommended.
.It Cm LogVerbose
Specify one or more overrides to LogLevel.
Specify one or more overrides to
.Cm LogLevel .
An override consists of a pattern lists that matches the source file, function
and line number to force detailed logging for.
For example, an override pattern of:
@ -1792,6 +1793,14 @@ implements an in-process SFTP server.
This may simplify configurations using
.Cm ChrootDirectory
to force a different filesystem root on clients.
It accepts the same command line arguments as
.Cm sftp-server
and even though it is in-process, settings such as
.Cm LogLevel
or
.Cm SyslogFacility
do not apply to it and must be set explicitly via
command line arguments.
.Pp
By default no subsystems are defined.
.It Cm SyslogFacility

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ntp.c,v 1.173 2024/02/08 00:15:53 jsg Exp $ */
/* $OpenBSD: ntp.c,v 1.174 2024/02/21 03:31:28 deraadt Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -596,7 +596,7 @@ ntp_dispatch_imsg_dns(void)
dlen = imsg.hdr.len - IMSG_HEADER_SIZE;
if (dlen == 0) { /* no data -> temp error */
log_warnx("DNS lookup tempfail");
log_debug("DNS lookup tempfail");
peer->state = STATE_DNS_TEMPFAIL;
if (conf->tmpfail++ == TRIES_AUTO_DNSFAIL)
priv_settime(0, "of dns failures");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: aspa.c,v 1.27 2024/02/16 15:13:49 tb Exp $ */
/* $OpenBSD: aspa.c,v 1.28 2024/02/21 09:17:06 tb Exp $ */
/*
* Copyright (c) 2022 Job Snijders <job@fastly.com>
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
@ -32,14 +32,6 @@
#include "extern.h"
/*
* Parse results and data of the ASPA object.
*/
struct parse {
const char *fn; /* ASPA file name */
struct aspa *res; /* results */
};
extern ASN1_OBJECT *aspa_oid;
/*
@ -68,26 +60,26 @@ IMPLEMENT_ASN1_FUNCTIONS(ASProviderAttestation);
* Return zero on failure, non-zero on success.
*/
static int
aspa_parse_providers(struct parse *p, const STACK_OF(ASN1_INTEGER) *providers)
aspa_parse_providers(const char *fn, struct aspa *aspa,
const STACK_OF(ASN1_INTEGER) *providers)
{
const ASN1_INTEGER *pa;
uint32_t provider;
size_t providersz, i;
if ((providersz = sk_ASN1_INTEGER_num(providers)) == 0) {
warnx("%s: ASPA: ProviderASSet needs at least one entry",
p->fn);
warnx("%s: ASPA: ProviderASSet needs at least one entry", fn);
return 0;
}
if (providersz >= MAX_ASPA_PROVIDERS) {
warnx("%s: ASPA: too many providers (more than %d)", p->fn,
warnx("%s: ASPA: too many providers (more than %d)", fn,
MAX_ASPA_PROVIDERS);
return 0;
}
p->res->providers = calloc(providersz, sizeof(provider));
if (p->res->providers == NULL)
aspa->providers = calloc(providersz, sizeof(provider));
if (aspa->providers == NULL)
err(1, NULL);
for (i = 0; i < providersz; i++) {
@ -96,29 +88,29 @@ aspa_parse_providers(struct parse *p, const STACK_OF(ASN1_INTEGER) *providers)
memset(&provider, 0, sizeof(provider));
if (!as_id_parse(pa, &provider)) {
warnx("%s: ASPA: malformed ProviderAS", p->fn);
warnx("%s: ASPA: malformed ProviderAS", fn);
return 0;
}
if (p->res->custasid == provider) {
if (aspa->custasid == provider) {
warnx("%s: ASPA: CustomerASID can't also be Provider",
p->fn);
fn);
return 0;
}
if (i > 0) {
if (p->res->providers[i - 1] > provider) {
if (aspa->providers[i - 1] > provider) {
warnx("%s: ASPA: invalid ProviderASSet order",
p->fn);
fn);
return 0;
}
if (p->res->providers[i - 1] == provider) {
warnx("%s: ASPA: duplicate ProviderAS", p->fn);
if (aspa->providers[i - 1] == provider) {
warnx("%s: ASPA: duplicate ProviderAS", fn);
return 0;
}
}
p->res->providers[p->res->providersz++] = provider;
aspa->providers[aspa->providersz++] = provider;
}
return 1;
@ -129,7 +121,8 @@ aspa_parse_providers(struct parse *p, const STACK_OF(ASN1_INTEGER) *providers)
* Returns zero on failure, non-zero on success.
*/
static int
aspa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
aspa_parse_econtent(const char *fn, struct aspa *aspa, const unsigned char *d,
size_t dsz)
{
const unsigned char *oder;
ASProviderAttestation *aspa_asn1;
@ -137,24 +130,24 @@ aspa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
oder = d;
if ((aspa_asn1 = d2i_ASProviderAttestation(NULL, &d, dsz)) == NULL) {
warnx("%s: ASPA: failed to parse ASProviderAttestation", p->fn);
warnx("%s: ASPA: failed to parse ASProviderAttestation", fn);
goto out;
}
if (d != oder + dsz) {
warnx("%s: %td bytes trailing garbage in eContent", p->fn,
warnx("%s: %td bytes trailing garbage in eContent", fn,
oder + dsz - d);
goto out;
}
if (!valid_econtent_version(p->fn, aspa_asn1->version, 1))
if (!valid_econtent_version(fn, aspa_asn1->version, 1))
goto out;
if (!as_id_parse(aspa_asn1->customerASID, &p->res->custasid)) {
warnx("%s: malformed CustomerASID", p->fn);
if (!as_id_parse(aspa_asn1->customerASID, &aspa->custasid)) {
warnx("%s: malformed CustomerASID", fn);
goto out;
}
if (!aspa_parse_providers(p, aspa_asn1->providers))
if (!aspa_parse_providers(fn, aspa, aspa_asn1->providers))
goto out;
rc = 1;
@ -171,36 +164,33 @@ struct aspa *
aspa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
size_t len)
{
struct parse p;
struct aspa *aspa;
size_t cmsz;
unsigned char *cms;
struct cert *cert = NULL;
time_t signtime = 0;
int rc = 0;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
cms = cms_parse_validate(x509, fn, der, len, aspa_oid, &cmsz,
&signtime);
if (cms == NULL)
return NULL;
if ((p.res = calloc(1, sizeof(*p.res))) == NULL)
if ((aspa = calloc(1, sizeof(*aspa))) == NULL)
err(1, NULL);
p.res->signtime = signtime;
aspa->signtime = signtime;
if (!x509_get_aia(*x509, fn, &p.res->aia))
if (!x509_get_aia(*x509, fn, &aspa->aia))
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
if (!x509_get_aki(*x509, fn, &aspa->aki))
goto out;
if (!x509_get_sia(*x509, fn, &p.res->sia))
if (!x509_get_sia(*x509, fn, &aspa->sia))
goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
if (!x509_get_ski(*x509, fn, &aspa->ski))
goto out;
if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
p.res->ski == NULL) {
if (aspa->aia == NULL || aspa->aki == NULL || aspa->sia == NULL ||
aspa->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
"missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
@ -211,9 +201,9 @@ aspa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
goto out;
}
if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
if (!x509_get_notbefore(*x509, fn, &aspa->notbefore))
goto out;
if (!x509_get_notafter(*x509, fn, &p.res->notafter))
if (!x509_get_notafter(*x509, fn, &aspa->notafter))
goto out;
if (x509_any_inherits(*x509)) {
@ -221,25 +211,25 @@ aspa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
goto out;
}
if (!aspa_parse_econtent(cms, cmsz, &p))
if (!aspa_parse_econtent(fn, aspa, cms, cmsz))
goto out;
if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
goto out;
p.res->valid = valid_aspa(fn, cert, p.res);
aspa->valid = valid_aspa(fn, cert, aspa);
rc = 1;
out:
if (rc == 0) {
aspa_free(p.res);
p.res = NULL;
aspa_free(aspa);
aspa = NULL;
X509_free(*x509);
*x509 = NULL;
}
cert_free(cert);
free(cms);
return p.res;
return aspa;
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: extern.h,v 1.204 2024/02/16 05:18:29 tb Exp $ */
/* $OpenBSD: extern.h,v 1.207 2024/02/21 12:48:25 tb Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@ -652,7 +652,6 @@ void takey_free(struct takey *);
void tak_free(struct tak *);
struct tak *tak_parse(X509 **, const char *, int, const unsigned char *,
size_t);
struct tak *tak_read(struct ibuf *);
void aspa_buffer(struct ibuf *, const struct aspa *);
void aspa_free(struct aspa *);
@ -703,16 +702,15 @@ int cms_parse_validate_detached(X509 **, const char *,
/* Work with RFC 3779 IP addresses, prefixes, ranges. */
int ip_addr_afi_parse(const char *, const ASN1_OCTET_STRING *,
enum afi *);
enum afi *);
int ip_addr_parse(const ASN1_BIT_STRING *,
enum afi, const char *, struct ip_addr *);
enum afi, const char *, struct ip_addr *);
void ip_addr_print(const struct ip_addr *, enum afi, char *,
size_t);
int ip_addr_cmp(const struct ip_addr *, const struct ip_addr *);
size_t);
int ip_addr_check_overlap(const struct cert_ip *,
const char *, const struct cert_ip *, size_t, int);
const char *, const struct cert_ip *, size_t, int);
int ip_addr_check_covered(enum afi, const unsigned char *,
const unsigned char *, const struct cert_ip *, size_t);
const unsigned char *, const struct cert_ip *, size_t);
int ip_cert_compose_ranges(struct cert_ip *);
void ip_roa_compose_ranges(struct roa_ip *);
void ip_warn(const char *, const char *, const struct cert_ip *);
@ -729,9 +727,9 @@ int sbgp_parse_ipaddrblk(const char *, const IPAddrBlocks *,
int as_id_parse(const ASN1_INTEGER *, uint32_t *);
int as_check_overlap(const struct cert_as *, const char *,
const struct cert_as *, size_t, int);
const struct cert_as *, size_t, int);
int as_check_covered(uint32_t, uint32_t,
const struct cert_as *, size_t);
const struct cert_as *, size_t);
void as_warn(const char *, const char *, const struct cert_as *);
int sbgp_as_id(const char *, struct cert_as *, size_t *,
@ -904,9 +902,10 @@ int output_json(FILE *, struct vrp_tree *, struct brk_tree *,
int output_ometric(FILE *, struct vrp_tree *, struct brk_tree *,
struct vap_tree *, struct stats *);
void logx(const char *fmt, ...)
void logx(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
time_t getmonotime(void);
time_t getmonotime(void);
time_t get_current_time(void);
int mkpath(const char *);
int mkpathat(int, const char *);
@ -958,12 +957,4 @@ int mkpathat(int, const char *);
/* Maximum number of delegated hosting locations (repositories) for each TAL. */
#define MAX_REPO_PER_TAL 1000
/*
* Time - Evaluation time is used as the current time if it is
* larger than X509_TIME_MIN, otherwise the system time is used.
*/
#define X509_TIME_MAX 253402300799LL
#define X509_TIME_MIN -62167219200LL
extern time_t get_current_time(void);
#endif /* ! EXTERN_H */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: gbr.c,v 1.29 2023/10/13 12:06:49 job Exp $ */
/* $OpenBSD: gbr.c,v 1.30 2024/02/21 09:17:06 tb Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
*
@ -24,14 +24,6 @@
#include "extern.h"
/*
* Parse results and data of the manifest file.
*/
struct parse {
const char *fn; /* manifest file name */
struct gbr *res; /* results */
};
extern ASN1_OBJECT *gbr_oid;
/*
@ -43,44 +35,41 @@ struct gbr *
gbr_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
size_t len)
{
struct parse p;
struct gbr *gbr;
struct cert *cert = NULL;
size_t cmsz;
unsigned char *cms;
time_t signtime = 0;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
cms = cms_parse_validate(x509, fn, der, len, gbr_oid, &cmsz, &signtime);
if (cms == NULL)
return NULL;
if ((p.res = calloc(1, sizeof(*p.res))) == NULL)
if ((gbr = calloc(1, sizeof(*gbr))) == NULL)
err(1, NULL);
p.res->signtime = signtime;
if ((p.res->vcard = strndup(cms, cmsz)) == NULL)
gbr->signtime = signtime;
if ((gbr->vcard = strndup(cms, cmsz)) == NULL)
err(1, NULL);
free(cms);
if (!x509_get_aia(*x509, fn, &p.res->aia))
if (!x509_get_aia(*x509, fn, &gbr->aia))
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
if (!x509_get_aki(*x509, fn, &gbr->aki))
goto out;
if (!x509_get_sia(*x509, fn, &p.res->sia))
if (!x509_get_sia(*x509, fn, &gbr->sia))
goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
if (!x509_get_ski(*x509, fn, &gbr->ski))
goto out;
if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
p.res->ski == NULL) {
if (gbr->aia == NULL || gbr->aki == NULL || gbr->sia == NULL ||
gbr->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
"missing AIA, AKI, SIA or SKI X509 extension", fn);
goto out;
}
if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
if (!x509_get_notbefore(*x509, fn, &gbr->notbefore))
goto out;
if (!x509_get_notafter(*x509, fn, &p.res->notafter))
if (!x509_get_notafter(*x509, fn, &gbr->notafter))
goto out;
if (!x509_inherits(*x509)) {
@ -91,10 +80,10 @@ gbr_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
goto out;
return p.res;
return gbr;
out:
gbr_free(p.res);
gbr_free(gbr);
X509_free(*x509);
*x509 = NULL;
cert_free(cert);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: geofeed.c,v 1.15 2023/10/13 12:06:49 job Exp $ */
/* $OpenBSD: geofeed.c,v 1.16 2024/02/21 09:17:06 tb Exp $ */
/*
* Copyright (c) 2022 Job Snijders <job@fastly.com>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@ -31,11 +31,6 @@
#include "extern.h"
struct parse {
const char *fn;
struct geofeed *res;
};
extern ASN1_OBJECT *geofeed_oid;
/*
@ -43,7 +38,7 @@ extern ASN1_OBJECT *geofeed_oid;
* Returns 1 on success, 0 on failure.
*/
static int
geofeed_parse_geoip(struct geofeed *res, char *cidr, char *loc)
geofeed_parse_geoip(struct geofeed *geofeed, char *cidr, char *loc)
{
struct geoip *geoip;
struct ip_addr *ipaddr;
@ -73,11 +68,11 @@ geofeed_parse_geoip(struct geofeed *res, char *cidr, char *loc)
ipaddr->prefixlen = plen;
res->geoips = recallocarray(res->geoips, res->geoipsz,
res->geoipsz + 1, sizeof(struct geoip));
if (res->geoips == NULL)
geofeed->geoips = recallocarray(geofeed->geoips, geofeed->geoipsz,
geofeed->geoipsz + 1, sizeof(struct geoip));
if (geofeed->geoips == NULL)
err(1, NULL);
geoip = &res->geoips[res->geoipsz++];
geoip = &geofeed->geoips[geofeed->geoipsz++];
if ((geoip->ip = calloc(1, sizeof(struct cert_ip))) == NULL)
err(1, NULL);
@ -102,7 +97,7 @@ geofeed_parse_geoip(struct geofeed *res, char *cidr, char *loc)
struct geofeed *
geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
{
struct parse p;
struct geofeed *geofeed;
char *delim, *line, *loc, *nl;
ssize_t linelen;
BIO *bio;
@ -118,10 +113,7 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
if (bio == NULL)
errx(1, "BIO_new");
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
if ((p.res = calloc(1, sizeof(struct geofeed))) == NULL)
if ((geofeed = calloc(1, sizeof(*geofeed))) == NULL)
err(1, NULL);
while ((nl = memchr(buf, '\n', len)) != NULL) {
@ -217,7 +209,7 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
loc = "";
/* read each prefix */
if (!geofeed_parse_geoip(p.res, line, loc))
if (!geofeed_parse_geoip(geofeed, line, loc))
goto out;
}
@ -232,24 +224,25 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
}
if (!cms_parse_validate_detached(x509, fn, der, dersz, geofeed_oid,
bio, &p.res->signtime))
bio, &geofeed->signtime))
goto out;
if (!x509_get_aia(*x509, fn, &p.res->aia))
if (!x509_get_aia(*x509, fn, &geofeed->aia))
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
if (!x509_get_aki(*x509, fn, &geofeed->aki))
goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
if (!x509_get_ski(*x509, fn, &geofeed->ski))
goto out;
if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
if (geofeed->aia == NULL || geofeed->aki == NULL ||
geofeed->ski == NULL) {
warnx("%s: missing AIA, AKI, or SKI X509 extension", fn);
goto out;
}
if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
if (!x509_get_notbefore(*x509, fn, &geofeed->notbefore))
goto out;
if (!x509_get_notafter(*x509, fn, &p.res->notafter))
if (!x509_get_notafter(*x509, fn, &geofeed->notafter))
goto out;
if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
@ -265,13 +258,13 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
goto out;
}
p.res->valid = valid_geofeed(fn, cert, p.res);
geofeed->valid = valid_geofeed(fn, cert, geofeed);
rc = 1;
out:
if (rc == 0) {
geofeed_free(p.res);
p.res = NULL;
geofeed_free(geofeed);
geofeed = NULL;
X509_free(*x509);
*x509 = NULL;
}
@ -280,7 +273,7 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
free(b64);
free(der);
return p.res;
return geofeed;
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: main.c,v 1.249 2024/02/16 11:55:42 tb Exp $ */
/* $OpenBSD: main.c,v 1.250 2024/02/21 12:48:25 tb Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@ -74,6 +74,11 @@ int rrdpon = 1;
int repo_timeout;
time_t deadline;
/* 9999-12-31 23:59:59 UTC */
#define X509_TIME_MAX 253402300799LL
/* 0000-01-01 00:00:00 UTC */
#define X509_TIME_MIN -62167219200LL
int64_t evaluation_time = X509_TIME_MIN;
struct stats stats;
@ -113,6 +118,18 @@ getmonotime(void)
return (ts.tv_sec);
}
/*
* Time - Evaluation time is used as the current time if it is
* larger than X509_TIME_MIN, otherwise the system time is used.
*/
time_t
get_current_time(void)
{
if (evaluation_time > X509_TIME_MIN)
return (time_t)evaluation_time;
return time(NULL);
}
void
entity_free(struct entity *ent)
{
@ -126,14 +143,6 @@ entity_free(struct entity *ent)
free(ent);
}
time_t
get_current_time(void)
{
if (evaluation_time > X509_TIME_MIN)
return (time_t)evaluation_time;
return time(NULL);
}
/*
* Read a queue entity from the descriptor.
* Matched by entity_write_req().

View File

@ -1,4 +1,4 @@
/* $OpenBSD: mft.c,v 1.110 2024/02/16 15:18:08 tb Exp $ */
/* $OpenBSD: mft.c,v 1.111 2024/02/21 09:17:06 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@ -34,15 +34,6 @@
#include "extern.h"
/*
* Parse results and data of the manifest file.
*/
struct parse {
const char *fn; /* manifest file name */
struct mft *res; /* result object */
int found_crl;
};
extern ASN1_OBJECT *mft_oid;
/*
@ -183,7 +174,8 @@ rtype_from_mftfile(const char *fn)
* Return zero on failure, non-zero on success.
*/
static int
mft_parse_filehash(struct parse *p, const FileAndHash *fh)
mft_parse_filehash(const char *fn, struct mft *mft, const FileAndHash *fh,
int *found_crl)
{
char *file = NULL;
int rc = 0;
@ -192,7 +184,7 @@ mft_parse_filehash(struct parse *p, const FileAndHash *fh)
size_t new_idx = 0;
if (!valid_mft_filename(fh->file->data, fh->file->length)) {
warnx("%s: RFC 6486 section 4.2.2: bad filename", p->fn);
warnx("%s: RFC 6486 section 4.2.2: bad filename", fn);
goto out;
}
file = strndup(fh->file->data, fh->file->length);
@ -201,25 +193,24 @@ mft_parse_filehash(struct parse *p, const FileAndHash *fh)
if (fh->hash->length != SHA256_DIGEST_LENGTH) {
warnx("%s: RFC 6486 section 4.2.1: hash: "
"invalid SHA256 length, have %d",
p->fn, fh->hash->length);
"invalid SHA256 length, have %d", fn, fh->hash->length);
goto out;
}
type = rtype_from_mftfile(file);
/* remember the filehash for the CRL in struct mft */
if (type == RTYPE_CRL && strcmp(file, p->res->crl) == 0) {
memcpy(p->res->crlhash, fh->hash->data, SHA256_DIGEST_LENGTH);
p->found_crl = 1;
if (type == RTYPE_CRL && strcmp(file, mft->crl) == 0) {
memcpy(mft->crlhash, fh->hash->data, SHA256_DIGEST_LENGTH);
*found_crl = 1;
}
if (filemode)
fent = &p->res->files[p->res->filesz++];
fent = &mft->files[mft->filesz++];
else {
/* Fisher-Yates shuffle */
new_idx = arc4random_uniform(p->res->filesz + 1);
p->res->files[p->res->filesz++] = p->res->files[new_idx];
fent = &p->res->files[new_idx];
new_idx = arc4random_uniform(mft->filesz + 1);
mft->files[mft->filesz++] = mft->files[new_idx];
fent = &mft->files[new_idx];
}
fent->type = type;
@ -308,30 +299,30 @@ mft_has_unique_names_and_hashes(const char *fn, const Manifest *mft)
* Returns 0 on failure and 1 on success.
*/
static int
mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
mft_parse_econtent(const char *fn, struct mft *mft, const unsigned char *d,
size_t dsz)
{
const unsigned char *oder;
Manifest *mft_asn1;
FileAndHash *fh;
int i, rc = 0;
int found_crl, i, rc = 0;
oder = d;
if ((mft_asn1 = d2i_Manifest(NULL, &d, dsz)) == NULL) {
warnx("%s: RFC 6486 section 4: failed to parse Manifest",
p->fn);
warnx("%s: RFC 6486 section 4: failed to parse Manifest", fn);
goto out;
}
if (d != oder + dsz) {
warnx("%s: %td bytes trailing garbage in eContent", p->fn,
warnx("%s: %td bytes trailing garbage in eContent", fn,
oder + dsz - d);
goto out;
}
if (!valid_econtent_version(p->fn, mft_asn1->version, 0))
if (!valid_econtent_version(fn, mft_asn1->version, 0))
goto out;
p->res->seqnum = x509_convert_seqnum(p->fn, mft_asn1->manifestNumber);
if (p->res->seqnum == NULL)
mft->seqnum = x509_convert_seqnum(fn, mft_asn1->manifestNumber);
if (mft->seqnum == NULL)
goto out;
/*
@ -339,60 +330,61 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
* which doesn't conform to RFC 5280. So, double check.
*/
if (ASN1_STRING_length(mft_asn1->thisUpdate) != GENTIME_LENGTH) {
warnx("%s: embedded from time format invalid", p->fn);
warnx("%s: embedded from time format invalid", fn);
goto out;
}
if (ASN1_STRING_length(mft_asn1->nextUpdate) != GENTIME_LENGTH) {
warnx("%s: embedded until time format invalid", p->fn);
warnx("%s: embedded until time format invalid", fn);
goto out;
}
if (!x509_get_time(mft_asn1->thisUpdate, &p->res->thisupdate)) {
warn("%s: parsing manifest thisUpdate failed", p->fn);
if (!x509_get_time(mft_asn1->thisUpdate, &mft->thisupdate)) {
warn("%s: parsing manifest thisUpdate failed", fn);
goto out;
}
if (!x509_get_time(mft_asn1->nextUpdate, &p->res->nextupdate)) {
warn("%s: parsing manifest nextUpdate failed", p->fn);
if (!x509_get_time(mft_asn1->nextUpdate, &mft->nextupdate)) {
warn("%s: parsing manifest nextUpdate failed", fn);
goto out;
}
if (p->res->thisupdate > p->res->nextupdate) {
warnx("%s: bad update interval", p->fn);
if (mft->thisupdate > mft->nextupdate) {
warnx("%s: bad update interval", fn);
goto out;
}
if (OBJ_obj2nid(mft_asn1->fileHashAlg) != NID_sha256) {
warnx("%s: RFC 6486 section 4.2.1: fileHashAlg: "
"want SHA256 object, have %s (NID %d)", p->fn,
"want SHA256 object, have %s (NID %d)", fn,
ASN1_tag2str(OBJ_obj2nid(mft_asn1->fileHashAlg)),
OBJ_obj2nid(mft_asn1->fileHashAlg));
goto out;
}
if (sk_FileAndHash_num(mft_asn1->fileList) >= MAX_MANIFEST_ENTRIES) {
warnx("%s: %d exceeds manifest entry limit (%d)", p->fn,
warnx("%s: %d exceeds manifest entry limit (%d)", fn,
sk_FileAndHash_num(mft_asn1->fileList),
MAX_MANIFEST_ENTRIES);
goto out;
}
p->res->files = calloc(sk_FileAndHash_num(mft_asn1->fileList),
mft->files = calloc(sk_FileAndHash_num(mft_asn1->fileList),
sizeof(struct mftfile));
if (p->res->files == NULL)
if (mft->files == NULL)
err(1, NULL);
found_crl = 0;
for (i = 0; i < sk_FileAndHash_num(mft_asn1->fileList); i++) {
fh = sk_FileAndHash_value(mft_asn1->fileList, i);
if (!mft_parse_filehash(p, fh))
if (!mft_parse_filehash(fn, mft, fh, &found_crl))
goto out;
}
if (!p->found_crl) {
warnx("%s: CRL not part of MFT fileList", p->fn);
if (!found_crl) {
warnx("%s: CRL not part of MFT fileList", fn);
goto out;
}
if (!mft_has_unique_names_and_hashes(p->fn, mft_asn1))
if (!mft_has_unique_names_and_hashes(fn, mft_asn1))
goto out;
rc = 1;
@ -409,7 +401,7 @@ struct mft *
mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
size_t len)
{
struct parse p;
struct mft *mft;
struct cert *cert = NULL;
int rc = 0;
size_t cmsz;
@ -417,28 +409,25 @@ mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
char *crldp = NULL, *crlfile;
time_t signtime = 0;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
cms = cms_parse_validate(x509, fn, der, len, mft_oid, &cmsz, &signtime);
if (cms == NULL)
return NULL;
assert(*x509 != NULL);
if ((p.res = calloc(1, sizeof(struct mft))) == NULL)
if ((mft = calloc(1, sizeof(*mft))) == NULL)
err(1, NULL);
p.res->signtime = signtime;
mft->signtime = signtime;
if (!x509_get_aia(*x509, fn, &p.res->aia))
if (!x509_get_aia(*x509, fn, &mft->aia))
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
if (!x509_get_aki(*x509, fn, &mft->aki))
goto out;
if (!x509_get_sia(*x509, fn, &p.res->sia))
if (!x509_get_sia(*x509, fn, &mft->sia))
goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
if (!x509_get_ski(*x509, fn, &mft->ski))
goto out;
if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
p.res->ski == NULL) {
if (mft->aia == NULL || mft->aki == NULL || mft->sia == NULL ||
mft->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
"missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
@ -470,16 +459,16 @@ mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
"bad CRL distribution point extension", fn);
goto out;
}
if ((p.res->crl = strdup(crlfile)) == NULL)
if ((mft->crl = strdup(crlfile)) == NULL)
err(1, NULL);
if (mft_parse_econtent(cms, cmsz, &p) == 0)
if (mft_parse_econtent(fn, mft, cms, cmsz) == 0)
goto out;
if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
goto out;
if (p.res->signtime > p.res->nextupdate) {
if (mft->signtime > mft->nextupdate) {
warnx("%s: dating issue: CMS signing-time after MFT nextUpdate",
fn);
goto out;
@ -488,15 +477,15 @@ mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
rc = 1;
out:
if (rc == 0) {
mft_free(p.res);
p.res = NULL;
mft_free(mft);
mft = NULL;
X509_free(*x509);
*x509 = NULL;
}
free(crldp);
cert_free(cert);
free(cms);
return p.res;
return mft;
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: roa.c,v 1.76 2024/02/16 15:13:49 tb Exp $ */
/* $OpenBSD: roa.c,v 1.77 2024/02/21 09:17:06 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@ -31,14 +31,6 @@
#include "extern.h"
/*
* Parse results and data of the manifest file.
*/
struct parse {
const char *fn; /* manifest file name */
struct roa *res; /* results */
};
extern ASN1_OBJECT *roa_oid;
/*
@ -103,7 +95,8 @@ IMPLEMENT_ASN1_FUNCTIONS(RouteOriginAttestation);
* Returns zero on failure, non-zero on success.
*/
static int
roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
roa_parse_econtent(const char *fn, struct roa *roa, const unsigned char *d,
size_t dsz)
{
const unsigned char *oder;
RouteOriginAttestation *roa_asn1;
@ -121,39 +114,40 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
oder = d;
if ((roa_asn1 = d2i_RouteOriginAttestation(NULL, &d, dsz)) == NULL) {
warnx("%s: RFC 6482 section 3: failed to parse "
"RouteOriginAttestation", p->fn);
"RouteOriginAttestation", fn);
goto out;
}
if (d != oder + dsz) {
warnx("%s: %td bytes trailing garbage in eContent", p->fn,
warnx("%s: %td bytes trailing garbage in eContent", fn,
oder + dsz - d);
goto out;
}
if (!valid_econtent_version(p->fn, roa_asn1->version, 0))
if (!valid_econtent_version(fn, roa_asn1->version, 0))
goto out;
if (!as_id_parse(roa_asn1->asid, &p->res->asid)) {
if (!as_id_parse(roa_asn1->asid, &roa->asid)) {
warnx("%s: RFC 6482 section 3.2: asID: "
"malformed AS identifier", p->fn);
"malformed AS identifier", fn);
goto out;
}
ipaddrblocksz = sk_ROAIPAddressFamily_num(roa_asn1->ipAddrBlocks);
if (ipaddrblocksz != 1 && ipaddrblocksz != 2) {
warnx("%s: draft-rfc6482bis: unexpected number of ipAddrBlocks "
"(got %d, expected 1 or 2)", p->fn, ipaddrblocksz);
"(got %d, expected 1 or 2)", fn, ipaddrblocksz);
goto out;
}
for (i = 0; i < ipaddrblocksz; i++) {
addrfam = sk_ROAIPAddressFamily_value(roa_asn1->ipAddrBlocks, i);
addrfam = sk_ROAIPAddressFamily_value(roa_asn1->ipAddrBlocks,
i);
addrs = addrfam->addresses;
addrsz = sk_ROAIPAddress_num(addrs);
if (!ip_addr_afi_parse(p->fn, addrfam->addressFamily, &afi)) {
if (!ip_addr_afi_parse(fn, addrfam->addressFamily, &afi)) {
warnx("%s: RFC 6482 section 3.3: addressFamily: "
"invalid", p->fn);
"invalid", fn);
goto out;
}
@ -161,14 +155,14 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
case AFI_IPV4:
if (ipv4_seen++ > 0) {
warnx("%s: RFC 6482bis section 4.3.2: "
"IPv4 appears twice", p->fn);
"IPv4 appears twice", fn);
goto out;
}
break;
case AFI_IPV6:
if (ipv6_seen++ > 0) {
warnx("%s: RFC 6482bis section 4.3.2: "
"IPv6 appears twice", p->fn);
"IPv6 appears twice", fn);
goto out;
}
break;
@ -176,27 +170,26 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
if (addrsz == 0) {
warnx("%s: RFC 6482bis, section 4.3.2: "
"empty ROAIPAddressFamily", p->fn);
"empty ROAIPAddressFamily", fn);
goto out;
}
if (p->res->ipsz + addrsz >= MAX_IP_SIZE) {
if (roa->ipsz + addrsz >= MAX_IP_SIZE) {
warnx("%s: too many ROAIPAddress entries: limit %d",
p->fn, MAX_IP_SIZE);
fn, MAX_IP_SIZE);
goto out;
}
p->res->ips = recallocarray(p->res->ips, p->res->ipsz,
p->res->ipsz + addrsz, sizeof(struct roa_ip));
if (p->res->ips == NULL)
roa->ips = recallocarray(roa->ips, roa->ipsz,
roa->ipsz + addrsz, sizeof(struct roa_ip));
if (roa->ips == NULL)
err(1, NULL);
for (j = 0; j < addrsz; j++) {
addr = sk_ROAIPAddress_value(addrs, j);
if (!ip_addr_parse(addr->address, afi, p->fn,
&ipaddr)) {
if (!ip_addr_parse(addr->address, afi, fn, &ipaddr)) {
warnx("%s: RFC 6482 section 3.3: address: "
"invalid IP address", p->fn);
"invalid IP address", fn);
goto out;
}
maxlen = ipaddr.prefixlen;
@ -206,24 +199,24 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
addr->maxLength)) {
warnx("%s: RFC 6482 section 3.2: "
"ASN1_INTEGER_get_uint64 failed",
p->fn);
fn);
goto out;
}
if (ipaddr.prefixlen > maxlen) {
warnx("%s: prefixlen (%d) larger than "
"maxLength (%llu)", p->fn,
"maxLength (%llu)", fn,
ipaddr.prefixlen,
(unsigned long long)maxlen);
goto out;
}
if (maxlen > ((afi == AFI_IPV4) ? 32 : 128)) {
warnx("%s: maxLength (%llu) too large",
p->fn, (unsigned long long)maxlen);
fn, (unsigned long long)maxlen);
goto out;
}
}
res = &p->res->ips[p->res->ipsz++];
res = &roa->ips[roa->ipsz++];
res->addr = ipaddr;
res->afi = afi;
res->maxlength = maxlen;
@ -245,45 +238,42 @@ struct roa *
roa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
size_t len)
{
struct parse p;
struct roa *roa;
size_t cmsz;
unsigned char *cms;
struct cert *cert = NULL;
time_t signtime = 0;
int rc = 0;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
cms = cms_parse_validate(x509, fn, der, len, roa_oid, &cmsz, &signtime);
if (cms == NULL)
return NULL;
if ((p.res = calloc(1, sizeof(struct roa))) == NULL)
if ((roa = calloc(1, sizeof(struct roa))) == NULL)
err(1, NULL);
p.res->signtime = signtime;
roa->signtime = signtime;
if (!x509_get_aia(*x509, fn, &p.res->aia))
if (!x509_get_aia(*x509, fn, &roa->aia))
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
if (!x509_get_aki(*x509, fn, &roa->aki))
goto out;
if (!x509_get_sia(*x509, fn, &p.res->sia))
if (!x509_get_sia(*x509, fn, &roa->sia))
goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
if (!x509_get_ski(*x509, fn, &roa->ski))
goto out;
if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
p.res->ski == NULL) {
if (roa->aia == NULL || roa->aki == NULL || roa->sia == NULL ||
roa->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
"missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
}
if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
if (!x509_get_notbefore(*x509, fn, &roa->notbefore))
goto out;
if (!x509_get_notafter(*x509, fn, &p.res->notafter))
if (!x509_get_notafter(*x509, fn, &roa->notafter))
goto out;
if (!roa_parse_econtent(cms, cmsz, &p))
if (!roa_parse_econtent(fn, roa, cms, cmsz))
goto out;
if (x509_any_inherits(*x509)) {
@ -303,19 +293,19 @@ roa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
* If the ROA isn't valid, we accept it anyway and depend upon
* the code around roa_read() to check the "valid" field itself.
*/
p.res->valid = valid_roa(fn, cert, p.res);
roa->valid = valid_roa(fn, cert, roa);
rc = 1;
out:
if (rc == 0) {
roa_free(p.res);
p.res = NULL;
roa_free(roa);
roa = NULL;
X509_free(*x509);
*x509 = NULL;
}
cert_free(cert);
free(cms);
return p.res;
return roa;
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rsc.c,v 1.33 2024/02/16 15:19:02 tb Exp $ */
/* $OpenBSD: rsc.c,v 1.34 2024/02/21 09:17:06 tb Exp $ */
/*
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2022 Job Snijders <job@fastly.com>
@ -31,14 +31,6 @@
#include "extern.h"
/*
* Parse results and data of the Signed Checklist file.
*/
struct parse {
const char *fn; /* Signed Checklist file name */
struct rsc *res; /* results */
};
extern ASN1_OBJECT *rsc_oid;
/*
@ -135,7 +127,8 @@ IMPLEMENT_ASN1_FUNCTIONS(RpkiSignedChecklist);
* Return 0 on failure.
*/
static int
rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
rsc_parse_aslist(const char *fn, struct rsc *rsc,
const ConstrainedASIdentifiers *asids)
{
int i, asz;
@ -143,18 +136,18 @@ rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
return 1;
if ((asz = sk_ASIdOrRange_num(asids->asnum)) == 0) {
warnx("%s: RSC asID empty", p->fn);
warnx("%s: RSC asID empty", fn);
return 0;
}
if (asz >= MAX_AS_SIZE) {
warnx("%s: too many AS number entries: limit %d",
p->fn, MAX_AS_SIZE);
fn, MAX_AS_SIZE);
return 0;
}
p->res->as = calloc(asz, sizeof(struct cert_as));
if (p->res->as == NULL)
rsc->as = calloc(asz, sizeof(struct cert_as));
if (rsc->as == NULL)
err(1, NULL);
for (i = 0; i < asz; i++) {
@ -164,18 +157,16 @@ rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
switch (aor->type) {
case ASIdOrRange_id:
if (!sbgp_as_id(p->fn, p->res->as, &p->res->asz,
aor->u.id))
if (!sbgp_as_id(fn, rsc->as, &rsc->asz, aor->u.id))
return 0;
break;
case ASIdOrRange_range:
if (!sbgp_as_range(p->fn, p->res->as, &p->res->asz,
if (!sbgp_as_range(fn, rsc->as, &rsc->asz,
aor->u.range))
return 0;
break;
default:
warnx("%s: RSC AsList: unknown type %d", p->fn,
aor->type);
warnx("%s: RSC AsList: unknown type %d", fn, aor->type);
return 0;
}
}
@ -184,7 +175,8 @@ rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
}
static int
rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
rsc_parse_iplist(const char *fn, struct rsc *rsc,
const ConstrainedIPAddrBlocks *ipAddrBlocks)
{
const ConstrainedIPAddressFamily *af;
const IPAddressOrRanges *aors;
@ -197,7 +189,7 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
return 1;
if (sk_ConstrainedIPAddressFamily_num(ipAddrBlocks) == 0) {
warnx("%s: RSC ipAddrBlocks empty", p->fn);
warnx("%s: RSC ipAddrBlocks empty", fn);
return 0;
}
@ -205,20 +197,20 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
af = sk_ConstrainedIPAddressFamily_value(ipAddrBlocks, i);
aors = af->addressesOrRanges;
ipsz = p->res->ipsz + sk_IPAddressOrRange_num(aors);
ipsz = rsc->ipsz + sk_IPAddressOrRange_num(aors);
if (ipsz >= MAX_IP_SIZE) {
warnx("%s: too many IP address entries: limit %d",
p->fn, MAX_IP_SIZE);
fn, MAX_IP_SIZE);
return 0;
}
p->res->ips = recallocarray(p->res->ips, p->res->ipsz, ipsz,
rsc->ips = recallocarray(rsc->ips, rsc->ipsz, ipsz,
sizeof(struct cert_ip));
if (p->res->ips == NULL)
if (rsc->ips == NULL)
err(1, NULL);
if (!ip_addr_afi_parse(p->fn, af->addressFamily, &afi)) {
warnx("%s: RSC: invalid AFI", p->fn);
if (!ip_addr_afi_parse(fn, af->addressFamily, &afi)) {
warnx("%s: RSC: invalid AFI", fn);
return 0;
}
@ -226,18 +218,18 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
aor = sk_IPAddressOrRange_value(aors, j);
switch (aor->type) {
case IPAddressOrRange_addressPrefix:
if (!sbgp_addr(p->fn, p->res->ips,
&p->res->ipsz, afi, aor->u.addressPrefix))
if (!sbgp_addr(fn, rsc->ips,
&rsc->ipsz, afi, aor->u.addressPrefix))
return 0;
break;
case IPAddressOrRange_addressRange:
if (!sbgp_addr_range(p->fn, p->res->ips,
&p->res->ipsz, afi, aor->u.addressRange))
if (!sbgp_addr_range(fn, rsc->ips,
&rsc->ipsz, afi, aor->u.addressRange))
return 0;
break;
default:
warnx("%s: RFC 3779: IPAddressOrRange: "
"unknown type %d", p->fn, aor->type);
"unknown type %d", fn, aor->type);
return 0;
}
}
@ -247,7 +239,7 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
}
static int
rsc_check_digesttype(struct parse *p, const X509_ALGOR *alg)
rsc_check_digesttype(const char *fn, struct rsc *rsc, const X509_ALGOR *alg)
{
const ASN1_OBJECT *obj;
int type, nid;
@ -256,13 +248,13 @@ rsc_check_digesttype(struct parse *p, const X509_ALGOR *alg)
if (type != V_ASN1_UNDEF) {
warnx("%s: RSC DigestAlgorithmIdentifier unexpected parameters:"
" %d", p->fn, type);
" %d", fn, type);
return 0;
}
if ((nid = OBJ_obj2nid(obj)) != NID_sha256) {
warnx("%s: RSC DigestAlgorithmIdentifier: want SHA256, have %s"
" (NID %d)", p->fn, ASN1_tag2str(nid), nid);
" (NID %d)", fn, ASN1_tag2str(nid), nid);
return 0;
}
@ -274,7 +266,8 @@ rsc_check_digesttype(struct parse *p, const X509_ALGOR *alg)
* Return zero on failure, non-zero on success.
*/
static int
rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
rsc_parse_checklist(const char *fn, struct rsc *rsc,
const STACK_OF(FileNameAndHash) *checkList)
{
FileNameAndHash *fh;
ASN1_IA5STRING *fileName;
@ -282,28 +275,28 @@ rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
size_t sz, i;
if ((sz = sk_FileNameAndHash_num(checkList)) == 0) {
warnx("%s: RSC checkList needs at least one entry", p->fn);
warnx("%s: RSC checkList needs at least one entry", fn);
return 0;
}
if (sz >= MAX_CHECKLIST_ENTRIES) {
warnx("%s: %zu exceeds checklist entry limit (%d)", p->fn, sz,
warnx("%s: %zu exceeds checklist entry limit (%d)", fn, sz,
MAX_CHECKLIST_ENTRIES);
return 0;
}
p->res->files = calloc(sz, sizeof(struct rscfile));
if (p->res->files == NULL)
rsc->files = calloc(sz, sizeof(struct rscfile));
if (rsc->files == NULL)
err(1, NULL);
p->res->filesz = sz;
rsc->filesz = sz;
for (i = 0; i < sz; i++) {
fh = sk_FileNameAndHash_value(checkList, i);
file = &p->res->files[i];
file = &rsc->files[i];
if (fh->hash->length != SHA256_DIGEST_LENGTH) {
warnx("%s: RSC Digest: invalid SHA256 length", p->fn);
warnx("%s: RSC Digest: invalid SHA256 length", fn);
return 0;
}
memcpy(file->hash, fh->hash->data, SHA256_DIGEST_LENGTH);
@ -312,7 +305,7 @@ rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
continue;
if (!valid_filename(fileName->data, fileName->length)) {
warnx("%s: RSC FileNameAndHash: bad filename", p->fn);
warnx("%s: RSC FileNameAndHash: bad filename", fn);
return 0;
}
@ -330,7 +323,8 @@ rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
* Returns zero on failure, non-zero on success.
*/
static int
rsc_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
rsc_parse_econtent(const char *fn, struct rsc *rsc, const unsigned char *d,
size_t dsz)
{
const unsigned char *oder;
RpkiSignedChecklist *rsc_asn1;
@ -343,35 +337,35 @@ rsc_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
oder = d;
if ((rsc_asn1 = d2i_RpkiSignedChecklist(NULL, &d, dsz)) == NULL) {
warnx("%s: RSC: failed to parse RpkiSignedChecklist", p->fn);
warnx("%s: RSC: failed to parse RpkiSignedChecklist", fn);
goto out;
}
if (d != oder + dsz) {
warnx("%s: %td bytes trailing garbage in eContent", p->fn,
warnx("%s: %td bytes trailing garbage in eContent", fn,
oder + dsz - d);
goto out;
}
if (!valid_econtent_version(p->fn, rsc_asn1->version, 0))
if (!valid_econtent_version(fn, rsc_asn1->version, 0))
goto out;
resources = rsc_asn1->resources;
if (resources->asID == NULL && resources->ipAddrBlocks == NULL) {
warnx("%s: RSC: one of asID or ipAddrBlocks must be present",
p->fn);
fn);
goto out;
}
if (!rsc_parse_aslist(p, resources->asID))
if (!rsc_parse_aslist(fn, rsc, resources->asID))
goto out;
if (!rsc_parse_iplist(p, resources->ipAddrBlocks))
if (!rsc_parse_iplist(fn, rsc, resources->ipAddrBlocks))
goto out;
if (!rsc_check_digesttype(p, rsc_asn1->digestAlgorithm))
if (!rsc_check_digesttype(fn, rsc, rsc_asn1->digestAlgorithm))
goto out;
if (!rsc_parse_checklist(p, rsc_asn1->checkList))
if (!rsc_parse_checklist(fn, rsc, rsc_asn1->checkList))
goto out;
rc = 1;
@ -388,40 +382,37 @@ struct rsc *
rsc_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
size_t len)
{
struct parse p;
struct rsc *rsc;
unsigned char *cms;
size_t cmsz;
struct cert *cert = NULL;
time_t signtime = 0;
int rc = 0;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
cms = cms_parse_validate(x509, fn, der, len, rsc_oid, &cmsz,
&signtime);
if (cms == NULL)
return NULL;
if ((p.res = calloc(1, sizeof(struct rsc))) == NULL)
if ((rsc = calloc(1, sizeof(struct rsc))) == NULL)
err(1, NULL);
p.res->signtime = signtime;
rsc->signtime = signtime;
if (!x509_get_aia(*x509, fn, &p.res->aia))
if (!x509_get_aia(*x509, fn, &rsc->aia))
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
if (!x509_get_aki(*x509, fn, &rsc->aki))
goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
if (!x509_get_ski(*x509, fn, &rsc->ski))
goto out;
if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
if (rsc->aia == NULL || rsc->aki == NULL || rsc->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
"missing AIA, AKI or SKI X509 extension", fn);
goto out;
}
if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
if (!x509_get_notbefore(*x509, fn, &rsc->notbefore))
goto out;
if (!x509_get_notafter(*x509, fn, &p.res->notafter))
if (!x509_get_notafter(*x509, fn, &rsc->notafter))
goto out;
if (X509_get_ext_by_NID(*x509, NID_sinfo_access, -1) != -1) {
@ -434,25 +425,25 @@ rsc_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
goto out;
}
if (!rsc_parse_econtent(cms, cmsz, &p))
if (!rsc_parse_econtent(fn, rsc, cms, cmsz))
goto out;
if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
goto out;
p.res->valid = valid_rsc(fn, cert, p.res);
rsc->valid = valid_rsc(fn, cert, rsc);
rc = 1;
out:
if (rc == 0) {
rsc_free(p.res);
p.res = NULL;
rsc_free(rsc);
rsc = NULL;
X509_free(*x509);
*x509 = NULL;
}
cert_free(cert);
free(cms);
return p.res;
return rsc;
}
/*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tak.c,v 1.18 2024/02/16 15:13:49 tb Exp $ */
/* $OpenBSD: tak.c,v 1.19 2024/02/21 09:17:06 tb Exp $ */
/*
* Copyright (c) 2022 Job Snijders <job@fastly.com>
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
@ -31,14 +31,6 @@
#include "extern.h"
/*
* Parse results and data of the Trust Anchor Key file.
*/
struct parse {
const char *fn; /* TAK file name */
struct tak *res; /* results */
};
extern ASN1_OBJECT *tak_oid;
/*
@ -161,22 +153,20 @@ parse_takey(const char *fn, const TAKey *takey)
* Returns zero on failure, non-zero on success.
*/
static int
tak_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
tak_parse_econtent(const char *fn, struct tak *tak, const unsigned char *d,
size_t dsz)
{
const unsigned char *oder;
TAK *tak_asn1;
const char *fn;
int rc = 0;
fn = p->fn;
oder = d;
if ((tak_asn1 = d2i_TAK(NULL, &d, dsz)) == NULL) {
warnx("%s: failed to parse Trust Anchor Key", fn);
goto out;
}
if (d != oder + dsz) {
warnx("%s: %td bytes trailing garbage in eContent", p->fn,
warnx("%s: %td bytes trailing garbage in eContent", fn,
oder + dsz - d);
goto out;
}
@ -184,19 +174,19 @@ tak_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
if (!valid_econtent_version(fn, tak_asn1->version, 0))
goto out;
p->res->current = parse_takey(fn, tak_asn1->current);
if (p->res->current == NULL)
tak->current = parse_takey(fn, tak_asn1->current);
if (tak->current == NULL)
goto out;
if (tak_asn1->predecessor != NULL) {
p->res->predecessor = parse_takey(fn, tak_asn1->predecessor);
if (p->res->predecessor == NULL)
tak->predecessor = parse_takey(fn, tak_asn1->predecessor);
if (tak->predecessor == NULL)
goto out;
}
if (tak_asn1->successor != NULL) {
p->res->successor = parse_takey(fn, tak_asn1->successor);
if (p->res->successor == NULL)
tak->successor = parse_takey(fn, tak_asn1->successor);
if (tak->successor == NULL)
goto out;
}
@ -214,42 +204,39 @@ struct tak *
tak_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
size_t len)
{
struct parse p;
struct tak *tak;
struct cert *cert = NULL;
unsigned char *cms;
size_t cmsz;
time_t signtime = 0;
int rc = 0;
memset(&p, 0, sizeof(struct parse));
p.fn = fn;
cms = cms_parse_validate(x509, fn, der, len, tak_oid, &cmsz, &signtime);
if (cms == NULL)
return NULL;
if ((p.res = calloc(1, sizeof(struct tak))) == NULL)
if ((tak = calloc(1, sizeof(struct tak))) == NULL)
err(1, NULL);
p.res->signtime = signtime;
tak->signtime = signtime;
if (!x509_get_aia(*x509, fn, &p.res->aia))
if (!x509_get_aia(*x509, fn, &tak->aia))
goto out;
if (!x509_get_aki(*x509, fn, &p.res->aki))
if (!x509_get_aki(*x509, fn, &tak->aki))
goto out;
if (!x509_get_sia(*x509, fn, &p.res->sia))
if (!x509_get_sia(*x509, fn, &tak->sia))
goto out;
if (!x509_get_ski(*x509, fn, &p.res->ski))
if (!x509_get_ski(*x509, fn, &tak->ski))
goto out;
if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
p.res->ski == NULL) {
if (tak->aia == NULL || tak->aki == NULL || tak->sia == NULL ||
tak->ski == NULL) {
warnx("%s: RFC 6487 section 4.8: "
"missing AIA, AKI, SIA, or SKI X509 extension", fn);
goto out;
}
if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
if (!x509_get_notbefore(*x509, fn, &tak->notbefore))
goto out;
if (!x509_get_notafter(*x509, fn, &p.res->notafter))
if (!x509_get_notafter(*x509, fn, &tak->notafter))
goto out;
if (!x509_inherits(*x509)) {
@ -257,13 +244,13 @@ tak_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
goto out;
}
if (!tak_parse_econtent(cms, cmsz, &p))
if (!tak_parse_econtent(fn, tak, cms, cmsz))
goto out;
if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
goto out;
if (strcmp(p.res->aki, p.res->current->ski) != 0) {
if (strcmp(tak->aki, tak->current->ski) != 0) {
warnx("%s: current TAKey's SKI does not match EE AKI", fn);
goto out;
}
@ -271,14 +258,14 @@ tak_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
rc = 1;
out:
if (rc == 0) {
tak_free(p.res);
p.res = NULL;
tak_free(tak);
tak = NULL;
X509_free(*x509);
*x509 = NULL;
}
cert_free(cert);
free(cms);
return p.res;
return tak;
}
/*