mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
pkg: abstract rsa out behind a pkgsign API
This mirrors a change we made in pkg(8), and will be used to next add
another signer that does ECC.
Reviewed by: bapt, emaste
(cherry picked from commit 5862580ded)
This commit is contained in:
parent
836f1da80e
commit
1e3003bed3
3 changed files with 110 additions and 9 deletions
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -55,6 +56,16 @@
|
|||
#include "config.h"
|
||||
#include "hash.h"
|
||||
|
||||
static const struct pkgsign_impl {
|
||||
const char *pi_name;
|
||||
const struct pkgsign_ops *pi_ops;
|
||||
} pkgsign_builtins[] = {
|
||||
{
|
||||
.pi_name = "rsa",
|
||||
.pi_ops = &pkgsign_rsa,
|
||||
},
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
HASH_UNKNOWN,
|
||||
HASH_SHA256,
|
||||
|
|
@ -77,6 +88,61 @@ STAILQ_HEAD(fingerprint_list, fingerprint);
|
|||
|
||||
static int debug;
|
||||
|
||||
static int
|
||||
pkgsign_new(const char *name, struct pkgsign_ctx **ctx)
|
||||
{
|
||||
const struct pkgsign_impl *impl;
|
||||
const struct pkgsign_ops *ops;
|
||||
struct pkgsign_ctx *nctx;
|
||||
size_t ctx_size;
|
||||
int ret;
|
||||
|
||||
assert(*ctx == NULL);
|
||||
ops = NULL;
|
||||
for (size_t i = 0; i < nitems(pkgsign_builtins); i++) {
|
||||
impl = &pkgsign_builtins[i];
|
||||
|
||||
if (strcmp(name, impl->pi_name) == 0) {
|
||||
ops = impl->pi_ops;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ops == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
ctx_size = ops->pkgsign_ctx_size;
|
||||
if (ctx_size == 0)
|
||||
ctx_size = sizeof(*nctx);
|
||||
assert(ctx_size >= sizeof(*nctx));
|
||||
|
||||
nctx = calloc(1, ctx_size);
|
||||
if (nctx == NULL)
|
||||
err(EXIT_FAILURE, "calloc");
|
||||
nctx->impl = impl;
|
||||
|
||||
ret = 0;
|
||||
if (ops->pkgsign_new != NULL)
|
||||
ret = (*ops->pkgsign_new)(name, nctx);
|
||||
|
||||
if (ret != 0) {
|
||||
free(nctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
*ctx = nctx;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
pkgsign_verify_cert(const struct pkgsign_ctx *ctx, int fd, const char *sigfile,
|
||||
const unsigned char *key, int keylen, unsigned char *sig, int siglen)
|
||||
{
|
||||
|
||||
return ((*ctx->impl->pi_ops->pkgsign_verify_cert)(ctx, fd, sigfile,
|
||||
key, keylen, sig, siglen));
|
||||
}
|
||||
|
||||
static int
|
||||
extract_pkg_static(int fd, char *p, int sz)
|
||||
{
|
||||
|
|
@ -509,10 +575,12 @@ verify_pubsignature(int fd_pkg, int fd_sig)
|
|||
{
|
||||
struct pubkey *pk;
|
||||
const char *pubkey;
|
||||
struct pkgsign_ctx *sctx;
|
||||
bool ret;
|
||||
|
||||
pk = NULL;
|
||||
pubkey = NULL;
|
||||
sctx = NULL;
|
||||
ret = false;
|
||||
if (config_string(PUBKEY, &pubkey) != 0) {
|
||||
warnx("No CONFIG_PUBKEY defined");
|
||||
|
|
@ -524,9 +592,14 @@ verify_pubsignature(int fd_pkg, int fd_sig)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (pkgsign_new("rsa", &sctx) != 0) {
|
||||
warnx("Failed to fetch 'rsa' signer");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify the signature. */
|
||||
printf("Verifying signature with public key %s... ", pubkey);
|
||||
if (rsa_verify_cert(fd_pkg, pubkey, NULL, 0, pk->sig,
|
||||
if (pkgsign_verify_cert(sctx, fd_pkg, pubkey, NULL, 0, pk->sig,
|
||||
pk->siglen) == false) {
|
||||
fprintf(stderr, "Signature is not valid\n");
|
||||
goto cleanup;
|
||||
|
|
@ -549,6 +622,7 @@ verify_signature(int fd_pkg, int fd_sig)
|
|||
struct fingerprint_list *trusted, *revoked;
|
||||
struct fingerprint *fingerprint;
|
||||
struct sig_cert *sc;
|
||||
struct pkgsign_ctx *sctx;
|
||||
bool ret;
|
||||
int trusted_count, revoked_count;
|
||||
const char *fingerprints;
|
||||
|
|
@ -557,6 +631,7 @@ verify_signature(int fd_pkg, int fd_sig)
|
|||
|
||||
hash = NULL;
|
||||
sc = NULL;
|
||||
sctx = NULL;
|
||||
trusted = revoked = NULL;
|
||||
ret = false;
|
||||
|
||||
|
|
@ -620,10 +695,15 @@ verify_signature(int fd_pkg, int fd_sig)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (pkgsign_new("rsa", &sctx) != 0) {
|
||||
fprintf(stderr, "Failed to fetch 'rsa' signer\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify the signature. */
|
||||
printf("Verifying signature with trusted certificate %s... ", sc->name);
|
||||
if (rsa_verify_cert(fd_pkg, NULL, sc->cert, sc->certlen, sc->sig,
|
||||
sc->siglen) == false) {
|
||||
if (pkgsign_verify_cert(sctx, fd_pkg, NULL, sc->cert, sc->certlen,
|
||||
sc->sig, sc->siglen) == false) {
|
||||
fprintf(stderr, "Signature is not valid\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,25 @@
|
|||
#ifndef _PKG_H
|
||||
#define _PKG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct pkgsign_ctx {
|
||||
const struct pkgsign_impl *impl;
|
||||
};
|
||||
|
||||
/* Tentatively won't be needing to free any state, all allocated in the ctx. */
|
||||
typedef int pkgsign_new_cb(const char *, struct pkgsign_ctx *);
|
||||
typedef bool pkgsign_verify_cert_cb(const struct pkgsign_ctx *, int,
|
||||
const char *, const unsigned char *, int, unsigned char *, int);
|
||||
|
||||
struct pkgsign_ops {
|
||||
size_t pkgsign_ctx_size;
|
||||
pkgsign_new_cb *pkgsign_new;
|
||||
pkgsign_verify_cert_cb *pkgsign_verify_cert;
|
||||
};
|
||||
|
||||
extern const struct pkgsign_ops pkgsign_rsa;
|
||||
|
||||
struct sig_cert {
|
||||
char *name;
|
||||
unsigned char *sig;
|
||||
|
|
@ -44,9 +63,6 @@ struct pubkey {
|
|||
int siglen;
|
||||
};
|
||||
|
||||
bool rsa_verify_cert(int, const char *, const unsigned char *, int,
|
||||
unsigned char *, int);
|
||||
|
||||
char *pkg_read_fd(int fd, size_t *osz);
|
||||
|
||||
#endif /* _PKG_H */
|
||||
|
|
|
|||
|
|
@ -77,9 +77,10 @@ load_public_key_buf(const unsigned char *cert, int certlen)
|
|||
return (pkey);
|
||||
}
|
||||
|
||||
bool
|
||||
rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key,
|
||||
int keylen, unsigned char *sig, int siglen)
|
||||
static bool
|
||||
rsa_verify_cert(const struct pkgsign_ctx *ctx __unused, int fd,
|
||||
const char *sigfile, const unsigned char *key, int keylen,
|
||||
unsigned char *sig, int siglen)
|
||||
{
|
||||
EVP_MD_CTX *mdctx;
|
||||
EVP_PKEY *pkey;
|
||||
|
|
@ -153,3 +154,7 @@ cleanup:
|
|||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
const struct pkgsign_ops pkgsign_rsa = {
|
||||
.pkgsign_verify_cert = rsa_verify_cert,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue