diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-09-30 14:42:15 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-09-30 14:42:15 +0000 |
commit | 7210911fb861ce3558f542b66a055768d4e6989b (patch) | |
tree | bad60d7a0ce22bfd2af2b115a51329028de16fed | |
parent | b04835fc3178e51d37f560b024bb1aeea9a83697 (diff) |
Instead of using the kind of hidden b64_pton() from libc resolv.h switch
to the -lcrypto base64 decoder using EVP_Decode* this is more portable.
With and OK tb@, OK benno@ (on a less polished version)
-rw-r--r-- | usr.sbin/rpki-client/tal.c | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/usr.sbin/rpki-client/tal.c b/usr.sbin/rpki-client/tal.c index e9b7df4a692..05a7b6aed81 100644 --- a/usr.sbin/rpki-client/tal.c +++ b/usr.sbin/rpki-client/tal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tal.c,v 1.19 2020/09/12 15:46:48 claudio Exp $ */ +/* $OpenBSD: tal.c,v 1.20 2020/09/30 14:42:14 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -19,14 +19,46 @@ #include <assert.h> #include <ctype.h> #include <err.h> +#include <limits.h> #include <libgen.h> -#include <resolv.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "extern.h" +static int +base64_decode(const unsigned char *in, size_t inlen, unsigned char **out, + size_t *outlen) +{ + EVP_ENCODE_CTX ctx; + unsigned char *to; + int tolen; + + *out = NULL; + *outlen = 0; + + if (inlen >= INT_MAX - 3) + return -1; + tolen = ((inlen + 3) / 4) * 3 + 1; + if ((to = malloc(tolen)) == NULL) + return -1; + + EVP_DecodeInit(&ctx); + if (EVP_DecodeUpdate(&ctx, to, &tolen, in, inlen) == -1) + goto fail; + *outlen = tolen; + if (EVP_DecodeFinal(&ctx, to + tolen, &tolen) == -1) + goto fail; + *outlen += tolen; + *out = to; + return 0; + +fail: + free(to); + return -1; +} + /* * Inner function for parsing RFC 7730 from a buffer. * Returns a valid pointer on success, NULL otherwise. @@ -36,9 +68,9 @@ static struct tal * tal_parse_buffer(const char *fn, char *buf) { char *nl, *line; - unsigned char *b64 = NULL; - size_t sz; - int rc = 0, b64sz; + unsigned char *der; + size_t sz, dersz; + int rc = 0; struct tal *tal = NULL; enum rtype rp; EVP_PKEY *pkey = NULL; @@ -105,17 +137,14 @@ tal_parse_buffer(const char *fn, char *buf) } /* Now the BASE64-encoded public key. */ - sz = ((sz + 3) / 4) * 3 + 1; - if ((b64 = malloc(sz)) == NULL) - err(1, NULL); - if ((b64sz = b64_pton(buf, b64, sz)) < 0) - errx(1, "b64_pton"); + if ((base64_decode(buf, sz, &der, &dersz)) == -1) + errx(1, "base64 decode"); - tal->pkey = b64; - tal->pkeysz = b64sz; + tal->pkey = der; + tal->pkeysz = dersz; /* Make sure it's a valid public key. */ - pkey = d2i_PUBKEY(NULL, (const unsigned char **)&b64, b64sz); + pkey = d2i_PUBKEY(NULL, (const unsigned char **)&der, dersz); if (pkey == NULL) { cryptowarnx("%s: RFC 7730 section 2.1: subjectPublicKeyInfo: " "failed public key parse", fn); |