-/* $OpenBSD: cert.c,v 1.59 2022/04/01 17:22:07 claudio Exp $ */
+/* $OpenBSD: cert.c,v 1.60 2022/04/02 12:17:53 claudio Exp $ */
/*
* Copyright (c) 2021 Job Snijders <job@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
* anchor or a certificate) as defined in RFC 6487.
* Returns the parse results or NULL on failure.
*/
-static struct cert *
-cert_parse_inner(const char *fn, const unsigned char *der, size_t len)
+struct cert *
+cert_parse_pre(const char *fn, const unsigned char *der, size_t len)
{
int rc = 0, extsz, c;
int sia_present = 0;
}
struct cert *
-cert_parse(const char *fn, const unsigned char *der, size_t len)
+cert_parse(const char *fn, struct cert *p)
{
- struct cert *p;
-
- if ((p = cert_parse_inner(fn, der, len)) == NULL)
- return NULL;
-
if (p->aki == NULL) {
warnx("%s: RFC 6487 section 8.4.2: "
"non-trust anchor missing AKI", fn);
}
struct cert *
-ta_parse(const char *fn, const unsigned char *der, size_t len,
- const unsigned char *pkey, size_t pkeysz)
+ta_parse(const char *fn, struct cert *p, const unsigned char *pkey,
+ size_t pkeysz)
{
ASN1_TIME *notBefore, *notAfter;
- EVP_PKEY *pk = NULL, *opk = NULL;
- struct cert *p;
-
- if ((p = cert_parse_inner(fn, der, len)) == NULL)
- return NULL;
+ EVP_PKEY *pk, *opk;
/* first check pubkey against the one from the TAL */
pk = d2i_PUBKEY(NULL, &pkey, pkeysz);
if ((opk = X509_get0_pubkey(p->x509)) == NULL) {
cryptowarnx("%s: RFC 6487 (trust anchor): missing pubkey", fn);
goto badcert;
- } else if (EVP_PKEY_cmp(pk, opk) != 1) {
+ }
+ if (EVP_PKEY_cmp(pk, opk) != 1) {
cryptowarnx("%s: RFC 6487 (trust anchor): "
"pubkey does not match TAL pubkey", fn);
goto badcert;
-/* $OpenBSD: extern.h,v 1.123 2022/04/01 17:22:07 claudio Exp $ */
+/* $OpenBSD: extern.h,v 1.124 2022/04/02 12:17:53 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
void cert_buffer(struct ibuf *, const struct cert *);
void cert_free(struct cert *);
-struct cert *cert_parse(const char *, const unsigned char *, size_t);
-struct cert *ta_parse(const char *, const unsigned char *, size_t,
- const unsigned char *, size_t);
+struct cert *cert_parse_pre(const char *, const unsigned char *, size_t);
+struct cert *cert_parse(const char *, struct cert *);
+struct cert *ta_parse(const char *, struct cert *, const unsigned char *,
+ size_t);
struct cert *cert_read(struct ibuf *);
void cert_insert_brks(struct brk_tree *, struct cert *);
#define RPKI_PATH_OUT_DIR "/var/db/rpki-client"
#define RPKI_PATH_BASE_DIR "/var/cache/rpki-client"
+/* Maximum number of TAL files we'll load. */
+#define TALSZ_MAX 8
+
/* Maximum number of IP and AS ranges accepted in any single file */
#define MAX_IP_SIZE 200000
#define MAX_AS_SIZE 200000
-/* $OpenBSD: main.c,v 1.189 2022/02/10 18:58:46 tb Exp $ */
+/* $OpenBSD: main.c,v 1.190 2022/04/02 12:17:53 claudio Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
#include "extern.h"
#include "version.h"
-/*
- * Maximum number of TAL files we'll load.
- */
-#define TALSZ_MAX 8
-
const char *tals[TALSZ_MAX];
const char *taldescs[TALSZ_MAX];
unsigned int talrepocnt[TALSZ_MAX];
-/* $OpenBSD: parser.c,v 1.65 2022/04/01 17:22:07 claudio Exp $ */
+/* $OpenBSD: parser.c,v 1.66 2022/04/02 12:17:53 claudio Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
static struct auth_tree auths = RB_INITIALIZER(&auths);
static struct crl_tree crlt = RB_INITIALIZER(&crlt);
+struct tal *talobj[TALSZ_MAX];
+
extern ASN1_OBJECT *certpol_oid;
struct parse_repo {
/* Extract certificate data. */
- cert = cert_parse(file, der, len);
+ cert = cert_parse_pre(file, der, len);
+ if (cert == NULL)
+ return NULL;
+ cert = cert_parse(file, cert);
if (cert == NULL)
return NULL;
/* Extract certificate data. */
- cert = ta_parse(file, der, len, pkey, pkeysz);
+ cert = cert_parse_pre(file, der, len);
+ if (cert == NULL)
+ return NULL;
+ cert = ta_parse(file, cert, pkey, pkeysz);
if (cert == NULL)
return NULL;
goto done;
}
- cert = cert_parse(uri, f, flen);
+ cert = cert_parse_pre(uri, f, flen);
free(f);
if (cert == NULL)
free(f);
}
+static struct tal *
+find_tal(struct cert *cert)
+{
+ EVP_PKEY *pk, *opk;
+ struct tal *tal;
+ int i;
+
+ if ((opk = X509_get0_pubkey(cert->x509)) == NULL)
+ return NULL;
+
+ for (i = 0; i < TALSZ_MAX; i++) {
+ const unsigned char *pkey;
+
+ if (talobj[i] == NULL)
+ break;
+ tal = talobj[i];
+ pkey = tal->pkey;
+ pk = d2i_PUBKEY(NULL, &pkey, tal->pkeysz);
+ if (pk == NULL)
+ continue;
+ if (EVP_PKEY_cmp(pk, opk) == 1) {
+ EVP_PKEY_free(pk);
+ return tal;
+ }
+ EVP_PKEY_free(pk);
+ }
+ return NULL;
+}
+
/*
* Parse file passed with -f option.
*/
struct roa *roa = NULL;
struct gbr *gbr = NULL;
struct tal *tal = NULL;
- enum rtype type;
char *aia = NULL, *aki = NULL;
+ enum rtype type;
+ int is_ta = 0;
if (num++ > 0)
printf("--\n");
switch (type) {
case RTYPE_CER:
- cert = cert_parse(file, buf, len);
+ cert = cert_parse_pre(file, buf, len);
+ if (cert == NULL)
+ break;
+ is_ta = X509_get_extension_flags(cert->x509) & EXFLAG_SS;
+ if (!is_ta)
+ cert = cert_parse(file, cert);
if (cert == NULL)
break;
cert_print(cert);
printf("Validation: OK\n");
else
printf("Validation: Failed\n");
+ } else if (is_ta) {
+ if ((tal = find_tal(cert)) != NULL) {
+ cert = ta_parse(file, cert, tal->pkey, tal->pkeysz);
+ printf("TAL: %s\n", tal->descr);
+ tal = NULL;
+ } else {
+ cert_free(cert);
+ cert = NULL;
+ printf("TAL: not found\n");
+ }
+ if (cert != NULL)
+ printf("Validation: OK\n");
+ else
+ printf("Validation: Failed\n");
}
X509_free(x509);
errx(1, "%s: could not parse tal file",
entp->file);
tal->id = entp->talid;
+ talobj[tal->id] = tal;
parse_load_ta(tal);
- tal_free(tal);
break;
default:
errx(1, "unhandled entity type %d", entp->type);