From nobody Sat Jan 11 02:49:01 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YVNJZ3JZtz5l4dT; Sat, 11 Jan 2025 02:49:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YVNJY4Nxfz4Hn2; Sat, 11 Jan 2025 02:49:01 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1736563741; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=EUKGiAwX2STqOjw+r9Jbad3LlHoXpW1x3b1kLCdP9PQ=; b=com8pnKkHUXos/AuOcczmogAp0VCX82ZtYd1JkxDXlC6/cTNnpA9GJy8vUwdK2Vif8LeCf nj1uH4KV1UQpcQzsX+iqMkxHoKnhxc80AFBFJzjE0figFFXVmsqGfFejqZemYC2ogwrTfi hLo5SWQNmEOZC/if/PK6Ebn7ltkzABVCcxwMucTwTjeRVPRaBgX36vUGCL6ULvzT/643rt /Izs+e2V+njCiQNIvmXOcf5bjv1lCxkyZqe+Wl8iVOEn2oyuCu6Yq+gBc7FX/wowoImA0H 6pRzcXn7/Z20mNAy0cWC/T7XqvSjIvjVDiAh/O56QPYI0H/ibrRBEhFkrjYS9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1736563741; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=EUKGiAwX2STqOjw+r9Jbad3LlHoXpW1x3b1kLCdP9PQ=; b=Zv4hu1XbZ6ITOMqC6sGoapzeERgUfuCSbc6RNxEXrQYZYBUzRlwz32kMyJi/Ww+l5uCgmU +Ealb2fdxYAVn7/S1VKK1FT2sgSq+IA9M8l/Q/aw6LhOZ8n9t06mIOgGm+HJC9ICp0EPju nH3JsDIwnNxK3d09i2fuNJkJriRx1/fXHj3YIQlkxefwdg5wDXXpEtSgk5wmo4WPbT3Jqp Yc/xcQ2hJYW7zSVUs/59qsVHhfm9iIUjZRjIydFZLfIzVnfmS8M9Ma5mn2VD+sBMfT7edJ 7mOlNGgbOWQr6Ikwuwd4UWM4KKPzkvc3RRwbkJwIGOmPPkMCL7yb1CN4/R8Xiw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1736563741; a=rsa-sha256; cv=none; b=hoIBGVXVyGIK/Fb8rEbX8BzoiNRDHQyXyqrN+DFTB0tv+1mgjgNygkYjo+lWEHk7o6YkRY SgzorSwevjpgZ8s2wjpz0kNWFCE52JsjOKayigApawOswZvUuo1z6EsUygm4VFU8jV714v 3sz+Jop/KAedGYRLk9lrmFSENUh2wYup3K519bm9XH1Zyr5ruZasQ7TAmkca3mQDHg4/Io A1tI4Mmj/lsmDGuJGJ18tfmBjoyZYYrYR6hbqUmImay+hWLB4XpuWv3SfL+4Y+w6ThpFis YvGAEcbrWW+sPteL97SkhSaD0+X1F9+AVi8Rwfa8BTj+wdVj0wE5NTQ41VBZEg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YVNJY40VJzgC0; Sat, 11 Jan 2025 02:49:01 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 50B2n1WW066482; Sat, 11 Jan 2025 02:49:01 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 50B2n1v3066479; Sat, 11 Jan 2025 02:49:01 GMT (envelope-from git) Date: Sat, 11 Jan 2025 02:49:01 GMT Message-Id: <202501110249.50B2n1v3066479@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: 14cf1cdf9a09 - stable/13 - pkg: pull rsa bits out of pkg.c List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 14cf1cdf9a099d47b8c80596b462696ebda1c11d Auto-Submitted: auto-generated The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=14cf1cdf9a099d47b8c80596b462696ebda1c11d commit 14cf1cdf9a099d47b8c80596b462696ebda1c11d Author: Kyle Evans AuthorDate: 2025-01-01 21:10:27 +0000 Commit: Kyle Evans CommitDate: 2025-01-11 02:48:30 +0000 pkg: pull rsa bits out of pkg.c We'll eventually add a pkgsign abstraction over these similar to how we do in pkg(8), but start by isolating these parts. Reviewed by: bapt, emaste (cherry picked from commit 2629e90dd05fb69d767525f960101d7d055ffae0) --- usr.sbin/pkg/Makefile | 2 +- usr.sbin/pkg/pkg.c | 130 +----------------------------------------- usr.sbin/pkg/pkg.h | 50 ++++++++++++++++ usr.sbin/pkg/rsa.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 130 deletions(-) diff --git a/usr.sbin/pkg/Makefile b/usr.sbin/pkg/Makefile index 3e0e047382ca..af0a4d57ee90 100644 --- a/usr.sbin/pkg/Makefile +++ b/usr.sbin/pkg/Makefile @@ -22,7 +22,7 @@ CONFSNAME_${PKGCONF}= ${PKGCONF:C/\.conf.+$/.conf/} CONFSDIR= /etc/pkg CONFSMODE= 644 PROG= pkg -SRCS= pkg.c dns_utils.c config.c hash.c +SRCS= pkg.c rsa.c dns_utils.c config.c hash.c MAN= pkg.7 CFLAGS+=-I${SRCTOP}/contrib/libucl/include diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c index 1915893af283..3e5e52751e0d 100644 --- a/usr.sbin/pkg/pkg.c +++ b/usr.sbin/pkg/pkg.c @@ -49,27 +49,12 @@ #include #include -#include -#include +#include "pkg.h" #include "dns_utils.h" #include "config.h" #include "hash.h" -struct sig_cert { - char *name; - unsigned char *sig; - int siglen; - unsigned char *cert; - int certlen; - bool trusted; -}; - -struct pubkey { - unsigned char *sig; - int siglen; -}; - typedef enum { HASH_UNKNOWN, HASH_SHA256, @@ -399,119 +384,6 @@ load_fingerprints(const char *path, int *count) return (fingerprints); } -static EVP_PKEY * -load_public_key_file(const char *file) -{ - EVP_PKEY *pkey; - BIO *bp; - char errbuf[1024]; - - bp = BIO_new_file(file, "r"); - if (!bp) - errx(EXIT_FAILURE, "Unable to read %s", file); - - if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) - warnx("ici: %s", ERR_error_string(ERR_get_error(), errbuf)); - - BIO_free(bp); - - return (pkey); -} - -static EVP_PKEY * -load_public_key_buf(const unsigned char *cert, int certlen) -{ - EVP_PKEY *pkey; - BIO *bp; - char errbuf[1024]; - - bp = BIO_new_mem_buf(__DECONST(void *, cert), certlen); - - if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - - BIO_free(bp); - - return (pkey); -} - -static bool -rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key, - int keylen, unsigned char *sig, int siglen) -{ - EVP_MD_CTX *mdctx; - EVP_PKEY *pkey; - char *sha256; - char errbuf[1024]; - bool ret; - - sha256 = NULL; - pkey = NULL; - mdctx = NULL; - ret = false; - - SSL_load_error_strings(); - - /* Compute SHA256 of the package. */ - if (lseek(fd, 0, 0) == -1) { - warn("lseek"); - goto cleanup; - } - if ((sha256 = sha256_fd(fd)) == NULL) { - warnx("Error creating SHA256 hash for package"); - goto cleanup; - } - - if (sigfile != NULL) { - if ((pkey = load_public_key_file(sigfile)) == NULL) { - warnx("Error reading public key"); - goto cleanup; - } - } else { - if ((pkey = load_public_key_buf(key, keylen)) == NULL) { - warnx("Error reading public key"); - goto cleanup; - } - } - - /* Verify signature of the SHA256(pkg) is valid. */ - if ((mdctx = EVP_MD_CTX_create()) == NULL) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - - if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - if (EVP_DigestVerifyUpdate(mdctx, sha256, strlen(sha256)) != 1) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - - if (EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - - ret = true; - printf("done\n"); - goto cleanup; - -error: - printf("failed\n"); - -cleanup: - free(sha256); - if (pkey) - EVP_PKEY_free(pkey); - if (mdctx) - EVP_MD_CTX_destroy(mdctx); - ERR_free_strings(); - - return (ret); -} - static struct pubkey * read_pubkey(int fd) { diff --git a/usr.sbin/pkg/pkg.h b/usr.sbin/pkg/pkg.h new file mode 100644 index 000000000000..01f69f5a825b --- /dev/null +++ b/usr.sbin/pkg/pkg.h @@ -0,0 +1,50 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2012-2014 Baptiste Daroussin + * Copyright (c) 2013 Bryan Drewery + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _PKG_H +#define _PKG_H + +struct sig_cert { + char *name; + unsigned char *sig; + int siglen; + unsigned char *cert; + int certlen; + bool trusted; +}; + +struct pubkey { + unsigned char *sig; + int siglen; +}; + +bool rsa_verify_cert(int, const char *, const unsigned char *, int, + unsigned char *, int); + +#endif /* _PKG_H */ diff --git a/usr.sbin/pkg/rsa.c b/usr.sbin/pkg/rsa.c new file mode 100644 index 000000000000..afc446a6ad06 --- /dev/null +++ b/usr.sbin/pkg/rsa.c @@ -0,0 +1,155 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2012-2014 Baptiste Daroussin + * Copyright (c) 2013 Bryan Drewery + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +#include +#include + +#include "pkg.h" + +#include "config.h" +#include "hash.h" + +static EVP_PKEY * +load_public_key_file(const char *file) +{ + EVP_PKEY *pkey; + BIO *bp; + char errbuf[1024]; + + bp = BIO_new_file(file, "r"); + if (!bp) + errx(EXIT_FAILURE, "Unable to read %s", file); + + if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) + warnx("ici: %s", ERR_error_string(ERR_get_error(), errbuf)); + + BIO_free(bp); + + return (pkey); +} + +static EVP_PKEY * +load_public_key_buf(const unsigned char *cert, int certlen) +{ + EVP_PKEY *pkey; + BIO *bp; + char errbuf[1024]; + + bp = BIO_new_mem_buf(__DECONST(void *, cert), certlen); + + if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + + BIO_free(bp); + + return (pkey); +} + +bool +rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key, + int keylen, unsigned char *sig, int siglen) +{ + EVP_MD_CTX *mdctx; + EVP_PKEY *pkey; + char *sha256; + char errbuf[1024]; + bool ret; + + sha256 = NULL; + pkey = NULL; + mdctx = NULL; + ret = false; + + SSL_load_error_strings(); + + /* Compute SHA256 of the package. */ + if (lseek(fd, 0, 0) == -1) { + warn("lseek"); + goto cleanup; + } + if ((sha256 = sha256_fd(fd)) == NULL) { + warnx("Error creating SHA256 hash for package"); + goto cleanup; + } + + if (sigfile != NULL) { + if ((pkey = load_public_key_file(sigfile)) == NULL) { + warnx("Error reading public key"); + goto cleanup; + } + } else { + if ((pkey = load_public_key_buf(key, keylen)) == NULL) { + warnx("Error reading public key"); + goto cleanup; + } + } + + /* Verify signature of the SHA256(pkg) is valid. */ + if ((mdctx = EVP_MD_CTX_create()) == NULL) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + + if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + if (EVP_DigestVerifyUpdate(mdctx, sha256, strlen(sha256)) != 1) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + + if (EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + + ret = true; + printf("done\n"); + goto cleanup; + +error: + printf("failed\n"); + +cleanup: + free(sha256); + if (pkey) + EVP_PKEY_free(pkey); + if (mdctx) + EVP_MD_CTX_destroy(mdctx); + ERR_free_strings(); + + return (ret); +}