summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/svr4pkg/hdrs/install.h9
-rw-r--r--usr/src/cmd/svr4pkg/hdrs/libinst.h15
-rw-r--r--usr/src/cmd/svr4pkg/hdrs/messages.h24
-rw-r--r--usr/src/cmd/svr4pkg/libinst/setadmin.c161
-rw-r--r--usr/src/cmd/svr4pkg/pkgadd/Makefile2
-rw-r--r--usr/src/cmd/svr4pkg/pkgadd/main.c381
-rw-r--r--usr/src/cmd/svr4pkg/pkgadd/quit.c43
-rw-r--r--usr/src/cmd/svr4pkg/pkgadd/quit.h5
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/Makefile11
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/addcert.c573
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/certs.c239
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/listcert.c245
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/lock.c7
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/main.c51
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/pkgadm.h19
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/pkgadm_msgs.h153
-rw-r--r--usr/src/cmd/svr4pkg/pkgadm/removecert.c201
-rw-r--r--usr/src/cmd/svr4pkg/pkgchk/main.c7
-rw-r--r--usr/src/cmd/svr4pkg/pkginstall/instvol.c7
-rw-r--r--usr/src/cmd/svr4pkg/pkginstall/main.c5
-rw-r--r--usr/src/cmd/svr4pkg/pkgremove/main.c30
-rw-r--r--usr/src/cmd/svr4pkg/pkgrm/main.c30
-rw-r--r--usr/src/cmd/svr4pkg/pkgscripts/default5
-rw-r--r--usr/src/cmd/svr4pkg/pkgtrans/main.c101
-rw-r--r--usr/src/lib/libpkg/Makefile.com22
-rw-r--r--usr/src/lib/libpkg/THIRDPARTYLICENSE51
-rw-r--r--usr/src/lib/libpkg/common/ckparam.c5
-rw-r--r--usr/src/lib/libpkg/common/dstream.c89
-rw-r--r--usr/src/lib/libpkg/common/gpkgmap.c6
-rw-r--r--usr/src/lib/libpkg/common/keystore.c2474
-rw-r--r--usr/src/lib/libpkg/common/keystore.h145
-rw-r--r--usr/src/lib/libpkg/common/llib-lpkg8
-rw-r--r--usr/src/lib/libpkg/common/mapfile-vers57
-rw-r--r--usr/src/lib/libpkg/common/p12lib.c2798
-rw-r--r--usr/src/lib/libpkg/common/p12lib.h245
-rw-r--r--usr/src/lib/libpkg/common/path_valid.c61
-rw-r--r--usr/src/lib/libpkg/common/pkgerr.c125
-rw-r--r--usr/src/lib/libpkg/common/pkgerr.h104
-rw-r--r--usr/src/lib/libpkg/common/pkglib.h51
-rw-r--r--usr/src/lib/libpkg/common/pkglibmsgs.h209
-rw-r--r--usr/src/lib/libpkg/common/pkgserv.c5
-rw-r--r--usr/src/lib/libpkg/common/pkgtrans.c592
-rw-r--r--usr/src/lib/libpkg/common/pkgweb.c3240
-rw-r--r--usr/src/lib/libpkg/common/pkgweb.h130
-rw-r--r--usr/src/lib/libpkg/common/progerr.c16
-rw-r--r--usr/src/lib/libpkg/common/security.c282
-rw-r--r--usr/src/man/man1/pkgtrans.190
-rw-r--r--usr/src/man/man1m/pkgadd.1m229
-rw-r--r--usr/src/man/man1m/pkgadm.1m335
-rw-r--r--usr/src/man/man4/admin.4100
-rw-r--r--usr/src/pkg/manifests/package-svr4.mf2
51 files changed, 266 insertions, 13529 deletions
diff --git a/usr/src/cmd/svr4pkg/hdrs/install.h b/usr/src/cmd/svr4pkg/hdrs/install.h
index 829b08dc2a..66308fa64c 100644
--- a/usr/src/cmd/svr4pkg/hdrs/install.h
+++ b/usr/src/cmd/svr4pkg/hdrs/install.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,11 +97,6 @@ struct admin {
char *setuid;
char *conflict;
char *action;
- char *networktimeout;
- char *networkretries;
- char *authentication;
- char *keystore;
- char *proxy;
char *basedir;
char *rscriptalt;
};
diff --git a/usr/src/cmd/svr4pkg/hdrs/libinst.h b/usr/src/cmd/svr4pkg/hdrs/libinst.h
index 2d87d8e9ff..deef500c2b 100644
--- a/usr/src/cmd/svr4pkg/hdrs/libinst.h
+++ b/usr/src/cmd/svr4pkg/hdrs/libinst.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -330,12 +334,6 @@ extern void putConditionInfo __P((char *, char *));
extern void setadminFile __P((char *file));
extern char *setadminSetting __P((char *a_paramName,
char *a_paramValue));
-extern char *set_keystore_admin __P((void));
-extern boolean_t get_proxy_port_admin __P((char **, ushort_t *));
-extern boolean_t check_keystore_admin __P((char **));
-extern int web_ck_retries __P((void));
-extern int web_ck_timeout __P((void));
-extern int web_ck_authentication __P((void));
/* setlist.c */
extern char *cl_iscript __P((int idx));
@@ -355,11 +353,6 @@ extern unsigned cl_svfy __P((int i));
extern unsigned cl_dvfy __P((int i));
extern unsigned cl_pthrel __P((int i));
-/* passwd.c */
-extern int pkg_passphrase_cb __P((char *, int, int, void *));
-extern void set_passarg __P((char *));
-extern void set_prompt __P((char *));
-
/* fixpath.c */
extern void __P(export_client_env(char *));
extern void __P(set_partial_inst(void));
diff --git a/usr/src/cmd/svr4pkg/hdrs/messages.h b/usr/src/cmd/svr4pkg/hdrs/messages.h
index 67b2f9bf34..d20a1d6df5 100644
--- a/usr/src/cmd/svr4pkg/hdrs/messages.h
+++ b/usr/src/cmd/svr4pkg/hdrs/messages.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -335,7 +339,6 @@ extern "C" {
#define DBG_REMOVE_PKG_FROM_ZONE gettext("removing package <%s> from zone <%s>")
#define DBG_REMOVING_DSTREAM_PKGDIR gettext("removing temporary stream <%s> for package <%s>")
#define DBG_REMOVING_DSTREAM_TMPDIR gettext("removing package datastream temporary directory <%s>")
-#define DBG_REMOVING_DWNLD_TMPDIR gettext("removing download temporary directory <%s>")
#define DBG_REMOVING_PKG_TMPDIR gettext("removing temporary directory <%s> for package <%s>")
#define DBG_REMOVING_ZONE_TMPDIR gettext("removing zones temporary directory <%s>")
#define DBG_RESTORE_ZONE_STATE gettext("restoring state of zone <%s>")
@@ -405,8 +408,6 @@ extern "C" {
#define ERR_ACCRESP gettext("unable to access response file <%s>")
#define ERR_ADMBD gettext("%s is already installed at %s. Admin file will force a duplicate installation at %s.")
-#define ERR_ADM_KEYSTORE gettext("unable to determine keystore location")
-#define ERR_ADM_PROXY gettext("Admin file proxy setting invalid")
#define ERR_ALLZONES_AND_G_USED gettext("The -G option (install packages in the global zone only)\nmay not be used with package <%s> because the package must be\ninstalled in all zones.")
#define ERR_ALLZONES_AND_IN_LZ gettext("The package <%s> may only be installed by the global zone administrator")
#define ERR_ALLZONES_AND_IN_LZ_PKGRM gettext("The package <%s> may only be removed by the global zone administrator")
@@ -468,7 +469,6 @@ extern "C" {
#define ERR_DSINIT gettext("could not process datastream from <%s>")
#define ERR_DSTREAM gettext("unable to unpack datastream")
#define ERR_DSTREAMCNT gettext("datastream early termination problem")
-#define ERR_DWNLDTEMPDIR gettext("unable to make temporary directory for download operations in directory <%s>: %s")
#define ERR_FCHMOD gettext("unable to change mode of file <%s> to <0x%04lx>: (%d) %s")
#define ERR_FINALCK_ATTR gettext("ERROR: attribute verification of <%s> failed")
#define ERR_FINALCK_CONT gettext("ERROR: content verification of <%s> failed")
@@ -477,8 +477,6 @@ extern "C" {
#define ERR_FSTAT gettext("unable to fstat fd <%d> pathname <%s>: (%d) %s")
#define ERR_GPKGLIST_ERROR gettext("unable to determine list of packages to operate on (internal error in gpkglist)")
#define ERR_GZ_USED_TOGETHER gettext("the -G and zonelist options cannot be used together")
-#define ERR_ILL_HTTP_OPTS gettext("The -i and (-k or -P) options are mutually exclusive.")
-#define ERR_ILL_PASSWD gettext("A password is required to retrieve the public certificate from the keystore.")
#define ERR_INCOMP_VERS gettext("A version of <%s> package \"%s\" (which is incompatible with the package that is being installed) is currently installed and must be removed.")
#define ERR_INPUT gettext("error while reading file <%s>: (%d) %s")
#define ERR_INSTALL_ZONES_SKIPPED gettext("unable to boot <%d> zones that are not currently running - no packages installed on those zones")
@@ -544,12 +542,8 @@ extern "C" {
#define ERR_PKGADDCHK_MKPKGDIR gettext("Unable to make required packaging directory")
#define ERR_PKGADDCHK_PRIVFAILED gettext("Privilege checking failed.")
#define ERR_PKGADDCHK_SPCFAILED gettext("Space checking failed.")
-#define ERR_PKGASK_AND_IGNORE_SIG gettext("cannot use the -i option with pkgask")
-#define ERR_PKGASK_AND_KEYSTORE_FILE gettext("cannot use the -k option with pkgask")
#define ERR_PKGASK_AND_NOINTERACT gettext("cannot use the -n option with pkgask")
-#define ERR_PKGASK_AND_PROXY gettext("cannot use the -x option with pkgask")
#define ERR_PKGASK_AND_SPOOLDIR gettext("cannot use the -s option with pkgask")
-#define ERR_PKGASK_AND_URI gettext("cannot use web based sources via -d with pkgask")
#define ERR_PKGBINCP gettext("unable to copy <%s>\n\tto <%s>")
#define ERR_PKGBINREN gettext("unable to rename <%s>\n\tto <%s>")
#define ERR_PKGINFO gettext("unable to open pkginfo file <%s>")
@@ -586,7 +580,6 @@ extern "C" {
#define ERR_PRERVFY_NOFILE gettext("unable to perform preremoval check of package <%s> in zone <%s>")
#define ERR_PRERVFY_OPEN_FILE gettext("unable to examine preremoval check file <%s> for package <%s> in zone <%s>: %s")
#define ERR_PRERVFY_UNKNOWN_LINE gettext("unknown preremoval dependency check line <%s> for package <%s> zone <%s>: ignored")
-#define ERR_PROXY gettext("Proxy specification <%s> invalid")
#define ERR_RDONLY gettext("read-only parameter <%s> cannot be assigned a value")
#define ERR_READ gettext("unable to read <%s>: (%d) %s")
#define ERR_REMOVE gettext("unable to remove file <%s>: %s")
@@ -594,7 +587,6 @@ extern "C" {
#define ERR_REQUEST gettext("request script did not complete successfully")
#define ERR_RESOLVEPATH gettext("unable to resolve path <%s>: %s")
#define ERR_RESPFILE gettext("response file is invalid for pre-SVR4 package")
-#define ERR_RESPFILE_AND_URI gettext("cannot use -r option with web based sources via -d")
#define ERR_RESPONSE gettext("unable to open response file <%s>")
#define ERR_RMDIR gettext("unable to remove existing directory at <%s>")
#define ERR_RMPATH gettext("unable to remove <%s>")
@@ -651,12 +643,12 @@ extern "C" {
#define ERR_UNSUCC gettext("(A previous attempt may have been unsuccessful.)")
#ifdef Z_OPTION_IS_SUPPORTED
-#define ERR_USAGE_PKGADD_GLOBALZONE gettext("usage:\n\t%s [-nvi] [-d device] [[-M] -R host_path] [-V fs_file] [-a admin_file] [-r response] [-x proxy] [-k keystore] [-G|-Z] [-P passwd] [-Y category[,category ...] | pkg [pkg ...]]\n\t%s -s dir [-d device] [-x proxy] [-k keystore] [-G|-Z] [-P passwd] [-Y category[,category ...] | pkg [pkg ...]]\n")
+#define ERR_USAGE_PKGADD_GLOBALZONE gettext("usage:\n\t%s [-nv] [-d device] [[-M] -R host_path] [-V fs_file] [-a admin_file] [-r response] [-G|-Z] [-Y category[,category ...] | pkg [pkg ...]]\n\t%s -s dir [-d device] [-G|-Z] [-Y category[,category ...] | pkg [pkg ...]]\n")
#else
-#define ERR_USAGE_PKGADD_GLOBALZONE gettext("usage:\n\t%s [-nvi] [-d device] [[-M] -R host_path] [-V fs_file] [-a admin_file] [-r response] [-x proxy] [-k keystore] [-G] [-P passwd] [-Y category[,category ...] | pkg [pkg ...]]\n\t%s -s dir [-d device] [-x proxy] [-k keystore] [-G] [-P passwd] [-Y category[,category ...] | pkg [pkg ...]]\n")
+#define ERR_USAGE_PKGADD_GLOBALZONE gettext("usage:\n\t%s [-nv] [-d device] [[-M] -R host_path] [-V fs_file] [-a admin_file] [-r response] [-G] [-Y category[,category ...] | pkg [pkg ...]]\n\t%s -s dir [-d device] [-G] [-Y category[,category ...] | pkg [pkg ...]]\n")
#endif
-#define ERR_USAGE_PKGADD_NONGLOBALZONE gettext("usage:\n\t%s [-nvi] [-d device] [[-M] -R host_path] [-V fs_file] [-a admin_file] [-r response] [-x proxy] [-k keystore] [-P passwd] [-Y category[,category ...] | pkg [pkg ...]]\n\t%s -s dir [-d device] [-x proxy] [-k keystore] [-P passwd] [-Y category[,category ...] | pkg [pkg ...]]\n")
+#define ERR_USAGE_PKGADD_NONGLOBALZONE gettext("usage:\n\t%s [-nv] [-d device] [[-M] -R host_path] [-V fs_file] [-a admin_file] [-r response] [-Y category[,category ...] | pkg [pkg ...]]\n\t%s -s dir [-d device] [-Y category[,category ...] | pkg [pkg ...]]\n")
#define ERR_USAGE_PKGASK gettext("usage: %s -r response [-d device] [-R host_path] [-Y category[,category ...]] | [pkg [pkg ...]]\n")
#define ERR_USAGE_PKGINSTALL gettext("usage:\n\tpkginstall [-o] [-n] [-d device] [-m mountpt [-f fstype]] [-v] [[-M] -R host_path] [-V fs_file] [-b bindir] [-a admin_file] [-r resp_file] [-N calling_prog] directory pkginst\n")
#define ERR_USAGE_PKGREMOVE gettext("usage:\n\tpkgremove [-a admin_file] [-n] [-V ...] [[-M|-A] -R host_path] [-v] [-o] [-N calling_prog] pkginst\n")
@@ -738,7 +730,6 @@ extern "C" {
#define MSG_NODENAME gettext("(unknown)")
#define MSG_NOTEMPTY gettext("%s <non-empty directory not removed>")
#define MSG_N_PKGS_NOT_PROCESSED gettext("\n%d packages were not processed!\n")
-#define MSG_PASSPROMPT gettext("Enter keystore password:")
#define MSG_PKGADDCHK_ABADFILE gettext("\\nPackaging file <%s> is corrupt for %s <%s> on %s <%s>")
#define MSG_PKGADDCHK_BADFILE gettext("\\nPackaging files are corrupt for %s <%s> on %s <%s>.")
#define MSG_PKGADDCHK_CFCONTENT gettext("\\nThe file <%s> is already installed and in use by %s <%s> on %s <%s>.")
@@ -816,7 +807,6 @@ extern "C" {
#define MSG_VERIFYING gettext("Verifying signer <%s>")
#define MSG_VERIFYING_CLASS gettext("[ verifying class <%s> ]")
-#define PASSWD_CMDLINE gettext("## WARNING: USING \"%s\" MAKES PASSWORD VISIBLE TO ALL USERS.")
#define SPECIAL_ACCESS gettext("unable to maintain package contents text due to an access failure: %s")
#define SPECIAL_INPUT gettext("unable to maintain package contents text: alternate root path too long")
#define SPECIAL_MALLOC gettext("unable to maintain package contents text due to insufficient memory: %s")
diff --git a/usr/src/cmd/svr4pkg/libinst/setadmin.c b/usr/src/cmd/svr4pkg/libinst/setadmin.c
index e9f36534a4..778fff36db 100644
--- a/usr/src/cmd/svr4pkg/libinst/setadmin.c
+++ b/usr/src/cmd/svr4pkg/libinst/setadmin.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,8 +42,6 @@
#include <locale.h>
#include <libintl.h>
#include <pkglib.h>
-#include <pkgerr.h>
-#include <pkgweb.h>
#include <install.h>
#include <libinst.h>
#include <libadm.h>
@@ -55,17 +57,12 @@ static struct {
char *tag;
} admlist[] = {
&adm.action, "action",
- &adm.authentication, "authentication",
&adm.basedir, "basedir",
&adm.conflict, "conflict",
&adm.idepend, "idepend",
&adm.instance, "instance",
- &adm.keystore, "keystore",
&adm.mail, "mail",
- &adm.networkretries, "networkretries",
- &adm.networktimeout, "networktimeout",
&adm.partial, "partial",
- &adm.proxy, "proxy",
&adm.rdepend, "rdepend",
&adm.RSCRIPTALT, RSCRIPTALT_KEYWORD,
&adm.runlevel, "runlevel",
@@ -184,153 +181,3 @@ setadminFile(char *file)
adm.mail = DEFMAIL; /* if we don't assign anything to it */
}
}
-
-
-/*
- * Function: web_ck_retries
- * Description: Reads admin file setting for networkretries, or uses default
- * Parameters: None
- * Returns: admin file setting for networkretries, or the default if no
- * admin file setting exists or if it is outside the
- * allowable range.
- */
-int
-web_ck_retries(void)
-{
- int retries = NET_RETRIES_DEFAULT;
-
- if (ADMSET(networkretries)) {
- /* Make sure value is within valid range */
- if ((retries = atoi(adm.networkretries)) == 0) {
- return (NET_RETRIES_DEFAULT);
- } else if (retries <= NET_RETRIES_MIN ||
- retries > NET_RETRIES_MAX) {
- return (NET_RETRIES_DEFAULT);
- }
- }
- return (retries);
-}
-
-/*
- * Function: web_ck_authentication
- * Description: Retrieves admin file setting for authentication
- * Parameters: None
- * Returns: admin file policy for authentication - AUTH_QUIT
- * or AUTH_NOCHECK.
- * non-zero failure
- */
-int
-web_ck_authentication(void)
-{
- if (ADM(authentication, "nocheck"))
- return (AUTH_NOCHECK);
-
- return (AUTH_QUIT);
-}
-
-/*
- * Function: web_ck_timeout
- * Description: Retrieves admin file policy for networktimeout's
- * Parameters: NONE
- * Returns: Admin file setting for networktimeout, or default
- * timeout value if admin file does not specify one,
- * or specifies one that is out of the allowable range.
- */
-int
-web_ck_timeout(void)
-{
- int timeout = NET_TIMEOUT_DEFAULT;
-
- if (ADMSET(networktimeout)) {
- /* Make sure value is within valid range */
- if ((timeout = atoi(adm.networktimeout)) == 0) {
- return (NET_TIMEOUT_DEFAULT);
- } else if (timeout <= NET_TIMEOUT_MIN ||
- timeout > NET_TIMEOUT_MAX) {
- return (NET_TIMEOUT_DEFAULT);
- }
- }
- return (timeout);
-}
-
-/*
- * Function: check_keystore_admin
- * Description: Retrieves security keystore setting from admin file,
- * or validates user-supplied keystore policy.
- * Parameters: keystore - Where to store resulting keystore policy
- * Returns: B_TRUE - admin file contained valid keystore, or
- * user-supplied keystore passed in "keystore" was
- * valid. Resulting keystore stored in "keystore"
- *
- * B_FALSE - No location supplied to store result,
- * or user-supplied keystore was not valid.
- */
-boolean_t
-check_keystore_admin(char **keystore)
-{
-
- if (!keystore) {
- /* no location to store keystore */
- return (B_FALSE);
- }
-
- if (*keystore != NULL) {
- if (!path_valid(*keystore)) {
- /* the given keystore is invalid */
- return (B_FALSE);
- }
-
- /* the user-supplied keystore was valid */
- return (B_TRUE);
- }
-
- /* no user-supplied, so use default */
- if ((*keystore = set_keystore_admin()) == NULL) {
- *keystore = PKGSEC;
- }
- return (B_TRUE);
-}
-
-/*
- * Function: get_proxy_port_admin
- * Description: Retrieves proxy setting from admin file
- * Parameters: proxy - where to store resulting proxy (host:port or URL)
- * port - Where to store resulting proxy port
- * Returns: B_TRUE - admin file had a valid proxy setting,
- * and it is stored in "proxy".
- * B_FALSE - no proxy setting in admin file, or
- * invalid setting in admin file.
- */
-boolean_t
-get_proxy_port_admin(char **proxy, ushort_t *port)
-{
- if (ADMSET(proxy) && !path_valid(adm.proxy)) {
- /* admin file has bad keystore */
- return (B_FALSE);
- } else if (ADMSET(proxy)) {
- *proxy = strdup(adm.proxy);
- *port = strip_port(adm.proxy);
- }
- return (B_TRUE);
-}
-
-/*
- * Function: set_keystore_admin
- * Description: Retrieves security keystore setting from admin file,
- * Parameters: NONE
- * Returns: Keystore file policy from admin file, if set
- * and valid. NULL otherwise.
- */
-char *
-set_keystore_admin(void)
-{
- if (ADMSET(keystore) && !path_valid(adm.keystore)) {
- return (NULL);
- }
-
- if (!ADMSET(keystore)) {
- return (NULL);
- }
-
- return (adm.keystore);
-}
diff --git a/usr/src/cmd/svr4pkg/pkgadd/Makefile b/usr/src/cmd/svr4pkg/pkgadd/Makefile
index 66e6abb737..eb3634da75 100644
--- a/usr/src/cmd/svr4pkg/pkgadd/Makefile
+++ b/usr/src/cmd/svr4pkg/pkgadd/Makefile
@@ -20,6 +20,7 @@
#
#
+# Copyright (c) 2017 Peter Tribble.
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -35,7 +36,6 @@ ROOTLINKS= $(ROOTUSRSBIN)/pkgask
include $(SRC)/cmd/svr4pkg/Makefile.svr4pkg
LDLIBS += -lpkg -linstzones -ladm
-LDLIBS += -lcrypto -lwanboot
.KEEP_STATE:
diff --git a/usr/src/cmd/svr4pkg/pkgadd/main.c b/usr/src/cmd/svr4pkg/pkgadd/main.c
index 9917fb5253..1e201f4b5a 100644
--- a/usr/src/cmd/svr4pkg/pkgadd/main.c
+++ b/usr/src/cmd/svr4pkg/pkgadd/main.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -55,15 +59,12 @@
#include <locale.h>
#include <libintl.h>
#include <pkgtrans.h>
-#include <boot_http.h>
#include <assert.h>
/*
* consolidation pkg command library includes
*/
#include <pkglib.h>
-#include <pkgerr.h>
-#include <pkgweb.h>
#include <instzones_api.h>
@@ -236,30 +237,26 @@ static int pkgZoneInstall(char *a_zoneName,
char *a_adminFile, boolean_t a_tmpzn);
static void resetreturn();
static void usage(void);
-static boolean_t add_packages(char **a_pkgList, char *a_uri,
+static boolean_t add_packages(char **a_pkgList,
char *a_idsName, int a_repeat,
char *a_altBinDir, char *a_device,
boolean_t a_noZones);
static boolean_t add_packages_in_global_no_zones(char **a_pkgList,
- char *a_uri, char *a_idsName, int a_repeat,
+ char *a_idsName, int a_repeat,
char *a_altBinDir, char *a_device);
static boolean_t add_packages_in_global_with_zones(char **a_pkgList,
- char *a_uri, char *a_idsName, int a_repeat,
+ char *a_idsName, int a_repeat,
char *a_altBinDir, char *a_device,
zoneList_t a_zlst);
static boolean_t add_packages_in_nonglobal_zone(char **a_pkgList,
- char *a_uri, char *a_idsName, int a_repeat,
+ char *a_idsName, int a_repeat,
char *a_altBinDir, char *a_device);
static boolean_t check_applicability(char *a_packageDir,
char *a_pkgInst, char *a_rootPath,
CAF_T a_flags);
static boolean_t get_package_list(char ***r_pkgList, char **a_argv,
char *a_categories, char **a_categoryList,
- int a_ignoreSignatures, PKG_ERR *a_err,
- ushort_t a_httpProxyPort, char *a_httpProxyName,
- keystore_handle_t a_keystore,
- char *a_keystoreFile, char *a_idsName,
- int *r_repeat);
+ char *a_idsName, int *r_repeat);
static boolean_t continue_installation(void);
static boolean_t unpack_and_check_packages(char **a_pkgList,
char *a_idsName, char *a_packageDir);
@@ -290,33 +287,22 @@ static boolean_t unpack_and_check_packages(char **a_pkgList,
int
main(int argc, char **argv)
{
- PKG_ERR *err = NULL;
- WebScheme scheme = none;
char **category = NULL;
char *abiPtr;
char *altBinDir = (char *)NULL;
char *catg_arg = NULL;
char *device = NULL; /* dev pkg stored on */
- char *dwnld_dir = NULL;
- char *keystore_file = NULL;
char *p;
char *q;
char *prog;
char *prog_full_name = NULL;
- char *proxy = NULL;
char *spoolDir = NULL; /* specified with -s */
- char *uri = NULL;
char Rpath[PATH_MAX+1] = {'\0'};
int c;
- int ignore_sig = 0;
int n;
int repeat;
- int retries = NET_RETRIES_DEFAULT;
- int timeout = NET_TIMEOUT_DEFAULT;
- keystore_handle_t keystore = NULL;
struct sigaction nact;
struct sigaction oact;
- ushort_t proxy_port = 0;
/* initialize locale environment */
@@ -350,14 +336,6 @@ main(int argc, char **argv)
npkgs = 0;
- /* set default password prompt for encrypted packages */
-
- set_passphrase_prompt(MSG_PASSPROMPT);
-
- /* initialize security operations structures and libraries */
-
- sec_init();
-
if (z_running_in_global_zone() && !enable_local_fs()) {
progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
}
@@ -371,7 +349,7 @@ main(int argc, char **argv)
*/
while ((c = getopt(argc, argv,
- "?Aa:b:B:Cc:D:d:GhIik:MnO:P:R:r:Ss:tV:vx:Y:zZ")) != EOF) {
+ "?Aa:b:B:Cc:D:d:GhIMnO:R:r:Ss:tV:vY:zZ")) != EOF) {
switch (c) {
/*
@@ -481,22 +459,7 @@ main(int argc, char **argv)
/* NOTREACHED */
}
- if (strncmp(optarg, HTTP, 7) == 0) {
- scheme = web_http;
- } else if (strncmp(optarg, HTTPS, 8) == 0) {
- scheme = web_https;
- }
-
- if (scheme == web_https || scheme == web_http) {
- uri = optarg;
- if ((device = malloc(PATH_MAX)) == NULL) {
- progerr(ERR_MEM);
- exit(1);
- }
- (void) memset(device, '\0', PATH_MAX);
- } else {
- device = flex_device(optarg, 1);
- }
+ device = flex_device(optarg, 1);
break;
/*
@@ -532,29 +495,6 @@ main(int argc, char **argv)
break;
/*
- * Not a public interface: ignore signatures.
- */
- case 'i':
- ignore_sig++;
- break;
-
- /*
- * Public interface: Use keystore as the location from which to
- * get trusted certificate authority certificates when verifying
- * digital signatures found in packages. If no keystore is
- * specified, then the default keystore locations are searched
- * for valid trusted certificates.
- */
- case 'k':
- if (!path_valid(optarg)) {
- progerr(ERR_PATH, optarg);
- quit(1);
- /* NOTREACHED */
- }
- keystore_file = optarg;
- break;
-
- /*
* Public interface: Instruct pkgadd not to use the
* $root_path/etc/vfstab file for determining the client's
* mount points. This option assumes the mount points are
@@ -655,27 +595,6 @@ main(int argc, char **argv)
break;
/*
- * Public interface: Password to use to decrypt keystore
- * specified with -k, if required. See PASS PHRASE
- * ARGUMENTS for more information about the format of this
- * option's argument.
- */
- case 'P':
- if (optarg[0] == '-') {
- usage();
- quit(1);
- }
- set_passphrase_passarg(optarg);
- if (ci_strneq(optarg, "pass:", 5)) {
- /*
- * passwords on the command line are highly
- * insecure. complain.
- */
- logerr(PASSWD_CMDLINE, "pass:<pass>");
- }
- break;
-
- /*
* Public interface: Define the full path name of a
* directory to use as the root_path. All files,
* including package system information files, are
@@ -777,24 +696,6 @@ main(int argc, char **argv)
break;
/*
- * Public interface: Specify a HTTP[S] proxy to use when
- * downloading packages The format of proxy is host:port,
- * where host is the hostname of the HTTP[S] proxy, and
- * port is the port number associated with the proxy. This
- * switch overrides all other methods of specifying a
- * proxy. See ENVIRONMENT VARIABLES for more information
- * on alternate methods of specifying a default proxy.
- */
- case 'x':
- if (!path_valid(optarg)) {
- progerr(ERR_PATH, optarg);
- quit(1);
- /* NOTREACHED */
- }
- proxy = optarg;
- break;
-
- /*
* Public interface: Install packages based on the value
* of the CATEGORY parameter stored in the package's
* pkginfo(4) file. All packages on the source medium
@@ -925,30 +826,6 @@ main(int argc, char **argv)
/* pkgask does not support the same options as pkgadd */
- if (askflag && proxy) {
- progerr(ERR_PKGASK_AND_PROXY);
- usage();
- return (1);
- }
-
- if (askflag && uri) {
- progerr(ERR_PKGASK_AND_URI);
- usage();
- return (1);
- }
-
- if (askflag && keystore_file) {
- progerr(ERR_PKGASK_AND_KEYSTORE_FILE);
- usage();
- return (1);
- }
-
- if (askflag && ignore_sig) {
- progerr(ERR_PKGASK_AND_IGNORE_SIG);
- usage();
- return (1);
- }
-
if (askflag && spoolDir) {
progerr(ERR_PKGASK_AND_SPOOLDIR);
usage();
@@ -961,14 +838,6 @@ main(int argc, char **argv)
return (1);
}
- /* cannot use response file and web address together */
-
- if (respfile && uri) {
- progerr(ERR_RESPFILE_AND_URI);
- usage();
- return (1);
- }
-
/* cannot use response file/not-interactive and spool-to directory */
if (spoolDir && nointeract) {
@@ -1063,9 +932,9 @@ main(int argc, char **argv)
set_depend_pkginfo_DB(B_TRUE);
}
- /* if no device and no url, get and validate default device */
+ /* if no device, get and validate default device */
- if ((device == NULL) && (uri == NULL)) {
+ if (device == NULL) {
device = devattr("spool", "pathname");
if (device == NULL) {
progerr(ERR_NODEVICE);
@@ -1124,106 +993,6 @@ main(int argc, char **argv)
echoDebug(DBG_PKGADD_TMPDIR, tmpdir);
/*
- * setup and prepare secure package operations
- */
-
- /* initialize error object used by security functions */
-
- err = pkgerr_new();
-
- /* validate keystore file */
-
- if (!check_keystore_admin(&keystore_file)) {
- progerr(ERR_ADM_KEYSTORE);
- quit(1);
- /* NOTREACHED */
- }
-
- /* if uri provided, establish session */
-
- if (uri != NULL) {
- boolean_t b;
- int len;
- char *bname = (char *)NULL;
-
- set_web_install();
-
- if (!get_proxy_port(err, &proxy, &proxy_port)) {
- pkgerr(err);
- quit(1);
- /* NOTREACHED */
- }
-
- if (proxy == NULL) {
- if (!get_proxy_port_admin(&proxy, &proxy_port)) {
- progerr(ERR_ADM_PROXY);
- quit(1);
- /* NOTREACHED */
- }
- }
-
- if ((retries = web_ck_retries()) == 0) {
- pkgerr(err);
- quit(1);
- /* NOTREACHED */
- }
-
- if ((timeout = web_ck_timeout()) == 0) {
- pkgerr(err);
- quit(1);
- /* NOTREACHED */
- }
-
- /* create temporary directory */
-
- b = setup_temporary_directory(&dwnld_dir, tmpdir, "dwnld");
- if (b != B_TRUE) {
- progerr(ERR_DWNLDTEMPDIR, tmpdir, strerror(errno));
- quit(1);
- /* NOTREACHED */
- }
- canonize_slashes(dwnld_dir);
-
- /* register with quit() so directory is removed on exit */
-
- quitSetDwnldTmpdir(dwnld_dir); /* DO NOT FREE() */
-
- /* open keystore if this is a secure download */
- if (scheme == web_https) {
- if (open_keystore(err, keystore_file,
- get_prog_name(), pkg_passphrase_cb,
- KEYSTORE_DFLT_FLAGS, &keystore) != 0) {
- pkgerr(err);
- web_cleanup();
- quit(1);
- /* NOTREACHED */
- }
- }
-
- if (!web_session_control(err, uri, dwnld_dir, keystore, proxy,
- proxy_port, retries, timeout, nointeract, &bname)) {
- pkgerr(err);
- web_cleanup();
- quit(1);
- /* NOTREACHED */
- }
-
- /*
- * reset device to point to newly-downloaded file; note
- * when (scheme == web_https || scheme == web_http) that
- * device gets preloaded with a pointer to PATH_MAX bytes
- * allocated via malloc().
- */
-
- len = snprintf(device, PATH_MAX, "%s/%s", dwnld_dir, bname);
- if ((len < 0) || (len >= PATH_MAX)) {
- progerr(ERR_DIR_CONST, tmpdir);
- quit(1);
- /* NOTREACHED */
- }
- }
-
- /*
* See if user wants this to be handled as an old style pkg.
* NOTE : the ``exception_pkg()'' stuff is to be used only
* through on495. This function comes out for on1095. See
@@ -1286,8 +1055,7 @@ main(int argc, char **argv)
quit(1);
}
- n = pkgtrans(device, spoolDir, &argv[optind],
- 0, NULL, NULL);
+ n = pkgtrans(device, spoolDir, &argv[optind], 0);
quit(n);
/* NOTREACHED */
}
@@ -1337,8 +1105,7 @@ main(int argc, char **argv)
*/
b = get_package_list(&pkglist, argv, catg_arg, category,
- ignore_sig, err, proxy_port, proxy, keystore,
- keystore_file, ids_name, &repeat);
+ ids_name, &repeat);
if (b == B_FALSE) {
char path[PATH_MAX];
@@ -1384,7 +1151,7 @@ main(int argc, char **argv)
* package list generated - add packages
*/
- b = add_packages(pkglist, uri, ids_name, repeat,
+ b = add_packages(pkglist, ids_name, repeat,
altBinDir, device, noZones);
/*
@@ -3125,13 +2892,9 @@ unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir)
static boolean_t
get_package_list(char ***r_pkgList, char **a_argv, char *a_categories,
- char **a_categoryList, int a_ignoreSignatures, PKG_ERR *a_err,
- ushort_t a_httpProxyPort, char *a_httpProxyName,
- keystore_handle_t a_keystore, char *a_keystoreFile,
- char *a_idsName, int *r_repeat)
+ char **a_categoryList, char *a_idsName, int *r_repeat)
{
int n;
- url_hport_t *proxytmp = NULL;
/* entry assertions */
@@ -3166,83 +2929,6 @@ get_package_list(char ***r_pkgList, char **a_argv, char *a_categories,
/* NOTREACHED */
}
- /*
- * If we are not ignoring signatures, check the package's
- * signature if one exists. pkgask doesn't care about
- * signatures though.
- */
- if (!askflag && !a_ignoreSignatures && a_idsName &&
- (web_ck_authentication() == AUTH_QUIT)) {
-
- PKCS7 *sig = NULL;
- STACK_OF(X509) *cas = NULL;
-
- /* Retrieve signature */
- if (!get_signature(a_err, a_idsName, &pkgdev, &sig)) {
- pkgerr(a_err);
- web_cleanup();
- quit(1);
- /* NOTREACHED */
- }
-
- if (sig != NULL) {
- /* Found signature. Verify. */
- if (a_httpProxyName != NULL) {
- /* Proxy will be needed for OCSP */
- proxytmp = malloc(sizeof (url_hport_t));
- if (url_parse_hostport(a_httpProxyName,
- proxytmp, a_httpProxyPort)
- != URL_PARSE_SUCCESS) {
- progerr(ERR_PROXY,
- a_httpProxyName);
- PKCS7_free(sig);
- quit(99);
- /* NOTREACHED */
- }
- }
-
- /* Start with fresh error stack */
- pkgerr_clear(a_err);
-
- if (a_keystore == NULL) {
- /* keystore not opened - open it */
- if (open_keystore(a_err, a_keystoreFile,
- get_prog_name(), pkg_passphrase_cb,
- KEYSTORE_DFLT_FLAGS,
- &a_keystore) != 0) {
- pkgerr(a_err);
- web_cleanup();
- PKCS7_free(sig);
- quit(1);
- /* NOTREACHED */
- }
- }
-
- /* get trusted CA certs */
- if (find_ca_certs(a_err, a_keystore, &cas) != 0) {
- pkgerr(a_err);
- PKCS7_free(sig);
- web_cleanup();
- quit(1);
- /* NOTREACHED */
- }
-
- /* Verify signature */
- if (!ds_validate_signature(a_err, &pkgdev,
- &a_argv[optind], a_idsName, sig,
- cas, proxytmp, nointeract)) {
- pkgerr(a_err);
- quit(99);
- /* NOTREACHED */
- }
-
- /* cleanup */
- PKCS7_free(sig);
- web_cleanup();
- pkgerr_free(a_err);
- }
- }
-
/* order package list if input data stream specified */
if (a_idsName) {
@@ -3732,7 +3418,7 @@ boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName,
*/
static boolean_t
-add_packages_in_global_with_zones(char **a_pkgList, char *a_uri,
+add_packages_in_global_with_zones(char **a_pkgList,
char *a_idsName, int a_repeat, char *a_altBinDir,
char *a_device, zoneList_t a_zlst)
{
@@ -3756,7 +3442,7 @@ static char *zoneAdminFile = (char *)NULL;
assert(a_zlst != (zoneList_t)NULL);
echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ENTRY);
- echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ARGS, npkgs, PSTR(a_uri),
+ echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ARGS, npkgs,
PSTR(a_idsName), a_repeat, PSTR(a_device));
/* create temporary directory for use by zone operations */
@@ -3812,7 +3498,7 @@ static char *zoneAdminFile = (char *)NULL;
pkgs[1] = (char *)NULL;
n = pkgtrans(packageDir, zoneStreamName, pkgs,
- PT_SILENT|PT_ODTSTREAM, NULL, NULL);
+ PT_SILENT|PT_ODTSTREAM);
if (n != 0) {
progerr(ERR_CANNOT_CONVERT_PKGSTRM,
pkginst, packageDir, zoneStreamName);
@@ -3963,8 +3649,7 @@ static char *zoneAdminFile = (char *)NULL;
respfile = respfile_path;
}
- echo(MSG_PROC_INST, pkginst,
- (a_uri && a_idsName) ? a_uri : a_device);
+ echo(MSG_PROC_INST, pkginst, a_device);
/*
* If we're installing another package in the same
@@ -4118,7 +3803,7 @@ static char *zoneAdminFile = (char *)NULL;
*/
static boolean_t
-add_packages_in_nonglobal_zone(char **a_pkgList, char *a_uri,
+add_packages_in_nonglobal_zone(char **a_pkgList,
char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
{
static char *zoneTempDir = (char *)NULL;
@@ -4137,7 +3822,7 @@ static char *zoneTempDir = (char *)NULL;
/* entry debugging info */
echoDebug(DBG_ADDPACKAGES_LZ_ENTRY);
- echoDebug(DBG_ADDPACKAGES_LZ_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
+ echoDebug(DBG_ADDPACKAGES_LZ_ARGS, npkgs, PSTR(a_idsName),
a_repeat, PSTR(a_device));
/* create temporary directory for use by zone operations */
@@ -4221,8 +3906,7 @@ static char *zoneTempDir = (char *)NULL;
respfile = respfile_path;
}
- echo(MSG_PROC_INST, pkginst,
- (a_uri && a_idsName) ? a_uri : a_device);
+ echo(MSG_PROC_INST, pkginst, a_device);
/*
* If we're installing another package in the same
@@ -4296,7 +3980,7 @@ static char *zoneTempDir = (char *)NULL;
*/
static boolean_t
-add_packages_in_global_no_zones(char **a_pkgList, char *a_uri,
+add_packages_in_global_no_zones(char **a_pkgList,
char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
{
int n;
@@ -4309,7 +3993,7 @@ add_packages_in_global_no_zones(char **a_pkgList, char *a_uri,
assert(a_pkgList != (char **)NULL);
echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ENTRY);
- echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ARGS, npkgs, PSTR(a_uri),
+ echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ARGS, npkgs,
PSTR(a_idsName), a_repeat, PSTR(a_device));
/*
@@ -4374,8 +4058,7 @@ add_packages_in_global_no_zones(char **a_pkgList, char *a_uri,
respfile = respfile_path;
}
- echo(MSG_PROC_INST, pkginst,
- (a_uri && a_idsName) ? a_uri : a_device);
+ echo(MSG_PROC_INST, pkginst, a_device);
/*
* If we're installing another package in the same
@@ -4446,7 +4129,7 @@ add_packages_in_global_no_zones(char **a_pkgList, char *a_uri,
*/
static boolean_t
-add_packages(char **a_pkgList, char *a_uri,
+add_packages(char **a_pkgList,
char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device,
boolean_t a_noZones)
{
@@ -4458,7 +4141,7 @@ add_packages(char **a_pkgList, char *a_uri,
assert(a_pkgList != (char **)NULL);
echoDebug(DBG_ADDPACKAGES_ENTRY);
- echoDebug(DBG_ADDPACKAGES_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
+ echoDebug(DBG_ADDPACKAGES_ARGS, npkgs, PSTR(a_idsName),
a_repeat, PSTR(a_altBinDir), PSTR(a_device));
/*
@@ -4480,7 +4163,7 @@ add_packages(char **a_pkgList, char *a_uri,
return (B_FALSE);
}
- b = add_packages_in_nonglobal_zone(a_pkgList, a_uri, a_idsName,
+ b = add_packages_in_nonglobal_zone(a_pkgList, a_idsName,
a_repeat, a_altBinDir, a_device);
(void) z_unlock_this_zone(ZLOCKS_ALL);
@@ -4524,7 +4207,7 @@ add_packages(char **a_pkgList, char *a_uri,
/* add packages to all zones */
- b = add_packages_in_global_with_zones(a_pkgList, a_uri,
+ b = add_packages_in_global_with_zones(a_pkgList,
a_idsName, a_repeat, a_altBinDir, a_device, zlst);
/* unlock all zones */
@@ -4551,7 +4234,7 @@ add_packages(char **a_pkgList, char *a_uri,
return (B_FALSE);
}
- b = add_packages_in_global_no_zones(a_pkgList, a_uri, a_idsName,
+ b = add_packages_in_global_no_zones(a_pkgList, a_idsName,
a_repeat, a_altBinDir, a_device);
(void) z_unlock_this_zone(ZLOCKS_ALL);
diff --git a/usr/src/cmd/svr4pkg/pkgadd/quit.c b/usr/src/cmd/svr4pkg/pkgadd/quit.c
index eb41e97fc1..f93273dbc4 100644
--- a/usr/src/cmd/svr4pkg/pkgadd/quit.c
+++ b/usr/src/cmd/svr4pkg/pkgadd/quit.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,7 +40,6 @@
#include <libintl.h>
#include <pkglib.h>
-#include <pkgweb.h>
#include <messages.h>
#include <libadm.h>
@@ -65,7 +68,6 @@ extern int warnflag; /* != 0 if non-fatal error has occurred (2) */
* forward declarations
*/
-static char *dwnldTempDir = (char *)NULL;
static char *idsName = (char *)NULL;
static char *zoneTempDir = (char *)NULL;
static ckreturnFunc_t *ckreturnFunc = (ckreturnFunc_t *)NULL;
@@ -79,7 +81,6 @@ static zoneList_t zoneList = (zoneList_t)NULL;
void quit(int retcode);
void quitSetCkreturnFunc(ckreturnFunc_t *a_ckreturnFunc);
-void quitSetDwnldTmpdir(char *a_dwnldTempDir);
void quitSetIdsName(char *a_idsName);
void quitSetZoneName(char *a_zoneName);
void quitSetZoneTmpdir(char *z_zoneTempDir);
@@ -201,23 +202,6 @@ quitSetZoneTmpdir(char *a_zoneTempDir)
}
/*
- * Name: quitSetDwnldTmpdir
- * Description: set the path to the "download temporary directory" in use
- * Arguments: a_dwnldTempDir - pointer to string representing the full path to
- * the temporary directory used to hold files used during
- * download operations
- * Returns: void
- * NOTE: If a download temporary directory is set when quit() is called,
- * the directory is recursively removed before quit() calls exit
- */
-
-void
-quitSetDwnldTmpdir(char *a_dwnldTempDir)
-{
- dwnldTempDir = a_dwnldTempDir;
-}
-
-/*
* Name: quit
* Description: cleanup and exit
* Arguments: a_retcode - the code to use to determine final exit status;
@@ -282,14 +266,6 @@ quit(int a_retcode)
(void) chdir("/");
- /* if set remove download temporary directory */
-
- if (dwnldTempDir != (char *)NULL) {
- echoDebug(DBG_REMOVING_DWNLD_TMPDIR, dwnldTempDir);
- (void) rrmdir(dwnldTempDir);
- dwnldTempDir = (char *)NULL;
- }
-
/* if set remove zone temporary directory */
if (zoneTempDir != (char *)NULL) {
@@ -305,17 +281,6 @@ quit(int a_retcode)
echoDebug(DBG_REMOVING_DSTREAM_TMPDIR, pkgdev.dirname);
(void) rrmdir(pkgdev.dirname); /* from tempnam */
}
- /*
- * cleanup after a web-based install.
- * web-based install failures
- * are indicated by exit codes 10-98
- * exit code 99 is fatal error exit.
- */
- if (pkgdev.pathname != NULL && is_web_install() &&
- (a_retcode == 0 ||
- (a_retcode >= 10 && a_retcode < 99))) {
- (void) web_cleanup();
- }
(void) ds_close(1);
} else if (pkgdev.mount) {
(void) pkgumount(&pkgdev);
diff --git a/usr/src/cmd/svr4pkg/pkgadd/quit.h b/usr/src/cmd/svr4pkg/pkgadd/quit.h
index 3b9a7d6b5f..463de0218a 100644
--- a/usr/src/cmd/svr4pkg/pkgadd/quit.h
+++ b/usr/src/cmd/svr4pkg/pkgadd/quit.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,7 +53,6 @@ extern "C" {
extern sighdlrFunc_t *quitGetTrapHandler(void);
extern void quit(int retcode);
extern void quitSetCkreturnFunc(ckreturnFunc_t *a_ckreturnFunc);
-extern void quitSetDwnldTmpdir(char *z_dwnldTempDir);
extern void quitSetIdsName(char *a_idsName);
extern void quitSetZoneName(char *a_zoneName);
extern void quitSetZoneTmpdir(char *z_zoneTempDir);
diff --git a/usr/src/cmd/svr4pkg/pkgadm/Makefile b/usr/src/cmd/svr4pkg/pkgadm/Makefile
index 620e32cf0d..5706ea704e 100644
--- a/usr/src/cmd/svr4pkg/pkgadm/Makefile
+++ b/usr/src/cmd/svr4pkg/pkgadm/Makefile
@@ -20,22 +20,19 @@
#
#
+# Copyright (c) 2017 Peter Tribble.
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
PROG= pkgadm
-OBJS= addcert.o \
- certs.o \
- listcert.o \
- lock.o \
- main.o \
- removecert.o
+OBJS= lock.o \
+ main.o
include $(SRC)/cmd/svr4pkg/Makefile.svr4pkg
-LDLIBS += -lpkg -ladm -lcrypto -lgen
+LDLIBS += -lpkg -ladm -lgen
.KEEP_STATE:
all: $(PROG)
diff --git a/usr/src/cmd/svr4pkg/pkgadm/addcert.c b/usr/src/cmd/svr4pkg/pkgadm/addcert.c
deleted file mode 100644
index 0a1c7bdec0..0000000000
--- a/usr/src/cmd/svr4pkg/pkgadm/addcert.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <signal.h>
-#include <locale.h>
-#include <sys/param.h>
-#include <openssl/bio.h>
-#include <openssl/x509v3.h>
-#include <openssl/ui.h>
-
-#include <pkglib.h>
-#include <libinst.h>
-#include <pkgerr.h>
-#include <keystore.h>
-#include "pkgadm.h"
-#include "pkgadm_msgs.h"
-
-typedef enum {
- VerifyFailed,
- Accept,
- Reject
-} VerifyStatus;
-
-static VerifyStatus verify_trust(X509 *);
-static boolean_t is_ca_cert(X509 *);
-
-/*
- * Name: addcert
- * Desc: Imports a user certificate into the keystore, along with a
- * private key.
- * Returns: 0 on success, non-zero otherwise.
- */
-int
-addcert(int argc, char **argv)
-{
- int i;
- char keystore_file[MAXPATHLEN] = "";
- char *keystore_base = NULL;
- char *homedir;
- char *passarg = NULL;
- char *import_passarg = NULL;
- char *altroot = NULL;
- char *prog = NULL;
- char *alias = NULL;
- char *infile = NULL;
- char *inkeyfile = NULL;
- keystore_encoding_format_t informat = NULL;
- char *informat_str = NULL;
- int ret = 1;
- boolean_t trusted = B_FALSE;
- boolean_t implicit_trust = B_FALSE;
-
- FILE *certfile = NULL;
- FILE *keyfile = NULL;
- X509 *cert = NULL;
- STACK_OF(X509) *trustcerts = NULL;
- EVP_PKEY *key = NULL;
- PKG_ERR *err = NULL;
- keystore_handle_t keystore = NULL;
-
- while ((i = getopt(argc, argv, ":a:k:e:f:n:P:p:R:ty")) != EOF) {
- switch (i) {
- case 'a':
- prog = optarg;
- break;
- case 'k':
- keystore_base = optarg;
- break;
- case 'e':
- inkeyfile = optarg;
- break;
- case 'f':
- informat_str = optarg;
- break;
- case 'n':
- alias = optarg;
- break;
- case 'P':
- passarg = optarg;
- break;
- case 'p':
- import_passarg = optarg;
- break;
- case 'R':
- altroot = optarg;
- break;
- case 't':
- trusted = B_TRUE;
- break;
- case 'y':
- implicit_trust = B_TRUE;
- break;
- case ':':
- log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt);
- /* LINTED fallthrough intentional */
- case '?':
- default:
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
- }
-
- if (!trusted && alias == NULL) {
- /* for untrusted (user) certs, we require a name */
- log_msg(LOG_MSG_ERR, MSG_USER_NAME);
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- } else if (trusted && alias != NULL) {
- /* for trusted certs, we cannot have a name */
- log_msg(LOG_MSG_ERR, MSG_TRUSTED_NAME);
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
-
- if (trusted && inkeyfile != NULL) {
- /* for trusted certs, we cannot have a private key */
- log_msg(LOG_MSG_ERR, MSG_TRUSTED_KEY);
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
-
- /* last argument should be the path to the certificate */
- if ((argc-optind) > 1) {
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- } else if ((argc-optind) < 1) {
- infile = "stdin";
- certfile = stdin;
- log_msg(LOG_MSG_DEBUG, "Loading stdin certificate");
- } else {
- infile = argv[optind];
- log_msg(LOG_MSG_DEBUG, "Loading <%s> certificate",
- argv[optind]);
- if ((certfile = fopen(infile, "r")) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_OPEN, infile);
- goto cleanup;
- }
- }
-
- /*
- * if specific key file supplied, open it, otherwise open
- * default (stdin)
- */
- if (inkeyfile != NULL) {
- if ((keyfile = fopen(inkeyfile, "r")) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_OPEN, inkeyfile);
- goto cleanup;
- }
- } else {
- inkeyfile = "stdin";
- keyfile = stdin;
- }
-
- /* set up proper keystore */
- if (altroot != NULL) {
- if (strlcpy(keystore_file, altroot, MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG, altroot);
- goto cleanup;
- }
-
- if (strlcat(keystore_file, "/", MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG, altroot);
- goto cleanup;
- }
- }
-
- if (keystore_base == NULL) {
- if (geteuid() == 0 || altroot != NULL) {
- /*
- * If we have an alternate
- * root, then we have no choice but to use
- * root's keystore on that alternate root,
- * since there is no way to resolve a
- * user's home dir given an alternate root
- */
- if (strlcat(keystore_file, PKGSEC,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- } else {
- if ((homedir = getenv("HOME")) == NULL) {
- /*
- * not superuser, but no home dir, so
- * use superuser's keystore
- */
- if (strlcat(keystore_file, PKGSEC,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- } else {
- if (strlcat(keystore_file, homedir,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- homedir);
- goto cleanup;
- }
- if (strlcat(keystore_file, "/.pkg/security",
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- }
- }
- } else {
- if (strlcat(keystore_file, keystore_base,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_base);
- goto cleanup;
- }
- }
-
- /* figure out input format */
- if (informat_str == NULL) {
- informat = KEYSTORE_FORMAT_PEM;
- } else {
- if (ci_streq(informat_str, "pem")) {
- informat = KEYSTORE_FORMAT_PEM;
- } else if (ci_streq(informat_str, "der")) {
- informat = KEYSTORE_FORMAT_DER;
- } else {
- log_msg(LOG_MSG_ERR, MSG_BAD_FORMAT, informat_str);
- goto cleanup;
- }
- }
-
- err = pkgerr_new();
-
- if (trusted) {
- /* load all possible certs */
- if (load_all_certs(err, certfile, informat, import_passarg,
- &trustcerts) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile);
- goto cleanup;
- }
-
- /* we must have gotten at least one cert, if not, fail */
- if (sk_X509_num(trustcerts) < 1) {
- log_msg(LOG_MSG_ERR, MSG_NO_CERTS, infile);
- goto cleanup;
- }
- } else {
- /* first, try to load user certificate and key */
- if (load_cert_and_key(err, certfile, informat, import_passarg,
- &key, &cert) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile);
- goto cleanup;
- }
-
- /* we must have gotten a cert, if not, fail */
- if (cert == NULL) {
- log_msg(LOG_MSG_ERR, MSG_NO_CERTS, infile);
- goto cleanup;
- }
-
- if (key == NULL) {
- /*
- * if we are importing a user cert, and did not get
- * a key, try to load it from the key file
- */
- if (keyfile == NULL) {
- log_msg(LOG_MSG_ERR, MSG_NEED_KEY, infile);
- goto cleanup;
- } else {
- log_msg(LOG_MSG_DEBUG,
- "Loading private key <%s>", inkeyfile);
- if (load_cert_and_key(err, keyfile, informat,
- import_passarg,
- &key, NULL) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR,
- MSG_NO_ADDKEY, inkeyfile);
- goto cleanup;
- }
-
- if (key == NULL) {
- log_msg(LOG_MSG_ERR, MSG_NO_PRIVKEY,
- inkeyfile);
- log_msg(LOG_MSG_ERR,
- MSG_NO_ADDKEY, inkeyfile);
- goto cleanup;
- }
- }
- }
- }
-
- if (trusted) {
- /* check validity date of all certificates */
- for (i = 0; i < sk_X509_num(trustcerts); i++) {
- /* LINTED pointer cast may result in improper algnmnt */
- cert = sk_X509_value(trustcerts, i);
- if (check_cert(err, cert) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT,
- infile);
- goto cleanup;
- }
- }
- } else {
- /* check validity date of user certificate */
- if (check_cert_and_key(err, cert, key) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile);
- goto cleanup;
- }
- }
-
- if (trusted && !implicit_trust) {
- /*
- * if importing more than one cert, must use implicit trust,
- * because we can't ask the user to individually trust
- * each one, since there may be many
- */
- if (sk_X509_num(trustcerts) != 1) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_MULTIPLE_TRUST, infile, "-y");
- goto cleanup;
- } else {
- /* LINTED pointer cast may result in improper algnmnt */
- cert = sk_X509_value(trustcerts, 0);
- }
-
- /* ask the user */
- switch (verify_trust(cert)) {
- case Accept:
- /* user accepted */
- break;
- case Reject:
- /* user aborted operation */
- log_msg(LOG_MSG_ERR, MSG_ADDCERT_ABORT);
- goto cleanup;
- case VerifyFailed:
- default:
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile);
- goto cleanup;
- }
- }
-
- /* now load the key store */
- log_msg(LOG_MSG_DEBUG, "Loading keystore <%s>", keystore_file);
-
- set_passphrase_prompt(MSG_KEYSTORE_PASSPROMPT);
- set_passphrase_passarg(passarg);
- if (open_keystore(err, keystore_file, prog, pkg_passphrase_cb,
- KEYSTORE_ACCESS_READWRITE | KEYSTORE_PATH_HARD, &keystore) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile);
- goto cleanup;
- }
-
- /* now merge the new cert into the keystore */
- log_msg(LOG_MSG_DEBUG, "Merging certificate <%s>",
- get_subject_display_name(cert));
- if (trusted) {
- /* merge all trusted certs found */
- for (i = 0; i < sk_X509_num(trustcerts); i++) {
- /* LINTED pointer cast may result in improper algnmnt */
- cert = sk_X509_value(trustcerts, i);
- if (merge_ca_cert(err, cert, keystore) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR,
- MSG_NO_ADDCERT, infile);
- goto cleanup;
-
- } else {
- log_msg(LOG_MSG_INFO, MSG_TRUSTING,
- get_subject_display_name(cert));
- }
- }
- } else {
- /* merge user cert */
- if (merge_cert_and_key(err, cert, key, alias, keystore) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile);
- goto cleanup;
- }
- }
-
- /* now write it back out */
- log_msg(LOG_MSG_DEBUG, "Closing keystore");
- set_passphrase_prompt(MSG_KEYSTORE_PASSOUTPROMPT);
- set_passphrase_passarg(passarg);
- if (close_keystore(err, keystore, pkg_passphrase_cb) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_ADDCERT, infile);
- goto cleanup;
- }
-
- if (trusted) {
- log_msg(LOG_MSG_INFO, MSG_TRUSTED, infile);
- } else {
- log_msg(LOG_MSG_INFO, MSG_ADDED, infile, alias);
- }
-
- ret = 0;
-
- /* fallthrough intentional */
-cleanup:
- if (err != NULL)
- pkgerr_free(err);
-
- if (certfile != NULL)
- (void) fclose(certfile);
-
- if (keyfile != NULL)
- (void) fclose(keyfile);
-
- return (ret);
- }
-
-/* Asks user to verify certificate data before proceeding */
-static VerifyStatus verify_trust(X509 *cert)
-{
- char vfy_trust = 'y';
- VerifyStatus ret = Accept;
- PKG_ERR *err;
- UI *ui = NULL;
-
- err = pkgerr_new();
- /* print cert data */
- if (print_cert(err, cert, KEYSTORE_FORMAT_TEXT,
- get_subject_display_name(cert), B_TRUE, stdout) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- ret = VerifyFailed;
- goto cleanup;
- }
-
- if ((ui = UI_new()) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_MEM);
- ret = VerifyFailed;
- goto cleanup;
- }
-
- /*
- * The prompt is internationalized, but the valid
- * response values are fixed, to avoid any complex
- * multibyte processing that results in bugs
- */
- if (UI_add_input_boolean(ui, MSG_VERIFY_TRUST,
- "",
- "yY", "nN",
- UI_INPUT_FLAG_ECHO, &vfy_trust) <= 0) {
- log_msg(LOG_MSG_ERR, MSG_MEM);
- ret = VerifyFailed;
- goto cleanup;
- }
-
- if (UI_process(ui) != 0) {
- log_msg(LOG_MSG_ERR, MSG_MEM);
- ret = VerifyFailed;
- goto cleanup;
- }
-
- if (vfy_trust != 'y') {
- ret = Reject;
- goto cleanup;
- }
-
- /*
- * if the cert does not appear to be a CA cert
- * r is not self-signed, verify that as well
- */
- if (!is_ca_cert(cert)) {
- UI_free(ui);
- if ((ui = UI_new()) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_MEM);
- ret = VerifyFailed;
- goto cleanup;
- }
-
- if (UI_add_input_boolean(ui,
- MSG_VERIFY_NOT_CA,
- "",
- "yY", "nN",
- UI_INPUT_FLAG_ECHO, &vfy_trust) <= 0) {
- ret = VerifyFailed;
- goto cleanup;
- }
-
- if (UI_process(ui) != 0) {
- log_msg(LOG_MSG_ERR, MSG_MEM);
- ret = VerifyFailed;
- goto cleanup;
- }
-
- if (vfy_trust != 'y') {
- ret = Reject;
- goto cleanup;
- }
- }
-
-cleanup:
- if (ui != NULL)
- UI_free(ui);
-
- if (err != NULL)
- pkgerr_free(err);
-
- return (ret);
-}
-/*
- * Name: is_ca_cert
- * Desc: Determines if a given certificate has the attributes
- * of a CA certificate
- * Returns: B_TRUE if certificate has attributes of a CA cert
- * B_FALSE otherwise
- */
-static boolean_t
-is_ca_cert(X509 *x)
-{
-
- /*
- * X509_check_purpose causes the extensions that we
- * care about to be decoded and stored in the X509
- * structure, so we must call it first
- * before checking for CA extensions in the X509
- * structure
- */
- (void) X509_check_purpose(x, X509_PURPOSE_ANY, 0);
-
- /* keyUsage if present should allow cert signing */
- if ((x->ex_flags & EXFLAG_KUSAGE) &&
- !(x->ex_kusage & KU_KEY_CERT_SIGN)) {
- return (B_FALSE);
- }
-
- /* If basicConstraints says not a CA then say so */
- if (x->ex_flags & EXFLAG_BCONS) {
- if (!(x->ex_flags & EXFLAG_CA)) {
- return (B_FALSE);
- }
- }
-
- /* no explicit not-a-CA flags set, so assume that it is */
- return (B_TRUE);
-}
diff --git a/usr/src/cmd/svr4pkg/pkgadm/certs.c b/usr/src/cmd/svr4pkg/pkgadm/certs.c
deleted file mode 100644
index c7c8f045ae..0000000000
--- a/usr/src/cmd/svr4pkg/pkgadm/certs.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <stdio.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <pkglocs.h>
-#include <locale.h>
-#include <libintl.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <libintl.h>
-#include <dirent.h>
-#include <openssl/err.h>
-#include <openssl/pkcs7.h>
-#include <openssl/pkcs12.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/x509v3.h>
-
-#include <pkglib.h>
-#include <p12lib.h>
-#include <install.h>
-#include <libadm.h>
-#include <libinst.h>
-#include "pkgadm.h"
-#include "pkgadm_msgs.h"
-
-
-/*
- * Function: load_cert_and_key
- * Description: Loads a public key certificate and associated private key
- * from a stream.
- * Parameters: err - Where to write errors to for underlying library calls
- * incert - File to read certs and keys from
- * format - The format of the file
- * passarg - How to collect password if needed to decrypt file
- * key - Location to store resulting key if found
- * cert - Location to store resulting cert if found.
- *
- * Returns: f one or more certificates are found in the file,
- * and one or more keys are found, then the first
- * certificate is used, and the keys are searched for a
- * match. If no key matches the cert, then only the cert
- * is returned. If no certs are found, but one or more
- * keys are found, then the first key is returned.
- */
-int
-load_cert_and_key(PKG_ERR *err, FILE *incert,
- keystore_encoding_format_t format, char *passarg, EVP_PKEY **key,
- X509 **cert)
-{
- X509 *tmpcert = NULL;
- EVP_PKEY *tmpkey = NULL;
- STACK_OF(EVP_PKEY) *keys = NULL;
- STACK_OF(X509) *certs = NULL;
- int i, ret = 0;
- keystore_passphrase_data data;
- unsigned long crypto_err;
-
- if (key) *key = NULL;
- if (cert) *cert = NULL;
-
- switch (format) {
- case KEYSTORE_FORMAT_DER:
- /* first try to load a DER cert, which cannot contain a key */
- if ((tmpcert = d2i_X509_fp(incert, NULL)) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_PARSE);
- ret = 1;
- }
- break;
- case KEYSTORE_FORMAT_PEM:
- default:
- data.err = err;
- set_passphrase_passarg(passarg);
- set_passphrase_prompt(gettext("Enter PEM passphrase:"));
- if (sunw_PEM_contents(incert, pkg_passphrase_cb,
- &data, &keys, &certs) < 0) {
- /* print out openssl-generated PEM errors */
- while ((crypto_err = ERR_get_error()) != 0) {
- log_msg(LOG_MSG_ERR,
- ERR_reason_error_string(crypto_err));
- }
- ret = 1;
- goto cleanup;
- }
-
- /* take the first cert in the file, if any */
- if (cert && (certs != NULL)) {
- if (sk_X509_num(certs) != 1) {
- log_msg(LOG_MSG_ERR, MSG_MULTIPLE_CERTS);
- ret = 1;
- goto cleanup;
- } else {
- tmpcert = sk_X509_value(certs, 0);
- }
- }
-
- if (key && (keys != NULL)) {
- if (tmpcert != NULL) {
- /*
- * if we found a cert and some keys,
- * only return the key that
- * matches the cert
- */
- for (i = 0; i < sk_EVP_PKEY_num(keys); i++) {
- if (X509_check_private_key(tmpcert,
- sk_EVP_PKEY_value(keys, i))) {
- tmpkey =
- sk_EVP_PKEY_value(keys, i);
- break;
- }
- }
- } else {
- if (sk_EVP_PKEY_num(keys) > 0) {
- tmpkey = sk_EVP_PKEY_value(keys, 0);
- }
- }
- }
- break;
- }
-
- /* set results */
- if (key && tmpkey) {
- *key = tmpkey;
- tmpkey = NULL;
- }
-
- if (cert && tmpcert) {
- *cert = tmpcert;
- tmpcert = NULL;
- }
-
-cleanup:
- if (tmpcert != NULL) {
- X509_free(tmpcert);
- }
- if (tmpkey != NULL) {
- sunw_evp_pkey_free(tmpkey);
- }
- return (ret);
-}
-
-/*
- * Function: load_all_certs
- * Description: Loads alll certificates from a stream.
- * Parameters: err - Where to write errors to for underlying library calls
- * incert - File to read certs and keys from
- * format - The format of the file
- * passarg - How to collect password if needed to decrypt file
- * certs - Location to store resulting cert if found.
- *
- * Returns: 0 - success, all certs placed in ''certs'
- * non-zero failure, errors in 'err'
- */
-int
-load_all_certs(PKG_ERR *err, FILE *incert,
- keystore_encoding_format_t format, char *passarg, STACK_OF(X509) **certs)
-{
- X509 *tmpcert = NULL;
- STACK_OF(X509) *tmpcerts = NULL;
- int ret = 0;
- keystore_passphrase_data data;
- unsigned long crypto_err;
- if (certs) *certs = NULL;
-
- switch (format) {
- case KEYSTORE_FORMAT_DER:
- /* first try to load a DER cert, which cannot contain a key */
- if ((tmpcert = d2i_X509_fp(incert, NULL)) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_PARSE);
- ret = 1;
- goto cleanup;
- }
-
- if ((tmpcerts = sk_X509_new_null()) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_MEM);
- ret = 1;
- goto cleanup;
- }
- sk_X509_push(tmpcerts, tmpcert);
- break;
- case KEYSTORE_FORMAT_PEM:
- default:
- data.err = err;
- set_passphrase_prompt(MSG_PEM_PASSPROMPT);
- set_passphrase_passarg(passarg);
- if (sunw_PEM_contents(incert, pkg_passphrase_cb,
- &data, NULL, &tmpcerts) < 0) {
- /* print out openssl-generated PEM errors */
- while ((crypto_err = ERR_get_error()) != 0) {
- log_msg(LOG_MSG_ERR,
- ERR_reason_error_string(crypto_err));
- }
- }
- break;
- }
-
- /* set results */
- if (certs && tmpcerts) {
- *certs = tmpcerts;
- tmpcerts = NULL;
- }
-
-cleanup:
- if (tmpcerts != NULL) {
- sk_X509_free(tmpcerts);
- }
- return (ret);
-}
diff --git a/usr/src/cmd/svr4pkg/pkgadm/listcert.c b/usr/src/cmd/svr4pkg/pkgadm/listcert.c
deleted file mode 100644
index 731427271f..0000000000
--- a/usr/src/cmd/svr4pkg/pkgadm/listcert.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <signal.h>
-#include <locale.h>
-#include <sys/param.h>
-#include <openssl/bio.h>
-
-#include <libinst.h>
-#include <pkglib.h>
-#include <pkgerr.h>
-#include <keystore.h>
-#include "pkgadm.h"
-#include "pkgadm_msgs.h"
-
-/*
- * Name: listcert
- * Desc: Lists one or more certificates from the keystore
- * Syntax: listcert [-a app] [-f format] [-k keystore] \
- * [-n name] [-o outfile] [-P passarg] [-R altroot]
- */
-int
-listcert(int argc, char **argv)
-{
- int i;
- char keystore_file[MAXPATHLEN] = "";
- char *keystore_base = NULL;
- char *homedir;
- char *passarg = NULL;
- char *altroot = NULL;
- char *prog = NULL;
- char *format_str = NULL;
- keystore_encoding_format_t format;
- char *alias = NULL;
- char *outfile_str = NULL;
- FILE *outfile = NULL;
- int ret = 1;
- PKG_ERR *err = NULL;
- keystore_handle_t keystore = NULL;
-
- while ((i = getopt(argc, argv, ":a:f:k:n:o:P:R:")) != EOF) {
- switch (i) {
- case 'a':
- prog = optarg;
- break;
- case 'f':
- format_str = optarg;
- break;
- case 'k':
- keystore_base = optarg;
- break;
- case 'n':
- alias = optarg;
- break;
- case 'o':
- outfile_str = optarg;
- break;
- case 'P':
- passarg = optarg;
- break;
- case 'R':
- altroot = optarg;
- break;
- case ':':
- log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt);
- /* fallthrough intentional */
- case '?':
- default:
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
- }
-
- /* should be no arguments left */
- if ((argc-optind) > 0) {
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
-
- /* figure out format */
- if (format_str == NULL) {
- format = KEYSTORE_FORMAT_TEXT;
- } else {
- if (ci_streq(format_str, "text")) {
- format = KEYSTORE_FORMAT_TEXT;
- } else if (ci_streq(format_str, "pem")) {
- format = KEYSTORE_FORMAT_PEM;
- } else if (ci_streq(format_str, "der")) {
- format = KEYSTORE_FORMAT_DER;
- } else {
- log_msg(LOG_MSG_ERR, MSG_BAD_FORMAT, format_str);
- goto cleanup;
- }
- }
-
- /* open output file */
- if (outfile_str == NULL) {
- outfile = stdout;
- outfile_str = "stdout";
- } else {
- if ((outfile = fopen(outfile_str, "w+")) == NULL) {
- log_msg(LOG_MSG_ERR, MSG_OPEN_WRITE, outfile_str);
- goto cleanup;
- }
- }
-
- /* set up proper keystore */
- if (altroot != NULL) {
- if (strlcpy(keystore_file, altroot, MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG, altroot);
- goto cleanup;
- }
-
- if (strlcat(keystore_file, "/", MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG, altroot);
- goto cleanup;
- }
- }
-
- if (keystore_base == NULL) {
- if (geteuid() == 0 || altroot != NULL) {
- /*
- * If we have an alternate
- * root, then we have no choice but to use
- * root's keystore on that alternate root,
- * since there is no way to resolve a
- * user's home dir given an alternate root
- */
- if (strlcat(keystore_file, PKGSEC,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- } else {
- if ((homedir = getenv("HOME")) == NULL) {
- /*
- * not superuser, but no home dir, so
- * use superuser's keystore
- */
- if (strlcat(keystore_file, PKGSEC,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- } else {
- if (strlcat(keystore_file, homedir,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- homedir);
- goto cleanup;
- }
- if (strlcat(keystore_file, "/.pkg/security",
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- }
- }
- } else {
- if (strlcat(keystore_file, keystore_base,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_base);
- goto cleanup;
- }
- }
- err = pkgerr_new();
-
- /* now load the key store */
- log_msg(LOG_MSG_DEBUG, "Loading keystore <%s>", keystore_file);
-
- set_passphrase_prompt(MSG_KEYSTORE_PASSPROMPT);
- set_passphrase_passarg(passarg);
- if (open_keystore(err, keystore_file, prog,
- pkg_passphrase_cb, KEYSTORE_DFLT_FLAGS,
- &keystore) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_PRINT, outfile_str);
- goto cleanup;
- }
-
- /* list the certs */
- log_msg(LOG_MSG_DEBUG, "Listing certificates");
- if (print_certs(err, keystore, alias, format, outfile) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_PRINT, outfile_str);
- goto cleanup;
- }
-
- /* now close it out */
- log_msg(LOG_MSG_DEBUG, "Closing keystore");
- set_passphrase_prompt(MSG_KEYSTORE_PASSOUTPROMPT);
- set_passphrase_passarg(passarg);
- if (close_keystore(err, keystore, pkg_passphrase_cb) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_PRINT, outfile_str);
- goto cleanup;
- }
-
- /* everything worked */
- ret = 0;
-
- /* fallthrough intentional */
-cleanup:
- if (outfile != NULL)
- (void) fclose(outfile);
-
- if (err != NULL)
- pkgerr_free(err);
-
- return (ret);
-}
diff --git a/usr/src/cmd/svr4pkg/pkgadm/lock.c b/usr/src/cmd/svr4pkg/pkgadm/lock.c
index 7963fd5d5b..7832cd3eae 100644
--- a/usr/src/cmd/svr4pkg/pkgadm/lock.c
+++ b/usr/src/cmd/svr4pkg/pkgadm/lock.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -58,7 +62,6 @@
#include <locale.h>
#include <libgen.h>
#include <sys/param.h>
-#include <openssl/bio.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
@@ -69,8 +72,6 @@
#include <libinst.h>
#include <pkglib.h>
-#include <pkgerr.h>
-#include <keystore.h>
#include "pkgadm.h"
#include "pkgadm_msgs.h"
diff --git a/usr/src/cmd/svr4pkg/pkgadm/main.c b/usr/src/cmd/svr4pkg/pkgadm/main.c
index 91eda6947d..cd07946284 100644
--- a/usr/src/cmd/svr4pkg/pkgadm/main.c
+++ b/usr/src/cmd/svr4pkg/pkgadm/main.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,19 +39,12 @@
#include <unistd.h>
#include <locale.h>
#include <sys/param.h>
-#include <openssl/bio.h>
#include <pkglib.h>
-#include <pkgerr.h>
-#include <keystore.h>
#include "pkgadm.h"
#include "pkgadm_msgs.h"
#include "libadm.h"
-/* initial error message buffer size */
-
-#define ERR_BUFSIZE 2048
-
/* Local Function Prototypes */
static void print_version();
@@ -68,15 +65,6 @@ struct cmd cmds[] = {
{ NULL, NULL }
};
-struct cmd cert_cmds[] = {
- { "addcert", addcert},
- { "listcert", listcert},
- { "removecert", removecert},
- /* last one must be all NULLs */
- { NULL, NULL }
-};
-
-
/*
* Function: main
*
@@ -137,20 +125,6 @@ main(int argc, char **argv)
}
}
- /* initialize security library */
- sec_init();
-
- /* OK, hand it off to the subcommand processors */
- for (cur_cmd = 0; cert_cmds[cur_cmd].c_name != NULL; cur_cmd++) {
- if (ci_streq(argv[optind], cert_cmds[cur_cmd].c_name)) {
- /* make subcommand the first option */
- newargc = argc - optind;
- newargv = argv + optind;
- opterr = optind = 1; optopt = 0;
- return (cert_cmds[cur_cmd].c_func(newargc, newargv));
- }
- }
-
/* bad subcommand */
log_msg(LOG_MSG_ERR, MSG_BAD_SUB, argv[optind]);
log_msg(LOG_MSG_INFO, MSG_USAGE);
@@ -184,23 +158,6 @@ get_verbose()
}
/*
- * Name: log_pkgerr
- * Description: Outputs pkgerr messages to logging facility.
- * Scope: public
- * Arguments: type - the severity of the message
- * err - error stack to dump to facility
- * Returns: none
- */
-void
-log_pkgerr(LogMsgType type, PKG_ERR *err)
-{
- int i;
- for (i = 0; i < pkgerr_num(err); i++) {
- log_msg(type, "%s", pkgerr_get(err, i));
- }
-}
-
-/*
* Name: print_Version
* Desc: Prints Version of packaging tools
* Arguments: none
diff --git a/usr/src/cmd/svr4pkg/pkgadm/pkgadm.h b/usr/src/cmd/svr4pkg/pkgadm/pkgadm.h
index 8911389517..8c338e3eb0 100644
--- a/usr/src/cmd/svr4pkg/pkgadm/pkgadm.h
+++ b/usr/src/cmd/svr4pkg/pkgadm/pkgadm.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,8 +36,6 @@
extern "C" {
#endif
-#include <pkgerr.h>
-#include <keystore.h>
#include "pkglib.h"
#include "libinst.h"
@@ -52,23 +54,10 @@ extern "C" {
/* main.c */
extern void log_msg(LogMsgType, const char *, ...);
-extern void log_pkgerr(LogMsgType, PKG_ERR *);
extern void set_verbose(boolean_t);
extern boolean_t get_verbose(void);
/* lock.c */
extern int admin_lock(int, char **);
-/* listcert.c */
-extern int listcert(int, char **);
-/* importcert.c */
-extern int addcert(int, char **);
-/* removecert.c */
-extern int removecert(int, char **);
-
-/* certs.c */
-extern int load_cert_and_key(PKG_ERR *, FILE *,
- keystore_encoding_format_t, char *, EVP_PKEY **, X509 **);
-extern int load_all_certs(PKG_ERR *, FILE *,
- keystore_encoding_format_t, char *, STACK_OF(X509) **);
#define PKGADM_DBSTATUS_TEXT "text"
diff --git a/usr/src/cmd/svr4pkg/pkgadm/pkgadm_msgs.h b/usr/src/cmd/svr4pkg/pkgadm/pkgadm_msgs.h
index bc6b9aaf7e..fb9f494393 100644
--- a/usr/src/cmd/svr4pkg/pkgadm/pkgadm_msgs.h
+++ b/usr/src/cmd/svr4pkg/pkgadm/pkgadm_msgs.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,24 +52,6 @@ extern "C" {
#define MSG_USAGE gettext(\
"usage:\n" \
"\n" \
-"pkgadm addcert [-ty] [-a app] [-k keystore] [-e keyfile]\n" \
-"\t[-f format] [-n name] [-P passarg] [-p input_passarg]\n" \
-"\t[-R rootpath] certfile\n" \
-"\n" \
-"\t- Adds a trusted CA certificate or user certificate\n" \
-"\tand private key\n" \
-"\n" \
-"pkgadm removecert [-a app] [-k keystore] -n name [-P passarg]\n" \
-"\t[-R rootpath]\n" \
-"\n" \
-"\t- Removes a trusted CA certificate or user certificate\n" \
-"\tand private key\n" \
-"\n" \
-"pkgadm listcert [-a app] [-f format] [-k keystore] -n name\n" \
-"\t[-P passarg] [-o outfile] [-R rootpath]\n" \
-"\n" \
-"\t- Prints trusted CA certificates or user certificates\n" \
-"\n" \
"pkgadm dbstatus [-R rootpath]\n" \
"\n" \
"\t- Returns 'text' - the text install database in use since Solaris 2.0\n" \
@@ -97,16 +83,6 @@ extern "C" {
#define MSG_T_RESULT_THREE gettext(\
"required <%d> actual <%d> <%30s> ~- <%30s>\n")
-#define MSG_KEYSTORE_PASSPROMPT gettext(\
- "Enter Keystore Password: ")
-
-#define MSG_KEYSTORE_PASSOUTPROMPT gettext(\
- "Type a Keystore protection Password.\n" \
- "Press ENTER for no protection password (not recommended): ")
-
-#define MSG_PEM_PASSPROMPT gettext(\
- "Enter PEM Passphrase: ")
-
#define MSG_ERROR gettext(\
"ERROR")
@@ -115,20 +91,11 @@ extern "C" {
#define CREATE_PKGDIR_WARN gettext(\
"Creating directory <%s>\n")
-#define MSG_WRN_UNKNOWN gettext(\
- "Signer <%s> has unsupported signature, ignoring")
-
#define MSG_VALID_STALE gettext(\
"Removing stale lock on <%s> pid <%ld> zid <%ld>")
/* errors */
-#define MSG_FATAL gettext(\
- "Fatal Error")
-
-#define MSG_TOO_LONG gettext(\
- "Length of <%s> exceeds maximum allowed length")
-
#define MSG_INTERNAL gettext(\
"Intenal Error <%s>")
@@ -138,121 +105,9 @@ extern "C" {
#define MSG_OPEN_WRITE gettext(\
"Cannot open <%s> for writing")
-#define MSG_BAD_PASSARG gettext(\
- "Invalid password retrieval method <%s>")
-
-#define MSG_BAD_PASS gettext(\
- "Invalid password")
-
#define ERR_LOG_FAIL gettext(\
"Failed to log message using format <%s>")
-#define MSG_BAD_FORMAT gettext(\
- "Invalid format: <%s>")
-
-#define MSG_USER_NAME gettext(\
- "An alias is required when adding user certificates")
-
-#define MSG_TRUSTED_NAME gettext(\
- "Trusted certificates cannot have an explicit alias")
-
-#define MSG_MULTIPLE_TRUST gettext(\
- "Found multiple certificates in <%s>. You must explicitly trust " \
- "them using <%s>")
-
-#define MSG_NO_MULTIPLE_TRUST gettext(\
- "Found multiple certificates in <%s>. You must explicitly trust " \
- "them using <%s>")
-
-#define MSG_TRUSTED_KEY gettext(\
- "Cannot supply private key when adding trusted certificates")
-
-#define MSG_TRUST_KEY_FOUND gettext(\
- "One or more private keys were found in trusted certificate file <%s>")
-
-#define MSG_ADDCERT_ABORT gettext(\
- "Addition of trusted certificate aborted by user request")
-
-
-#define MSG_NEED_KEY gettext(\
- "No private key found in <%s>, must specify one with -e")
-
-#define MSG_NO_PRIVKEY gettext(\
- "No private key found in <%s>")
-
-#define MSG_NO_CERTS gettext(\
- "No certificates found in <%s>")
-
-#define MSG_MULTIPLE_CERTS gettext(\
- "Multiple certificates found in <%s>")
-
-#define MSG_NO_ADDCERT gettext(\
- "Cannot add certificate(s) from <%s>. No changes have been made.")
-
-#define MSG_NO_ADDKEY gettext(\
- "Cannot add private key from <%s>. No changes have been made.")
-
-#define MSG_NO_REMOVECERT gettext(\
- "Cannot remove certificate with alias <%s>")
-
-#define MSG_VERIFY_TRUST gettext(\
- "Are you sure you want to trust this certificate? ")
-
-#define MSG_VERIFY_NOT_CA gettext(\
- "\n" \
- "This certificate does not appear to be issued and signed\n" \
- "by a certificate authority (CA). CA Certificates are normally\n" \
- "self-signed and have CA Basic Constraints.\n" \
- "Are you sure you want to trust this certificate? ")
-
-#define MSG_PARSE gettext(\
- "Parsing error")
-
-#define MSG_TRUSTED gettext(\
- "Certificate(s) from <%s> are now trusted")
-
-#define MSG_TRUSTING gettext(\
- "Trusting certificate <%s>")
-
-#define MSG_ADDED gettext(\
- "Successfully added Certificate <%s> with alias <%s>")
-
-#define MSG_REMOVED gettext(\
- "Successfully removed Certificate(s) with alias <%s>")
-
-#define MSG_MEM gettext(\
- "Out of memory")
-
-#define MSG_PRINT gettext(\
- "Cannot print certificates to <%s>")
-
-#define MSG_PROBLEM_CONVERT gettext(\
- "Does %s/var/sadm exist? Can the user write to it? (%s)")
-
-#define MSG_CONTENTS_FORMAT gettext(\
- "Operation failed due to corrupted install contents data file.")
-
-#define MSG_MKDIR_FAILED gettext(\
- "Could not mkdir for path %s. %s.")
-
-#define MSG_RENAME_FAILED gettext(\
- "Could not rename %s to %s\n%s")
-
-#define MSG_REMOVE_FAILED gettext(\
- "Could not remove %s\n%s")
-
-#define MSG_FILE_ACCESS gettext(\
- "Operation failed: unable to access file %s: %s")
-
-#define MSG_NOT_READABLE gettext(\
- "Operation failed: unable to read file %s")
-
-#define MSG_BUILD_INDEXES gettext(\
- "Operation failed: unable to build indexes\n")
-
-#define MSG_FILE_NAME_TOO_LONG gettext(\
- "Operation failed: file name too long: %s\n")
-
#define MSG_ZONES_MISSING_REQUEST gettext(\
"Must specify operation to perform\n")
diff --git a/usr/src/cmd/svr4pkg/pkgadm/removecert.c b/usr/src/cmd/svr4pkg/pkgadm/removecert.c
deleted file mode 100644
index 3a176b6184..0000000000
--- a/usr/src/cmd/svr4pkg/pkgadm/removecert.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <signal.h>
-#include <locale.h>
-#include <sys/param.h>
-#include <openssl/bio.h>
-
-#include <libinst.h>
-#include <pkglib.h>
-#include <pkgerr.h>
-#include <keystore.h>
-#include "pkgadm.h"
-#include "pkgadm_msgs.h"
-
-/*
- * Name: removecert
- * Desc: Removes a user certificate and associated private key,
- * or a trusted certificate, from the keystore.
- * Syntax: addcert [-a app] [-k keystore] -n name [-P passarg] [-R altroot]
- */
-int
-removecert(int argc, char **argv)
-{
- int i;
- char keystore_file[MAXPATHLEN] = "";
- char *keystore_base = NULL;
- char *homedir;
- char *passarg = NULL;
- char *altroot = NULL;
- char *prog = NULL;
- char *alias = NULL;
- int ret = 1;
- PKG_ERR *err = NULL;
- keystore_handle_t keystore = NULL;
-
- while ((i = getopt(argc, argv, ":a:k:n:P:R:")) != EOF) {
- switch (i) {
- case 'a':
- prog = optarg;
- break;
- case 'k':
- keystore_base = optarg;
- break;
- case 'n':
- alias = optarg;
- break;
- case 'P':
- passarg = optarg;
- break;
- case 'R':
- altroot = optarg;
- break;
- case ':':
- log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt);
- /* fallthrough intentional */
- case '?':
- default:
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
- }
-
- /* we require a name */
- if (alias == NULL) {
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
-
- /* should be no arguments left */
- if ((argc-optind) > 0) {
- log_msg(LOG_MSG_ERR, MSG_USAGE);
- goto cleanup;
- }
-
- /* set up proper keystore */
- if (keystore_base == NULL) {
- if (geteuid() == 0 || altroot != NULL) {
- /*
- * If we have an alternate
- * root, then we have no choice but to use
- * root's keystore on that alternate root,
- * since there is no way to resolve a
- * user's home dir given an alternate root
- */
- if (strlcat(keystore_file, PKGSEC,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- } else {
- if ((homedir = getenv("HOME")) == NULL) {
- /*
- * not superuser, but no home dir, so
- * use superuser's keystore
- */
- if (strlcat(keystore_file, PKGSEC,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- } else {
- if (strlcat(keystore_file, homedir,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- homedir);
- goto cleanup;
- }
- if (strlcat(keystore_file, "/.pkg/security",
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_file);
- goto cleanup;
- }
- }
- }
- } else {
- if (strlcat(keystore_file, keystore_base,
- MAXPATHLEN) >= MAXPATHLEN) {
- log_msg(LOG_MSG_ERR, MSG_TOO_LONG,
- keystore_base);
- goto cleanup;
- }
- }
-
- err = pkgerr_new();
-
- /* now load the key store */
- log_msg(LOG_MSG_DEBUG, "Loading keystore <%s>", keystore_file);
-
- set_passphrase_prompt(MSG_KEYSTORE_PASSPROMPT);
- set_passphrase_passarg(passarg);
-
- if (open_keystore(err, keystore_file, prog, pkg_passphrase_cb,
- KEYSTORE_ACCESS_READWRITE | KEYSTORE_PATH_HARD, &keystore) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- goto cleanup;
- }
-
- /* now remove the selected certs */
- log_msg(LOG_MSG_DEBUG, "Removing certificate(s) with name <%s>",
- alias);
- if (delete_cert_and_keys(err, keystore, alias) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_REMOVECERT, alias);
- goto cleanup;
- }
-
- /* now write it back out */
- log_msg(LOG_MSG_DEBUG, "Closing keystore");
- set_passphrase_prompt(MSG_KEYSTORE_PASSOUTPROMPT);
- set_passphrase_passarg(passarg);
- if (close_keystore(err, keystore, pkg_passphrase_cb) != 0) {
- log_pkgerr(LOG_MSG_ERR, err);
- log_msg(LOG_MSG_ERR, MSG_NO_REMOVECERT, alias);
- goto cleanup;
- }
-
- log_msg(LOG_MSG_INFO, MSG_REMOVED, alias);
-
- ret = 0;
- /* fallthrough intentional */
-cleanup:
-
- if (err != NULL)
- pkgerr_free(err);
-
- return (ret);
-}
diff --git a/usr/src/cmd/svr4pkg/pkgchk/main.c b/usr/src/cmd/svr4pkg/pkgchk/main.c
index 23951c11c4..af2e415783 100644
--- a/usr/src/cmd/svr4pkg/pkgchk/main.c
+++ b/usr/src/cmd/svr4pkg/pkgchk/main.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -412,8 +416,7 @@ main(int argc, char *argv[])
progerr(gettext(ERR_MKDIR), spooldir);
quit(99);
}
- if (n = pkgtrans(device, spooldir, pkg, PT_SILENT,
- NULL, NULL))
+ if (n = pkgtrans(device, spooldir, pkg, PT_SILENT))
quit(n);
if (catg_arg != NULL)
pkg = gpkglist(spooldir, all_pkgs, category);
diff --git a/usr/src/cmd/svr4pkg/pkginstall/instvol.c b/usr/src/cmd/svr4pkg/pkginstall/instvol.c
index cdf8eb045d..3b645a4abb 100644
--- a/usr/src/cmd/svr4pkg/pkginstall/instvol.c
+++ b/usr/src/cmd/svr4pkg/pkginstall/instvol.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -56,7 +60,6 @@
*/
#include <pkglib.h>
-#include <pkgweb.h>
/*
* local pkg command library includes
@@ -159,7 +162,7 @@ instvol(struct cfextra **extlist, char *srcinst, int part,
/*
* r_updated is an optional parameter that can be passed in
- * by the caller if the caller wants to know if any objects are
+ * by the caller if the caller wants to know if any objects are
* updated. Do not initialize r_updated; the call to instvol
* could be cumulative and any previous update indication must not
* be disturbed - this flag is only set, it must never be reset.
diff --git a/usr/src/cmd/svr4pkg/pkginstall/main.c b/usr/src/cmd/svr4pkg/pkginstall/main.c
index 5fc0a69fef..297b05b6ca 100644
--- a/usr/src/cmd/svr4pkg/pkginstall/main.c
+++ b/usr/src/cmd/svr4pkg/pkginstall/main.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -51,7 +55,6 @@
#include <assert.h>
#include <instzones_api.h>
#include <pkglib.h>
-#include <pkgweb.h>
#include <install.h>
#include <libinst.h>
#include <libadm.h>
diff --git a/usr/src/cmd/svr4pkg/pkgremove/main.c b/usr/src/cmd/svr4pkg/pkgremove/main.c
index 03632902ac..8209b52158 100644
--- a/usr/src/cmd/svr4pkg/pkgremove/main.c
+++ b/usr/src/cmd/svr4pkg/pkgremove/main.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -121,7 +125,6 @@ static char pkgbin[PATH_MAX],
*admnfile, /* file to use for installation admin */
*tmpdir; /* location to place temporary files */
-static boolean_t path_valid(char *path);
static void ckreturn(int retcode, char *msg);
static void rmclass(char *aclass, int rm_remote, char *a_zoneName);
static void usage(void);
@@ -1352,28 +1355,3 @@ usage(void)
exit(1);
}
-
-/*
- * Name: path_valid
- * Description: Checks a string for being a valid path
- *
- * Arguments: path - path to validate
- *
- * Returns : B_TRUE - success, B_FALSE otherwise.
- * B_FALSE means path was null, too long (>PATH_MAX),
- * or too short (<1)
- */
-static boolean_t
-path_valid(char *path)
-{
- if (path == NULL) {
- return (B_FALSE);
- } else if (strlen(path) > PATH_MAX) {
- return (B_FALSE);
- } else if (strlen(path) >= 1) {
- return (B_TRUE);
- } else {
- /* path < 1 */
- return (B_FALSE);
- }
-}
diff --git a/usr/src/cmd/svr4pkg/pkgrm/main.c b/usr/src/cmd/svr4pkg/pkgrm/main.c
index 7df5c39bc8..39a0846704 100644
--- a/usr/src/cmd/svr4pkg/pkgrm/main.c
+++ b/usr/src/cmd/svr4pkg/pkgrm/main.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -190,7 +194,6 @@ static boolean_t check_applicability(char *a_packageDir,
char *a_pkgInst, char *a_rootPath,
CAF_T a_flags);
static boolean_t check_packages(char **a_pkgList, char *a_packageDir);
-static boolean_t path_valid(char *path);
static boolean_t remove_packages(char **a_pkgList, int a_nodelete,
int a_longestPkg, int a_repeat,
char *a_altBinDir, char *a_pkgdir,
@@ -2643,31 +2646,6 @@ remove_packages(char **a_pkgList, int a_nodelete, int a_longestPkg,
}
/*
- * Name: path_valid
- * Description: Checks a string for being a valid path
- *
- * Arguments: path - path to validate
- *
- * Returns : B_TRUE - success, B_FALSE otherwise.
- * B_FALSE means path was null, too long (>PATH_MAX),
- * or too short (<1)
- */
-static boolean_t
-path_valid(char *path)
-{
- if (path == NULL) {
- return (B_FALSE);
- } else if (strlen(path) > PATH_MAX) {
- return (B_FALSE);
- } else if (strlen(path) >= 1) {
- return (B_TRUE);
- } else {
- /* path < 1 */
- return (B_FALSE);
- }
-}
-
-/*
*/
static boolean_t
diff --git a/usr/src/cmd/svr4pkg/pkgscripts/default b/usr/src/cmd/svr4pkg/pkgscripts/default
index 5774d36838..a1e5e2857a 100644
--- a/usr/src/cmd/svr4pkg/pkgscripts/default
+++ b/usr/src/cmd/svr4pkg/pkgscripts/default
@@ -33,9 +33,4 @@ space=ask
setuid=ask
conflict=ask
action=ask
-networktimeout=60
-networkretries=3
-authentication=quit
-keystore=/var/sadm/security
-proxy=
basedir=default
diff --git a/usr/src/cmd/svr4pkg/pkgtrans/main.c b/usr/src/cmd/svr4pkg/pkgtrans/main.c
index 857301150c..79218e06dd 100644
--- a/usr/src/cmd/svr4pkg/pkgtrans/main.c
+++ b/usr/src/cmd/svr4pkg/pkgtrans/main.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,13 +50,10 @@
#include <messages.h>
static int options;
-static keystore_handle_t keystore = NULL;
static void usage(void);
static void trap(int signo);
-#define KEYSTORE_OPEN "Retrieving signing certificates from keystore <%s>"
-
int
main(int argc, char *argv[])
{
@@ -60,11 +61,7 @@ main(int argc, char *argv[])
void (*func)();
extern char *optarg;
extern int optind;
- char *keystore_alias = NULL;
- char *keystore_file = NULL;
- boolean_t create_sig = B_FALSE;
char *homedir = NULL;
- PKG_ERR *err;
int ret, len;
(void) setlocale(LC_ALL, "");
@@ -76,7 +73,7 @@ main(int argc, char *argv[])
(void) set_prog_name(argv[0]);
- while ((c = getopt(argc, argv, "ga:P:k:snio?")) != EOF) {
+ while ((c = getopt(argc, argv, "snio?")) != EOF) {
switch (c) {
case 'n':
options |= PT_RENAME;
@@ -94,30 +91,6 @@ main(int argc, char *argv[])
options |= PT_ODTSTREAM;
break;
- case 'g':
- /* this should eventually be a PT_ option */
- create_sig = B_TRUE;
- break;
-
- case 'k':
- keystore_file = optarg;
- break;
-
- case 'a':
- keystore_alias = optarg;
- break;
-
- case 'P':
- set_passphrase_passarg(optarg);
- if (ci_strneq(optarg, "pass:", 5)) {
- /*
- * passwords on the command line are highly
- * insecure. complain.
- */
- logerr(PASSWD_CMDLINE, "pass:<pass>");
- }
- break;
-
default:
usage();
return (1);
@@ -137,60 +110,8 @@ main(int argc, char *argv[])
return (1);
}
- if (create_sig) {
- sec_init();
- err = pkgerr_new();
-
- /* figure out which keystore to use */
- if (keystore_file == NULL) {
- if (geteuid() == 0) {
- /* we are superuser, so use their keystore */
- keystore_file = PKGSEC;
-
- } else if ((homedir = getenv("HOME")) == NULL) {
- /*
- * not superuser, but no home dir, so
- * use superuser's keystore
- */
- keystore_file = PKGSEC;
-
- } else if (asprintf(&keystore_file, "%s/.pkg/security",
- homedir) < 0) {
- logerr(ERR_MEM);
- quit(1);
- }
- }
-
- logerr(gettext(KEYSTORE_OPEN), keystore_file);
-
- set_passphrase_prompt(MSG_PASSPROMPT);
-
- /* open keystore for reading */
- if (open_keystore(err, keystore_file, get_prog_name(),
- pkg_passphrase_cb, KEYSTORE_DFLT_FLAGS, &keystore) != 0) {
- pkgerr(err);
- pkgerr_free(err);
- quit(1);
- }
-
- } else {
- /* no signature, so don't use a keystore */
- keystore = NULL;
- }
-
ret = pkgtrans(flex_device(argv[optind], 1),
- flex_device(argv[optind+1], 1), &argv[optind+2], options,
- keystore, keystore_alias);
-
- if (create_sig) {
- /* close keystore */
- if (close_keystore(err, keystore, NULL) != 0) {
- pkgerr(err);
- pkgerr_free(err);
- quit(1);
- }
- keystore = NULL;
- }
+ flex_device(argv[optind+1], 1), &argv[optind+2], options);
quit(ret);
/*NOTREACHED*/
@@ -199,17 +120,10 @@ main(int argc, char *argv[])
void
quit(int retcode)
{
- PKG_ERR *err;
-
- err = pkgerr_new();
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGHUP, SIG_IGN);
(void) ds_close(1);
(void) pkghead(NULL);
- if (keystore != NULL) {
- (void) close_keystore(err, keystore, NULL);
- pkgerr_free(err);
- }
exit(retcode);
}
@@ -231,7 +145,6 @@ static void
usage(void)
{
(void) fprintf(stderr,
- gettext("usage: %s [-ionsg] [-k keystore] " \
- "[-a alias] [-P password] srcdev dstdev [pkg [pkg...]]\n"),
+ gettext("usage: %s [-ions] srcdev dstdev [pkg [pkg...]]\n"),
get_prog_name());
}
diff --git a/usr/src/lib/libpkg/Makefile.com b/usr/src/lib/libpkg/Makefile.com
index 3e3b294c7e..a0dd3bcab5 100644
--- a/usr/src/lib/libpkg/Makefile.com
+++ b/usr/src/lib/libpkg/Makefile.com
@@ -20,6 +20,9 @@
#
#
+# Copyright 2017 Peter Tribble.
+
+#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -33,12 +36,11 @@ OBJECTS= \
devtype.o dstream.o gpkglist.o \
gpkgmap.o isdir.o logerr.o \
mappath.o ncgrpw.o nhash.o \
- pkgexecl.o pkgexecv.o pkgmount.o \
- pkgtrans.o ppkgmap.o \
+ path_valid.o pkgexecl.o pkgexecv.o \
+ pkgmount.o pkgtrans.o ppkgmap.o \
progerr.o putcfile.o rrmdir.o \
runcmd.o srchcfile.o tputcfent.o \
- verify.o security.o pkgweb.o \
- pkgerr.o keystore.o p12lib.o \
+ verify.o \
vfpops.o fmkdir.o pkgstr.o \
handlelocalfs.o pkgserv.o
@@ -52,29 +54,19 @@ POFILE = libpkg.po
MSGFILES = $(OBJECTS:%.o=../common/%.i)
CLEANFILES += $(MSGFILES)
-# This library is NOT lint clean
-
-# openssl forces us to ignore dubious pointer casts, thanks to its clever
-# use of macros for stack management.
-LINTFLAGS= -umx -errtags \
- -erroff=E_BAD_PTR_CAST_ALIGN,E_BAD_PTR_CAST
-LINTFLAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
-LINTFLAGS64 += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -lc -lssl -lwanboot -lcrypto -lscf -ladm
+LDLIBS += -lc -lscf -ladm
CFLAGS += $(CCVERBOSE)
-CERRWARN += -_gcc=-Wno-unused-label
CERRWARN += -_gcc=-Wno-parentheses
CERRWARN += -_gcc=-Wno-uninitialized
CERRWARN += -_gcc=-Wno-clobbered
CERRWARN += -_gcc=-Wno-switch
-CERRWARN += -_gcc=-Wno-unused-value
CPPFLAGS += -I$(SRCDIR) -D_FILE_OFFSET_BITS=64
.KEEP_STATE:
diff --git a/usr/src/lib/libpkg/THIRDPARTYLICENSE b/usr/src/lib/libpkg/THIRDPARTYLICENSE
deleted file mode 100644
index 0051c6904d..0000000000
--- a/usr/src/lib/libpkg/THIRDPARTYLICENSE
+++ /dev/null
@@ -1,51 +0,0 @@
- * ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
diff --git a/usr/src/lib/libpkg/common/ckparam.c b/usr/src/lib/libpkg/common/ckparam.c
index 47beb1c6be..209d3b4d5d 100644
--- a/usr/src/lib/libpkg/common/ckparam.c
+++ b/usr/src/lib/libpkg/common/ckparam.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,6 +35,7 @@
#include <ctype.h>
#include <string.h>
+#include <stdlib.h>
#include <sys/types.h>
#include "pkglib.h"
#include "pkglibmsgs.h"
diff --git a/usr/src/lib/libpkg/common/dstream.c b/usr/src/lib/libpkg/common/dstream.c
index 38ca430614..6622b74361 100644
--- a/usr/src/lib/libpkg/common/dstream.c
+++ b/usr/src/lib/libpkg/common/dstream.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,7 +46,6 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <fcntl.h>
-#include <openssl/err.h>
#include "pkglib.h"
#include "pkglibmsgs.h"
#include "pkglocale.h"
@@ -135,7 +138,6 @@ ds_order(char *list[])
static char *pds_header;
static char *ds_header;
-static char *ds_header_raw;
static int ds_headsize;
static char *
@@ -421,15 +423,6 @@ ds_init(char *device, char **pkg, char *norewind)
pds_header = ds_header;
- /* save raw copy of header for later use in BIO_dump_header */
- if ((ds_header_raw = (char *)malloc(header_size)) == NULL) {
- progerr(pkg_gt(ERR_UNPACK));
- logerr(pkg_gt(MSG_MEM));
- (void) ds_close(0);
- return (1);
- }
- (void) memcpy(ds_header_raw, ds_header, header_size);
-
/* read datastream table of contents */
ds_head = tail = (struct dstoc *)0;
ds_volcnt = 1;
@@ -491,16 +484,9 @@ ds_init(char *device, char **pkg, char *norewind)
}
(void) strlcat(cmd, pkg[i], CMDSIZ);
(void) strlcat(cmd, "'/*' ", CMDSIZ);
-
- /* extract signature too, if present. */
- (void) strlcat(cmd, SIGNATURE_FILENAME, CMDSIZ);
(void) strlcat(cmd, " ", CMDSIZ);
}
- /*
- * if we are extracting all packages (pkgs == NULL),
- * signature will automatically be extracted
- */
if (n = esystem(cmd, ds_fd, -1)) {
rpterr();
progerr(pkg_gt(ERR_UNPACK));
@@ -718,73 +704,6 @@ ds_next(char *device, char *instdir)
}
/*
- * Name: BIO_ds_dump
- * Description: Dumps all data from the static 'ds_fd' file handle into
- * the supplied BIO.
- *
- * Arguments: err - where to record any errors.
- * device - Description of device being dumped into,
- * for error reporting
- * bio - BIO object to dump data into
- *
- * Returns : zero - successfully dumped all data to EOF
- * non-zero - some failure occurred.
- */
-int
-BIO_ds_dump(PKG_ERR *err, char *device, BIO *bio)
-{
- int amtread;
- char readbuf[BLK_SIZE];
-
- /*
- * note this will read to the end of the device, so it won't
- * work for character devices since we don't know when the
- * end of the CPIO archive is
- */
- while ((amtread = read(ds_fd, readbuf, BLK_SIZE)) != 0) {
- if (BIO_write(bio, readbuf, amtread) != amtread) {
- pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, device,
- ERR_error_string(ERR_get_error(), NULL));
- return (1);
- }
- }
-
- return (0);
- /*NOTREACHED*/
-}
-
-
-/*
- * Name: BIO_ds_dump_header
- * Description: Dumps all ds_headsize bytes from the
- * static 'ds_header_raw' character array
- * to the supplied BIO.
- *
- * Arguments: err - where to record any errors.
- * bio - BIO object to dump data into
- *
- * Returns : zero - successfully dumped all raw
- * header characters
- * non-zero - some failure occurred.
- */
-int
-BIO_ds_dump_header(PKG_ERR *err, BIO *bio)
-{
-
- char zeros[BLK_SIZE];
-
- (void) memset(zeros, 0, BLK_SIZE);
-
- if (BIO_write(bio, ds_header_raw, ds_headsize) != ds_headsize) {
- pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, "bio",
- ERR_error_string(ERR_get_error(), NULL));
- return (1);
- }
-
- return (0);
-}
-
-/*
* ds_ginit: Determine the device being accessed, set the buffer size,
* and perform any device specific initialization.
*/
diff --git a/usr/src/lib/libpkg/common/gpkgmap.c b/usr/src/lib/libpkg/common/gpkgmap.c
index 4bbe60dfc3..a8bd01c87c 100644
--- a/usr/src/lib/libpkg/common/gpkgmap.c
+++ b/usr/src/lib/libpkg/common/gpkgmap.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -389,7 +393,6 @@ end:
return (-1);
}
-done:
return (1);
}
@@ -930,7 +933,6 @@ end:
return (-1);
}
-done:
return (1);
}
diff --git a/usr/src/lib/libpkg/common/keystore.c b/usr/src/lib/libpkg/common/keystore.c
deleted file mode 100644
index 633c04b58e..0000000000
--- a/usr/src/lib/libpkg/common/keystore.c
+++ /dev/null
@@ -1,2474 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Module: keystore.c
- * Description: This module contains the structure definitions for processing
- * package keystore files.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <strings.h>
-#include <libintl.h>
-#include <time.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include <openssl/pkcs12.h>
-#include <openssl/asn1.h>
-#include <openssl/pem.h>
-#include <openssl/err.h>
-#include <openssl/safestack.h>
-#include <openssl/stack.h>
-#include "p12lib.h"
-#include "pkgerr.h"
-#include "keystore.h"
-#include "pkglib.h"
-#include "pkglibmsgs.h"
-
-typedef struct keystore_t {
- boolean_t dirty;
- boolean_t new;
- char *path;
- char *passphrase;
- /* truststore handles */
- int cafd;
- STACK_OF(X509) *cacerts;
- char *capath;
-
- /* user certificate handles */
- STACK_OF(X509) *clcerts;
- char *clpath;
-
- /* private key handles */
- STACK_OF(EVP_PKEY) *pkeys;
- char *keypath;
-} keystore_t;
-
-/* local routines */
-static keystore_t *new_keystore(void);
-static void free_keystore(keystore_t *);
-static boolean_t verify_keystore_integrity(PKG_ERR *, keystore_t *);
-static boolean_t check_password(PKCS12 *, char *);
-static boolean_t resolve_paths(PKG_ERR *, char *, char *,
- long, keystore_t *);
-static boolean_t lock_keystore(PKG_ERR *, long, keystore_t *);
-
-static boolean_t unlock_keystore(PKG_ERR *, keystore_t *);
-static boolean_t read_keystore(PKG_ERR *, keystore_t *,
- keystore_passphrase_cb);
-static boolean_t write_keystore(PKG_ERR *, keystore_t *,
- keystore_passphrase_cb);
-static boolean_t write_keystore_file(PKG_ERR *, char *, PKCS12 *);
-static boolean_t clear_keystore_file(PKG_ERR *, char *);
-static PKCS12 *read_keystore_file(PKG_ERR *, char *);
-static char *get_time_string(ASN1_TIME *);
-
-/* locking routines */
-static boolean_t restore_keystore_file(PKG_ERR *, char *);
-static int file_lock(int, int, int);
-static int file_unlock(int);
-static boolean_t file_lock_test(int, int);
-static boolean_t file_empty(char *);
-static boolean_t get_keystore_passwd(PKG_ERR *err, PKCS12 *p12,
- keystore_passphrase_cb cb, keystore_t *keystore);
-static boolean_t wait_restore(int, char *, char *, char *);
-
-#define KEYSTORE_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
-
-/* wait on other keystore access for 1 minute before giving up */
-#define LOCK_TIMEOUT 60
-
-/*
- * print_certs - prints certificates out of a keystore, to a file.
- *
- * Arguments:
- * err - Error object to append errors to
- * keystore - Keystore on which to operate
- * alias - Name of certificate to print, NULL means print all
- * format - Format in which to print certificates
- * outfile - Where to print certificates
- *
- * Returns:
- * 0 - Success
- * non-zero - Failure, errors added to err
- */
-int
-print_certs(PKG_ERR *err, keystore_handle_t keystore_h, char *alias,
- keystore_encoding_format_t format, FILE *outfile)
-{
- int i;
- X509 *cert;
- char *fname = NULL;
- boolean_t found = B_FALSE;
- keystore_t *keystore = keystore_h;
-
- if (keystore->clcerts != NULL) {
- /* print out each client cert */
- for (i = 0; i < sk_X509_num(keystore->clcerts); i++) {
- cert = sk_X509_value(keystore->clcerts, i);
- (void) sunw_get_cert_fname(GETDO_COPY, cert,
- &fname);
-
- if (fname == NULL) {
- /* no name recorded, keystore is corrupt */
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_NO_ALIAS),
- get_subject_display_name(cert));
- return (1);
- }
-
- if ((alias != NULL) && (!streq(alias, fname))) {
- /* name does not match, skip it */
- (void) OPENSSL_free(fname);
- fname = NULL;
- continue;
- } else {
- found = B_TRUE;
- (void) print_cert(err, cert, format,
- fname, B_FALSE, outfile);
- (void) OPENSSL_free(fname);
- fname = NULL;
- }
- }
- }
-
- if (fname != NULL) {
- (void) OPENSSL_free(fname);
- fname = NULL;
- }
-
- if (keystore->cacerts != NULL) {
- /* print out each trusted cert */
- for (i = 0; i < sk_X509_num(keystore->cacerts); i++) {
- cert = sk_X509_value(keystore->cacerts, i);
- (void) sunw_get_cert_fname(GETDO_COPY,
- cert, &fname);
-
- if (fname == NULL) {
- /* no name recorded, keystore is corrupt */
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_NO_ALIAS),
- get_subject_display_name(cert));
- return (1);
- }
-
- if ((alias != NULL) && (!streq(alias, fname))) {
- /* name does not match, skip it */
- (void) OPENSSL_free(fname);
- fname = NULL;
- continue;
- } else {
- found = B_TRUE;
- (void) print_cert(err, cert, format,
- fname, B_TRUE, outfile);
- (void) OPENSSL_free(fname);
- fname = NULL;
- }
- }
- }
-
- if (fname != NULL) {
- (void) OPENSSL_free(fname);
- fname = NULL;
- }
-
- if (found) {
- return (0);
- } else {
- /* no certs printed */
- if (alias != NULL) {
- pkgerr_add(err, PKGERR_NOALIASMATCH,
- gettext(ERR_KEYSTORE_NOCERT),
- alias, keystore->path);
- } else {
- pkgerr_add(err, PKGERR_NOPUBKEY,
- gettext(ERR_KEYSTORE_NOPUBCERTS),
- keystore->path);
- pkgerr_add(err, PKGERR_NOCACERT,
- gettext(ERR_KEYSTORE_NOCACERTS),
- keystore->path);
- }
- return (1);
- }
-}
-
-/*
- * print_cert - prints a single certificate, to a file
- *
- * Arguments:
- * err - Error object to append errors to
- * x - The certificate to print
- * alias - Name of certificate to print
- * format - Format in which to print certificate
- * outfile - Where to print certificate
- *
- * Returns:
- * 0 - Success
- * non-zero - Failure, errors added to err
- */
-int print_cert(PKG_ERR *err, X509 *x,
- keystore_encoding_format_t format, char *alias, boolean_t is_trusted,
- FILE *outfile)
-{
-
- char *vdb_str;
- char *vda_str;
- char vd_str[ATTR_MAX];
- int ret = 0;
- char *cn_str, *icn_str, *typ_str;
- char *tmp;
- char *md5_fp;
- char *sha1_fp;
- int len;
-
- /* need to localize the word "Fingerprint", hence these pointers */
- char md5_label[ATTR_MAX];
- char sha1_label[ATTR_MAX];
-
- if (is_trusted) {
- typ_str = gettext(MSG_KEYSTORE_TRUSTED);
- } else {
- typ_str = gettext(MSG_KEYSTORE_UNTRUSTED);
- }
-
- if ((cn_str = get_subject_display_name(x)) == NULL) {
- cn_str = gettext(MSG_KEYSTORE_UNKNOWN);
- }
-
- if ((icn_str = get_issuer_display_name(x)) == NULL) {
- icn_str = gettext(MSG_KEYSTORE_UNKNOWN);
- }
-
- vdb_str = xstrdup(get_time_string(X509_get_notBefore(x)));
- vda_str = xstrdup(get_time_string(X509_get_notAfter(x)));
- if (((len = snprintf(vd_str, ATTR_MAX, "<%s> - <%s>",
- vdb_str, vda_str)) < 0) || (len >= ATTR_MAX)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_LEN), vdb_str);
- ret = 1;
- goto cleanup;
- }
-
- if ((tmp = get_fingerprint(x, EVP_md5())) == NULL) {
- md5_fp = gettext(MSG_KEYSTORE_UNKNOWN);
- } else {
- /*
- * make a copy, otherwise the next call to get_fingerprint
- * will overwrite this one
- */
- md5_fp = xstrdup(tmp);
- }
-
- if ((tmp = get_fingerprint(x, EVP_sha1())) == NULL) {
- sha1_fp = gettext(MSG_KEYSTORE_UNKNOWN);
- } else {
- sha1_fp = xstrdup(tmp);
- }
-
- (void) snprintf(md5_label, ATTR_MAX, "%s %s",
- OBJ_nid2sn(EVP_MD_type(EVP_md5())),
- /* i18n: 14 characters max */
- gettext(MSG_KEYSTORE_FP));
-
- (void) snprintf(sha1_label, ATTR_MAX, "%s %s",
- OBJ_nid2sn(EVP_MD_type(EVP_sha1())),
- /* i18n: 14 characters max */
- gettext(MSG_KEYSTORE_FP));
-
- switch (format) {
- case KEYSTORE_FORMAT_PEM:
- (void) PEM_write_X509(outfile, x);
- break;
- case KEYSTORE_FORMAT_DER:
- (void) i2d_X509_fp(outfile, x);
- break;
- case KEYSTORE_FORMAT_TEXT:
- (void) fprintf(outfile, "%18s: %s\n",
- /* i18n: 18 characters max */
- gettext(MSG_KEYSTORE_AL), alias);
- (void) fprintf(outfile, "%18s: %s\n",
- /* i18n: 18 characters max */
- gettext(MSG_KEYSTORE_CN), cn_str);
- (void) fprintf(outfile, "%18s: %s\n",
- /* i18n: 18 characters max */
- gettext(MSG_KEYSTORE_TY), typ_str);
- (void) fprintf(outfile, "%18s: %s\n",
- /* i18n: 18 characters max */
- gettext(MSG_KEYSTORE_IN), icn_str);
- (void) fprintf(outfile, "%18s: %s\n",
- /* i18n: 18 characters max */
- gettext(MSG_KEYSTORE_VD), vd_str);
- (void) fprintf(outfile, "%18s: %s\n", md5_label, md5_fp);
- (void) fprintf(outfile, "%18s: %s\n", sha1_label, sha1_fp);
- (void) fprintf(outfile, "\n");
- break;
- default:
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_KEYSTORE_INTERNAL),
- __FILE__, __LINE__);
- ret = 1;
- goto cleanup;
- }
-
-cleanup:
- if (md5_fp != NULL)
- free(md5_fp);
- if (sha1_fp != NULL)
- free(sha1_fp);
- if (vda_str != NULL)
- free(vda_str);
- if (vdb_str != NULL)
- free(vdb_str);
- return (ret);
-}
-
-/*
- * open_keystore - Initialize new keystore object for
- * impending access.
- *
- * Arguments:
- * err - Error object to append errors to
- * keystore_file - Base filename or directory of keystore
- * app - Application making request
- * passwd - Password used to decrypt keystore
- * flags - Control flags used to control access mode and behavior
- * result - Resulting keystore object stored here on success
- *
- * Returns:
- * 0 - Success - result contains a pointer to the opened keystore
- * non-zero - Failure, errors added to err
- */
-int
-open_keystore(PKG_ERR *err, char *keystore_file, char *app,
- keystore_passphrase_cb cb, long flags, keystore_handle_t *result)
-{
- int ret = 0;
- keystore_t *tmpstore;
-
- tmpstore = new_keystore();
-
- tmpstore->dirty = B_FALSE;
- tmpstore->new = B_FALSE;
- tmpstore->path = xstrdup(keystore_file);
-
- if (!resolve_paths(err, keystore_file, app, flags, tmpstore)) {
- /* unable to determine keystore paths */
- pkgerr_add(err, PKGERR_CORRUPT, gettext(ERR_KEYSTORE_REPAIR),
- keystore_file);
- ret = 1;
- goto cleanup;
- }
-
- if (!verify_keystore_integrity(err, tmpstore)) {
- /* unable to repair keystore */
- pkgerr_add(err, PKGERR_CORRUPT, gettext(ERR_KEYSTORE_REPAIR),
- keystore_file);
- ret = 1;
- goto cleanup;
- }
-
- if (!lock_keystore(err, flags, tmpstore)) {
- pkgerr_add(err, PKGERR_LOCKED, gettext(ERR_KEYSTORE_LOCKED),
- keystore_file);
- ret = 1;
- goto cleanup;
- }
-
- /* now that we have locked the keystore, go ahead and read it */
- if (!read_keystore(err, tmpstore, cb)) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_PARSE),
- keystore_file);
- ret = 1;
- goto cleanup;
- }
-
- *result = tmpstore;
- tmpstore = NULL;
-
-cleanup:
- if (tmpstore != NULL)
- free_keystore(tmpstore);
- return (ret);
-}
-
-/*
- * new_keystore - Allocates and initializes a Keystore object
- *
- * Arguments:
- * NONE
- *
- * Returns:
- * NULL - out of memory
- * otherwise, returns a pointer to the newly allocated object,
- * which should be freed with free_keystore() when no longer
- * needed.
- */
-static keystore_t
-*new_keystore(void)
-{
- keystore_t *tmpstore;
-
- if ((tmpstore = (keystore_t *)malloc(sizeof (keystore_t))) == NULL) {
- return (NULL);
- }
- tmpstore->dirty = B_FALSE;
- tmpstore->new = B_FALSE;
- tmpstore->path = NULL;
- tmpstore->passphrase = NULL;
- tmpstore->cafd = -1;
- tmpstore->cacerts = NULL;
- tmpstore->capath = NULL;
- tmpstore->clcerts = NULL;
- tmpstore->clpath = NULL;
- tmpstore->pkeys = NULL;
- tmpstore->keypath = NULL;
-
- return (tmpstore);
-}
-
-/*
- * free_keystore - Deallocates a Keystore object
- *
- * Arguments:
- * keystore - The keystore to deallocate
- *
- * Returns:
- * NONE
- */
-static void
-free_keystore(keystore_t *keystore)
-{
- if (keystore->path != NULL)
- free(keystore->path);
- if (keystore->capath != NULL)
- free(keystore->capath);
- if (keystore->passphrase != NULL)
- free(keystore->passphrase);
- if (keystore->clpath != NULL)
- free(keystore->clpath);
- if (keystore->keypath != NULL)
- free(keystore->keypath);
-
- if (keystore->pkeys != NULL) {
- sk_EVP_PKEY_pop_free(keystore->pkeys,
- sunw_evp_pkey_free);
- }
- if (keystore->clcerts != NULL)
- sk_X509_free(keystore->clcerts);
- if (keystore->cacerts != NULL)
- sk_X509_free(keystore->cacerts);
- free(keystore);
-}
-
-/*
- * close_keystore - Writes keystore to disk if needed, then
- * unlocks and closes keystore.
- *
- * Arguments:
- * err - Error object to append errors to
- * keystore - Keystore which should be closed
- * passwd - Password used to encrypt keystore
- *
- * Returns:
- * 0 - Success - keystore is committed to disk, and unlocked
- * non-zero - Failure, errors added to err
- */
-int
-close_keystore(PKG_ERR *err, keystore_handle_t keystore_h,
- keystore_passphrase_cb cb)
-{
- int ret = 0;
- keystore_t *keystore = keystore_h;
-
- if (keystore->dirty) {
- /* write out the keystore first */
- if (!write_keystore(err, keystore, cb)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->path);
- ret = 1;
- goto cleanup;
- }
- }
-
- if (!unlock_keystore(err, keystore)) {
- pkgerr_add(err, PKGERR_UNLOCK, gettext(ERR_KEYSTORE_UNLOCK),
- keystore->path);
- ret = 1;
- goto cleanup;
- }
-
- free_keystore(keystore);
-cleanup:
- return (ret);
-}
-
-/*
- * merge_ca_cert - Adds a trusted certificate (trust anchor) to a keystore.
- * certificate checked for validity dates and non-duplicity.
- *
- * Arguments:
- * err - Error object to add errors to
- * cacert - Certificate which to merge into keystore
- * keystore - The keystore into which the certificate is merged
- *
- * Returns:
- * 0 - Success - Certificate passes validity, and
- * is merged into keystore
- * non-zero - Failure, errors recorded in err
- */
-int
-merge_ca_cert(PKG_ERR *err, X509 *cacert, keystore_handle_t keystore_h)
-{
-
- int ret = 0;
- X509 *existing = NULL;
- char *fname;
- keystore_t *keystore = keystore_h;
-
- /* check validity dates */
- if (check_cert(err, cacert) != 0) {
- ret = 1;
- goto cleanup;
- }
-
- /* create the certificate's friendlyName */
- fname = get_subject_display_name(cacert);
-
- if (sunw_set_fname(fname, NULL, cacert) != 0) {
- pkgerr_add(err, PKGERR_NOMEM, gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
-
- /* merge certificate into the keystore */
- if (keystore->cacerts == NULL) {
- /* no existing truststore, so make a new one */
- if ((keystore->cacerts = sk_X509_new_null()) == NULL) {
- pkgerr_add(err, PKGERR_NOMEM, gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
- } else {
- /* existing truststore, make sure there's no duplicate */
- if (sunw_find_fname(fname, NULL, keystore->cacerts,
- NULL, &existing) < 0) {
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_KEYSTORE_INTERNAL),
- __FILE__, __LINE__);
- ERR_print_errors_fp(stderr);
- ret = 1;
- goto cleanup;
- /* could not search properly! */
- }
- if (existing != NULL) {
- /* whoops, found one already */
- pkgerr_add(err, PKGERR_DUPLICATE,
- gettext(ERR_KEYSTORE_DUPLICATECERT), fname);
- ret = 1;
- goto cleanup;
- }
- }
-
- (void) sk_X509_push(keystore->cacerts, cacert);
- keystore->dirty = B_TRUE;
-cleanup:
- if (existing != NULL)
- X509_free(existing);
- return (ret);
-}
-
-/*
- * find_key_cert_pair - Searches a keystore for a matching
- * public key certificate and private key, given an alias.
- *
- * Arguments:
- * err - Error object to add errors to
- * ks - Keystore to search
- * alias - Name to used to match certificate's alias
- * key - Resulting key is placed here
- * cert - Resulting cert is placed here
- *
- * Returns:
- * 0 - Success - Matching cert/key pair placed in key and cert.
- * non-zero - Failure, errors recorded in err
- */
-int
-find_key_cert_pair(PKG_ERR *err, keystore_handle_t ks_h, char *alias,
- EVP_PKEY **key, X509 **cert)
-{
- X509 *tmpcert = NULL;
- EVP_PKEY *tmpkey = NULL;
- int ret = 0;
- int items_found;
- keystore_t *ks = ks_h;
-
- if (key == NULL || cert == NULL) {
- pkgerr_add(err, PKGERR_NOPUBKEY,
- gettext(ERR_KEYSTORE_NOPUBCERTS), ks->path);
- ret = 1;
- goto cleanup;
- }
-
- if (ks->clcerts == NULL) {
- /* no public certs */
- pkgerr_add(err, PKGERR_NOPUBKEY,
- gettext(ERR_KEYSTORE_NOCERTS), ks->path);
- ret = 1;
- goto cleanup;
- }
- if (ks->pkeys == NULL) {
- /* no private keys */
- pkgerr_add(err, PKGERR_NOPRIVKEY,
- gettext(ERR_KEYSTORE_NOKEYS), ks->path);
- ret = 1;
- goto cleanup;
- }
-
- /* try the easy case first */
- if ((sk_EVP_PKEY_num(ks->pkeys) == 1) &&
- (sk_X509_num(ks->clcerts) == 1)) {
- tmpkey = sk_EVP_PKEY_value(ks->pkeys, 0);
- tmpcert = sk_X509_value(ks->clcerts, 0);
- if (sunw_check_keys(tmpcert, tmpkey)) {
- /*
- * only one private key and public key cert, and they
- * match, so use them
- */
- *key = tmpkey;
- tmpkey = NULL;
- *cert = tmpcert;
- tmpcert = NULL;
- goto cleanup;
- }
- }
-
- /* Attempt to find the right pair given the alias */
- items_found = sunw_find_fname(alias, ks->pkeys, ks->clcerts,
- &tmpkey, &tmpcert);
-
- if ((items_found < 0) ||
- (items_found & (FOUND_PKEY | FOUND_CERT)) == 0) {
- /* no key/cert pair found. bail. */
- pkgerr_add(err, PKGERR_BADALIAS,
- gettext(ERR_KEYSTORE_NOMATCH), alias);
- ret = 1;
- goto cleanup;
- }
-
- /* success */
- *key = tmpkey;
- tmpkey = NULL;
- *cert = tmpcert;
- tmpcert = NULL;
-
-cleanup:
-
- if (tmpcert != NULL)
- (void) X509_free(tmpcert);
-
- if (tmpkey != NULL)
- sunw_evp_pkey_free(tmpkey);
-
- return (ret);
-}
-
-/*
- * find_ca_certs - Searches a keystore for trusted certificates
- *
- * Arguments:
- * err - Error object to add errors to
- * ks - Keystore to search
- * cacerts - resulting set of trusted certs are placed here
- *
- * Returns:
- * 0 - Success - trusted cert list returned in cacerts
- * non-zero - Failure, errors recorded in err
- */
-int
-find_ca_certs(PKG_ERR *err, keystore_handle_t ks_h, STACK_OF(X509) **cacerts)
-{
-
- keystore_t *ks = ks_h;
-
- /* easy */
- if (cacerts == NULL) {
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_KEYSTORE_INTERNAL), __FILE__, __LINE__);
- return (1);
- }
-
- *cacerts = ks->cacerts;
- return (0);
-}
-
-/*
- * find_cl_certs - Searches a keystore for user certificates
- *
- * Arguments:
- * err - Error object to add errors to
- * ks - Keystore to search
- * cacerts - resulting set of user certs are placed here
- *
- * No matching of any kind is performed.
- * Returns:
- * 0 - Success - trusted cert list returned in cacerts
- * non-zero - Failure, errors recorded in err
- */
-/* ARGSUSED */
-int
-find_cl_certs(PKG_ERR *err, keystore_handle_t ks_h, STACK_OF(X509) **clcerts)
-{
- keystore_t *ks = ks_h;
-
- /* easy */
- *clcerts = ks->clcerts;
- return (0);
-}
-
-
-/*
- * merge_cert_and_key - Adds a user certificate and matching
- * private key to a keystore.
- * certificate checked for validity dates and non-duplicity.
- *
- * Arguments:
- * err - Error object to add errors to
- * cert - Certificate which to merge into keystore
- * key - matching private key to 'cert'
- * alias - Name which to store the cert and key under
- * keystore - The keystore into which the certificate is merged
- *
- * Returns:
- * 0 - Success - Certificate passes validity, and
- * is merged into keystore, along with key
- * non-zero - Failure, errors recorded in err
- */
-int
-merge_cert_and_key(PKG_ERR *err, X509 *cert, EVP_PKEY *key, char *alias,
- keystore_handle_t keystore_h)
-{
- X509 *existingcert = NULL;
- EVP_PKEY *existingkey = NULL;
- int ret = 0;
- keystore_t *keystore = keystore_h;
-
- /* check validity dates */
- if (check_cert(err, cert) != 0) {
- ret = 1;
- goto cleanup;
- }
-
- /* set the friendlyName of the key and cert to the supplied alias */
- if (sunw_set_fname(alias, key, cert) != 0) {
- pkgerr_add(err, PKGERR_NOMEM, gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
-
- /* merge certificate and key into the keystore */
- if (keystore->clcerts == NULL) {
- /* no existing truststore, so make a new one */
- if ((keystore->clcerts = sk_X509_new_null()) == NULL) {
- pkgerr_add(err, PKGERR_NOMEM, gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
- } else {
- /* existing certstore, make sure there's no duplicate */
- if (sunw_find_fname(alias, NULL, keystore->clcerts,
- NULL, &existingcert) < 0) {
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_KEYSTORE_INTERNAL),
- __FILE__, __LINE__);
- ERR_print_errors_fp(stderr);
- ret = 1;
- goto cleanup;
- /* could not search properly! */
- }
- if (existingcert != NULL) {
- /* whoops, found one already */
- pkgerr_add(err, PKGERR_DUPLICATE,
- gettext(ERR_KEYSTORE_DUPLICATECERT), alias);
- ret = 1;
- goto cleanup;
- }
- }
-
- if (keystore->pkeys == NULL) {
- /* no existing keystore, so make a new one */
- if ((keystore->pkeys = sk_EVP_PKEY_new_null()) == NULL) {
- pkgerr_add(err, PKGERR_NOMEM, gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
- } else {
- /* existing keystore, so make sure there's no duplicate entry */
- if (sunw_find_fname(alias, keystore->pkeys, NULL,
- &existingkey, NULL) < 0) {
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_KEYSTORE_INTERNAL),
- __FILE__, __LINE__);
- ERR_print_errors_fp(stderr);
- ret = 1;
- goto cleanup;
- /* could not search properly! */
- }
- if (existingkey != NULL) {
- /* whoops, found one already */
- pkgerr_add(err, PKGERR_DUPLICATE,
- gettext(ERR_KEYSTORE_DUPLICATEKEY), alias);
- ret = 1;
- goto cleanup;
- }
- }
-
- (void) sk_X509_push(keystore->clcerts, cert);
- (void) sk_EVP_PKEY_push(keystore->pkeys, key);
- keystore->dirty = B_TRUE;
-cleanup:
- if (existingcert != NULL)
- (void) X509_free(existingcert);
- if (existingkey != NULL)
- (void) sunw_evp_pkey_free(existingkey);
- return (ret);
-}
-
-/*
- * delete_cert_and_keys - Deletes one or more certificates
- * and matching private keys from a keystore.
- *
- * Arguments:
- * err - Error object to add errors to
- * ks - The keystore from which certs and keys are deleted
- * alias - Name which to search for certificates and keys
- * to delete
- *
- * Returns:
- * 0 - Success - All trusted certs which match 'alias'
- * are deleted. All user certificates
- * which match 'alias' are deleted, along
- * with the matching private key.
- * non-zero - Failure, errors recorded in err
- */
-int
-delete_cert_and_keys(PKG_ERR *err, keystore_handle_t ks_h, char *alias)
-{
- X509 *existingcert;
- EVP_PKEY *existingkey;
- int i;
- char *fname = NULL;
- boolean_t found = B_FALSE;
- keystore_t *ks = ks_h;
-
- /* delete any and all client certs with the supplied name */
- if (ks->clcerts != NULL) {
- for (i = 0; i < sk_X509_num(ks->clcerts); i++) {
- existingcert = sk_X509_value(ks->clcerts, i);
- if (sunw_get_cert_fname(GETDO_COPY,
- existingcert, &fname) >= 0) {
- if (streq(fname, alias)) {
- /* match, so nuke it */
- existingcert =
- sk_X509_delete(ks->clcerts, i);
- X509_free(existingcert);
- existingcert = NULL;
- found = B_TRUE;
- }
- (void) OPENSSL_free(fname);
- fname = NULL;
- }
- }
- if (sk_X509_num(ks->clcerts) <= 0) {
- /* we deleted all the client certs */
- sk_X509_free(ks->clcerts);
- ks->clcerts = NULL;
- }
- }
-
- /* and now the private keys */
- if (ks->pkeys != NULL) {
- for (i = 0; i < sk_EVP_PKEY_num(ks->pkeys); i++) {
- existingkey = sk_EVP_PKEY_value(ks->pkeys, i);
- if (sunw_get_pkey_fname(GETDO_COPY,
- existingkey, &fname) >= 0) {
- if (streq(fname, alias)) {
- /* match, so nuke it */
- existingkey =
- sk_EVP_PKEY_delete(ks->pkeys, i);
- sunw_evp_pkey_free(existingkey);
- existingkey = NULL;
- found = B_TRUE;
- }
- (void) OPENSSL_free(fname);
- fname = NULL;
- }
- }
- if (sk_EVP_PKEY_num(ks->pkeys) <= 0) {
- /* we deleted all the private keys */
- sk_EVP_PKEY_free(ks->pkeys);
- ks->pkeys = NULL;
- }
- }
-
- /* finally, remove any trust anchors that match */
-
- if (ks->cacerts != NULL) {
- for (i = 0; i < sk_X509_num(ks->cacerts); i++) {
- existingcert = sk_X509_value(ks->cacerts, i);
- if (sunw_get_cert_fname(GETDO_COPY,
- existingcert, &fname) >= 0) {
- if (streq(fname, alias)) {
- /* match, so nuke it */
- existingcert =
- sk_X509_delete(ks->cacerts, i);
- X509_free(existingcert);
- existingcert = NULL;
- found = B_TRUE;
- }
- (void) OPENSSL_free(fname);
- fname = NULL;
- }
- }
- if (sk_X509_num(ks->cacerts) <= 0) {
- /* we deleted all the CA certs */
- sk_X509_free(ks->cacerts);
- ks->cacerts = NULL;
- }
- }
-
- if (found) {
- ks->dirty = B_TRUE;
- return (0);
- } else {
- /* no certs or keys deleted */
- pkgerr_add(err, PKGERR_NOALIASMATCH,
- gettext(ERR_KEYSTORE_NOCERTKEY),
- alias, ks->path);
- return (1);
- }
-}
-
-/*
- * check_cert - Checks certificate validity. This routine
- * checks that the current time falls within the period
- * of validity for the cert.
- *
- * Arguments:
- * err - Error object to add errors to
- * cert - The certificate to check
- *
- * Returns:
- * 0 - Success - Certificate checks out
- * non-zero - Failure, errors and reasons recorded in err
- */
-int
-check_cert(PKG_ERR *err, X509 *cert)
-{
- char currtimestr[ATTR_MAX];
- time_t currtime;
- char *r;
- /* get current time */
- if ((currtime = time(NULL)) == (time_t)-1) {
- pkgerr_add(err, PKGERR_TIME, gettext(ERR_CURR_TIME));
- return (1);
- }
-
- (void) strlcpy(currtimestr, ctime(&currtime), ATTR_MAX);
-
- /* trim whitespace from end of time string */
- for (r = (currtimestr + strlen(currtimestr) - 1); isspace(*r); r--) {
- *r = '\0';
- }
- /* check validity of cert */
- switch (sunw_check_cert_times(CHK_BOTH, cert)) {
- case CHKERR_TIME_OK:
- /* Current time meets requested checks */
- break;
- case CHKERR_TIME_BEFORE_BAD:
- /* 'not before' field is invalid */
- case CHKERR_TIME_AFTER_BAD:
- /* 'not after' field is invalid */
- pkgerr_add(err, PKGERR_TIME, gettext(ERR_CERT_TIME_BAD));
- return (1);
- case CHKERR_TIME_IS_BEFORE:
- /* Current time is before 'not before' */
- case CHKERR_TIME_HAS_EXPIRED:
- /*
- * Ignore expiration time since the trust cert used to
- * verify the certs used to sign Sun patches is already
- * expired. Once the patches get resigned with the new
- * cert we will check expiration against the time the
- * patch was signed and not the time it is installed.
- */
- return (0);
- default:
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_KEYSTORE_INTERNAL),
- __FILE__, __LINE__);
- return (1);
- }
-
- /* all checks ok */
- return (0);
-}
-
-/*
- * check_cert - Checks certificate validity. This routine
- * checks everything that check_cert checks, and additionally
- * verifies that the private key and corresponding public
- * key are indeed a pair.
- *
- * Arguments:
- * err - Error object to add errors to
- * cert - The certificate to check
- * key - the key to check
- * Returns:
- * 0 - Success - Certificate checks out
- * non-zero - Failure, errors and reasons recorded in err
- */
-int
-check_cert_and_key(PKG_ERR *err, X509 *cert, EVP_PKEY *key)
-{
-
- /* check validity dates */
- if (check_cert(err, cert) != 0) {
- return (1);
- }
-
- /* check key pair match */
- if (sunw_check_keys(cert, key) == 0) {
- pkgerr_add(err, PKGERR_VERIFY, gettext(ERR_MISMATCHED_KEYS),
- get_subject_display_name(cert));
- return (1);
- }
-
- /* all checks OK */
- return (0);
-}
-
-/* ------------------ private functions ---------------------- */
-
-/*
- * verify_keystore_integrity - Searches for the remnants
- * of a failed or aborted keystore modification, and
- * cleans up the files, retstores the keystore to a known
- * state.
- *
- * Arguments:
- * err - Error object to add errors to
- * keystore_file - Base directory or filename of keystore
- * app - Application making request
- *
- * Returns:
- * 0 - Success - Keystore is restored, or untouched in the
- * case that cleanup was unnecessary
- * non-zero - Failure, errors and reasons recorded in err
- */
-static boolean_t
-verify_keystore_integrity(PKG_ERR *err, keystore_t *keystore)
-{
- if (keystore->capath != NULL) {
- if (!restore_keystore_file(err, keystore->capath)) {
- return (B_FALSE);
- }
- }
- if (keystore->clpath != NULL) {
- if (!restore_keystore_file(err, keystore->clpath)) {
- return (B_FALSE);
- }
- }
- if (keystore->keypath != NULL) {
- if (!restore_keystore_file(err, keystore->keypath)) {
- return (B_FALSE);
- }
- }
- return (B_TRUE);
-}
-
-/*
- * restore_keystore_file - restores a keystore file to
- * a known state.
- *
- * Keystore files can possibly be corrupted by a variety
- * of error conditions during reading/writing. This
- * routine, along with write_keystore_file, tries to
- * maintain keystore integrity by writing the files
- * out in a particular order, minimizing the time period
- * that the keystore is in an indeterminate state.
- *
- * With the current implementation, there are some failures
- * that are wholly unrecoverable, such as disk corruption.
- * These routines attempt to minimize the risk, but not
- * eliminate it. When better, atomic operations are available
- * (such as a trued atabase with commit, rollback, and
- * guaranteed atomicity), this implementation should use that.
- *
- * Arguments:
- * err - Error object to add errors to
- * keystore_file - keystore file path to restore.
- *
- * Returns:
- * 0 - Success - Keystore file is restored, or untouched in the
- * case that cleanup was unnecessary
- * non-zero - Failure, errors and reasons recorded in err
- */
-/* ARGSUSED */
-static boolean_t
-restore_keystore_file(PKG_ERR *err, char *keystore_file)
-{
- char newpath[MAXPATHLEN];
- char backuppath[MAXPATHLEN];
- int newfd;
- struct stat buf;
- int len;
-
- if (((len = snprintf(newpath, MAXPATHLEN, "%s.new",
- keystore_file)) < 0) ||
- (len >= ATTR_MAX)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_LEN), keystore_file);
- return (B_FALSE);
- }
-
- if (((len = snprintf(backuppath, MAXPATHLEN, "%s.bak",
- keystore_file)) < 0) ||
- (len >= ATTR_MAX)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_LEN), keystore_file);
- return (B_FALSE);
- }
-
- if ((newfd = open(newpath, O_RDWR|O_NONBLOCK, 0)) != -1) {
- if (fstat(newfd, &buf) != -1) {
- if (S_ISREG(buf.st_mode)) {
- /*
- * restore the file, waiting on it
- * to be free for locking, or for
- * it to disappear
- */
- if (!wait_restore(newfd, keystore_file,
- newpath, backuppath)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_WRITE),
- newpath, strerror(errno));
- (void) close(newfd);
- return (B_FALSE);
- } else {
- return (B_TRUE);
- }
- } else {
- /* "new" file is not a regular file */
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_NOT_REG), newpath);
- (void) close(newfd);
- return (B_FALSE);
- }
- } else {
- /* couldn't stat "new" file */
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_WRITE), newpath,
- strerror(errno));
- (void) close(newfd);
- return (B_FALSE);
- }
- } else {
- /* "new" file doesn't exist */
- return (B_TRUE);
- }
-}
-
-static boolean_t
-wait_restore(int newfd, char *keystore_file,
- char *origpath, char *backuppath)
-{
- struct stat buf;
- FILE *newstream;
- PKCS12 *p12;
-
- (void) alarm(LOCK_TIMEOUT);
- if (file_lock(newfd, F_WRLCK, 1) == -1) {
- /* could not lock file */
- (void) alarm(0);
- return (B_FALSE);
- }
- (void) alarm(0);
-
- if (fstat(newfd, &buf) != -1) {
- if (S_ISREG(buf.st_mode)) {
- /*
- * The new file still
- * exists, with no
- * owner. It must be
- * the result of an
- * aborted update.
- */
- newstream = fdopen(newfd, "r");
- if ((p12 =
- d2i_PKCS12_fp(newstream,
- NULL)) != NULL) {
- /*
- * The file
- * appears
- * complete.
- * Replace the
- * exsisting
- * keystore
- * file with
- * this one
- */
- (void) rename(keystore_file, backuppath);
- (void) rename(origpath, keystore_file);
- PKCS12_free(p12);
- } else {
- /* The file is not complete. Remove it */
- (void) remove(origpath);
- }
- /* remove backup file */
- (void) remove(backuppath);
- (void) fclose(newstream);
- (void) close(newfd);
- return (B_TRUE);
- } else {
- /*
- * new file exists, but is not a
- * regular file
- */
- (void) close(newfd);
- return (B_FALSE);
- }
- } else {
- /*
- * could not stat file. Unless
- * the reason was that the file
- * is now gone, this is an error
- */
- if (errno != ENOENT) {
- (void) close(newfd);
- return (B_FALSE);
- }
- /*
- * otherwise, file is gone. The process
- * that held the lock must have
- * successfully cleaned up and
- * exited with a valid keystore
- * state
- */
- (void) close(newfd);
- return (B_TRUE);
- }
-}
-
-/*
- * resolve_paths - figure out if we are dealing with a single-file
- * or multi-file keystore
- *
- * The flags tell resolve_paths how to behave:
- *
- * KEYSTORE_PATH_SOFT
- * If the keystore file does not exist at <base>/<app> then
- * use <base> as the path to the keystore. This can be used,
- * for example, to access an app-specific keystore iff it
- * exists, otherwise revert back to an app-generic keystore.
- *
- * KEYSTORE_PATH_HARD
- * Always use the keystore located at <keystore_path>/<app>.
- * In read/write mode, if the files do not exist, then
- * they will be created. This is used to avoid falling
- * back to an app-generic keystore path when the app-specific
- * one does not exist.
- *
- * Arguments:
- * err - Error object to add errors to
- * keystore_file - base keystore file path to lock
- * app - Application making requests
- * flags - Control flags (see above description)
- * keystore - object which is being locked
- *
- * Returns:
- * B_TRUE - Success - Keystore file is locked, paths to
- * appropriate files placed in keystore.
- * B_FALSE - Failure, errors and reasons recorded in err
- */
-static boolean_t
-resolve_paths(PKG_ERR *err, char *keystore_file, char *app,
- long flags, keystore_t *keystore)
-{
- char storepath[PATH_MAX];
- struct stat buf;
- boolean_t multi = B_FALSE;
- int fd1, fd2, len;
-
- /*
- * figure out whether we are dealing with a single-file keystore
- * or a multi-file keystore
- */
- if (app != NULL) {
- if (((len = snprintf(storepath, PATH_MAX, "%s/%s",
- keystore_file, app)) < 0) ||
- (len >= ATTR_MAX)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_LEN),
- keystore_file);
- return (B_FALSE);
- }
-
- if (((fd1 = open(storepath, O_NONBLOCK|O_RDONLY)) == -1) ||
- (fstat(fd1, &buf) == -1) ||
- !S_ISDIR(buf.st_mode)) {
- /*
- * app-specific does not exist
- * fallback to app-generic, if flags say we can
- */
- if ((flags & KEYSTORE_PATH_MASK) ==
- KEYSTORE_PATH_SOFT) {
-
- if (((fd2 = open(keystore_file,
- O_NONBLOCK|O_RDONLY)) != -1) &&
- (fstat(fd2, &buf) != -1)) {
- if (S_ISDIR(buf.st_mode)) {
- /*
- * app-generic dir
- * exists, so use it
- * as a multi-file
- * keystore
- */
- multi = B_TRUE;
- app = NULL;
- } else if (S_ISREG(buf.st_mode)) {
- /*
- * app-generic file exists, so
- * use it as a single file ks
- */
- multi = B_FALSE;
- app = NULL;
- }
- }
- }
- }
- if (fd1 != -1)
- (void) close(fd1);
- if (fd2 != -1)
- (void) close(fd2);
- } else {
- if (((fd1 = open(keystore_file,
- O_NONBLOCK|O_RDONLY)) != -1) &&
- (fstat(fd1, &buf) != -1) &&
- S_ISDIR(buf.st_mode)) {
- /*
- * app-generic dir exists, so use
- * it as a multi-file keystore
- */
- multi = B_TRUE;
- }
- if (fd1 != -1)
- (void) close(fd1);
- }
-
- if (app != NULL) {
- /* app-specific keystore */
- (void) snprintf(storepath, PATH_MAX, "%s/%s/%s",
- keystore_file, app, TRUSTSTORE);
- keystore->capath = xstrdup(storepath);
- (void) snprintf(storepath, PATH_MAX, "%s/%s/%s",
- keystore_file, app, CERTSTORE);
- keystore->clpath = xstrdup(storepath);
- (void) snprintf(storepath, PATH_MAX, "%s/%s/%s",
- keystore_file, app, KEYSTORE);
- keystore->keypath = xstrdup(storepath);
- } else {
- /* app-generic keystore */
- if (!multi) {
- /* single-file app-generic keystore */
- keystore->capath = xstrdup(keystore_file);
- keystore->keypath = NULL;
- keystore->clpath = NULL;
- } else {
- /* multi-file app-generic keystore */
- (void) snprintf(storepath, PATH_MAX, "%s/%s",
- keystore_file, TRUSTSTORE);
- keystore->capath = xstrdup(storepath);
- (void) snprintf(storepath, PATH_MAX, "%s/%s",
- keystore_file, CERTSTORE);
- keystore->clpath = xstrdup(storepath);
- (void) snprintf(storepath, PATH_MAX, "%s/%s",
- keystore_file, KEYSTORE);
- keystore->keypath = xstrdup(storepath);
- }
- }
-
- return (B_TRUE);
-}
-
-/*
- * lock_keystore - Locks a keystore for shared (read-only)
- * or exclusive (read-write) access.
- *
- * The flags tell lock_keystore how to behave:
- *
- * KEYSTORE_ACCESS_READONLY
- * opens keystore read-only. Attempts to modify results in an error
- *
- * KEYSTORE_ACCESS_READWRITE
- * opens keystore read-write
- *
- * KEYSTORE_PATH_SOFT
- * If the keystore file does not exist at <base>/<app> then
- * use <base> as the path to the keystore. This can be used,
- * for example, to access an app-specific keystore iff it
- * exists, otherwise revert back to an app-generic keystore.
- *
- * KEYSTORE_PATH_HARD
- * Always use the keystore located at <keystore_path>/<app>.
- * In read/write mode, if the files do not exist, then
- * they will be created. This is used to avoid falling
- * back to an app-generic keystore path when the app-specific
- * one does not exist.
- *
- * Arguments:
- * err - Error object to add errors to
- * flags - Control flags (see above description)
- * keystore - object which is being locked
- *
- * Returns:
- * 0 - Success - Keystore file is locked, paths to
- * appropriate files placed in keystore.
- * non-zero - Failure, errors and reasons recorded in err
- */
-static boolean_t
-lock_keystore(PKG_ERR *err, long flags, keystore_t *keystore)
-{
- boolean_t ret = B_TRUE;
- struct stat buf;
-
- switch (flags & KEYSTORE_ACCESS_MASK) {
- case KEYSTORE_ACCESS_READONLY:
- if ((keystore->cafd =
- open(keystore->capath, O_NONBLOCK|O_RDONLY)) == -1) {
- if (errno == ENOENT) {
- /*
- * no keystore. try to create an
- * empty one so we can lock on it and
- * prevent others from gaining
- * exclusive access. It will be
- * deleted when the keystore is closed.
- */
- if ((keystore->cafd =
- open(keystore->capath,
- O_NONBLOCK|O_RDWR|O_CREAT|O_EXCL,
- S_IRUSR|S_IWUSR)) == -1) {
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_NO_KEYSTORE),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_KEYSTORE_OPEN),
- keystore->capath, strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
- }
- if (fstat(keystore->cafd, &buf) != -1) {
- if (S_ISREG(buf.st_mode)) {
- if (file_lock(keystore->cafd, F_RDLCK,
- 0) == -1) {
- pkgerr_add(err, PKGERR_LOCKED,
- gettext(ERR_KEYSTORE_LOCKED_READ),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- /* ca file not a regular file! */
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_NOT_REG),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_KEYSTORE_OPEN),
- keystore->capath, strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
- break;
- case KEYSTORE_ACCESS_READWRITE:
-
- if ((keystore->cafd = open(keystore->capath,
- O_RDWR|O_NONBLOCK)) == -1) {
- /* does not exist. try to create an empty one */
- if (errno == ENOENT) {
- if ((keystore->cafd =
- open(keystore->capath,
- O_NONBLOCK|O_RDWR|O_CREAT|O_EXCL,
- S_IRUSR|S_IWUSR)) == -1) {
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_KEYSTORE_OPEN),
- keystore->capath, strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
- }
- if (fstat(keystore->cafd, &buf) != -1) {
- if (S_ISREG(buf.st_mode)) {
- if (file_lock(keystore->cafd, F_WRLCK,
- 0) == -1) {
- pkgerr_add(err, PKGERR_LOCKED,
- gettext(ERR_KEYSTORE_LOCKED),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- /* ca file not a regular file! */
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_NOT_REG),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- pkgerr_add(err, PKGERR_READ,
- gettext(ERR_KEYSTORE_OPEN),
- keystore->capath, strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
-
- break;
- default:
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_KEYSTORE_INTERNAL),
- __FILE__, __LINE__);
- ret = B_FALSE;
- goto cleanup;
- }
-
-cleanup:
- if (!ret) {
- if (keystore->cafd > 0) {
- (void) file_unlock(keystore->cafd);
- (void) close(keystore->cafd);
- keystore->cafd = -1;
- }
-
- if (keystore->capath != NULL)
- free(keystore->capath);
- if (keystore->clpath != NULL)
- free(keystore->clpath);
- if (keystore->keypath != NULL)
- free(keystore->keypath);
- keystore->capath = NULL;
- keystore->clpath = NULL;
- keystore->keypath = NULL;
- }
-
- return (ret);
-}
-
-/*
- * unlock_keystore - Unocks a keystore
- *
- * Arguments:
- * err - Error object to add errors to
- * keystore - keystore object to unlock
- * Returns:
- * 0 - Success - Keystore files are unlocked, files are closed,
- * non-zero - Failure, errors and reasons recorded in err
- */
-/* ARGSUSED */
-static boolean_t
-unlock_keystore(PKG_ERR *err, keystore_t *keystore)
-{
-
- /*
- * Release lock on the CA file.
- * Delete file if it is empty
- */
- if (file_empty(keystore->capath)) {
- (void) remove(keystore->capath);
- }
-
- (void) file_unlock(keystore->cafd);
- (void) close(keystore->cafd);
- return (B_TRUE);
-}
-
-/*
- * read_keystore - Reads keystore files of disk, parses
- * into internal structures.
- *
- * Arguments:
- * err - Error object to add errors to
- * keystore - keystore object to read into
- * cb - callback to get password, if required
- * Returns:
- * 0 - Success - Keystore files are read, and placed
- * into keystore structure.
- * non-zero - Failure, errors and reasons recorded in err
- */
-static boolean_t
-read_keystore(PKG_ERR *err, keystore_t *keystore, keystore_passphrase_cb cb)
-{
- boolean_t ret = B_TRUE;
- PKCS12 *p12 = NULL;
- boolean_t ca_empty;
- boolean_t have_passwd = B_FALSE;
- boolean_t cl_empty = B_TRUE;
- boolean_t key_empty = B_TRUE;
-
- ca_empty = file_empty(keystore->capath);
-
- if (keystore->clpath != NULL)
- cl_empty = file_empty(keystore->clpath);
- if (keystore->keypath != NULL)
- key_empty = file_empty(keystore->keypath);
-
- if (ca_empty && cl_empty && key_empty) {
- keystore->new = B_TRUE;
- }
-
- if (!ca_empty) {
- /* first read the ca file */
- if ((p12 = read_keystore_file(err,
- keystore->capath)) == NULL) {
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT), keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* Get password, using callback if necessary */
- if (!have_passwd) {
- if (!get_keystore_passwd(err, p12, cb, keystore)) {
- ret = B_FALSE;
- goto cleanup;
- }
- have_passwd = B_TRUE;
- }
-
- /* decrypt and parse keystore file */
- if (sunw_PKCS12_contents(p12, keystore->passphrase,
- &keystore->pkeys, &keystore->cacerts) < 0) {
- /* could not parse the contents */
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT), keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- PKCS12_free(p12);
- p12 = NULL;
- } else {
-
- /*
- * truststore is empty, so we don't have any trusted
- * certs
- */
- keystore->cacerts = NULL;
- }
-
- /*
- * if there is no cl file or key file, use the cl's and key's found
- * in the ca file
- */
- if (keystore->clpath == NULL && !ca_empty) {
- if (sunw_split_certs(keystore->pkeys, keystore->cacerts,
- &keystore->clcerts, NULL) < 0) {
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT), keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- /*
- * files are in separate files. read keys out of the keystore
- * certs out of the certstore, if they are not empty
- */
- if (!cl_empty) {
- if ((p12 = read_keystore_file(err,
- keystore->clpath)) == NULL) {
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT),
- keystore->clpath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* Get password, using callback if necessary */
- if (!have_passwd) {
- if (!get_keystore_passwd(err, p12, cb,
- keystore)) {
- ret = B_FALSE;
- goto cleanup;
- }
- have_passwd = B_TRUE;
- }
-
- if (check_password(p12,
- keystore->passphrase) == B_FALSE) {
- /*
- * password in client cert file
- * is different than
- * the one in the other files!
- */
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(ERR_MISMATCHPASS),
- keystore->clpath,
- keystore->capath, keystore->path);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (sunw_PKCS12_contents(p12, keystore->passphrase,
- NULL, &keystore->clcerts) < 0) {
- /* could not parse the contents */
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT),
- keystore->clpath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- PKCS12_free(p12);
- p12 = NULL;
- } else {
- keystore->clcerts = NULL;
- }
-
- if (!key_empty) {
- if ((p12 = read_keystore_file(err,
- keystore->keypath)) == NULL) {
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT),
- keystore->keypath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* Get password, using callback if necessary */
- if (!have_passwd) {
- if (!get_keystore_passwd(err, p12, cb,
- keystore)) {
- ret = B_FALSE;
- goto cleanup;
- }
- have_passwd = B_TRUE;
- }
-
- if (check_password(p12,
- keystore->passphrase) == B_FALSE) {
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(ERR_MISMATCHPASS),
- keystore->keypath,
- keystore->capath, keystore->path);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (sunw_PKCS12_contents(p12, keystore->passphrase,
- &keystore->pkeys, NULL) < 0) {
- /* could not parse the contents */
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT),
- keystore->keypath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- PKCS12_free(p12);
- p12 = NULL;
- } else {
- keystore->pkeys = NULL;
- }
- }
-
-cleanup:
- if (p12 != NULL)
- PKCS12_free(p12);
- return (ret);
-}
-
-/*
- * get_keystore_password - retrieves pasword used to
- * decrypt PKCS12 structure.
- *
- * Arguments:
- * err - Error object to add errors to
- * p12 - PKCS12 structure which returned password should
- * decrypt
- * cb - callback to collect password.
- * keystore - The keystore in which the PKCS12 structure
- * will eventually populate.
- * Returns:
- * B_TRUE - success.
- * keystore password is set in keystore->passphrase.
- * B_FALSE - failure, errors logged
- */
-static boolean_t
-get_keystore_passwd(PKG_ERR *err, PKCS12 *p12, keystore_passphrase_cb cb,
- keystore_t *keystore)
-{
- char *passwd;
- char passbuf[KEYSTORE_PASS_MAX + 1];
- keystore_passphrase_data data;
-
- /* see if no password is the right password */
- if (check_password(p12, "") == B_TRUE) {
- passwd = "";
- } else if (check_password(p12, NULL) == B_TRUE) {
- passwd = NULL;
- } else {
- /* oops, it's encrypted. get password */
- data.err = err;
- if (cb(passbuf, KEYSTORE_PASS_MAX, 0,
- &data) == -1) {
- /* could not get password */
- return (B_FALSE);
- }
-
- if (check_password(p12, passbuf) == B_FALSE) {
- /* wrong password */
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(ERR_BADPASS));
- return (B_FALSE);
- }
-
- /*
- * make copy of password buffer, since it
- * goes away upon return
- */
- passwd = xstrdup(passbuf);
- }
- keystore->passphrase = passwd;
- return (B_TRUE);
-}
-
-/*
- * write_keystore - Writes keystore files to disk
- *
- * Arguments:
- * err - Error object to add errors to
- * keystore - keystore object to write from
- * passwd - password used to encrypt keystore
- * Returns:
- * 0 - Success - Keystore contents are written out to
- * the same locations as read from
- * non-zero - Failure, errors and reasons recorded in err
- */
-static boolean_t
-write_keystore(PKG_ERR *err, keystore_t *keystore,
- keystore_passphrase_cb cb)
-{
- PKCS12 *p12 = NULL;
- boolean_t ret = B_TRUE;
- keystore_passphrase_data data;
- char passbuf[KEYSTORE_PASS_MAX + 1];
-
- if (keystore->capath != NULL && keystore->clpath == NULL &&
- keystore->keypath == NULL) {
-
- /*
- * keystore is a file.
- * just write out a single file
- */
- if ((keystore->pkeys == NULL) &&
- (keystore->clcerts == NULL) &&
- (keystore->cacerts == NULL)) {
- if (!clear_keystore_file(err, keystore->capath)) {
- /*
- * no keys or certs to write out, so
- * blank the ca file. we do not
- * delete it since it is used as a
- * lock by lock_keystore() in
- * subsequent invocations
- */
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- /*
- * if the keystore is being created for the first time,
- * prompt for a passphrase for encryption
- */
- if (keystore->new) {
- data.err = err;
- if (cb(passbuf, KEYSTORE_PASS_MAX,
- 1, &data) == -1) {
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- /*
- * use the one used when the keystore
- * was read
- */
- (void) strlcpy(passbuf, keystore->passphrase,
- KEYSTORE_PASS_MAX);
- }
-
- p12 = sunw_PKCS12_create(passbuf, keystore->pkeys,
- keystore->clcerts, keystore->cacerts);
-
- if (p12 == NULL) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_FORM),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!write_keystore_file(err, keystore->capath, p12)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- }
-
- } else {
- /* files are seprate. Do one at a time */
-
- /*
- * if the keystore is being created for the first time,
- * prompt for a passphrase for encryption
- */
- if (keystore->new && ((keystore->pkeys != NULL) ||
- (keystore->clcerts != NULL) ||
- (keystore->cacerts != NULL))) {
- data.err = err;
- if (cb(passbuf, KEYSTORE_PASS_MAX,
- 1, &data) == -1) {
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- /* use the one used when the keystore was read */
- (void) strlcpy(passbuf, keystore->passphrase,
- KEYSTORE_PASS_MAX);
- }
-
- /* do private keys first */
- if (keystore->pkeys != NULL) {
- p12 = sunw_PKCS12_create(passbuf, keystore->pkeys,
- NULL, NULL);
-
- if (p12 == NULL) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_FORM),
- keystore->keypath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!write_keystore_file(err, keystore->keypath,
- p12)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->keypath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- PKCS12_free(p12);
- } else {
- if ((remove(keystore->keypath) != 0) &&
- (errno != ENOENT)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_REMOVE),
- keystore->keypath);
- ret = B_FALSE;
- goto cleanup;
- }
- }
-
- /* do user certs next */
- if (keystore->clcerts != NULL) {
- p12 = sunw_PKCS12_create(passbuf, NULL,
- keystore->clcerts, NULL);
-
- if (p12 == NULL) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_FORM),
- keystore->clpath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!write_keystore_file(err, keystore->clpath, p12)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->clpath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- PKCS12_free(p12);
- } else {
- if ((remove(keystore->clpath) != 0) &&
- (errno != ENOENT)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_REMOVE),
- keystore->clpath);
- ret = B_FALSE;
- goto cleanup;
- }
- }
-
-
- /* finally do CA cert file */
- if (keystore->cacerts != NULL) {
- p12 = sunw_PKCS12_create(passbuf, NULL,
- NULL, keystore->cacerts);
-
- if (p12 == NULL) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_FORM),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!write_keystore_file(err, keystore->capath, p12)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- PKCS12_free(p12);
- p12 = NULL;
- } else {
- /*
- * nothing to write out, so truncate the file
- * (it will be deleted during close_keystore)
- */
- if (!clear_keystore_file(err, keystore->capath)) {
- pkgerr_add(err, PKGERR_WRITE,
- gettext(ERR_KEYSTORE_WRITE),
- keystore->capath);
- ret = B_FALSE;
- goto cleanup;
- }
- }
- }
-
-cleanup:
- if (p12 != NULL)
- PKCS12_free(p12);
-
- return (ret);
-}
-
-/*
- * clear_keystore_file - Clears (zeros out) a keystore file.
- *
- * Arguments:
- * err - Error object to add errors to
- * dest - Path of keystore file to zero out.
- * Returns:
- * 0 - Success - Keystore file is truncated to zero length
- * non-zero - Failure, errors and reasons recorded in err
- */
-static boolean_t
-clear_keystore_file(PKG_ERR *err, char *dest)
-{
- int fd;
- struct stat buf;
-
- fd = open(dest, O_RDWR|O_NONBLOCK);
- if (fd == -1) {
- /* can't open for writing */
- pkgerr_add(err, PKGERR_WRITE, gettext(MSG_OPEN),
- errno);
- return (B_FALSE);
- }
-
- if ((fstat(fd, &buf) == -1) || !S_ISREG(buf.st_mode)) {
- /* not a regular file */
- (void) close(fd);
- pkgerr_add(err, PKGERR_WRITE, gettext(ERR_NOT_REG),
- dest);
- return (B_FALSE);
- }
-
- if (ftruncate(fd, 0) == -1) {
- (void) close(fd);
- pkgerr_add(err, PKGERR_WRITE, gettext(ERR_WRITE),
- dest, strerror(errno));
- return (B_FALSE);
- }
-
- (void) close(fd);
- return (B_TRUE);
-}
-
-/*
- * write_keystore_file - Writes keystore file to disk.
- *
- * Keystore files can possibly be corrupted by a variety
- * of error conditions during reading/writing. This
- * routine, along with restore_keystore_file, tries to
- * maintain keystore integity by writing the files
- * out in a particular order, minimizing the time period
- * that the keystore is in an indeterminate state.
- *
- * With the current implementation, there are some failures
- * that are wholly unrecoverable, such as disk corruption.
- * These routines attempt to minimize the risk, but not
- * eliminate it. When better, atomic operations are available
- * (such as a true database with commit, rollback, and
- * guaranteed atomicity), this implementation should use that.
- *
- *
- * Arguments:
- * err - Error object to add errors to
- * dest - Destination filename
- * contents - Contents to write to the file
- * Returns:
- * 0 - Success - Keystore contents are written out to
- * the destination.
- * non-zero - Failure, errors and reasons recorded in err
- */
-static boolean_t
-write_keystore_file(PKG_ERR *err, char *dest, PKCS12 *contents)
-{
- FILE *newfile = NULL;
- boolean_t ret = B_TRUE;
- char newpath[MAXPATHLEN];
- char backuppath[MAXPATHLEN];
- struct stat buf;
- int fd;
-
- (void) snprintf(newpath, MAXPATHLEN, "%s.new", dest);
- (void) snprintf(backuppath, MAXPATHLEN, "%s.bak", dest);
-
- if ((fd = open(newpath, O_CREAT|O_EXCL|O_WRONLY|O_NONBLOCK,
- S_IRUSR|S_IWUSR)) == -1) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_KEYSTORE_OPEN),
- newpath, strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (fstat(fd, &buf) == -1) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_KEYSTORE_OPEN),
- newpath, strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!S_ISREG(buf.st_mode)) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_NOT_REG),
- newpath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if ((newfile = fdopen(fd, "w")) == NULL) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_KEYSTORE_OPEN),
- newpath, strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (i2d_PKCS12_fp(newfile, contents) == 0) {
- pkgerr_add(err, PKGERR_WRITE, gettext(ERR_KEYSTORE_WRITE),
- newpath);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* flush, then close */
- (void) fflush(newfile);
- (void) fclose(newfile);
- newfile = NULL;
-
- /* now back up the original file */
- (void) rename(dest, backuppath);
-
- /* put new one in its place */
- (void) rename(newpath, dest);
-
- /* remove backup */
- (void) remove(backuppath);
-
-cleanup:
- if (newfile != NULL)
- (void) fclose(newfile);
- if (fd != -1)
- (void) close(fd);
-
- return (ret);
-}
-
-/*
- * read_keystore_file - Reads single keystore file
- * off disk in PKCS12 format.
- *
- * Arguments:
- * err - Error object to add errors to
- * file - File path to read
- * Returns:
- * PKCS12 contents of file, or NULL if an error occurred.
- * errors recorded in 'err'.
- */
-static PKCS12
-*read_keystore_file(PKG_ERR *err, char *file)
-{
- int fd;
- struct stat buf;
- FILE *newfile;
- PKCS12 *p12 = NULL;
-
- if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_KEYSTORE_OPEN),
- file, strerror(errno));
- goto cleanup;
- }
-
- if (fstat(fd, &buf) == -1) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_KEYSTORE_OPEN),
- file, strerror(errno));
- goto cleanup;
- }
-
- if (!S_ISREG(buf.st_mode)) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_NOT_REG),
- file);
- goto cleanup;
- }
-
- if ((newfile = fdopen(fd, "r")) == NULL) {
- pkgerr_add(err, PKGERR_READ, gettext(ERR_KEYSTORE_OPEN),
- file, strerror(errno));
- goto cleanup;
- }
-
- if ((p12 = d2i_PKCS12_fp(newfile, NULL)) == NULL) {
- pkgerr_add(err, PKGERR_CORRUPT,
- gettext(ERR_KEYSTORE_CORRUPT), file);
- goto cleanup;
- }
-
-cleanup:
- if (newfile != NULL)
- (void) fclose(newfile);
- if (fd != -1)
- (void) close(fd);
-
- return (p12);
-}
-
-
-/*
- * Locks the specified file.
- */
-static int
-file_lock(int fd, int type, int wait)
-{
- struct flock lock;
-
- lock.l_type = type;
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
-
- if (!wait) {
- if (file_lock_test(fd, type)) {
- /*
- * The caller would have to wait to get the
- * lock on this file.
- */
- return (-1);
- }
- }
-
- return (fcntl(fd, F_SETLKW, &lock));
-}
-
-/*
- * Returns FALSE if the file is not locked; TRUE
- * otherwise.
- */
-static boolean_t
-file_lock_test(int fd, int type)
-{
- struct flock lock;
-
- lock.l_type = type;
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
-
- if (fcntl(fd, F_GETLK, &lock) != -1) {
- if (lock.l_type != F_UNLCK) {
- /*
- * The caller would have to wait to get the
- * lock on this file.
- */
- return (B_TRUE);
- }
- }
-
- /*
- * The file is not locked.
- */
- return (B_FALSE);
-}
-
-/*
- * Unlocks the specified file.
- */
-static int
-file_unlock(int fd)
-{
- struct flock lock;
-
- lock.l_type = F_UNLCK;
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
-
- return (fcntl(fd, F_SETLK, &lock));
-}
-
-/*
- * Determines if file has a length of 0 or not
- */
-static boolean_t
-file_empty(char *path)
-{
- struct stat buf;
-
- /* file is empty if size = 0 or it doesn't exist */
- if (lstat(path, &buf) == 0) {
- if (buf.st_size == 0) {
- return (B_TRUE);
- }
- } else {
- if (errno == ENOENT) {
- return (B_TRUE);
- }
- }
-
- return (B_FALSE);
-}
-
-/*
- * Name: get_time_string
- * Description: Generates a human-readable string from an ASN1_TIME
- *
- * Arguments: intime - The time to convert
- *
- * Returns : A pointer to a static string representing the passed-in time.
- */
-static char
-*get_time_string(ASN1_TIME *intime)
-{
-
- static char time[ATTR_MAX];
- BIO *mem;
- char *p;
-
- if (intime == NULL) {
- return (NULL);
- }
- if ((mem = BIO_new(BIO_s_mem())) == NULL) {
- return (NULL);
- }
-
- if (ASN1_TIME_print(mem, intime) == 0) {
- (void) BIO_free(mem);
- return (NULL);
- }
-
- if (BIO_gets(mem, time, ATTR_MAX) <= 0) {
- (void) BIO_free(mem);
- return (NULL);
- }
-
- (void) BIO_free(mem);
-
- /* trim the end of the string */
- for (p = time + strlen(time) - 1; isspace(*p); p--) {
- *p = '\0';
- }
-
- return (time);
-}
-
-/*
- * check_password - do various password checks to see if the current password
- * will work or we need to prompt for a new one.
- *
- * Arguments:
- * pass - password to check
- *
- * Returns:
- * B_TRUE - Password is OK.
- * B_FALSE - Password not valid.
- */
-static boolean_t
-check_password(PKCS12 *p12, char *pass)
-{
- boolean_t ret = B_TRUE;
-
- /*
- * If password is zero length or NULL then try verifying both cases
- * to determine which password is correct. The reason for this is that
- * under PKCS#12 password based encryption no password and a zero
- * length password are two different things...
- */
-
- /* Check the mac */
- if (pass == NULL || *pass == '\0') {
- if (PKCS12_verify_mac(p12, NULL, 0) == 0 &&
- PKCS12_verify_mac(p12, "", 0) == 0)
- ret = B_FALSE;
- } else if (PKCS12_verify_mac(p12, pass, -1) == 0) {
- ret = B_FALSE;
- }
- return (ret);
-}
diff --git a/usr/src/lib/libpkg/common/keystore.h b/usr/src/lib/libpkg/common/keystore.h
deleted file mode 100644
index b48ba030aa..0000000000
--- a/usr/src/lib/libpkg/common/keystore.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _KEYSTORE_H
-#define _KEYSTORE_H
-
-
-/*
- * Module: keystore.h
- * Description: This module contains the structure definitions for processing
- * package keystore files.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include "pkgerr.h"
-
-/* keystore structures */
-
-/* this opaque type represents a keystore */
-typedef void *keystore_handle_t;
-
-/* flags passed to open_keystore */
-
-/* opens keystore read-only. Attempts to modify results in an error */
-#define KEYSTORE_ACCESS_READONLY 0x00000001L
-
-/* opens keystore read-write */
-#define KEYSTORE_ACCESS_READWRITE 0x00000002L
-
-/*
- * tells open_keystore to fall back to app-generic paths in the case that
- * the app-specific paths do not exist.
- */
-#define KEYSTORE_PATH_SOFT 0x00000010L
-
-/*
- * tells open_keystore to use the app-specific paths no matter what,
- * failing if they cannot be used for any reason.
- */
-#define KEYSTORE_PATH_HARD 0x00000020L
-
-/* masks off various types of flags */
-#define KEYSTORE_ACCESS_MASK 0x0000000FL
-#define KEYSTORE_PATH_MASK 0x000000F0L
-
-/* default is read-only, soft */
-#define KEYSTORE_DFLT_FLAGS \
- (KEYSTORE_ACCESS_READONLY|KEYSTORE_PATH_SOFT)
-
-/*
- * possible encoding formats used by the library, used
- * by print_cert
- */
-typedef enum {
- KEYSTORE_FORMAT_PEM,
- KEYSTORE_FORMAT_DER,
- KEYSTORE_FORMAT_TEXT
-} keystore_encoding_format_t;
-
-/*
- * structure passed back to password callback for determining how
- * to prompt for passphrase, and where to record errors
- */
-typedef struct {
- PKG_ERR *err;
-} keystore_passphrase_data;
-
-
-/* max length of a passphrase. One could use a short story! */
-#define KEYSTORE_PASS_MAX 1024
-
-/* callback for collecting passphrase when open_keystore() is called */
-typedef int keystore_passphrase_cb(char *, int, int, void *);
-
-/* names of the individual files within the keystore path */
-#define TRUSTSTORE "truststore"
-#define KEYSTORE "keystore"
-#define CERTSTORE "certstore"
-
-/* keystore.c */
-extern int open_keystore(PKG_ERR *, char *, char *,
- keystore_passphrase_cb, long flags, keystore_handle_t *);
-
-extern int print_certs(PKG_ERR *, keystore_handle_t, char *,
- keystore_encoding_format_t, FILE *);
-
-extern int check_cert(PKG_ERR *, X509 *);
-
-extern int check_cert_and_key(PKG_ERR *, X509 *, EVP_PKEY *);
-
-extern int print_cert(PKG_ERR *, X509 *,
- keystore_encoding_format_t, char *, boolean_t, FILE *);
-
-extern int close_keystore(PKG_ERR *, keystore_handle_t,
- keystore_passphrase_cb);
-
-extern int merge_ca_cert(PKG_ERR *, X509 *, keystore_handle_t);
-extern int merge_cert_and_key(PKG_ERR *, X509 *, EVP_PKEY *,
- char *, keystore_handle_t);
-
-extern int delete_cert_and_keys(PKG_ERR *, keystore_handle_t,
- char *);
-
-extern int find_key_cert_pair(PKG_ERR *, keystore_handle_t,
- char *, EVP_PKEY **, X509 **);
-
-extern int find_ca_certs(PKG_ERR *, keystore_handle_t,
- STACK_OF(X509) **);
-
-extern int find_cl_certs(PKG_ERR *, keystore_handle_t,
- STACK_OF(X509) **);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _KEYSTORE_H */
diff --git a/usr/src/lib/libpkg/common/llib-lpkg b/usr/src/lib/libpkg/common/llib-lpkg
index b60597a9bc..b2fdb70d75 100644
--- a/usr/src/lib/libpkg/common/llib-lpkg
+++ b/usr/src/lib/libpkg/common/llib-lpkg
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,9 +32,5 @@
/* LINTLIBRARY */
/* PROTOLIB1 */
#include <cfext.h>
-#include <keystore.h>
-#include <p12lib.h>
-#include <pkgerr.h>
#include <pkglib.h>
#include <pkglocale.h>
-#include <pkgweb.h>
diff --git a/usr/src/lib/libpkg/common/mapfile-vers b/usr/src/lib/libpkg/common/mapfile-vers
index ffdda251f7..40dcd44f49 100644
--- a/usr/src/lib/libpkg/common/mapfile-vers
+++ b/usr/src/lib/libpkg/common/mapfile-vers
@@ -20,6 +20,10 @@
#
#
+# Copyright (c) 2017 Peter Tribble.
+#
+
+#
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
#
@@ -45,28 +49,23 @@ SYMBOL_VERSION SUNWprivate {
attrdefault;
attrpreset;
averify;
- backoff;
basepath;
canonize;
canonize_slashes;
cgrgid;
cgrnam;
- check_cert;
- check_cert_and_key;
checksum_off;
checksum_on;
ckparam;
ckvolseq;
clgrgid;
clgrnam;
- close_keystore;
clpwnam;
clpwuid;
compute_checksum;
cpwnam;
cpwuid;
cverify;
- delete_cert_and_keys;
devtype;
disable_attribute_check;
ds_close;
@@ -81,32 +80,21 @@ SYMBOL_VERSION SUNWprivate {
ds_putinfo;
ds_readbuf;
ds_skiptoend;
- ds_validate_signature;
e_ExecCmdArray;
e_ExecCmdList;
- echo_out;
ecleanup;
enable_local_fs;
epclose;
epopen;
esystem;
- find_ca_certs;
- find_cl_certs;
- find_key_cert_pair;
fmkdir;
fverify;
getErrbufAddr;
getErrbufSize;
getErrstr;
get_categories;
- get_cert_chain;
get_disable_attribute_check;
- get_endof_string;
get_prog_name;
- get_proxy_port;
- get_signature;
- get_startof_string;
- get_subject_display_name;
getmapmode;
gpkglist;
gpkgmap;
@@ -118,7 +106,6 @@ SYMBOL_VERSION SUNWprivate {
isPathRemote;
is_not_valid_category;
is_not_valid_length;
- is_web_install;
iscpio;
isdir;
isfile;
@@ -126,22 +113,11 @@ SYMBOL_VERSION SUNWprivate {
lookup_cache;
mappath;
mapvar;
- merge_ca_cert;
- merge_cert_and_key;
nonABI_symlinks;
- open_keystore;
path_valid;
- pkg_passphrase_cb;
pkgclosefilter;
pkgcloseserver;
pkgcmd;
- pkgerr;
- pkgerr_add;
- pkgerr_clear;
- pkgerr_free;
- pkgerr_get;
- pkgerr_new;
- pkgerr_num;
pkgexecl;
pkgexecv;
pkggetentry;
@@ -176,42 +152,19 @@ SYMBOL_VERSION SUNWprivate {
pkgtrans;
pkgumount;
ppkgmap;
- print_cert;
- print_certs;
progerr;
putcfile;
putcvfpfile;
- reset_backoff;
restore_local_fs;
rpterr;
rrmdir;
- sec_init;
setErrstr;
set_memalloc_failure_func;
set_nonABI_symlinks;
- set_passphrase_passarg;
- set_passphrase_prompt;
set_prog_name;
- set_web_install;
setmapmode;
srchcfile;
- strip_port;
- sunw_PKCS12_contents;
- sunw_PKCS12_create;
- sunw_check_cert_times;
- sunw_check_keys;
- sunw_evp_pkey_free;
- sunw_find_fname;
- sunw_find_localkeyid;
- sunw_get_cert_fname;
- sunw_get_pkey_fname;
- sunw_get_pkey_localkeyid;
- sunw_set_fname;
- sunw_set_localkeyid;
- sunw_split_certs;
- sunw_PEM_contents;
tputcfent;
- validate_signature;
vfpCheckpointFile;
vfpCheckpointOpen;
vfpClearModified;
@@ -226,8 +179,6 @@ SYMBOL_VERSION SUNWprivate {
vfpSetSize;
vfpTruncate;
vfpWriteToFile;
- web_cleanup;
- web_session_control;
xmalloc;
xrealloc;
xstrdup;
diff --git a/usr/src/lib/libpkg/common/p12lib.c b/usr/src/lib/libpkg/common/p12lib.c
deleted file mode 100644
index 238aa57d54..0000000000
--- a/usr/src/lib/libpkg/common/p12lib.c
+++ /dev/null
@@ -1,2798 +0,0 @@
-/*
- * ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
- */
-
-
-#include <strings.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-
-#include <openssl/pkcs12.h>
-#include "p12lib.h"
-
-/*
- * OpenSSL provides a framework for pushing error codes onto a stack.
- * When an error occurs, the consumer may use the framework to
- * pop the errors off the stack and provide a trace of where the
- * errors occurred.
- *
- * Our PKCS12 code plugs into this framework by calling
- * ERR_load_SUNW_strings(). To push an error (which by the way, consists
- * of a function code and an error code) onto the stack our PKCS12 code
- * calls SUNWerr().
- *
- * Consumers of our PKCS12 code can then call the OpenSSL error routines
- * when an error occurs and retrieve the stack of errors.
- */
-
-#ifndef OPENSSL_NO_ERR
-
-/* Function codes and their matching strings */
-static ERR_STRING_DATA SUNW_str_functs[] = {
- { ERR_PACK(0, SUNW_F_USE_X509CERT, 0), "sunw_use_x509cert" },
- { ERR_PACK(0, SUNW_F_USE_PKEY, 0), "sunw_use_pkey" },
- { ERR_PACK(0, SUNW_F_USE_TASTORE, 0), "sunw_use_tastore" },
- { ERR_PACK(0, SUNW_F_USE_CERTFILE, 0), "sunw_p12_use_certfile" },
- { ERR_PACK(0, SUNW_F_USE_KEYFILE, 0), "sunw_p12_use_keyfile" },
- { ERR_PACK(0, SUNW_F_USE_TRUSTFILE, 0), "sunw_p12_use_trustfile" },
- { ERR_PACK(0, SUNW_F_READ_FILE, 0), "p12_read_file" },
- { ERR_PACK(0, SUNW_F_DOPARSE, 0), "p12_doparse" },
- { ERR_PACK(0, SUNW_F_PKCS12_PARSE, 0), "sunw_PKCS12_parse" },
- { ERR_PACK(0, SUNW_F_PKCS12_CONTENTS, 0), "sunw_PKCS12_contents" },
- { ERR_PACK(0, SUNW_F_PARSE_ONE_BAG, 0), "parse_one_bag" },
- { ERR_PACK(0, SUNW_F_PKCS12_CREATE, 0), "sunw_PKCS12_create" },
- { ERR_PACK(0, SUNW_F_SPLIT_CERTS, 0), "sunw_split_certs" },
- { ERR_PACK(0, SUNW_F_FIND_LOCALKEYID, 0), "sunw_find_localkeyid" },
- { ERR_PACK(0, SUNW_F_SET_LOCALKEYID, 0), "sunw_set_localkeyid" },
- { ERR_PACK(0, SUNW_F_GET_LOCALKEYID, 0), "sunw_get_localkeyid" },
- { ERR_PACK(0, SUNW_F_SET_FNAME, 0), "sunw_set_fname" },
- { ERR_PACK(0, SUNW_F_GET_PKEY_FNAME, 0), "sunw_get_pkey_fname" },
- { ERR_PACK(0, SUNW_F_APPEND_KEYS, 0), "sunw_append_keys" },
- { ERR_PACK(0, SUNW_F_PEM_CONTENTS, 0), "sunw_PEM_contents" },
- { ERR_PACK(0, SUNW_F_PEM_INFO, 0), "pem_info" },
- { ERR_PACK(0, SUNW_F_ASC2BMPSTRING, 0), "asc2bmpstring" },
- { ERR_PACK(0, SUNW_F_UTF82ASCSTR, 0), "utf82ascstr" },
- { ERR_PACK(0, SUNW_F_FINDATTR, 0), "findattr" },
- { ERR_PACK(0, SUNW_F_TYPE2ATTRIB, 0), "type2attrib" },
- { ERR_PACK(0, SUNW_F_MOVE_CERTS, 0), "move_certs" },
- { ERR_PACK(0, SUNW_F_FIND_FNAME, 0), "sunw_find_fname" },
- { ERR_PACK(0, SUNW_F_PARSE_OUTER, 0), "parse_outer" },
- { ERR_PACK(0, SUNW_F_CHECKFILE, 0), "checkfile" },
- { 0, NULL }
-};
-
-/* Error codes and their matching strings */
-static ERR_STRING_DATA SUNW_str_reasons[] = {
- { SUNW_R_INVALID_ARG, "invalid argument" },
- { SUNW_R_MEMORY_FAILURE, "memory failure" },
- { SUNW_R_MAC_VERIFY_FAILURE, "mac verify failure" },
- { SUNW_R_MAC_CREATE_FAILURE, "mac create failure" },
- { SUNW_R_BAD_FILETYPE, "bad file type" },
- { SUNW_R_BAD_PKEY, "bad or missing private key" },
- { SUNW_R_BAD_PKEYTYPE, "unsupported key type" },
- { SUNW_R_PKEY_READ_ERR, "unable to read private key" },
- { SUNW_R_NO_TRUST_ANCHOR, "no trust anchors found" },
- { SUNW_R_READ_TRUST_ERR, "unable to read trust anchor" },
- { SUNW_R_ADD_TRUST_ERR, "unable to add trust anchor" },
- { SUNW_R_PKCS12_PARSE_ERR, "PKCS12 parse error" },
- { SUNW_R_PKCS12_CREATE_ERR, "PKCS12 create error" },
- { SUNW_R_BAD_CERTTYPE, "unsupported certificate type" },
- { SUNW_R_PARSE_CERT_ERR, "error parsing PKCS12 certificate" },
- { SUNW_R_PARSE_BAG_ERR, "error parsing PKCS12 bag" },
- { SUNW_R_MAKE_BAG_ERR, "error making PKCS12 bag" },
- { SUNW_R_BAD_LKID, "bad localKeyID format" },
- { SUNW_R_SET_LKID_ERR, "error setting localKeyID" },
- { SUNW_R_BAD_FNAME, "bad friendlyName format" },
- { SUNW_R_SET_FNAME_ERR, "error setting friendlyName" },
- { SUNW_R_BAD_TRUST, "bad or missing trust anchor" },
- { SUNW_R_BAD_BAGTYPE, "unsupported bag type" },
- { SUNW_R_CERT_ERR, "certificate error" },
- { SUNW_R_PKEY_ERR, "private key error" },
- { SUNW_R_READ_ERR, "error reading file" },
- { SUNW_R_ADD_ATTR_ERR, "error adding attribute" },
- { SUNW_R_STR_CONVERT_ERR, "error converting string" },
- { SUNW_R_PKCS12_EMPTY_ERR, "empty PKCS12 structure" },
- { SUNW_R_PASSWORD_ERR, "bad password" },
- { 0, NULL }
-};
-
-/*
- * The library name that our module will be known as. This name
- * may be retrieved via OpenSSLs error APIs.
- */
-static ERR_STRING_DATA SUNW_lib_name[] = {
- { 0, SUNW_LIB_NAME },
- { 0, NULL }
-};
-#endif
-
-/*
- * The value of this variable (initialized by a call to
- * ERR_load_SUNW_strings()) is what identifies our errors
- * to OpenSSL as being ours.
- */
-static int SUNW_lib_error_code = 0;
-
-/* local routines */
-static int parse_pkcs12(PKCS12 *, const char *, int, char *, int, char *,
- EVP_PKEY **, X509 **, STACK_OF(X509) **);
-static int pem_info(FILE *, pem_password_cb, void *,
- STACK_OF(EVP_PKEY) **, STACK_OF(X509) **);
-
-static int parse_outer(PKCS12 *, const char *, STACK_OF(EVP_PKEY) *,
- STACK_OF(X509) *);
-
-static int parse_all_bags(STACK_OF(PKCS12_SAFEBAG) *, const char *,
- STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
-
-static int parse_one_bag(PKCS12_SAFEBAG *, const char *,
- STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
-
-static X509_ATTRIBUTE *type2attrib(ASN1_TYPE *, int);
-static ASN1_TYPE *attrib2type(X509_ATTRIBUTE *);
-static uchar_t *utf82ascstr(ASN1_UTF8STRING *);
-static ASN1_BMPSTRING *asc2bmpstring(const char *, int);
-static int find_attr_by_nid(STACK_OF(X509_ATTRIBUTE) *, int);
-static int find_attr(int, ASN1_STRING *, STACK_OF(EVP_PKEY) *,
- EVP_PKEY **, STACK_OF(X509) *, X509 **);
-
-static chk_errs_t check_time(chk_actions_t, X509 *);
-static int get_key_cert(int, STACK_OF(EVP_PKEY) *, EVP_PKEY **,
- STACK_OF(X509) *, X509 **cert);
-static int move_certs(STACK_OF(X509) *, STACK_OF(X509) *);
-static int sunw_append_keys(STACK_OF(EVP_PKEY) *,
- STACK_OF(EVP_PKEY) *);
-static int set_results(STACK_OF(EVP_PKEY) **,
- STACK_OF(EVP_PKEY) **, STACK_OF(X509) **, STACK_OF(X509) **,
- STACK_OF(X509) **, STACK_OF(X509) **,
- STACK_OF(EVP_PKEY) **, STACK_OF(EVP_PKEY) **);
-
-/*
- * ----------------------------------------------------------------------------
- * Public routines
- * ----------------------------------------------------------------------------
- */
-
-/*
- * sunw_PKCS12_parse - Parse a PKCS12 structure and break it into its parts.
- *
- * Parse and decrypt a PKCS#12 structure returning user key, user cert and/or
- * other (CA) certs. Note either ca should be NULL, *ca should be NULL,
- * or it should point to a valid STACK_OF(X509) structure. pkey and cert can
- * be passed uninitialized.
- *
- * Arguments:
- * p12 - Structure with pkcs12 info to be parsed
- * pass - Pass phrase for the private key (possibly empty) or NULL if
- * there is none.
- * matchty - Info about which certs/keys to return if many are in the file.
- * keyid - If private key localkeyids friendlynames are to match a
- * predetermined value, the value to match. This value should
- * be an octet string.
- * keyid_len- Length of the keyid byte string.
- * name_str - If friendlynames are to match a predetermined value, the value
- * to match. This value should be a NULL terminated string.
- * pkey - Points to location pointing to the private key returned.
- * cert - Points to locaiton which points to the client cert returned
- * ca - Points to location that points to a stack of 'certificate
- * authority' certs/trust anchors.
- *
- * Match based on the value of 'matchty' and the contents of 'keyid'
- * and/or 'name_str', as appropriate. Go through the lists of certs and
- * private keys which were taken from the pkcs12 structure, looking for
- * matches of the requested type. This function only searches the lists of
- * matching private keys and client certificates. Kinds of matches allowed,
- * and the order in which they will be checked, are:
- *
- * 1) Find the key and/or cert whose localkeyid attributes matches
- * 'keyid'.
- * 2) Find the key and/or cert whose friendlyname attributes matches
- * 'name_str'
- * 3) Return the first matching key/cert pair found.
- * 4) Return the last matching key/cert pair found.
- * 5) Return whatever cert and/or key are available, even unmatching.
- *
- * Append to the CA list, the certs which do not have matching private
- * keys and which were not selected.
- *
- * If none of the bits are set, no client certs or private keys will be
- * returned. CA (aka trust anchor) certs can be.
- *
- * Notes: If #3 is selected, then #4 will never occur. CA certs will be
- * selected after a cert/key pairs are isolated.
- *
- * Returns:
- * < 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * >= 0 - Objects were found and returned. Which objects are indicated by
- * which bits are set (FOUND_PKEY, FOUND_CERT, FOUND_CA_CERTS).
- */
-int
-sunw_PKCS12_parse(PKCS12 *p12, const char *pass, int matchty, char *keyid,
- int keyid_len, char *name_str, EVP_PKEY **pkey, X509 **cert,
- STACK_OF(X509) **ca)
-{
- boolean_t ca_supplied;
- int retval = -1;
-
- /* If NULL PKCS12 structure, this is an error */
- if (p12 == NULL) {
- SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
- return (-1);
- }
-
- /* Set up arguments.... These will be allocated if needed */
- if (pkey)
- *pkey = NULL;
- if (cert)
- *cert = NULL;
-
- /*
- * If there is already a ca list, use it. Otherwise, allocate one
- * and free is later if an error occurs or whatever.)
- */
- ca_supplied = (ca != NULL && *ca != NULL);
- if (ca != NULL && *ca == NULL) {
- if ((*ca = sk_X509_new_null()) == NULL) {
- SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
- }
-
- /*
- * If password is zero length or NULL then try verifying both cases
- * to determine which password is correct. The reason for this is that
- * under PKCS#12 password based encryption no password and a zero
- * length password are two different things. If the password has a
- * non-zero length and is not NULL then call PKCS12_verify_mac() with
- * a length of '-1' and let it use strlen() to figure out the length
- * of the password.
- */
- /* Check the mac */
- if (pass == NULL || *pass == '\0') {
- if (PKCS12_verify_mac(p12, NULL, 0))
- pass = NULL;
- else if (PKCS12_verify_mac(p12, "", 0))
- pass = "";
- else {
- SUNWerr(SUNW_F_PKCS12_PARSE,
- SUNW_R_MAC_VERIFY_FAILURE);
- goto err;
- }
- } else if (PKCS12_verify_mac(p12, pass, -1) == 0) {
- SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_MAC_VERIFY_FAILURE);
- goto err;
- }
-
- retval = parse_pkcs12(p12, pass, matchty, keyid, keyid_len,
- name_str, pkey, cert, ca);
- if (retval < 0) {
- SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_PKCS12_PARSE_ERR);
- goto err;
- }
- return (retval);
-
-err:
- if (pkey && *pkey) {
- sunw_evp_pkey_free(*pkey);
- }
- if (cert && *cert)
- X509_free(*cert);
- if (ca_supplied == B_FALSE && ca != NULL)
- sk_X509_pop_free(*ca, X509_free);
-
- return (-1);
-
-}
-
-
-/*
- * sunw_PEM_contents() parses a PEM file and returns component parts found
- *
- * Parse and decrypt a PEM file, returning any user keys and certs.
- *
- * There are some limits to this function. It will ignore the following:
- * - certificates identified by "TRUSTED CERTIFICATE"
- * - CERTIFICATE REQUEST and NEW CERTIFICATE REQUEST records.
- * - X509 CRL
- * - DH PARAMETERS
- * - DSA PARAMETERS
- * - Any PUBLIC KEY
- * - PKCS7
- * - PRIVATE KEY or ENCRYPTED PRIVATE KEY (PKCS 8)
- *
- * Arguments:
- * fp - File pointer for file containing PEM data.
- * pass - Pass phrase for the private key or NULL if there is none.
- * pkeys - Points to address of a stack of private keys to return.
- * certs - Points to address of a stack of client certs to return.
- *
- * The pointers to stacks should either be NULL or their contents should
- * either be NULL or should point to a valid STACK_OF(X509) structure.
- * If the stacks contain information, corresponding information from the
- * file will be appended to the original contents.
- *
- * Note: Client certs and and their matching private keys will be in any
- * order.
- *
- * Certs which have no matching private key are assumed to be ca certs.
- *
- * Returns:
- * < 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * >= 0 - Objects were found and returned. Which objects are indicated by
- * which bits are set (FOUND_PKEY, FOUND_CERT)
- */
-int sunw_PEM_contents(FILE *fp, pem_password_cb *cb, void *userdata,
- STACK_OF(EVP_PKEY) **pkey, STACK_OF(X509) **certs)
-{
- STACK_OF(EVP_PKEY) *work_kl = NULL;
- STACK_OF(X509) *work_ca = NULL;
- int retval = -1;
-
- /*
- * Allocate the working stacks for private key and for the
- * ca certs.
- */
- if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) {
- SUNWerr(SUNW_F_PEM_CONTENTS, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
-
- if ((work_ca = sk_X509_new_null()) == NULL) {
- SUNWerr(SUNW_F_PEM_CONTENTS, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
-
- /* Error strings are set within the following. */
- if (pem_info(fp, cb, userdata, &work_kl, &work_ca) <= 0) {
- goto cleanup;
- }
-
- /* on error, set_results() returns an error on the stack */
- retval = set_results(pkey, &work_kl, certs, &work_ca, NULL, NULL, NULL,
- NULL);
-cleanup:
- if (work_kl != NULL) {
- sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
- }
- if (work_ca != NULL)
- sk_X509_pop_free(work_ca, X509_free);
-
- return (retval);
-}
-
-
-/*
- * sunw_PKCS12_contents() parses a pkcs#12 structure and returns component
- * parts found, without evaluation.
- *
- * Parse and decrypt a PKCS#12 structure returning any user keys and/or
- * various certs. Note these should either be NULL, *whatever should
- * be NULL, or it should point to a valid STACK_OF(X509) structure.
- *
- * Arguments:
- * p12 - Structure with pkcs12 info to be parsed
- * pass - Pass phrase for the private key and entire pkcs12 wad (possibly
- * empty) or NULL if there is none.
- * pkeys - Points to address of a stack of private keys to return.
- * certs - Points to address of a stack of client certs return.
- *
- * Note: The certs and keys being returned are in random order.
- *
- * Returns:
- * < 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * >= 0 - Objects were found and returned. Which objects are indicated by
- * which bits are set (FOUND_PKEY or FOUND_CERT)
- */
-int
-sunw_PKCS12_contents(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) **pkey,
- STACK_OF(X509) **certs)
-{
- STACK_OF(EVP_PKEY) *work_kl = NULL;
- STACK_OF(X509) *work_ca = NULL;
- int retval = -1;
-
- /*
- * Allocate the working stacks for private key and for the
- * ca certs.
- */
- if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
-
- if ((work_ca = sk_X509_new_null()) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CONTENTS, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
-
- if (parse_outer(p12, pass, work_kl, work_ca) == 0) {
- /*
- * Error already on stack
- */
- goto cleanup;
- }
-
- /* on error, set_results() returns an error on the stack */
- retval = set_results(pkey, &work_kl, certs, &work_ca, NULL,
- NULL, NULL, NULL);
-
-cleanup:
- if (work_kl != NULL) {
- sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
- }
-
- return (retval);
-}
-
-
-
-/*
- * sunw_split_certs() - Given a list of certs and a list of private keys,
- * moves certs which match one of the keys to a different stack.
- *
- * Arguments:
- * allkeys - Points to a stack of private keys to search.
- * allcerts - Points to a stack of certs to be searched.
- * keycerts - Points to address of a stack of certs with matching private
- * keys. They are moved from 'allcerts'. This may not be NULL
- * when called. If *keycerts is NULL upon entry, a new stack will
- * be allocated. Otherwise, it must be a valid STACK_OF(509).
- * nocerts - Points to address of a stack for keys which have no matching
- * certs. Keys are moved from 'allkeys' here when they have no
- * matching certs. If this is NULL, matchless keys will be
- * discarded.
- *
- * Notes: If an error occurs while moving certs, the cert being move may be
- * lost. 'keycerts' may only contain part of the matching certs. The number
- * of certs successfully moved can be found by checking sk_X509_num(keycerts).
- *
- * If there is a key which does not have a matching cert, it is moved to
- * the list nocerts.
- *
- * If all certs are removed from 'certs' and/or 'pkeys', it will be the
- * caller's responsibility to free the empty stacks.
- *
- * Returns:
- * < 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * >= 0 - The number of certs moved from 'cert' to 'pkcerts'.
- */
-int
-sunw_split_certs(STACK_OF(EVP_PKEY) *allkeys, STACK_OF(X509) *allcerts,
- STACK_OF(X509) **keycerts, STACK_OF(EVP_PKEY) **nocerts)
-{
- STACK_OF(X509) *matching;
- STACK_OF(EVP_PKEY) *nomatch;
- EVP_PKEY *tmpkey;
- X509 *tmpcert;
- int count = 0;
- int found;
- int res;
- int i;
- int k;
-
- *keycerts = NULL;
- if (nocerts != NULL)
- *nocerts = NULL;
- nomatch = NULL;
-
- if ((matching = sk_X509_new_null()) == NULL) {
- SUNWerr(SUNW_F_SPLIT_CERTS, SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
- *keycerts = matching;
-
- k = 0;
- while (k < sk_EVP_PKEY_num(allkeys)) {
- found = 0;
- tmpkey = sk_EVP_PKEY_value(allkeys, k);
-
- for (i = 0; i < sk_X509_num(allcerts); i++) {
- tmpcert = sk_X509_value(allcerts, i);
- res = X509_check_private_key(tmpcert, tmpkey);
- if (res != 0) {
- count++;
- found = 1;
- tmpcert = sk_X509_delete(allcerts, i);
- if (sk_X509_push(matching, tmpcert) == 0) {
- X509_free(tmpcert);
- SUNWerr(SUNW_F_SPLIT_CERTS,
- SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
- break;
- }
- }
- if (found != 0) {
- /*
- * Found a match - keep the key & check out the next
- * one.
- */
- k++;
- } else {
- /*
- * No cert matching this key. Move the key if
- * possible or discard it. Don't increment the
- * index.
- */
- if (nocerts == NULL) {
- tmpkey = sk_EVP_PKEY_delete(allkeys, k);
- sunw_evp_pkey_free(tmpkey);
- } else {
- if (*nocerts == NULL) {
- nomatch = sk_EVP_PKEY_new_null();
- if (nomatch == NULL) {
- SUNWerr(SUNW_F_SPLIT_CERTS,
- SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
- *nocerts = nomatch;
- }
- tmpkey = sk_EVP_PKEY_delete(allkeys, k);
- if (sk_EVP_PKEY_push(nomatch, tmpkey) == 0) {
- sunw_evp_pkey_free(tmpkey);
- SUNWerr(SUNW_F_SPLIT_CERTS,
- SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
- }
- }
- }
-
- return (count);
-}
-
-/*
- * sunw_PKCS12_create() creates a pkcs#12 structure and given component parts.
- *
- * Given one or more of user private key, user cert and/or other (CA) certs,
- * return an encrypted PKCS12 structure containing them.
- *
- * Arguments:
- * pass - Pass phrase for the pkcs12 structure and private key (possibly
- * empty) or NULL if there is none. It will be used to encrypt
- * both the private key(s) and as the pass phrase for the whole
- * pkcs12 wad.
- * pkeys - Points to stack of private keys.
- * certs - Points to stack of client (public ke) certs
- * cacerts - Points to stack of 'certificate authority' certs (or trust
- * anchors).
- *
- * Note that any of these may be NULL.
- *
- * Returns:
- * NULL - An error occurred.
- * != NULL - Address of PKCS12 structure. The user is responsible for
- * freeing the memory when done.
- */
-PKCS12 *
-sunw_PKCS12_create(const char *pass, STACK_OF(EVP_PKEY) *pkeys,
- STACK_OF(X509) *certs, STACK_OF(X509) *cacerts)
-{
- int nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
- int nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
- STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
- STACK_OF(PKCS7) *safes = NULL;
- PKCS12_SAFEBAG *bag = NULL;
- PKCS8_PRIV_KEY_INFO *p8 = NULL;
- EVP_PKEY *pkey = NULL;
- PKCS12 *ret_p12 = NULL;
- PKCS12 *p12 = NULL;
- PKCS7 *authsafe = NULL;
- X509 *cert = NULL;
- uchar_t *str = NULL;
- int certs_there = 0;
- int keys_there = 0;
- int len;
- int i;
-
- if ((safes = sk_PKCS7_new_null()) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
- return (NULL);
- }
-
- if ((bags = sk_PKCS12_SAFEBAG_new_null()) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
- goto err_ret;
- }
-
- if (certs != NULL && sk_X509_num(certs) > 0) {
-
- for (i = 0; i < sk_X509_num(certs); i++) {
- cert = sk_X509_value(certs, i);
-
- /* Add user certificate */
- if ((bag = M_PKCS12_x5092certbag(cert)) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR);
- goto err_ret;
- }
- if (cert->aux != NULL && cert->aux->alias != NULL &&
- cert->aux->alias->type == V_ASN1_UTF8STRING) {
- str = utf82ascstr(cert->aux->alias);
- if (str == NULL) {
- /*
- * Error already on stack
- */
- goto err_ret;
- }
- if (PKCS12_add_friendlyname_asc(bag,
- (char const *) str,
- strlen((char const *) str)) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_ADD_ATTR_ERR);
- goto err_ret;
- }
- }
- if (cert->aux != NULL && cert->aux->keyid != NULL &&
- cert->aux->keyid->type == V_ASN1_OCTET_STRING) {
- str = cert->aux->keyid->data;
- len = cert->aux->keyid->length;
-
- if (str != NULL &&
- PKCS12_add_localkeyid(bag, str, len) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_ADD_ATTR_ERR);
- goto err_ret;
- }
- }
- if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_MEMORY_FAILURE);
- goto err_ret;
- }
- certs_there++;
- bag = NULL;
- }
- }
-
- if (cacerts != NULL && sk_X509_num(cacerts) > 0) {
-
- /* Put all certs in structure */
- for (i = 0; i < sk_X509_num(cacerts); i++) {
- cert = sk_X509_value(cacerts, i);
- if ((bag = M_PKCS12_x5092certbag(cert)) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR);
- goto err_ret;
- }
-
- if (cert->aux != NULL && cert->aux->alias != NULL &&
- cert->aux->alias->type == V_ASN1_UTF8STRING) {
- str = utf82ascstr(cert->aux->alias);
- if (str == NULL) {
- /*
- * Error already on stack
- */
- goto err_ret;
- }
- if (PKCS12_add_friendlyname_asc(
- bag, (char const *) str,
- strlen((char const *) str)) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_ADD_ATTR_ERR);
- goto err_ret;
- }
- }
- if (cert->aux != NULL && cert->aux->keyid != NULL &&
- cert->aux->keyid->type == V_ASN1_OCTET_STRING) {
- str = cert->aux->keyid->data;
- len = cert->aux->keyid->length;
-
- if (str != NULL &&
- PKCS12_add_localkeyid(bag, str, len) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_ADD_ATTR_ERR);
- goto err_ret;
- }
- }
- if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_MEMORY_FAILURE);
- goto err_ret;
- }
- certs_there++;
- bag = NULL;
- }
- }
-
- if (certs != NULL || cacerts != NULL && certs_there) {
- /* Turn certbags into encrypted authsafe */
- authsafe = PKCS12_pack_p7encdata(nid_cert, pass, -1,
- NULL, 0, PKCS12_DEFAULT_ITER, bags);
- if (authsafe == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_CERT_ERR);
- goto err_ret;
- }
- sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
- bags = NULL;
-
- if (sk_PKCS7_push(safes, authsafe) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
- goto err_ret;
- }
- authsafe = NULL;
- }
-
- if (pkeys != NULL && sk_EVP_PKEY_num(pkeys) > 0) {
-
- if (bags == NULL &&
- (bags = sk_PKCS12_SAFEBAG_new_null()) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MEMORY_FAILURE);
- goto err_ret;
- }
-
- for (i = 0; i < sk_EVP_PKEY_num(pkeys); i++) {
-
- pkey = sk_EVP_PKEY_value(pkeys, i);
-
- /* Make a shrouded key bag */
- if ((p8 = EVP_PKEY2PKCS8(pkey)) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKEY_ERR);
- goto err_ret;
- }
-
- bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0,
- PKCS12_DEFAULT_ITER, p8);
- if (bag == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_MAKE_BAG_ERR);
- goto err_ret;
- }
- PKCS8_PRIV_KEY_INFO_free(p8);
- p8 = NULL;
-
- len = sunw_get_pkey_fname(GETDO_COPY, pkey,
- (char **)&str);
- if (str != NULL) {
- if (PKCS12_add_friendlyname_asc(bag,
- (const char *)str, len) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_ADD_ATTR_ERR);
- goto err_ret;
- }
- }
- str = NULL;
-
- len = sunw_get_pkey_localkeyid(GETDO_COPY, pkey,
- (char **)&str, &len);
- if (str != NULL) {
- if (PKCS12_add_localkeyid(bag, str, len) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_ADD_ATTR_ERR);
- goto err_ret;
- }
- }
- str = NULL;
-
- if (sk_PKCS12_SAFEBAG_push(bags, bag) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_MEMORY_FAILURE);
- goto err_ret;
- }
- keys_there++;
- bag = NULL;
- }
-
- if (keys_there) {
- /* Turn into unencrypted authsafe */
- authsafe = PKCS12_pack_p7data(bags);
- if (authsafe == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_PKCS12_CREATE_ERR);
- goto err_ret;
- }
- sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
- bags = NULL;
-
- if (sk_PKCS7_push(safes, authsafe) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE,
- SUNW_R_MEMORY_FAILURE);
- }
- authsafe = NULL;
- }
- }
-
- if (certs_there == 0 && keys_there == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_EMPTY_ERR);
- goto err_ret;
- }
-
- if ((p12 = PKCS12_init(NID_pkcs7_data)) == NULL) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_CREATE_ERR);
- goto err_ret;
- }
-
- /*
- * Note that safes is copied by the following. Therefore, it needs
- * to be freed whether or not the following succeeds.
- */
- if (M_PKCS12_pack_authsafes(p12, safes) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_PKCS12_CREATE_ERR);
- goto err_ret;
- }
- if (PKCS12_set_mac(p12, pass, -1, NULL, 0, 2048, NULL) == 0) {
- SUNWerr(SUNW_F_PKCS12_CREATE, SUNW_R_MAC_CREATE_FAILURE);
- goto err_ret;
- }
-
- ret_p12 = p12;
- p12 = NULL;
-
- /* Fallthrough is intentional */
-
-err_ret:
-
- if (str != NULL)
- free(str);
-
- if (p8 != NULL)
- PKCS8_PRIV_KEY_INFO_free(p8);
-
- if (bag != NULL)
- PKCS12_SAFEBAG_free(bag);
- if (bags != NULL)
- sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
- if (authsafe != NULL)
- PKCS7_free(authsafe);
- if (safes != NULL)
- sk_PKCS7_pop_free(safes, PKCS7_free);
- if (p12 != NULL)
- PKCS12_free(p12);
-
- return (ret_p12);
-}
-
-/*
- * sunw_evp_pkey_free() Given an EVP_PKEY structure, free any attributes
- * that are attached. Then free the EVP_PKEY itself.
- *
- * This is a replacement for EVP_PKEY_free() for the sunw stuff.
- * It should be used in places where EVP_PKEY_free would be used,
- * including calls to sk_EVP_PKEY_pop_free().
- *
- * Arguments:
- * pkey - Entry which potentially has attributes to be freed.
- *
- * Returns:
- * None.
- */
-void
-sunw_evp_pkey_free(EVP_PKEY *pkey)
-{
- if (pkey != NULL) {
- if (pkey->attributes != NULL) {
- sk_X509_ATTRIBUTE_pop_free(pkey->attributes,
- X509_ATTRIBUTE_free);
- pkey->attributes = NULL;
- }
- EVP_PKEY_free(pkey);
- }
-}
-
-/*
- * sunw_set_localkeyid() sets the localkeyid in a cert, a private key or
- * both. Any existing localkeyid will be discarded.
- *
- * Arguments:
- * keyid_str- A byte string with the localkeyid to set
- * keyid_len- Length of the keyid byte string.
- * pkey - Points to a private key to set the keyidstr in.
- * cert - Points to a cert to set the keyidstr in.
- *
- * Note that setting a keyid into a cert which will not be written out as
- * a PKCS12 cert is pointless since it will be lost.
- *
- * Returns:
- * 0 - Success.
- * < 0 - An error occurred. It was probably an error in allocating
- * memory. The error will be set in the error stack. Call
- * ERR_get_error() to get specific information.
- */
-int
-sunw_set_localkeyid(const char *keyid_str, int keyid_len, EVP_PKEY *pkey,
- X509 *cert)
-{
- X509_ATTRIBUTE *attr = NULL;
- ASN1_STRING *str = NULL;
- ASN1_TYPE *keyid = NULL;
- int retval = -1;
- int i;
-
- if (cert != NULL) {
- if (X509_keyid_set1(cert, (uchar_t *)keyid_str, keyid_len)
- == 0) {
- SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_SET_LKID_ERR);
- goto cleanup;
- }
- }
- if (pkey != NULL) {
- str = (ASN1_STRING *)M_ASN1_OCTET_STRING_new();
- if (str == NULL ||
- M_ASN1_OCTET_STRING_set(str, keyid_str, keyid_len) == 0 ||
- (keyid = ASN1_TYPE_new()) == NULL) {
- SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
-
- ASN1_TYPE_set(keyid, V_ASN1_OCTET_STRING, str);
- str = NULL;
-
- attr = type2attrib(keyid, NID_localKeyID);
- if (attr == NULL) {
- /*
- * Error already on stack
- */
- goto cleanup;
- }
- keyid = NULL;
-
- if (pkey->attributes == NULL) {
- pkey->attributes = sk_X509_ATTRIBUTE_new_null();
- if (pkey->attributes == NULL) {
- SUNWerr(SUNW_F_SET_LOCALKEYID,
- SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
- } else {
- i = find_attr_by_nid(pkey->attributes, NID_localKeyID);
- if (i >= 0)
- sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
- }
- if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) {
- SUNWerr(SUNW_F_SET_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
- attr = NULL;
- }
- retval = 0;
-
-cleanup:
- if (str != NULL)
- ASN1_STRING_free(str);
- if (keyid != NULL)
- ASN1_TYPE_free(keyid);
- if (attr != NULL)
- X509_ATTRIBUTE_free(attr);
-
- return (retval);
-}
-
-/*
- * sunw_get_pkey_localkeyid() gets the localkeyid from a private key. It can
- * optionally remove the value found.
- *
- * Arguments:
- * dowhat - What to do with the attributes (remove them or copy them).
- * pkey - Points to a private key to set the keyidstr in.
- * keyid_str- Points to a location which will receive the pointer to
- * a byte string containing the binary localkeyid. Note that
- * this is a copy, and the caller must free it.
- * keyid_len- Length of keyid_str.
- *
- * Returns:
- * >= 0 - The number of characters in the keyid returned.
- * < 0 - An error occurred. It was probably an error in allocating
- * memory. The error will be set in the error stack. Call
- * ERR_get_error() to get specific information.
- */
-int
-sunw_get_pkey_localkeyid(getdo_actions_t dowhat, EVP_PKEY *pkey,
- char **keyid_str, int *keyid_len)
-{
- X509_ATTRIBUTE *attr = NULL;
- ASN1_OCTET_STRING *str = NULL;
- ASN1_TYPE *ty = NULL;
- int len = 0;
- int i;
-
- if (keyid_str != NULL)
- *keyid_str = NULL;
- if (keyid_len != NULL)
- *keyid_len = 0;
-
- if (pkey == NULL || pkey->attributes == NULL) {
- return (0);
- }
-
- if ((i = find_attr_by_nid(pkey->attributes, NID_localKeyID)) < 0) {
- return (0);
- }
- attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
-
- if ((ty = attrib2type(attr)) == NULL ||
- ty->type != V_ASN1_OCTET_STRING) {
- return (0);
- }
-
- if (dowhat == GETDO_DEL) {
- attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
- if (attr != NULL)
- X509_ATTRIBUTE_free(attr);
- return (0);
- }
-
- str = ty->value.octet_string;
- len = str->length;
- if ((*keyid_str = malloc(len)) == NULL) {
- SUNWerr(SUNW_F_GET_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
-
- (void) memcpy(*keyid_str, str->data, len);
- *keyid_len = len;
-
- return (len);
-}
-
-/*
- * sunw_get_pkey_fname() gets the friendlyName from a private key. It can
- * optionally remove the value found.
- *
- * Arguments:
- * dowhat - What to do with the attributes (remove them or copy them).
- * pkey - Points to a private key to get the frientlyname from
- * fname - Points to a location which will receive the pointer to a
- * byte string with the ASCII friendlyname
- *
- * Returns:
- * >= 0 - The number of characters in the frienlyname returned.
- * < 0 - An error occurred. It was probably an error in allocating
- * memory. The error will be set in the error stack. Call
- * ERR_get_error() to get specific information.
- */
-int
-sunw_get_pkey_fname(getdo_actions_t dowhat, EVP_PKEY *pkey, char **fname)
-{
- X509_ATTRIBUTE *attr = NULL;
- ASN1_BMPSTRING *str = NULL;
- ASN1_TYPE *ty = NULL;
- int len = 0;
- int i;
-
- if (fname != NULL)
- *fname = NULL;
-
- if (pkey == NULL || pkey->attributes == NULL) {
- return (0);
- }
-
- if ((i = find_attr_by_nid(pkey->attributes, NID_friendlyName)) < 0) {
- return (0);
- }
- attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
-
- if ((ty = attrib2type(attr)) == NULL ||
- ty->type != V_ASN1_BMPSTRING) {
- return (0);
- }
-
- if (dowhat == GETDO_DEL) {
- attr = sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
- if (attr != NULL)
- X509_ATTRIBUTE_free(attr);
- return (0);
- }
-
- str = ty->value.bmpstring;
-#if OPENSSL_VERSION_NUMBER < 0x10000000L
- *fname = uni2asc(str->data, str->length);
-#else
- *fname = OPENSSL_uni2asc(str->data, str->length);
-#endif
- if (*fname == NULL) {
- SUNWerr(SUNW_F_GET_PKEY_FNAME, SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
-
- len = strlen(*fname);
-
- return (len);
-}
-
-/*
- * sunw_find_localkeyid() searches stacks of certs and private keys,
- * and returns the first matching cert/private key found.
- *
- * Look for a keyid in a stack of certs. if 'certs' is NULL and 'pkeys' is
- * not NULL, search the list of private keys. Move the matching cert to
- * 'matching_cert' and its matching private key to 'matching_pkey'. If no
- * cert or keys match, no match occurred.
- *
- * Arguments:
- * keyid_str- A byte string with the localkeyid to match
- * keyid_len- Length of the keyid byte string.
- * pkeys - Points to a stack of private keys which match the certs.
- * This may be NULL, in which case no keys are returned.
- * certs - Points to a stack of certs to search. If NULL, search the
- * stack of keys instead.
- * matching_pkey
- * - Pointer to receive address of first matching pkey found.
- * 'matching_pkey' must not be NULL; '*matching_pkey' will be
- * reset.
- * matching_cert
- * - Pointer to receive address of first matching cert found.
- * 'matching_cert' must not be NULL; '*matching_cert' will be
- * reset.
- *
- * Returns:
- * < 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * >= 0 - Objects were found and returned. Which objects are indicated by
- * which bits are set (FOUND_PKEY and/or FOUND_CERT).
- */
-int
-sunw_find_localkeyid(char *keyid_str, int len, STACK_OF(EVP_PKEY) *pkeys,
-STACK_OF(X509) *certs, EVP_PKEY **matching_pkey, X509 **matching_cert)
-{
- ASN1_STRING *cmpstr = NULL;
- EVP_PKEY *tmp_pkey = NULL;
- X509 *tmp_cert = NULL;
- int retval = 0;
-
- /* If NULL arguments, this is an error */
- if (keyid_str == NULL ||
- (pkeys == NULL || certs == NULL) ||
- (pkeys != NULL && matching_pkey == NULL) ||
- (certs != NULL && matching_cert == NULL)) {
- SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_INVALID_ARG);
- return (-1);
- }
-
- if (matching_pkey != NULL)
- *matching_pkey = NULL;
- if (matching_cert != NULL)
- *matching_cert = NULL;
-
- cmpstr = (ASN1_STRING *)M_ASN1_OCTET_STRING_new();
- if (cmpstr == NULL ||
- M_ASN1_OCTET_STRING_set(cmpstr, keyid_str, len) == 0) {
- SUNWerr(SUNW_F_FIND_LOCALKEYID, SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
-
- retval = find_attr(NID_localKeyID, cmpstr, pkeys, &tmp_pkey, certs,
- &tmp_cert);
- if (retval == 0) {
- ASN1_STRING_free(cmpstr);
- return (retval);
- }
-
- if (matching_pkey != NULL)
- *matching_pkey = tmp_pkey;
- if (matching_cert != NULL)
- *matching_cert = tmp_cert;
-
- return (retval);
-}
-
-/*
- * sunw_find_fname() searches stacks of certs and private keys for one with
- * a matching friendlyname and returns the first matching cert/private
- * key found.
- *
- * Look for a friendlyname in a stack of certs. if 'certs' is NULL and 'pkeys'
- * is not NULL, search the list of private keys. Move the matching cert to
- * 'matching_cert' and its matching private key to 'matching_pkey'. If no
- * cert or keys match, no match occurred.
- *
- * Arguments:
- * fname - Friendlyname to find (NULL-terminated ASCII string).
- * pkeys - Points to a stack of private keys which match the certs.
- * This may be NULL, in which case no keys are returned.
- * certs - Points to a stack of certs to search. If NULL, search the
- * stack of keys instead.
- * matching_pkey
- * - Pointer to receive address of first matching pkey found.
- * matching_cert
- * - Pointer to receive address of first matching cert found.
- *
- * Returns:
- * < 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * >= 0 - Objects were found and returned. Which objects are indicated by
- * which bits are set (FOUND_PKEY and/or FOUND_CERT).
- */
-int
-sunw_find_fname(char *fname, STACK_OF(EVP_PKEY) *pkeys, STACK_OF(X509) *certs,
- EVP_PKEY **matching_pkey, X509 ** matching_cert)
-{
- ASN1_STRING *cmpstr = NULL;
- EVP_PKEY *tmp_pkey = NULL;
- X509 *tmp_cert = NULL;
- int retval = 0;
-
- /* If NULL arguments, this is an error */
- if (fname == NULL ||
- (pkeys == NULL && certs == NULL) ||
- (pkeys != NULL && matching_pkey == NULL) ||
- (certs != NULL && matching_cert == NULL)) {
- SUNWerr(SUNW_F_FIND_FNAME, SUNW_R_INVALID_ARG);
- return (-1);
- }
-
- if (matching_pkey != NULL)
- *matching_pkey = NULL;
- if (matching_cert != NULL)
- *matching_cert = NULL;
-
- cmpstr = (ASN1_STRING *)asc2bmpstring(fname, strlen(fname));
- if (cmpstr == NULL) {
- /*
- * Error already on stack
- */
- return (-1);
- }
-
- retval = find_attr(NID_friendlyName, cmpstr, pkeys, &tmp_pkey, certs,
- &tmp_cert);
- if (retval == 0) {
- ASN1_STRING_free(cmpstr);
- return (retval);
- }
-
- if (matching_pkey != NULL)
- *matching_pkey = tmp_pkey;
- if (matching_cert != NULL)
- *matching_cert = tmp_cert;
-
- return (retval);
-}
-
-/*
- * sunw_get_cert_fname() gets the fiendlyname from a cert. It can
- * optionally remove the value found.
- *
- * Arguments:
- * dowhat - What to do with the attributes (remove them or copy them).
- * cert - Points to a cert to get the friendlyName from.
- * fname - Points to a location which will receive the pointer to a
- * byte string with the ASCII friendlyname
- *
- * Returns:
- * >= 0 - The number of characters in the friendlyname returned.
- * < 0 - An error occurred. It was probably an error in allocating
- * memory. The error will be set in the error stack. Call
- * ERR_get_error() to get specific information.
- */
-int
-sunw_get_cert_fname(getdo_actions_t dowhat, X509 *cert, char **fname)
-{
- int len;
-
- if (fname != NULL)
- *fname = NULL;
-
- if (cert == NULL || cert->aux == NULL || cert->aux->alias == NULL) {
- return (0);
- }
-
- if (dowhat == GETDO_DEL) {
- /* Delete the entry */
- ASN1_UTF8STRING_free(cert->aux->alias);
- cert->aux->alias = NULL;
- return (0);
- }
-
- *((uchar_t **)fname) = utf82ascstr(cert->aux->alias);
- if (*fname == NULL) {
- /*
- * Error already on stack
- */
- return (-1);
- }
-
- len = strlen(*fname);
-
- return (len);
-}
-
-/*
- * sunw_set_fname() sets the friendlyName in a cert, a private key or
- * both. Any existing friendlyname will be discarded.
- *
- * Arguments:
- * ascname - An ASCII string with the friendlyName to set
- * pkey - Points to a private key to set the fname in.
- * cert - Points to a cert to set the fname in.
- *
- * Note that setting a friendlyName into a cert which will not be written out
- * as a PKCS12 cert is pointless since it will be lost.
- *
- * Returns:
- * 0 - Success.
- * <0 - An error occurred. It was probably an error in allocating
- * memory. The error will be set in the error stack. Call
- * ERR_get_error() to get specific information.
- */
-int
-sunw_set_fname(const char *ascname, EVP_PKEY *pkey, X509 *cert)
-{
- X509_ATTRIBUTE *attr = NULL;
- ASN1_BMPSTRING *str = NULL;
- ASN1_TYPE *fname = NULL;
- unsigned char *data = NULL;
- int retval = -1;
- int len;
- int i;
-
- str = asc2bmpstring(ascname, strlen(ascname));
- if (str == NULL) {
- /*
- * Error already on stack
- */
- return (-1);
- }
-
- if (cert != NULL) {
- if (cert->aux != NULL && cert->aux->alias != NULL) {
- ASN1_UTF8STRING_free(cert->aux->alias);
- }
-
- len = ASN1_STRING_to_UTF8(&data, str);
- i = -23;
- if (len <= 0 || (i = X509_alias_set1(cert, data, len)) == 0) {
- SUNWerr(SUNW_F_SET_FNAME, SUNW_R_SET_FNAME_ERR);
- goto cleanup;
- }
- }
- if (pkey != NULL) {
- if ((fname = ASN1_TYPE_new()) == NULL) {
- SUNWerr(SUNW_F_SET_FNAME, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
-
- ASN1_TYPE_set(fname, V_ASN1_BMPSTRING, str);
- str = NULL;
-
- attr = type2attrib(fname, NID_friendlyName);
- if (attr == NULL) {
- /*
- * Error already on stack
- */
- goto cleanup;
- }
- fname = NULL;
-
- if (pkey->attributes == NULL) {
- pkey->attributes = sk_X509_ATTRIBUTE_new_null();
- if (pkey->attributes == NULL) {
- SUNWerr(SUNW_F_SET_FNAME,
- SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
- } else if ((i = find_attr_by_nid(pkey->attributes,
- NID_friendlyName)) >= 0) {
- (void) sk_X509_ATTRIBUTE_delete(pkey->attributes, i);
- }
-
- if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == 0) {
- SUNWerr(SUNW_F_SET_FNAME, SUNW_R_MEMORY_FAILURE);
- goto cleanup;
- }
-
- attr = NULL;
- }
- retval = 0;
-
-cleanup:
- if (data != NULL)
- OPENSSL_free(data);
- if (str != NULL)
- ASN1_BMPSTRING_free(str);
- if (fname != NULL)
- ASN1_TYPE_free(fname);
- if (attr != NULL)
- X509_ATTRIBUTE_free(attr);
-
- return (retval);
-}
-
-/*
- * sunw_check_keys() compares the public key in the certificate and a
- * private key to ensure that they match.
- *
- * Arguments:
- * cert - Points to a certificate.
- * pkey - Points to a private key.
- *
- * Returns:
- * == 0 - These do not match.
- * != 0 - The cert's public key and the private key match.
- */
-int
-sunw_check_keys(X509 *cert, EVP_PKEY *pkey)
-{
- int retval = 0;
-
- if (pkey != NULL && cert != NULL)
- retval = X509_check_private_key(cert, pkey);
-
- return (retval);
-}
-
-/*
- * sunw_check_cert_times() compares the time fields in a certificate
- *
- * Compare the 'not before' and the 'not after' times in the cert
- * to the current time. Return the results of the comparison (bad time formats,
- * cert not yet in force, cert expired or in range)
- *
- * Arguments:
- * dowhat - what field(s) to check.
- * cert - Points to a cert to check
- *
- * Returns:
- * Results of the comparison.
- */
-chk_errs_t
-sunw_check_cert_times(chk_actions_t chkwhat, X509 *cert)
-{
- return (check_time(chkwhat, cert));
-}
-
-/*
- * ----------------------------------------------------------------------------
- * Local routines
- * ----------------------------------------------------------------------------
- */
-
-
-/*
- * parse_pkcs12 - Oversee parsing of the pkcs12 structure. Get it
- * parsed. After that either return what's found directly, or
- * do any required matching.
- *
- * Arguments:
- * p12 - Structure with pkcs12 info to be parsed
- * pass - Pass phrase for the private key (possibly empty) or NULL if
- * there is none.
- * matchty - Info about which certs/keys to return if many are in the file.
- * keyid - If private key localkeyids friendlynames are to match a
- * predetermined value, the value to match. This value should
- * be an octet string.
- * keyid_len- Length of the keyid byte string.
- * name_str - If friendlynames are to match a predetermined value, the value
- * to match. This value should be a NULL terminated string.
- * pkey - Points to location pointing to the private key returned.
- * cert - Points to locaiton which points to the client cert returned
- * ca - Points to location that points to a stack of 'certificate
- * authority' certs/trust anchors.
- *
- * Note about error codes: This function is an internal function, and the
- * place where it is called sets error codes. Therefore only set an error
- * code if it is something that is unique or if the function which detected
- * the error doesn't set one.
- *
- * Returns:
- * == -1 - An error occurred. Call ERR_get_error() to get error information.
- * Where possible, memory has been freed.
- * == 0 - No matching returns were found.
- * > 0 - This is the aithmetic 'or' of the FOUND_* bits that indicate which
- * of the requested entries were found.
- */
-static int
-parse_pkcs12(PKCS12 *p12, const char *pass, int matchty, char *keyid,
- int kstr_len, char *name_str, EVP_PKEY **pkey, X509 **cert,
- STACK_OF(X509) **ca)
-{
- STACK_OF(EVP_PKEY) *work_kl = NULL; /* Head for private key list */
- STACK_OF(EVP_PKEY) *nocerts = NULL; /* Head for alt. key list */
- STACK_OF(X509) *work_ca = NULL; /* Head for cert list */
- STACK_OF(X509) *work_cl = NULL;
- int retval = 0;
- int n;
-
- retval = sunw_PKCS12_contents(p12, pass, &work_kl, &work_ca);
- if (retval < 0) {
- goto cleanup;
- } else if (retval == 0) {
- /*
- * Not really an error here - its just that nothing was found.
- */
- goto cleanup;
- }
-
- if (sk_EVP_PKEY_num(work_kl) > 0) {
-
- if (sunw_split_certs(work_kl, work_ca, &work_cl, &nocerts)
- < 0) {
- goto cleanup;
- }
- }
-
- /*
- * Go through the lists of certs and private keys which were
- * returned, looking for matches of the appropriate type. Do these
- * in the order described above.
- */
- if ((matchty & DO_FIND_KEYID) != 0) {
-
- if (keyid == NULL) {
- SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
- retval = -1;
- goto cleanup;
- }
-
- /* See if string matches localkeyid's */
- retval = sunw_find_localkeyid(keyid, kstr_len,
- work_kl, work_cl, pkey, cert);
- if (retval != 0) {
- if (retval == -1)
- goto cleanup;
- else
- goto last_part;
- }
- }
- if ((matchty & DO_FIND_FN) != 0) {
-
- if (name_str == NULL) {
- SUNWerr(SUNW_F_PKCS12_PARSE, SUNW_R_INVALID_ARG);
- retval = -1;
- goto cleanup;
- }
-
- /* See if string matches friendly names */
- retval = sunw_find_fname(name_str, work_kl, work_cl,
- pkey, cert);
- if (retval != 0) {
- if (retval == -1)
- goto cleanup;
- else
- goto last_part;
- }
- }
-
- if (matchty & DO_FIRST_PAIR) {
-
- /* Find the first cert and private key and return them */
- retval = get_key_cert(0, work_kl, pkey, work_cl, cert);
- if (retval != 0) {
- if (retval == -1)
- goto cleanup;
- else
- goto last_part;
- }
- }
-
- if (matchty & DO_LAST_PAIR) {
-
- /*
- * Find the last matching cert and private key and return
- * them. Since keys which don't have matching client certs
- * are at the end of the list of keys, use the number of
- * client certs to compute the position of the last private
- * key which matches a client cert.
- */
- n = sk_X509_num(work_cl) - 1;
- retval = get_key_cert(n, work_kl, pkey, work_cl, cert);
- if (retval != 0) {
- if (retval == -1)
- goto cleanup;
- else
- goto last_part;
- }
- }
-
- if (matchty & DO_UNMATCHING) {
- STACK_OF(EVP_PKEY) *tmpk;
- STACK_OF(X509) *tmpc;
-
- /* Find the first cert and private key and return them */
- tmpc = work_cl;
- if (work_cl == NULL || sk_X509_num(work_cl) == 0)
- tmpc = work_ca;
- tmpk = work_kl;
- if (work_kl == NULL || sk_EVP_PKEY_num(work_kl) == 0)
- tmpk = nocerts;
- retval = get_key_cert(0, tmpk, pkey, tmpc, cert);
- if (retval != 0) {
- if (retval == -1)
- goto cleanup;
- else
- goto last_part;
- }
- }
-
-last_part:
- /* If no errors, terminate normally */
- if (retval != -1)
- retval |= set_results(NULL, NULL, NULL, NULL, ca, &work_ca,
- NULL, NULL);
- if (retval >= 0) {
- goto clean_part;
- }
-
- /* Fallthrough is intentional in error cases. */
-cleanup:
- if (pkey != NULL && *pkey != NULL) {
- sunw_evp_pkey_free(*pkey);
- *pkey = NULL;
- }
- if (cert != NULL && *cert != NULL) {
- X509_free(*cert);
- *cert = NULL;
- }
-
-clean_part:
-
- if (work_kl != NULL) {
- sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
- }
- if (work_ca != NULL)
- sk_X509_pop_free(work_ca, X509_free);
- if (work_cl != NULL)
- sk_X509_pop_free(work_cl, X509_free);
-
- return (retval);
-}
-
-/*
- * parse_outer - Unpack the outer PKCS#12 structure and go through the
- * individual bags. Return stacks of certs, private keys found and
- * CA certs found.
- *
- * Note about error codes: This function is an internal function, and the
- * place where it is called sets error codes.
- *
- * Returns:
- * 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * 1 - PKCS12 data object was parsed and lists of certs and private keys
- * were returned.
- */
-static int
-parse_outer(PKCS12 *p12, const char *pass, STACK_OF(EVP_PKEY) *kl,
- STACK_OF(X509) *cl)
-{
- STACK_OF(PKCS12_SAFEBAG) *bags;
- STACK_OF(PKCS7) *asafes;
- int i, bagnid;
- PKCS7 *p7;
-
- if ((asafes = M_PKCS12_unpack_authsafes(p12)) == NULL)
- return (0);
-
- for (i = 0; i < sk_PKCS7_num(asafes); i++) {
- p7 = sk_PKCS7_value(asafes, i);
- bagnid = OBJ_obj2nid(p7->type);
- if (bagnid == NID_pkcs7_data) {
- bags = M_PKCS12_unpack_p7data(p7);
- } else if (bagnid == NID_pkcs7_encrypted) {
- /*
- * A length of '-1' means strlen() can be used
- * to determine the password length.
- */
- bags = M_PKCS12_unpack_p7encdata(p7, pass, -1);
- } else {
- SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_BAD_BAGTYPE);
- return (0);
- }
-
- if (bags == NULL) {
- SUNWerr(SUNW_F_PARSE_OUTER, SUNW_R_PARSE_BAG_ERR);
- sk_PKCS7_pop_free(asafes, PKCS7_free);
- return (0);
- }
- if (parse_all_bags(bags, pass, kl, cl) == 0) {
- sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
- sk_PKCS7_pop_free(asafes, PKCS7_free);
- return (0);
- }
- }
-
- return (1);
-}
-
-/*
- * parse_all_bags - go through the stack of bags, parsing each.
- *
- * Note about error codes: This function is an internal function, and the
- * place where it is called sets error codes.
- *
- * Returns:
- * 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * 1 - Stack of safebags was parsed and lists of certs and private keys
- * were returned.
- */
-static int
-parse_all_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
- STACK_OF(EVP_PKEY) *kl, STACK_OF(X509) *cl)
-{
- int i;
- for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
- if (parse_one_bag(sk_PKCS12_SAFEBAG_value(bags, i),
- pass, kl, cl) == 0)
- return (0);
- }
- return (1);
-}
-
-/*
- * parse_one_bag - Parse an individual bag
- *
- * i = parse_one_bag(bag, pass, kl, cl);
- *
- * Arguments:
- * bag - pkcs12 safebag to parse.
- * pass - password for use in decryption of shrouded keybag
- * kl - Stack of private keys found so far. New private keys will
- * be added here if found.
- * cl - Stack of certs found so far. New certificates will be
- * added here if found.
- *
- * Returns:
- * 0 - An error returned. Call ERR_get_error() to get errors information.
- * Where possible, memory has been freed.
- * 1 - one safebag was parsed. If it contained a cert or private key, it
- * was added to the stack of certs or private keys found, respectively.
- * localKeyId or friendlyName attributes are returned with the
- * private key or certificate.
- */
-static int
-parse_one_bag(PKCS12_SAFEBAG *bag, const char *pass, STACK_OF(EVP_PKEY) *kl,
- STACK_OF(X509) *cl)
-{
- X509_ATTRIBUTE *attr = NULL;
- ASN1_TYPE *keyid = NULL;
- ASN1_TYPE *fname = NULL;
- PKCS8_PRIV_KEY_INFO *p8;
- EVP_PKEY *pkey = NULL;
- X509 *x509 = NULL;
- uchar_t *data = NULL;
- char *str = NULL;
- int retval = 1;
-
- keyid = PKCS12_get_attr(bag, NID_localKeyID);
- fname = PKCS12_get_attr(bag, NID_friendlyName);
-
- switch (M_PKCS12_bag_type(bag)) {
- case NID_keyBag:
- if ((pkey = EVP_PKCS82PKEY(bag->value.keybag)) == NULL) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
- retval = 0;
- break;
- }
- break;
-
- case NID_pkcs8ShroudedKeyBag:
- /*
- * A length of '-1' means strlen() can be used
- * to determine the password length.
- */
- if ((p8 = M_PKCS12_decrypt_skey(bag, pass, -1)) == NULL) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
- retval = 0;
- break;
- }
- pkey = EVP_PKCS82PKEY(p8);
- PKCS8_PRIV_KEY_INFO_free(p8);
- if (pkey == NULL) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_PARSE_BAG_ERR);
- retval = 0;
- }
- break;
-
- case NID_certBag:
- if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_CERTTYPE);
- break;
- }
- if ((x509 = M_PKCS12_certbag2x509(bag)) == NULL) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_PARSE_CERT_ERR);
- retval = 0;
- break;
- }
-
- if (keyid != NULL) {
- if (keyid->type != V_ASN1_OCTET_STRING) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_BAD_LKID);
- retval = 0;
- break;
- }
- if (X509_keyid_set1(x509,
- keyid->value.octet_string->data,
- keyid->value.octet_string->length) == 0) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_SET_LKID_ERR);
- retval = 0;
- break;
- }
- }
-
- if (fname != NULL) {
- ASN1_STRING *tmpstr = NULL;
- int len;
-
- if (fname->type != V_ASN1_BMPSTRING) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_BAD_FNAME);
- retval = 0;
- break;
- }
-
- tmpstr = fname->value.asn1_string;
- len = ASN1_STRING_to_UTF8(&data, tmpstr);
- if (len < 0) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_SET_FNAME_ERR);
- retval = 0;
- break;
- }
-
- if (X509_alias_set1(x509, data, len) == 0) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_SET_FNAME_ERR);
- retval = 0;
- break;
- }
- }
-
- if (sk_X509_push(cl, x509) == 0) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_MEMORY_FAILURE);
- retval = 0;
- break;
- }
- x509 = NULL;
- break;
-
- case NID_safeContentsBag:
- if (keyid != NULL)
- ASN1_TYPE_free(keyid);
- if (fname != NULL)
- ASN1_TYPE_free(fname);
- if (parse_all_bags(bag->value.safes, pass, kl, cl) == 0) {
- /*
- * Error already on stack
- */
- return (0);
- }
- return (1);
-
- default:
- if (keyid != NULL)
- ASN1_TYPE_free(keyid);
- if (fname != NULL)
- ASN1_TYPE_free(fname);
- SUNWerr(SUNW_F_PARSE_ONE_BAG, SUNW_R_BAD_BAGTYPE);
- return (0);
- }
-
-
- if (pkey != NULL) {
- if (retval != 0 && (keyid != NULL || fname != NULL) &&
- pkey->attributes == NULL) {
- pkey->attributes = sk_X509_ATTRIBUTE_new_null();
- if (pkey->attributes == NULL) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_MEMORY_FAILURE);
- retval = 0;
- }
- }
-
- if (retval != 0 && keyid != NULL) {
- attr = type2attrib(keyid, NID_localKeyID);
- if (attr == NULL)
- /*
- * Error already on stack
- */
- retval = 0;
- else {
- keyid = NULL;
- if (sk_X509_ATTRIBUTE_push(pkey->attributes,
- attr) == 0) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_MEMORY_FAILURE);
- retval = 0;
- } else {
- attr = NULL;
- }
- }
- }
-
- if (retval != 0 && fname != NULL) {
- attr = type2attrib(fname, NID_friendlyName);
- if (attr == NULL) {
- /*
- * Error already on stack
- */
- retval = 0;
- } else {
- fname = NULL;
- if (sk_X509_ATTRIBUTE_push(pkey->attributes,
- attr) == 0) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_MEMORY_FAILURE);
- retval = 0;
- } else {
- attr = NULL;
- }
- }
- }
-
- /* Save the private key */
- if (retval != 0) {
- if (sk_EVP_PKEY_push(kl, pkey) == 0) {
- SUNWerr(SUNW_F_PARSE_ONE_BAG,
- SUNW_R_MEMORY_FAILURE);
- retval = 0;
- } else {
- pkey = NULL;
- }
- }
- }
-
- if (pkey != NULL) {
- sunw_evp_pkey_free(pkey);
- }
-
- if (x509 != NULL)
- X509_free(x509);
-
- if (keyid != NULL)
- ASN1_TYPE_free(keyid);
-
- if (fname != NULL)
- ASN1_TYPE_free(fname);
-
- if (attr != NULL)
- X509_ATTRIBUTE_free(attr);
-
- if (data != NULL)
- OPENSSL_free(data);
-
- if (str != NULL)
- OPENSSL_free(str);
-
- return (retval);
-}
-
-/*
- * This function uses the only function that reads PEM files, regardless of
- * the kinds of information included (private keys, public keys, cert requests,
- * certs). Other interfaces that read files require that the application
- * specifically know what kinds of things to read next, and call different
- * interfaces for the different kinds of entities.
- *
- * There is only one aspect of this function that's a bit problematic.
- * If it finds an encrypted private key, it does not decrypt it. It returns
- * the encrypted data and other information needed to decrypt it. The caller
- * must do the decryption. This function does the decoding.
- */
-static int
-pem_info(FILE *fp, pem_password_cb cb, void *userdata,
- STACK_OF(EVP_PKEY) **pkeys, STACK_OF(X509) **certs)
-{
- STACK_OF(X509_INFO) *info;
- STACK_OF(EVP_PKEY) *work_kl;
- STACK_OF(X509) *work_cl;
- X509_INFO *x;
- int retval = 0;
- int i;
-
- info = PEM_X509_INFO_read(fp, NULL, cb, userdata);
- if (info == NULL) {
- SUNWerr(SUNW_F_PEM_INFO, SUNW_R_READ_ERR);
- return (-1);
- }
-
- /*
- * Allocate the working stacks for private key(s) and for the cert(s).
- */
- if ((work_kl = sk_EVP_PKEY_new_null()) == NULL) {
- SUNWerr(SUNW_F_PEM_INFO, SUNW_R_MEMORY_FAILURE);
- retval = -1;
- goto cleanup;
- }
-
- if ((work_cl = sk_X509_new_null()) == NULL) {
- SUNWerr(SUNW_F_PEM_INFO, SUNW_R_MEMORY_FAILURE);
- retval = -1;
- goto cleanup;
- }
-
- /*
- * Go through the entries in the info structure.
- */
- for (i = 0; i < sk_X509_INFO_num(info); i++) {
- x = sk_X509_INFO_value(info, i);
- if (x->x509) {
- if (sk_X509_push(work_cl, x->x509) == 0) {
- retval = -1;
- break;
- }
- x->x509 = NULL;
- }
- if (x->x_pkey != NULL && x->x_pkey->dec_pkey != NULL &&
- (x->x_pkey->dec_pkey->type == EVP_PKEY_RSA ||
- x->x_pkey->dec_pkey->type == EVP_PKEY_DSA)) {
- const uchar_t *p;
-
- /*
- * If the key was encrypted, PEM_X509_INFO_read does
- * not decrypt it. If that is the case, the 'enc_pkey'
- * field is set to point to the unencrypted key data.
- * Go through the additional steps to decode it before
- * going on.
- */
- if (x->x_pkey->enc_pkey != NULL) {
-
- if (PEM_do_header(&x->enc_cipher,
- (uchar_t *)x->enc_data,
- (long *)&x->enc_len,
- cb, userdata) == 0) {
- if (ERR_GET_REASON(ERR_peek_error()) ==
- PEM_R_BAD_PASSWORD_READ) {
- SUNWerr(SUNW_F_PEM_INFO,
- SUNW_R_PASSWORD_ERR);
- } else {
- SUNWerr(SUNW_F_PEM_INFO,
- SUNW_R_PKEY_READ_ERR);
- }
- retval = -1;
- break;
- }
- if (x->x_pkey->dec_pkey->type == EVP_PKEY_RSA) {
- RSA **pp;
-
- pp = &(x->x_pkey->dec_pkey->pkey.rsa);
- p = (uchar_t *)x->enc_data;
- if (d2i_RSAPrivateKey(pp, &p,
- x->enc_len) == NULL) {
- SUNWerr(SUNW_F_PEM_INFO,
- SUNW_R_PKEY_READ_ERR);
- retval = -1;
- break;
- }
- } else {
- DSA **pp;
-
- pp = &(x->x_pkey->dec_pkey->pkey.dsa);
- p = (uchar_t *)x->enc_data;
- if (d2i_DSAPrivateKey(pp, &p,
- x->enc_len) == NULL) {
- SUNWerr(SUNW_F_PEM_INFO,
- SUNW_R_PKEY_READ_ERR);
- retval = -1;
- break;
- }
- }
- }
-
- /* Save the key. */
- retval = sk_EVP_PKEY_push(work_kl, x->x_pkey->dec_pkey);
- if (retval == 0) {
- retval = -1;
- break;
- }
- x->x_pkey->dec_pkey = NULL;
- } else if (x->x_pkey != NULL) {
- SUNWerr(SUNW_F_PEM_INFO, SUNW_R_BAD_PKEYTYPE);
- retval = -1;
- break;
- }
- }
- if (retval == -1)
- goto cleanup;
-
- /* If error occurs, then error already on stack */
- retval = set_results(pkeys, &work_kl, certs, &work_cl, NULL, NULL,
- NULL, NULL);
-
-cleanup:
- if (work_kl != NULL) {
- sk_EVP_PKEY_pop_free(work_kl, sunw_evp_pkey_free);
- }
- if (work_cl != NULL)
- sk_X509_pop_free(work_cl, X509_free);
-
- sk_X509_INFO_pop_free(info, X509_INFO_free);
-
- return (retval);
-}
-
-/*
- * sunw_append_keys - Given two stacks of private keys, remove the keys from
- * the second stack and append them to the first. Both stacks must exist
- * at time of call.
- *
- * Arguments:
- * dst - the stack to receive the keys from 'src'
- * src - the stack whose keys are to be moved.
- *
- * Returns:
- * -1 - An error occurred. The error status is set.
- * >= 0 - The number of keys that were copied.
- */
-static int
-sunw_append_keys(STACK_OF(EVP_PKEY) *dst, STACK_OF(EVP_PKEY) *src)
-{
- EVP_PKEY *tmpk;
- int count = 0;
-
- while (sk_EVP_PKEY_num(src) > 0) {
- tmpk = sk_EVP_PKEY_delete(src, 0);
- if (sk_EVP_PKEY_push(dst, tmpk) == 0) {
- sunw_evp_pkey_free(tmpk);
- SUNWerr(SUNW_F_APPEND_KEYS, SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
- count ++;
- }
-
- return (count);
-}
-
-/*
- * move_certs - Given two stacks of certs, remove the certs from
- * the second stack and append them to the first.
- *
- * Arguments:
- * dst - the stack to receive the certs from 'src'
- * src - the stack whose certs are to be moved.
- *
- * Returns:
- * -1 - An error occurred. The error status is set.
- * >= 0 - The number of certs that were copied.
- */
-static int
-move_certs(STACK_OF(X509) *dst, STACK_OF(X509) *src)
-{
- X509 *tmpc;
- int count = 0;
-
- while (sk_X509_num(src) > 0) {
- tmpc = sk_X509_delete(src, 0);
- if (sk_X509_push(dst, tmpc) == 0) {
- X509_free(tmpc);
- SUNWerr(SUNW_F_MOVE_CERTS, SUNW_R_MEMORY_FAILURE);
- return (-1);
- }
- count++;
- }
-
- return (count);
-}
-
-/*
- * get_key_cert - Get a cert and its matching key from the stacks of certs
- * and keys. They are removed from the stacks.
- *
- * Arguments:
- * n - Offset of the entries to return.
- * kl - Points to a stack of private keys that matches the list of
- * certs below.
- * pkey - Points at location where the address of the matching private
- * key will be stored.
- * cl - Points to a stack of client certs with matching private keys.
- * cert - Points to locaiton where the address of the matching client cert
- * will be returned
- *
- * The assumption is that the stacks of keys and certs contain key/cert pairs,
- * with entries in the same order and hence at the same offset. Provided
- * the key and cert selected match, each will be removed from its stack and
- * returned.
- *
- * A stack of certs can be passed in without a stack of private keys, and vise
- * versa. In that case, the indicated key/cert will be returned.
- *
- * Returns:
- * 0 - No matches were found.
- * > 0 - Bits set based on FOUND_* definitions, indicating what is returned.
- * This can be FOUND_PKEY, FOUND_CERT or (FOUND_PKEY | FOUND_CERT).
- */
-static int
-get_key_cert(int n, STACK_OF(EVP_PKEY) *kl, EVP_PKEY **pkey, STACK_OF(X509) *cl,
- X509 **cert)
-{
- int retval = 0;
- int nk;
- int nc;
-
- nk = (kl != NULL) ? sk_EVP_PKEY_num(kl) : 0;
- nc = (cl != NULL) ? sk_X509_num(cl) : 0;
-
- if (pkey != NULL && *pkey == NULL) {
- if (nk > 0 && n >= 0 || n < nk) {
- *pkey = sk_EVP_PKEY_delete(kl, n);
- if (*pkey != NULL)
- retval |= FOUND_PKEY;
- }
- }
-
- if (cert != NULL && *cert == NULL) {
- if (nc > 0 && n >= 0 && n < nc) {
- *cert = sk_X509_delete(cl, n);
- if (*cert != NULL)
- retval |= FOUND_CERT;
- }
- }
-
- return (retval);
-}
-
-
-/*
- * asc2bmpstring - Convert a regular C ASCII string to an ASn1_STRING in
- * ASN1_BMPSTRING format.
- *
- * Arguments:
- * str - String to be convered.
- * len - Length of the string.
- *
- * Returns:
- * == NULL - An error occurred. Error information (accessible by
- * ERR_get_error()) is set.
- * != NULL - Points to an ASN1_BMPSTRING structure with the converted
- * string as a value.
- */
-static ASN1_BMPSTRING *
-asc2bmpstring(const char *str, int len)
-{
- ASN1_BMPSTRING *bmp = NULL;
- uchar_t *uni = NULL;
- int unilen;
-
- /* Convert the character to the bmp format. */
-#if OPENSSL_VERSION_NUMBER < 0x10000000L
- if (asc2uni(str, len, &uni, &unilen) == 0) {
-#else
- if (OPENSSL_asc2uni(str, len, &uni, &unilen) == 0) {
-#endif
- SUNWerr(SUNW_F_ASC2BMPSTRING, SUNW_R_MEMORY_FAILURE);
- return (NULL);
- }
-
- /*
- * Adjust for possible pair of NULL bytes at the end because
- * asc2uni() returns a doubly null terminated string.
- */
- if (uni[unilen - 1] == '\0' && uni[unilen - 2] == '\0')
- unilen -= 2;
-
- /* Construct comparison string with correct format */
- bmp = M_ASN1_BMPSTRING_new();
- if (bmp == NULL) {
- SUNWerr(SUNW_F_ASC2BMPSTRING, SUNW_R_MEMORY_FAILURE);
- OPENSSL_free(uni);
- return (NULL);
- }
-
- bmp->data = uni;
- bmp->length = unilen;
-
- return (bmp);
-}
-
-/*
- * utf82ascstr - Convert a UTF8STRING string to a regular C ASCII string.
- * This goes through an intermediate step with a ASN1_STRING type of
- * IA5STRING (International Alphabet 5, which is the same as ASCII).
- *
- * Arguments:
- * str - UTF8STRING to be converted.
- *
- * Returns:
- * == NULL - An error occurred. Error information (accessible by
- * ERR_get_error()) is set.
- * != NULL - Points to a NULL-termianted ASCII string. The caller must
- * free it.
- */
-static uchar_t *
-utf82ascstr(ASN1_UTF8STRING *ustr)
-{
- ASN1_STRING tmpstr;
- ASN1_STRING *astr = &tmpstr;
- uchar_t *retstr = NULL;
- int mbflag;
- int ret;
-
- if (ustr == NULL || ustr->type != V_ASN1_UTF8STRING) {
- SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_INVALID_ARG);
- return (NULL);
- }
-
- mbflag = MBSTRING_ASC;
- tmpstr.data = NULL;
- tmpstr.length = 0;
-
- ret = ASN1_mbstring_copy(&astr, ustr->data, ustr->length, mbflag,
- B_ASN1_IA5STRING);
- if (ret < 0) {
- SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_STR_CONVERT_ERR);
- return (NULL);
- }
-
- retstr = OPENSSL_malloc(astr->length + 1);
- if (retstr == NULL) {
- SUNWerr(SUNW_F_UTF82ASCSTR, SUNW_R_MEMORY_FAILURE);
- return (NULL);
- }
-
- (void) memcpy(retstr, astr->data, astr->length);
- retstr[astr->length] = '\0';
- OPENSSL_free(astr->data);
-
- return (retstr);
-}
-
-
-/*
- * type2attrib - Given a ASN1_TYPE, return a X509_ATTRIBUTE of the type
- * specified by the given NID.
- *
- * Arguments:
- * ty - Type structure to be made into an attribute
- * nid - NID of the attribute
- *
- * Returns:
- * NULL An error occurred.
- * != NULL An X509_ATTRIBUTE structure.
- */
-X509_ATTRIBUTE *
-type2attrib(ASN1_TYPE *ty, int nid)
-{
- X509_ATTRIBUTE *a;
-
- if ((a = X509_ATTRIBUTE_new()) == NULL ||
- (a->value.set = sk_ASN1_TYPE_new_null()) == NULL ||
- sk_ASN1_TYPE_push(a->value.set, ty) == 0) {
- if (a != NULL)
- X509_ATTRIBUTE_free(a);
- SUNWerr(SUNW_F_TYPE2ATTRIB, SUNW_R_MEMORY_FAILURE);
- return (NULL);
- }
- a->single = 0;
- a->object = OBJ_nid2obj(nid);
-
- return (a);
-}
-
-/*
- * attrib2type - Given a X509_ATTRIBUTE, return pointer to the ASN1_TYPE
- * component
- *
- * Arguments:
- * attr - Attribute structure containing a type.
- *
- * Returns:
- * NULL An error occurred.
- * != NULL An ASN1_TYPE structure.
- */
-static ASN1_TYPE *
-attrib2type(X509_ATTRIBUTE *attr)
-{
- ASN1_TYPE *ty = NULL;
-
- if (attr == NULL || attr->single == 1)
- return (NULL);
-
- if (sk_ASN1_TYPE_num(attr->value.set) > 0)
- ty = sk_ASN1_TYPE_value(attr->value.set, 0);
-
- return (ty);
-}
-
-/*
- * find_attr_by_nid - Given a ASN1_TYPE, return the offset of a X509_ATTRIBUTE
- * of the type specified by the given NID.
- *
- * Arguments:
- * attrs - Stack of attributes to search
- * nid - NID of the attribute being searched for
- *
- * Returns:
- * -1 None found
- * != -1 Offset of the matching attribute.
- */
-static int
-find_attr_by_nid(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
-{
- X509_ATTRIBUTE *a;
- int i;
-
- if (attrs == NULL)
- return (-1);
-
- for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
- a = sk_X509_ATTRIBUTE_value(attrs, i);
- if (OBJ_obj2nid(a->object) == nid)
- return (i);
- }
- return (-1);
-}
-
-/*
- * Called by our PKCS12 code to read our function and error codes
- * into memory so that the OpenSSL framework can retrieve them.
- */
-void
-ERR_load_SUNW_strings(void)
-{
- assert(SUNW_lib_error_code == 0);
-#ifndef OPENSSL_NO_ERR
- /*
- * Have OpenSSL provide us with a unique ID.
- */
- SUNW_lib_error_code = ERR_get_next_error_library();
-
- ERR_load_strings(SUNW_lib_error_code, SUNW_str_functs);
- ERR_load_strings(SUNW_lib_error_code, SUNW_str_reasons);
-
- SUNW_lib_name->error = ERR_PACK(SUNW_lib_error_code, 0, 0);
- ERR_load_strings(0, SUNW_lib_name);
-#endif
-}
-
-/*
- * The SUNWerr macro resolves to this routine. So when we need
- * to push an error, this routine does it for us. Notice that
- * the SUNWerr macro provides a filename and line #.
- */
-void
-ERR_SUNW_error(int function, int reason, char *file, int line)
-{
- assert(SUNW_lib_error_code != 0);
-#ifndef OPENSSL_NO_ERR
- ERR_PUT_error(SUNW_lib_error_code, function, reason, file, line);
-#endif
-}
-
-/*
- * check_time - Given an indication of the which time(s) to check, check
- * that time or those times against the current time and return the
- * relationship.
- *
- * Arguments:
- * chkwhat - What kind of check to do.
- * cert - The cert to check.
- *
- * Returns:
- * CHKERR_* values.
- */
-static chk_errs_t
-check_time(chk_actions_t chkwhat, X509 *cert)
-{
- int i;
-
- if (chkwhat == CHK_NOT_BEFORE || chkwhat == CHK_BOTH) {
- i = X509_cmp_time(X509_get_notBefore(cert), NULL);
- if (i == 0)
- return (CHKERR_TIME_BEFORE_BAD);
- if (i > 0)
- return (CHKERR_TIME_IS_BEFORE);
-
- /* The current time is after the 'not before' time */
- }
-
- if (chkwhat == CHK_NOT_AFTER || chkwhat == CHK_BOTH) {
- i = X509_cmp_time(X509_get_notAfter(cert), NULL);
- if (i == 0)
- return (CHKERR_TIME_AFTER_BAD);
- if (i < 0)
- return (CHKERR_TIME_HAS_EXPIRED);
- }
-
- return (CHKERR_TIME_OK);
-}
-
-/*
- * find_attr - Look for a given attribute of the type associated with the NID.
- *
- * Arguments:
- * nid - NID for the attribute to be found (either NID_friendlyName or
- * NID_locakKeyId)
- * str - ASN1_STRING-type structure containing the value to be found,
- * FriendlyName expects a ASN1_BMPSTRING and localKeyID uses a
- * ASN1_STRING.
- * kl - Points to a stack of private keys.
- * pkey - Points at a location where the address of the matching private
- * key will be stored.
- * cl - Points to a stack of client certs with matching private keys.
- * cert - Points to locaiton where the address of the matching client cert
- * will be returned
- *
- * This function is designed to process lists of certs and private keys.
- * This is made complex because these the attributes are stored differently
- * for certs and for keys. For certs, only a few attributes are retained.
- * FriendlyName is stored in the aux structure, under the name 'alias'.
- * LocalKeyId is also stored in the aux structure, under the name 'keyid'.
- * A pkey structure has a stack of attributes.
- *
- * The basic approach is:
- * - If there there is no stack of certs but a stack of private keys exists,
- * search the stack of keys for a match. Alternately, if there is a stack
- * of certs and no private keys, search the certs.
- *
- * - If there are both certs and keys, assume that the matching certs and
- * keys are in their respective stacks, with matching entries in the same
- * order. Search for the name or keyid in the stack of certs. If it is
- * not found, then this function returns 0 (nothing found).
- *
- * - Once a cert is found, verify that the key actually matches by
- * comparing the private key with the public key (in the cert).
- * If they don't match, return an error.
- *
- * A pointer to cert and/or pkey which matches the name or keyid is stored
- * in the return arguments.
- *
- * Returns:
- * 0 - No matches were found.
- * > 0 - Bits set based on FOUND_* definitions, indicating what was found.
- * This can be FOUND_PKEY, FOUND_CERT or (FOUND_PKEY | FOUND_CERT).
- */
-static int
-find_attr(int nid, ASN1_STRING *str, STACK_OF(EVP_PKEY) *kl, EVP_PKEY **pkey,
- STACK_OF(X509) *cl, X509 **cert)
-{
- ASN1_UTF8STRING *ustr = NULL;
- ASN1_STRING *s;
- ASN1_TYPE *t;
- EVP_PKEY *p;
- uchar_t *fname = NULL;
- X509 *x;
- int found = 0;
- int chkcerts;
- int len;
- int res;
- int c = -1;
- int k = -1;
-
- chkcerts = (cert != NULL || pkey != NULL) && cl != NULL;
- if (chkcerts && nid == NID_friendlyName &&
- str->type == V_ASN1_BMPSTRING) {
- ustr = ASN1_UTF8STRING_new();
- if (ustr == NULL) {
- SUNWerr(SUNW_F_FINDATTR, SUNW_R_MEMORY_FAILURE);
- return (0);
- }
- len = ASN1_STRING_to_UTF8(&fname, str);
- if (fname == NULL) {
- ASN1_UTF8STRING_free(ustr);
- SUNWerr(SUNW_F_FINDATTR, SUNW_R_STR_CONVERT_ERR);
- return (0);
- }
-
- if (ASN1_STRING_set(ustr, fname, len) == 0) {
- ASN1_UTF8STRING_free(ustr);
- OPENSSL_free(fname);
- SUNWerr(SUNW_F_FINDATTR, SUNW_R_MEMORY_FAILURE);
- return (0);
- }
- }
-
- if (chkcerts) {
- for (c = 0; c < sk_X509_num(cl); c++) {
- res = -1;
- x = sk_X509_value(cl, c);
- if (nid == NID_friendlyName && ustr != NULL) {
- if (x->aux == NULL || x->aux->alias == NULL)
- continue;
- s = x->aux->alias;
- if (s != NULL && s->type == ustr->type &&
- s->data != NULL) {
- res = ASN1_STRING_cmp(s, ustr);
- }
- } else {
- if (x->aux == NULL || x->aux->keyid == NULL)
- continue;
- s = x->aux->keyid;
- if (s != NULL && s->type == str->type &&
- s->data != NULL) {
- res = ASN1_STRING_cmp(s, str);
- }
- }
- if (res == 0) {
- if (cert != NULL)
- *cert = sk_X509_delete(cl, c);
- found = FOUND_CERT;
- break;
- }
- }
- if (ustr != NULL) {
- ASN1_UTF8STRING_free(ustr);
- OPENSSL_free(fname);
- }
- }
-
- if (pkey != NULL && kl != NULL) {
- /*
- * Looking for pkey to match a cert? If so, assume that
- * lists of certs and their matching pkeys are in the same
- * order. Call X509_check_private_key() to verify this
- * assumption.
- */
- if (found != 0 && cert != NULL) {
- k = c;
- p = sk_EVP_PKEY_value(kl, k);
- if (X509_check_private_key(x, p) != 0) {
- if (pkey != NULL)
- *pkey = sk_EVP_PKEY_delete(kl, k);
- found |= FOUND_PKEY;
- }
- } else if (cert == NULL) {
- for (k = 0; k < sk_EVP_PKEY_num(kl); k++) {
- p = sk_EVP_PKEY_value(kl, k);
- if (p == NULL || p->attributes == NULL)
- continue;
-
- t = PKCS12_get_attr_gen(p->attributes, nid);
- if (t != NULL || ASN1_STRING_cmp(str,
- t->value.asn1_string) == 0)
- continue;
-
- found |= FOUND_PKEY;
- if (pkey != NULL)
- *pkey = sk_EVP_PKEY_delete(kl, k);
- break;
- }
- }
- }
-
- return (found);
-}
-
-/*
- * set_results - Given two pointers to stacks of private keys, certs or CA
- * CA certs, either copy the second stack to the first, or append the
- * contents of the second to the first.
- *
- * Arguments:
- * pkeys - Points to stack of pkeys
- * work_kl - Points to working stack of pkeys
- * certs - Points to stack of certs
- * work_cl - Points to working stack of certs
- * cacerts - Points to stack of CA certs
- * work_ca - Points to working stack of CA certs
- * xtrakeys - Points to stack of unmatcned pkeys
- * work_xl - Points to working stack of unmatcned pkeys
- *
- * The arguments are in pairs. The first of each pair points to a stack
- * of keys or certs. The second of the pair points at a 'working stack'
- * of the same type of entities. Actions taken are as follows:
- *
- * - If either the first or second argument is NULL, or if there are no
- * members in the second stack, there is nothing to do.
- * - If the first argument points to a pointer which is NULL, then there
- * is no existing stack for the first argument. Copy the stack pointer
- * from the second argument to the first argument and NULL out the stack
- * pointer for the second.
- * - Otherwise, go through the elements of the second stack, removing each
- * and adding it to the first stack.
- *
- * Returns:
- * == -1 - An error occurred. Call ERR_get_error() to get error information.
- * == 0 - No matching returns were found.
- * > 0 - This is the arithmetic 'or' of the FOUND_* bits that indicate which
- * of the requested entries were manipulated.
- */
-static int
-set_results(STACK_OF(EVP_PKEY) **pkeys, STACK_OF(EVP_PKEY) **work_kl,
- STACK_OF(X509) **certs, STACK_OF(X509) **work_cl,
- STACK_OF(X509) **cacerts, STACK_OF(X509) **work_ca,
- STACK_OF(EVP_PKEY) **xtrakeys, STACK_OF(EVP_PKEY) **work_xl)
-{
- int retval = 0;
-
- if (pkeys != NULL && work_kl != NULL && *work_kl != NULL &&
- sk_EVP_PKEY_num(*work_kl) > 0) {
- if (*pkeys == NULL) {
- *pkeys = *work_kl;
- *work_kl = NULL;
- } else {
- if (sunw_append_keys(*pkeys, *work_kl) < 0) {
- return (-1);
- }
- }
- retval |= FOUND_PKEY;
- }
- if (certs != NULL && work_cl != NULL && *work_cl != NULL &&
- sk_X509_num(*work_cl) > 0) {
- if (*certs == NULL) {
- *certs = *work_cl;
- *work_cl = NULL;
- } else {
- if (move_certs(*certs, *work_cl) < 0) {
- return (-1);
- }
- }
- retval |= FOUND_CERT;
- }
-
- if (cacerts != NULL && work_ca != NULL && *work_ca != NULL &&
- sk_X509_num(*work_ca) > 0) {
- if (*cacerts == NULL) {
- *cacerts = *work_ca;
- *work_ca = NULL;
- } else {
- if (move_certs(*cacerts, *work_ca) < 0) {
- return (-1);
- }
- }
- retval |= FOUND_CA_CERTS;
- }
-
- if (xtrakeys != NULL && work_xl != NULL && *work_xl != NULL &&
- sk_EVP_PKEY_num(*work_xl) > 0) {
- if (*xtrakeys == NULL) {
- *xtrakeys = *work_xl;
- *work_xl = NULL;
- } else {
- if (sunw_append_keys(*xtrakeys, *work_xl) < 0) {
- return (-1);
- }
- }
- retval |= FOUND_XPKEY;
- }
-
- return (retval);
-}
diff --git a/usr/src/lib/libpkg/common/p12lib.h b/usr/src/lib/libpkg/common/p12lib.h
deleted file mode 100644
index 3d80ddaa35..0000000000
--- a/usr/src/lib/libpkg/common/p12lib.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _P12LIB_H
-#define _P12LIB_H
-
-
-#include <openssl/pkcs12.h>
-#include <openssl/pem.h>
-
-/*
- * PKCS12 file routines borrowed from SNT's libwanboot.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* These declarations allow us to make stacks of EVP_PKEY objects */
-DECLARE_STACK_OF(EVP_PKEY)
-#define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
-#define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
-#define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
-#define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
-#define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
-#define sk_EVP_PKEY_find(st, val) SKM_sk_find(EVP_PKEY, (st), (val))
-#define sk_EVP_PKEY_delete(st, i) SKM_sk_delete(EVP_PKEY, (st), (i))
-#define sk_EVP_PKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY, (st), (ptr))
-#define sk_EVP_PKEY_insert(st, val, i) SKM_sk_insert(EVP_PKEY, (st), (val), (i))
-#define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
- (free_func))
-#define sk_EVP_PKEY_pop(st) SKM_sk_pop(EVP_PKEY, (st))
-
-/* Error reporting routines required by OpenSSL */
-#define SUNW_LIB_NAME "SUNW_PKCS12"
-#define SUNWerr(f, r) ERR_SUNW_error((f), (r), __FILE__, __LINE__)
-
-/* Error codes for the SUNW functions. */
-/* OpenSSL prefers codes to start at 100 */
-
-/* Function codes. */
-typedef enum {
- SUNW_F_USE_X509CERT = 100,
- SUNW_F_USE_PKEY,
- SUNW_F_USE_TASTORE,
- SUNW_F_USE_CERTFILE,
- SUNW_F_USE_KEYFILE,
- SUNW_F_USE_TRUSTFILE,
- SUNW_F_READ_FILE,
- SUNW_F_DOPARSE,
- SUNW_F_PKCS12_PARSE,
- SUNW_F_PKCS12_CONTENTS,
- SUNW_F_PARSE_ONE_BAG,
- SUNW_F_PKCS12_CREATE,
- SUNW_F_SPLIT_CERTS,
- SUNW_F_FIND_LOCALKEYID,
- SUNW_F_SET_LOCALKEYID,
- SUNW_F_SET_FNAME,
- SUNW_F_GET_LOCALKEYID,
- SUNW_F_GET_PKEY_FNAME,
- SUNW_F_APPEND_KEYS,
- SUNW_F_PEM_CONTENTS,
- SUNW_F_PEM_INFO,
- SUNW_F_ASC2BMPSTRING,
- SUNW_F_UTF82ASCSTR,
- SUNW_F_FINDATTR,
- SUNW_F_TYPE2ATTRIB,
- SUNW_F_MOVE_CERTS,
- SUNW_F_FIND_FNAME,
- SUNW_F_PARSE_OUTER,
- SUNW_F_CHECKFILE
-} sunw_err_func_t;
-
-/* Reason codes. */
-typedef enum {
- SUNW_R_INVALID_ARG = 100,
- SUNW_R_MEMORY_FAILURE,
- SUNW_R_MAC_VERIFY_FAILURE,
- SUNW_R_MAC_CREATE_FAILURE,
- SUNW_R_BAD_FILETYPE,
- SUNW_R_BAD_PKEY,
- SUNW_R_BAD_PKEYTYPE,
- SUNW_R_PKEY_READ_ERR,
- SUNW_R_NO_TRUST_ANCHOR,
- SUNW_R_READ_TRUST_ERR,
- SUNW_R_ADD_TRUST_ERR,
- SUNW_R_PKCS12_PARSE_ERR,
- SUNW_R_PKCS12_CREATE_ERR,
- SUNW_R_PARSE_BAG_ERR,
- SUNW_R_MAKE_BAG_ERR,
- SUNW_R_BAD_CERTTYPE,
- SUNW_R_PARSE_CERT_ERR,
- SUNW_R_BAD_LKID,
- SUNW_R_SET_LKID_ERR,
- SUNW_R_BAD_FNAME,
- SUNW_R_SET_FNAME_ERR,
- SUNW_R_BAD_TRUST,
- SUNW_R_BAD_BAGTYPE,
- SUNW_R_CERT_ERR,
- SUNW_R_PKEY_ERR,
- SUNW_R_READ_ERR,
- SUNW_R_ADD_ATTR_ERR,
- SUNW_R_STR_CONVERT_ERR,
- SUNW_R_PKCS12_EMPTY_ERR,
- SUNW_R_PASSWORD_ERR
-} sunw_err_reason_t;
-
-/*
- * Type of checking to perform when calling sunw_check_cert_times
- */
-typedef enum {
- CHK_NOT_BEFORE = 1, /* Check 'not before' date */
- CHK_NOT_AFTER, /* Check 'not after' date */
- CHK_BOTH /* Check both dates */
-} chk_actions_t;
-
-/*
- * Return type for sunw_check_cert_times
- */
-typedef enum {
- CHKERR_TIME_OK = 0, /* Current time meets requested checks */
- CHKERR_TIME_BEFORE_BAD, /* 'not before' field is invalid */
- CHKERR_TIME_AFTER_BAD, /* 'not after' field is invalid */
- CHKERR_TIME_IS_BEFORE, /* Current time is before 'not before' */
- CHKERR_TIME_HAS_EXPIRED /* Current time is after 'not after' */
-} chk_errs_t;
-
-/*
- * This type indicates what to do with an attribute being returned.
- */
-typedef enum {
- GETDO_COPY = 1, /* Simply return the value of the attribute */
- GETDO_DEL /* Delete the attribute at the same time. */
-} getdo_actions_t;
-
-/*
- * For sunw_pkcs12_parse, the following are values for bits that indicate
- * various types of searches/matching to do. Any of these values can be
- * OR'd together. However, the order in which an attempt will be made
- * to satisfy them is the order in which they are listed below. The
- * exception is DO_NONE. It should not be OR'd with any other value.
- */
-#define DO_NONE 0x00 /* Don't even try to match */
-#define DO_FIND_KEYID 0x01 /* 1st cert, key with matching localkeyid */
-#define DO_FIND_FN 0x02 /* 1st cert, key with matching friendlyname */
-#define DO_FIRST_PAIR 0x04 /* Return first matching cert/key pair found */
-#define DO_LAST_PAIR 0x08 /* Return last matching cert/key pair found */
-#define DO_UNMATCHING 0x10 /* Return first cert and/or key */
-
-/* Bits returned, which indicate what values were found. */
-#define FOUND_PKEY 0x01 /* Found one or more private key */
-#define FOUND_CERT 0x02 /* Found one or more client certificate */
-#define FOUND_CA_CERTS 0x04 /* Added at least one cert to the CA list */
-#define FOUND_XPKEY 0x08 /* Found at least one private key which does */
- /* not match a certificate in the certs list */
-
-/* p12lib.c */
-PKCS12 *sunw_PKCS12_create(const char *, STACK_OF(EVP_PKEY) *,
- STACK_OF(X509) *, STACK_OF(X509) *);
-
-int sunw_split_certs(STACK_OF(EVP_PKEY) *, STACK_OF(X509) *,
- STACK_OF(X509) **, STACK_OF(EVP_PKEY) **);
-
-void sunw_evp_pkey_free(EVP_PKEY *);
-int sunw_set_localkeyid(const char *, int, EVP_PKEY *, X509 *);
-int sunw_get_pkey_localkeyid(getdo_actions_t, EVP_PKEY *, char **, int *);
-int sunw_get_pkey_fname(getdo_actions_t, EVP_PKEY *, char **);
-int sunw_find_localkeyid(char *, int, STACK_OF(EVP_PKEY) *,
- STACK_OF(X509) *, EVP_PKEY **, X509 **);
-int sunw_find_fname(char *, STACK_OF(EVP_PKEY) *, STACK_OF(X509) *,
- EVP_PKEY **, X509 **);
-int sunw_set_fname(const char *, EVP_PKEY *, X509 *);
-int sunw_check_keys(X509 *, EVP_PKEY *);
-
-chk_errs_t sunw_check_cert_times(chk_actions_t, X509 *);
-extern void ERR_SUNW_error(int function, int reason, char *file, int line);
-extern void ERR_load_SUNW_strings(void);
-int sunw_PKCS12_contents(PKCS12 *, const char *,
- STACK_OF(EVP_PKEY) **, STACK_OF(X509) **);
-int sunw_get_cert_fname(getdo_actions_t, X509 *, char **);
-int sunw_PEM_contents(FILE *, pem_password_cb, void *,
- STACK_OF(EVP_PKEY) **, STACK_OF(X509) **);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _P12LIB_H */
diff --git a/usr/src/lib/libpkg/common/path_valid.c b/usr/src/lib/libpkg/common/path_valid.c
new file mode 100644
index 0000000000..c320685cdb
--- /dev/null
+++ b/usr/src/lib/libpkg/common/path_valid.c
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+
+/*
+ * Name: path_valid
+ * Description: Checks a string for being a valid path
+ *
+ * Arguments: path - path to validate
+ *
+ * Returns : B_TRUE - success, B_FALSE otherwise.
+ * B_FALSE means path was null, too long (>PATH_MAX),
+ * or too short (<1)
+ */
+boolean_t
+path_valid(char *path)
+{
+ if (path == NULL) {
+ return (B_FALSE);
+ } else if (strlen(path) > PATH_MAX) {
+ return (B_FALSE);
+ } else if (strlen(path) >= 1) {
+ return (B_TRUE);
+ } else {
+ /* path < 1 */
+ return (B_FALSE);
+ }
+}
diff --git a/usr/src/lib/libpkg/common/pkgerr.c b/usr/src/lib/libpkg/common/pkgerr.c
deleted file mode 100644
index 6828d88968..0000000000
--- a/usr/src/lib/libpkg/common/pkgerr.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * Module: pkgerr.c
- * Description:
- * Module for handling error messages that come from libpkg libraries.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <locale.h>
-#include <libintl.h>
-#include <stdlib.h>
-#include <sys/varargs.h>
-#include "pkgerr.h"
-
-/* max length of any formatted error message */
-#define MAX_ERRMSGLEN 1024
-
-/* private structures (not visible outside this file) */
-struct _pkg_err_struct {
- int nerrs;
- char **msgs;
- PKG_ERR_CODE *errs;
-};
-
-/* ---------------------- public functions ----------------------- */
-
-PKG_ERR
-*pkgerr_new()
-{
- PKG_ERR *newerr;
-
- newerr = (PKG_ERR *)malloc(sizeof (PKG_ERR));
- newerr->nerrs = 0;
- newerr->msgs = NULL;
- newerr->errs = NULL;
- return (newerr);
-}
-
-/*PRINTFLIKE3*/
-void
-pkgerr_add(PKG_ERR *err, PKG_ERR_CODE code, char *fmt, ...)
-{
- char errmsgbuf[1024];
- va_list ap;
-
- va_start(ap, fmt);
- (void) vsnprintf(errmsgbuf, MAX_ERRMSGLEN, fmt, ap);
- va_end(ap);
-
- err->nerrs++;
-
- err->msgs = (char **)realloc(err->msgs,
- err->nerrs * sizeof (char *));
- err->errs = (PKG_ERR_CODE *)realloc(err->errs,
- err->nerrs * sizeof (PKG_ERR_CODE));
- err->msgs[err->nerrs - 1] = strdup(errmsgbuf);
- err->errs[err->nerrs - 1] = code;
-}
-
-void
-pkgerr_clear(PKG_ERR *err)
-{
- int i;
-
- for (i = 0; i < err->nerrs; i++) {
- free(err->msgs[i]);
- }
-
- free(err->msgs);
- free(err->errs);
- err->msgs = NULL;
- err->errs = NULL;
- err->nerrs = 0;
-}
-
-int
-pkgerr_num(PKG_ERR *err)
-{
- return (err->nerrs);
-}
-
-char
-*pkgerr_get(PKG_ERR *err, int pos)
-{
- if (pos < 0 || pos > (err->nerrs - 1)) {
- return (NULL);
- }
-
- return (err->msgs[pos]);
-}
-
-void
-pkgerr_free(PKG_ERR *err)
-{
- pkgerr_clear(err);
- free(err);
-}
diff --git a/usr/src/lib/libpkg/common/pkgerr.h b/usr/src/lib/libpkg/common/pkgerr.h
deleted file mode 100644
index 10e0e219d9..0000000000
--- a/usr/src/lib/libpkg/common/pkgerr.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _PKGERR_H
-#define _PKGERR_H
-
-
-/*
- * Module: pkgerr.h
- * Description:
- *
- * Implements error routines to handle the creation,
- * management, and destruction of error objects, which
- * hold error messages and codes returned from libpkg
- * routines that support the objects defined herein.
- */
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Public Definitions
- */
-
-typedef enum {
- PKGERR_OK = 0,
- PKGERR_EXIST,
- PKGERR_READ,
- PKGERR_CORRUPT,
- PKGERR_PARSE,
- PKGERR_BADPASS,
- PKGERR_BADALIAS,
- PKGERR_INTERNAL,
- PKGERR_UNSUP,
- PKGERR_NOALIAS,
- PKGERR_NOALIASMATCH,
- PKGERR_MULTIPLE,
- PKGERR_INCOMPLETE,
- PKGERR_NOPRIVKEY,
- PKGERR_NOPUBKEY,
- PKGERR_NOCACERT,
- PKGERR_NOMEM,
- PKGERR_CHAIN,
- PKGERR_LOCKED,
- PKGERR_WRITE,
- PKGERR_UNLOCK,
- PKGERR_TIME,
- PKGERR_DUPLICATE,
- PKGERR_WEB,
- PKGERR_VERIFY
-} PKG_ERR_CODE;
-
-/*
- * Public Structures
- */
-
-/* external reference to PKG_ERR object (contents private) */
-typedef PKG_ERR_CODE pkg_err_t;
-
-typedef struct _pkg_err_struct PKG_ERR;
-
-/*
- * Public Methods
- */
-
-PKG_ERR *pkgerr_new();
-void pkgerr_add(PKG_ERR *, PKG_ERR_CODE, char *, ...);
-void pkgerr_clear(PKG_ERR *);
-int pkgerr_dump(PKG_ERR *, FILE *);
-int pkgerr_num(PKG_ERR *);
-char *pkgerr_get(PKG_ERR *, int);
-void pkgerr_free(PKG_ERR *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKGERR_H */
diff --git a/usr/src/lib/libpkg/common/pkglib.h b/usr/src/lib/libpkg/common/pkglib.h
index 4e4bdabf91..31f392fe95 100644
--- a/usr/src/lib/libpkg/common/pkglib.h
+++ b/usr/src/lib/libpkg/common/pkglib.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,12 +44,6 @@ extern "C" {
#include <stdio.h>
#include <pkgdev.h>
#include <pkgstrct.h>
-#include <openssl/bio.h>
-#include <openssl/x509.h>
-#include <netdb.h>
-#include <boot_http.h>
-#include "pkgerr.h"
-#include "keystore.h"
#include "cfext.h"
/*
@@ -355,33 +353,13 @@ struct dstr {
#define SMALL_DIVISOR 4
#define MED_DIVISOR 5
#define LARGE_DIVISOR 10
-#define MED_DWNLD (10 * 1024 * 1024) /* 10 MB */
-#define LARGE_DWNLD (5 * MED_DWNLD) /* 50 MB */
-
-#define HTTP "http://"
-#define HTTPS "https://"
#define PKGADD "pkgadd"
-/* Settings for network admin defaults */
-
-#define NET_TIMEOUT_DEFAULT 60
-#define NET_RETRIES_DEFAULT 3
-#define NET_TIMEOUT_MIN 1 /* 1 second */
-#define NET_TIMEOUT_MAX (5 * 60) /* 5 minutes */
-#define NET_RETRIES_MIN 1
-#define NET_RETRIES_MAX 10
-#define AUTH_NOCHECK 0
-#define AUTH_QUIT 1
-
/* package header magic tokens */
#define HDR_PREFIX "# PaCkAgE DaTaStReAm"
#define HDR_SUFFIX "# end of header"
-/* name of security files */
-#define PKGSEC "/var/sadm/security"
-#define SIGNATURE_FILENAME "signature"
-
#define GROUP "/etc/group"
#define PASSWD "/etc/passwd"
@@ -435,9 +413,6 @@ extern int ds_getpkg(char *device, int n, char *dstdir);
extern int ds_ginit(char *device);
extern boolean_t ds_fd_open(void);
extern int ds_init(char *device, char **pkg, char *norewind);
-extern int BIO_ds_dump_header(PKG_ERR *, BIO *);
-extern int BIO_ds_dump(PKG_ERR *, char *, BIO *);
-extern int BIO_dump_cmd(char *cmd, BIO *bio);
extern int ds_next(char *, char *);
extern int ds_readbuf(char *device);
extern int epclose(FILE *pp);
@@ -464,7 +439,7 @@ extern int pkghead(char *device);
extern int pkgmount(struct pkgdev *devp, char *pkg, int part, int nparts,
int getvolflg);
extern int pkgtrans(char *device1, char *device2, char **pkg,
- int options, keystore_handle_t, char *);
+ int options);
extern int pkgumount(struct pkgdev *devp);
extern int ppkgmap(struct cfent *ept, FILE *fp);
extern int putcfile(struct cfent *ept, FILE *fp);
@@ -474,9 +449,6 @@ extern void set_memalloc_failure_func(void (*)(int));
extern void *xmalloc(size_t size);
extern void *xrealloc(void *ptr, size_t size);
extern char *xstrdup(char *str);
-extern void set_passphrase_prompt(char *);
-extern void set_passphrase_passarg(char *);
-extern int pkg_passphrase_cb(char *, int, int, void *);
extern int srchcfile(struct cfent *ept, char *path, PKGserver server);
extern struct group *cgrgid(gid_t gid);
@@ -503,7 +475,6 @@ extern int mappath(int flag, char *path);
extern int mapvar(int flag, char *varname);
/*PRINTFLIKE1*/
extern void progerr(char *fmt, ...);
-extern void pkgerr(PKG_ERR *);
extern void rpterr(void);
extern void tputcfent(struct cfent *ept, FILE *fp);
extern void set_nonABI_symlinks(void);
@@ -511,15 +482,6 @@ extern int nonABI_symlinks(void);
extern void disable_attribute_check(void);
extern int get_disable_attribute_check(void);
-/* security.c */
-extern void sec_init(void);
-extern char *get_subject_display_name(X509 *);
-extern char *get_issuer_display_name(X509 *);
-extern char *get_serial_num(X509 *);
-extern char *get_fingerprint(X509 *, const EVP_MD *);
-extern int get_cert_chain(PKG_ERR *, X509 *, STACK_OF(X509) *,
- STACK_OF(X509) *, STACK_OF(X509) **);
-
/* pkgstr.c */
void pkgstrConvertUllToTimeString_r(unsigned long long a_time,
char *a_buf, int a_bufLen);
@@ -567,6 +529,9 @@ extern int vfpWriteToFile(VFP_T *a_vfp, char *a_path);
boolean_t enable_local_fs(void);
boolean_t restore_local_fs(void);
+/* path_valid.c */
+extern boolean_t path_valid(char *);
+
/* pkgserv.c */
extern PKGserver pkgopenserver(const char *, const char *, boolean_t);
extern void pkgcloseserver(PKGserver);
diff --git a/usr/src/lib/libpkg/common/pkglibmsgs.h b/usr/src/lib/libpkg/common/pkglibmsgs.h
index 4b811ca6ae..342b836d73 100644
--- a/usr/src/lib/libpkg/common/pkglibmsgs.h
+++ b/usr/src/lib/libpkg/common/pkglibmsgs.h
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -54,8 +58,6 @@ extern "C" {
/* pkgtrans messages */
#define MSG_TRANSFER "Transferring <%s> package instance\n"
-#define MSG_STORE_ACC "Retrieving signature certificates from <%s>\n"
-#define MSG_SIGNING "Generating digital signature for signer <%s>\n"
#define MSG_RENAME "\t... instance renamed <%s> on destination\n"
#define ERR_TRANSFER "unable to complete package transfer"
@@ -90,124 +92,6 @@ extern "C" {
#define MSG_OPEN "- open of <%s> failed, errno=%d"
#define MSG_STATVFS "- statvfs(%s) failed, errno=%d"
-/* security problems */
-#define ERR_PARSE "unable to parse keystore <%s>, invalid " \
- "format or corrupt"
-#define ERR_BADPASS "Invalid password. Password does not " \
- "decrypt keystore"
-
-#define MSG_PASSWD_FILE "Password file <%s> cannot be read"
-#define MSG_PASSWD_AGAIN "For Verification"
-#define MSG_PASSWD_NOMATCH "Passwords do not match"
-#define MSG_BADPASSARG "Password retrieval method <%s> invalid"
-#define MSG_NOPASS "Cannot get passphrase using " \
- "retrieval method <%s>"
-
-#define ERR_MISMATCHPASS "<%s> encrypted with different password " \
- " than <%s>, keystore <%s> corrupt"
-
-#define MSG_CHSIGDIR "- unable to change directory to <%s/%s>"
-#define MSG_MKSIGDIR "- unable to make directory <%s/%s>"
-#define ERR_CANTSIGN "- destination device must be datastream in order to" \
- " sign contents"
-#define ERR_STORE "unable to find or use store <%s> from application " \
- "<%s>:<%s>"
-
-#define ERR_NO_KEYSTORE "unable to open keystore <%s> for reading"
-#define ERR_NOT_REG "<%s> is not a regular file"
-#define ERR_KEYSTORE_CORRUPT "Keystore file <%s> is corrupt or unparseable"
-#define ERR_KEYSTORE_REPAIR "unable to repair keystore <%s>"
-#define ERR_KEYSTORE_LOCKED_READ "unable to lock keystore file <%s> " \
- "for reading, try again later"
-#define ERR_KEYSTORE_LOCKED "unable to lock keystore <%s> for exclusive " \
- "access"
-#define ERR_KEYSTORE_UNLOCK "unable to unlock keystore <%s> for " \
- "application <%s>"
-#define ERR_KEYSTORE_WRITE "unable to open keystore <%s> for writing"
-#define ERR_KEYSTORE_REMOVE "unable to delete keystore file <%s>"
-#define ERR_KEYSTORE_READ "unable to open keystore <%s> for reading"
-#define ERR_KEYSTORE_OPEN "unable to open keystore <%s>:<%s>"
-#define ERR_KEYSTORE_FORM "unable to form PKCS12 keystore file for " \
- "writing to <%s>"
-
-#define ERR_KEYSTORE_NOPUBCERTS "unable to find any public key certificates " \
- "in keystore file <%s>"
-
-#define ERR_KEYSTORE_NOPRIVKEYS "unable to find any private keys in keystore "\
- "file <%s>"
-
-#define ERR_KEYSTORE_NOCACERTS "unable to find any trusted certificates in "\
- "file <%s>"
-
-#define ERR_KEYSTORE_NOTRUST "unable to find any trusted certificates in "\
- "keystore"
-
-#define ERR_KEYSTORE_NOMATCH "unable to find certificate and key pair " \
- "with alias <%s> in keystore"
-
-#define ERR_KEYSTORE_DUPLICATECERT "Certificate with alias <%s> " \
- "already exists in keystore"
-#define ERR_KEYSTORE_DUPLICATEKEY "Private key with alias <%s> already" \
- " exists in keystore"
-#define ERR_KEYSTORE_NO_ALIAS "Keystore certificate <%s> has no recorded " \
- "alias, must be deleted from keystore"
-#define ERR_KEYSTORE_NOCERT "No certificate with alias <%s> found in " \
- "keystore <%s>"
-#define ERR_KEYSTORE_NOCERTKEY "No certificates or private keys with alias " \
- "<%s> found in keystore <%s>"
-
-#define ERR_KEYSTORE_INTERNAL "Internal Error file %s line %d"
-
-#define ERR_CURR_TIME "Cannot determine current time from system"
-#define ERR_CERT_TIME "Certificate <%s> has expired or is not yet valid.\n" \
- "Current time: <%s>\n Certificate valid: <%s> - <%s>"
-#define ERR_MISMATCHED_KEYS "Private key does not match public key in " \
- "certificate <%s>"
-#define ERR_CERT_TIME_BAD "Certificate has corrupt validity dates, " \
- "cannot process"
-#define ERR_TRUSTSTORE "unable to find or use trusted certificate " \
- "store <%s> from application <%s>:<%s>"
-
-#define ERR_STORE_PW "unable to read password from <%s>"
-
-#define ERR_SEC "unable to sign package contents using <%s> " \
- "private key"
-
-#define ERR_NOGEN "unable to generate digital signature"
-
-#define ERR_STORE_PW "unable to read password from <%s>"
-#define ERR_CORRUPTSIG "Invalid or corrupt signature in datastream <%s>"
-#define ERR_CORRUPTSIG_TYPE "Wrong PKCS7 signature type in datastream <%s>"
-#define ERR_CORRUPTSIG_DT "Signature found but not detached in " \
- "datastream <%s>"
-#define ERR_KEYSTORE "invalid or corrupt PKCS12 file <%s>."
-#define ERR_KEYSTORE_NOCERTS "Store <%s> contains no certificates"
-#define ERR_KEYSTORE_NOKEYS "Store <%s> contains no private keys"
-#define ERR_SIG_INT "Internal error during signature verification."
-#define MSG_VERIFY "## Verifying signature for signer <%s>"
-#define MSG_VERIFY_OK "## Signature for signer <%s> verified."
-#define ERR_VERIFY "Signature verification failed."
-#define ERR_VERIFY_SIG "Signature verification failed while verifying " \
- "certificate <subject=%s, issuer=%s>:<%s>."
-#define ERR_VERIFY_ISSUER "Could not find issuer certificate for signer <%s>"
-#define ERR_OPENSIG "Signature found in datastream but cannot be " \
- " opened: <%s>"
-
-#define ERR_SIGFOUND "signature found in datastream <%s>, you must " \
- "specify a keystore with -k"
-#define ERR_DSINIT "could not process datastream from <%s>"
-
-#define MSG_KEYSTORE_AL "Keystore Alias"
-#define MSG_KEYSTORE_SN "Serial Number"
-#define MSG_KEYSTORE_FP "Fingerprint"
-#define MSG_KEYSTORE_CN "Common Name"
-#define MSG_KEYSTORE_IN "Issuer Common Name"
-#define MSG_KEYSTORE_VD "Validity Dates"
-#define MSG_KEYSTORE_TY "Certificate Type"
-#define MSG_KEYSTORE_TRUSTED "Trusted Certificate"
-#define MSG_KEYSTORE_UNTRUSTED "Signing Certificate"
-#define MSG_KEYSTORE_UNKNOWN "Unknown"
-
/* parameter errors */
#define ERR_LEN "length of parameter <%s> value exceeds limit"
#define ERR_ASCII "parameter <%s> must be ascii"
@@ -337,92 +221,7 @@ extern "C" {
#define ERR_SETUID "setuid(%d) failed."
#define ERR_EX_FAIL "exec of %s failed, errno=%d"
-/* pkgweb errors */
-#define MSG_DWNLD "\n## Downloading..."
-#define ERR_DWNLD_FAILED "\n## After %d retries, unable to complete transfer"
-#define MSG_DWNLD_TIMEOUT "\n## Timed out, retrying..."
-#define MSG_DWNLD_CONNREF "\n## Connection to <%s> refused, retrying..."
-#define MSG_DWNLD_HOSTDWN "\n## <%s> not responding, retrying..."
-#define MSG_DWNLD_PART "\n## Found partially downloaded file <%s> of " \
- "size <%ld> bytes. To force a complete " \
- "re-download, delete this file and try again"
-#define MSG_DWNLD_PREV "\n## Using previously spooled package datastream <%s>"
-#define MSG_DWNLD_CONT "\n## Continuing previously attempted download..."
-#define MSG_DWNLD_COMPLETE "## Download Complete\n"
-
-#define ERR_DWNLD_NO_CONT "unable to open partially downloaded file <%s> " \
- "for appending"
-#define ERR_BAD_PATH "unable to locate keystore."
-#define ERR_EMPTYPATH "No valid path exists for the keystore file."
-#define ERR_RETRIES "The number of server retries is not a valid " \
- "value. Please specify a value within the range of %d - %d."
-#define ERR_TIMEOUT "The network timeout value is not a valid " \
- "value. Please specify a value within the range of %d - %d."
-#define ERR_PARSE_URL "unable to parse the url <%s>."
-#define ERR_MEM "unable to allocate memory."
-#define ERR_HTTPS_PASSWD "unable set password for HTTPS connection."
-#define ERR_HTTPS_CA "unable to set CA file for HTTPS connection."
-#define ERR_HTTP "Failure occurred with http(s) negotiation: <%s>"
-#define ERR_WRITE "Cannot write to file <%s> : <%s>"
-#define ERR_READ "Cannot read from file <%s> : <%s>"
-#define ERR_SVR_RESP "unable to establish a connection with the http(s) server."
-#define ERR_INIT_CONN "unable to establish a connection with <%s>."
-#define ERR_INIT_SESS "unable to intialize download session for <%s>."
-#define ERR_INIT_CONN_PROXY "unable to establish a connection with <%s> " \
- "using <%s> as the proxy"
-#define ERR_CLOSE_CONN "unable to close the connection with <%s>."
-#define ERR_NO_HEAD_VAL "HTTP Response did not include header <%s>."
-/* CSTYLED */
-#define ERR_BAD_HEAD_VAL "HTTP Header value \"<%s>: <%s>\" unusable or " \
- "unparseable."
-#define ERR_BAD_CONTENT "The package <%s> attempting to be installed " \
- "is illegal."
-#define ERR_DWNLD "unable to download package datastream from <%s>."
-#define ERR_OPEN_TMP "unable to open temporary file for writing."
-#define ERR_WRITE_TMP "unable to write to temporary file."
-#define ERR_DISK_SPACE "Not enough disk space is available to download " \
- "package to\n%s. %llukb needed, %llukb available."
-#define ERR_CERTS "unable to find a valid certificate in <%s>."
-#define ERR_CERTCHAIN "unable to build certificate chain for subject <%s>:<%s>."
-#define ERR_ILL_ENV "The environment variable <%s=%s> is illegal"
-#define ERR_BAD_PROXY "Invalid proxy specification: <%s>"
-#define ERR_TMPDIR "unable to find temporary directory <%s>"
#define ERR_MEM "unable to allocate memory."
-#define ERR_NO_DWNLD_DIR "No download directory available."
-#define MSG_OCSP_VERIFY "## Contacting OCSP Responder <%s> for " \
- "certificate <%s> status"
-#define MSG_OCSP_VERIFY_PROXY "## Contacting OCSP Responder <%s> through " \
- "proxy <%s:%d> for certificate <%s> status"
-#define ERR_OCSP_PARSE "OCSP Responder URL <%s> invalid or unparseable"
-#define ERR_OCSP_RESP_PARSE "OCSP Response <%s> unparseable or empty"
-#define ERR_OCSP_RESP_NOTOK "OCSP Request failed. Expected status " \
- "<%d>, got <%d>, Reason=<%s>"
-#define WRN_OCSP_RESP_NONCE "WARNING: Invalid or no nonce found in " \
- "OCSP response."
-#define ERR_OCSP_RESP_TYPE "OCSP response message type invalid: <%s>, " \
- "expecting <%s>"
-#define ERR_OCSP_CONNECT "Cannot connect to OCSP Responder <%s> port <%d>"
-#define ERR_OCSP_SEND "Cannot send OCSP request to OCSP Responder <%s>"
-#define ERR_OCSP_READ "Cannot read OCSP response from OCSP Responder <%s>"
-#define ERR_OCSP_RESPONDER "OCSP Responder cannot process OCSP Request"
-#define ERR_OCSP_UNSUP "Unsupported OCSP Option <%s>"
-#define ERR_OCSP_VERIFY_NOTIME "Cannot access system time() to determine " \
- "OCSP Response validity"
-#define ERR_OCSP_VERIFY_SIG "OCSP Response, signed by <%s>, cannot be " \
- "verified: <%s>"
-#define ERR_OCSP_VERIFY_FAIL "unable to validate response from OCSP " \
- "Responder <%s>"
-#define ERR_OCSP_VERIFY_NO_STATUS "OCSP Responder did not supply validity " \
- "of certificate <%s> "
-#define ERR_OCSP_VERIFY_VALIDITY_NOTBEFORE "OCSP Response is only valid " \
- "after <%s>. Current time is <%s>."
-#define ERR_OCSP_VERIFY_VALIDITY "OCSP Response is only valid from <%s> " \
- "to <%s>. Current time is <%s>."
-#define ERR_OCSP_VERIFY_STATUS "OCSP Responder indicates certificate <%s> " \
- "status is <%s>"
-#define ERR_OCSP_VERIFY "OCSP Responder rejected certificate, or did not " \
- "recognize"
-#define ERR_OCSP_NO_URI "No OCSP Responder URL"
#define MSG_BASE_USED "Using <%s> as the package base directory."
diff --git a/usr/src/lib/libpkg/common/pkgserv.c b/usr/src/lib/libpkg/common/pkgserv.c
index 785f275dfc..7d1c3b8ad0 100644
--- a/usr/src/lib/libpkg/common/pkgserv.c
+++ b/usr/src/lib/libpkg/common/pkgserv.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -506,6 +510,7 @@ pkgcmd(PKGserver srv, void *cmd, size_t len, char **result, size_t *rlen,
}
/* Error return */
if (da.data_size == sizeof (int)) {
+ /* LINTED */
int x = *(int *)da.data_ptr;
if (x != 0) {
if (result == NULL || da.rbuf != *result)
diff --git a/usr/src/lib/libpkg/common/pkgtrans.c b/usr/src/lib/libpkg/common/pkgtrans.c
index a717360580..cfc4009b08 100644
--- a/usr/src/lib/libpkg/common/pkgtrans.c
+++ b/usr/src/lib/libpkg/common/pkgtrans.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,11 +50,6 @@
#include <dirent.h>
#include <signal.h>
#include <devmgmt.h>
-#include <openssl/pkcs12.h>
-#include <openssl/x509.h>
-#include <openssl/pkcs7.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
#include <note.h>
#include "pkginfo.h"
#include "pkgstrct.h"
@@ -58,9 +57,7 @@
#include "pkgdev.h"
#include "pkglib.h"
#include "pkglibmsgs.h"
-#include "keystore.h"
#include "pkglocale.h"
-#include "pkgerr.h"
extern char *pkgdir; /* pkgparam.c */
@@ -113,12 +110,9 @@ static int cat_and_count(struct dm_buf *, char *);
static int ckoverwrite(char *dir, char *inst, int options);
static int pkgxfer(char *srcinst, int options);
-static int wdsheader(struct dm_buf *, char *src, char *device,
- char **pkg, PKCS7 *);
+static int wdsheader(struct dm_buf *, char *device, char **pkg);
static struct dm_buf *genheader(char *, char **);
-static int dump_hdr_and_pkgs(BIO *, struct dm_buf *, char **);
-
extern int ds_fd; /* open file descriptor for data stream WHERE? */
static char *root_names[] = {
@@ -170,8 +164,7 @@ pkghead(char *device)
}
/* check for datastream */
- if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY,
- NULL, NULL)) {
+ if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY)) {
cleanup();
return (n);
}
@@ -239,90 +232,12 @@ rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize)
/* will return 0, 1, 3, or 99 */
static int
-_pkgtrans(char *device1, char *device2, char **pkg, int options,
- keystore_handle_t keystore, char *keystore_alias)
+_pkgtrans(char *device1, char *device2, char **pkg, int options)
{
- BIO *p7_bio = NULL;
- EVP_PKEY *privkey = NULL;
- PKCS7 *sec_pkcs7 = NULL;
- PKCS7_SIGNER_INFO *sec_signerinfo = NULL;
- PKG_ERR *err;
- STACK_OF(X509) *cacerts = NULL;
- STACK_OF(X509) *clcerts = NULL;
- STACK_OF(X509) *sec_chain = NULL;
- X509 *pubcert = NULL;
- boolean_t making_sig = B_FALSE;
char *src, *dst;
int errflg, i, n;
struct dm_buf *hdr;
- making_sig = (keystore != NULL) ? B_TRUE : B_FALSE;
-
- if (making_sig) {
-
- /* new error object */
- err = pkgerr_new();
-
- /* find matching cert and key */
- if (find_key_cert_pair(err, keystore,
- keystore_alias, &privkey, &pubcert) != 0) {
- pkgerr(err);
- pkgerr_free(err);
- return (1);
- }
-
- /* get CA certificates */
- if (find_ca_certs(err, keystore, &cacerts) != 0) {
- pkgerr(err);
- pkgerr_free(err);
- return (1);
- }
-
- /* get CL (aka "chain") certificates */
- if (find_cl_certs(err, keystore, &clcerts) != 0) {
- pkgerr(err);
- pkgerr_free(err);
- return (1);
- }
-
- /* initialize PKCS7 object to be filled in later */
- sec_pkcs7 = PKCS7_new();
- (void) PKCS7_set_type(sec_pkcs7, NID_pkcs7_signed);
- sec_signerinfo = PKCS7_add_signature(sec_pkcs7,
- pubcert, privkey, EVP_sha1());
-
- if (sec_signerinfo == NULL) {
- progerr(gettext(ERR_SEC), keystore_alias);
- ERR_print_errors_fp(stderr);
- pkgerr_free(err);
- return (1);
- }
-
- /* add signer cert into signature */
- (void) PKCS7_add_certificate(sec_pkcs7, pubcert);
-
- /* attempt to resolve cert chain starting at the signer cert */
- if (get_cert_chain(err, pubcert, clcerts, cacerts,
- &sec_chain) != 0) {
- pkgerr(err);
- pkgerr_free(err);
- return (1);
- }
-
- /*
- * add the verification chain of certs into the signature.
- * The first cert is the user cert, which we don't need,
- * since it's baked in already, so skip it
- */
- for (i = 1; i < sk_X509_num(sec_chain); i++) {
- (void) PKCS7_add_certificate(sec_pkcs7,
- sk_X509_value(sec_chain, i));
- }
-
- pkgerr_free(err);
- err = NULL;
- }
-
if (signal_received > 0) {
return (1);
}
@@ -417,17 +332,6 @@ _pkgtrans(char *device1, char *device2, char **pkg, int options,
logerr(pkg_gt(MSG_TWODSTREAM));
return (1);
}
- } else {
- /*
- * output device isn't a stream. If we're making a signed
- * package, then fail, since we can't make signed,
- * non-stream pkgs
- */
- if (making_sig) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(ERR_CANTSIGN));
- return (1);
- }
}
if ((srcdev.dirname && dstdev.dirname) &&
@@ -531,59 +435,13 @@ _pkgtrans(char *device1, char *device2, char **pkg, int options,
cleanup();
return (1);
}
- if (making_sig) {
- /* start up signature data stream */
- (void) PKCS7_content_new(sec_pkcs7, NID_pkcs7_data);
- (void) PKCS7_set_detached(sec_pkcs7, 1);
- p7_bio = PKCS7_dataInit(sec_pkcs7, NULL);
-
- /*
- * Here we generate all the data that will go into
- * the package, and send it through the signature
- * generator, essentially calculating the signature
- * of the entire package so we can place it in the
- * header. Otherwise we'd have to place it at the end
- * of the pkg, which would break the ABI
- */
- if (!(options & PT_SILENT)) {
- (void) fprintf(stderr, pkg_gt(MSG_SIGNING),
- get_subject_display_name(pubcert));
- }
- if (dump_hdr_and_pkgs(p7_bio, hdr, pkg) != 0) {
- progerr(gettext(ERR_NOGEN));
- logerr(pkg_gt(MSG_GETVOL));
- cleanup();
- return (1);
-
- }
-
- BIO_flush(p7_bio);
- /*
- * now generate PKCS7 signature
- */
- if (!PKCS7_dataFinal(sec_pkcs7, p7_bio)) {
- progerr(gettext(ERR_NOGEN));
- logerr(pkg_gt(MSG_GETVOL));
- cleanup();
- return (1);
- }
-
- (void) BIO_free(p7_bio);
- }
-
- /* write out header to stream, which includes signature */
- if (wdsheader(hdr, src, ods_name, pkg, sec_pkcs7)) {
+ /* write out header to stream */
+ if (wdsheader(hdr, ods_name, pkg)) {
cleanup();
return (1);
}
- if (sec_pkcs7 != NULL) {
- /* nuke in-memory signature for safety */
- PKCS7_free(sec_pkcs7);
- sec_pkcs7 = NULL;
- }
-
ds_volno = 1; /* number of volumes in datastream */
pinput = hdrbuf.text_buffer;
/* skip past first line in header */
@@ -630,8 +488,7 @@ _pkgtrans(char *device1, char *device2, char **pkg, int options,
}
int
-pkgtrans(char *device1, char *device2, char **pkg, int options,
- keystore_handle_t keystore, char *keystore_alias)
+pkgtrans(char *device1, char *device2, char **pkg, int options)
{
int r;
struct sigaction nact;
@@ -683,7 +540,7 @@ pkgtrans(char *device1, char *device2, char **pkg, int options,
* perform the package translation
*/
- r = _pkgtrans(device1, device2, pkg, options, keystore, keystore_alias);
+ r = _pkgtrans(device1, device2, pkg, options);
/*
* reset signal handlers
@@ -922,20 +779,12 @@ genheader(char *src, char **pkg)
}
static int
-wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig)
+wdsheader(struct dm_buf *hdr, char *device, char **pkg)
{
- FILE *fp;
- char path[PATH_MAX], tmp_entry[ENTRY_MAX],
- tmp_file[L_tmpnam+1];
- char srcpath[PATH_MAX];
+ char tmp_entry[ENTRY_MAX], tmp_file[L_tmpnam+1];
int i, n;
int list_fd;
int block_cnt;
- int len;
- char cwd[MAXPATHLEN + 1];
- boolean_t making_sig = B_FALSE;
-
- making_sig = (sig != NULL) ? B_TRUE : B_FALSE;
(void) ds_close(0);
if (dstdev.pathname)
@@ -982,161 +831,32 @@ wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig)
* Create a cpio-compatible list of the requisite files in
* the temporary file.
*/
- if (!making_sig) {
- for (i = 0; pkg[i]; i++) {
- register ssize_t entry_size;
-
- /*
- * Copy pkginfo and pkgmap filenames into the
- * temporary string allowing for the first line
- * as a special case.
- */
- entry_size = sprintf(tmp_entry,
- (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
- pkg[i], PKGINFO, pkg[i], PKGMAP);
-
- if (write(list_fd, tmp_entry,
- entry_size) != entry_size) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
- (void) close(list_fd);
- ecleanup();
- return (1);
- }
- }
-
- } else {
+ for (i = 0; pkg[i]; i++) {
register ssize_t entry_size;
/*
- * if we're making a signature, we must make a
- * temporary area full of symlinks to the requisite
- * files, plus an extra entry for the signature, so
- * that cpio will put all files and signature in the
- * same archive in a single invocation of cpio.
+ * Copy pkginfo and pkgmap filenames into the
+ * temporary string allowing for the first line
+ * as a special case.
*/
- tmpsymdir = xstrdup(tmpnam(NULL));
+ entry_size = sprintf(tmp_entry,
+ (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
+ pkg[i], PKGINFO, pkg[i], PKGMAP);
- if (mkdir(tmpsymdir, S_IRWXU)) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_MKDIR), tmpsymdir);
- return (1);
- }
-
- /* generate the signature */
- if (((len = snprintf(path, PATH_MAX, "%s/%s",
- tmpsymdir, SIGNATURE_FILENAME)) >= PATH_MAX) ||
- len < 0) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_NOTMPFIL), tmpsymdir);
- cleanup();
- return (1);
- }
-
- if ((fp = fopen(path, "w")) == NULL) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_NOTMPFIL), path);
- cleanup();
- return (1);
- }
- (void) PEM_write_PKCS7(fp, sig);
- (void) fclose(fp);
-
- for (i = 0; pkg[i]; i++) {
- (void) snprintf(path, sizeof (path),
- "%s/%s", tmpsymdir, pkg[i]);
- if (mkdir(path, 0755)) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_MKDIR), path);
- cleanup();
- return (1);
- }
- (void) snprintf(path, sizeof (path),
- "%s/%s/%s", tmpsymdir, pkg[i], PKGINFO);
- (void) snprintf(srcpath, sizeof (srcpath),
- "%s/%s/%s", src, pkg[i], PKGINFO);
- if (symlink(srcpath, path) != 0) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_SYMLINK), path, srcpath);
- cleanup();
- return (1);
- }
-
- (void) snprintf(path, sizeof (path),
- "%s/%s/%s", tmpsymdir, pkg[i], PKGMAP);
- (void) snprintf(srcpath, sizeof (srcpath),
- "%s/%s/%s", src, pkg[i], PKGMAP);
- if (symlink(srcpath, path) != 0) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_SYMLINK), path, srcpath);
- cleanup();
- return (1);
- }
-
- /*
- * Copy pkginfo and pkgmap filenames into the
- * temporary string allowing for the first line
- * as a special case.
- */
- entry_size = snprintf(tmp_entry, sizeof (tmp_entry),
- (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
- pkg[i], PKGINFO, pkg[i], PKGMAP);
-
- if (write(list_fd, tmp_entry,
- entry_size) != entry_size) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
- (void) close(list_fd);
- ecleanup();
- cleanup();
- return (1);
- }
- }
-
- /* add signature to list of files */
- entry_size = snprintf(tmp_entry, sizeof (tmp_entry), "\n%s",
- SIGNATURE_FILENAME);
- if (write(list_fd, tmp_entry, entry_size) != entry_size) {
+ if (write(list_fd, tmp_entry,
+ entry_size) != entry_size) {
progerr(pkg_gt(ERR_TRANSFER));
logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
(void) close(list_fd);
ecleanup();
- cleanup();
return (1);
}
}
(void) lseek(list_fd, 0, SEEK_SET);
- if (!making_sig) {
- (void) snprintf(tmp_entry, sizeof (tmp_entry),
- "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE);
- } else {
- /*
- * when making a signature, we must make sure to follow
- * symlinks during the cpio so that we don't archive
- * the links themselves
- */
- (void) snprintf(tmp_entry, sizeof (tmp_entry),
- "%s -ocDL -C %d", CPIOPROC, (int)BLK_SIZE);
- }
-
- if (making_sig) {
- /* save cwd and change to symlink dir for cpio invocation */
- if (getcwd(cwd, MAXPATHLEN + 1) == NULL) {
- logerr(pkg_gt(ERR_GETWD));
- progerr(pkg_gt(ERR_TRANSFER));
- cleanup();
- return (1);
- }
-
- if (chdir(tmpsymdir)) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_CHDIR), tmpsymdir);
- cleanup();
- return (1);
- }
- }
+ (void) snprintf(tmp_entry, sizeof (tmp_entry),
+ "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE);
if (n = esystem(tmp_entry, list_fd, ds_fd)) {
rpterr();
@@ -1151,15 +871,6 @@ wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig)
(void) close(list_fd);
(void) unlink(tmp_file);
- if (making_sig) {
- /* change to back to src dir for subsequent operations */
- if (chdir(cwd)) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_CHDIR), cwd);
- cleanup();
- return (1);
- }
- }
return (0);
}
@@ -1679,135 +1390,6 @@ pkgxfer(char *srcinst, int options)
return (0);
}
-/*
- * Name: pkgdump
- * Description: Dump a cpio archive of a package's contents to a BIO.
- *
- * Arguments: srcinst - Name of package, which resides on the
- * device pointed to by the static 'srcdev' variable,
- * to dump.
- * bio - BIO object to dump data to
- *
- * Returns : 0 - success
- * nonzero - failure. errors printed to screen.
- */
-static int
-pkgdump(char *srcinst, BIO *bio)
-{
- FILE *fp;
- char *src;
- char temp[MAXPATHLEN],
- srcdir[MAXPATHLEN],
- cmd[CMDSIZE];
- int i, n, part, nparts, maxpartsize, iscomp;
-
- /*
- * when this routine is entered, the entire package
- * is already available at 'src' - including the
- * pkginfo/pkgmap files and the objects as well.
- */
-
- /* read the pkgmap to get it's size information */
- if ((fp = fopen(PKGMAP, "r")) == NULL) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
- return (1);
- }
-
- nparts = 1;
- if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
- return (1);
- else
- (void) fclose(fp);
-
- /* make sure the first volume is available */
- if (srcdev.mount) {
- src = srcdev.dirname;
- (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, srcinst);
- if (ckvolseq(srcdir, 1, nparts)) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_SEQUENCE));
- return (1);
- }
- }
-
- /*
- * form cpio command that will output the contents of all of
- * this package's parts
- */
- for (part = 1; part <= nparts; /* void */) {
-
- if (part == 1) {
- (void) snprintf(cmd, CMDSIZE, "find %s %s",
- PKGINFO, PKGMAP);
- if (nparts && (isdir(INSTALL) == 0)) {
- (void) strlcat(cmd, " ", sizeof (cmd));
- (void) strlcat(cmd, INSTALL, sizeof (cmd));
- }
- } else
- (void) snprintf(cmd, CMDSIZE, "find %s", PKGINFO);
-
- if (nparts > 1) {
- (void) snprintf(temp, MAXPATHLEN, "%s.%d", RELOC, part);
- if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
- (void) strlcat(cmd, " ", CMDSIZE);
- (void) strlcat(cmd, temp, CMDSIZE);
- }
- (void) snprintf(temp, MAXPATHLEN, "%s.%d", ROOT, part);
- if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
- (void) strlcat(cmd, " ", CMDSIZE);
- (void) strlcat(cmd, temp, CMDSIZE);
- }
- (void) snprintf(temp, MAXPATHLEN, "%s.%d",
- ARCHIVE, part);
- if (isdir(temp) == 0) {
- (void) strlcat(cmd, " ", CMDSIZE);
- (void) strlcat(cmd, temp, CMDSIZE);
- }
- } else if (nparts) {
- for (i = 0; reloc_names[i] != NULL; i++) {
- if (iscpio(reloc_names[i], &iscomp) ||
- isdir(reloc_names[i]) == 0) {
- (void) strlcat(cmd, " ", CMDSIZE);
- (void) strlcat(cmd, reloc_names[i],
- CMDSIZE);
- }
- }
- for (i = 0; root_names[i] != NULL; i++) {
- if (iscpio(root_names[i], &iscomp) ||
- isdir(root_names[i]) == 0) {
- (void) strlcat(cmd, " ", CMDSIZE);
- (void) strlcat(cmd, root_names[i],
- CMDSIZE);
- }
- }
- if (isdir(ARCHIVE) == 0) {
- (void) strlcat(cmd, " ", CMDSIZE);
- (void) strlcat(cmd, ARCHIVE, CMDSIZE);
- }
- }
-
- (void) snprintf(cmd + strlen(cmd),
- sizeof (cmd) - strlen(cmd),
- " -print | %s -ocD -C %d",
- CPIOPROC, (int)BLK_SIZE);
- /*
- * execute the command, dumping all standard output
- * to the BIO.
- */
- n = BIO_dump_cmd(cmd, bio);
- if (n != 0) {
- rpterr();
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
- return (1);
- }
-
- part++;
- }
- return (0);
-}
-
static void
sigtrap(int signo)
{
@@ -1845,129 +1427,3 @@ cleanup(void)
(void) pkgumount(&dstdev);
(void) ds_close(1);
}
-
-/*
- * Name: dump_hdr_and_pkgs
- * Description: Dumps datastream header and each package's contents
- * to the supplied BIO
- *
- * Arguments: bio - BIO object to dump data to
- * hdr - Header for the datastream being dumped
- * pkglist - NULL-terminated list of packages
- * to dump. The location of the packages are stored
- * in the static 'srcdev' variable.
- *
- * Returns : 0 - success
- * nonzero - failure. errors printed to screen.
- */
-static int
-dump_hdr_and_pkgs(BIO *bio, struct dm_buf *hdr, char **pkglist)
-{
- int block_cnt, i;
- char srcdir[MAXPATHLEN];
- char cwd[MAXPATHLEN + 1];
- char *src;
-
- /* write out the header to the signature stream */
- for (block_cnt = 0; block_cnt < hdr->allocation;
- block_cnt += BLK_SIZE) {
- (void) BIO_write(bio, (hdr->text_buffer + block_cnt), BLK_SIZE);
- }
-
- /* save current directory */
- if (getcwd(cwd, MAXPATHLEN + 1) == NULL) {
- logerr(pkg_gt(ERR_GETWD));
- progerr(pkg_gt(ERR_TRANSFER));
- return (1);
- }
-
- /* now write out each package's contents */
- for (i = 0; pkglist[i]; i++) {
- /*
- * change to the source dir, so we can find and dump
- * the package(s) bits into the BIO
- *
- */
- src = srcdev.dirname;
-
- /* change to the package source directory */
- (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, pkglist[i]);
- if (chdir(srcdir)) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_CHDIR), srcdir);
- return (1);
- }
-
- if (pkgdump(pkglist[i], bio)) {
- pkglist[i] = NULL;
- return (1);
- }
- }
-
- /* change back to directory we were in upon entering this routine */
- if (chdir(cwd)) {
- progerr(pkg_gt(ERR_TRANSFER));
- logerr(pkg_gt(MSG_CHDIR), cwd);
- return (1);
- }
-
- return (0);
-}
-
-/*
- * Name: BIO_dump_cmd
- * Description: Dump the output of invoking a command
- * to a BIO.
- *
- * Arguments: cmd - Command to invoke
- * bio - BIO to dump output of command to
- * only 'stdout' is dumped.
- * Returns : 0 - success
- * nonzero - failure. errors printed to screen.
- */
-int
-BIO_dump_cmd(char *cmd, BIO *bio)
-{
- char buf[BLK_SIZE];
- FILE *fp;
- int rc;
-
- /* start up the process */
- if ((fp = epopen(cmd, "r")) == NULL) {
- rpterr();
- return (1);
- }
-
- /* read output in chunks, transfer to BIO */
- while (fread(buf, BLK_SIZE, 1, fp) == 1) {
- if (BIO_write(bio, buf, BLK_SIZE) != BLK_SIZE) {
- (void) sighold(SIGINT);
- (void) sighold(SIGHUP);
- (void) epclose(fp);
- (void) sigrelse(SIGINT);
- (void) sigrelse(SIGHUP);
- rpterr();
- return (1);
- }
- }
-
- /* done with stream, make sure no errors were encountered */
- if (ferror(fp)) {
- (void) epclose(fp);
- rpterr();
- return (1);
- }
-
- /* done, close stream, report any errors */
- (void) sighold(SIGINT);
- (void) sighold(SIGHUP);
- rc = epclose(fp);
- (void) sigrelse(SIGINT);
- (void) sigrelse(SIGHUP);
- if (rc != 0) {
- rpterr();
- return (1);
- }
-
- return (rc);
-}
diff --git a/usr/src/lib/libpkg/common/pkgweb.c b/usr/src/lib/libpkg/common/pkgweb.c
deleted file mode 100644
index bcda3e53f2..0000000000
--- a/usr/src/lib/libpkg/common/pkgweb.c
+++ /dev/null
@@ -1,3240 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#include <stdio.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <pkglocs.h>
-#include <locale.h>
-#include <libintl.h>
-#include <libgen.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <boot_http.h>
-#include <errno.h>
-#include <ctype.h>
-#include <openssl/pkcs7.h>
-#include <openssl/ocsp.h>
-#include <openssl/pkcs12.h>
-#include <openssl/err.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/x509v3.h>
-#include "pkglib.h"
-#include "pkglibmsgs.h"
-#include "pkglocale.h"
-#include "keystore.h"
-#include "pkgweb.h"
-#include "pkgerr.h"
-#include "p12lib.h"
-
-/* fixed format when making an OCSP request */
-#define OCSP_REQUEST_FORMAT \
- "POST %s HTTP/1.0\r\n" \
- "Content-Type: application/ocsp-request\r\n" \
- "Content-Length: %d\r\n\r\n"
-
-/*
- * no security is afforded by using this phrase to "encrypt" CA certificates,
- * but it might aid in debugging and has to be non-null
- */
-#define WEB_CA_PHRASE "schizophrenic"
-
-/* This one needs the ': ' at the end */
-#define CONTENT_TYPE_HDR "Content-Type"
-#define CONTENT_DISPOSITION_HDR "Content-Disposition"
-#define CONTENT_OCSP_RESP "application/ocsp-response"
-#define CONTENT_LENGTH_HDR "Content-Length"
-#define LAST_MODIFIED_HDR "Last-Modified"
-#define OCSP_BUFSIZ 1024
-
-/*
- * default amount of time that is allowed for error when checking
- * OCSP response validity.
- * For example, if this is set to 5 minutes, then if a response
- * is issued that is valid from 12:00 to 1:00, then we will
- * accept it if the local time is between 11:55 and 1:05.
- * This takes care of not-quite-synchronized server and client clocks.
- */
-#define OCSP_VALIDITY_PERIOD (5 * 60)
-
-/* this value is defined by getpassphrase(3c) manpage */
-#define MAX_PHRASELEN 257
-
-/* Max length of "enter password again" prompt message */
-#define MAX_VERIFY_MSGLEN 1024
-
-/* local prototypes */
-static boolean_t remove_dwnld_file(char *);
-static boolean_t get_ENV_proxyport(PKG_ERR *, ushort_t *);
-static boolean_t make_link(char *, char *);
-static WebStatus web_send_request(PKG_ERR *, int, int, int);
-static boolean_t web_eval_headers(PKG_ERR *);
-static WebStatus web_get_file(PKG_ERR *, char *, int, char **);
-static boolean_t ck_dwnld_dir_space(PKG_ERR *, char *, ulong_t);
-static WebStatus web_connect(PKG_ERR *);
-static boolean_t web_setup(PKG_ERR *);
-static boolean_t check_dwnld_dir(PKG_ERR *, char *);
-static boolean_t parse_url_proxy(PKG_ERR *, char *, char *, ushort_t);
-static boolean_t web_disconnect(void);
-static char *get_unique_filename(char *, char *);
-static boolean_t get_ENV_proxy(PKG_ERR *, char **);
-static char *condense_lastmodified(char *);
-static int web_verify(int, X509_STORE_CTX *);
-static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
-static boolean_t get_ocsp_uri(X509 *, char **);
-static OCSPStatus ocsp_verify(PKG_ERR *, X509 *, X509 *, char *, url_hport_t *,
- STACK_OF(X509) *);
-static char *get_time_string(ASN1_GENERALIZEDTIME *);
-static char *write_ca_file(PKG_ERR *, char *, STACK_OF(X509) *, char *);
-static boolean_t _get_random_info(void *, int);
-static boolean_t init_session(void);
-static void progress_setup(int, ulong_t);
-static void progress_report(int, ulong_t);
-static void progress_finish(int);
-static char *replace_token(char *, char, char);
-static void dequote(char *);
-static void trim(char *);
-
-
-/*
- * structure used to hold data passed back to the
- * X509 verify callback routine in validate_signature()
- */
-typedef struct {
- url_hport_t *proxy;
- PKG_ERR *err;
- STACK_OF(X509) *cas;
-} verify_cb_data_t;
-
-/* Progress bar variables */
-static ulong_t const_increment, const_divider, completed, const_completed;
-
-/* current network backoff wait period */
-static int cur_backoff = 0;
-
-/* download session context handle */
-static WEB_SESSION *ps;
-
-static int webpkg_install = 0;
-static char *prompt = NULL;
-static char *passarg = NULL;
-
-
-/* ~~~~~~~~~~~~~~ Public Functions ~~~~~~~~~~~~~~~~~~~ */
-
-/*
- * Name: set_prompt
- * Description: Specifies the prompt to use with the pkglib
- * passphrase callback routine.
- *
- * Arguments: newprompt - The prompt to display
- *
- * Returns : NONE
- */
-void
-set_passphrase_prompt(char *newprompt)
-{
- prompt = newprompt;
-}
-
-/*
- * Name: set_passarg
- * Description: Specifies the passphrase retrieval method
- * to use with the pkglib
- * passphrase callback routine.
- *
- * Arguments: newpassarg - The new password retrieval arg
- *
- * Returns : NONE
- */
-void
-set_passphrase_passarg(char *newpassarg)
-{
- passarg = newpassarg;
-}
-
-/*
- * Name: get_proxy_port
- * Description: Resolves proxy specification
- *
- * Arguments: err - where to record any errors.
- * proxy - Location to store result - if *proxy is not
- * null, then it will be validated, but not changed
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- * on success, *proxy and *port are set to either
- * the user-supplied proxy and port, or the
- * ones found in the environment variables
- * HTTPPROXY and/or HTTPROXYPORT
- */
-boolean_t
-get_proxy_port(PKG_ERR *err, char **proxy, ushort_t *port)
-{
- if (*proxy != NULL) {
- if (!path_valid(*proxy)) {
- /* bad proxy supplied */
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_BAD_PROXY), *proxy);
- return (B_FALSE);
- }
- if (!get_ENV_proxyport(err, port)) {
- /* env set, but bad */
- return (B_FALSE);
- }
- } else {
- if (!get_ENV_proxy(err, proxy)) {
- /* environment variable set, but bad */
- return (B_FALSE);
- }
- if ((*proxy != NULL) && !path_valid(*proxy)) {
- /* env variable set, but bad */
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_BAD_PROXY), *proxy);
- return (B_FALSE);
- }
- if (!get_ENV_proxyport(err, port)) {
- /* env variable set, but bad */
- return (B_FALSE);
- }
- }
- return (B_TRUE);
-}
-
-/*
- * Name: path_valid
- * Description: Checks a string for being a valid path
- *
- * Arguments: path - path to validate
- *
- * Returns : B_TRUE - success, B_FALSE otherwise.
- * B_FALSE means path was null, too long (>PATH_MAX),
- * or too short (<1)
- */
-boolean_t
-path_valid(char *path)
-{
- if (path == NULL) {
- return (B_FALSE);
- } else if (strlen(path) > PATH_MAX) {
- return (B_FALSE);
- } else if (strlen(path) >= 1) {
- return (B_TRUE);
- } else {
- /* path < 1 */
- return (B_FALSE);
- }
-}
-
-/*
- * Name: web_cleanup
- * Description: Deletes temp files, closes, frees memory taken
- * by 'ps' static structure
- *
- * Arguments: none
- *
- * Returns : none
- */
-void
-web_cleanup(void)
-{
- PKG_ERR *err;
-
- if (ps == NULL)
- return;
-
- err = pkgerr_new();
-
- if (ps->keystore) {
- (void) close_keystore(err, ps->keystore, NULL);
- }
-
- ps->keystore = NULL;
-
- pkgerr_free(err);
-
- if (ps->uniqfile) {
- (void) remove_dwnld_file(ps->uniqfile);
- free(ps->uniqfile);
- ps->uniqfile = NULL;
- }
- if (ps->link) {
- (void) remove_dwnld_file(ps->link);
- free(ps->link);
- ps->link = NULL;
- }
- if (ps->dwnld_dir) {
- (void) rmdir(ps->dwnld_dir);
- ps->dwnld_dir = NULL;
- }
- if (ps->errstr) {
- free(ps->errstr);
- ps->errstr = NULL;
- }
-
- if (ps->content) {
- free(ps->content);
- ps->content = NULL;
- }
-
- if (ps->resp) {
- http_free_respinfo(ps->resp);
- ps->resp = NULL;
- }
-
- if (ps) {
- free(ps);
- ps = NULL;
- }
-}
-
-/*
- * Name: web_session_control
- * Description: Downloads an arbitrary URL and saves to disk.
- *
- * Arguments: err - where to record any errors.
- * url - URL pointing to content to download - can be
- * http:// or https://
- * dwnld_dir - Directory to download into
- * keystore - keystore to use for accessing trusted
- * certs when downloading using SSL
- * proxy - HTTP proxy to use, or NULL for no proxy
- * proxy_port - HTTP proxy port to use, ignored
- * if proxy is NULL
- * passarg - method to retrieve password
- * retries - # of times to retry download before
- * giving up
- * timeout - how long to wait before retrying,
- * when download is interrupted
- * nointeract - if non-zero, do not output
- * download progress to screen
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- */
-boolean_t
-web_session_control(PKG_ERR *err, char *url, char *dwnld_dir,
- keystore_handle_t keystore, char *proxy, ushort_t proxy_port,
- int retries, int timeout, int nointeract, char **fname)
-{
- int i;
- boolean_t ret = B_TRUE;
- boolean_t retrieved = B_FALSE;
-
- if (!init_session()) {
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!parse_url_proxy(err, url, proxy, proxy_port)) {
- ret = B_FALSE;
- goto cleanup;
- }
-
- ps->timeout = timeout;
-
- if (keystore != NULL)
- ps->keystore = keystore;
-
- if (dwnld_dir != NULL)
- ps->dwnld_dir = xstrdup(dwnld_dir);
- else {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_NO_DWNLD_DIR));
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!check_dwnld_dir(err, dwnld_dir)) {
- ret = B_FALSE;
- goto cleanup;
- }
-
- for (i = 0; i < retries && !retrieved; i++) {
- if (!web_setup(err)) {
- ret = B_FALSE;
- goto cleanup;
- }
-
- switch (web_connect(err)) {
- /* time out and wait a little bit for these failures */
- case WEB_OK:
- /* were able to connect */
- reset_backoff();
- break;
- case WEB_TIMEOUT:
- echo_out(nointeract, gettext(MSG_DWNLD_TIMEOUT));
- (void) web_disconnect();
- backoff();
- continue;
-
- case WEB_CONNREFUSED:
- echo_out(nointeract, gettext(MSG_DWNLD_CONNREF),
- ps->url.hport.hostname);
- (void) web_disconnect();
- backoff();
- continue;
- case WEB_HOSTDOWN:
- echo_out(nointeract, gettext(MSG_DWNLD_HOSTDWN),
- ps->url.hport.hostname);
- (void) web_disconnect();
- backoff();
- continue;
-
- default:
- /* every other failure is a hard failure, so bail */
- ret = B_FALSE;
- goto cleanup;
- }
-
- switch (web_send_request(err, HTTP_REQ_TYPE_HEAD,
- ps->data.cur_pos, ps->data.content_length)) {
- case WEB_OK:
- /* were able to connect */
- reset_backoff();
- break;
- case WEB_TIMEOUT:
- echo_out(nointeract, gettext(MSG_DWNLD_TIMEOUT));
- (void) web_disconnect();
- backoff();
- continue;
-
- case WEB_CONNREFUSED:
- echo_out(nointeract, gettext(MSG_DWNLD_CONNREF),
- ps->url.hport.hostname);
- (void) web_disconnect();
- backoff();
- continue;
- case WEB_HOSTDOWN:
- echo_out(nointeract, gettext(MSG_DWNLD_HOSTDWN),
- ps->url.hport.hostname);
- (void) web_disconnect();
- backoff();
- continue;
- default:
- /* every other case is failure, so bail */
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!web_eval_headers(err)) {
- ret = B_FALSE;
- goto cleanup;
- }
-
- switch (web_get_file(err, dwnld_dir, nointeract, fname)) {
- case WEB_OK:
- /* were able to retrieve file */
- retrieved = B_TRUE;
- reset_backoff();
- break;
-
- case WEB_TIMEOUT:
- echo_out(nointeract, gettext(MSG_DWNLD_TIMEOUT));
- (void) web_disconnect();
- backoff();
- continue;
-
- case WEB_CONNREFUSED:
- echo_out(nointeract, gettext(MSG_DWNLD_CONNREF),
- ps->url.hport.hostname);
- (void) web_disconnect();
- backoff();
- continue;
- case WEB_HOSTDOWN:
- echo_out(nointeract, gettext(MSG_DWNLD_HOSTDWN),
- ps->url.hport.hostname);
- (void) web_disconnect();
- backoff();
- continue;
- default:
- /* every other failure is a hard failure, so bail */
- ret = B_FALSE;
- goto cleanup;
- }
- }
-
- if (!retrieved) {
- /* max retries attempted */
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_DWNLD_FAILED), retries);
- ret = B_FALSE;
- }
-cleanup:
- (void) web_disconnect();
- if (!ret) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_DWNLD), url);
- }
- return (ret);
-}
-
-/*
- * Name: get_signature
- * Description: retrieves signature from signed package.
- *
- * Arguments: err - where to record any errors.
- * ids_name - name of package stream, for error reporting
- * devp - Device on which package resides that we
- * result - where to store resulting PKCS7 signature
- *
- * Returns : B_TRUE - package is signed and signature returned OR
- * package is not signed, in which case result is NULL
- *
- * B_FALSE - there were problems accessing signature,
- * and it is unknown whether it is signed or not. Errors
- * recorded in 'err'.
- */
-boolean_t
-get_signature(PKG_ERR *err, char *ids_name, struct pkgdev *devp, PKCS7 **result)
-{
- char path[PATH_MAX];
- int len, fd = -1;
- struct stat buf;
- FILE *fp = NULL;
- boolean_t ret = B_TRUE;
- BIO *sig_in = NULL;
- PKCS7 *p7 = NULL;
-
- /*
- * look for signature. If one was in the stream,
- * it is now extracted
- */
- if (((len = snprintf(path, PATH_MAX, "%s/%s", devp->dirname,
- SIGNATURE_FILENAME)) >= PATH_MAX) || (len < 0)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_LEN), ids_name);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if ((fd = open(path, O_RDONLY|O_NONBLOCK)) == -1) {
- /*
- * only if the signature is non-existant
- * do we "pass"
- */
- if (errno != ENOENT) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_OPENSIG),
- strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
- } else {
- /* found sig file. parse it. */
- if (fstat(fd, &buf) == -1) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_OPENSIG), strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (!S_ISREG(buf.st_mode)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_OPENSIG),
- (gettext(ERR_NOT_REG)));
- ret = B_FALSE;
- goto cleanup;
- }
-
- if ((fp = fdopen(fd, "r")) == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_OPENSIG), strerror(errno));
- ret = B_FALSE;
- goto cleanup;
- }
-
- /*
- * read in signature. If it's invalid, we
- * punt, unless we're ignoring it
- */
- if ((sig_in = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_OPENSIG), strerror(errno));
- goto cleanup;
- }
-
- if ((p7 = PEM_read_bio_PKCS7(sig_in,
- NULL, NULL, NULL)) == NULL) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_CORRUPTSIG),
- ids_name);
- ret = B_FALSE;
- goto cleanup;
- }
- *result = p7;
- p7 = NULL;
- }
-
-cleanup:
- if (sig_in)
- (void) BIO_free(sig_in);
- if (fp)
- (void) fclose(fp);
- if (fd != -1)
- (void) close(fd);
- if (p7)
- (void) PKCS7_free(p7);
-
- return (ret);
-}
-
-/*
- * Name: echo_out
- * Description: Conditionally output a message to stdout
- *
- * Arguments: nointeract - if non-zero, do not output anything
- * fmt - print format
- * ... - print arguments
- *
- * Returns : none
- */
-/*PRINTFLIKE2*/
-void
-echo_out(int nointeract, char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
-
- if (nointeract)
- return;
-
- (void) vfprintf(stdout, fmt, ap);
-
- va_end(ap);
-
- (void) putc('\n', stdout);
-}
-
-/*
- * Name: strip_port
- * Description: Returns "port" portion of a "hostname:port" string
- *
- * Arguments: proxy - full "hostname:port" string pointer
- *
- * Returns : the "port" portion of a "hostname:port" string,
- * converted to a decimal integer, or (int)0
- * if string contains no :port suffix.
- */
-ushort_t
-strip_port(char *proxy)
-{
- char *tmp_port;
-
- if ((tmp_port = strpbrk(proxy, ":")) != NULL)
- return (atoi(tmp_port));
- else
- return (0);
-}
-
-/*
- * Name: set_web_install
- * Description: Sets flag indicating we are doing a web-based install
- *
- * Arguments: none
- *
- * Returns : none
- */
-void
-set_web_install(void)
-{
- webpkg_install++;
-}
-
-/*
- * Name: is_web_install
- * Description: Determines whether we are doing a web-based install
- *
- * Arguments: none
- *
- * Returns : non-zero if we are doing a web-based install, 0 otherwise
- */
-int
-is_web_install(void)
-{
- return (webpkg_install);
-}
-
-/* ~~~~~~~~~~~~~~ Private Functions ~~~~~~~~~~~~~~~~~~~ */
-
-/*
- * Name: web_disconnect
- * Description: Disconnects connection to web server
- *
- * Arguments: none
- *
- * Returns : B_TRUE - successful disconnect, B_FALSE otherwise
- * Temp certificiate files are deleted,
- * if one was used to initiate the connection
- * (such as when using SSL)
- */
-static boolean_t
-web_disconnect(void)
-{
- if (ps->certfile) {
- (void) unlink(ps->certfile);
- }
- if (http_srv_disconnect(ps->hps) == 0)
- if (http_srv_close(ps->hps) == 0)
- return (B_TRUE);
-
- return (B_FALSE);
-}
-
-/*
- * Name: check_dwnld_dir
- * Description: Creates temp download directory
- *
- * Arguments: err - where to record any errors.
- * dwnld_dir - name of directory to create
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- * on success, directory is created with
- * safe permissions
- */
-static boolean_t
-check_dwnld_dir(PKG_ERR *err, char *dwnld_dir)
-{
- DIR *dirp;
-
- /*
- * Check the directory passed in. If it doesn't exist, create it
- * with strict permissions
- */
- if ((dirp = opendir(dwnld_dir)) == NULL) {
- if (mkdir(dwnld_dir, 0744) == -1) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTEMP),
- dwnld_dir);
- return (B_FALSE);
- }
- }
- if (dirp) {
- (void) closedir(dirp);
- }
- return (B_TRUE);
-}
-
-/*
- * Name: ds_validate_signature
- * Description: Validates signature found in a package datastream
- *
- * Arguments: err - where to record any errors.
- * pkgdev - Package context handle of package to verify
- * pkgs - Null-terminated List of package name to verify
- * ids_name - Pathname to stream to validate
- * p7 - PKCS7 signature decoded from stream header
- * cas - List of trusted CA certificates
- * proxy - Proxy to use when doing online validation (OCSP)
- * nointeract - if non-zero, do not output to screen
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- * success means signature was completely validated,
- * and contents of stream checked against signature.
- */
-boolean_t
-ds_validate_signature(PKG_ERR *err, struct pkgdev *pkgdev, char **pkgs,
- char *ids_name, PKCS7 *p7, STACK_OF(X509) *cas,
- url_hport_t *proxy, int nointeract)
-{
- BIO *p7_bio;
- boolean_t ret = B_TRUE;
-
- /* make sure it's a Signed PKCS7 message */
- if (!PKCS7_type_is_signed(p7)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_CORRUPTSIG_TYPE),
- ids_name);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* initialize PKCS7 object to be filled in */
- if (!PKCS7_get_detached(p7)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_CORRUPTSIG_DT),
- ids_name);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* dump header and packages into BIO to calculate the message digest */
- if ((p7_bio = PKCS7_dataInit(p7, NULL)) == NULL) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_CORRUPTSIG),
- ids_name);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if ((BIO_ds_dump_header(err, p7_bio) != 0) ||
- (BIO_ds_dump(err, ids_name, p7_bio) != 0)) {
- ret = B_FALSE;
- goto cleanup;
- }
- (void) BIO_flush(p7_bio);
-
- /* validate the stream and its signature */
- if (!validate_signature(err, ids_name, p7_bio, p7, cas,
- proxy, nointeract)) {
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* reset device stream (really bad performance for tapes) */
- (void) ds_close(1);
- (void) ds_init(ids_name, pkgs, pkgdev->norewind);
-
-cleanup:
- return (ret);
-}
-
-
-/*
- * Name: validate_signature
- * Description: Validates signature of an arbitrary stream of bits
- *
- * Arguments: err - where to record any errors.
- * name - Descriptive name of object being validated,
- * for good error reporting messages
- * indata - BIO object to read stream bits from
- * p7 - PKCS7 signature of stream
- * cas - List of trusted CA certificates
- * proxy - Proxy to use when doing online validation (OCSP)
- * nointeract - if non-zero, do not output to screen
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- * success means signature was completely validated,
- * and contents of stream checked against signature.
- */
-boolean_t
-validate_signature(PKG_ERR *err, char *name, BIO *indata, PKCS7 *p7,
- STACK_OF(X509) *cas, url_hport_t *proxy, int nointeract)
-{
- STACK_OF(PKCS7_SIGNER_INFO) *sec_sinfos = NULL;
-
- PKCS7_SIGNER_INFO *signer = NULL;
- X509_STORE *sec_truststore = NULL;
- X509_STORE_CTX *ctx = NULL;
- X509 *signer_cert = NULL, *issuer = NULL;
- STACK_OF(X509) *chaincerts = NULL;
- int i, k;
- unsigned long errcode;
- const char *err_data = NULL;
- const char *err_reason = NULL;
- char *err_string;
- int err_flags;
- verify_cb_data_t verify_data;
- char *signer_sname;
- char *signer_iname;
- PKCS7_ISSUER_AND_SERIAL *ias;
- boolean_t ret = B_TRUE;
-
- /* only support signed PKCS7 signatures */
- if (!PKCS7_type_is_signed(p7)) {
- PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* initialize temporary internal trust store used for verification */
- sec_truststore = X509_STORE_new();
-
- for (i = 0; i < sk_X509_num(cas); i++) {
- if (X509_STORE_add_cert(sec_truststore,
- sk_X509_value(cas, i)) == 0) {
- pkgerr_add(err, PKGERR_VERIFY, gettext(ERR_MEM));
- ret = B_FALSE;
- goto cleanup;
- }
- }
-
- /* get signers from the signature */
- if ((sec_sinfos = PKCS7_get_signer_info(p7)) == NULL) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_CORRUPTSIG), name);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* verify each signer found in the PKCS7 signature */
- for (k = 0; k < sk_PKCS7_SIGNER_INFO_num(sec_sinfos); k++) {
- signer = sk_PKCS7_SIGNER_INFO_value(sec_sinfos, k);
- signer_cert = PKCS7_cert_from_signer_info(p7, signer);
- signer_sname = get_subject_display_name(signer_cert);
- signer_iname = get_issuer_display_name(signer_cert);
-
- echo_out(nointeract, gettext(MSG_VERIFY), signer_sname);
-
- /* find the issuer of the current cert */
- chaincerts = p7->d.sign->cert;
- ias = signer->issuer_and_serial;
- issuer = X509_find_by_issuer_and_serial(chaincerts,
- ias->issuer, ias->serial);
-
- /* were we not able to find the issuer cert */
- if (issuer == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_VERIFY_ISSUER),
- signer_iname, signer_sname);
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* Lets verify */
- if ((ctx = X509_STORE_CTX_new()) == NULL) {
- pkgerr_add(err, PKGERR_VERIFY, gettext(ERR_MEM));
- ret = B_FALSE;
- goto cleanup;
- }
- (void) X509_STORE_CTX_init(ctx, sec_truststore,
- issuer, chaincerts);
- (void) X509_STORE_CTX_set_purpose(ctx,
- X509_PURPOSE_ANY);
-
- /* callback will perform OCSP on certificates with OCSP data */
- X509_STORE_CTX_set_verify_cb(ctx, web_verify);
-
- /* pass needed data into callback through the app_data handle */
- verify_data.proxy = proxy;
- verify_data.cas = cas;
- verify_data.err = err;
- (void) X509_STORE_CTX_set_app_data(ctx, &verify_data);
-
- /* first verify the certificate chain */
- i = X509_verify_cert(ctx);
- if (i <= 0 && ctx->error != X509_V_ERR_CERT_HAS_EXPIRED) {
- signer_sname =
- get_subject_display_name(ctx->current_cert);
- signer_iname =
- get_issuer_display_name(ctx->current_cert);
- /* if the verify context holds an error, print it */
- if (ctx->error != X509_V_OK) {
- pkgerr_add(err, PKGERR_VERIFY,
- gettext(ERR_VERIFY_SIG), signer_sname,
- signer_iname,
- (char *)X509_verify_cert_error_string(ctx->error));
- } else {
- /* some other error. print them all. */
- while ((errcode = ERR_get_error_line_data(NULL,
- NULL, &err_data, &err_flags)) != 0) {
- size_t errsz;
- err_reason =
- ERR_reason_error_string(errcode);
- if (err_reason == NULL) {
- err_reason =
- gettext(ERR_SIG_INT);
- }
-
- if (!(err_flags & ERR_TXT_STRING)) {
- err_data =
- gettext(ERR_SIG_INT);
- }
- errsz = strlen(err_reason) +
- strlen(err_data) + 3;
- err_string = xmalloc(errsz);
- (void) snprintf(err_string, errsz,
- "%s: %s", err_reason, err_data);
- pkgerr_add(err, PKGERR_VERIFY,
- gettext(ERR_VERIFY_SIG),
- signer_sname, signer_iname,
- err_string);
- free(err_string);
- }
- }
- ret = B_FALSE;
- goto cleanup;
- }
-
- /* now verify the signature */
- i = PKCS7_signatureVerify(indata, p7, signer, issuer);
-
- if (i <= 0) {
- /* print out any OpenSSL-specific errors */
- signer_sname =
- get_subject_display_name(ctx->current_cert);
- signer_iname =
- get_subject_display_name(ctx->current_cert);
- while ((errcode = ERR_get_error_line_data(NULL,
- NULL, &err_data, &err_flags)) != 0) {
- err_reason =
- ERR_reason_error_string(errcode);
- if (err_reason == NULL) {
- err_reason =
- gettext(ERR_SIG_INT);
- }
-
- if (!(err_flags & ERR_TXT_STRING)) {
- err_data =
- gettext(ERR_SIG_INT);
- }
- pkgerr_add(err, PKGERR_VERIFY,
- gettext(ERR_VERIFY_SIG), signer_sname,
- signer_iname, err_reason);
- pkgerr_add(err, PKGERR_VERIFY,
- gettext(ERR_VERIFY_SIG), signer_sname,
- signer_iname, err_data);
- }
- ret = B_FALSE;
- goto cleanup;
- }
-
- echo_out(nointeract, gettext(MSG_VERIFY_OK), signer_sname);
- }
-
- /* signature(s) verified successfully */
-cleanup:
- if (ctx)
- X509_STORE_CTX_cleanup(ctx);
- return (ret);
-}
-
-/*
- * Name: web_verify
- * Description: Callback used by PKCS7_dataVerify when
- * verifying a certificate chain.
- *
- * Arguments: err - where to record any errors.
- * ctx - The context handle of the current verification operation
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- * if it's '0' (not OK) we simply return it, since the
- * verification operation has already determined that the
- * cert is invalid. if 'ok' is non-zero, then we do our
- * checks, and return 0 or 1 based on if the cert is
- * invalid or valid.
- */
-static int
-web_verify(int ok, X509_STORE_CTX *ctx)
-{
- X509 *curr_cert;
- X509 *curr_issuer;
- char *uri;
- url_hport_t *proxy;
- PKG_ERR *err = NULL;
- STACK_OF(X509) *cas;
- if (!ok) {
- /* don't override a verify failure */
- return (ok);
- }
-
-
- /* get app data supplied through callback context */
- err = ((verify_cb_data_t *)X509_STORE_CTX_get_app_data(ctx))->err;
- proxy = ((verify_cb_data_t *)X509_STORE_CTX_get_app_data(ctx))->proxy;
- cas = ((verify_cb_data_t *)X509_STORE_CTX_get_app_data(ctx))->cas;
-
- /* Check revocation status */
- curr_cert = X509_STORE_CTX_get_current_cert(ctx);
-
- /* this shouldn't happen */
- if (curr_cert == NULL) {
- pkgerr_add(err, PKGERR_INTERNAL, gettext(ERR_PKG_INTERNAL),
- __FILE__, __LINE__);
- return (0);
- }
-
- /* don't perform OCSP unless cert has required OCSP extensions */
- if (get_ocsp_uri(curr_cert, &uri)) {
- if (get_issuer(&curr_issuer, ctx, curr_cert) <= 0) {
- /* no issuer! */
- pkgerr_add(err, PKGERR_INTERNAL,
- gettext(ERR_PKG_INTERNAL),
- __FILE__, __LINE__);
- return (0);
- }
-
- /*
- * ok we have the current cert
- * and its issuer. Do the OCSP check
- */
-
- /*
- * OCSP extensions are, by, RFC 2459, never critical
- * extensions, therefore, we only fail if we were able
- * to explicitly contact an OCSP responder, and that
- * responder did not indicate the cert was valid. We
- * also fail if user-supplied data could not be parsed
- * or we run out of memory. We succeeed for "soft"
- * failures, such as not being able to connect to the
- * OCSP responder, or trying to use if the OCSP URI
- * indicates SSL must be used (which we do not
- * support)
- */
- switch (ocsp_verify(err, curr_cert, curr_issuer,
- uri, proxy, cas)) {
- case OCSPMem: /* Ran out of memory */
- case OCSPInternal: /* Some internal error */
- case OCSPVerify: /* OCSP responder indicated fail */
- return (0);
- }
- /* all other cases are success, or soft failures */
- pkgerr_clear(err);
- }
-
- return (ok);
-}
-
-/*
- * Name: get_time_string
- * Description: Generates a human-readable string from an ASN1_GENERALIZED_TIME
- *
- * Arguments: intime - The time to convert
- *
- * Returns : A pointer to a static string representing the passed-in time.
- */
-static char
-*get_time_string(ASN1_GENERALIZEDTIME *intime)
-{
-
- static char time[ATTR_MAX];
- BIO *mem;
- char *p;
-
- if (intime == NULL) {
- return (NULL);
- }
- if ((mem = BIO_new(BIO_s_mem())) == NULL) {
- return (NULL);
- }
-
- if (ASN1_GENERALIZEDTIME_print(mem, intime) == 0) {
- (void) BIO_free(mem);
- return (NULL);
- }
-
- if (BIO_gets(mem, time, ATTR_MAX) <= 0) {
- (void) BIO_free(mem);
- return (NULL);
- }
-
- (void) BIO_free(mem);
-
- /* trim the end of the string */
- for (p = time + strlen(time) - 1; isspace(*p); p--) {
- *p = '\0';
- }
-
- return (time);
-}
-
-/*
- * Name: get_ocsp_uri
- * Description: Examines an X509 certificate and retrieves the embedded
- * OCSP Responder URI if one exists.
- *
- * Arguments: cert - The cert to inspect
- * uri - pointer where the newly-allocated URI is placed, if found
- *
- * Returns : Success if the URI was found. Appropriate status otherwise.
- */
-static boolean_t
-get_ocsp_uri(X509 *cert, char **uri)
-{
- AUTHORITY_INFO_ACCESS *aia;
- ACCESS_DESCRIPTION *ad;
- int i;
-
- if (getenv("PKGWEB_TEST_OCSP")) {
- *uri = xstrdup(getenv("PKGWEB_TEST_OCSP"));
- return (B_TRUE);
- }
-
- /* get the X509v3 extension holding the OCSP URI */
- if ((aia = X509_get_ext_d2i(cert, NID_info_access,
- NULL, NULL)) != NULL) {
- for (i = 0; i < sk_ACCESS_DESCRIPTION_num(aia); i++) {
- ad = sk_ACCESS_DESCRIPTION_value(aia, i);
- if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
- if (ad->location->type == GEN_URI) {
- *uri =
- xstrdup((char *)ASN1_STRING_data(ad->location->d.ia5));
- return (B_TRUE);
- }
- }
- }
- }
-
- /* no URI was found */
- return (B_FALSE);
-}
-
-/*
- * Name: ocsp_verify
- * Description: Attempts to contact an OCSP Responder and ascertain the validity
- * of an X509 certificate.
- *
- * Arguments: err - Error object to add error messages to
- * cert - The cert to validate
- * issuer - The certificate of the issuer of 'cert'
- * uri - The OCSP Responder URI
- * cas - The trusted CA certificates used to verify the
- * signed OCSP response
- * Returns : Success - The OCSP Responder reported a 'good'
- * status for the cert otherwise, appropriate
- * error is returned.
- */
-static OCSPStatus
-ocsp_verify(PKG_ERR *err, X509 *cert, X509 *issuer,
- char *uri, url_hport_t *proxy, STACK_OF(X509) *cas)
-{
- OCSP_CERTID *id;
- OCSP_REQUEST *req;
- OCSP_RESPONSE *resp;
- OCSP_BASICRESP *bs;
- BIO *cbio, *mem;
- char ocspbuf[OCSP_BUFSIZ];
- char *host = NULL, *portstr = NULL, *path = "/", *p, *q, *r;
- int port, status, reason;
- int len, retval, respcode, use_ssl = 0;
- ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
- char *subjname;
- time_t currtime;
- char currtimestr[ATTR_MAX];
- unsigned long errcode;
- const char *err_reason;
-
- subjname = get_subject_display_name(cert);
-
- /* parse the URI into its constituent parts */
- if (OCSP_parse_url(uri, &host, &portstr, &path, &use_ssl) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_PARSE), uri);
- return (OCSPParse);
- }
-
- /* we don't currently support SSL-based OCSP Responders */
- if (use_ssl) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_UNSUP), uri);
- return (OCSPUnsupported);
- }
-
- /* default port if none specified */
- if (portstr == NULL) {
- port = (int)URL_DFLT_SRVR_PORT;
- } else {
- port = (int)strtoul(portstr, &r, 10);
- if (*r != '\0') {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_PARSE), uri);
- return (OCSPParse);
- }
- }
-
- /* allocate new request structure */
- if ((req = OCSP_REQUEST_new()) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_MEM));
- return (OCSPMem);
- }
-
- /* convert cert and issuer fields into OCSP request data */
- if ((id = OCSP_cert_to_id(NULL, cert, issuer)) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_PKG_INTERNAL),
- __FILE__, __LINE__);
- return (OCSPInternal);
- }
-
- /* fill out request structure with request data */
- if ((OCSP_request_add0_id(req, id)) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_PKG_INTERNAL),
- __FILE__, __LINE__);
- return (OCSPInternal);
- }
-
- /* add nonce */
- (void) OCSP_request_add1_nonce(req, NULL, -1);
-
- /* connect to host, or proxy */
- if (proxy != NULL) {
- if ((cbio = BIO_new_connect(proxy->hostname)) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_MEM));
- return (OCSPMem);
- }
-
- /*
- * BIO_set_conn_int_port takes an int *, so let's give it one
- * rather than an ushort_t *
- */
- port = proxy->port;
- (void) BIO_set_conn_int_port(cbio, &port);
- if (BIO_do_connect(cbio) <= 0) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_CONNECT),
- proxy->hostname, port);
- return (OCSPConnect);
- }
- } else {
- if ((cbio = BIO_new_connect(host)) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_MEM));
- return (OCSPMem);
- }
-
- (void) BIO_set_conn_int_port(cbio, &port);
- if (BIO_do_connect(cbio) <= 0) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_CONNECT),
- host, port);
- return (OCSPConnect);
- }
- }
-
- /* calculate length of binary request data */
- len = i2d_OCSP_REQUEST(req, NULL);
-
- /* send the request headers */
- if (proxy != NULL) {
- retval = BIO_printf(cbio, OCSP_REQUEST_FORMAT, uri, len);
- } else {
- retval = BIO_printf(cbio, OCSP_REQUEST_FORMAT, path, len);
- }
-
- if (retval <= 0) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_SEND), host);
- return (OCSPRequest);
- }
-
- /* send the request binary data */
- if (i2d_OCSP_REQUEST_bio(cbio, req) <= 0) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_SEND), host);
- return (OCSPRequest);
- }
-
- /*
- * read the response into a memory BIO, so we can 'gets'
- * (socket bio's don't support BIO_gets)
- */
- if ((mem = BIO_new(BIO_s_mem())) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_MEM));
- return (OCSPMem);
- }
-
- while ((len = BIO_read(cbio, ocspbuf, OCSP_BUFSIZ))) {
- if (len < 0) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_READ), host);
- return (OCSPRequest);
- }
- if (BIO_write(mem, ocspbuf, len) != len) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_MEM));
- return (OCSPMem);
- }
- }
-
- /* now get the first line of the response */
- if (BIO_gets(mem, ocspbuf, OCSP_BUFSIZ) <= 0) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_RESP_PARSE));
- return (OCSPRequest);
- }
-
- /* parse the header response */
- /* it should look like "HTTP/x.x 200 OK" */
-
- /* skip past the protocol info */
- for (p = ocspbuf; (*p != '\0') && !isspace(*p); p++)
- continue;
-
- /* skip past whitespace betwen protocol and start of response code */
- while ((*p != '\0') && isspace(*p)) {
- p++;
- }
-
- if (*p == '\0') {
- /* premature end */
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_RESP_PARSE), ocspbuf);
- return (OCSPRequest);
- }
-
- /* find end of response code */
- for (q = p; (*q != NULL) && !isspace(*q); q++)
- continue;
-
- /* mark end of response code */
- *q++ = '\0';
-
- /* parse response code */
- respcode = strtoul(p, &r, 10);
- if (*r != '\0') {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_RESP_PARSE), ocspbuf);
- return (OCSPRequest);
- }
-
- /* now find beginning of the response string */
- while ((*q != NULL) && isspace(*q)) {
- q++;
- }
-
- /* trim whitespace from end of message */
- for (r = (q + strlen(q) - 1); isspace(*r); r--) {
- *r = '\0';
- }
-
- /* response must be OK */
- if (respcode != 200) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_RESP_NOTOK), 200,
- respcode, q);
- return (OCSPRequest);
- }
-
- /* read headers, looking for content-type or a blank line */
- while (BIO_gets(mem, ocspbuf, OCSP_BUFSIZ) > 0) {
-
- /* if we get a content type, make sure it's the right type */
- if (ci_strneq(ocspbuf, CONTENT_TYPE_HDR,
- strlen(CONTENT_TYPE_HDR))) {
-
- /* look for the delimiting : */
- p = strchr(ocspbuf + strlen(CONTENT_TYPE_HDR), ':');
-
- if (p == NULL) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_RESP_PARSE), ocspbuf);
- return (OCSPResponder);
- }
-
- /* skip over ':' */
- p++;
-
- /* find beginning of the content type */
- while ((*p != NULL) && isspace(*p)) {
- p++;
- }
-
- if (!ci_strneq(p, CONTENT_OCSP_RESP,
- strlen(CONTENT_OCSP_RESP))) {
- /* response is not right type */
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_RESP_TYPE),
- p, CONTENT_OCSP_RESP);
- return (OCSPResponder);
- }
-
- /* continue with next header line */
- continue;
- }
-
- /* scan looking for a character */
- for (p = ocspbuf; (*p != '\0') && isspace(*p); p++) {
- continue;
- }
- /*
- * if we got to the end of the line with
- * no chars, then this is a blank line
- */
- if (*p == '\0') {
- break;
- }
- }
-
-
- if (*p != '\0') {
- /* last line was not blank */
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_RESP_PARSE), ocspbuf);
- return (OCSPResponder);
- }
-
- /* now read in the binary response */
- if ((resp = d2i_OCSP_RESPONSE_bio(mem, NULL)) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_READ), host);
- return (OCSPResponder);
- }
-
- /* free temp BIOs */
- (void) BIO_free(mem);
- (void) BIO_free_all(cbio);
- cbio = NULL;
-
- /* make sure request was successful */
- if (OCSP_response_status(resp) != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_RESP_NOTOK),
- OCSP_RESPONSE_STATUS_SUCCESSFUL,
- OCSP_response_status(resp),
- OCSP_response_status_str(OCSP_response_status(resp)));
- return (OCSPResponder);
- }
-
- /* parse binary response into internal structure */
- if ((bs = OCSP_response_get1_basic(resp)) == NULL) {
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_READ), host);
- return (OCSPParse);
- }
-
- /*
- * From here to the end of the code, the return values
- * should be hard failures
- */
-
- /* verify the response, warn if no nonce */
- if (OCSP_check_nonce(req, bs) <= 0) {
- logerr(pkg_gt(WRN_OCSP_RESP_NONCE));
- }
-
- if (OCSP_basic_verify(bs, cas, NULL, OCSP_TRUSTOTHER) <= 0) {
- while ((errcode = ERR_get_error()) != NULL) {
- err_reason = ERR_reason_error_string(errcode);
- if (err_reason == NULL) {
- err_reason =
- gettext(ERR_SIG_INT);
- }
- pkgerr_add(err, PKGERR_PARSE, (char *)err_reason);
- }
- pkgerr_add(err, PKGERR_PARSE, gettext(ERR_OCSP_VERIFY_FAIL),
- uri);
- return (OCSPVerify);
- }
-
- /* check the validity of our certificate */
- if (OCSP_resp_find_status(bs, id, &status, &reason,
- &rev, &thisupd, &nextupd) == NULL) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_VERIFY_NO_STATUS), subjname);
- return (OCSPVerify);
- }
-
- if ((currtime = time(NULL)) == (time_t)-1) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_VERIFY_NOTIME));
- return (OCSPVerify);
- }
-
- (void) strlcpy(currtimestr, ctime(&currtime), ATTR_MAX);
-
- /* trim end */
- for (r = currtimestr + strlen(currtimestr) - 1;
- isspace(*r); r--) {
- *r = '\0';
- }
-
- if (!OCSP_check_validity(thisupd, nextupd,
- OCSP_VALIDITY_PERIOD, -1)) {
- if (nextupd != NULL) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_VERIFY_VALIDITY),
- get_time_string(thisupd), get_time_string(nextupd),
- currtimestr);
- } else {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_VERIFY_VALIDITY),
- get_time_string(thisupd),
- currtimestr);
- }
- return (OCSPVerify);
- }
-
- if (status != V_OCSP_CERTSTATUS_GOOD) {
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_OCSP_VERIFY_STATUS), subjname,
- OCSP_cert_status_str(status));
- return (OCSPVerify);
- }
-
- /* everythign checks out */
- return (OCSPSuccess);
-}
-
-/*
- * Name: get_issuer
- * Description: Attempts to find the issuing certificate for a given certificate
- * This will look in both the list of trusted certificates found in
- * the X509_STORE_CTX structure, as well as the list of untrusted
- * chain certificates found in the X509_STORE_CTX structure.
- * Arguments:
- * issuer - The resulting issuer cert is placed here, if found
- * ctx - The current verification context
- * x - The certificate whose issuer we are looking for
- * Returns : Success - The issuer cert was found and placed in *issuer.
- * otherwise, appropriate error is returned.
- */
-static int
-get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
-{
- int i, ok;
-
- /*
- * first look in the list of trusted
- * certs, using the context's method to do so
- */
- if ((ok = ctx->get_issuer(issuer, ctx, x)) > 0) {
- return (ok);
- }
-
- if (ctx->untrusted != NULL) {
- /* didn't find it in trusted certs, look through untrusted */
- for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
- if (X509_check_issued(sk_X509_value(ctx->untrusted, i),
- x) == X509_V_OK) {
- *issuer = sk_X509_value(ctx->untrusted, i);
- return (1);
- }
- }
- }
- *issuer = NULL;
- return (0);
-}
-
-/*
- * Name: parse_url_proxy
- * Description: Parses URL and optional proxy specification, populates static
- * 'ps' structure
- *
- * Arguments: err - where to record any errors.
- * url - URL to parse
- * proxy - proxy to parse, or NULL for no proxy
- * proxy_port - Default proxy port to use if no proxy
- * port specified in 'proxy'
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- * on success, 'ps->url' and 'ps->proxy' are populated
- * with parsed data.
- */
-static boolean_t
-parse_url_proxy(PKG_ERR *err, char *url, char *proxy, ushort_t proxy_port)
-{
- boolean_t ret = B_TRUE;
- if (!path_valid(url)) {
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (url_parse(url, &ps->url) != URL_PARSE_SUCCESS) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_PARSE_URL), url);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (proxy != NULL) {
- if (url_parse_hostport(proxy, &ps->proxy, proxy_port)
- != URL_PARSE_SUCCESS) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_BAD_PROXY), proxy);
- ret = B_FALSE;
- goto cleanup;
- }
- }
-
-cleanup:
- return (ret);
-}
-
-/*
- * Name: web_setup
- * Description: Initializes http library settings
- *
- * Arguments: err - where to record any errors.
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- */
-static boolean_t
-web_setup(PKG_ERR *err)
-{
- boolean_t ret = B_TRUE;
- static boolean_t keepalive = B_TRUE;
-
- if ((ps->hps = http_srv_init(&ps->url)) == NULL) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_INIT_SESS), ps->url);
- ret = B_FALSE;
- goto cleanup;
- }
-
- if (getenv("WEBPKG_DEBUG") != NULL) {
- http_set_verbose(B_TRUE);
- }
-
- if (ps->proxy.hostname[0] != '\0' &&
- http_set_proxy(ps->hps, &ps->proxy) != 0) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_INIT_SESS), ps->url);
- ret = B_FALSE;
- goto cleanup;
- }
- if (http_set_keepalive(ps->hps, keepalive) != 0) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_INIT_SESS), ps->url);
- ret = B_FALSE;
- goto cleanup;
- }
- if (http_set_socket_read_timeout(ps->hps, ps->timeout) != 0) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_INIT_SESS), ps->url);
- ret = B_FALSE;
- goto cleanup;
- }
- if (http_set_random_file(ps->hps, RANDOM) != 0) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_INIT_SESS), ps->url);
- ret = B_FALSE;
- goto cleanup;
- }
-
- (void) http_set_p12_format(B_TRUE);
-
-cleanup:
- return (ret);
-}
-
-/*
- * Name: web_connect
- * Description: Makes connection with URL stored in static 'ps' structure.
- *
- * Arguments: err - where to record any errors.
- *
- * Returns : WEB_OK - connection successful
- * WEB_VERIFY_SETUP - Unable to complete necessary
- * SSL setup
- * WEB_CONNREFUSED - Connection was refused to web site
- * WEB_HOSTDOWN - Host was not responding to request
- * WEB_NOCONNECT - Some other connection failure
- */
-static WebStatus
-web_connect(PKG_ERR *err)
-{
- STACK_OF(X509) *sec_cas = NULL;
- char *path;
- WebStatus ret = WEB_OK;
- ulong_t errcode;
- uint_t errsrc;
- int my_errno = 0;
- const char *libhttperr = NULL;
-
- if (ps->url.https == B_TRUE) {
- /* get CA certificates */
- if (find_ca_certs(err, ps->keystore, &sec_cas) != 0) {
- ret = WEB_VERIFY_SETUP;
- goto cleanup;
- }
-
- if (sk_X509_num(sec_cas) < 1) {
- /* no trusted websites */
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_KEYSTORE_NOTRUST));
- ret = WEB_VERIFY_SETUP;
- goto cleanup;
- }
-
- /*
- * write out all CA certs to temp file. libwanboot should
- * have an interface for giving it a list of trusted certs
- * through an in-memory structure, but currently that does
- * not exist
- */
- if ((path = write_ca_file(err, ps->dwnld_dir, sec_cas,
- WEB_CA_PHRASE)) == NULL) {
- ret = WEB_VERIFY_SETUP;
- goto cleanup;
- }
-
- ps->certfile = path;
- if (http_set_password(ps->hps, WEB_CA_PHRASE) != 0) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_HTTPS_PASSWD));
- ret = WEB_VERIFY_SETUP;
- goto cleanup;
- }
-
- if (http_set_certificate_authority_file(path) != 0) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_HTTPS_CA));
- ret = WEB_VERIFY_SETUP;
- goto cleanup;
- }
- }
-
- if (http_srv_connect(ps->hps) != 0) {
- while ((errcode = http_get_lasterr(ps->hps, &errsrc)) != 0) {
- /* Have an error - is it EINTR? */
- if (errsrc == ERRSRC_SYSTEM) {
- my_errno = errcode;
- break;
- } else if (libhttperr == NULL) {
- /* save the first non-system error message */
- libhttperr = http_errorstr(errsrc, errcode);
- }
- }
- switch (my_errno) {
- case EINTR:
- case ETIMEDOUT:
- /* Timed out. Try, try again */
- ret = WEB_TIMEOUT;
- break;
- case ECONNREFUSED:
- ret = WEB_CONNREFUSED;
- break;
- case EHOSTDOWN:
- ret = WEB_HOSTDOWN;
- break;
- default:
- /* some other fatal error */
- ret = WEB_NOCONNECT;
- if (libhttperr == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_INIT_CONN),
- ps->url.hport.hostname);
- } else {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_HTTP), libhttperr);
- }
- break;
- }
- }
-cleanup:
- return (ret);
-}
-
-/*
- * Name: write_ca_file
- * Description: Writes out a PKCS12 file containing all trusted certs
- * found in keystore recorded in static 'ps' structure
- *
- * This routine is used because the libwanboot library's
- * HTTPS routines cannot accept trusted certificates
- * through an in-memory structure, when initiating an
- * SSL connection. They must be in a PKCS12, which is
- * admittedly a poor interface.
- *
- * Arguments: err - where to record any errors.
- * tmpdir - Directory to write certificate file in
- * cacerts - Certs to write out
- * passwd - password used to encrypt certs
- *
- * Returns : path to resulting file, if successfullly written,
- * otherwise NULL.
- */
-static char
-*write_ca_file(PKG_ERR *err, char *tmpdir, STACK_OF(X509) *cacerts,
- char *passwd)
-{
- int fd, len;
- FILE *fp;
- PKCS12 *p12 = NULL;
- char *ret = NULL;
- static char tmp_file[PATH_MAX] = "";
- struct stat buf;
-
- if (!path_valid(tmpdir)) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTEMP), tmpdir);
- goto cleanup;
- }
-
- /* mkstemp replaces XXXXXX with a unique string */
- if (((len = snprintf(tmp_file, PATH_MAX, "%s/%sXXXXXX", tmpdir,
- "cert")) < 0) ||
- (len >= PATH_MAX)) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTEMP), tmpdir);
- goto cleanup;
- }
-
- if ((fd = mkstemp(tmp_file)) == -1) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTMPFIL), tmp_file);
- goto cleanup;
- }
-
- if (fstat(fd, &buf) == -1) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTMPFIL), tmp_file);
- goto cleanup;
- }
-
- if (!S_ISREG(buf.st_mode)) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTMPFIL), tmp_file);
- goto cleanup;
- }
-
- if ((fp = fdopen(fd, "w")) == NULL) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTMPFIL), tmp_file);
- goto cleanup;
- }
-
- if ((p12 = sunw_PKCS12_create(passwd, NULL, NULL, cacerts)) == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_KEYSTORE_FORM), tmp_file);
- goto cleanup;
- }
-
- if (i2d_PKCS12_fp(fp, p12) == 0) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_KEYSTORE_FORM), tmp_file);
- goto cleanup;
- }
-
- (void) fflush(fp);
- (void) fclose(fp);
- (void) close(fd);
- fp = NULL;
- fd = -1;
- ret = tmp_file;
-
-cleanup:
- if (p12 != NULL)
- PKCS12_free(p12);
- if (fp != NULL)
- (void) fclose(fp);
- if (fd != -1) {
- (void) close(fd);
- (void) unlink(tmp_file);
- }
-
- return (ret);
-}
-
-/*
- * Name: web_send_request
- * Description: Sends an HTTP request for a file to the
- * web server being communicated with in the static
- * 'ps' structure
- *
- * Arguments: err - where to record any errors.
- * request_type - HTTP_REQ_TYPE_HEAD to send an HTTP HEAD request,
- * or HTTP_REQ_TYPE_GET to send an HTTP GET request
- * cp -
- * Returns : WEB_OK - request sent successfully
- * WEB_CONNREFUSED - Connection was refused to web site
- * WEB_HOSTDOWN - Host was not responding to request
- * WEB_NOCONNECT - Some other connection failure
- */
-static WebStatus
-web_send_request(PKG_ERR *err, int request_type, int cp, int ep)
-{
- WebStatus ret = WEB_OK;
- ulong_t errcode;
- uint_t errsrc;
- int my_errno = 0;
- const char *libhttperr = NULL;
- switch (request_type) {
- case HTTP_REQ_TYPE_HEAD:
- if ((http_head_request(ps->hps, ps->url.abspath)) != 0) {
- while ((errcode = http_get_lasterr(ps->hps,
- &errsrc)) != 0) {
- /* Have an error - is it EINTR? */
- if (errsrc == ERRSRC_SYSTEM) {
- my_errno = errcode;
- break;
- } else if (libhttperr == NULL) {
- /* save first non-system error message */
- libhttperr =
- http_errorstr(errsrc, errcode);
- }
- }
- switch (my_errno) {
- case EINTR:
- case ETIMEDOUT:
- /* Timed out. Try, try again */
- ret = WEB_TIMEOUT;
- break;
- case ECONNREFUSED:
- ret = WEB_CONNREFUSED;
- break;
- case EHOSTDOWN:
- ret = WEB_HOSTDOWN;
- break;
- default:
- /* some other fatal error */
- ret = WEB_NOCONNECT;
- if (libhttperr == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_INIT_CONN),
- ps->url.hport.hostname);
- } else {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_HTTP), libhttperr);
- }
- break;
- }
- goto cleanup;
- }
- break;
-
- case HTTP_REQ_TYPE_GET:
- if (cp && ep) {
- if (http_get_range_request(ps->hps, ps->url.abspath,
- cp, ep - cp) != 0) {
- while ((errcode = http_get_lasterr(ps->hps,
- &errsrc)) != 0) {
- /* Have an error - is it EINTR? */
- if (errsrc == ERRSRC_SYSTEM) {
- my_errno = errcode;
- break;
- } else {
- /*
- * save first non-system
- * error message
- */
- libhttperr =
- http_errorstr(errsrc,
- errcode);
- }
- }
- switch (my_errno) {
- case EINTR:
- case ETIMEDOUT:
- /* Timed out. Try, try again */
- ret = WEB_TIMEOUT;
- break;
- case ECONNREFUSED:
- ret = WEB_CONNREFUSED;
- break;
- case EHOSTDOWN:
- ret = WEB_HOSTDOWN;
- break;
- default:
- /* some other fatal error */
- ret = WEB_NOCONNECT;
- if (libhttperr == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_INIT_CONN),
- ps->url.hport.hostname);
- } else {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_HTTP),
- libhttperr);
- }
- break;
- }
- goto cleanup;
- }
-
- if (!web_eval_headers(err)) {
- ret = WEB_NOCONNECT;
- goto cleanup;
- }
- } else {
- if ((http_get_request(ps->hps, ps->url.abspath))
- != 0) {
- while ((errcode = http_get_lasterr(ps->hps,
- &errsrc)) != 0) {
- /* Have an error - is it EINTR? */
- if (errsrc == ERRSRC_SYSTEM) {
- my_errno = errcode;
- break;
- } else {
- /*
- * save the first non-system
- * error message
- */
- libhttperr =
- http_errorstr(errsrc,
- errcode);
- }
- }
- switch (my_errno) {
- case EINTR:
- case ETIMEDOUT:
- /* Timed out. Try, try again */
- ret = WEB_TIMEOUT;
- break;
- case ECONNREFUSED:
- ret = WEB_CONNREFUSED;
- break;
- case EHOSTDOWN:
- ret = WEB_HOSTDOWN;
- break;
- default:
- /* some other fatal error */
- ret = WEB_NOCONNECT;
- if (libhttperr == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_INIT_CONN),
- ps->url.hport.hostname);
- } else {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_HTTP),
- libhttperr);
- }
- break;
- }
- goto cleanup;
- }
-
- if (!web_eval_headers(err)) {
- ret = WEB_NOCONNECT;
- goto cleanup;
- }
- }
- break;
- default:
- pkgerr_add(err, PKGERR_INTERNAL, gettext(ERR_PKG_INTERNAL),
- __FILE__, __LINE__);
- }
-
-cleanup:
- return (ret);
-}
-
-/*
- * Name: web_eval_headers
- * Description: Evaluates HTTP headers returned during an HTTP request.
- * This must be called before calling
- * http_get_header_value().
- *
- * Arguments: err - where to record any errors.
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- */
-static boolean_t
-web_eval_headers(PKG_ERR *err)
-{
- const char *http_err;
- ulong_t herr;
- uint_t errsrc;
-
- if (http_process_headers(ps->hps, &ps->resp) != 0) {
- if ((ps->resp != NULL) && (ps->resp->statusmsg != NULL)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_HTTP),
- ps->resp->statusmsg);
- }
-
- herr = http_get_lasterr(ps->hps, &errsrc);
- http_err = http_errorstr(errsrc, herr);
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_HTTP),
- http_err);
- return (B_FALSE);
- }
- return (B_TRUE);
-}
-
-/*
- * Name: web_get_file
- * Description: Downloads the file URL from the website, all of
- * which are recorded in the static 'ps' struct
- *
- * Arguments: err - where to record any errors.
- * dwnld_dir - Directory to download file into
- * device - Where to store path to resulting
- * file
- * nointeract - if non-zero, do not output
- * progress
- * fname - name of downloaded file link in the dwnld_dir
- *
- * Returns : WEB_OK - download successful
- * WEB_CONNREFUSED - Connection was refused to web site
- * WEB_HOSTDOWN - Host was not responding to request
- * WEB_GET_FAIL - Unable to initialize download
- * state (temp file creation, header parsing, etc)
- * WEB_NOCONNECT - Some other connection failure
- */
-static WebStatus
-web_get_file(PKG_ERR *err, char *dwnld_dir, int nointeract, char **fname)
-{
- int i, fd;
- int n = 0;
- ulong_t abs_pos = 0;
- char *head_val = NULL;
- char *lastmod_val = NULL;
- char *bname = NULL;
- struct stat status;
- WebStatus ret = WEB_OK;
- WebStatus req_ret;
- ulong_t errcode;
- uint_t errsrc;
- int my_errno = 0;
- const char *libhttperr = NULL;
- char *disp;
- char tmp_file[PATH_MAX];
- int len;
-
- ps->data.prev_cont_length =
- ps->data.content_length =
- ps->data.cur_pos = 0;
-
- if ((head_val = http_get_header_value(ps->hps,
- CONTENT_LENGTH_HDR)) != NULL) {
- ps->data.content_length = atol(head_val);
- } else {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_NO_HEAD_VAL),
- CONTENT_LENGTH_HDR);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
-
- free(head_val);
- head_val = NULL;
-
- if ((head_val = http_get_header_value(ps->hps,
- CONTENT_DISPOSITION_HDR)) != NULL) {
- /* "inline; parm=val; parm=val */
- if ((disp = strtok(head_val, "; \t\n\f\r")) != NULL) {
- /* disp = "inline" */
- while ((disp = strtok(NULL, "; \t\n\f\r")) != NULL) {
- /* disp = "parm=val" */
- if (ci_strneq(disp, "filename=", 9)) {
- bname = xstrdup(basename(disp + 9));
- trim(bname);
- dequote(bname);
- }
- }
- }
- free(head_val);
- head_val = NULL;
- }
-
- if (bname == NULL) {
- /*
- * couldn't determine filename from header value,
- * so take basename of URL
- */
- if ((bname = get_endof_string(ps->url.abspath, '/')) == NULL) {
- /* URL is bad */
- pkgerr_add(err, PKGERR_PARSE,
- gettext(ERR_PARSE_URL), ps->url.abspath);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
- }
-
- *fname = bname;
-
- if ((head_val = http_get_header_value(ps->hps, LAST_MODIFIED_HDR))
- != NULL) {
-
- if ((lastmod_val = condense_lastmodified(head_val)) == NULL) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_BAD_HEAD_VAL),
- LAST_MODIFIED_HDR, head_val);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
- free(head_val);
- head_val = NULL;
-
- if ((ps->uniqfile = get_unique_filename(dwnld_dir,
- lastmod_val)) == NULL) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_OPEN_TMP));
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
-
- free(lastmod_val);
- lastmod_val = NULL;
-
- if ((fd = open(ps->uniqfile,
- O_NONBLOCK|O_RDWR|O_APPEND|O_CREAT|O_EXCL,
- 640)) == -1) {
-
- /*
- * A partial downloaded file
- * already exists, so open it.
- */
- if ((fd = open(ps->uniqfile,
- O_NONBLOCK|O_RDWR|O_APPEND)) != -1) {
- if (fstat(fd, &status) == -1 ||
- !S_ISREG(status.st_mode)) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_DWNLD_NO_CONT),
- ps->uniqfile);
- ret = WEB_GET_FAIL;
- goto cleanup;
- } else {
- echo_out(nointeract,
- gettext(MSG_DWNLD_PART),
- ps->uniqfile,
- status.st_size);
- ps->data.prev_cont_length =
- status.st_size;
- }
- } else {
- /* unable to open partial file */
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_DWNLD_NO_CONT),
- ps->uniqfile);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
- }
- } else {
- /*
- * no "Last-Modified" header, so this file is not eligible for
- * spooling and "resuming last download" operations
- */
- ps->spool = B_FALSE;
-
- /* mkstemp replaces XXXXXX with a unique string */
- if (((len = snprintf(tmp_file, PATH_MAX,
- "%s/%sXXXXXX", dwnld_dir, "stream")) < 0) ||
- (len >= PATH_MAX)) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(MSG_NOTEMP), dwnld_dir);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
-
- if ((fd = mkstemp(tmp_file)) == -1) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(MSG_NOTMPFIL), tmp_file);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
-
- if (fstat(fd, &status) == -1 ||
- !S_ISREG(status.st_mode)) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_DWNLD_NO_CONT),
- ps->uniqfile);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
-
- ps->data.prev_cont_length = 0;
- ps->uniqfile = xstrdup(tmp_file);
- }
-
- /* File has already been completely downloaded */
- if (ps->data.prev_cont_length == ps->data.content_length) {
- echo_out(nointeract, gettext(MSG_DWNLD_PREV), ps->uniqfile);
- ps->data.cur_pos = ps->data.prev_cont_length;
- if (!make_link(dwnld_dir, bname)) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTEMP),
- dwnld_dir);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
- /* we're done, so cleanup and return success */
- goto cleanup;
- } else if (ps->data.prev_cont_length != 0) {
- ps->data.cur_pos = ps->data.prev_cont_length;
- }
-
- if (!ck_dwnld_dir_space(err, dwnld_dir,
- (ps->data.prev_cont_length != 0) ?
- (ps->data.content_length - ps->data.cur_pos) :
- ps->data.content_length)) {
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
-
- if ((req_ret = web_send_request(err, HTTP_REQ_TYPE_GET,
- ps->data.cur_pos, ps->data.content_length)) != WEB_OK) {
- ret = req_ret;
- goto cleanup;
- }
-
- if (ps->data.prev_cont_length != 0)
- echo_out(nointeract, gettext(MSG_DWNLD_CONT));
- else
- echo_out(nointeract, gettext(MSG_DWNLD));
-
- progress_setup(nointeract, ps->data.content_length);
-
- /* Download the file a BLOCK at a time */
- while (ps->data.cur_pos < ps->data.content_length) {
- progress_report(nointeract, abs_pos);
- i = ((ps->data.content_length - ps->data.cur_pos) < BLOCK) ?
- (ps->data.content_length - ps->data.cur_pos)
- : BLOCK;
- if ((n = http_read_body(ps->hps, ps->content, i)) <= 0) {
- while ((errcode = http_get_lasterr(ps->hps,
- &errsrc)) != 0) {
- /* Have an error - is it EINTR? */
- if (errsrc == ERRSRC_SYSTEM) {
- my_errno = errcode;
- break;
- } else {
- /*
- * save first non-system
- * error message
- */
- libhttperr =
- http_errorstr(errsrc, errcode);
- }
- }
- switch (my_errno) {
- case EINTR:
- case ETIMEDOUT:
- /* Timed out. Try, try again */
- ret = WEB_TIMEOUT;
- break;
- case ECONNREFUSED:
- ret = WEB_CONNREFUSED;
- break;
- case EHOSTDOWN:
- ret = WEB_HOSTDOWN;
- break;
- default:
- /* some other fatal error */
- ret = WEB_NOCONNECT;
- if (libhttperr == NULL) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_INIT_CONN),
- ps->url.hport.hostname);
- } else {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_HTTP), libhttperr);
- }
- break;
- }
- goto cleanup;
- }
- if ((n = write(fd, ps->content, n)) == 0) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_WRITE),
- ps->uniqfile, strerror(errno));
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
- ps->data.cur_pos += n;
- abs_pos += n;
- }
-
- progress_finish(nointeract);
- echo_out(nointeract, gettext(MSG_DWNLD_COMPLETE));
-
- if (!make_link(dwnld_dir, bname)) {
- pkgerr_add(err, PKGERR_WEB, gettext(MSG_NOTEMP),
- dwnld_dir);
- ret = WEB_GET_FAIL;
- goto cleanup;
- }
-
-cleanup:
- sync();
- if (fd != -1) {
- (void) close(fd);
- }
-
- if (head_val != NULL)
- free(head_val);
-
- if (lastmod_val != NULL)
- free(lastmod_val);
-
- return (ret);
-}
-
-/*
- * Name: make_link
- * Description: Create new link to file being downloaded
- *
- * Arguments: dwnld_dir - directory in which downloaded file exists
- * bname - name of link
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- */
-static boolean_t
-make_link(char *dwnld_dir, char *bname)
-{
- int len;
-
- if ((ps->link = (char *)xmalloc(PATH_MAX)) == NULL)
- return (B_FALSE);
- if (((len = snprintf(ps->link, PATH_MAX, "%s/%s",
- dwnld_dir, bname)) < 0) ||
- len >= PATH_MAX)
- return (B_FALSE);
-
- (void) link(ps->uniqfile, ps->link);
-
- return (B_TRUE);
-}
-
-/*
- * Name: get_startof_string
- * Description: searches string for token, returns a newly-allocated
- * substring of the given string up to, but not
- * including, token. for example
- * get_startof_string("abcd", 'c') will return "ab"
- *
- * Arguments: path - path to split
- * token - character to split on
- *
- * Returns : substring of 'path', up to, but not including,
- * token, if token appears in path. Otherwise,
- * returns NULL.
- */
-char *
-get_startof_string(char *path, char token)
-{
- char *p, *p2;
-
- if (path == NULL)
- return (NULL);
-
- p = xstrdup(path);
-
- p2 = strchr(p, token);
- if (p2 == NULL) {
- free(p);
- return (NULL);
- } else {
- *p2 = '\0';
- return (p);
- }
-}
-
-/*
- * Name: get_endof_string
- * Description: searches string for token, returns a
- * newly-allocated substring of the given string,
- * starting at character following token, to end of
- * string.
- *
- * for example get_end_string("abcd", 'c')
- * will return "d"
- *
- * Arguments: path - path to split
- * token - character to split on
- *
- * Returns : substring of 'path', beginning at character
- * following token, to end of string, if
- * token appears in path. Otherwise,
- * returns NULL.
- */
-char *
-get_endof_string(char *path, char token)
-{
- char *p, *p2;
-
- if (path == NULL)
- return (NULL);
-
- p = xstrdup(path);
-
- if ((p2 = strrchr(p, token)) == NULL) {
- return (NULL);
- }
-
- return (p2 + 1);
-}
-
-/*
- * Name: progress_setup
- * Description: Initialize session for reporting progress
- *
- * Arguments: nointeract - if non-zero, do not do anything
- * ulong_t - size of job to report progress for
- *
- * Returns : none
- */
-static void
-progress_setup(int nointeract, ulong_t size_of_load)
-{
- ulong_t divisor;
- ulong_t term_width = TERM_WIDTH;
-
- if (nointeract)
- return;
-
- if (size_of_load > MED_DWNLD && size_of_load < LARGE_DWNLD)
- divisor = MED_DIVISOR;
- else if (size_of_load > LARGE_DWNLD) {
- term_width = TERM_WIDTH - 8;
- divisor = LARGE_DIVISOR;
- } else
- divisor = SMALL_DIVISOR;
-
- const_increment = size_of_load / term_width;
- const_divider = size_of_load / divisor;
- const_completed = 100 / divisor;
-}
-
-/*
- * Name: progress_report
- * Description: Report progress for current progress context,
- * to stderr
- *
- * Arguments: nointeract - if non-zero, do not do anything
- * position - how far along in the job to report.
- * This should be <= size used during progress_setup
- *
- * Returns : none
- */
-static void
-progress_report(int nointeract, ulong_t position)
-{
- static ulong_t increment;
- static ulong_t divider;
-
- if (nointeract)
- return;
-
- if (position == 0) {
- increment = const_increment;
- divider = const_divider;
- }
- if (position > increment && position < divider) {
- (void) putc('.', stderr);
- increment += const_increment;
- } else if (position > divider) {
- completed += const_completed;
- (void) fprintf(stderr, "%ld%c", completed, '%');
- increment += const_increment;
- divider += const_divider;
- }
-}
-
-/*
- * Name: progress_finish
- * Description: Finalize session for reporting progress.
- * "100%" is reported to screen
- *
- * Arguments: nointeract - if non-zero, do not do anything
- *
- * Returns : none
- */
-static void
-progress_finish(int nointeract)
-{
- if (nointeract)
- return;
-
- (void) fprintf(stderr, "%d%c\n", 100, '%');
-}
-
-/*
- * Name: init_session
- * Description: Initializes static 'ps' structure with default
- * values
- *
- * Arguments: none
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- */
-static boolean_t
-init_session(void)
-{
- if ((ps = (WEB_SESSION *)
- xmalloc(sizeof (WEB_SESSION))) == NULL) {
- return (B_FALSE);
- }
- (void) memset(ps, 0, sizeof (*ps));
-
- if ((ps->content = (char *)xmalloc(BLOCK)) == NULL) {
- return (B_FALSE);
- }
-
- (void) memset(ps->content, 0, BLOCK);
-
- ps->data.cur_pos = 0UL;
- ps->data.content_length = 0UL;
- ps->url.https = B_FALSE;
- ps->uniqfile = NULL;
- ps->link = NULL;
- ps->dwnld_dir = NULL;
- ps->spool = B_TRUE;
- ps->errstr = NULL;
- ps->keystore = NULL;
-
- return (B_TRUE);
-}
-
-/*
- * Name: ck_downld_dir_space
- * Description: Verify enough space exists in directory to hold file
- *
- * Arguments: err - where to record any errors.
- * dwnld_dir - Directory to check available space in
- * bytes_needed - How many bytes are need
- *
- * Returns : B_TRUE - enough space exists in dwnld_dir to hold
- * bytes_needed bytes, otherwise B_FALSE
- */
-static boolean_t
-ck_dwnld_dir_space(PKG_ERR *err, char *dwnld_dir, ulong_t bytes_needed)
-{
- u_longlong_t bytes_avail;
- u_longlong_t block_pad;
- struct statvfs64 status;
-
- if (statvfs64(dwnld_dir, &status)) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_TMPDIR), dwnld_dir);
- return (B_FALSE);
- }
-
- block_pad = (status.f_frsize ? status.f_frsize : status.f_bsize);
- bytes_avail = status.f_bavail * block_pad;
-
- if ((((u_longlong_t)bytes_needed) + block_pad) > bytes_avail) {
- pkgerr_add(err, PKGERR_WEB, gettext(ERR_DISK_SPACE),
- dwnld_dir,
- (((u_longlong_t)bytes_needed) + block_pad) / 1024ULL,
- bytes_avail / 1024ULL);
- return (B_FALSE);
- }
-
- return (B_TRUE);
-}
-
-/*
- * Description:
- * This function returns a unique file name based on the parts of the
- * URI. This is done to enable partially downloaded files to be resumed.
- * Arguments:
- * dir - The directory that should contain the filename.
- * last_modified - A string representing the date of last modification,
- * used as part of generating unique name
- * Returns:
- * A valid filename or NULL.
- */
-
-static char *
-get_unique_filename(char *dir, char *last_modified)
-{
- char *buf, *buf2, *beg_str;
- int len;
-
- if ((buf = (char *)xmalloc(PATH_MAX)) == NULL) {
- return (NULL);
- }
- if ((buf2 = (char *)xmalloc(PATH_MAX)) == NULL) {
- return (NULL);
- }
-
- /* prepare strings for being cat'ed onto */
- buf[0] = buf2[0] = '\0';
- /*
- * No validation of the path is done here. We just construct the path
- * and it must be validated later
- */
-
- if (dir) {
- if (((len = snprintf(buf2, PATH_MAX, "%s/", dir)) < 0) ||
- (len >= PATH_MAX))
- return (NULL);
- } else {
- return (NULL);
- }
-
- if (ps->url.abspath)
- if (strlcat(buf, ps->url.abspath, PATH_MAX) >= PATH_MAX)
- return (NULL);
- if (ps->url.hport.hostname)
- if (isdigit((int)ps->url.hport.hostname[0])) {
- if (strlcat(buf, ps->url.hport.hostname, PATH_MAX)
- >= PATH_MAX)
- return (NULL);
- } else {
- if ((beg_str =
- get_startof_string(ps->url.hport.hostname, '.'))
- != NULL)
- if (strlcat(buf, beg_str, PATH_MAX) >= PATH_MAX)
- return (NULL);
- }
- if (last_modified != NULL)
- if (strlcat(buf, last_modified, PATH_MAX) >= PATH_MAX)
- return (NULL);
-
- if ((buf = replace_token(buf, '/', '_')) != NULL) {
- if (strlcat(buf2, buf, PATH_MAX) >= PATH_MAX) {
- return (NULL);
- } else {
- if (buf) free(buf);
- return (buf2);
- }
- } else {
- if (buf) free(buf);
- if (buf2) free(buf2);
- return (NULL);
- }
-}
-
-/*
- * Description:
- * Removes token(s) consisting of one character from any path.
- * Arguments:
- * path - The path to search for the token in.
- * token - The token to search for
- * Returns:
- * The path with all tokens removed or NULL.
- */
-static char *
-replace_token(char *path, char oldtoken, char newtoken)
-{
- char *newpath, *p;
-
- if ((path == NULL) || (oldtoken == '\0') || (newtoken == '\0')) {
- return (NULL);
- }
-
- newpath = xstrdup(path);
-
- for (p = newpath; *p != '\0'; p++) {
- if (*p == oldtoken) {
- *p = newtoken;
- }
- }
-
- return (newpath);
-}
-
-/*
- * Name: trim
- * Description: Trims whitespace from a string
- * has been registered)
- * Scope: private
- * Arguments: string - string to trim. It is assumed
- * this string is writable up to it's entire
- * length.
- * Returns: none
- */
-static void
-trim(char *str)
-{
- int len, i;
- if (str == NULL) {
- return;
- }
-
- len = strlen(str);
- /* strip from front */
- while (isspace(*str)) {
- for (i = 0; i < len; i++) {
- str[i] = str[i+1];
- }
- }
-
- /* strip from back */
- len = strlen(str);
- while (isspace(str[len-1])) {
- len--;
- }
- str[len] = '\0';
-}
-
-/*
- * Description:
- * Resolves double quotes
- * Arguments:
- * str - The string to resolve
- * Returns:
- * None
- */
-static void
-dequote(char *str)
-{
- char *cp;
-
- if ((str == NULL) || (str[0] != '"')) {
- /* no quotes */
- return;
- }
-
- /* remove first quote */
- (void) memmove(str, str + 1, strlen(str) - 1);
-
- /*
- * scan string looking for ending quote.
- * escaped quotes like \" don't count
- */
- cp = str;
-
- while (*cp != '\0') {
- switch (*cp) {
- case '\\':
- /* found an escaped character */
- /* make sure end of string is not '\' */
- if (*++cp != '\0') {
- cp++;
- }
- break;
-
- case '"':
- *cp = '\0';
- break;
- default:
- cp++;
- }
- }
-}
-
-/*
- * Name: get_ENV_proxy
- * Description: Retrieves setting of proxy env variable
- *
- * Arguments: err - where to record any errors.
- * proxy - where to store proxy
- *
- * Returns : B_TRUE - http proxy was found and valid, stored in proxy
- * B_FALSE - error, errors recorded in err
- */
-static boolean_t
-get_ENV_proxy(PKG_ERR *err, char **proxy)
-{
- char *buf;
-
- if ((buf = getenv("HTTPPROXY")) != NULL) {
- if (!path_valid(buf)) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_ILL_ENV), "HTTPPROXY", buf);
- return (B_FALSE);
- } else {
- *proxy = buf;
- return (B_TRUE);
- }
- } else {
- /* try the other env variable */
- if ((buf = getenv("http_proxy")) != NULL) {
- if (!path_valid(buf)) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_ILL_ENV), "http_proxy", buf);
- return (B_FALSE);
- }
- if (!strneq(buf, "http://", 7)) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_ILL_ENV), "http_proxy", buf);
- return (B_FALSE);
- }
-
- /* skip over the http:// part of the proxy "url" */
- *proxy = buf + 7;
- return (B_TRUE);
- }
- }
-
- /* either the env variable(s) were set and valid, or not set */
- return (B_TRUE);
-}
-
-/*
- * Name: get_ENV_proxyport
- * Description: Retrieves setting of PROXYPORT env variable
- *
- * Arguments: err - where to record any errors.
- * port - where to store resulting port
- *
- * Returns : B_TRUE - string found in PROXYPORT variable, converted
- * to decimal integer, if it exists
- * and is valid. Or, PROXYPORT not set, port set to 1.
- * B_FALSE - env variable set, but invalid
- * (not a number for example)
- */
-static boolean_t
-get_ENV_proxyport(PKG_ERR *err, ushort_t *port)
-{
- char *buf;
- ushort_t newport;
- buf = getenv("HTTPPROXYPORT");
- if (buf != NULL) {
- if (!path_valid(buf)) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_ILL_ENV), "HTTPPROXYPORT", buf);
- return (B_FALSE);
- }
- if ((newport = atoi(buf)) == 0) {
- pkgerr_add(err, PKGERR_WEB,
- gettext(ERR_ILL_ENV), "HTTPPROXYPORT", buf);
- return (B_FALSE);
- }
- *port = newport;
- return (B_TRUE);
- } else {
- *port = 1;
- return (B_TRUE);
- }
-}
-
-/*
- * Name: remove_dwnld_file
- * Description: Removes newly-downloaded file if completely downloaded.
- *
- * Arguments: path - path to file to remove
- *
- * Returns : B_TRUE - success, B_FALSE otherwise
- * if it's '0' (not OK) we simply return it, since the
- * verification operation has already determined that the
- * cert is invalid. if 'ok' is non-zero, then we do our
- * checks, and return 0 or 1 based on if the cert is
- * invalid or valid.
- */
-static boolean_t
-remove_dwnld_file(char *path)
-{
- if (path && path != NULL) {
- /*
- * Only remove the downloaded file if it has been completely
- * downloaded, or is not eligible for spooling
- */
- if ((!ps->spool) ||
- (ps->data.cur_pos >= ps->data.content_length)) {
- (void) unlink(path);
- }
- } else {
- return (B_FALSE);
- }
- return (B_TRUE);
-}
-
-/*
- * Name: condense_lastmodifided
- * Description: generates a substring of a last-modified string,
- * and removes colons.
- *
- * Arguments: last_modified - string of the form
- * "Wed, 23 Oct 2002 21:59:45 GMT"
- *
- * Returns :
- * new string, consisting of hours/minutes/seconds only,
- * sans any colons.
- */
-char *
-condense_lastmodified(char *last_modified)
-{
- char *p, *p2;
-
- /*
- * Last-Modified: Wed, 23 Oct 2002 21:59:45 GMT
- * Strip the hours, minutes and seconds, without the ':'s, from
- * the above string, void of the ':".
- */
-
- if (last_modified == NULL)
- return (NULL);
-
- if ((p = xstrdup(last_modified)) == NULL)
- return (NULL);
- p2 = (strstr(p, ":") - 2);
- p2[8] = '\0';
- return (replace_token(p2, ':', '_'));
-}
-
-/*
- * Name: backoff
- * Description: sleeps for a certain # of seconds after a network
- * failure.
- * Scope: public
- * Arguments: none
- * Returns: none
- */
-void
-backoff()
-{
- static boolean_t initted = B_FALSE;
- int backoff;
- long seed;
-
- if (!initted) {
- /* seed the rng */
- (void) _get_random_info(&seed, sizeof (seed));
- srand48(seed);
- initted = B_TRUE;
- }
-
- backoff = (int)(drand48() * (double)cur_backoff);
- (void) sleep(backoff);
- if (cur_backoff < MAX_BACKOFF) {
- /*
- * increase maximum time we might wait
- * next time so as to fall off over
- * time.
- */
- cur_backoff *= BACKOFF_FACTOR;
- }
-}
-
-/*
- * Name: reset_backoff
- * Description: notifies the backoff service that whatever was
- * being backoff succeeded.
- * Scope: public
- * Arguments: none
- * Returns: none
- */
-void
-reset_backoff()
-{
- cur_backoff = MIN_BACKOFF;
-}
-
-/*
- * Name: _get_random_info
- * Description: generate an amount of random bits. Currently
- * only a small amount (a long long) can be
- * generated at one time.
- * Scope: private
- * Arguments: buf - [RO, *RW] (char *)
- * Buffer to copy bits into
- * size - amount to copy
- * Returns: B_TRUE on success, B_FALSE otherwise. The buffer is filled
- * with the amount of bytes of random data specified.
- */
-static boolean_t
-_get_random_info(void *buf, int size)
-{
- struct timeval tv;
- typedef struct {
- long low_time;
- long hostid;
- } randomness;
- randomness r;
-
- /* if the RANDOM file exists, use it */
- if (access(RANDOM, R_OK) == 0) {
- if ((RAND_load_file(RANDOM, 1024 * 1024)) > 0) {
- if (RAND_bytes((uchar_t *)buf, size) == 1) {
- /* success */
- return (B_TRUE);
- }
- }
- }
-
- /* couldn't use RANDOM file, so fallback to time of day and hostid */
- (void) gettimeofday(&tv, (struct timezone *)0);
-
- /* Wouldn't it be nice if we could hash these */
- r.low_time = tv.tv_usec;
- r.hostid = gethostid();
-
- if (sizeof (r) < size) {
- /*
- * Can't copy correctly
- */
- return (B_FALSE);
- }
- (void) memcpy(buf, &r, size);
- return (B_TRUE);
-}
-
-/*
- * Name: pkg_passphrase_cb
- * Description: Default callback that applications can use when
- * a passphrase is needed. This routine collects
- * a passphrase from the user using the given
- * passphrase retrieval method set with
- * set_passphrase_passarg(). If the method
- * indicates an interactive prompt, then the
- * prompt set with set_passphrase_prompt()
- * is displayed.
- *
- * Arguments: buf - Buffer to copy passphrase into
- * size - Max amount to copy to buf
- * rw - Whether this passphrase is needed
- * to read something off disk, or
- * write something to disk. Applications
- * typically want to ask twice when getting
- * a passphrase for writing something.
- * data - application-specific data. In this
- * callback, data is a pointer to
- * a keystore_passphrase_data structure.
- *
- * Returns: Length of passphrase collected, or -1 on error.
- * Errors recorded in 'err' object in the *data.
- */
-int
-pkg_passphrase_cb(char *buf, int size, int rw, void *data)
-{
- BIO *pwdbio = NULL;
- char passphrase_copy[MAX_PHRASELEN + 1];
- PKG_ERR *err;
- int passlen;
- char *ws;
- char prompt_copy[MAX_VERIFY_MSGLEN];
- char *passphrase;
- char *arg;
-
- err = ((keystore_passphrase_data *)data)->err;
-
- if (passarg == NULL) {
- arg = "console";
- } else {
- arg = passarg;
- }
-
- /* default method of collecting password is by prompting */
- if (ci_streq(arg, "console")) {
- if ((passphrase = getpassphrase(prompt)) == NULL) {
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(MSG_NOPASS), arg);
- return (-1);
- }
-
- if (rw) {
- /*
- * if the password is being supplied for
- * writing something to disk, verify it first
- */
-
- /* make a copy (getpassphrase overwrites) */
- (void) strlcpy(passphrase_copy, passphrase,
- MAX_PHRASELEN + 1);
-
- if (((passlen = snprintf(prompt_copy,
- MAX_VERIFY_MSGLEN, "%s: %s",
- gettext(MSG_PASSWD_AGAIN),
- prompt)) < 0) ||
- (passlen >= (MAX_PHRASELEN + 1))) {
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(MSG_NOPASS), arg);
- return (-1);
- }
-
- if ((passphrase =
- getpassphrase(prompt_copy)) == NULL) {
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(MSG_NOPASS), arg);
- return (-1);
- }
-
- if (!streq(passphrase_copy, passphrase)) {
- pkgerr_add(err, PKGERR_READ,
- gettext(MSG_PASSWD_NOMATCH));
- return (-1);
- }
- }
- } else if (ci_strneq(arg, "pass:", 5)) {
- passphrase = arg + 5;
- } else if (ci_strneq(arg, "env:", 4)) {
- passphrase = getenv(arg + 4);
- } else if (ci_strneq(arg, "file:", 5)) {
-
- /* open file for reading */
- if ((pwdbio = BIO_new_file(arg + 5, "r")) == NULL) {
- pkgerr_add(err, PKGERR_EXIST,
- gettext(MSG_PASSWD_FILE), arg + 5);
- return (-1);
- }
-
- /* read first line */
- if (((passlen = BIO_gets(pwdbio, buf, size)) < 1) ||
- (passlen > size)) {
- pkgerr_add(err, PKGERR_READ, gettext(MSG_PASSWD_FILE),
- arg + 5);
- return (-1);
- }
- BIO_free_all(pwdbio);
- pwdbio = NULL;
-
- if (passlen == size) {
- /*
- * password was maximum length, so there is
- * no null terminator. null-terminate it
- */
- buf[size - 1] = '\0';
- }
-
- /* first newline found is end of passwd, so nuke it */
- if ((ws = strchr(buf, '\n')) != NULL) {
- *ws = '\0';
- }
- return (strlen(buf));
- } else {
- /* unrecognized passphrase */
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(MSG_BADPASSARG), arg);
- return (-1);
- }
-
- if (passphrase == NULL) {
- /* unable to collect passwd from given source */
- pkgerr_add(err, PKGERR_BADPASS,
- gettext(MSG_NOPASS), arg);
- return (-1);
- }
-
- (void) strlcpy(buf, passphrase, size);
- return (strlen(buf));
-}
diff --git a/usr/src/lib/libpkg/common/pkgweb.h b/usr/src/lib/libpkg/common/pkgweb.h
deleted file mode 100644
index fe9dc372d9..0000000000
--- a/usr/src/lib/libpkg/common/pkgweb.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _PKGWEB_H
-#define _PKGWEB_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <netdb.h>
-#include <boot_http.h>
-
-/* shortest backoff delay possible (in seconds) */
-#define MIN_BACKOFF 1
-
-/* how much to increase backoff time after each failure */
-#define BACKOFF_FACTOR 2
-
-/* Maximum amount of backoff for a heavy network or flaky server */
-#define MAX_BACKOFF 128
-
-typedef enum {
- HTTP_REQ_TYPE_HEAD,
- HTTP_REQ_TYPE_GET
-} HTTPRequestType;
-
-typedef enum {
- OCSPSuccess,
- OCSPMem,
- OCSPParse,
- OCSPConnect,
- OCSPRequest,
- OCSPResponder,
- OCSPUnsupported,
- OCSPVerify,
- OCSPInternal,
- OCSPNoURI
-} OCSPStatus;
-
-typedef enum {
- none,
- web_http,
- web_https,
- web_ftp
-} WebScheme;
-
-typedef enum {
- WEB_OK,
- WEB_TIMEOUT,
- WEB_CONNREFUSED,
- WEB_HOSTDOWN,
- WEB_VERIFY_SETUP,
- WEB_NOCONNECT,
- WEB_GET_FAIL
-} WebStatus;
-
-typedef struct {
- ulong_t prev_cont_length;
- ulong_t content_length;
- ulong_t cur_pos;
-} DwnldData;
-
-typedef struct {
- keystore_handle_t keystore;
- char *certfile;
- char *uniqfile;
- char *link;
- char *errstr;
- char *dwnld_dir;
- boolean_t spool;
- void *content;
- int timeout;
- url_hport_t proxy;
- url_t url;
- DwnldData data;
- http_respinfo_t *resp;
- boot_http_ver_t *http_vers;
- http_handle_t *hps;
-} WEB_SESSION;
-
-extern boolean_t web_session_control(PKG_ERR *, char *, char *,
- keystore_handle_t, char *, ushort_t, int, int, int, char **);
-extern boolean_t get_signature(PKG_ERR *, char *, struct pkgdev *,
- PKCS7 **);
-extern boolean_t validate_signature(PKG_ERR *, char *, BIO *, PKCS7 *,
- STACK_OF(X509) *, url_hport_t *, int);
-extern boolean_t ds_validate_signature(PKG_ERR *, struct pkgdev *, char **,
- char *, PKCS7 *, STACK_OF(X509) *, url_hport_t *, int);
-extern boolean_t get_proxy_port(PKG_ERR *, char **, ushort_t *);
-extern boolean_t path_valid(char *);
-extern void web_cleanup(void);
-extern ushort_t strip_port(char *proxy);
-extern void set_web_install(void);
-extern int is_web_install(void);
-extern void echo_out(int, char *, ...);
-extern void backoff(void);
-extern void reset_backoff(void);
-extern char *get_endof_string(char *, char);
-extern char *get_startof_string(char *, char);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKGWEB_H */
diff --git a/usr/src/lib/libpkg/common/progerr.c b/usr/src/lib/libpkg/common/progerr.c
index e239dd8bda..567d77b581 100644
--- a/usr/src/lib/libpkg/common/progerr.c
+++ b/usr/src/lib/libpkg/common/progerr.c
@@ -20,6 +20,10 @@
*/
/*
+ * Copyright (c) 2017 Peter Tribble.
+ */
+
+/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,7 +40,6 @@
#include <stdlib.h>
#include <errno.h>
#include "pkglocale.h"
-#include "pkgerr.h"
static char *ProgName = NULL; /* Set via set_prog_name() */
@@ -94,17 +97,6 @@ progerr(char *fmt, ...)
(void) fprintf(stderr, "\n");
}
-void
-pkgerr(PKG_ERR *err)
-{
- int i;
-
- for (i = 0; i < pkgerr_num(err); i++) {
- progerr("%s", pkgerr_get(err, i));
- }
-}
-
-
/*
* set_memalloc_failure_func()
* Allows an appliation to specify the function to be called when
diff --git a/usr/src/lib/libpkg/common/security.c b/usr/src/lib/libpkg/common/security.c
deleted file mode 100644
index 9f2070c0c6..0000000000
--- a/usr/src/lib/libpkg/common/security.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-
-/*
- * Module: security.c
- * Description:
- * Module for handling certificates and various
- * utilities to access their data.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <limits.h>
-#include <pkgstrct.h>
-#include <pkginfo.h>
-#include <locale.h>
-#include <libintl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <openssl/bio.h>
-#include <openssl/pkcs12.h>
-#include <openssl/pkcs7.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-#include "pkgerr.h"
-#include "pkglib.h"
-#include "pkglibmsgs.h"
-#include "pkglocale.h"
-#include "p12lib.h"
-
-/* length of allowable passwords */
-#define MAX_PASSLEN 128
-
-/*
- * Name: init_security
- * Description: Initializes structures, libraries, for security operations
- * Arguments: none
- * Returns: 0 if we couldn't initialize, non-zero otherwise
- */
-void
-sec_init(void)
-{
- OpenSSL_add_all_algorithms();
- SSL_load_error_strings();
- ERR_load_SUNW_strings();
- (void) SSL_library_init();
-}
-
-/*
- * get_cert_chain - Builds a chain of certificates, from a given
- * user certificate to a trusted certificate.
- *
- * Arguments:
- * err - Error object to add errors to
- * cert - User cert to start with
- * cas - Trusted certs to use as trust anchors
- * chain - The resulting chain of certs (in the form of an
- * ordered set) is placed here.
- *
- * Returns:
- * 0 - Success - chain is stored in 'chain'.
- * non-zero - Failure, errors recorded in err
- */
-int
-get_cert_chain(PKG_ERR *err, X509 *cert, STACK_OF(X509) *clcerts,
- STACK_OF(X509) *cas, STACK_OF(X509) **chain)
-{
- X509_STORE_CTX *store_ctx = NULL;
- X509_STORE *ca_store = NULL;
- X509 *ca_cert = NULL;
- int i;
- int ret = 0;
-
- if ((ca_store = X509_STORE_new()) == NULL) {
- pkgerr_add(err, PKGERR_NOMEM,
- gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
-
- /* add all ca certs into the store */
- for (i = 0; i < sk_X509_num(cas); i++) {
- /* LINTED pointer cast may result in improper alignment */
- ca_cert = sk_X509_value(cas, i);
- if (X509_STORE_add_cert(ca_store, ca_cert) == 0) {
- pkgerr_add(err, PKGERR_NOMEM, gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
- }
-
- /* initialize context object used during the chain resolution */
-
- if ((store_ctx = X509_STORE_CTX_new()) == NULL) {
- pkgerr_add(err, PKGERR_NOMEM, gettext(ERR_MEM));
- ret = 1;
- goto cleanup;
- }
-
- (void) X509_STORE_CTX_init(store_ctx, ca_store, cert, clcerts);
- /* attempt to verify the cert, which builds the cert chain */
- if (X509_verify_cert(store_ctx) <= 0) {
- pkgerr_add(err, PKGERR_CHAIN,
- gettext(ERR_CERTCHAIN),
- get_subject_display_name(cert),
- X509_verify_cert_error_string(store_ctx->error));
- ret = 1;
- goto cleanup;
- }
- *chain = X509_STORE_CTX_get1_chain(store_ctx);
-
-cleanup:
- if (ca_store != NULL)
- (void) X509_STORE_free(ca_store);
- if (store_ctx != NULL) {
- (void) X509_STORE_CTX_cleanup(store_ctx);
- (void) X509_STORE_CTX_free(store_ctx);
- }
-
- return (ret);
-}
-
-/*
- * Name: get_subject_name
- * Description: Retrieves a name used for identifying a certificate's subject.
- *
- * Arguments: cert - The certificate to get the name from
- *
- * Returns : A static buffer containing the common name (CN) of the
- * subject of the cert.
- *
- * if the CN is not available, returns a string with the entire
- * X509 distinguished name.
- */
-char
-*get_subject_display_name(X509 *cert)
-{
-
- X509_NAME *xname;
- static char sname[ATTR_MAX];
-
- xname = X509_get_subject_name(cert);
- if (X509_NAME_get_text_by_NID(xname,
- NID_commonName, sname,
- ATTR_MAX) <= 0) {
- (void) strncpy(sname,
- X509_NAME_oneline(xname,
- NULL, 0), ATTR_MAX);
- sname[ATTR_MAX - 1] = '\0';
- }
- return (sname);
-}
-
-/*
- * Name: get_display_name
- * Description: Retrieves a name used for identifying a certificate's issuer.
- *
- * Arguments: cert - The certificate to get the name from
- *
- * Returns : A static buffer containing the common name (CN)
- * of the issuer of the cert.
- *
- * if the CN is not available, returns a string with the entire
- * X509 distinguished name.
- */
-char
-*get_issuer_display_name(X509 *cert)
-{
-
- X509_NAME *xname;
- static char sname[ATTR_MAX];
-
- xname = X509_get_issuer_name(cert);
- if (X509_NAME_get_text_by_NID(xname,
- NID_commonName, sname,
- ATTR_MAX) <= 0) {
- (void) strncpy(sname,
- X509_NAME_oneline(xname,
- NULL, 0), ATTR_MAX);
- sname[ATTR_MAX - 1] = '\0';
- }
- return (sname);
-}
-
-
-/*
- * Name: get_serial_num
- * Description: Retrieves the serial number of an X509 cert
- *
- * Arguments: cert - The certificate to get the data from
- *
- * Returns : A static buffer containing the serial number
- * of the cert
- *
- * if the SN is not available, returns NULL
- */
-char
-*get_serial_num(X509 *cert)
-{
- static char sn_str[ATTR_MAX];
- ASN1_INTEGER *sn;
-
- if ((sn = X509_get_serialNumber(cert)) != 0) {
- return (NULL);
- } else {
- (void) snprintf(sn_str, ATTR_MAX, "%ld",
- ASN1_INTEGER_get(sn));
- }
-
- return (sn_str);
-}
-
-/*
- * Name: get_fingerprint
- * Description: Generates a fingerprint string given
- * a digest algorithm with which to calculate
- * the fingerprint
- *
- * Arguments: cert - The certificate to get the data from
- * Arguments: alg - The algorithm to use to calculate the fingerprint
- *
- * Returns : A static buffer containing the digest
- * NULL if cert is NULL, or digest cannot be calculated
- */
-char
-*get_fingerprint(X509 *cert, const EVP_MD *alg)
-{
- static char fp_str[ATTR_MAX];
- char tmp[ATTR_MAX] = "";
- unsigned int n;
- unsigned char md[EVP_MAX_MD_SIZE];
- int i;
-
- if (!X509_digest(cert, alg, md, &n)) {
- return (NULL);
- }
-
- /* start with empty string */
- fp_str[0] = '\0';
-
- for (i = 0; i < (int)n; i++) {
- /* form a byte of the fingerprint */
- (void) snprintf(tmp, ATTR_MAX, "%02X:", md[i]);
- /* cat it onto the end of the result */
- (void) strlcat(fp_str, tmp, ATTR_MAX);
- }
-
- /* nuke trailing ':' */
- fp_str[strlen(fp_str) - 1] = '\0';
-
- return (fp_str);
-}
diff --git a/usr/src/man/man1/pkgtrans.1 b/usr/src/man/man1/pkgtrans.1
index 6f0f54c353..dd128d66fb 100644
--- a/usr/src/man/man1/pkgtrans.1
+++ b/usr/src/man/man1/pkgtrans.1
@@ -1,21 +1,20 @@
'\" te
.\" Copyright 1989 AT&T
.\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved
+.\" Copyright (c) 2017 Peter Tribble.
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH PKGTRANS 1 "Oct 30, 2007"
+.TH PKGTRANS 1 "Mar 2, 2017"
.SH NAME
pkgtrans \- translate package format
.SH SYNOPSIS
.LP
.nf
-\fBpkgtrans\fR [\fB-inosg\fR] [\fB-k\fR \fIkeystore\fR] [\fB-a\fR \fIalias\fR] [\fB-P\fR \fIpasswd\fR] \fIdevice1\fR \fIdevice2\fR
- [\fIpkginst\fR]...
+\fBpkgtrans\fR [\fB-inos\fR] \fIdevice1\fR \fIdevice2\fR [\fIpkginst\fR]...
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBpkgtrans\fR utility translates an installable package from one format to
another. It translates:
@@ -29,12 +28,6 @@ a file system format to a datastream
.TP
.ie t \(bu
.el o
-a file system format to a signed datastream
-.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
a datastream to a file system format
.RE
.RS +4
@@ -44,32 +37,11 @@ a datastream to a file system format
one file system format to another file system format
.RE
.SH OPTIONS
-.sp
.LP
The options and arguments for this command are:
.sp
.ne 2
.na
-\fB\fB-a\fR \fIalias\fR\fR
-.ad
-.RS 15n
-Use public key certificate associated with friendlyName alias, and the
-corresponding private key. See \fBKEYSTORE LOCATIONS\fR and \fBKEYSTORE AND
-CERTIFICATE FORMATS\fR in \fBpkgadd\fR(1M) for more information.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-g\fR\fR
-.ad
-.RS 15n
-Sign resulting datastream.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-i\fR\fR
.ad
.RS 15n
@@ -79,24 +51,6 @@ Copies only the \fBpkginfo\fR(4) and \fBpkgmap\fR(4) files.
.sp
.ne 2
.na
-\fB\fB-k\fR \fIkeystore\fR\fR
-.ad
-.RS 15n
-Use keystore to retrieve private key used to generate signature. If it not
-specified, default locations are searched to find the specified private key
-specified by \fB-a\fR. If no alias is given, and multiple keys exist in the key
-store, \fBpkgtrans\fR will abort. See \fBKEYSTORE LOCATIONS\fR and \fBKEYSTORE
-AND CERTIFICATE FORMATS\fR in \fBpkgadd\fR(1M) for more information on search
-locations and formats.
-.sp
-When running as a user other than root, the default base directory for
-certificate searching is \fB~/.pkg/security\fR, where \fB~\fR is the home
-directory of the user invoking \fBpkgtrans\fR.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-n\fR\fR
.ad
.RS 15n
@@ -118,16 +72,6 @@ be overwritten if it already exists.
.sp
.ne 2
.na
-\fB\fB-P\fR \fIpasswd\fR\fR
-.ad
-.RS 15n
-Supply password used to decrypt the keystore. See \fBPASS PHRASE ARGUMENTS\fR
-in \fBpkgadd\fR(1M) for details on the syntax of the argument to this option.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-s\fR\fR
.ad
.RS 15n
@@ -137,7 +81,6 @@ format on devices that support both formats.
.RE
.SH OPERANDS
-.sp
.ne 2
.na
\fB\fIdevice1\fR\fR
@@ -175,7 +118,6 @@ quotes (\fB\&'\fR) or preceded by a backslash (\fB\e\fR).
.RE
.SH DEVICE SPECIFIERS
-.sp
.LP
Packaging tools, including \fBpkgtrans\fR, \fBpkgadd\fR(1M), and
\fBpkgchk\fR(1M), have options for specifying a package location by specifying
@@ -270,23 +212,7 @@ example% pkgtrans -s /tmp /dev/diskette pkg1 pkg2
.sp
.LP
-\fBExample 4 \fRCreating a Signed Package
-.sp
-.LP
-The following example creates a signed package from \fBpkg1\fR and \fBpkg2\fR,
-and reads the password from the \fB$PASS\fR environment variable:
-
-.sp
-.in +2
-.nf
-example% pkgtrans -sg -k /tmp/keystore.p12 -a foo \e
- -p env:PASS /tmp /tmp/signedpkg pkg1 pkg2
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 5 \fRTranslating a Package Datastream
+\fBExample 4 \fRTranslating a Package Datastream
.sp
.LP
The following example translates a package datastream into a file system format
@@ -301,12 +227,10 @@ example% pkgtrans /tmp/pkg1.pkg ~/tmp pkg1
.sp
.SH ENVIRONMENT VARIABLES
-.sp
.LP
The \fBMAXINST\fR variable is set in the \fBpkginfo\fR(4) file and declares the
maximum number of package instances.
.SH EXIT STATUS
-.sp
.ne 2
.na
\fB\fB0\fR\fR
@@ -325,7 +249,6 @@ An error occurred.
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -342,10 +265,8 @@ Interface Stability See below.
.sp
.LP
-The command-line syntax is Evolving. The digitally-signed stream package is
-Evolving.
+The command-line syntax is Evolving.
.SH SEE ALSO
-.sp
.LP
\fBpkginfo\fR(1), \fBpkgmk\fR(1), \fBpkgparam\fR(1), \fBpkgproto\fR(1),
\fBinstallf\fR(1M), \fBpkgadd\fR(1M), \fBpkgask\fR(1M), \fBpkgrm\fR(1M),
@@ -355,7 +276,6 @@ Evolving.
.LP
\fIApplication Packaging Developer\&'s Guide\fR
.SH NOTES
-.sp
.LP
By default, \fBpkgtrans\fR does not translate any instance of a package if any
instance of that package already exists on the destination device. Using the
diff --git a/usr/src/man/man1m/pkgadd.1m b/usr/src/man/man1m/pkgadd.1m
index 29a7d3ae08..65120ba7d5 100644
--- a/usr/src/man/man1m/pkgadd.1m
+++ b/usr/src/man/man1m/pkgadd.1m
@@ -1,18 +1,18 @@
'\" te
+.\" Copyright (c) 2017 Peter Tribble.
.\" Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved
.\" Copyright 1989 AT&T
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH PKGADD 1M "April 9, 2016"
+.TH PKGADD 1M "Mar 2, 2017"
.SH NAME
pkgadd \- transfer software packages to the system
.SH SYNOPSIS
.LP
.nf
-\fBpkgadd\fR [\fB-nv\fR] [\fB-a\fR \fIadmin\fR] [\fB-G\fR] [\fB-x\fR \fIproxy\fR]
- [ [\fB-M\fR] \fB-R\fR \fIroot_path\fR] [\fB-r\fR \fIresponse\fR] [\fB-k\fR \fIkeystore\fR]
- [\fB-P\fR \fIpasswd\fR] [\fB-V\fR \fIfs_file\fR]
+\fBpkgadd\fR [\fB-nv\fR] [\fB-a\fR \fIadmin\fR] [\fB-G\fR] [ [\fB-M\fR] \fB-R\fR \fIroot_path\fR]
+ [\fB-r\fR \fIresponse\fR] [\fB-V\fR \fIfs_file\fR]
[\fB-d\fR \fIdevice\fR | \fB-d\fR \fIdatastream\fR \fIpkginst\fR | all]
[\fIpkginst\fR | \fB-Y\fR \fIcategory\fR [\fI, category\fR]...]
.fi
@@ -120,19 +120,6 @@ for a package, \fBSUNW_PKG_ALLZONES\fR is set to true. See \fBpkginfo\fR(4).
.sp
.ne 2
.na
-\fB\fB-k\fR \fIkeystore\fR\fR
-.ad
-.sp .6
-.RS 4n
-Use \fIkeystore\fR as the location from which to get trusted certificate
-authority certificates when verifying digital signatures found in packages. If
-no keystore is specified, then the default keystore locations are searched for
-valid trusted certificates. See \fBKEYSTORE LOCATIONS\fR for more information.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-M\fR\fR
.ad
.sp .6
@@ -157,18 +144,6 @@ installed files. The default mode is interactive.
.sp
.ne 2
.na
-\fB\fB-P\fR \fIpasswd\fR\fR
-.ad
-.sp .6
-.RS 4n
-Password to use to decrypt keystore specified with \fB-k\fR, if required. See
-\fBPASS PHRASE ARGUMENTS\fR for more information about the format of this
-option's argument.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB\fR\fB-r\fR \fIresponse\fR\fR
.ad
.sp .6
@@ -237,20 +212,6 @@ file is non-existent or unreliable.
.RE
.sp
-.ne 2
-.na
-\fB\fB-x\fR \fIproxy\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specify a HTTP[S] proxy to use when downloading packages The format of proxy is
-\fIhost\fR:\fIport\fR, where \fIhost\fR is the hostname of the HTTP[S] proxy,
-and \fIport\fR is the port number associated with the proxy. This switch
-overrides all other methods of specifying a proxy. See ENVIRONMENT VARIABLES
-for more information on alternate methods of specifying a default proxy.
-.RE
-
-.sp
.LP
When executed without options or operands, \fBpkgadd\fR uses
\fB/var/spool/pkg\fR (the default spool directory).
@@ -295,13 +256,6 @@ A device alias (for example, \fB/floppy/floppy0\fR).
.el o
A datastream created by \fBpkgtrans\fR (see \fBpkgtrans\fR(1)).
.RE
-.RS +4
-.TP
-.ie t \(bu
-.el o
-A URL pointing to a datastream created by \fBpkgtrans\fR. The supported
-Universal Resource Identifiers (URIs) are \fBhttp:\fR and \fBhttps:\fR.
-.RE
The second form of the \fB-d\fR specifier, above, indicates the syntax you use
when specifying a datastream. In this case you must specify either a
comma-separated list of package names or the keyword \fBall\fR.
@@ -342,135 +296,6 @@ the package's \fBpkginfo\fR(4) file. All packages on the source medium whose
installation or spooling.
.RE
-.SH KEYSTORE LOCATIONS
-.LP
-Package and tools such as \fBpkgadd\fR use a set of trusted certificates to
-perform signature validation on any signatures found within the packages. If
-there are no signatures included in the packages then signature validation is
-skipped. The certificates can come from a variety of locations. If \fB-k\fR
-\fIkeystore\fR is specified, and \fIkeystore\fR is a directory, then
-\fIkeystore\fR is assumed to be the base directory of the certificates to be
-used. If \fIkeystore\fR is a file, then the file itself is assumed to have all
-required keys and certificates. When \fB-k\fR is not specified, then
-\fB/var/sadm/security\fR is used as the base directory.
-.sp
-.LP
-Within the specified base directory, the store locations to be searched are
-different based on the application doing the searching and the type of store
-being searched for. The following directories are searched in the specified
-order:
-.RS +4
-.TP
-1.
-\fI<store_dir>\fR/\fI<app_name>\fR/\fI<store_type>\fR
-.RE
-.RS +4
-.TP
-2.
-\fI<store_dir>\fR/\fI<store_type>\fR
-.RE
-.sp
-.LP
-Where \fI<store_dir>\fR is the directory specified by \fB-k\fR,
-\fI<app_name>\fR is the name of the application doing the searching, and
-\fI<store_type>\fR is one of \fBkeystore\fR (for private keys), \fBcertstore\fR
-(for untrusted public key certificates), or \fBtruststore\fR (for trusted
-certificate authority certificates).
-.sp
-.LP
-For example, when \fBpkgadd\fR is run with \fB-k\fR \fB/export/certs\fR, then
-the following locations are successively searched to find the trust store:
-.RS +4
-.TP
-1.
-/export/certs/pkgadd/truststore
-.RE
-.RS +4
-.TP
-2.
-/export/certs/truststore
-.RE
-.sp
-.LP
-This searching order enables administrators to have a single location for most
-applications, and special certificate locations for certain applications.
-.SH KEYSTORE AND CERTIFICATE FORMATS
-.LP
-The packaging utilities, such as \fBpkgtrans\fR, require access to a set of
-keys and certificates in order to sign, and optionally verify, packages.
-.sp
-.LP
-The keystore files found by following the search pattern specified in
-\fBKEYSTORE LOCATIONS\fR must each be a self-contained PKCS#12-format file.
-.sp
-.LP
-When signing a package with \fBpkgtrans\fR, if a \fBcertstore\fR has more than
-one public key certificate, then each public key must have a \fBfriendlyName\fR
-attribute in order to be identifiable and selectable with the \fB-a\fR option
-when signing packages. In addition, the public key certificate selected with
-\fB-a\fR and found in the \fBcertstore\fR must have an associated private key
-in the keystore.
-.sp
-.LP
-Several browsers and utilities can be used to export and import certificates
-and keys into a PKCS#12 keystore. For example, a trusted certificate can be
-exported from Mozilla, and then imported into a PKCS#12 keystore for use with
-\fBpkgadd\fR with the OpenSSL Toolkit.
-.SH PASS PHRASE ARGUMENTS
-.LP
-\fBpkgtrans\fR and \fBpkgadd\fR accept password arguments, typically using
-\fB-p\fR to specify the password. These allow the password to be obtained from
-a variety of sources. Both of these options take a single argument whose format
-is described below. If no password argument is given and a password is required
-then the user is prompted to enter one: this will typically be read from the
-current terminal with echoing turned off.
-.sp
-.ne 2
-.na
-\fB\fBpass:\fIpassword\fR\fR\fR
-.ad
-.sp .6
-.RS 4n
-The actual password is \fIpassword\fR. Because the password is visible to
-utilities such as \fBps\fR this form should only be used where security is not
-important.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBenv:\fIvar\fR\fR\fR
-.ad
-.sp .6
-.RS 4n
-Obtain the password from the environment variable \fIvar\fR. Because the
-environment of other processes is visible on certain platforms this option
-should be used with caution.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBfile:\fIpathname\fR\fR\fR
-.ad
-.sp .6
-.RS 4n
-The first line contained within \fIpathname\fR is the password. \fIpathname\fR
-need not refer to a regular file: it could, for example, refer to a device or
-named pipe. For example, to read the password from standard input, use
-\fBfile:/dev/stdin\fR.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBconsole\fR\fR
-.ad
-.sp .6
-.RS 4n
-Read the password from \fB/dev/tty\fR.
-.RE
-
.SH EXAMPLES
.LP
\fBExample 1 \fRInstalling a Package from a Solaris DVD
@@ -588,39 +413,6 @@ Reboot after installation of all packages.
Reboot after installation of this package.
.RE
-.SH ENVIRONMENT VARIABLES
-.ne 2
-.na
-\fB\fBHTTPPROXY\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies an HTTP proxy host. Overrides administration file setting, and
-\fBhttp_proxy\fR environment variable.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBHTTPPROXYPORT\fR\fR
-.ad
-.sp .6
-.RS 4n
-Specifies the port to use when contacting the host specified by
-\fBHTTPPROXY\fR. Ignored if \fBHTTPPROXY\fR is not set.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBhttp_proxy\fR\fR
-.ad
-.sp .6
-.RS 4n
-URL format for specifying proxy host and port. Overrides administration file
-setting.
-.RE
-
.SH FILES
.ne 2
.na
@@ -652,12 +444,7 @@ Interface Stability Evolving
\fBpkgtrans\fR(1), \fBinstallf\fR(1M), \fBpkgadm\fR(1M), \fBpkgask\fR(1M),
\fBpkgchk\fR(1M), \fBpkgrm\fR(1M), \fBremovef\fR(1M), \fBadmin\fR(4),
\fBpkginfo\fR(4), \fBattributes\fR(5), \fBlargefile\fR(5), \fBzones\fR(5)
-.sp
-.LP
-\fI\fR
-.sp
-.LP
-\fBhttp://www.openssl.org\fR
+
.SH NOTES
.LP
When transferring a package to a spool directory, the \fB-r\fR, \fB-n\fR, and
@@ -681,9 +468,3 @@ needed to complete it.
If the default \fIadmin\fR file is too restrictive, the administration file may
need to be modified to allow for total non-interaction during a package
installation. See \fBadmin\fR(4) for details.
-.sp
-.LP
-If a package stream is specified with \fB-d\fR, and a digital signature is
-found in that stream, the default behavior is to attempt to validate the
-certificate and signature found. This behavior can be overridden with
-\fBadmin\fR file settings. See \fBadmin\fR(4) for more information.
diff --git a/usr/src/man/man1m/pkgadm.1m b/usr/src/man/man1m/pkgadm.1m
index 9f7a3d020d..2a5180eb5e 100644
--- a/usr/src/man/man1m/pkgadm.1m
+++ b/usr/src/man/man1m/pkgadm.1m
@@ -1,33 +1,15 @@
'\" te
+.\" Copyright (c) 2017 Peter Tribble.
.\" Copyright (c) 2003, Sun Microsystems, Inc. All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.
.\" See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with
.\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH PKGADM 1M "Mar 20, 2009"
+.TH PKGADM 1M "Mar 2, 2017"
.SH NAME
-pkgadm \- manage packaging and patching system
+pkgadm \- manage packaging system
.SH SYNOPSIS
.LP
.nf
-\fBpkgadm addcert\fR [\fB-ty\fR] [\fB-a\fR \fIapp\fR] [\fB-k\fR \fIkeystore\fR] [\fB-e\fR \fIkeyfile\fR]
- [\fB-f\fR \fIformat\fR] [\fB-n\fR \fIname\fR] [\fB-P\fR \fIpassarg\fR]
- [\fB-p\fR \fIimport_passarg\fR] [\fB-R\fR \fIrootpath\fR] certfile
-.fi
-
-.LP
-.nf
-\fBpkgadm removecert\fR [\fB-a\fR \fIapp\fR] [\fB-k\fR \fIkeystore\fR] \fB-n\fR \fIname\fR
- [\fB-P\fR \fIpassarg\fR] [\fB-R\fR \fIrootpath\fR]
-.fi
-
-.LP
-.nf
-\fBpkgadm listcert\fR [\fB-a\fR \fIapp\fR] [\fB-f\fR \fIformat\fR] [\fB-k\fR \fIkeystore\fR] \fB-n\fR \fIname\fR
- [\fB-P\fR \fIpassarg\fR] [\fB-o\fR \fIoutfile\fR] [\fB-R\fR \fIrootpath\fR]
-.fi
-
-.LP
-.nf
\fBpkgadm dbstatus\fR [\fB-R\fR \fIrootpath\fR]
.fi
@@ -47,55 +29,10 @@ pkgadm \- manage packaging and patching system
.fi
.SH DESCRIPTION
-.sp
.LP
-The \fBpkgadm\fR utility is used for managing the packaging and patching
+The \fBpkgadm\fR utility is used for managing the packaging
system. It has several subcommands that perform various operations relating to
-packaging. The \fBpkgadm\fR command includes subcommands for managing
-certificates and keys used.
-.SS "Managing Keys and Certificates"
-.sp
-.LP
-\fBpkgadm\fR maintains the packaging-system-wide keystore in
-\fB/var/sadm/security\fR, and individual user's certificates in
-\fB~/.pkg/security\fR. The following subcommands operate on the package
-keystore database:
-.sp
-.ne 2
-.na
-\fB\fBaddcert\fR\fR
-.ad
-.sp .6
-.RS 4n
-Add (import) a certificate into the database, with optional trust. Once added,
-trusted certificates can be used to verify signed packages and patches.
-Non-trusted user certificates and their associated keys can be used to sign
-packages and patches. Added user certificates are \fBnot\fR used to build
-certificate chains during certificate verification.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBremovecert\fR\fR
-.ad
-.sp .6
-.RS 4n
-Removes a user certificate/private key pair, or a trusted certificate authority
-certificate from the keystore. Once removed, the certificate and keys cannot be
-used.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBlistcert\fR\fR
-.ad
-.sp .6
-.RS 4n
-Print details of one or more certificates in the keystore.
-.RE
-
+packaging.
.sp
.ne 2
.na
@@ -108,7 +45,6 @@ Writes the contents file and rolls the contents log file. With use of the
.RE
.SS "Internal Install Database"
-.sp
.LP
The Solaris operating system relies upon enhanced System V revision 4 (SVr4)
packages as the basis for its software installation and revision management.
@@ -118,161 +54,14 @@ determine how the package internal database is implemented. The \fBdbstatus\fR
command returns a string that indicates the type of internal database in use.
In the current implementation, the \fBdbstatus\fR command always returns the
string \fBtext\fR, which indicates that the \fBcontents\fR(4) package database
-is inuse. Future releases of Solaris might supply alternative database
+is in use. Future releases of Solaris might supply alternative database
implementations.
.SH OPTIONS
-.sp
.LP
The following options are supported:
.sp
.ne 2
.na
-\fB\fB-a\fR \fIapp\fR\fR
-.ad
-.sp .6
-.RS 4n
-If this option is used, then the command only affects the keystore associated
-with a particular application. Otherwise, the global keystore is affected.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-e\fR \fIkeyfile\fR\fR
-.ad
-.sp .6
-.RS 4n
-When adding a non-trusted certificate/key combination, this option can be used
-to specify the file that contains the private key. If this option is not used,
-the private key must be in the same file as the certificate being added.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-f\fR \fIformat\fR\fR
-.ad
-.sp .6
-.RS 4n
-When adding certificates, this specifies the format to expect certificates and
-private keys in. Possible values when adding are:
-.sp
-.ne 2
-.na
-\fB\fBpem\fR\fR
-.ad
-.sp .6
-.RS 4n
-Certificate and any private key uses PEM encoding.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBder\fR\fR
-.ad
-.sp .6
-.RS 4n
-Certificate and any private key uses DER encoding.
-.RE
-
-When printing certificates, this specifies the output format used when
-printing. Acceptable values for format are:
-.sp
-.ne 2
-.na
-\fB\fBpem\fR\fR
-.ad
-.sp .6
-.RS 4n
-Output each certificate using PEM encoding.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBder\fR\fR
-.ad
-.sp .6
-.RS 4n
-Output each certificate using DER encoding.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBtext\fR\fR
-.ad
-.sp .6
-.RS 4n
-Output each certificate in human-readable format.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-k\fR \fIkeystore\fR\fR
-.ad
-.sp .6
-.RS 4n
-Overrides the default location used when accessing the keystore.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-n\fR \fIname\fR\fR
-.ad
-.sp .6
-.RS 4n
-Identifies the entity in the store on which you want to operate. When adding a
-user certificate, or removing certificates, this name is required. The name is
-associated with the certificate/key combination, and when adding, can be used
-later to reference the entity. When printing certificates, if no alias is
-supplied, then all keystore entities are printed.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-o\fR \fIoutfile\fR\fR
-.ad
-.sp .6
-.RS 4n
-Output the result of the command to \fIoutfile\fR. Only used when examining
-(printing) certificates from the key store. Standard out is the default.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-P\fR \fIpassarg\fR\fR
-.ad
-.sp .6
-.RS 4n
-Password retrieval method to use to decrypt keystore specified with \fB-k\fR,
-if required. See \fBPASS PHRASE ARGUMENTS\fR in \fBpkgadd\fR(1M) for more
-information about the format of this option's argument. \fBconsole\fR is the
-default.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-p\fR \fIimport_passarg\fR\fR
-.ad
-.sp .6
-.RS 4n
-This option's argument is identical to \fB-P\fR, but is used for supplying the
-password used to decrypt the certificate and/or private key being added.
-\fBconsole\fR is the default.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-q\fR\fR
.ad
.sp .6
@@ -287,13 +76,7 @@ password used to decrypt the certificate and/or private key being added.
.ad
.sp .6
.RS 4n
-Defines the full name of a directory to use as the root (\fB/\fR) path. The
-default user location of the certificate operations is \fB${HOME}/.pkg\fR. If
-the \fB-R\fR option is supplied, the certificates and keys will be stored under
-\fB\fI<altroot>\fR/var/sadm/security\fR. Note that this operation fails if the
-user does not have sufficient permissions to access this directory. The
-\fBlistcert\fR command requires read permission, while \fBaddcert\fR and
-\fBremovecert\fR require both read and write permission.
+Defines the full name of a directory to use as the root (\fB/\fR) path.
.LP
Note -
.sp
@@ -308,22 +91,6 @@ zone's file system. See \fBzones\fR(5).
.sp
.ne 2
.na
-\fB\fB-t\fR\fR
-.ad
-.sp .6
-.RS 4n
-Indicates the certificate being added is a trusted CA certificate. The details
-of the certificate (including the Subject Name, Validity Dates, and
-Fingerprints) are printed and the user is asked to verify the data. This
-verification step can be skipped with \fB-y\fR. When importing a trusted
-certificate, a private key should not be supplied, and will be rejected if
-supplied. Once a certificate is trusted, it can be used as a trust anchor when
-verifying future untrusted certificates.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-V\fR\fR
.ad
.sp .6
@@ -334,19 +101,6 @@ Print version associated with packaging tools.
.sp
.ne 2
.na
-\fB\fB-y\fR\fR
-.ad
-.sp .6
-.RS 4n
-When adding a trusted certificate, the details of the certificate (Subject
-name, Issuer name, Validity dates, Fingerprints) are shown to the user and the
-user is asked to verify the correctness before proceeding. With \fB-y\fR, this
-additional verification step is skipped.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fB-?\fR\fR
.ad
.sp .6
@@ -354,88 +108,22 @@ additional verification step is skipped.
Print help message.
.RE
-.SH OPERANDS
-.sp
-.LP
-The following operand is supported:
-.sp
-.ne 2
-.na
-\fB\fBcertfile\fR\fR
-.ad
-.sp .6
-.RS 4n
-File containing the certificate and optional private key, used when adding a
-trust anchor or certificate/key combination. Certificates must be encoded using
-PEM or binary DER.
-.RE
-
-.SH KEYSTORE ALIASES
-.sp
-.LP
-All keystore entries (user cert/key and trusted certificate entries) are
-accessed via unique aliases. Aliases are case-sensitive.
-.sp
-.LP
-An alias is specified when you add an entity to a keystore using the
-\fBaddcert\fR or \fBtrustcert\fR subcommand. If an alias is not supplied for a
-trust anchor, the trust anchor's Common Name is used as the alias. An alias is
-required when adding a signing certificate or chain certificate. Subsequent
-\fBpkgcert\fR or other package tool commands must use this same alias to refer
-to the entity.
-.SH KEYSTORE PASSWORDS
-.sp
-.LP
-See the \fBpkgadd\fR(1M) man page for a description of the passwords supplied
-to the \fBpkgadm\fR utility.
.SH EXAMPLES
.LP
-\fBExample 1 \fRAdding a Trust Anchor
-.sp
-.LP
-The following example adds a well-known and trusted certificate to be used when
-verifying signatures on packages.
-
-.sp
-.in +2
-.nf
-example% pkgadm addcert -t /tmp/certfile.pem
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 2 \fRAdding a Signing Certificate
+\fBExample 1 \fRSynchronizing the contents file
.sp
.LP
-The following example adds a signing certificate and associated private key,
-each of which is in a separate file, which can then be used to sign packages.
+The following example forces any pending changes to the contents(4) file to be flushed and the pkgserv daemon to shut down.
.sp
.in +2
.nf
-example% pkgadm addcert -a pkgtrans -e /tmp/keyfile.pem \e
-/tmp/certfile.pem
-.fi
-.in -2
-.sp
-
-.LP
-\fBExample 3 \fRPrinting Certificates
-.sp
-.LP
-The following example prints all certificates in the root keystore.
-
-.sp
-.in +2
-.nf
-example% pkgadm listcert
+example% pkgadm sync -q
.fi
.in -2
.sp
.SH EXIT STATUS
-.sp
.ne 2
.na
\fB\fB0\fR\fR
@@ -456,7 +144,6 @@ fatal error
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -472,7 +159,6 @@ Interface Stability Evolving
.TE
.SH SEE ALSO
-.sp
.LP
\fBpkginfo\fR(1), \fBpkgmk\fR(1), \fBpkgparam\fR(1), \fBpkgproto\fR(1),
\fBpkgtrans\fR(1), \fBsvcs\fR(1), \fBinstallf\fR(1M), \fBpkgadd\fR(1M),
@@ -483,7 +169,6 @@ Interface Stability Evolving
.LP
\fI\fR
.SH NOTES
-.sp
.LP
The service for \fBpkgadm\fR is managed by the service management facility,
\fBsmf\fR(5), under the service identifier:
diff --git a/usr/src/man/man4/admin.4 b/usr/src/man/man4/admin.4
index 4efdf5bdf9..c7090f9b04 100644
--- a/usr/src/man/man4/admin.4
+++ b/usr/src/man/man4/admin.4
@@ -1,13 +1,13 @@
'\" te
+.\" Copyright (c) 2017 Peter Tribble.
.\" Copyright 1989 AT&T Copyright (c) 1997, Sun Microsystems, Inc. All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH ADMIN 4 "Dec 20, 2004"
+.TH ADMIN 4 "Mar 2, 2017"
.SH NAME
admin \- installation defaults file
.SH DESCRIPTION
-.sp
.LP
\fBadmin\fR is a generic name for an \fBASCII\fR file that defines default
installation actions by assigning values to installation parameters. For
@@ -37,7 +37,7 @@ assigned, \fBpkgadd\fR(1M) asks the installer how to proceed.
.LP
The valid parameters and their possible values are shown below except as noted.
They can be specified in any order. Any of these parameters (except the
-\fBmail\fR and \fBproxy\fR parameters) can be assigned the value \fBask\fR,
+\fBmail\fR parameter) can be assigned the value \fBask\fR,
which means that, when the parameter is reached during the installation
sequence, the installer is notified and asked to supply instructions (see
\fBNOTES\fR).
@@ -358,86 +358,6 @@ Abort installation if space requirements are not met.
.sp
.ne 2
.na
-\fB\fBauthentication\fR\fR
-.ad
-.RS 30n
-Controls resolution when a datastream package with signature is to be
-installed. Options are:
-.sp
-.ne 2
-.na
-\fB\fBnocheck\fR\fR
-.ad
-.RS 11n
-Do not verify package signature. This also disables the use of the Online
-Certificate Status Protocol (OCSP) to validate the package's signing
-certificate.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBquit\fR\fR
-.ad
-.RS 11n
-Abort installation if package signature cannot be verified.
-.RE
-
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBnetworktimeout\fR\fR
-.ad
-.RS 30n
-Number of seconds to wait before giving up a network connection when
-downloading a package. This entry must be a positive integer. If not present,
-the default value of 60 is used.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBnetworkretries\fR\fR
-.ad
-.RS 30n
-Number of times to retry a failed network connection when downloading a
-package. This entry must be a positive integer. If not present, the default
-value of 5 is used.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBkeystore\fR\fR
-.ad
-.RS 30n
-Location of trusted certificates used when downloading packages over SSL and
-when verifying signatures on packages. This is the base directory of the
-certificate location for trusted certificates used when validating digital
-signatures on packages. For example, if this setting is
-\fB/var/sadm/security\fR, then \fBpkgadd\fR will use
-\fB/var/sadm/security/pkgadd/truststore\fR, then
-\fB/var/sadm/security/truststore\fR when searching for trusted certificates.
-See \fBKEYSTORE LOCATIONS\fR and \fBKEYSTORE AND CERTIFICATE FORMATS\fR in
-\fBpkgadd\fR(1M) for details on certificate store format and usage.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBproxy\fR\fR
-.ad
-.RS 30n
-The default proxy to use when installing packages from the network. Currently,
-only HTTP or HTTPS proxies are supported. If this field is blank or
-nonexistent, then no proxy will be used.
-.RE
-
-.sp
-.ne 2
-.na
\fB\fBrscriptalt=root | noaccess\fR\fR
.ad
.RS 30n
@@ -496,11 +416,6 @@ setuid=ask
conflict=ask
action=ask
basedir=default
-authentication=quit
-networktimeout=10
-networkretries=3
-keystore=/var/sadm/security
-proxy=
.fi
.in -2
.sp
@@ -524,17 +439,11 @@ instance=unique
idepend=quit
rdepend=quit
space=quit
-authentication=quit
-networktimeout=10
-networkretries=5
-keystore=/opt/certs
-proxy=syrinx.eng.example.com:8080
.fi
.in -2
.sp
.SH FILES
-.sp
.LP
The default \fBadmin\fR file is consulted during package installation when no
other \fBadmin\fR file is specified.
@@ -549,7 +458,6 @@ default \fBadmin\fR file
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -565,12 +473,10 @@ Interface Stability Evolving
.TE
.SH SEE ALSO
-.sp
.LP
\fBpkgadd\fR(1M), \fBprodreg\fR(1M), \fBlibwsreg\fR(3LIB), \fBpkginfo\fR(4),
\fBattributes\fR(5), \fBzones\fR(5)
.SH NOTES
-.sp
.LP
The value \fBask\fR should not be defined in an \fBadmin\fR file that will be
used for non-interactive installation (because, by definition, there is no
diff --git a/usr/src/pkg/manifests/package-svr4.mf b/usr/src/pkg/manifests/package-svr4.mf
index 5476930ec4..65e255b17f 100644
--- a/usr/src/pkg/manifests/package-svr4.mf
+++ b/usr/src/pkg/manifests/package-svr4.mf
@@ -118,6 +118,4 @@ legacy pkg=SUNWpkgcmdsu \
license cr_ATT license=cr_ATT
license cr_Sun license=cr_Sun
license lic_CDDL license=lic_CDDL
-license usr/src/lib/libpkg/THIRDPARTYLICENSE \
- license=usr/src/lib/libpkg/THIRDPARTYLICENSE
link path=usr/lib/libpkg.so target=./libpkg.so.1