summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhylee <none@none>2007-12-06 15:56:13 -0800
committerhylee <none@none>2007-12-06 15:56:13 -0800
commit431deaa01ac039d796fdfaf86b909a75e7d9ac48 (patch)
tree0d4bb232b811d43a31fcb0d6149d0624c643e3f4
parentc73e9863820a560b7fbb4fb258aa450a88315a39 (diff)
downloadillumos-gate-431deaa01ac039d796fdfaf86b909a75e7d9ac48.tar.gz
PSARC 2007/604 KMF Pluggability Enhancements
6621224 KMF Dynamic Plugin Support 6621231 pktool list keystore=file dir=/tmp/test prints out incorrect output
-rw-r--r--usr/src/cmd/cmd-crypto/etc/Makefile1
-rw-r--r--usr/src/cmd/cmd-crypto/etc/kmf.conf43
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/Makefile6
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/install.c311
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c21
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/list.c83
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/modify.c262
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/uninstall.c248
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/util.c30
-rw-r--r--usr/src/cmd/cmd-crypto/kmfcfg/util.h9
-rw-r--r--usr/src/cmd/cmd-crypto/pktool/list.c2
-rw-r--r--usr/src/cmd/cmd-crypto/scripts/Makefile6
-rw-r--r--usr/src/cmd/cmd-crypto/scripts/i.kmfconf116
-rw-r--r--usr/src/cmd/cmd-crypto/scripts/r.kmfconf81
-rw-r--r--usr/src/lib/libkmf/include/kmfapi.h3
-rw-r--r--usr/src/lib/libkmf/include/kmfapiP.h23
-rw-r--r--usr/src/lib/libkmf/include/kmftypes.h16
-rw-r--r--usr/src/lib/libkmf/libkmf/common/certop.c6
-rw-r--r--usr/src/lib/libkmf/libkmf/common/generalop.c422
-rw-r--r--usr/src/lib/libkmf/libkmf/common/llib-lkmf3
-rw-r--r--usr/src/lib/libkmf/libkmf/common/mapfile-vers5
-rw-r--r--usr/src/pkgdefs/SUNWcsr/Makefile1
-rw-r--r--usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl2
-rw-r--r--usr/src/pkgdefs/SUNWcsr/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_com2
-rw-r--r--usr/src/pkgdefs/common_files/i.kmfconfbase34
26 files changed, 1690 insertions, 48 deletions
diff --git a/usr/src/cmd/cmd-crypto/etc/Makefile b/usr/src/cmd/cmd-crypto/etc/Makefile
index 7b600f0489..14f4b1e541 100644
--- a/usr/src/cmd/cmd-crypto/etc/Makefile
+++ b/usr/src/cmd/cmd-crypto/etc/Makefile
@@ -32,6 +32,7 @@ RELEASECRYPTO = SUNW_SunOS_5.10 \
ETCCRYPTOFILES = \
kcf.conf \
pkcs11.conf \
+ kmf.conf \
$(RELEASECRYPTO:%=certs/%) \
certs/CA \
certs/SUNWObjectCA
diff --git a/usr/src/cmd/cmd-crypto/etc/kmf.conf b/usr/src/cmd/cmd-crypto/etc/kmf.conf
new file mode 100644
index 0000000000..e98dea72be
--- /dev/null
+++ b/usr/src/cmd/cmd-crypto/etc/kmf.conf
@@ -0,0 +1,43 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# /etc/crypto/kmf.conf
+#
+# This file contains non-default plugin entries to the Solaris Key Management
+# Framework (KMF). Do NOT edit this file by hand. An administrator should use
+# kmfcfg(1m) to install or uninstall a non-default plugin. A developer for a
+# KMF plugin package should provide an input file and use the {i,r}.kmfconf
+# class action scripts to update this file during the installation and removal
+# of the package.
+#
+# This document does not constitute an API. The /etc/crypto/kmf.conf file
+# may not exist or may have a different content or interpretation in a future
+# release. The existence of this notice does not imply that any other
+# documentation that lacks this notice constitutes an API.
+#
+# The format for each entry is:
+# keystore:modulepath=path[;option=option_str]
+#
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/Makefile b/usr/src/cmd/cmd-crypto/kmfcfg/Makefile
index 57e1b6d72e..f476df768f 100644
--- a/usr/src/cmd/cmd-crypto/kmfcfg/Makefile
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -36,7 +36,9 @@ OBJS = kmfcfg.o \
create.o \
modify.o \
export.o \
- import.o
+ import.o \
+ install.o \
+ uninstall.o
include ../../Makefile.cmd
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/install.c b/usr/src/cmd/cmd-crypto/kmfcfg/install.c
new file mode 100644
index 0000000000..6147638c43
--- /dev/null
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/install.c
@@ -0,0 +1,311 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <strings.h>
+#include <ctype.h>
+#include <libgen.h>
+#include <libintl.h>
+#include <errno.h>
+#include <kmfapiP.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <cryptoutil.h>
+#include "util.h"
+
+static int err; /* To store errno which may be overwritten by gettext() */
+
+int
+kc_install(int argc, char *argv[])
+{
+ int rv = KC_OK;
+ int opt;
+ extern int optind_av;
+ extern char *optarg_av;
+ char *keystore_name = NULL;
+ char *modulepath = NULL;
+ char *option_str = NULL;
+ conf_entry_t *entry = NULL;
+ char realpath[MAXPATHLEN];
+ struct stat statbuf;
+ FILE *pfile = NULL;
+ FILE *pfile_tmp = NULL;
+ char tmpfile_name[MAXPATHLEN];
+ int found_count = 0;
+ char buffer[BUFSIZ];
+ char *ptr;
+ boolean_t found;
+
+ while ((opt = getopt_av(argc, argv, "k:(keystore)m:(modulepath)"
+ "o:(option)")) != EOF) {
+ switch (opt) {
+ case 'k':
+ if (keystore_name != NULL)
+ rv = KC_ERR_USAGE;
+ else {
+ keystore_name = get_string(optarg_av, &rv);
+ if (keystore_name == NULL) {
+ (void) fprintf(stderr, gettext(
+ "Error keystore input.\n"));
+ }
+ }
+ break;
+ case 'm':
+ if (modulepath != NULL)
+ rv = KC_ERR_USAGE;
+ else {
+ modulepath = get_string(optarg_av, &rv);
+ if (modulepath == NULL) {
+ (void) fprintf(stderr,
+ gettext("Error modulepath.\n"));
+ }
+ }
+ break;
+ case 'o':
+ if (option_str != NULL) {
+ rv = KC_ERR_USAGE;
+ } else {
+ option_str = get_string(optarg_av, &rv);
+ if (option_str == NULL) {
+ (void) fprintf(stderr,
+ gettext("Error option input.\n"));
+ }
+ }
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("Error input option.\n"));
+ rv = KC_ERR_USAGE;
+ break;
+ }
+ if (rv != KC_OK)
+ goto out;
+ }
+
+ /* No additional args allowed. */
+ argc -= optind_av;
+ if (argc) {
+ (void) fprintf(stderr,
+ gettext("Error input option\n"));
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if (keystore_name == NULL || modulepath == NULL) {
+ (void) fprintf(stderr, gettext("Error input option\n"));
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if (strcasecmp(keystore_name, "nss") == 0 ||
+ strcasecmp(keystore_name, "pkcs11") == 0 ||
+ strcasecmp(keystore_name, "file") == 0) {
+ (void) fprintf(stderr,
+ gettext("Can not use the built-in keystore name %s\n"),
+ keystore_name);
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ entry = get_keystore_entry(keystore_name);
+ if (entry != NULL) {
+ (void) fprintf(stderr, gettext("%s exists already.\n"),
+ keystore_name);
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ /*
+ * Find the absolute path of the module and check if it exists in
+ * the system. If $ISA is in the path, will check the 32bit version
+ * only.
+ */
+ if (strncmp(modulepath, "/", 1) != 0) {
+ /*
+ * Only contain the base name; prepand it with
+ * KMF_PLUGIN_PATH
+ */
+ (void) snprintf(realpath, MAXPATHLEN, "%s%s",
+ KMF_PLUGIN_PATH, modulepath);
+ } else {
+ char *buf = modulepath;
+ char *isa;
+
+ if ((isa = strstr(buf, PKCS11_ISA)) != NULL) {
+ (void) strncpy(realpath, buf, isa - buf);
+ isa += strlen(PKCS11_ISA) - 1;
+ (void) strlcat(realpath, isa, MAXPATHLEN);
+ } else {
+ (void) strlcpy(realpath, modulepath, MAXPATHLEN);
+ }
+ }
+
+ if (stat(realpath, &statbuf) != 0) {
+ (void) fprintf(stderr, gettext("%s not found.\n"),
+ realpath);
+ rv = KC_ERR_ACCESS;
+ goto out;
+ }
+
+ if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to update the configuration - %s\n"),
+ strerror(err));
+ rv = KC_ERR_ACCESS;
+ goto out;
+ }
+
+ if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to lock the configuration - %s\n"),
+ strerror(err));
+ rv = KC_ERR_INSTALL;
+ goto out;
+ }
+
+ /*
+ * Create a temporary file in the /etc/crypto directory.
+ */
+ (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name));
+ if (mkstemp(tmpfile_name) == -1) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to create a temporary file - %s\n"),
+ strerror(err));
+ rv = KC_ERR_INSTALL;
+ goto out;
+ }
+
+ if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to open %s - %s\n"),
+ tmpfile_name, strerror(err));
+ rv = KC_ERR_INSTALL;
+ goto out;
+ }
+
+ /*
+ * Loop thru the config file. If the file was reserved within a
+ * package bracket, just uncomment it. Other wise, append it at
+ * the end. The resulting file will be saved in the temp file first.
+ */
+ while (fgets(buffer, BUFSIZ, pfile) != NULL) {
+ found = B_FALSE;
+ if (buffer[0] == '#') {
+ ptr = buffer;
+ ptr++;
+ while (*ptr == '#' || *ptr == ' ')
+ ptr++;
+ if (strncmp(keystore_name, ptr, strlen(keystore_name))
+ == 0) {
+ found = B_TRUE;
+ found_count++;
+ }
+ }
+
+ if (found == B_FALSE) {
+ if (fputs(buffer, pfile_tmp) == EOF) {
+ rv = KC_ERR_INSTALL;
+ goto out;
+ }
+ } else {
+ if (found_count == 1) {
+ if (fputs(ptr, pfile_tmp) == EOF) {
+ rv = KC_ERR_INSTALL;
+ goto out;
+ }
+ } else {
+ /*
+ * Found a second entry with #keystore_name.
+ * This should not happen. The kmf.conf file
+ * is corrupted. Give a warning and skip
+ * this entry.
+ */
+ (void) fprintf(stderr, gettext(
+ "(Warning) Found an additional reserved "
+ "entry for %s.\n"), keystore_name);
+ }
+ }
+ }
+
+ if (found_count == 0) {
+ char buf[MAXPATHLEN];
+ /*
+ * This entry was not in package before, append it to the
+ * end of the temp file.
+ */
+ if (option_str == NULL)
+ (void) snprintf(buf, MAXPATHLEN, "%s:%s%s\n",
+ keystore_name, CONF_MODULEPATH, modulepath);
+ else
+ (void) snprintf(buf, MAXPATHLEN, "%s:%s%s;%s%s\n",
+ keystore_name, CONF_MODULEPATH, modulepath,
+ CONF_OPTION, option_str);
+
+ if (fputs(buf, pfile_tmp) == EOF) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to write to %s: %s\n"), tmpfile_name,
+ strerror(err));
+ rv = KC_ERR_INSTALL;
+ goto out;
+ }
+ }
+
+out:
+ if (pfile != NULL)
+ (void) fclose(pfile);
+
+ if (rv != KC_OK && pfile_tmp != NULL)
+ (void) unlink(tmpfile_name);
+
+ if (pfile_tmp != NULL)
+ (void) fclose(pfile_tmp);
+
+ if (rv == KC_OK) {
+ if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to update the configuration - %s"),
+ strerror(err));
+ return (KC_ERR_INSTALL);
+ }
+
+ if (chmod(_PATH_KMF_CONF,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to update the configuration - %s\n"),
+ strerror(err));
+ return (KC_ERR_INSTALL);
+ }
+ }
+
+ return (rv);
+}
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c b/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c
index e58368284f..997fbc131d 100644
--- a/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -53,11 +53,15 @@ int kc_create(int argc, char *argv[]);
int kc_modify(int argc, char *argv[]);
int kc_export(int argc, char *argv[]);
int kc_import(int argc, char *argv[]);
+int kc_install(int argc, char *argv[]);
+int kc_uninstall(int argc, char *argv[]);
+
static int kc_help();
static verbcmd cmds[] = {
- { "list", kc_list, "list [dbfile=dbfile] "
- "[policy=policyname]" },
+ { "list", kc_list,
+ "list [dbfile=dbfile] [policy=policyname]\n"
+ "\tlist plugin" },
{ "delete", kc_delete, "delete [dbfile=dbfile] "
"policy=policyname" },
{ "create", kc_create,
@@ -125,11 +129,16 @@ static verbcmd cmds[] = {
"\t\tipsecUser | timeStamping |\n\t"
"\t\tOCSPSigning],[...]\n"
"\t\t[ekuoids=OID,OID,OID...]\n"
- "\t\t[eku-none=true|false]\n" },
+ "\t\t[eku-none=true|false]\n\n"
+ "\tmodify plugin keystore=keystorename option=optionstring\n"},
+
{ "import", kc_import, "import [dbfile=dbfile] policy=policyname "
"infile=inputdbfile\n" },
{ "export", kc_export, "export [dbfile=dbfile] policy=policyname "
"outfile=newdbfile\n" },
+ { "install", kc_install, "install keystore=keystorename "
+ "modulepath=path [option=optionstring]\n"},
+ { "uninstall", kc_uninstall, "uninstall keystore=keystorename\n"},
{ "-?", kc_help, "help"},
{ "help", kc_help, ""}
};
@@ -235,6 +244,10 @@ main(int argc, char *argv[])
break;
case KC_ERR_ACCESS:
break;
+ case KC_ERR_INSTALL:
+ break;
+ case KC_ERR_UNINSTALL:
+ break;
default:
(void) fprintf(stderr, gettext("%s operation failed. "
"error 0x%02x\n"), cmds[found].verb, ret);
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/list.c b/usr/src/cmd/cmd-crypto/kmfcfg/list.c
index b05400a2fd..ff2f83a8d5 100644
--- a/usr/src/cmd/cmd-crypto/kmfcfg/list.c
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/list.c
@@ -30,10 +30,13 @@
#include <libgen.h>
#include <libintl.h>
#include <errno.h>
+#include <sys/stat.h>
#include <kmfapiP.h>
-
#include "util.h"
+#define LIB_NSS_PATH "/usr/lib/mps/libnss3.so"
+#define LIB_NSPR_PATH "/usr/lib/mps/libnspr4.so"
+
static void
show_policy(KMF_POLICY_RECORD *plc)
{
@@ -162,6 +165,46 @@ show_policy(KMF_POLICY_RECORD *plc)
(void) printf("\n");
}
+void
+show_plugin(void)
+{
+ conf_entrylist_t *phead = NULL;
+ struct stat statbuf;
+
+ (void) printf(gettext("KMF plugin information:\n"));
+ (void) printf(gettext("-----------------------\n"));
+
+ /* List the built-in plugins */
+ (void) printf("pkcs11:kmf_pkcs11.so.1 (built-in)\n");
+ (void) printf("file:kmf_openssl.so.1 (built-in)\n");
+
+ /*
+ * If the NSS libraries are not installed in the system,
+ * then we will not show the nss plugin either.
+ */
+ if (stat(LIB_NSS_PATH, &statbuf) == 0 &&
+ stat(LIB_NSPR_PATH, &statbuf) == 0) {
+ (void) printf("nss:kmf_nss.so.1 (built-in)\n");
+ }
+
+ /* List non-default plugins, if there is any. */
+ if (get_entrylist(&phead) == KMF_OK) {
+ while (phead != NULL) {
+ (void) printf("%s:%s", phead->entry->keystore,
+ phead->entry->modulepath);
+
+ if (phead->entry->option == NULL)
+ (void) printf("\n");
+ else
+ (void) printf(";option=%s\n",
+ phead->entry->option);
+ phead = phead->next;
+ }
+ free_entrylist(phead);
+ }
+}
+
+
int
kc_list(int argc, char *argv[])
{
@@ -173,28 +216,41 @@ kc_list(int argc, char *argv[])
char *policyname = NULL;
POLICY_LIST *plclist = NULL, *pnode;
int sanity_err = 0;
+ boolean_t list_plugin = B_FALSE;
- while ((opt = getopt_av(argc, argv, "i:(dbfile)p:(policy)")) != EOF) {
+ while ((opt = getopt_av(argc, argv, "i:(dbfile)p:(policy)m(plugin)"))
+ != EOF) {
switch (opt) {
- case 'i':
+ case 'i':
+ if (list_plugin)
+ rv = KC_ERR_USAGE;
+ else {
filename = get_string(optarg_av, &rv);
if (filename == NULL) {
(void) fprintf(stderr,
gettext("Error dbfile input.\n"));
}
- break;
- case 'p':
+ }
+ break;
+ case 'p':
+ if (list_plugin)
+ rv = KC_ERR_USAGE;
+ else {
policyname = get_string(optarg_av, &rv);
if (policyname == NULL) {
(void) fprintf(stderr,
gettext("Error policy name.\n"));
}
- break;
- default:
- (void) fprintf(stderr,
- gettext("Error input option.\n"));
- rv = KC_ERR_USAGE;
- break;
+ }
+ break;
+ case 'm':
+ list_plugin = B_TRUE;
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("Error input option.\n"));
+ rv = KC_ERR_USAGE;
+ break;
}
if (rv != KC_OK)
goto out;
@@ -209,6 +265,11 @@ kc_list(int argc, char *argv[])
goto out;
}
+ if (list_plugin) {
+ show_plugin();
+ goto out;
+ }
+
if (filename == NULL) {
filename = strdup(KMF_DEFAULT_POLICY_FILE);
if (filename == NULL) {
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/modify.c b/usr/src/cmd/cmd-crypto/kmfcfg/modify.c
index de9f7539ee..462a35f705 100644
--- a/usr/src/cmd/cmd-crypto/kmfcfg/modify.c
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/modify.c
@@ -32,6 +32,8 @@
#include <errno.h>
#include <kmfapiP.h>
#include <cryptoutil.h>
+#include <sys/stat.h>
+#include <sys/param.h>
#include "util.h"
#define KC_IGNORE_DATE 0x0000001
@@ -60,8 +62,11 @@
#define KC_EKUS 0x0800000
#define KC_EKUS_NONE 0x1000000
+static int err; /* To store errno which may be overwritten by gettext() */
+
+
int
-kc_modify(int argc, char *argv[])
+kc_modify_policy(int argc, char *argv[])
{
KMF_RETURN ret;
int rv = KC_OK;
@@ -843,3 +848,258 @@ out:
return (rv);
}
+
+
+static int
+kc_modify_plugin(int argc, char *argv[])
+{
+ int rv = KC_OK;
+ int opt;
+ extern int optind_av;
+ extern char *optarg_av;
+ char *keystore_name = NULL;
+ char *option = NULL;
+ boolean_t modify_plugin = B_FALSE;
+ boolean_t has_option_arg = B_FALSE;
+ conf_entry_t *entry = NULL;
+ FILE *pfile = NULL;
+ FILE *pfile_tmp = NULL;
+ char tmpfile_name[MAXPATHLEN];
+ char buffer[MAXPATHLEN];
+ char buffer2[MAXPATHLEN];
+
+ while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)"))
+ != EOF) {
+ switch (opt) {
+ case 'p':
+ if (modify_plugin) {
+ (void) fprintf(stderr,
+ gettext("duplicate plugin input.\n"));
+ rv = KC_ERR_USAGE;
+ } else {
+ modify_plugin = B_TRUE;
+ }
+ break;
+ case 'k':
+ if (keystore_name != NULL)
+ rv = KC_ERR_USAGE;
+ else {
+ keystore_name = get_string(optarg_av, &rv);
+ if (keystore_name == NULL) {
+ (void) fprintf(stderr, gettext(
+ "Error keystore input.\n"));
+ rv = KC_ERR_USAGE;
+ }
+ }
+ break;
+ case 'o':
+ if (has_option_arg) {
+ (void) fprintf(stderr,
+ gettext("duplicate option input.\n"));
+ rv = KC_ERR_USAGE;
+ } else {
+ has_option_arg = B_TRUE;
+ option = get_string(optarg_av, NULL);
+ }
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("Error input option.\n"));
+ rv = KC_ERR_USAGE;
+ break;
+ }
+
+ if (rv != KC_OK)
+ goto out;
+ }
+
+ /* No additional args allowed. */
+ argc -= optind_av;
+ if (argc) {
+ (void) fprintf(stderr,
+ gettext("Error input option\n"));
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if (keystore_name == NULL || has_option_arg == B_FALSE) {
+ (void) fprintf(stderr,
+ gettext("Error input option\n"));
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if (strcasecmp(keystore_name, "nss") == 0 ||
+ strcasecmp(keystore_name, "pkcs11") == 0 ||
+ strcasecmp(keystore_name, "file") == 0) {
+ (void) fprintf(stderr,
+ gettext("Can not modify the built-in keystore %s\n"),
+ keystore_name);
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ entry = get_keystore_entry(keystore_name);
+ if (entry == NULL) {
+ (void) fprintf(stderr, gettext("%s does not exist.\n"),
+ keystore_name);
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if ((entry->option == NULL && option == NULL) ||
+ (entry->option != NULL && option != NULL &&
+ strcmp(entry->option, option) == 0)) {
+ (void) fprintf(stderr, gettext("No change - "
+ "the new option is same as the old option.\n"));
+ rv = KC_OK;
+ goto out;
+ }
+
+ if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to update the configuration - %s\n"),
+ strerror(err));
+ rv = KC_ERR_ACCESS;
+ goto out;
+ }
+
+ if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to lock the configuration - %s\n"),
+ strerror(err));
+ rv = KC_ERR_MODIFY_PLUGIN;
+ goto out;
+ }
+
+ /*
+ * Create a temporary file in the /etc/crypto directory.
+ */
+ (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name));
+ if (mkstemp(tmpfile_name) == -1) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to create a temporary file - %s\n"),
+ strerror(err));
+ rv = KC_ERR_MODIFY_PLUGIN;
+ goto out;
+ }
+
+ if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to open %s - %s\n"),
+ tmpfile_name, strerror(err));
+ rv = KC_ERR_MODIFY_PLUGIN;
+ goto out;
+ }
+
+ /*
+ * Loop thru the config file and update the entry.
+ */
+ while (fgets(buffer, MAXPATHLEN, pfile) != NULL) {
+ char *name;
+ int len;
+
+ if (buffer[0] == '#') {
+ if (fputs(buffer, pfile_tmp) == EOF) {
+ rv = KC_ERR_MODIFY_PLUGIN;
+ goto out;
+ } else {
+ continue;
+ }
+ }
+
+ /*
+ * make a copy of the original buffer to buffer2. Also get
+ * rid of the trailing '\n' from buffer2.
+ */
+ (void) strlcpy(buffer2, buffer, MAXPATHLEN);
+ len = strlen(buffer2);
+ if (buffer2[len-1] == '\n') {
+ len--;
+ }
+ buffer2[len] = '\0';
+
+ if ((name = strtok(buffer2, SEP_COLON)) == NULL) {
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+
+ if (strcmp(name, keystore_name) == 0) {
+ /* found the entry */
+ if (option == NULL)
+ (void) snprintf(buffer, MAXPATHLEN,
+ "%s:%s%s\n", keystore_name,
+ CONF_MODULEPATH, entry->modulepath);
+ else
+ (void) snprintf(buffer, MAXPATHLEN,
+ "%s:%s%s;%s%s\n", keystore_name,
+ CONF_MODULEPATH, entry->modulepath,
+ CONF_OPTION, option);
+
+ if (fputs(buffer, pfile_tmp) == EOF) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to write to %s: %s\n"),
+ tmpfile_name, strerror(err));
+ rv = KC_ERR_MODIFY_PLUGIN;
+ goto out;
+ }
+ } else {
+
+ if (fputs(buffer, pfile_tmp) == EOF) {
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+ }
+ }
+
+ if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to update the configuration - %s"), strerror(err));
+ rv = KC_ERR_MODIFY_PLUGIN;
+ goto out;
+ }
+
+ if (chmod(_PATH_KMF_CONF,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to update the configuration - %s\n"),
+ strerror(err));
+ rv = KC_ERR_MODIFY_PLUGIN;
+ goto out;
+ }
+
+out:
+ if (entry != NULL)
+ free_entry(entry);
+
+ if (pfile != NULL)
+ (void) fclose(pfile);
+
+ if (rv != KC_OK && pfile_tmp != NULL)
+ (void) unlink(tmpfile_name);
+
+ if (pfile_tmp != NULL)
+ (void) fclose(pfile_tmp);
+
+ return (rv);
+}
+
+
+int
+kc_modify(int argc, char *argv[])
+{
+ if (argc > 2 &&
+ strcmp(argv[0], "modify") == 0 &&
+ strcmp(argv[1], "plugin") == 0) {
+ return (kc_modify_plugin(argc, argv));
+ } else {
+ return (kc_modify_policy(argc, argv));
+ }
+}
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/uninstall.c b/usr/src/cmd/cmd-crypto/kmfcfg/uninstall.c
new file mode 100644
index 0000000000..72de8e627c
--- /dev/null
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/uninstall.c
@@ -0,0 +1,248 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <strings.h>
+#include <ctype.h>
+#include <libgen.h>
+#include <libintl.h>
+#include <errno.h>
+#include <kmfapiP.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <cryptoutil.h>
+#include "util.h"
+
+static int err; /* To store errno which may be overwritten by gettext() */
+
+int
+kc_uninstall(int argc, char *argv[])
+{
+ int rv = KC_OK;
+ int opt;
+ extern int optind_av;
+ extern char *optarg_av;
+ char *keystore_name = NULL;
+ conf_entry_t *entry = NULL;
+ FILE *pfile = NULL;
+ FILE *pfile_tmp = NULL;
+ char tmpfile_name[MAXPATHLEN];
+ char buffer[MAXPATHLEN];
+ char buffer2[MAXPATHLEN];
+ boolean_t found;
+ boolean_t in_package;
+
+ while ((opt = getopt_av(argc, argv, "k:(keystore)")) != EOF) {
+ switch (opt) {
+ case 'k':
+ if (keystore_name != NULL)
+ rv = KC_ERR_USAGE;
+ else {
+ keystore_name = get_string(optarg_av, &rv);
+ if (keystore_name == NULL) {
+ (void) fprintf(stderr, gettext(
+ "Error keystore input.\n"));
+ }
+ }
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("Error input option.\n"));
+ rv = KC_ERR_USAGE;
+ break;
+ }
+ if (rv != KC_OK)
+ goto out;
+ }
+
+ /* No additional args allowed. */
+ argc -= optind_av;
+ if (argc) {
+ (void) fprintf(stderr,
+ gettext("Error input option\n"));
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if (keystore_name == NULL) {
+ (void) fprintf(stderr,
+ gettext("Error input option\n"));
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if (strcasecmp(keystore_name, "nss") == 0 ||
+ strcasecmp(keystore_name, "pkcs11") == 0 ||
+ strcasecmp(keystore_name, "file") == 0) {
+ (void) fprintf(stderr,
+ gettext("Can not uninstall the built-in keystore %s\n"),
+ keystore_name);
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+
+ entry = get_keystore_entry(keystore_name);
+ if (entry == NULL) {
+ (void) fprintf(stderr, gettext("%s does not exist.\n"),
+ keystore_name);
+ rv = KC_ERR_USAGE;
+ goto out;
+ }
+
+ if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to update the configuration - %s\n"),
+ strerror(err));
+ rv = KC_ERR_ACCESS;
+ goto out;
+ }
+
+ if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to lock the configuration - %s\n"),
+ strerror(err));
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+
+ /*
+ * Create a temporary file in the /etc/crypto directory.
+ */
+ (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name));
+ if (mkstemp(tmpfile_name) == -1) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to create a temporary file - %s\n"),
+ strerror(err));
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+
+ if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("failed to open a temporary file - %s\n"),
+ strerror(err));
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+
+ /*
+ * Loop thru the config file. If the plugin to be uninstalled is in
+ * a package, then just comment it off.
+ */
+ in_package = B_FALSE;
+ while (fgets(buffer, MAXPATHLEN, pfile) != NULL) {
+ found = B_FALSE;
+ if (buffer[0] != ' ' && buffer[0] != '\n' &&
+ buffer[0] != '\t') {
+ if (strstr(buffer, " Start ") != NULL) {
+ in_package = B_TRUE;
+ } else if (strstr(buffer, " End ") != NULL) {
+ in_package = B_FALSE;
+ } else if (buffer[0] != '#') {
+ char *name;
+ int len;
+
+ /*
+ * make a copy of the original buffer to
+ * buffer2. Also get rid of the trailing
+ * '\n' from buffer2.
+ */
+ (void) strlcpy(buffer2, buffer, MAXPATHLEN);
+ /* get rid of trailing '\n' */
+ len = strlen(buffer2);
+ if (buffer2[len-1] == '\n') {
+ len--;
+ }
+ buffer2[len] = '\0';
+
+ if ((name = strtok(buffer2, SEP_COLON)) ==
+ NULL) {
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+
+ if (strcmp(keystore_name, name) == 0)
+ found = B_TRUE;
+ }
+ }
+
+ if (found) {
+ /*
+ * If found and not in_package, then don't write
+ * this line to the result file.
+ */
+ if (in_package) {
+ (void) snprintf(buffer2, sizeof (buffer2),
+ "%s%s", "#", buffer);
+
+ if (fputs(buffer2, pfile_tmp) == EOF) {
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+ }
+ } else {
+ if (fputs(buffer, pfile_tmp) == EOF) {
+ rv = KC_ERR_UNINSTALL;
+ goto out;
+ }
+ }
+ }
+
+out:
+ if (pfile != NULL)
+ (void) fclose(pfile);
+
+ if (rv != KC_OK && pfile_tmp != NULL)
+ (void) unlink(tmpfile_name);
+
+ if (pfile_tmp != NULL)
+ (void) fclose(pfile_tmp);
+
+ if (rv == KC_OK) {
+ if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to update the configuration - %s"),
+ strerror(err));
+ return (KC_ERR_UNINSTALL);
+ }
+
+ if (chmod(_PATH_KMF_CONF,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
+ err = errno;
+ (void) fprintf(stderr, gettext(
+ "failed to update the configuration - %s\n"),
+ strerror(err));
+ return (KC_ERR_UNINSTALL);
+ }
+ }
+
+ return (rv);
+}
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/util.c b/usr/src/cmd/cmd-crypto/kmfcfg/util.c
index 3fce0c839d..f151e454ce 100644
--- a/usr/src/cmd/cmd-crypto/kmfcfg/util.c
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/util.c
@@ -34,9 +34,9 @@
#include <libxml/parser.h>
#include <kmfapiP.h>
-
#include "util.h"
+
/* Supporting structures and global variables for getopt_av(). */
typedef struct av_opts_s {
int shortnm; /* short name character */
@@ -490,3 +490,31 @@ print_sanity_error(KMF_RETURN ret)
break;
}
}
+
+
+conf_entry_t *
+get_keystore_entry(char *kstore_name)
+{
+ conf_entrylist_t *phead = NULL;
+ conf_entrylist_t *ptr;
+ conf_entry_t *rtn_entry = NULL;
+
+ if (kstore_name == NULL)
+ return (NULL);
+
+ if (get_entrylist(&phead) != KMF_OK)
+ return (NULL);
+
+ ptr = phead;
+ while (ptr != NULL) {
+ if (strcmp(ptr->entry->keystore, kstore_name) == 0)
+ break;
+ ptr = ptr->next;
+ }
+
+ if (ptr != NULL) /* found the entry */
+ rtn_entry = dup_entry(ptr->entry);
+
+ free_entrylist(phead);
+ return (rtn_entry);
+}
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/util.h b/usr/src/cmd/cmd-crypto/kmfcfg/util.h
index 74f4b0be9b..db1af092e4 100644
--- a/usr/src/cmd/cmd-crypto/kmfcfg/util.h
+++ b/usr/src/cmd/cmd-crypto/kmfcfg/util.h
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _UTIL_H
@@ -49,6 +49,8 @@ int parseEKUNames(char *, KMF_POLICY_RECORD *);
uint16_t parseKUlist(char *);
void print_sanity_error(KMF_RETURN);
+conf_entry_t *get_keystore_entry(char *);
+
#define KC_OK 0
#define KC_ERR_USAGE 1
#define KC_ERR_LOADDB 2
@@ -59,6 +61,11 @@ void print_sanity_error(KMF_RETURN);
#define KC_ERR_INCOMPLETE_POLICY 7
#define KC_ERR_MEMORY 8
#define KC_ERR_ACCESS 9
+#define KC_ERR_INSTALL 10
+#define KC_ERR_UNINSTALL 11
+#define KC_ERR_MODIFY_PLUGIN 12
+
+#define CONF_TEMPFILE "/etc/crypto/kmfXXXXXX"
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/cmd-crypto/pktool/list.c b/usr/src/cmd/cmd-crypto/pktool/list.c
index 0cc686ebc2..934d3f4df1 100644
--- a/usr/src/cmd/cmd-crypto/pktool/list.c
+++ b/usr/src/cmd/cmd-crypto/pktool/list.c
@@ -514,7 +514,7 @@ list_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
char *issuer, char *subject,
KMF_CERT_VALIDITY find_criteria_flag)
{
- int rv;
+ KMF_RETURN rv = KMF_OK;
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
int numattr = 0;
KMF_ATTRIBUTE attrlist[16];
diff --git a/usr/src/cmd/cmd-crypto/scripts/Makefile b/usr/src/cmd/cmd-crypto/scripts/Makefile
index 9aa297ad53..44b8c971c6 100644
--- a/usr/src/cmd/cmd-crypto/scripts/Makefile
+++ b/usr/src/cmd/cmd-crypto/scripts/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -29,7 +29,9 @@ CLASS_ACTION_SCRIPTS = \
i.kcfconf \
r.kcfconf \
i.pkcs11conf \
- r.pkcs11conf
+ r.pkcs11conf \
+ i.kmfconf \
+ r.kmfconf
MANIFEST = cryptosvc.xml
diff --git a/usr/src/cmd/cmd-crypto/scripts/i.kmfconf b/usr/src/cmd/cmd-crypto/scripts/i.kmfconf
new file mode 100644
index 0000000000..52b06b088c
--- /dev/null
+++ b/usr/src/cmd/cmd-crypto/scripts/i.kmfconf
@@ -0,0 +1,116 @@
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# 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
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Class action script for "kmfconf" class files.
+#
+# This script appends the input file from the package to the
+# /etc/crypto/kmf.conf file.
+#
+# The syntax of the input file is
+# keystore:modulepath=path[;option=option_str]
+#
+#
+pkg_start="# Start $PKGINST"
+pkg_end="# End $PKGINST"
+tmpfile=/tmp/$$kmfconf
+error=no
+
+while read src dest
+do
+ [ "$src" = /dev/null ] && continue
+
+ if [ -f "$dest" ]
+ then
+ # For multiple input files; exit if error occurred in previous
+ # input file.
+ if [ "$error" = yes ]
+ then
+ echo "$0: failed to update $lastdest for $PKGINST."
+ exit 2
+ fi
+ lastdest=$dest
+
+ #
+ # If the package has been already installed, remove old entries
+ #
+ start=0;
+ end=0;
+ egrep -s "$pkg_start" $dest && start=1
+ egrep -s "$pkg_end" $dest && end=1
+
+ if [ $start -ne $end ]
+ then
+ echo "$0: missing Start or End delimiters for \
+ $PKGINST in $dest."
+ echo "$0: $dest may be corrupted and was not updated."
+ error=yes
+ continue
+ fi
+
+ if [ $start -eq 1 ]
+ then
+ sed -e "/$pkg_start/,/$pkg_end/d" $dest > $tmpfile \
+ || error=yes
+ else
+ cp $dest $tmpfile || error=yes
+ fi
+
+ #
+ # Check the input file syntax (should at least contain
+ # ":module_path="). Then append the input entries with the
+ #scc package delimiters.
+ #
+ line_count=`wc -l $src | awk '{ print $1}'`
+ file_count=`grep ":modulepath=" $src | wc -l`
+ if [ $line_count -ne $file_count ]
+ then
+ echo "$0: Syntax Error - $src for $PKGINST."
+ error=yes
+ continue
+ else
+ echo "$pkg_start" >> $tmpfile || error=yes
+ cat $src >> $tmpfile || error=yes
+ echo "$pkg_end" >> $tmpfile || error=yes
+ fi
+
+ # Install the updated config file and clean up the tmp file
+ if [ "$error" = no ]
+ then
+ mv $tmpfile $dest || error=yes
+ fi
+ rm -f $tmpfile
+ else
+ echo "$0: ERROR - $dest doesn't exist for $PKGINST."
+ exit 2
+ fi
+done
+
+if [ "$error" = yes ]
+then
+ echo "$0: ERROR - failed to update $lastdest for $PKGINST."
+ exit 2
+fi
+
+exit 0
diff --git a/usr/src/cmd/cmd-crypto/scripts/r.kmfconf b/usr/src/cmd/cmd-crypto/scripts/r.kmfconf
new file mode 100644
index 0000000000..8c35957f76
--- /dev/null
+++ b/usr/src/cmd/cmd-crypto/scripts/r.kmfconf
@@ -0,0 +1,81 @@
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# 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
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Removal class action script for "kmfconf" class files.
+#
+# This script removes entries belonging to the package from the
+# /etc/crypto/kmf.conf file.
+#
+
+pkg_start="# Start $PKGINST"
+pkg_end="# End $PKGINST"
+tmpfile=/tmp/$$kmfconf
+error=no
+
+while read dest
+do
+ # For multiple input files; exit if error occurred in preious
+ # input file.
+ if [ "$error" = yes ]
+ then
+ echo "$0: failed to update $lastdest for $PKGINST."
+ exit 2
+ fi
+ lastdest=$dest
+
+ # Strip all entries belonging to this package
+ start=0
+ end=0
+ egrep -s "$pkg_start" $dest && start=1
+ egrep -s "$pkg_end" $dest && end=1
+
+ if [ $start -ne $end ] ; then
+ echo "$0: missing Start or End delimiters for $PKGINST in \
+ $dest."
+ echo "$0: $dest may be corrupted and was not updated."
+ error=yes
+ continue
+ fi
+
+ if [ $start -eq 1 ]
+ then
+ sed -e "/$pkg_start/,/$pkg_end/d" $dest > $tmpfile || error=yes
+ if [ "$error" = no ]
+ then
+ mv $tmpfile $dest || error=yes
+ fi
+ rm -f $tmpfile
+ else
+ echo "$0: WARNING - no entries found in $dest for $PKGINST."
+ exit 0
+ fi
+done
+
+if [ "$error" = yes ]
+then
+ echo "$0: ERROR - failed to update $lastdest for $PKGINST."
+ exit 2
+fi
+exit 0
diff --git a/usr/src/lib/libkmf/include/kmfapi.h b/usr/src/lib/libkmf/include/kmfapi.h
index ad732f6ffd..85a54175ca 100644
--- a/usr/src/lib/libkmf/include/kmfapi.h
+++ b/usr/src/lib/libkmf/include/kmfapi.h
@@ -289,6 +289,9 @@ extern char *kmf_ku_to_string(uint32_t);
extern KMF_RETURN kmf_hexstr_to_bytes(unsigned char *, unsigned char **,
size_t *);
+extern KMF_RETURN kmf_get_plugin_info(KMF_HANDLE_T, char *,
+ KMF_KEYSTORE_TYPE *, char **);
+
#define KMF_CompareRDNs kmf_compare_rdns
/*
diff --git a/usr/src/lib/libkmf/include/kmfapiP.h b/usr/src/lib/libkmf/include/kmfapiP.h
index ac89acb565..948f3acfb8 100644
--- a/usr/src/lib/libkmf/include/kmfapiP.h
+++ b/usr/src/lib/libkmf/include/kmfapiP.h
@@ -330,6 +330,29 @@ typedef enum {
#define OCSPREQ_TEMPNAME "/tmp/ocsp.reqXXXXXX"
#define OCSPRESP_TEMPNAME "/tmp/ocsp.respXXXXXX"
+#define _PATH_KMF_CONF "/etc/crypto/kmf.conf"
+#define CONF_MODULEPATH "modulepath="
+#define CONF_OPTION "option="
+
+typedef struct {
+ char *keystore;
+ char *modulepath;
+ char *option;
+ KMF_KEYSTORE_TYPE kstype;
+} conf_entry_t;
+
+typedef struct conf_entrylist {
+ conf_entry_t *entry;
+ struct conf_entrylist *next;
+} conf_entrylist_t;
+
+
+extern KMF_RETURN get_entrylist(conf_entrylist_t **);
+extern void free_entrylist(conf_entrylist_t *);
+extern void free_entry(conf_entry_t *);
+extern conf_entry_t *dup_entry(conf_entry_t *);
+boolean_t is_valid_keystore_type(KMF_KEYSTORE_TYPE);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libkmf/include/kmftypes.h b/usr/src/lib/libkmf/include/kmftypes.h
index 211525f974..cb970800db 100644
--- a/usr/src/lib/libkmf/include/kmftypes.h
+++ b/usr/src/lib/libkmf/include/kmftypes.h
@@ -74,14 +74,12 @@ typedef struct
KMF_X509_PRIVATE kmf_private;
} KMF_X509_DER_CERT;
-typedef enum {
- KMF_KEYSTORE_NSS = 1,
- KMF_KEYSTORE_OPENSSL = 2,
- KMF_KEYSTORE_PK11TOKEN = 3,
- KMF_KEYSTORE_DEFAULT /* based on configuration */
-} KMF_KEYSTORE_TYPE;
+typedef int KMF_KEYSTORE_TYPE;
+#define KMF_KEYSTORE_NSS 1
+#define KMF_KEYSTORE_OPENSSL 2
+#define KMF_KEYSTORE_PK11TOKEN 3
-#define VALID_KEYSTORE_TYPE(t) ((t >= KMF_KEYSTORE_NSS) &&\
+#define VALID_DEFAULT_KEYSTORE_TYPE(t) ((t >= KMF_KEYSTORE_NSS) &&\
(t <= KMF_KEYSTORE_PK11TOKEN))
typedef enum {
@@ -291,6 +289,7 @@ typedef enum {
KMF_ERR_OCSP_RESPONSE_STATUS = 0x2f,
KMF_ERR_OCSP_NO_BASIC_RESPONSE = 0x30,
KMF_ERR_OCSP_BAD_SIGNER = 0x31,
+
KMF_ERR_OCSP_RESPONSE_SIGNATURE = 0x32,
KMF_ERR_OCSP_UNKNOWN_CERT = 0x33,
KMF_ERR_OCSP_STATUS_TIME_INVALID = 0x34,
@@ -325,7 +324,8 @@ typedef enum {
KMF_ERR_SENSITIVE_KEY = 0x51,
KMF_ERR_UNEXTRACTABLE_KEY = 0x52,
KMF_ERR_KEY_MISMATCH = 0x53,
- KMF_ERR_ATTR_NOT_FOUND = 0x54
+ KMF_ERR_ATTR_NOT_FOUND = 0x54,
+ KMF_ERR_KMF_CONF = 0x55
} KMF_RETURN;
/* Data structures for OCSP support */
diff --git a/usr/src/lib/libkmf/libkmf/common/certop.c b/usr/src/lib/libkmf/libkmf/common/certop.c
index 4d5e151ce7..5889ffe77e 100644
--- a/usr/src/lib/libkmf/libkmf/common/certop.c
+++ b/usr/src/lib/libkmf/libkmf/common/certop.c
@@ -1371,7 +1371,7 @@ cert_crl_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
issuer_cert == NULL)
return (KMF_ERR_BAD_PARAMETER);
- if (!VALID_KEYSTORE_TYPE(*kstype))
+ if (!is_valid_keystore_type(*kstype))
return (KMF_ERR_BAD_PARAMETER);
policy = handle->policy;
@@ -1985,7 +1985,7 @@ find_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
issuer_cert == NULL)
return (KMF_ERR_BAD_PARAMETER);
- if (!VALID_KEYSTORE_TYPE(*kstype))
+ if (!is_valid_keystore_type(*kstype))
return (KMF_ERR_BAD_PARAMETER);
kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR,
@@ -2117,7 +2117,7 @@ find_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
user_issuerDN == NULL)
return (KMF_ERR_BAD_PARAMETER);
- if (!VALID_KEYSTORE_TYPE(*kstype))
+ if (!is_valid_keystore_type(*kstype))
return (KMF_ERR_BAD_PARAMETER);
/* Get the TA name and serial number from the policy */
diff --git a/usr/src/lib/libkmf/libkmf/common/generalop.c b/usr/src/lib/libkmf/libkmf/common/generalop.c
index 1e2f2504a4..e5a19df4b5 100644
--- a/usr/src/lib/libkmf/libkmf/common/generalop.c
+++ b/usr/src/lib/libkmf/libkmf/common/generalop.c
@@ -159,6 +159,22 @@ static KMF_RETURN AddPlugin(KMF_HANDLE_T, KMF_PLUGIN *);
static void free_extensions(KMF_X509_EXTENSIONS *extns);
static void DestroyPlugin(KMF_PLUGIN *);
+#if defined(__sparcv9)
+#define ISA_PATH "/sparcv9"
+#elif defined(__sparc)
+#define ISA_PATH "/"
+#elif defined(__i386)
+#define ISA_PATH "/"
+#elif defined(__amd64)
+#define ISA_PATH "/amd64"
+#endif
+
+#define DEFAULT_KEYSTORE_NUM 3
+static int kstore_num = DEFAULT_KEYSTORE_NUM;
+conf_entrylist_t *extra_plugin_list = NULL;
+static boolean_t check_extra_plugin = B_FALSE;
+mutex_t extra_plugin_lock = DEFAULTMUTEX;
+
KMF_RETURN
init_pk11()
{
@@ -186,6 +202,7 @@ FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype)
{
KMF_PLUGIN_LIST *node;
KMF_RETURN ret = KMF_OK;
+ KMF_PLUGIN *pluginrec = NULL;
if (handle == NULL)
return (NULL);
@@ -196,10 +213,12 @@ FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype)
while (node != NULL && node->plugin->type != kstype)
node = node->next;
- /* If the plugin was not found, try to initialize it here. */
- if (node == NULL) {
+ if (node != NULL)
+ return (node->plugin);
+
+ /* The plugin was not found, try to initialize it here. */
+ if (VALID_DEFAULT_KEYSTORE_TYPE(kstype)) {
int i;
- KMF_PLUGIN *pluginrec = NULL;
int numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM);
for (i = 0; i < numitems; i++) {
if (plugin_list[i].kstype == kstype) {
@@ -209,21 +228,80 @@ FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype)
}
}
- /* No matching plugins found in the available list */
- if (ret != KMF_OK || pluginrec == NULL)
+ goto out;
+
+ } else {
+ /*
+ * Not a built-in plugin. Check if it is in the
+ * extra_plugin_list. If it is, try to initialize it here.
+ */
+ conf_entrylist_t *phead = extra_plugin_list;
+ char realpath[MAXPATHLEN];
+
+ while (phead != NULL) {
+ if (phead->entry->kstype == kstype)
+ break;
+ else
+ phead = phead->next;
+ }
+
+ if (phead == NULL)
return (NULL);
- ret = AddPlugin(handle, pluginrec);
- if (ret != KMF_OK) {
- DestroyPlugin(pluginrec);
- pluginrec = NULL;
+ /*
+ * Get the absolute path of the module.
+ * - If modulepath is not a full path, then prepend it
+ * with KMF_PLUGIN_PATH.
+ * - If modulepath is a full path and contain $ISA, then
+ * subsitute the architecture dependent path.
+ */
+ (void) memset(realpath, 0, sizeof (realpath));
+ if (strncmp(phead->entry->modulepath, "/", 1) != 0) {
+ (void) snprintf(realpath, MAXPATHLEN, "%s%s",
+ KMF_PLUGIN_PATH, phead->entry->modulepath);
+ } else {
+ char *buf = phead->entry->modulepath;
+ char *isa;
+
+ if ((isa = strstr(buf, PKCS11_ISA)) != NULL) {
+ char *isa_str;
+
+ (void) strncpy(realpath, buf, isa - buf);
+ isa_str = strdup(ISA_PATH);
+ if (isa_str == NULL) /* not enough memory */
+ return (NULL);
+
+ (void) strncat(realpath, isa_str,
+ strlen(isa_str));
+ free(isa_str);
+
+ isa += strlen(PKCS11_ISA);
+ (void) strlcat(realpath, isa, MAXPATHLEN);
+ } else {
+ (void) snprintf(realpath, MAXPATHLEN, "%s",
+ phead->entry->modulepath);
+ }
}
- return (pluginrec);
- } else {
- return (node->plugin);
+
+ ret = InitializePlugin(phead->entry->kstype, realpath,
+ &pluginrec);
+ goto out;
+ }
+
+out:
+ if (ret != KMF_OK || pluginrec == NULL)
+ /* No matching plugins found in the built-in list */
+ return (NULL);
+
+ ret = AddPlugin(handle, pluginrec);
+ if (ret != KMF_OK) {
+ DestroyPlugin(pluginrec);
+ pluginrec = NULL;
}
+ return (pluginrec);
}
+
static KMF_RETURN
InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin)
{
@@ -361,6 +439,46 @@ kmf_initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname)
(void) memset(handle, 0, sizeof (KMF_HANDLE));
handle->plugins = NULL;
+ /*
+ * When this function is called the first time, get the additional
+ * plugins from the config file.
+ */
+ (void) mutex_lock(&extra_plugin_lock);
+ if (!check_extra_plugin) {
+
+ ret = get_entrylist(&extra_plugin_list);
+ check_extra_plugin = B_TRUE;
+
+ /*
+ * Assign the kstype number to the additional plugins here.
+ * The global kstore_num will be protected by the mutex lock.
+ */
+ if (ret == KMF_OK) {
+ conf_entrylist_t *phead = extra_plugin_list;
+ while (phead != NULL) {
+ phead->entry->kstype = ++kstore_num;
+ phead = phead->next;
+ }
+ }
+
+ /*
+ * If the KMF configuration file does not exist or cannot be
+ * parsed correctly, we will give a warning in syslog and
+ * continue on as there is no extra plugins in the system.
+ */
+ if (ret == KMF_ERR_KMF_CONF) {
+ cryptoerror(LOG_WARNING, "KMF was unable to parse "
+ "the private KMF config file.\n");
+ ret = KMF_OK;
+ }
+
+ if (ret != KMF_OK) {
+ (void) mutex_unlock(&extra_plugin_lock);
+ goto errout;
+ }
+ }
+ (void) mutex_unlock(&extra_plugin_lock);
+
/* Initialize the handle with the policy */
ret = kmf_set_policy((void *)handle,
policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile,
@@ -2145,6 +2263,286 @@ kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist,
return (rv);
}
+
+void
+free_entry(conf_entry_t *entry)
+{
+ if (entry == NULL)
+ return;
+ free(entry->keystore);
+ free(entry->modulepath);
+ free(entry->option);
+}
+
+void
+free_entrylist(conf_entrylist_t *list)
+{
+ conf_entrylist_t *next;
+
+ while (list != NULL) {
+ next = list->next;
+ free_entry(list->entry);
+ free(list);
+ list = next;
+ }
+}
+
+static KMF_RETURN
+parse_entry(char *buf, conf_entry_t **entry)
+{
+ KMF_RETURN ret = KMF_OK;
+ conf_entry_t *tmp = NULL;
+ char *token1;
+ char *token2;
+ char *token3;
+ char *lasts;
+ char *value;
+
+ if ((token1 = strtok_r(buf, SEP_COLON, &lasts)) == NULL)
+ return (KMF_ERR_KMF_CONF);
+
+ if ((tmp = calloc(sizeof (conf_entry_t), 1)) == NULL)
+ return (KMF_ERR_MEMORY);
+
+ if ((tmp->keystore = strdup(token1)) == NULL) {
+ ret = KMF_ERR_MEMORY;
+ goto end;
+ }
+
+ if ((token2 = strtok_r(NULL, SEP_SEMICOLON, &lasts)) == NULL) {
+ ret = KMF_ERR_KMF_CONF;
+ goto end;
+ }
+
+ /* need to get token3 first to satisfy nested strtok invocations */
+ token3 = strtok_r(NULL, SEP_SEMICOLON, &lasts);
+
+ /* parse token2 */
+ if (strncmp(token2, CONF_MODULEPATH, strlen(CONF_MODULEPATH)) != 0) {
+ ret = KMF_ERR_KMF_CONF;
+ goto end;
+ }
+
+ if (value = strpbrk(token2, SEP_EQUAL)) {
+ value++; /* get rid of = */
+ } else {
+ ret = KMF_ERR_KMF_CONF;
+ goto end;
+ }
+
+ if ((tmp->modulepath = strdup(value)) == NULL) {
+ ret = KMF_ERR_MEMORY;
+ goto end;
+ }
+
+ /* parse token3, if it exists */
+ if (token3 != NULL) {
+ if (strncmp(token3, CONF_OPTION, strlen(CONF_OPTION))
+ != 0) {
+ ret = KMF_ERR_KMF_CONF;
+ goto end;
+ }
+
+ if (value = strpbrk(token3, SEP_EQUAL)) {
+ value++; /* get rid of = */
+ } else {
+ ret = KMF_ERR_KMF_CONF;
+ goto end;
+ }
+
+ if ((tmp->option = strdup(value)) == NULL) {
+ ret = KMF_ERR_MEMORY;
+ goto end;
+ }
+ }
+
+ *entry = tmp;
+
+end:
+ if (ret != KMF_OK) {
+ free_entry(tmp);
+ free(tmp);
+ }
+ return (ret);
+}
+
+
+conf_entry_t *
+dup_entry(conf_entry_t *entry)
+{
+ conf_entry_t *rtn_entry;
+
+ if (entry == NULL)
+ return (NULL);
+
+ rtn_entry = malloc(sizeof (conf_entry_t));
+ if (rtn_entry == NULL)
+ return (NULL);
+
+ if ((rtn_entry->keystore = strdup(entry->keystore)) == NULL)
+ goto out;
+
+ if ((rtn_entry->modulepath = strdup(entry->modulepath)) == NULL)
+ goto out;
+
+ if (entry->option != NULL &&
+ (rtn_entry->option = strdup(entry->modulepath)) == NULL)
+ goto out;
+
+ return (rtn_entry);
+
+out:
+ free_entry(rtn_entry);
+ return (NULL);
+}
+
+
+/*
+ * This function takes a keystore_name as input and returns
+ * the KMF_KEYSTORE_TYPE value assigned to it. If the "option"
+ * argument is not NULL, this function also returns the option string
+ * if there is an option string for the plugin module.
+ */
+KMF_RETURN
+kmf_get_plugin_info(KMF_HANDLE_T handle, char *keystore_name,
+ KMF_KEYSTORE_TYPE *kstype, char **option)
+{
+ KMF_RETURN ret = KMF_OK;
+ conf_entrylist_t *phead = extra_plugin_list;
+ boolean_t is_default = B_TRUE;
+
+ /*
+ * Although handle is not really used in the function, we will
+ * check the handle to make sure that kmf_intialize() is called
+ * before this function.
+ */
+ if (handle == NULL || keystore_name == NULL || kstype == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ if (strcmp(keystore_name, "pkcs11") == 0) {
+ *kstype = KMF_KEYSTORE_PK11TOKEN;
+ } else if (strcmp(keystore_name, "file") == 0) {
+ *kstype = KMF_KEYSTORE_OPENSSL;
+ } else if (strcmp(keystore_name, "nss") == 0) {
+ *kstype = KMF_KEYSTORE_NSS;
+ } else {
+ is_default = B_FALSE;
+ }
+
+ if (is_default) {
+ if (option != NULL)
+ *option = NULL;
+ goto out;
+ }
+
+ /* Not a built-in plugin; check if it is in extra_plugin_list. */
+ while (phead != NULL) {
+ if (strcmp(phead->entry->keystore, keystore_name) == 0)
+ break;
+ phead = phead->next;
+ }
+
+ if (phead == NULL) {
+ ret = KMF_ERR_PLUGIN_NOTFOUND;
+ goto out;
+ }
+
+ /* found it */
+ *kstype = phead->entry->kstype;
+ if (option != NULL) {
+ if (phead->entry->option == NULL)
+ *option = NULL;
+ else {
+ *option = strdup(phead->entry->option);
+ if (*option == NULL) {
+ ret = KMF_ERR_MEMORY;
+ goto out;
+ }
+ }
+ }
+
+out:
+ return (ret);
+}
+
+/*
+ * Retrieve the non-default plugin list from the kmf.conf file.
+ */
+KMF_RETURN
+get_entrylist(conf_entrylist_t **entlist)
+{
+ KMF_RETURN rv = KMF_OK;
+ FILE *pfile;
+ conf_entry_t *entry;
+ conf_entrylist_t *rtnlist = NULL;
+ conf_entrylist_t *ptmp;
+ conf_entrylist_t *pcur;
+ char buffer[MAXPATHLEN];
+ size_t len;
+
+ if ((pfile = fopen(_PATH_KMF_CONF, "rF")) == NULL) {
+ cryptoerror(LOG_ERR, "failed to open %s.\n", _PATH_KMF_CONF);
+ return (KMF_ERR_KMF_CONF);
+ }
+
+ while (fgets(buffer, MAXPATHLEN, pfile) != NULL) {
+ if (buffer[0] == '#' || buffer[0] == ' ' ||
+ buffer[0] == '\n'|| buffer[0] == '\t') {
+ continue; /* ignore comment lines */
+ }
+
+ len = strlen(buffer);
+ if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */
+ len--;
+ }
+ buffer[len] = '\0';
+
+ rv = parse_entry(buffer, &entry);
+ if (rv != KMF_OK) {
+ goto end;
+ }
+
+ if ((ptmp = malloc(sizeof (conf_entrylist_t))) == NULL) {
+ rv = KMF_ERR_MEMORY;
+ goto end;
+ }
+ ptmp->entry = entry;
+ ptmp->next = NULL;
+
+ if (rtnlist == NULL) {
+ rtnlist = pcur = ptmp;
+ } else {
+ pcur->next = ptmp;
+ pcur = ptmp;
+ }
+ }
+
+end:
+ (void) fclose(pfile);
+
+ if (rv == KMF_OK) {
+ *entlist = rtnlist;
+ } else if (rtnlist != NULL) {
+ free_entrylist(rtnlist);
+ *entlist = NULL;
+ kstore_num = DEFAULT_KEYSTORE_NUM;
+ }
+
+ return (rv);
+}
+
+
+boolean_t
+is_valid_keystore_type(KMF_KEYSTORE_TYPE kstype)
+{
+
+ if (kstype > 0 && kstype <= kstore_num)
+ return (B_TRUE);
+ else
+ return (B_FALSE);
+}
+
+
/*
* This API is used by elfsign. We must keep it in old API form.
*/
diff --git a/usr/src/lib/libkmf/libkmf/common/llib-lkmf b/usr/src/lib/libkmf/libkmf/common/llib-lkmf
index 114e823e4d..355ed9bb21 100644
--- a/usr/src/lib/libkmf/libkmf/common/llib-lkmf
+++ b/usr/src/lib/libkmf/libkmf/common/llib-lkmf
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,3 +29,4 @@
/* PROTOLIB1 */
#include <kmfapi.h>
#include <kmfpolicy.h>
+#include <kmfapiP.h>
diff --git a/usr/src/lib/libkmf/libkmf/common/mapfile-vers b/usr/src/lib/libkmf/libkmf/common/mapfile-vers
index 31ef381e6d..4b658709c5 100644
--- a/usr/src/lib/libkmf/libkmf/common/mapfile-vers
+++ b/usr/src/lib/libkmf/libkmf/common/mapfile-vers
@@ -232,6 +232,7 @@ SUNW_1.1 {
kmf_get_ocsp_status_for_cert;
kmf_get_pk11_handle;
kmf_get_plugin_error_str;
+ kmf_get_plugin_info;
kmf_get_policy;
kmf_get_string_attr;
kmf_get_sym_key_value;
@@ -318,6 +319,10 @@ SUNWprivate_1.1 {
KMF_SignDataWithKey;
KMF_VerifyCertWithCert;
KMF_VerifyDataWithCert;
+ dup_entry;
+ free_entry;
+ free_entrylist;
+ get_entrylist;
parsePolicyElement;
PKCS_AcquirePublicKeyHandle;
PKCS_GetDefaultSignatureMode;
diff --git a/usr/src/pkgdefs/SUNWcsr/Makefile b/usr/src/pkgdefs/SUNWcsr/Makefile
index 79c7b8da00..1bd6428e71 100644
--- a/usr/src/pkgdefs/SUNWcsr/Makefile
+++ b/usr/src/pkgdefs/SUNWcsr/Makefile
@@ -44,6 +44,7 @@ DATAFILES += \
i.inetdconf \
i.initd \
i.inittab \
+ i.kmfconfbase \
i.locallogin \
i.localprofile \
i.logadmconf \
diff --git a/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl
index d179b67f7e..3447c3832d 100644
--- a/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWcsr/pkginfo.tmpl
@@ -44,7 +44,7 @@ DESC="core software for a specific instruction-set architecture"
VENDOR="Sun Microsystems, Inc."
HOTLINE="Please contact your local service provider"
EMAIL=""
-CLASSES="none ttydefs initd renamenew preserve cronroot passwd tiservices inetdconf definit etcremote nsswitch netconfig deflogin defsu syslogconf ttysrch group inittab etcrpc etcprofile mailxrc shadow locallogin localprofile logadmconf logindevperm nscd fstypes pamconf services rbac renameold dhcpinittab policyconf pkcs11confbase defpasswd defkbd vfstab manifest hosts"
+CLASSES="none ttydefs initd renamenew preserve cronroot passwd tiservices inetdconf definit etcremote nsswitch netconfig deflogin defsu syslogconf ttysrch group inittab etcrpc etcprofile mailxrc shadow locallogin localprofile logadmconf logindevperm nscd fstypes pamconf services rbac renameold dhcpinittab policyconf pkcs11confbase defpasswd defkbd vfstab manifest hosts kmfconfbase"
BASEDIR=/
SUNW_PKGVERS="1.0"
SUNW_PKG_ALLZONES="true"
diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_com b/usr/src/pkgdefs/SUNWcsr/prototype_com
index e1f1ccf9c9..cceeea6d89 100644
--- a/usr/src/pkgdefs/SUNWcsr/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_com
@@ -83,6 +83,7 @@ i i.manifest
i r.manifest
i i.ttydefs
i i.hosts
+i i.kmfconfbase
#
# source locations relative to the prototype file
#
@@ -109,6 +110,7 @@ e preserve etc/cron.d/cron.deny 644 root sys
f none etc/cron.d/queuedefs 644 root sys
d none etc/crypto 755 root sys
e pkcs11confbase etc/crypto/pkcs11.conf 644 root sys
+e kmfconfbase etc/crypto/kmf.conf 644 root sys
d none etc/crypto/certs 755 root sys
f none etc/crypto/certs/CA 644 root sys
l none etc/crypto/certs/SUNWObjectCA=../../../etc/certs/SUNWObjectCA
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_com b/usr/src/pkgdefs/SUNWcsu/prototype_com
index c4e511b360..2ff0fc1e19 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com
@@ -714,11 +714,13 @@ f none usr/sadm/install/miniroot.db 444 root sys
d none usr/sadm/install/scripts 755 root bin
f none usr/sadm/install/scripts/i.ipsecalgs 555 root sys
f none usr/sadm/install/scripts/i.kcfconf 555 root sys
+f none usr/sadm/install/scripts/i.kmfconf 555 root sys
f none usr/sadm/install/scripts/i.manifest 555 root sys
f none usr/sadm/install/scripts/i.pkcs11conf 555 root sys
f none usr/sadm/install/scripts/i.rbac 555 root sys
f none usr/sadm/install/scripts/r.ipsecalgs 555 root sys
f none usr/sadm/install/scripts/r.kcfconf 555 root sys
+f none usr/sadm/install/scripts/r.kmfconf 555 root sys
f none usr/sadm/install/scripts/r.manifest 555 root sys
f none usr/sadm/install/scripts/r.pkcs11conf 555 root sys
f none usr/sadm/install/scripts/r.rbac 555 root sys
diff --git a/usr/src/pkgdefs/common_files/i.kmfconfbase b/usr/src/pkgdefs/common_files/i.kmfconfbase
new file mode 100644
index 0000000000..9388631174
--- /dev/null
+++ b/usr/src/pkgdefs/common_files/i.kmfconfbase
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+while read src dest
+do
+ if [ ! -f $dest ] ; then
+ cp $src $dest
+ fi
+done
+exit 0