From owner-svn-src-releng@freebsd.org Wed Sep 16 21:00:24 2015 Return-Path: Delivered-To: svn-src-releng@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9FC789CEC81; Wed, 16 Sep 2015 21:00:24 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8ADDD1433; Wed, 16 Sep 2015 21:00:24 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t8GL0Op6091109; Wed, 16 Sep 2015 21:00:24 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t8GL0LrN091096; Wed, 16 Sep 2015 21:00:21 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201509162100.t8GL0LrN091096@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Wed, 16 Sep 2015 21:00:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r287873 - in releng: 10.1 10.1/sys/conf 10.1/usr.sbin/pkg 9.3 9.3/sys/conf 9.3/usr.sbin/pkg X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-releng@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the release engineering / security commits to the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Sep 2015 21:00:24 -0000 Author: delphij Date: Wed Sep 16 21:00:21 2015 New Revision: 287873 URL: https://svnweb.freebsd.org/changeset/base/287873 Log: Implement pubkey support for pkg(7) bootstrap. [EN-15:18] Approved by: so Modified: releng/10.1/UPDATING releng/10.1/sys/conf/newvers.sh releng/10.1/usr.sbin/pkg/config.c releng/10.1/usr.sbin/pkg/config.h releng/10.1/usr.sbin/pkg/pkg.c releng/9.3/UPDATING releng/9.3/sys/conf/newvers.sh releng/9.3/usr.sbin/pkg/config.c releng/9.3/usr.sbin/pkg/config.h releng/9.3/usr.sbin/pkg/pkg.c Modified: releng/10.1/UPDATING ============================================================================== --- releng/10.1/UPDATING Wed Sep 16 20:59:41 2015 (r287872) +++ releng/10.1/UPDATING Wed Sep 16 21:00:21 2015 (r287873) @@ -16,6 +16,10 @@ from older versions of FreeBSD, try WITH stable/10, and then rebuild without this option. The bootstrap process from older version of current is a bit fragile. +20150916: p20 FreeBSD-EN-15:18.pkg + + Implement pubkey support for pkg(7) bootstrap. [EN-15:18] + 20150825: p19 FreeBSD-SA-15:21.amd64 FreeBSD-SA-15:22.openssh FreeBSD-EN-15:14.ixgbe Modified: releng/10.1/sys/conf/newvers.sh ============================================================================== --- releng/10.1/sys/conf/newvers.sh Wed Sep 16 20:59:41 2015 (r287872) +++ releng/10.1/sys/conf/newvers.sh Wed Sep 16 21:00:21 2015 (r287873) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="10.1" -BRANCH="RELEASE-p19" +BRANCH="RELEASE-p20" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/10.1/usr.sbin/pkg/config.c ============================================================================== --- releng/10.1/usr.sbin/pkg/config.c Wed Sep 16 20:59:41 2015 (r287872) +++ releng/10.1/usr.sbin/pkg/config.c Wed Sep 16 21:00:21 2015 (r287873) @@ -133,6 +133,15 @@ static struct config_entry c[] = { false, true, }, + [PUBKEY] = { + PKG_CONFIG_STRING, + "PUBKEY", + NULL, + NULL, + NULL, + false, + false + } }; static const char * @@ -550,6 +559,8 @@ config_parse(const ucl_object_t *obj, pk sbuf_cpy(buf, "SIGNATURE_TYPE"); else if (strcasecmp(key, "fingerprints") == 0) sbuf_cpy(buf, "FINGERPRINTS"); + else if (strcasecmp(key, "pubkey") == 0) + sbuf_cpy(buf, "PUBKEY"); else if (strcasecmp(key, "enabled") == 0) { if ((cur->type != UCL_BOOLEAN) || !ucl_object_toboolean(cur)) Modified: releng/10.1/usr.sbin/pkg/config.h ============================================================================== --- releng/10.1/usr.sbin/pkg/config.h Wed Sep 16 20:59:41 2015 (r287872) +++ releng/10.1/usr.sbin/pkg/config.h Wed Sep 16 21:00:21 2015 (r287873) @@ -40,6 +40,7 @@ typedef enum { SIGNATURE_TYPE, FINGERPRINTS, REPOS_DIR, + PUBKEY, CONFIG_SIZE } pkg_config_key; Modified: releng/10.1/usr.sbin/pkg/pkg.c ============================================================================== --- releng/10.1/usr.sbin/pkg/pkg.c Wed Sep 16 20:59:41 2015 (r287872) +++ releng/10.1/usr.sbin/pkg/pkg.c Wed Sep 16 21:00:21 2015 (r287873) @@ -66,6 +66,11 @@ struct sig_cert { bool trusted; }; +struct pubkey { + unsigned char *sig; + int siglen; +}; + typedef enum { HASH_UNKNOWN, HASH_SHA256, @@ -474,6 +479,25 @@ cleanup: } 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; @@ -491,8 +515,8 @@ load_public_key_buf(const unsigned char } static bool -rsa_verify_cert(int fd, const unsigned char *key, int keylen, - unsigned char *sig, int siglen) +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; @@ -504,6 +528,8 @@ rsa_verify_cert(int fd, const unsigned c mdctx = NULL; ret = false; + SSL_load_error_strings(); + /* Compute SHA256 of the package. */ if (lseek(fd, 0, 0) == -1) { warn("lseek"); @@ -514,9 +540,16 @@ rsa_verify_cert(int fd, const unsigned c goto cleanup; } - if ((pkey = load_public_key_buf(key, keylen)) == NULL) { - warnx("Error reading public key"); - 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. */ @@ -556,6 +589,35 @@ cleanup: return (ret); } +static struct pubkey * +read_pubkey(int fd) +{ + struct pubkey *pk; + struct sbuf *sig; + char buf[4096]; + int r; + + if (lseek(fd, 0, 0) == -1) { + warn("lseek"); + return (NULL); + } + + sig = sbuf_new_auto(); + + while ((r = read(fd, buf, sizeof(buf))) >0) { + sbuf_bcat(sig, buf, r); + } + + sbuf_finish(sig); + pk = calloc(1, sizeof(struct pubkey)); + pk->siglen = sbuf_len(sig); + pk->sig = calloc(1, pk->siglen); + memcpy(pk->sig, sbuf_data(sig), pk->siglen); + sbuf_delete(sig); + + return (pk); +} + static struct sig_cert * parse_cert(int fd) { int my_fd; @@ -629,6 +691,45 @@ parse_cert(int fd) { } static bool +verify_pubsignature(int fd_pkg, int fd_sig) +{ + struct pubkey *pk; + const char *pubkey; + bool ret; + + pk = NULL; + pubkey = NULL; + ret = false; + if (config_string(PUBKEY, &pubkey) != 0) { + warnx("No CONFIG_PUBKEY defined"); + goto cleanup; + } + + if ((pk = read_pubkey(fd_sig)) == NULL) { + warnx("Error reading signature"); + goto cleanup; + } + + /* Verify the signature. */ + printf("Verifying signature with public key %s... ", pubkey); + if (rsa_verify_cert(fd_pkg, pubkey, NULL, 0, pk->sig, + pk->siglen) == false) { + fprintf(stderr, "Signature is not valid\n"); + goto cleanup; + } + + ret = true; + +cleanup: + if (pk) { + free(pk->sig); + free(pk); + } + + return (ret); +} + +static bool verify_signature(int fd_pkg, int fd_sig) { struct fingerprint_list *trusted, *revoked; @@ -706,7 +807,7 @@ verify_signature(int fd_pkg, int fd_sig) /* Verify the signature. */ printf("Verifying signature with trusted certificate %s... ", sc->name); - if (rsa_verify_cert(fd_pkg, sc->cert, sc->certlen, sc->sig, + if (rsa_verify_cert(fd_pkg, NULL, sc->cert, sc->certlen, sc->sig, sc->siglen) == false) { fprintf(stderr, "Signature is not valid\n"); goto cleanup; @@ -775,24 +876,42 @@ bootstrap_pkg(bool force) if (signature_type != NULL && strcasecmp(signature_type, "NONE") != 0) { - if (strcasecmp(signature_type, "FINGERPRINTS") != 0) { - warnx("Signature type %s is not supported for " - "bootstrapping.", signature_type); - goto cleanup; - } + if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { + + snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX", + getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); + snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig", + packagesite); + + if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto fetchfail; + } - snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX", - getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); - snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig", - packagesite); + if (verify_signature(fd_pkg, fd_sig) == false) + goto cleanup; + } else if (strcasecmp(signature_type, "PUBKEY") == 0) { - if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { - fprintf(stderr, "Signature for pkg not available.\n"); - goto fetchfail; - } + snprintf(tmpsig, MAXPATHLEN, + "%s/pkg.txz.pubkeysig.XXXXXX", + getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); + snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.pubkeysig", + packagesite); + + if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto fetchfail; + } - if (verify_signature(fd_pkg, fd_sig) == false) + if (verify_pubsignature(fd_pkg, fd_sig) == false) + goto cleanup; + } else { + warnx("Signature type %s is not supported for " + "bootstrapping.", signature_type); goto cleanup; + } } if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) @@ -861,21 +980,37 @@ bootstrap_pkg_local(const char *pkgpath, } if (signature_type != NULL && strcasecmp(signature_type, "NONE") != 0) { - if (strcasecmp(signature_type, "FINGERPRINTS") != 0) { - warnx("Signature type %s is not supported for " - "bootstrapping.", signature_type); - goto cleanup; - } + if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { - snprintf(path, sizeof(path), "%s.sig", pkgpath); + snprintf(path, sizeof(path), "%s.sig", pkgpath); - if ((fd_sig = open(path, O_RDONLY)) == -1) { - fprintf(stderr, "Signature for pkg not available.\n"); - goto cleanup; - } + if ((fd_sig = open(path, O_RDONLY)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto cleanup; + } - if (verify_signature(fd_pkg, fd_sig) == false) + if (verify_signature(fd_pkg, fd_sig) == false) + goto cleanup; + + } else if (strcasecmp(signature_type, "PUBKEY") == 0) { + + snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath); + + if ((fd_sig = open(path, O_RDONLY)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto cleanup; + } + + if (verify_pubsignature(fd_pkg, fd_sig) == false) + goto cleanup; + + } else { + warnx("Signature type %s is not supported for " + "bootstrapping.", signature_type); goto cleanup; + } } if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) Modified: releng/9.3/UPDATING ============================================================================== --- releng/9.3/UPDATING Wed Sep 16 20:59:41 2015 (r287872) +++ releng/9.3/UPDATING Wed Sep 16 21:00:21 2015 (r287873) @@ -11,6 +11,10 @@ handbook: Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20150916: p26 FreeBSD-EN-15:18.pkg + + Implement pubkey support for pkg(7) bootstrap. [EN-15:18] + 20150902: p25 FreeBSD-SA-15:23.bind Fix BIND remote denial of service vulnerability. [SA-15:23] Modified: releng/9.3/sys/conf/newvers.sh ============================================================================== --- releng/9.3/sys/conf/newvers.sh Wed Sep 16 20:59:41 2015 (r287872) +++ releng/9.3/sys/conf/newvers.sh Wed Sep 16 21:00:21 2015 (r287873) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.3" -BRANCH="RELEASE-p25" +BRANCH="RELEASE-p26" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/9.3/usr.sbin/pkg/config.c ============================================================================== --- releng/9.3/usr.sbin/pkg/config.c Wed Sep 16 20:59:41 2015 (r287872) +++ releng/9.3/usr.sbin/pkg/config.c Wed Sep 16 21:00:21 2015 (r287873) @@ -131,6 +131,15 @@ static struct config_entry c[] = { false, true, }, + [PUBKEY] = { + PKG_CONFIG_STRING, + "PUBKEY", + NULL, + NULL, + NULL, + false, + false + } }; static const char * @@ -347,6 +356,8 @@ config_parse(ucl_object_t *obj, pkg_conf sbuf_cpy(buf, "SIGNATURE_TYPE"); else if (strcasecmp(key, "fingerprints") == 0) sbuf_cpy(buf, "FINGERPRINTS"); + else if (strcasecmp(key, "pubkey") == 0) + sbuf_cpy(buf, "PUBKEY"); else if (strcasecmp(key, "enabled") == 0) { if ((cur->type != UCL_BOOLEAN) || !ucl_object_toboolean(cur)) Modified: releng/9.3/usr.sbin/pkg/config.h ============================================================================== --- releng/9.3/usr.sbin/pkg/config.h Wed Sep 16 20:59:41 2015 (r287872) +++ releng/9.3/usr.sbin/pkg/config.h Wed Sep 16 21:00:21 2015 (r287873) @@ -40,6 +40,7 @@ typedef enum { SIGNATURE_TYPE, FINGERPRINTS, REPOS_DIR, + PUBKEY, CONFIG_SIZE } pkg_config_key; Modified: releng/9.3/usr.sbin/pkg/pkg.c ============================================================================== --- releng/9.3/usr.sbin/pkg/pkg.c Wed Sep 16 20:59:41 2015 (r287872) +++ releng/9.3/usr.sbin/pkg/pkg.c Wed Sep 16 21:00:21 2015 (r287873) @@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -66,6 +65,11 @@ struct sig_cert { bool trusted; }; +struct pubkey { + unsigned char *sig; + int siglen; +}; + typedef enum { HASH_UNKNOWN, HASH_SHA256, @@ -176,14 +180,11 @@ fetch_to_fd(const char *url, char *path) /* To store _https._tcp. + hostname + \0 */ int fd; int retry, max_retry; - off_t done, r; - time_t now, last; + ssize_t r; char buf[10240]; char zone[MAXHOSTNAMELEN + 13]; static const char *mirror_type = NULL; - done = 0; - last = 0; max_retry = 3; current = mirrors = NULL; remote = NULL; @@ -233,19 +234,16 @@ fetch_to_fd(const char *url, char *path) } } - while (done < st.size) { - if ((r = fread(buf, 1, sizeof(buf), remote)) < 1) - break; - + while ((r = fread(buf, 1, sizeof(buf), remote)) > 0) { if (write(fd, buf, r) != r) { warn("write()"); goto fetchfail; } + } - done += r; - now = time(NULL); - if (now > last || done == st.size) - last = now; + if (r != 0) { + warn("An error occurred while fetching pkg(8)"); + goto fetchfail; } if (ferror(remote)) @@ -480,6 +478,29 @@ cleanup: } static RSA * +load_rsa_public_key_file(const char *file) +{ + RSA *rsa = NULL; + BIO *bp; + char errbuf[1024]; + + bp = BIO_new_file(file, "r"); + if (!bp) + errx(EXIT_FAILURE, "Unable to read %s", file); + + if (!PEM_read_bio_RSA_PUBKEY(bp, &rsa, NULL, NULL)) { + warn("error reading public key: %s", + ERR_error_string(ERR_get_error(), errbuf)); + BIO_free(bp); + return (NULL); + } + + BIO_free(bp); + + return (rsa); +} + +static RSA * load_rsa_public_key_buf(unsigned char *cert, int certlen) { RSA *rsa = NULL; @@ -499,8 +520,8 @@ load_rsa_public_key_buf(unsigned char *c static bool -rsa_verify_cert(int fd, unsigned char *key, int keylen, - unsigned char *sig, int siglen) +rsa_verify_cert(int fd, const char *sigfile, unsigned char *key, + int keylen, unsigned char *sig, int siglen) { char sha256[SHA256_DIGEST_LENGTH *2 +1]; char hash[SHA256_DIGEST_LENGTH]; @@ -517,7 +538,11 @@ rsa_verify_cert(int fd, unsigned char *k sha256_buf_bin(sha256, strlen(sha256), hash); - rsa = load_rsa_public_key_buf(key, keylen); + if (sigfile != NULL) { + rsa = load_rsa_public_key_file(sigfile); + } else { + rsa = load_rsa_public_key_buf(key, keylen); + } if (rsa == NULL) return (false); ret = RSA_verify(NID_sha256, hash, sizeof(hash), sig, siglen, rsa); @@ -532,6 +557,35 @@ rsa_verify_cert(int fd, unsigned char *k return (true); } +static struct pubkey * +read_pubkey(int fd) +{ + struct pubkey *pk; + struct sbuf *sig; + char buf[4096]; + int r; + + if (lseek(fd, 0, 0) == -1) { + warn("lseek"); + return (NULL); + } + + sig = sbuf_new_auto(); + + while ((r = read(fd, buf, sizeof(buf))) >0) { + sbuf_bcat(sig, buf, r); + } + + sbuf_finish(sig); + pk = calloc(1, sizeof(struct pubkey)); + pk->siglen = sbuf_len(sig); + pk->sig = calloc(1, pk->siglen); + memcpy(pk->sig, sbuf_data(sig), pk->siglen); + sbuf_delete(sig); + + return (pk); +} + static struct sig_cert * parse_cert(int fd) { int my_fd; @@ -605,6 +659,45 @@ parse_cert(int fd) { } static bool +verify_pubsignature(int fd_pkg, int fd_sig) +{ + struct pubkey *pk; + const char *pubkey; + bool ret; + + pk = NULL; + pubkey = NULL; + ret = false; + if (config_string(PUBKEY, &pubkey) != 0) { + warnx("No CONFIG_PUBKEY defined"); + goto cleanup; + } + + if ((pk = read_pubkey(fd_sig)) == NULL) { + warnx("Error reading signature"); + goto cleanup; + } + + /* Verify the signature. */ + printf("Verifying signature with public key %s... ", pubkey); + if (rsa_verify_cert(fd_pkg, pubkey, NULL, 0, pk->sig, + pk->siglen) == false) { + fprintf(stderr, "Signature is not valid\n"); + goto cleanup; + } + + ret = true; + +cleanup: + if (pk) { + free(pk->sig); + free(pk); + } + + return (ret); +} + +static bool verify_signature(int fd_pkg, int fd_sig) { struct fingerprint_list *trusted, *revoked; @@ -682,7 +775,7 @@ verify_signature(int fd_pkg, int fd_sig) /* Verify the signature. */ printf("Verifying signature with trusted certificate %s... ", sc->name); - if (rsa_verify_cert(fd_pkg, sc->cert, sc->certlen, sc->sig, + if (rsa_verify_cert(fd_pkg, NULL, sc->cert, sc->certlen, sc->sig, sc->siglen) == false) { printf("failed\n"); fprintf(stderr, "Signature is not valid\n"); @@ -750,24 +843,42 @@ bootstrap_pkg(bool force) if (signature_type != NULL && strcasecmp(signature_type, "NONE") != 0) { - if (strcasecmp(signature_type, "FINGERPRINTS") != 0) { - warnx("Signature type %s is not supported for " - "bootstrapping.", signature_type); - goto cleanup; - } + if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { - snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX", - getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); - snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig", - packagesite); + snprintf(tmpsig, MAXPATHLEN, "%s/pkg.txz.sig.XXXXXX", + getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); + snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.sig", + packagesite); + + if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto fetchfail; + } - if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { - fprintf(stderr, "Signature for pkg not available.\n"); - goto fetchfail; - } + if (verify_signature(fd_pkg, fd_sig) == false) + goto cleanup; + } else if (strcasecmp(signature_type, "PUBKEY") == 0) { + + snprintf(tmpsig, MAXPATHLEN, + "%s/pkg.txz.pubkeysig.XXXXXX", + getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP); + snprintf(url, MAXPATHLEN, "%s/Latest/pkg.txz.pubkeysig", + packagesite); + + if ((fd_sig = fetch_to_fd(url, tmpsig)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto fetchfail; + } - if (verify_signature(fd_pkg, fd_sig) == false) + if (verify_pubsignature(fd_pkg, fd_sig) == false) + goto cleanup; + } else { + warnx("Signature type %s is not supported for " + "bootstrapping.", signature_type); goto cleanup; + } } if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0) @@ -841,21 +952,37 @@ bootstrap_pkg_local(const char *pkgpath, } if (signature_type != NULL && strcasecmp(signature_type, "NONE") != 0) { - if (strcasecmp(signature_type, "FINGERPRINTS") != 0) { - warnx("Signature type %s is not supported for " - "bootstrapping.", signature_type); - goto cleanup; - } + if (strcasecmp(signature_type, "FINGERPRINTS") == 0) { - snprintf(path, sizeof(path), "%s.sig", pkgpath); + snprintf(path, sizeof(path), "%s.sig", pkgpath); - if ((fd_sig = open(path, O_RDONLY)) == -1) { - fprintf(stderr, "Signature for pkg not available.\n"); - goto cleanup; - } + if ((fd_sig = open(path, O_RDONLY)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto cleanup; + } + + if (verify_signature(fd_pkg, fd_sig) == false) + goto cleanup; + + } else if (strcasecmp(signature_type, "PUBKEY") == 0) { - if (verify_signature(fd_pkg, fd_sig) == false) + snprintf(path, sizeof(path), "%s.pubkeysig", pkgpath); + + if ((fd_sig = open(path, O_RDONLY)) == -1) { + fprintf(stderr, "Signature for pkg not " + "available.\n"); + goto cleanup; + } + + if (verify_pubsignature(fd_pkg, fd_sig) == false) + goto cleanup; + + } else { + warnx("Signature type %s is not supported for " + "bootstrapping.", signature_type); goto cleanup; + } } if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)