diff options
author | wyllys <none@none> | 2006-11-10 15:34:56 -0800 |
---|---|---|
committer | wyllys <none@none> | 2006-11-10 15:34:56 -0800 |
commit | 99ebb4ca412cb0a19d77a3899a87c055b9c30fa8 (patch) | |
tree | a972f78468519a4e00234388688f45a506e934ba /usr/src/cmd/cmd-crypto/kmfcfg | |
parent | 177fd15c9f814babb60e824f89984cdd8acf7c85 (diff) | |
download | illumos-joyent-99ebb4ca412cb0a19d77a3899a87c055b9c30fa8.tar.gz |
PSARC 2005/074 Solaris Key Management Framework
6224192 Solaris needs unified key management interfaces
--HG--
rename : usr/src/cmd/cmd-crypto/pktool/biginteger.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/biginteger.h
rename : usr/src/cmd/cmd-crypto/pktool/derparse.c => deleted_files/usr/src/cmd/cmd-crypto/pktool/derparse.c
rename : usr/src/cmd/cmd-crypto/pktool/derparse.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/derparse.h
rename : usr/src/cmd/cmd-crypto/pktool/osslcommon.c => deleted_files/usr/src/cmd/cmd-crypto/pktool/osslcommon.c
rename : usr/src/cmd/cmd-crypto/pktool/osslcommon.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/osslcommon.h
rename : usr/src/cmd/cmd-crypto/pktool/p12common.c => deleted_files/usr/src/cmd/cmd-crypto/pktool/p12common.c
rename : usr/src/cmd/cmd-crypto/pktool/p12common.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/p12common.h
Diffstat (limited to 'usr/src/cmd/cmd-crypto/kmfcfg')
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/Makefile | 91 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/create.c | 498 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/delete.c | 132 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/export.c | 167 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/import.c | 169 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c | 245 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.dtd | 84 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.xml | 40 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/list.c | 277 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/modify.c | 845 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/util.c | 497 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/kmfcfg/util.h | 66 |
12 files changed, 3111 insertions, 0 deletions
diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/Makefile b/usr/src/cmd/cmd-crypto/kmfcfg/Makefile new file mode 100644 index 0000000000..86fd4eb30e --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/Makefile @@ -0,0 +1,91 @@ +# +# 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. +# +# ident "%Z%%M% %I% %E% SMI" +# +# Makefile for policy testing code +# + +PROG = kmfcfg + +OBJS = kmfcfg.o \ + list.o \ + delete.o \ + util.o \ + create.o \ + modify.o \ + export.o \ + import.o + +include ../../Makefile.cmd + +KMFDIR = $(SRC)/lib/libkmf +SRCS = $(OBJS:%.o=%.c) + +POFILES = $(OBJS:%.o=%.po) +POFILE = $(PROG)_msg.po +MSGFILES = $(SRCS:%.c=%.i) + +CPPFLAGS += -I/usr/include/libxml2 -I$(KMFDIR)/include -I. +LDLIBS += -L$(ROOT)/usr/lib -lkmf -lcryptoutil +XMLLIB = -lxml2 + +.KEEP_STATE: + +XMLDIR= $(ROOT)/etc/security +DTDDIR= $(ROOT)/usr/share/lib/xml/dtd +ROOTDTDS= $(DTDDIR)/kmfpolicy.dtd +ROOTXML= $(XMLDIR)/kmfpolicy.xml + +$(ROOTDTDS) := FILEMODE = 444 +$(ROOTDTDS) := OWNER = root +$(ROOTDTDS) := GROUP = bin + +$(ROOTXML) := FILEMODE = 644 +$(ROOTXML) := OWNER = root +$(ROOTXML) := GROUP = bin + +all: $(PROG) $(ROOTDTDS) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(XMLLIB) + $(POST_PROCESS) + +$(POFILE): $(POFILES) + $(BUILDPO.pofiles) + +install: all $(ROOTDTDS) $(ROOTXML) $(ROOTPROG) + +$(XMLDIR)/%: % + $(INS.file) + +$(DTDDIR)/%: % + $(INS.file) + +clean: + $(RM) $(OBJS) + +lint : lint_SRCS + +include ../../Makefile.targ diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/create.c b/usr/src/cmd/cmd-crypto/kmfcfg/create.c new file mode 100644 index 0000000000..ceacf5f5d5 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/create.c @@ -0,0 +1,498 @@ +/* + * 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. + */ + +#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 <cryptoutil.h> +#include "util.h" + +int +kc_create(int argc, char *argv[]) +{ + KMF_RETURN ret; + int rv = KC_OK; + int opt; + extern int optind_av; + extern char *optarg_av; + char *filename = NULL; + int ocsp_set_attr = 0; + boolean_t crl_set_attr = 0; + KMF_POLICY_RECORD plc; + + (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); + + while ((opt = getopt_av(argc, argv, + "i:(dbfile)" + "p:(policy)" + "d:(ignore-date)" + "e:(ignore-unknown-eku)" + "a:(ignore-trust-anchor)" + "v:(validity-adjusttime)" + "t:(ta-name)" + "s:(ta-serial)" + "o:(ocsp-responder)" + "P:(ocsp-proxy)" + "r:(ocsp-use-cert-responder)" + "T:(ocsp-response-lifetime)" + "R:(ocsp-ignore-response-sign)" + "n:(ocsp-responder-cert-name)" + "A:(ocsp-responder-cert-serial)" + "c:(crl-basefilename)" + "I:(crl-directory)" + "g:(crl-get-crl-uri)" + "X:(crl-proxy)" + "S:(crl-ignore-crl-sign)" + "D:(crl-ignore-crl-date)" + "u:(keyusage)" + "E:(ekunames)" + "O:(ekuoids)")) != EOF) { + switch (opt) { + case 'i': + filename = get_string(optarg_av, &rv); + if (filename == NULL) { + (void) fprintf(stderr, + gettext("Error dbfile input.\n")); + } + break; + case 'p': + plc.name = get_string(optarg_av, &rv); + if (plc.name == NULL) { + (void) fprintf(stderr, + gettext("Error policy name.\n")); + } + break; + case 'd': + plc.ignore_date = get_boolean(optarg_av); + if (plc.ignore_date == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } + break; + case 'e': + plc.ignore_unknown_ekus = + get_boolean(optarg_av); + if (plc.ignore_unknown_ekus == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } + break; + case 'a': + plc.ignore_trust_anchor = + get_boolean(optarg_av); + if (plc.ignore_trust_anchor == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } + break; + case 'v': + plc.validity_adjusttime = + get_string(optarg_av, &rv); + if (plc.validity_adjusttime == NULL) { + (void) fprintf(stderr, + gettext("Error time input.\n")); + } else { + uint32_t adj; + /* for syntax checking */ + if (str2lifetime( + plc.validity_adjusttime, + &adj) < 0) { + (void) fprintf(stderr, + gettext("Error time " + "input.\n")); + rv = KC_ERR_USAGE; + } + } + break; + case 't': + plc.ta_name = get_string(optarg_av, &rv); + if (plc.ta_name == NULL) { + (void) fprintf(stderr, + gettext("Error name input.\n")); + } else { + KMF_X509_NAME taDN; + /* for syntax checking */ + if (KMF_DNParser(plc.ta_name, + &taDN) != KMF_OK) { + (void) fprintf(stderr, + gettext("Error name " + "input.\n")); + rv = KC_ERR_USAGE; + } else { + KMF_FreeDN(&taDN); + } + } + break; + case 's': + plc.ta_serial = get_string(optarg_av, &rv); + if (plc.ta_serial == NULL) { + (void) fprintf(stderr, + gettext("Error serial input.\n")); + } else { + uchar_t *bytes = NULL; + size_t bytelen; + + ret = KMF_HexString2Bytes( + (uchar_t *)plc.ta_serial, + &bytes, &bytelen); + if (ret != KMF_OK || bytes == NULL) { + (void) fprintf(stderr, + gettext("serial number " + "must be specified as a " + "hex number " + "(ex: 0x0102030405" + "ffeeddee)\n")); + rv = KC_ERR_USAGE; + } + if (bytes != NULL) + free(bytes); + } + break; + case 'o': + plc.VAL_OCSP_RESPONDER_URI = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESPONDER_URI == NULL) { + (void) fprintf(stderr, gettext( + "Error responder input.\n")); + } else { + ocsp_set_attr++; + } + break; + case 'P': + plc.VAL_OCSP_PROXY = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_PROXY == NULL) { + (void) fprintf(stderr, + gettext("Error proxy input.\n")); + } else { + ocsp_set_attr++; + } + break; + case 'r': + plc.VAL_OCSP_URI_FROM_CERT = + get_boolean(optarg_av); + if (plc.VAL_OCSP_URI_FROM_CERT == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + ocsp_set_attr++; + } + break; + case 'T': + plc.VAL_OCSP_RESP_LIFETIME = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { + (void) fprintf(stderr, + gettext("Error time input.\n")); + } else { + uint32_t adj; + /* for syntax checking */ + if (str2lifetime( + plc.VAL_OCSP_RESP_LIFETIME, + &adj) < 0) { + (void) fprintf(stderr, + gettext("Error time " + "input.\n")); + rv = KC_ERR_USAGE; + } else { + ocsp_set_attr++; + } + } + break; + case 'R': + plc.VAL_OCSP_IGNORE_RESP_SIGN = + get_boolean(optarg_av); + if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + ocsp_set_attr++; + } + break; + case 'n': + plc.VAL_OCSP_RESP_CERT_NAME = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { + (void) fprintf(stderr, + gettext("Error name input.\n")); + } else { + KMF_X509_NAME respDN; + /* for syntax checking */ + if (KMF_DNParser( + plc.VAL_OCSP_RESP_CERT_NAME, + &respDN) != KMF_OK) { + (void) fprintf(stderr, + gettext("Error name " + "input.\n")); + rv = KC_ERR_USAGE; + } else { + KMF_FreeDN(&respDN); + ocsp_set_attr++; + } + } + break; + case 'A': + plc.VAL_OCSP_RESP_CERT_SERIAL = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { + (void) fprintf(stderr, + gettext("Error serial input.\n")); + } else { + uchar_t *bytes = NULL; + size_t bytelen; + + ret = KMF_HexString2Bytes((uchar_t *) + plc.VAL_OCSP_RESP_CERT_SERIAL, + &bytes, &bytelen); + if (ret != KMF_OK || bytes == NULL) { + (void) fprintf(stderr, + gettext("serial number " + "must be specified as a " + "hex number " + "(ex: 0x0102030405" + "ffeeddee)\n")); + rv = KC_ERR_USAGE; + break; + } + if (bytes != NULL) + free(bytes); + ocsp_set_attr++; + } + break; + case 'c': + plc.VAL_CRL_BASEFILENAME = + get_string(optarg_av, &rv); + if (plc.VAL_CRL_BASEFILENAME == NULL) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + } else { + crl_set_attr++; + } + break; + case 'I': + plc.VAL_CRL_DIRECTORY = + get_string(optarg_av, &rv); + if (plc.VAL_CRL_DIRECTORY == NULL) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + } else { + crl_set_attr++; + } + break; + case 'g': + plc.VAL_CRL_GET_URI = get_boolean(optarg_av); + if (plc.VAL_CRL_GET_URI == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + crl_set_attr++; + } + break; + case 'X': + plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); + if (plc.VAL_CRL_PROXY == NULL) { + (void) fprintf(stderr, + gettext("Error proxy input.\n")); + } else { + crl_set_attr++; + } + break; + case 'S': + plc.VAL_CRL_IGNORE_SIGN = + get_boolean(optarg_av); + if (plc.VAL_CRL_IGNORE_SIGN == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + crl_set_attr++; + } + break; + case 'D': + plc.VAL_CRL_IGNORE_DATE = + get_boolean(optarg_av); + if (plc.VAL_CRL_IGNORE_DATE == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + crl_set_attr++; + } + break; + case 'u': + plc.ku_bits = parseKUlist(optarg_av); + if (plc.ku_bits == 0) { + (void) fprintf(stderr, gettext( + "Error keyusage input.\n")); + rv = KC_ERR_USAGE; + } + break; + case 'E': + if (parseEKUNames(optarg_av, &plc) != 0) { + (void) fprintf(stderr, + gettext("Error EKU input.\n")); + rv = KC_ERR_USAGE; + } + break; + case 'O': + if (parseEKUOIDs(optarg_av, &plc) != 0) { + (void) fprintf(stderr, + gettext("Error EKU OID input.\n")); + rv = KC_ERR_USAGE; + } + 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 (filename == NULL) { + filename = strdup(KMF_DEFAULT_POLICY_FILE); + if (filename == NULL) { + rv = KC_ERR_MEMORY; + goto out; + } + } + + /* + * Must have a policy name. The policy name can not be default + * if using the default policy file. + */ + if (plc.name == NULL) { + (void) fprintf(stderr, + gettext("You must specify a policy name\n")); + rv = KC_ERR_USAGE; + goto out; + } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && + strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { + (void) fprintf(stderr, + gettext("Can not create a default policy in the default " + "policy file\n")); + rv = KC_ERR_USAGE; + goto out; + } + + /* + * If the policy file exists and the policy is in the policy file + * already, we will not create it again. + */ + if (access(filename, R_OK) == 0) { + POLICY_LIST *plclist = NULL, *pnode; + int found = 0; + + rv = load_policies(filename, &plclist); + if (rv != KMF_OK) + goto out; + + pnode = plclist; + while (pnode != NULL && !found) { + if (strcmp(plc.name, pnode->plc.name) == 0) + found++; + pnode = pnode->next; + } + free_policy_list(plclist); + + if (found) { + (void) fprintf(stderr, + gettext("Could not create policy \"%s\" - exists " + "already\n"), plc.name); + rv = KC_ERR_USAGE; + goto out; + } + } + + /* + * If any OCSP attribute is set, turn on the OCSP checking flag. + * Also set "has_resp_cert" to be true, if the responder cert + * is provided. + */ + if (ocsp_set_attr > 0) + plc.revocation |= KMF_REVOCATION_METHOD_OCSP; + + if (plc.VAL_OCSP_RESP_CERT.name != NULL && + plc.VAL_OCSP_RESP_CERT.serial != NULL) { + plc.VAL_OCSP.has_resp_cert = B_TRUE; + } + + /* + * If any CRL attribute is set, turn on the CRL checking flag. + */ + if (crl_set_attr > 0) + plc.revocation |= KMF_REVOCATION_METHOD_CRL; + + /* + * Does a sanity check on the new policy. + */ + ret = KMF_VerifyPolicy(&plc); + if (ret != KMF_OK) { + print_sanity_error(ret); + rv = KC_ERR_ADD_POLICY; + goto out; + } + + /* + * Add to the DB. + */ + ret = KMF_AddPolicyToDB(&plc, filename, B_FALSE); + if (ret != KMF_OK) { + (void) fprintf(stderr, + gettext("Error adding policy to database: 0x%04x\n"), ret); + rv = KC_ERR_ADD_POLICY; + } + +out: + if (filename != NULL) + free(filename); + + KMF_FreePolicyRecord(&plc); + + return (rv); +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/delete.c b/usr/src/cmd/cmd-crypto/kmfcfg/delete.c new file mode 100644 index 0000000000..7e0a1c7d45 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/delete.c @@ -0,0 +1,132 @@ +/* + * 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. + */ + +#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 "util.h" + +int +kc_delete(int argc, char *argv[]) +{ + int rv = KC_OK; + KMF_RETURN kmfrv = KMF_OK; + int opt; + extern int optind_av; + extern char *optarg_av; + char *filename = NULL; + char *policyname = NULL; + + while ((opt = getopt_av(argc, argv, "i:(dbfile)p:(policy)")) != EOF) { + switch (opt) { + case 'i': + filename = get_string(optarg_av, &rv); + if (filename == NULL) { + (void) fprintf(stderr, + gettext("Error dbfile input.\n")); + } + break; + case 'p': + 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; + + } + + 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 (filename == NULL) { + filename = strdup(KMF_DEFAULT_POLICY_FILE); + if (filename == NULL) { + rv = KC_ERR_MEMORY; + goto out; + } + } + + /* + * Must have a policy name. The policy name can not be default + * if using the default policy file. + */ + if (policyname == NULL) { + (void) fprintf(stderr, + gettext("You must specify a policy name\n")); + rv = KC_ERR_USAGE; + goto out; + } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && + strcmp(policyname, KMF_DEFAULT_POLICY_NAME) == 0) { + (void) fprintf(stderr, + gettext("Can not delete the default policy in the default " + "policy file\n")); + rv = KC_ERR_USAGE; + goto out; + } + + /* Check the access permission of the policy DB */ + if (access(filename, W_OK) < 0) { + int err = errno; + (void) fprintf(stderr, + gettext("Cannot access \"%s\" for delete - %s\n"), + filename, strerror(err)); + rv = KC_ERR_ACCESS; + goto out; + } + + kmfrv = KMF_DeletePolicyFromDB(policyname, filename); + if (kmfrv != KMF_OK) + rv = KC_ERR_DELETE_POLICY; + +out: + if (filename != NULL) + free(filename); + + if (policyname != NULL) + free(policyname); + + return (rv); +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/export.c b/usr/src/cmd/cmd-crypto/kmfcfg/export.c new file mode 100644 index 0000000000..c1ddab153c --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/export.c @@ -0,0 +1,167 @@ +/* + * 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <strings.h> +#include <ctype.h> +#include <libgen.h> +#include <libintl.h> +#include <locale.h> +#include <errno.h> +#include <kmfapiP.h> + +#include "util.h" + +int +kc_export(int argc, char *argv[]) +{ + int rv = KC_OK; + char *filename = NULL; + char *outfile = NULL; + char *policyname = NULL; + POLICY_LIST *plclist = NULL, *pnode; + int opt, found = 0; + extern int optind_av; + extern char *optarg_av; + + while ((opt = getopt_av(argc, argv, + "d:(dbfile)p:(policy)o:(outfile)")) != EOF) { + switch (opt) { + case 'd': + filename = get_string(optarg_av, &rv); + if (filename == NULL) { + (void) fprintf(stderr, + gettext("Error dbfile input.\n")); + } + break; + case 'p': + policyname = get_string(optarg_av, &rv); + if (policyname == NULL) { + (void) fprintf(stderr, + gettext("Error policy name.\n")); + } + break; + case 'o': + outfile = get_string(optarg_av, &rv); + if (outfile == NULL) { + (void) fprintf(stderr, + gettext("Error outfile 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 (filename == NULL) { + filename = strdup(KMF_DEFAULT_POLICY_FILE); + if (filename == NULL) { + rv = KC_ERR_MEMORY; + goto out; + } + } + + if (policyname == NULL) { + (void) fprintf(stderr, + gettext("You must specify a policy name\n")); + rv = KC_ERR_USAGE; + goto out; + } + + if (outfile == NULL) { + (void) fprintf(stderr, + gettext("You must specify a output DB file\n")); + rv = KC_ERR_USAGE; + goto out; + } + + if (strcmp(outfile, KMF_DEFAULT_POLICY_FILE) == 0 && + strcmp(policyname, KMF_DEFAULT_POLICY_NAME) == 0) { + (void) fprintf(stderr, + gettext("Can not export the default policy record to " + "the system default policy database\n")); + rv = KC_ERR_USAGE; + goto out; + } + + rv = load_policies(filename, &plclist); + if (rv != KMF_OK) + goto out; + + pnode = plclist; + while (pnode != NULL && !found) { + if (strcmp(policyname, pnode->plc.name) == 0) { + KMF_RETURN ret; + + found++; + ret = KMF_VerifyPolicy(&pnode->plc); + if (ret != KMF_OK) { + print_sanity_error(ret); + rv = KC_ERR_VERIFY_POLICY; + break; + } + rv = KMF_AddPolicyToDB(&pnode->plc, outfile, B_FALSE); + } + pnode = pnode->next; + } + + if (!found) { + (void) fprintf(stderr, + gettext("Could not find policy \"%s\" in %s\n"), + policyname, filename); + rv = KC_ERR_FIND_POLICY; + } + +out: + if (filename != NULL) + free(filename); + + if (policyname != NULL) + free(policyname); + + if (outfile != NULL) + free(outfile); + + free_policy_list(plclist); + + return (rv); +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/import.c b/usr/src/cmd/cmd-crypto/kmfcfg/import.c new file mode 100644 index 0000000000..b55caac068 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/import.c @@ -0,0 +1,169 @@ +/* + * 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <strings.h> +#include <ctype.h> +#include <libgen.h> +#include <libintl.h> +#include <locale.h> +#include <errno.h> + +#include <kmfapiP.h> + +#include "util.h" + +int +kc_import(int argc, char *argv[]) +{ + int rv = KC_OK; + char *filename = NULL; + char *infile = NULL; + char *policyname = NULL; + POLICY_LIST *plclist = NULL, *pnode; + int opt, found = 0; + extern int optind_av; + extern char *optarg_av; + + while ((opt = getopt_av(argc, argv, + "d:(dbfile)p:(policy)i:(infile)")) != EOF) { + switch (opt) { + case 'd': + filename = get_string(optarg_av, &rv); + if (filename == NULL) { + (void) fprintf(stderr, + gettext("Error dbfile input.\n")); + } + break; + case 'p': + policyname = get_string(optarg_av, &rv); + if (policyname == NULL) { + (void) fprintf(stderr, + gettext("Error policy name.\n")); + } + break; + case 'i': + infile = get_string(optarg_av, &rv); + if (infile == NULL) { + (void) fprintf(stderr, + gettext("Error infile 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 (filename == NULL) { + filename = strdup(KMF_DEFAULT_POLICY_FILE); + if (filename == NULL) { + rv = KC_ERR_MEMORY; + goto out; + } + } + + if (policyname == NULL) { + (void) fprintf(stderr, + gettext("You must specify a policy name\n")); + rv = KC_ERR_USAGE; + goto out; + } + + if (infile == NULL) { + (void) fprintf(stderr, + gettext("You must specify a input DB file\n")); + rv = KC_ERR_USAGE; + goto out; + } + + if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && + strcmp(policyname, KMF_DEFAULT_POLICY_NAME) == 0) { + (void) fprintf(stderr, + gettext("Can not import the default policy record to " + "the system default policy database\n")); + rv = KC_ERR_USAGE; + goto out; + } + + rv = load_policies(infile, &plclist); + if (rv != KMF_OK) + goto out; + + pnode = plclist; + while (pnode != NULL && !found) { + if (strcmp(policyname, pnode->plc.name) == 0) { + KMF_RETURN ret; + + found++; + ret = KMF_VerifyPolicy(&pnode->plc); + if (ret != KMF_OK) { + print_sanity_error(ret); + rv = KC_ERR_VERIFY_POLICY; + break; + } + rv = KMF_AddPolicyToDB(&pnode->plc, filename, B_FALSE); + } + pnode = pnode->next; + } + + if (!found) { + (void) fprintf(stderr, + gettext("Could not find policy \"%s\" in %s\n"), + policyname, infile); + rv = KC_ERR_FIND_POLICY; + } + +out: + if (filename != NULL) + free(filename); + + if (policyname != NULL) + free(policyname); + + if (infile != NULL) + free(infile); + + free_policy_list(plclist); + + return (rv); +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c b/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c new file mode 100644 index 0000000000..e58368284f --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/kmfcfg.c @@ -0,0 +1,245 @@ +/* + * 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <strings.h> +#include <ctype.h> +#include <libgen.h> +#include <libintl.h> +#include <locale.h> + +#include <kmfapiP.h> + +#include "util.h" + +/* + * The verbcmd construct allows genericizing information about a verb so + * that it is easier to manipulate. Makes parsing code easier to read, + * fix, and extend with new verbs. + */ +typedef struct verbcmd_s { + char *verb; + int (*action)(int, char *[]); + char *synopsis; +} verbcmd; + +int kc_list(int argc, char *argv[]); +int kc_delete(int argc, char *argv[]); +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[]); +static int kc_help(); + +static verbcmd cmds[] = { + { "list", kc_list, "list [dbfile=dbfile] " + "[policy=policyname]" }, + { "delete", kc_delete, "delete [dbfile=dbfile] " + "policy=policyname" }, + { "create", kc_create, + "create [dbfile=dbfile] policy=policyname\n" + "\t\t[ignore-date=true|false]\n" + "\t\t[ignore-unknown-eku=true|false]\n" + "\t\t[ignore-trust-anchor=true|false]\n" + "\t\t[validity-adjusttime=adjusttime]\n" + "\t\t[ta-name=trust anchor subject DN]\n" + "\t\t[ta-serial=trust anchor serial number]\n" + "\t\t[ocsp-responder=URL]\n" + "\t\t[ocsp-proxy=URL]\n" + "\t\t[ocsp-use-cert-responder=true|false]\n" + "\t\t[ocsp-response-lifetime=timelimit]\n" + "\t\t[ocsp-ignore-response-sign=true|false]\n" + "\t\t[ocsp-responder-cert-name=Issuer DN]\n" + "\t\t[ocsp-responder-cert-serial=serial number]\n" + "\t\t[crl-basefilename=basefilename]\n" + "\t\t[crl-directory=directory]\n" + "\t\t[crl-get-crl-uri=true|false]\n" + "\t\t[crl-proxy=URL]\n" + "\t\t[crl-ignore-crl-sign=true|false]\n" + "\t\t[crl-ignore-crl-date=true|false]\n" + "\t\t[keyusage=digitalSignature|nonRepudiation\n\t" + "\t\t|keyEncipherment | dataEncipherment |\n\t" + "\t\tkeyAgreement |keyCertSign |\n\t" + "\t\tcRLSign | encipherOnly | decipherOnly],[...]\n" + "\t\t[ekunames=serverAuth | clientAuth |\n\t" + "\t\tcodeSigning | emailProtection |\n\t" + "\t\tipsecEndSystem | ipsecTunnel |\n\t" + "\t\tipsecUser | timeStamping |\n\t" + "\t\tOCSPSigning],[...]\n" + "\t\t[ekuoids=OID,OID,OID...]\n" }, + { "modify", kc_modify, + "modify [dbfile=dbfile] policy=policyname\n" + "\t\t[ignore-date=true|false]\n" + "\t\t[ignore-unknown-eku=true|false]\n" + "\t\t[ignore-trust-anchor=true|false]\n" + "\t\t[validity-adjusttime=adjusttime]\n" + "\t\t[ta-name=trust anchor subject DN]\n" + "\t\t[ta-serial=trust anchor serial number]\n" + "\t\t[ocsp-responder=URL]\n" + "\t\t[ocsp-proxy=URL]\n" + "\t\t[ocsp-use-cert-responder=true|false]\n" + "\t\t[ocsp-response-lifetime=timelimit]\n" + "\t\t[ocsp-ignore-response-sign=true|false]\n" + "\t\t[ocsp-responder-cert-name=Issuer DN]\n" + "\t\t[ocsp-responder-cert-serial=serial number]\n" + "\t\t[ocsp-none=true|false]\n" + "\t\t[crl-basefilename=basefilename]\n" + "\t\t[crl-directory=directory]\n" + "\t\t[crl-get-crl-uri=true|false]\n" + "\t\t[crl-proxy=URL]\n" + "\t\t[crl-ignore-crl-sign=true|false]\n" + "\t\t[crl-ignore-crl-date=true|false]\n" + "\t\t[crl-none=true|false]\n" + "\t\t[keyusage=digitalSignature|nonRepudiation\n\t" + "\t\t|keyEncipherment | dataEncipherment |\n\t" + "\t\tkeyAgreement |keyCertSign |\n\t" + "\t\tcRLSign | encipherOnly | decipherOnly],[...]\n" + "\t\t[keyusage-none=true|false]\n" + "\t\t[ekunames=serverAuth | clientAuth |\n\t" + "\t\tcodeSigning | emailProtection |\n\t" + "\t\tipsecEndSystem | ipsecTunnel |\n\t" + "\t\tipsecUser | timeStamping |\n\t" + "\t\tOCSPSigning],[...]\n" + "\t\t[ekuoids=OID,OID,OID...]\n" + "\t\t[eku-none=true|false]\n" }, + { "import", kc_import, "import [dbfile=dbfile] policy=policyname " + "infile=inputdbfile\n" }, + { "export", kc_export, "export [dbfile=dbfile] policy=policyname " + "outfile=newdbfile\n" }, + { "-?", kc_help, "help"}, + { "help", kc_help, ""} +}; + +static int num_cmds = sizeof (cmds) / sizeof (verbcmd); +static char *prog; + +static void +usage(void) +{ + int i; + + /* Display this block only in command-line mode. */ + (void) fprintf(stdout, gettext("Usage:\n")); + (void) fprintf(stdout, gettext("\t%s -?\t(help and usage)\n"), prog); + (void) fprintf(stdout, gettext("\t%s subcommand [options...]\n"), prog); + (void) fprintf(stdout, gettext("where subcommands may be:\n")); + + /* Display only those verbs that match the current tool mode. */ + for (i = 0; i < num_cmds; i++) { + /* Do NOT i18n/l10n. */ + (void) fprintf(stdout, "\t%s\n", cmds[i].synopsis); + } +} + +static int +kc_help() +{ + usage(); + return (0); +} + +int +main(int argc, char *argv[]) +{ + KMF_RETURN ret; + int found; + int i; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */ +#endif + (void) textdomain(TEXT_DOMAIN); + + prog = basename(argv[0]); + argv++; argc--; + + if (argc == 0) { + usage(); + exit(1); + } + + if (argc == 1 && argv[0][0] == '-') { + switch (argv[0][1]) { + case '?': + return (kc_help()); + default: + usage(); + exit(1); + } + } + + found = -1; + for (i = 0; i < num_cmds; i++) { + if (strcmp(cmds[i].verb, argv[0]) == 0) { + found = i; + break; + } + } + + if (found < 0) { + (void) fprintf(stderr, gettext("Invalid command: %s\n"), + argv[0]); + exit(1); + } + + ret = (*cmds[found].action)(argc, argv); + + switch (ret) { + case KC_OK: + break; + case KC_ERR_USAGE: + break; + case KC_ERR_LOADDB: + (void) fprintf(stderr, + gettext("Error loading database\n")); + break; + case KC_ERR_FIND_POLICY: + break; + case KC_ERR_DELETE_POLICY: + (void) fprintf(stderr, gettext("Error deleting policy " + "from database.\n")); + break; + case KC_ERR_ADD_POLICY: + break; + case KC_ERR_VERIFY_POLICY: + break; + case KC_ERR_INCOMPLETE_POLICY: + break; + case KC_ERR_MEMORY: + (void) fprintf(stderr, gettext("Out of memory.\n")); + break; + case KC_ERR_ACCESS: + break; + default: + (void) fprintf(stderr, gettext("%s operation failed. " + "error 0x%02x\n"), cmds[found].verb, ret); + break; + } + + return (ret); +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.dtd b/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.dtd new file mode 100644 index 0000000000..32fa28e99a --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.dtd @@ -0,0 +1,84 @@ +<?xml version='1.0' encoding='UTF-8' ?> + +<!-- + Copyright 2006 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" +--> + +<!--Element Definitions--> + +<!ELEMENT kmf-policy-db (kmf-policy*)> +<!ATTLIST kmf-policy-db allow-local-files (TRUE|FALSE) #IMPLIED> + +<!ELEMENT kmf-policy (validation-methods, key-usage-set?, ext-key-usage?)> +<!ATTLIST kmf-policy name CDATA #REQUIRED> +<!ATTLIST kmf-policy ignore-date (TRUE|FALSE) #IMPLIED> +<!ATTLIST kmf-policy ignore-unknown-eku (TRUE|FALSE) #IMPLIED> +<!ATTLIST kmf-policy ignore-trust-anchor (TRUE|FALSE) #IMPLIED> +<!ATTLIST kmf-policy validity-adjusttime CDATA #IMPLIED> +<!ATTLIST kmf-policy ta-name CDATA #IMPLIED> +<!ATTLIST kmf-policy ta-serial CDATA #IMPLIED> + +<!ELEMENT validation-methods (ocsp?, crl?)> +<!ELEMENT ocsp (ocsp-basic, responder-cert?)> + +<!ELEMENT ocsp-basic EMPTY> +<!ATTLIST ocsp-basic + responder CDATA #IMPLIED + proxy CDATA #IMPLIED + uri-from-cert (TRUE|FALSE) #IMPLIED + response-lifetime CDATA #IMPLIED + ignore-response-sign (TRUE|FALSE) #IMPLIED +> + +<!ELEMENT responder-cert EMPTY> +<!ATTLIST responder-cert + name CDATA #REQUIRED + serial CDATA #REQUIRED +> + +<!ELEMENT crl EMPTY> +<!ATTLIST crl basefilename CDATA #IMPLIED> +<!ATTLIST crl directory CDATA #IMPLIED> +<!ATTLIST crl get-crl-uri (TRUE|FALSE) #IMPLIED> +<!ATTLIST crl proxy CDATA #IMPLIED> +<!ATTLIST crl ignore-crl-sign (TRUE|FALSE) #IMPLIED> +<!ATTLIST crl ignore-crl-date (TRUE|FALSE) #IMPLIED> + +<!ELEMENT key-usage-set (key-usage+)> + +<!ELEMENT key-usage EMPTY> +<!ATTLIST key-usage use (digitalSignature | nonRepudiation | + keyEncipherment | dataEncipherment | keyAgreement | + keyCertSign | cRLSign | encipherOnly | decipherOnly) #IMPLIED> + +<!ELEMENT ext-key-usage (eku-name*, eku-oid*)> + +<!ELEMENT eku-name EMPTY> +<!ATTLIST eku-name name (serverAuth | clientAuth | + codeSigning | emailProtection | + ipsecEndSystem | ipsecTunnel | ipsecUser | + timeStamping | OCSPSigning) #IMPLIED > +<!ELEMENT eku-oid EMPTY> +<!ATTLIST eku-oid oid CDATA #IMPLIED> diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.xml b/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.xml new file mode 100644 index 0000000000..2c2ed35e2c --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/kmfpolicy.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2006 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 + + Sample KMF Policy Database file. + + ident "%Z%%M% %I% %E% SMI" +--> +<!DOCTYPE kmf-policy-db SYSTEM "/usr/share/lib/xml/dtd/kmfpolicy.dtd"> +<kmf-policy-db> + +<kmf-policy name="default" ignore-date="TRUE" ignore-trust-anchor="TRUE"> + <validation-methods> + <ocsp> + <ocsp-basic uri-from-cert="TRUE" + ignore-response-sign="TRUE"/> + </ocsp> + </validation-methods> +</kmf-policy> +</kmf-policy-db> diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/list.c b/usr/src/cmd/cmd-crypto/kmfcfg/list.c new file mode 100644 index 0000000000..e68e2b8643 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/list.c @@ -0,0 +1,277 @@ +/* + * 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. + */ + +#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 "util.h" + +static void +show_policy(KMF_POLICY_RECORD *plc) +{ + int i; + if (plc == NULL) + return; + + (void) printf("Name: %s\n", plc->name); + + (void) printf(gettext("Ignore Date: %s\n"), + plc->ignore_date ? gettext("true") : gettext("false")); + + (void) printf(gettext("Ignore Unknown EKUs: %s\n"), + plc->ignore_unknown_ekus ? gettext("true") : gettext("false")); + + (void) printf(gettext("Ignore TA: %s\n"), + plc->ignore_trust_anchor ? gettext("true") : gettext("false")); + + (void) printf(gettext("Validity Adjusted Time: %s\n"), + plc->validity_adjusttime ? + plc->validity_adjusttime : "<null>"); + + if (plc->ta_name == NULL && plc->ta_serial == NULL) { + (void) printf(gettext("Trust Anchor Certificate: <null>\n")); + } else { + (void) printf(gettext("Trust Anchor Certificate:\n")); + (void) printf(gettext("\tName: %s\n"), + plc->ta_name ? plc->ta_name : "<null>"); + (void) printf(gettext("\tSerial Number: %s\n"), + plc->ta_serial ? plc->ta_serial : "<null>"); + } + + if (plc->ku_bits != 0) { + (void) printf(gettext("Key Usage Bits: ")); + for (i = KULOWBIT; i <= KUHIGHBIT; i++) { + char *s = ku2str((plc->ku_bits & (1<<i))); + if (s != NULL) { + (void) printf("%s ", s); + } + } + (void) printf("\n"); + } else { + (void) printf(gettext("Key Usage Bits: 0\n")); + } + + if (plc->eku_set.eku_count > 0) { + (void) printf(gettext("Extended Key Usage Values:\n")); + for (i = 0; i < plc->eku_set.eku_count; i++) { + char *s = KMF_OID2EKUString(&plc->eku_set.ekulist[i]); + (void) printf("\t%s\t(%s)\n", + KMF_OID2String(&plc->eku_set.ekulist[i]), + s ? s : "unknown"); + } + } else { + (void) printf(gettext("Extended Key Usage Values: <null>\n")); + } + + (void) printf(gettext("Validation Policy Information:\n")); + + if (plc->revocation & KMF_REVOCATION_METHOD_OCSP) { + (void) printf(gettext(" OCSP:\n")); + + (void) printf(gettext("\tResponder URI: %s\n"), + plc->VAL_OCSP_BASIC.responderURI ? + plc->VAL_OCSP_BASIC.responderURI : "<null>"); + + (void) printf(gettext("\tProxy: %s\n"), + plc->VAL_OCSP_BASIC.proxy ? + plc->VAL_OCSP_BASIC.proxy : "<null>"); + + (void) printf(gettext("\tUse ResponderURI from Certificate: " + "%s\n"), plc->VAL_OCSP_BASIC.uri_from_cert ? + gettext("true") : gettext("false")); + + (void) printf(gettext("\tResponse lifetime: %s\n"), + plc->VAL_OCSP_BASIC.response_lifetime ? + plc->VAL_OCSP_BASIC.response_lifetime : "<null>"); + + (void) printf(gettext("\tIgnore Response signature: %s\n"), + plc->VAL_OCSP_BASIC.ignore_response_sign ? + gettext("true") : gettext("false")); + + if (!plc->VAL_OCSP.has_resp_cert) { + (void) printf(gettext("\tResponder Certificate:" + " <null>\n")); + } else { + (void) printf(gettext("\tResponder Certificate:\n")); + (void) printf(gettext("\t\tName: %s\n"), + plc->VAL_OCSP_RESP_CERT.name ? + plc->VAL_OCSP_RESP_CERT.name : "<null>"); + (void) printf(gettext("\t\tSerial: %s\n"), + plc->VAL_OCSP_RESP_CERT.serial ? + plc->VAL_OCSP_RESP_CERT.serial : "<null>"); + } + } + + if (plc->revocation & KMF_REVOCATION_METHOD_CRL) { + (void) printf(gettext(" CRL:\n")); + + (void) printf(gettext("\tBase filename: %s\n"), + plc->validation_info.crl_info.basefilename ? + plc->validation_info.crl_info.basefilename : "<null>"); + + (void) printf(gettext("\tDirectory: %s\n"), + plc->validation_info.crl_info.directory ? + plc->validation_info.crl_info.directory : "<null>"); + + (void) printf(gettext("\tDownload and cache CRL: %s\n"), + plc->validation_info.crl_info.get_crl_uri ? + gettext("true") : gettext("false")); + + (void) printf(gettext("\tProxy: %s\n"), + plc->validation_info.crl_info.proxy ? + plc->validation_info.crl_info.proxy : "<null>"); + + (void) printf(gettext("\tIgnore CRL signature: %s\n"), + plc->validation_info.crl_info.ignore_crl_sign ? + gettext("true") : gettext("false")); + + (void) printf(gettext("\tIgnore CRL validity date: %s\n"), + plc->validation_info.crl_info.ignore_crl_date ? + gettext("true") : gettext("false")); + } + + (void) printf("\n"); +} + +int +kc_list(int argc, char *argv[]) +{ + int rv = KC_OK; + int opt, found = 0; + extern int optind_av; + extern char *optarg_av; + char *filename = NULL; + char *policyname = NULL; + POLICY_LIST *plclist = NULL, *pnode; + int sanity_err = 0; + + while ((opt = getopt_av(argc, argv, "i:(dbfile)p:(policy)")) != EOF) { + switch (opt) { + case 'i': + filename = get_string(optarg_av, &rv); + if (filename == NULL) { + (void) fprintf(stderr, + gettext("Error dbfile input.\n")); + } + break; + case 'p': + 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; + } + 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 (filename == NULL) { + filename = strdup(KMF_DEFAULT_POLICY_FILE); + if (filename == NULL) { + rv = KC_ERR_MEMORY; + goto out; + } + } + + /* Check the access permission of the policy DB */ + if (access(filename, R_OK) < 0) { + int err = errno; + (void) fprintf(stderr, + gettext("Cannot access \"%s\" for list - %s\n"), filename, + strerror(err)); + rv = KC_ERR_ACCESS; + goto out; + } + + rv = load_policies(filename, &plclist); + if (rv != KMF_OK) { + goto out; + } + + pnode = plclist; + while (pnode != NULL) { + if (policyname == NULL || + strcmp(policyname, pnode->plc.name) == 0) { + KMF_POLICY_RECORD *plc = &pnode->plc; + + found++; + rv = KMF_VerifyPolicy(plc); + if (rv != KMF_OK) { + (void) fprintf(stderr, gettext( + "Policy Name: '%s' is invalid\n"), + plc->name); + sanity_err++; + } else { + show_policy(&pnode->plc); + } + } + pnode = pnode->next; + } + + free_policy_list(plclist); + + if (!found) { + if (policyname) + (void) fprintf(stderr, gettext( + "Cannot find policy '%s'\n"), policyname); + else + (void) fprintf(stderr, gettext("Cannot find " + "any policies to display\n")); + rv = KC_ERR_FIND_POLICY; + } else if (sanity_err) { + rv = KC_ERR_VERIFY_POLICY; + } + +out: + + if (filename != NULL) + free(filename); + + if (policyname != NULL) + free(policyname); + + return (rv); +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/modify.c b/usr/src/cmd/cmd-crypto/kmfcfg/modify.c new file mode 100644 index 0000000000..413bda3be7 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/modify.c @@ -0,0 +1,845 @@ +/* + * 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. + */ + +#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 <cryptoutil.h> +#include "util.h" + +#define KC_IGNORE_DATE 0x0000001 +#define KC_IGNORE_UNKNOWN_EKUS 0x0000002 +#define KC_IGNORE_TRUST_ANCHOR 0x0000004 +#define KC_VALIDITY_ADJUSTTIME 0x0000008 +#define KC_TA_NAME 0x0000010 +#define KC_TA_SERIAL 0x0000020 +#define KC_OCSP_RESPONDER_URI 0x0000040 +#define KC_OCSP_PROXY 0x0000080 +#define KC_OCSP_URI_FROM_CERT 0x0000100 +#define KC_OCSP_RESP_LIFETIME 0x0000200 +#define KC_OCSP_IGNORE_RESP_SIGN 0x0000400 +#define KC_OCSP_RESP_CERT_NAME 0x0000800 +#define KC_OCSP_RESP_CERT_SERIAL 0x0001000 +#define KC_OCSP_NONE 0x0002000 +#define KC_CRL_BASEFILENAME 0x0004000 +#define KC_CRL_DIRECTORY 0x0008000 +#define KC_CRL_GET_URI 0x0010000 +#define KC_CRL_PROXY 0x0020000 +#define KC_CRL_IGNORE_SIGN 0x0040000 +#define KC_CRL_IGNORE_DATE 0x0080000 +#define KC_CRL_NONE 0x0100000 +#define KC_KEYUSAGE 0x0200000 +#define KC_KEYUSAGE_NONE 0x0400000 +#define KC_EKUS 0x0800000 +#define KC_EKUS_NONE 0x1000000 + +int +kc_modify(int argc, char *argv[]) +{ + KMF_RETURN ret; + int rv = KC_OK; + int opt; + extern int optind_av; + extern char *optarg_av; + char *filename = NULL; + uint32_t flags = 0; + boolean_t ocsp_none_opt = B_FALSE; + boolean_t crl_none_opt = B_FALSE; + boolean_t ku_none_opt = B_FALSE; + boolean_t eku_none_opt = B_FALSE; + int ocsp_set_attr = 0; + int crl_set_attr = 0; + KMF_POLICY_RECORD oplc, plc; + + (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); + (void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD)); + + while ((opt = getopt_av(argc, argv, + "i:(dbfile)" + "p:(policy)" + "d:(ignore-date)" + "e:(ignore-unknown-eku)" + "a:(ignore-trust-anchor)" + "v:(validity-adjusttime)" + "t:(ta-name)" + "s:(ta-serial)" + "o:(ocsp-responder)" + "P:(ocsp-proxy)" + "r:(ocsp-use-cert-responder)" + "T:(ocsp-response-lifetime)" + "R:(ocsp-ignore-response-sign)" + "n:(ocsp-responder-cert-name)" + "A:(ocsp-responder-cert-serial)" + "y:(ocsp-none)" + "c:(crl-basefilename)" + "I:(crl-directory)" + "g:(crl-get-crl-uri)" + "X:(crl-proxy)" + "S:(crl-ignore-crl-sign)" + "D:(crl-ignore-crl-date)" + "z:(crl-none)" + "u:(keyusage)" + "Y:(keyusage-none)" + "E:(ekunames)" + "O:(ekuoids)" + "Z:(eku-none)")) != EOF) { + switch (opt) { + case 'i': + filename = get_string(optarg_av, &rv); + if (filename == NULL) { + (void) fprintf(stderr, + gettext("Error dbfile input.\n")); + } + break; + case 'p': + plc.name = get_string(optarg_av, &rv); + if (plc.name == NULL) { + (void) fprintf(stderr, + gettext("Error policy name.\n")); + } + break; + case 'd': + plc.ignore_date = get_boolean(optarg_av); + if (plc.ignore_date == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_IGNORE_DATE; + } + break; + case 'e': + plc.ignore_unknown_ekus = + get_boolean(optarg_av); + if (plc.ignore_unknown_ekus == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_IGNORE_UNKNOWN_EKUS; + } + break; + case 'a': + plc.ignore_trust_anchor = + get_boolean(optarg_av); + if (plc.ignore_trust_anchor == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_IGNORE_TRUST_ANCHOR; + } + break; + case 'v': + plc.validity_adjusttime = + get_string(optarg_av, &rv); + if (plc.validity_adjusttime == NULL) { + (void) fprintf(stderr, + gettext("Error time input.\n")); + } else { + uint32_t adj; + /* for syntax checking */ + if (str2lifetime( + plc.validity_adjusttime, + &adj) < 0) { + (void) fprintf(stderr, + gettext("Error time " + "input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_VALIDITY_ADJUSTTIME; + } + } + break; + case 't': + plc.ta_name = get_string(optarg_av, &rv); + if (plc.ta_name == NULL) { + (void) fprintf(stderr, + gettext("Error name input.\n")); + } else { + KMF_X509_NAME taDN; + /* for syntax checking */ + if (KMF_DNParser(plc.ta_name, + &taDN) != KMF_OK) { + (void) fprintf(stderr, + gettext("Error name " + "input.\n")); + rv = KC_ERR_USAGE; + } else { + KMF_FreeDN(&taDN); + flags |= KC_TA_NAME; + } + } + break; + case 's': + plc.ta_serial = get_string(optarg_av, &rv); + if (plc.ta_serial == NULL) { + (void) fprintf(stderr, + gettext("Error serial input.\n")); + } else { + uchar_t *bytes = NULL; + size_t bytelen; + + ret = KMF_HexString2Bytes( + (uchar_t *)plc.ta_serial, + &bytes, &bytelen); + if (ret != KMF_OK || bytes == NULL) { + (void) fprintf(stderr, + gettext("serial number " + "must be specified as a " + "hex number " + "(ex: 0x0102030405" + "ffeeddee)\n")); + rv = KC_ERR_USAGE; + break; + } + if (bytes != NULL) + free(bytes); + flags |= KC_TA_SERIAL; + } + break; + case 'o': + plc.VAL_OCSP_RESPONDER_URI = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESPONDER_URI == NULL) { + (void) fprintf(stderr, + gettext("Error responder " + "input.\n")); + } else { + flags |= KC_OCSP_RESPONDER_URI; + ocsp_set_attr++; + } + break; + case 'P': + plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv); + if (plc.VAL_OCSP_PROXY == NULL) { + (void) fprintf(stderr, + gettext("Error proxy input.\n")); + } else { + flags |= KC_OCSP_PROXY; + ocsp_set_attr++; + } + break; + case 'r': + plc.VAL_OCSP_URI_FROM_CERT = + get_boolean(optarg_av); + if (plc.VAL_OCSP_URI_FROM_CERT == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_OCSP_URI_FROM_CERT; + ocsp_set_attr++; + } + break; + case 'T': + plc.VAL_OCSP_RESP_LIFETIME = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { + (void) fprintf(stderr, + gettext("Error time input.\n")); + } else { + uint32_t adj; + /* for syntax checking */ + if (str2lifetime( + plc.VAL_OCSP_RESP_LIFETIME, + &adj) < 0) { + (void) fprintf(stderr, + gettext("Error time " + "input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_OCSP_RESP_LIFETIME; + ocsp_set_attr++; + } + } + break; + case 'R': + plc.VAL_OCSP_IGNORE_RESP_SIGN = + get_boolean(optarg_av); + if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_OCSP_IGNORE_RESP_SIGN; + ocsp_set_attr++; + } + break; + case 'n': + plc.VAL_OCSP_RESP_CERT_NAME = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { + (void) fprintf(stderr, + gettext("Error name input.\n")); + } else { + KMF_X509_NAME respDN; + /* for syntax checking */ + if (KMF_DNParser( + plc.VAL_OCSP_RESP_CERT_NAME, + &respDN) != KMF_OK) { + (void) fprintf(stderr, + gettext("Error name " + "input.\n")); + rv = KC_ERR_USAGE; + } else { + KMF_FreeDN(&respDN); + flags |= KC_OCSP_RESP_CERT_NAME; + ocsp_set_attr++; + } + } + break; + case 'A': + plc.VAL_OCSP_RESP_CERT_SERIAL = + get_string(optarg_av, &rv); + if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { + (void) fprintf(stderr, + gettext("Error serial input.\n")); + } else { + uchar_t *bytes = NULL; + size_t bytelen; + + ret = KMF_HexString2Bytes((uchar_t *) + plc.VAL_OCSP_RESP_CERT_SERIAL, + &bytes, &bytelen); + if (ret != KMF_OK || bytes == NULL) { + (void) fprintf(stderr, + gettext("serial number " + "must be specified as a " + "hex number " + "(ex: 0x0102030405" + "ffeeddee)\n")); + rv = KC_ERR_USAGE; + break; + } + if (bytes != NULL) + free(bytes); + flags |= KC_OCSP_RESP_CERT_SERIAL; + ocsp_set_attr++; + } + break; + case 'y': + ocsp_none_opt = get_boolean(optarg_av); + if (ocsp_none_opt == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_OCSP_NONE; + } + break; + case 'c': + plc.VAL_CRL_BASEFILENAME = + get_string(optarg_av, &rv); + if (plc.VAL_CRL_BASEFILENAME == NULL) { + (void) fprintf(stderr, gettext( + "Error basefilename input.\n")); + } else { + flags |= KC_CRL_BASEFILENAME; + crl_set_attr++; + } + break; + case 'I': + plc.VAL_CRL_DIRECTORY = + get_string(optarg_av, &rv); + if (plc.VAL_CRL_DIRECTORY == NULL) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + } else { + flags |= KC_CRL_DIRECTORY; + crl_set_attr++; + } + break; + case 'g': + plc.VAL_CRL_GET_URI = get_boolean(optarg_av); + if (plc.VAL_CRL_GET_URI == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_CRL_GET_URI; + crl_set_attr++; + } + break; + case 'X': + plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); + if (plc.VAL_CRL_PROXY == NULL) { + (void) fprintf(stderr, + gettext("Error proxy input.\n")); + } else { + flags |= KC_CRL_PROXY; + crl_set_attr++; + } + break; + case 'S': + plc.VAL_CRL_IGNORE_SIGN = + get_boolean(optarg_av); + if (plc.VAL_CRL_IGNORE_SIGN == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_CRL_IGNORE_SIGN; + crl_set_attr++; + } + break; + case 'D': + plc.VAL_CRL_IGNORE_DATE = + get_boolean(optarg_av); + if (plc.VAL_CRL_IGNORE_DATE == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_CRL_IGNORE_DATE; + crl_set_attr++; + } + break; + case 'z': + crl_none_opt = get_boolean(optarg_av); + if (crl_none_opt == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_CRL_NONE; + } + break; + case 'u': + plc.ku_bits = parseKUlist(optarg_av); + if (plc.ku_bits == 0) { + (void) fprintf(stderr, gettext( + "Error keyusage input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_KEYUSAGE; + } + break; + case 'Y': + ku_none_opt = get_boolean(optarg_av); + if (ku_none_opt == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_KEYUSAGE_NONE; + } + break; + case 'E': + if (parseEKUNames(optarg_av, &plc) != 0) { + (void) fprintf(stderr, + gettext("Error EKU input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_EKUS; + } + break; + case 'O': + if (parseEKUOIDs(optarg_av, &plc) != 0) { + (void) fprintf(stderr, + gettext("Error EKU OID input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_EKUS; + } + break; + case 'Z': + eku_none_opt = get_boolean(optarg_av); + if (eku_none_opt == -1) { + (void) fprintf(stderr, + gettext("Error boolean input.\n")); + rv = KC_ERR_USAGE; + } else { + flags |= KC_EKUS_NONE; + } + 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 (filename == NULL) { + filename = strdup(KMF_DEFAULT_POLICY_FILE); + if (filename == NULL) { + rv = KC_ERR_MEMORY; + goto out; + } + } + + /* + * Must have a policy name. The policy name can not be default + * if using the default policy file. + */ + if (plc.name == NULL) { + (void) fprintf(stderr, + gettext("You must specify a policy name.\n")); + rv = KC_ERR_USAGE; + goto out; + } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && + strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { + (void) fprintf(stderr, + gettext("Can not modify the default policy in the default " + "policy file.\n")); + rv = KC_ERR_USAGE; + goto out; + } + + /* Check the access permission of the policy DB */ + if (access(filename, W_OK) < 0) { + int err = errno; + (void) fprintf(stderr, + gettext("Cannot access \"%s\" for modify - %s\n"), + filename, strerror(err)); + rv = KC_ERR_ACCESS; + goto out; + } + + /* Try to load the named policy from the DB */ + ret = KMF_GetPolicy(filename, plc.name, &oplc); + if (ret != KMF_OK) { + (void) fprintf(stderr, + gettext("Error loading policy \"%s\" from %s\n"), filename, + plc.name); + return (KC_ERR_FIND_POLICY); + } + + /* Update the general policy attributes. */ + if (flags & KC_IGNORE_DATE) + oplc.ignore_date = plc.ignore_date; + + if (flags & KC_IGNORE_UNKNOWN_EKUS) + oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus; + + if (flags & KC_IGNORE_TRUST_ANCHOR) + oplc.ignore_trust_anchor = plc.ignore_trust_anchor; + + if (flags & KC_VALIDITY_ADJUSTTIME) { + if (oplc.validity_adjusttime) + free(oplc.validity_adjusttime); + oplc.validity_adjusttime = + plc.validity_adjusttime; + } + + if (flags & KC_TA_NAME) { + if (oplc.ta_name) + free(oplc.ta_name); + oplc.ta_name = plc.ta_name; + } + if (flags & KC_TA_SERIAL) { + if (oplc.ta_serial) + free(oplc.ta_serial); + oplc.ta_serial = plc.ta_serial; + } + + /* Update the OCSP policy */ + if (ocsp_none_opt == B_TRUE) { + if (ocsp_set_attr > 0) { + (void) fprintf(stderr, + gettext("Can not set ocsp-none=true and other " + "OCSP attributes at the same time.\n")); + rv = KC_ERR_USAGE; + goto out; + } + + /* + * If the original policy does not have OCSP checking, + * then we do not need to do anything. If the original + * policy has the OCSP checking, then we need to release the + * space of OCSP attributes and turn the OCSP checking off. + */ + if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) { + if (oplc.VAL_OCSP_BASIC.responderURI) { + free(oplc.VAL_OCSP_BASIC.responderURI); + oplc.VAL_OCSP_BASIC.responderURI = NULL; + } + + if (oplc.VAL_OCSP_BASIC.proxy) { + free(oplc.VAL_OCSP_BASIC.proxy); + oplc.VAL_OCSP_BASIC.proxy = NULL; + } + + if (oplc.VAL_OCSP_BASIC.response_lifetime) { + free(oplc.VAL_OCSP_BASIC.response_lifetime); + oplc.VAL_OCSP_BASIC.response_lifetime = NULL; + } + + if (flags & KC_OCSP_RESP_CERT_NAME) { + free(oplc.VAL_OCSP_RESP_CERT.name); + oplc.VAL_OCSP_RESP_CERT.name = NULL; + } + + if (flags & KC_OCSP_RESP_CERT_SERIAL) { + free(oplc.VAL_OCSP_RESP_CERT.serial); + oplc.VAL_OCSP_RESP_CERT.serial = NULL; + } + + /* Turn off the OCSP checking */ + oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP; + } + + } else { + /* + * If the "ocsp-none" option is not set or is set to false, + * then we only need to do the modification if there is at + * least one OCSP attribute is specified. + */ + if (ocsp_set_attr > 0) { + if (flags & KC_OCSP_RESPONDER_URI) { + if (oplc.VAL_OCSP_RESPONDER_URI) + free(oplc.VAL_OCSP_RESPONDER_URI); + oplc.VAL_OCSP_RESPONDER_URI = + plc.VAL_OCSP_RESPONDER_URI; + } + + if (flags & KC_OCSP_PROXY) { + if (oplc.VAL_OCSP_PROXY) + free(oplc.VAL_OCSP_PROXY); + oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY; + } + + if (flags & KC_OCSP_URI_FROM_CERT) + oplc.VAL_OCSP_URI_FROM_CERT = + plc.VAL_OCSP_URI_FROM_CERT; + + if (flags & KC_OCSP_RESP_LIFETIME) { + if (oplc.VAL_OCSP_RESP_LIFETIME) + free(oplc.VAL_OCSP_RESP_LIFETIME); + oplc.VAL_OCSP_RESP_LIFETIME = + plc.VAL_OCSP_RESP_LIFETIME; + } + + if (flags & KC_OCSP_IGNORE_RESP_SIGN) + oplc.VAL_OCSP_IGNORE_RESP_SIGN = + plc.VAL_OCSP_IGNORE_RESP_SIGN; + + if (flags & KC_OCSP_RESP_CERT_NAME) { + if (oplc.VAL_OCSP_RESP_CERT_NAME) + free(oplc.VAL_OCSP_RESP_CERT_NAME); + oplc.VAL_OCSP_RESP_CERT_NAME = + plc.VAL_OCSP_RESP_CERT_NAME; + } + + if (flags & KC_OCSP_RESP_CERT_SERIAL) { + if (oplc.VAL_OCSP_RESP_CERT_SERIAL) + free(oplc.VAL_OCSP_RESP_CERT_SERIAL); + oplc.VAL_OCSP_RESP_CERT_SERIAL = + plc.VAL_OCSP_RESP_CERT_SERIAL; + } + + if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL && + oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL) + oplc.VAL_OCSP.has_resp_cert = B_TRUE; + else + oplc.VAL_OCSP.has_resp_cert = B_FALSE; + + /* Turn on the OCSP checking */ + oplc.revocation |= KMF_REVOCATION_METHOD_OCSP; + } + } + + /* Update the CRL policy */ + if (crl_none_opt == B_TRUE) { + if (crl_set_attr > 0) { + (void) fprintf(stderr, + gettext("Can not set crl-none=true and other CRL " + "attributes at the same time.\n")); + rv = KC_ERR_USAGE; + goto out; + } + + /* + * If the original policy does not have CRL checking, + * then we do not need to do anything. If the original + * policy has the CRL checking, then we need to release the + * space of CRL attributes and turn the CRL checking off. + */ + if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) { + if (oplc.VAL_CRL_BASEFILENAME) { + free(oplc.VAL_CRL_BASEFILENAME); + oplc.VAL_CRL_BASEFILENAME = NULL; + } + + if (oplc.VAL_CRL_DIRECTORY) { + free(oplc.VAL_CRL_DIRECTORY); + oplc.VAL_CRL_DIRECTORY = NULL; + } + + if (oplc.VAL_CRL_PROXY) { + free(oplc.VAL_CRL_PROXY); + oplc.VAL_CRL_PROXY = NULL; + } + + /* Turn off the CRL checking */ + oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL; + } + } else { + /* + * If the "ocsp-none" option is not set or is set to false, + * then we only need to do the modification if there is at + * least one CRL attribute is specified. + */ + if (crl_set_attr > 0) { + if (flags & KC_CRL_BASEFILENAME) { + if (oplc.VAL_CRL_BASEFILENAME) + free(oplc.VAL_CRL_BASEFILENAME); + oplc.VAL_CRL_BASEFILENAME = + plc.VAL_CRL_BASEFILENAME; + } + + if (flags & KC_CRL_DIRECTORY) { + if (oplc.VAL_CRL_DIRECTORY) + free(oplc.VAL_CRL_DIRECTORY); + oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY; + } + + if (flags & KC_CRL_GET_URI) { + oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI; + } + + if (flags & KC_CRL_PROXY) { + if (oplc.VAL_CRL_PROXY) + free(oplc.VAL_CRL_PROXY); + oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY; + } + + if (flags & KC_CRL_IGNORE_SIGN) { + oplc.VAL_CRL_IGNORE_SIGN = + plc.VAL_CRL_IGNORE_SIGN; + } + + if (flags & KC_CRL_IGNORE_DATE) { + oplc.VAL_CRL_IGNORE_DATE = + plc.VAL_CRL_IGNORE_DATE; + } + + /* Turn on the CRL checking */ + oplc.revocation |= KMF_REVOCATION_METHOD_CRL; + } + } + + /* Update the Key Usage */ + if (ku_none_opt == B_TRUE) { + if (flags & KC_KEYUSAGE) { + (void) fprintf(stderr, + gettext("Can not set keyusage-none=true and " + "modify the keyusage value at the same time.\n")); + rv = KC_ERR_USAGE; + goto out; + } + + oplc.ku_bits = 0; + } else { + /* + * If the "keyusage-none" option is not set or is set to + * false, then we only need to do the modification if + * the keyusage value is specified. + */ + if (flags & KC_KEYUSAGE) + oplc.ku_bits = plc.ku_bits; + } + + + /* Update the Extended Key Usage */ + if (eku_none_opt == B_TRUE) { + if (flags & KC_EKUS) { + (void) fprintf(stderr, + gettext("Can not set eku-none=true and modify " + "EKU values at the same time.\n")); + rv = KC_ERR_USAGE; + goto out; + } + + /* Release current EKU list (if any) */ + if (oplc.eku_set.eku_count > 0) { + KMF_FreeEKUPolicy(&oplc.eku_set); + oplc.eku_set.eku_count = 0; + oplc.eku_set.ekulist = NULL; + } + } else { + /* + * If the "eku-none" option is not set or is set to false, + * then we only need to do the modification if either + * "ekuname" or "ekuoids" is specified. + */ + if (flags & KC_EKUS) { + /* Release current EKU list (if any) */ + KMF_FreeEKUPolicy(&oplc.eku_set); + oplc.eku_set = plc.eku_set; + } + } + + /* Do a sanity check on the modified policy */ + ret = KMF_VerifyPolicy(&oplc); + if (ret != KMF_OK) { + print_sanity_error(ret); + rv = KC_ERR_VERIFY_POLICY; + goto out; + } + + /* The modify operation is a delete followed by an add */ + ret = KMF_DeletePolicyFromDB(oplc.name, filename); + if (ret != KMF_OK) { + rv = KC_ERR_DELETE_POLICY; + goto out; + } + + /* + * Now add the modified policy back to the DB. + */ + ret = KMF_AddPolicyToDB(&oplc, filename, B_FALSE); + if (ret != KMF_OK) { + (void) fprintf(stderr, + gettext("Error adding policy to database: 0x%04x\n"), ret); + rv = KC_ERR_ADD_POLICY; + goto out; + } + +out: + if (filename != NULL) + free(filename); + + KMF_FreePolicyRecord(&oplc); + + return (rv); +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/util.c b/usr/src/cmd/cmd-crypto/kmfcfg/util.c new file mode 100644 index 0000000000..f3bdc633f2 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/util.c @@ -0,0 +1,497 @@ +/* + * 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <strings.h> +#include <ctype.h> +#include <libgen.h> +#include <libintl.h> + +#include <libxml/tree.h> +#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 */ + char *longnm; /* long name string, NOT terminated */ + int longnm_len; /* length of long name string */ + boolean_t has_arg; /* takes optional argument */ +} av_opts; + +static av_opts *opts_av = NULL; +static const char *_save_optstr = NULL; +static int _save_numopts = 0; +int optind_av = 1; +char *optarg_av = NULL; + +void +free_policy_list(POLICY_LIST *plist) +{ + POLICY_LIST *n = plist, *old; + + if (plist == NULL) + return; + + while (n != NULL) { + old = n; + KMF_FreePolicyRecord(&n->plc); + n = n->next; + free(old); + } + plist = NULL; +} + +int +load_policies(char *file, POLICY_LIST **policy_list) +{ + int rv = KC_OK; + KMF_RETURN kmfrv = KMF_OK; + POLICY_LIST *newitem, *plist = NULL; + xmlParserCtxtPtr ctxt; + xmlDocPtr doc = NULL; + xmlNodePtr cur, node; + + /* Create a parser context */ + ctxt = xmlNewParserCtxt(); + if (ctxt == NULL) + return (KMF_ERR_POLICY_DB_FORMAT); + + /* Read the policy DB and verify it against the schema. */ + doc = xmlCtxtReadFile(ctxt, file, NULL, + XML_PARSE_DTDVALID | XML_PARSE_NOERROR | XML_PARSE_NOWARNING); + if (doc == NULL || ctxt->valid == 0) { + kmfrv = KMF_ERR_POLICY_DB_FORMAT; + goto end; + } + + cur = xmlDocGetRootElement(doc); + if (cur == NULL) { + kmfrv = KMF_ERR_POLICY_DB_FORMAT; + goto end; + } + + node = cur->xmlChildrenNode; + while (node != NULL) { + char *c; + /* + * Search for the policy that matches the given name. + */ + if (!xmlStrcmp((const xmlChar *)node->name, + (const xmlChar *)KMF_POLICY_ELEMENT)) { + /* Check the name attribute */ + c = (char *)xmlGetProp(node, + (const xmlChar *)KMF_POLICY_NAME_ATTR); + + /* If a match, parse the rest of the data */ + if (c != NULL) { + xmlFree(c); + newitem = malloc(sizeof (POLICY_LIST)); + if (newitem != NULL) { + (void) memset(newitem, 0, + sizeof (POLICY_LIST)); + kmfrv = parsePolicyElement(node, + &newitem->plc); + } else { + kmfrv = KMF_ERR_MEMORY; + goto end; + } + /* add to linked list */ + if (plist == NULL) { + plist = newitem; + } else { + POLICY_LIST *n = plist; + while (n->next != NULL) + n = n->next; + + n->next = newitem; + newitem->next = NULL; + } + } + } + node = node->next; + } + +end: + if (ctxt != NULL) + xmlFreeParserCtxt(ctxt); + + if (doc != NULL) + xmlFreeDoc(doc); + + if (kmfrv != KMF_OK) { + free_policy_list(plist); + rv = KC_ERR_LOADDB; + } else { + *policy_list = plist; + } + + return (rv); +} + +/* + * Return 0 if there is any error in the input string. + */ +uint16_t +parseKUlist(char *kustring) +{ + uint16_t cur_bit; + uint16_t kubits = 0; + char *p; + + p = strtok(kustring, ","); + while (p != NULL) { + cur_bit = KMF_StringToKeyUsage(p); + if (cur_bit == 0) { + kubits = 0; + break; + } + kubits |= cur_bit; + p = strtok(NULL, ","); + } + + return (kubits); +} + +static void +addToEKUList(KMF_EKU_POLICY *ekus, KMF_OID *newoid) +{ + if (newoid != NULL && ekus != NULL) { + ekus->eku_count++; + ekus->ekulist = realloc( + ekus->ekulist, + ekus->eku_count * sizeof (KMF_OID)); + if (ekus->ekulist != NULL) { + ekus->ekulist[ekus->eku_count-1] = *newoid; + } + } +} + +int +parseEKUNames(char *ekulist, KMF_POLICY_RECORD *plc) +{ + int rv = KC_OK; + char *p; + KMF_OID *newoid; + KMF_EKU_POLICY *ekus = &plc->eku_set; + + if (ekulist == NULL || !strlen(ekulist)) + return (0); + + /* + * The list should be comma separated list of EKU Names. + */ + p = strtok(ekulist, ","); + + /* If no tokens found, then maybe its just a single EKU value */ + if (p == NULL) { + newoid = kmf_ekuname2oid(ekulist); + if (newoid != NULL) { + addToEKUList(ekus, newoid); + free(newoid); + } else { + rv = KC_ERR_USAGE; + } + } + + while (p != NULL) { + newoid = kmf_ekuname2oid(p); + if (newoid != NULL) { + addToEKUList(ekus, newoid); + free(newoid); + } else { + rv = KC_ERR_USAGE; + break; + } + p = strtok(NULL, ","); + } + + if (rv != KC_OK) + KMF_FreeEKUPolicy(ekus); + + return (rv); +} + +int +parseEKUOIDs(char *ekulist, KMF_POLICY_RECORD *plc) +{ + int rv = KC_OK; + char *p; + KMF_OID *newoid; + KMF_EKU_POLICY *ekus = &plc->eku_set; + + if (ekulist == NULL || !strlen(ekulist)) + return (0); + + /* + * The list should be comma separated list of EKU Names. + */ + p = strtok(ekulist, ","); + if (p == NULL) { + newoid = kmf_string2oid(ekulist); + if (newoid != NULL) { + addToEKUList(ekus, newoid); + free(newoid); + } else { + rv = KC_ERR_USAGE; + } + } + + while (p != NULL && rv == 0) { + newoid = kmf_string2oid(p); + if (newoid != NULL) { + addToEKUList(ekus, newoid); + free(newoid); + } else { + rv = KC_ERR_USAGE; + break; + } + p = strtok(NULL, ","); + } + + if (rv != KC_OK) + KMF_FreeEKUPolicy(ekus); + + return (rv); +} + +int +get_boolean(char *arg) +{ + if (arg == NULL) + return (-1); + if (strcasecmp(arg, "true") == 0) + return (1); + if (strcasecmp(arg, "false") == 0) + return (0); + return (-1); +} + +/* + * This function processes the input string. It removes the beginning + * and ending blank's first, makes a copy of the resulting string and + * return it. + * + * This function returns NULL, if there is an error in the + * input string or when the system is out of memory. The output + * "err_flag" argument will record the error code, if it is not NULL. + */ +char * +get_string(char *str, int *err_flag) +{ + char *p; + int len, i; + char *retstr = NULL; + + if (str == NULL) { + if (err_flag != NULL) + *err_flag = KC_ERR_USAGE; + return (NULL); + } + + /* Remove beginning whitespace */ + p = str; + while (p != NULL && isspace(*p)) + p++; + + if (p == NULL) { + if (err_flag != NULL) + *err_flag = KC_ERR_USAGE; + return (NULL); + } + + /* Remove the trailing blanks */ + len = strlen(p); + while (len > 0 && isspace(p[len-1])) + len--; + + if (len == 0) { + if (err_flag != NULL) + *err_flag = KC_ERR_USAGE; + return (NULL); + } + + /* Check if there is any non-printable character */ + i = 0; + while (i < len) { + if (isprint(p[i])) + i++; + else { + if (err_flag != NULL) + *err_flag = KC_ERR_USAGE; + return (NULL); + } + } + + /* Make a copy of the string and return it */ + retstr = malloc(len + 1); + if (retstr == NULL) { + if (err_flag != NULL) + *err_flag = KC_ERR_MEMORY; + return (NULL); + } + + if (err_flag != NULL) + *err_flag = KC_OK; + + (void) strncpy(retstr, p, len); + retstr[len] = '\0'; + return (retstr); +} + +/* + * Breaks out the getopt-style option string into a structure that can be + * traversed later for calls to getopt_av(). Option string is NOT altered, + * but the struct fields point to locations within option string. + */ +static int +populate_opts(char *optstring) +{ + int i; + av_opts *temp; + char *marker; + + if (optstring == NULL || *optstring == '\0') + return (0); + + /* + * This tries to imitate getopt(3c) Each option must conform to: + * <short name char> [ ':' ] [ '(' <long name string> ')' ] + * If long name is missing, the short name is used for long name. + */ + for (i = 0; *optstring != '\0'; i++) { + if ((temp = (av_opts *)((i == 0) ? malloc(sizeof (av_opts)) : + realloc(opts_av, (i+1) * sizeof (av_opts)))) == NULL) { + free(opts_av); + opts_av = NULL; + return (0); + } else + opts_av = (av_opts *)temp; + + marker = optstring; /* may need optstring later */ + + opts_av[i].shortnm = *marker++; /* set short name */ + + if (*marker == ':') { /* check for opt arg */ + marker++; + opts_av[i].has_arg = B_TRUE; + } + + if (*marker == '(') { /* check and set long name */ + marker++; + opts_av[i].longnm = marker; + opts_av[i].longnm_len = strcspn(marker, ")"); + optstring = marker + opts_av[i].longnm_len + 1; + } else { + /* use short name option character */ + opts_av[i].longnm = optstring; + opts_av[i].longnm_len = 1; + optstring = marker; + } + } + + return (i); +} + +/* + * getopt_av() is very similar to getopt(3c) in that the takes an option + * string, compares command line arguments for matches, and returns a single + * letter option when a match is found. However, getopt_av() differs from + * getopt(3c) by allowing both longname options and values be found + * on the command line. + */ +int +getopt_av(int argc, char * const *argv, const char *optstring) +{ + int i; + int len; + + if (optind_av >= argc) + return (EOF); + + /* First time or when optstring changes from previous one */ + if (_save_optstr != optstring) { + if (opts_av != NULL) + free(opts_av); + opts_av = NULL; + _save_optstr = optstring; + _save_numopts = populate_opts((char *)optstring); + } + + for (i = 0; i < _save_numopts; i++) { + if (strcmp(argv[optind_av], "--") == 0) { + optind_av++; + break; + } + + len = strcspn(argv[optind_av], "="); + + if (len == opts_av[i].longnm_len && strncmp(argv[optind_av], + opts_av[i].longnm, opts_av[i].longnm_len) == 0) { + /* matched */ + if (!opts_av[i].has_arg) { + optind_av++; + return (opts_av[i].shortnm); + } + + /* needs optarg */ + if (argv[optind_av][len] == '=') { + optarg_av = &(argv[optind_av][len+1]); + optind_av++; + return (opts_av[i].shortnm); + } + + optarg_av = NULL; + optind_av++; + return ((int)'?'); + } + } + + return (EOF); +} + +void +print_sanity_error(KMF_RETURN ret) +{ + switch (ret) { + case KMF_ERR_POLICY_NAME: + (void) fprintf(stderr, gettext("Error in the policy name\n")); + break; + case KMF_ERR_TA_POLICY: + (void) fprintf(stderr, + gettext("Error in trust anchor attributes\n")); + break; + case KMF_ERR_OCSP_POLICY: + (void) fprintf(stderr, + gettext("Error in OCSP policy attributes\n")); + break; + default: + break; + } +} diff --git a/usr/src/cmd/cmd-crypto/kmfcfg/util.h b/usr/src/cmd/cmd-crypto/kmfcfg/util.h new file mode 100644 index 0000000000..74f4b0be9b --- /dev/null +++ b/usr/src/cmd/cmd-crypto/kmfcfg/util.h @@ -0,0 +1,66 @@ +/* + * 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. + */ +#ifndef _UTIL_H +#define _UTIL_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <kmfapiP.h> + + +typedef struct _policy_list { + KMF_POLICY_RECORD plc; + struct _policy_list *next; +} POLICY_LIST; + +void free_policy_list(POLICY_LIST *); +int getopt_av(int, char * const *, const char *); + +int load_policies(char *, POLICY_LIST **); +int get_boolean(char *); +char *get_string(char *, int *err_flag); +int parseEKUOIDs(char *, KMF_POLICY_RECORD *); +int parseEKUNames(char *, KMF_POLICY_RECORD *); +uint16_t parseKUlist(char *); +void print_sanity_error(KMF_RETURN); + +#define KC_OK 0 +#define KC_ERR_USAGE 1 +#define KC_ERR_LOADDB 2 +#define KC_ERR_FIND_POLICY 3 +#define KC_ERR_DELETE_POLICY 4 +#define KC_ERR_ADD_POLICY 5 +#define KC_ERR_VERIFY_POLICY 6 +#define KC_ERR_INCOMPLETE_POLICY 7 +#define KC_ERR_MEMORY 8 +#define KC_ERR_ACCESS 9 + +#ifdef __cplusplus +} +#endif +#endif /* _UTIL_H */ |