13089Swyllys /*
23089Swyllys * CDDL HEADER START
33089Swyllys *
43089Swyllys * The contents of this file are subject to the terms of the
53089Swyllys * Common Development and Distribution License (the "License").
63089Swyllys * You may not use this file except in compliance with the License.
73089Swyllys *
83089Swyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93089Swyllys * or http://www.opensolaris.org/os/licensing.
103089Swyllys * See the License for the specific language governing permissions
113089Swyllys * and limitations under the License.
123089Swyllys *
133089Swyllys * When distributing Covered Code, include this CDDL HEADER in each
143089Swyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153089Swyllys * If applicable, add the following below this CDDL HEADER, with the
163089Swyllys * fields enclosed by brackets "[]" replaced with your own identifying
173089Swyllys * information: Portions Copyright [yyyy] [name of copyright owner]
183089Swyllys *
193089Swyllys * CDDL HEADER END
203089Swyllys *
2112611SJan.Pechanec@Sun.COM * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
223089Swyllys */
233089Swyllys
243089Swyllys #include <stdio.h>
253089Swyllys #include <strings.h>
263089Swyllys #include <ctype.h>
273089Swyllys #include <libgen.h>
283089Swyllys #include <libintl.h>
293089Swyllys #include <errno.h>
303089Swyllys #include <kmfapiP.h>
313089Swyllys #include <cryptoutil.h>
325626Shylee #include <sys/stat.h>
335626Shylee #include <sys/param.h>
343089Swyllys #include "util.h"
353089Swyllys
363089Swyllys #define KC_IGNORE_DATE 0x0000001
373089Swyllys #define KC_IGNORE_UNKNOWN_EKUS 0x0000002
383089Swyllys #define KC_IGNORE_TRUST_ANCHOR 0x0000004
393089Swyllys #define KC_VALIDITY_ADJUSTTIME 0x0000008
403089Swyllys #define KC_TA_NAME 0x0000010
413089Swyllys #define KC_TA_SERIAL 0x0000020
423089Swyllys #define KC_OCSP_RESPONDER_URI 0x0000040
433089Swyllys #define KC_OCSP_PROXY 0x0000080
443089Swyllys #define KC_OCSP_URI_FROM_CERT 0x0000100
453089Swyllys #define KC_OCSP_RESP_LIFETIME 0x0000200
463089Swyllys #define KC_OCSP_IGNORE_RESP_SIGN 0x0000400
473089Swyllys #define KC_OCSP_RESP_CERT_NAME 0x0000800
483089Swyllys #define KC_OCSP_RESP_CERT_SERIAL 0x0001000
493089Swyllys #define KC_OCSP_NONE 0x0002000
503089Swyllys #define KC_CRL_BASEFILENAME 0x0004000
513089Swyllys #define KC_CRL_DIRECTORY 0x0008000
523089Swyllys #define KC_CRL_GET_URI 0x0010000
533089Swyllys #define KC_CRL_PROXY 0x0020000
543089Swyllys #define KC_CRL_IGNORE_SIGN 0x0040000
553089Swyllys #define KC_CRL_IGNORE_DATE 0x0080000
563089Swyllys #define KC_CRL_NONE 0x0100000
573089Swyllys #define KC_KEYUSAGE 0x0200000
583089Swyllys #define KC_KEYUSAGE_NONE 0x0400000
593089Swyllys #define KC_EKUS 0x0800000
603089Swyllys #define KC_EKUS_NONE 0x1000000
6112611SJan.Pechanec@Sun.COM #define KC_MAPPER_OPTIONS 0x2000000
623089Swyllys
635626Shylee static int err; /* To store errno which may be overwritten by gettext() */
645626Shylee
6512611SJan.Pechanec@Sun.COM #define UPDATE_IF_DIFFERENT(old, new) \
6612611SJan.Pechanec@Sun.COM if ((old != NULL && new != NULL && strcmp(old, new) != 0) || \
6712611SJan.Pechanec@Sun.COM (old == NULL && new != NULL)) { \
6812611SJan.Pechanec@Sun.COM if (old != NULL) \
6912611SJan.Pechanec@Sun.COM free(old); \
7012611SJan.Pechanec@Sun.COM old = new; \
7112611SJan.Pechanec@Sun.COM }
725626Shylee
733089Swyllys int
kc_modify_policy(int argc,char * argv[])745626Shylee kc_modify_policy(int argc, char *argv[])
753089Swyllys {
763089Swyllys KMF_RETURN ret;
773089Swyllys int rv = KC_OK;
783089Swyllys int opt;
793089Swyllys extern int optind_av;
803089Swyllys extern char *optarg_av;
813089Swyllys char *filename = NULL;
8212611SJan.Pechanec@Sun.COM char *mapper_name = NULL;
8312611SJan.Pechanec@Sun.COM char *mapper_dir = NULL;
8412611SJan.Pechanec@Sun.COM char *mapper_pathname = NULL;
853089Swyllys uint32_t flags = 0;
863089Swyllys boolean_t ocsp_none_opt = B_FALSE;
873089Swyllys boolean_t crl_none_opt = B_FALSE;
883089Swyllys boolean_t ku_none_opt = B_FALSE;
893089Swyllys boolean_t eku_none_opt = B_FALSE;
903089Swyllys int ocsp_set_attr = 0;
913089Swyllys int crl_set_attr = 0;
923089Swyllys KMF_POLICY_RECORD oplc, plc;
933089Swyllys
943089Swyllys (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD));
953089Swyllys (void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD));
963089Swyllys
973089Swyllys while ((opt = getopt_av(argc, argv,
985051Swyllys "i:(dbfile)"
995051Swyllys "p:(policy)"
1005051Swyllys "d:(ignore-date)"
1015051Swyllys "e:(ignore-unknown-eku)"
1025051Swyllys "a:(ignore-trust-anchor)"
1035051Swyllys "v:(validity-adjusttime)"
1045051Swyllys "t:(ta-name)"
1055051Swyllys "s:(ta-serial)"
1065051Swyllys "o:(ocsp-responder)"
1075051Swyllys "P:(ocsp-proxy)"
1085051Swyllys "r:(ocsp-use-cert-responder)"
1095051Swyllys "T:(ocsp-response-lifetime)"
1105051Swyllys "R:(ocsp-ignore-response-sign)"
1115051Swyllys "n:(ocsp-responder-cert-name)"
1125051Swyllys "A:(ocsp-responder-cert-serial)"
1135051Swyllys "y:(ocsp-none)"
1145051Swyllys "c:(crl-basefilename)"
1155051Swyllys "I:(crl-directory)"
1165051Swyllys "g:(crl-get-crl-uri)"
1175051Swyllys "X:(crl-proxy)"
1185051Swyllys "S:(crl-ignore-crl-sign)"
1195051Swyllys "D:(crl-ignore-crl-date)"
1205051Swyllys "z:(crl-none)"
1215051Swyllys "u:(keyusage)"
1225051Swyllys "Y:(keyusage-none)"
1235051Swyllys "E:(ekunames)"
1245051Swyllys "O:(ekuoids)"
12512611SJan.Pechanec@Sun.COM "m:(mapper-name)"
12612611SJan.Pechanec@Sun.COM "M:(mapper-directory)"
12712611SJan.Pechanec@Sun.COM "Q:(mapper-pathname)"
12812611SJan.Pechanec@Sun.COM "q:(mapper-options)"
1295051Swyllys "Z:(eku-none)")) != EOF) {
1303089Swyllys switch (opt) {
1313089Swyllys case 'i':
1323089Swyllys filename = get_string(optarg_av, &rv);
1333089Swyllys if (filename == NULL) {
1343089Swyllys (void) fprintf(stderr,
1353089Swyllys gettext("Error dbfile input.\n"));
1363089Swyllys }
1373089Swyllys break;
1383089Swyllys case 'p':
1393089Swyllys plc.name = get_string(optarg_av, &rv);
1403089Swyllys if (plc.name == NULL) {
1413089Swyllys (void) fprintf(stderr,
1423089Swyllys gettext("Error policy name.\n"));
1433089Swyllys }
1443089Swyllys break;
1453089Swyllys case 'd':
1463089Swyllys plc.ignore_date = get_boolean(optarg_av);
1473089Swyllys if (plc.ignore_date == -1) {
1483089Swyllys (void) fprintf(stderr,
1493089Swyllys gettext("Error boolean input.\n"));
1503089Swyllys rv = KC_ERR_USAGE;
1513089Swyllys } else {
1523089Swyllys flags |= KC_IGNORE_DATE;
1533089Swyllys }
1543089Swyllys break;
1553089Swyllys case 'e':
1563089Swyllys plc.ignore_unknown_ekus =
1573089Swyllys get_boolean(optarg_av);
1583089Swyllys if (plc.ignore_unknown_ekus == -1) {
1593089Swyllys (void) fprintf(stderr,
1603089Swyllys gettext("Error boolean input.\n"));
1613089Swyllys rv = KC_ERR_USAGE;
1623089Swyllys } else {
1633089Swyllys flags |= KC_IGNORE_UNKNOWN_EKUS;
1643089Swyllys }
1653089Swyllys break;
1663089Swyllys case 'a':
1673089Swyllys plc.ignore_trust_anchor =
1683089Swyllys get_boolean(optarg_av);
1693089Swyllys if (plc.ignore_trust_anchor == -1) {
1703089Swyllys (void) fprintf(stderr,
1713089Swyllys gettext("Error boolean input.\n"));
1723089Swyllys rv = KC_ERR_USAGE;
1733089Swyllys } else {
1743089Swyllys flags |= KC_IGNORE_TRUST_ANCHOR;
1753089Swyllys }
1763089Swyllys break;
1773089Swyllys case 'v':
1783089Swyllys plc.validity_adjusttime =
1793089Swyllys get_string(optarg_av, &rv);
1803089Swyllys if (plc.validity_adjusttime == NULL) {
1813089Swyllys (void) fprintf(stderr,
1823089Swyllys gettext("Error time input.\n"));
1833089Swyllys } else {
1843089Swyllys uint32_t adj;
1853089Swyllys /* for syntax checking */
1863089Swyllys if (str2lifetime(
1873089Swyllys plc.validity_adjusttime,
1883089Swyllys &adj) < 0) {
1893089Swyllys (void) fprintf(stderr,
1903089Swyllys gettext("Error time "
1913089Swyllys "input.\n"));
1923089Swyllys rv = KC_ERR_USAGE;
1933089Swyllys } else {
1943089Swyllys flags |= KC_VALIDITY_ADJUSTTIME;
1953089Swyllys }
1963089Swyllys }
1973089Swyllys break;
1983089Swyllys case 't':
1993089Swyllys plc.ta_name = get_string(optarg_av, &rv);
2003089Swyllys if (plc.ta_name == NULL) {
2013089Swyllys (void) fprintf(stderr,
2023089Swyllys gettext("Error name input.\n"));
203*12919Swyllys.ingersoll@sun.com } else if (strcasecmp(plc.ta_name, "search")) {
2043089Swyllys KMF_X509_NAME taDN;
2053089Swyllys /* for syntax checking */
2065051Swyllys if (kmf_dn_parser(plc.ta_name,
2073089Swyllys &taDN) != KMF_OK) {
2083089Swyllys (void) fprintf(stderr,
2093089Swyllys gettext("Error name "
2103089Swyllys "input.\n"));
2113089Swyllys rv = KC_ERR_USAGE;
2123089Swyllys } else {
2135051Swyllys kmf_free_dn(&taDN);
2143089Swyllys flags |= KC_TA_NAME;
2153089Swyllys }
216*12919Swyllys.ingersoll@sun.com } else {
217*12919Swyllys.ingersoll@sun.com flags |= KC_TA_NAME;
2183089Swyllys }
2193089Swyllys break;
2203089Swyllys case 's':
2213089Swyllys plc.ta_serial = get_string(optarg_av, &rv);
2223089Swyllys if (plc.ta_serial == NULL) {
2233089Swyllys (void) fprintf(stderr,
2243089Swyllys gettext("Error serial input.\n"));
2253089Swyllys } else {
2263089Swyllys uchar_t *bytes = NULL;
2273089Swyllys size_t bytelen;
2283089Swyllys
2295051Swyllys ret = kmf_hexstr_to_bytes(
2303089Swyllys (uchar_t *)plc.ta_serial,
2313089Swyllys &bytes, &bytelen);
2323089Swyllys if (ret != KMF_OK || bytes == NULL) {
2333089Swyllys (void) fprintf(stderr,
2343089Swyllys gettext("serial number "
2353089Swyllys "must be specified as a "
2363089Swyllys "hex number "
2373089Swyllys "(ex: 0x0102030405"
2383089Swyllys "ffeeddee)\n"));
2393089Swyllys rv = KC_ERR_USAGE;
2403089Swyllys break;
2413089Swyllys }
2423089Swyllys if (bytes != NULL)
2433089Swyllys free(bytes);
2443089Swyllys flags |= KC_TA_SERIAL;
2453089Swyllys }
2463089Swyllys break;
2473089Swyllys case 'o':
2483089Swyllys plc.VAL_OCSP_RESPONDER_URI =
2495051Swyllys get_string(optarg_av, &rv);
2503089Swyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
2513089Swyllys (void) fprintf(stderr,
2523089Swyllys gettext("Error responder "
2533089Swyllys "input.\n"));
2543089Swyllys } else {
2553089Swyllys flags |= KC_OCSP_RESPONDER_URI;
2563089Swyllys ocsp_set_attr++;
2573089Swyllys }
2583089Swyllys break;
2593089Swyllys case 'P':
2603089Swyllys plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv);
2613089Swyllys if (plc.VAL_OCSP_PROXY == NULL) {
2623089Swyllys (void) fprintf(stderr,
2633089Swyllys gettext("Error proxy input.\n"));
2643089Swyllys } else {
2653089Swyllys flags |= KC_OCSP_PROXY;
2663089Swyllys ocsp_set_attr++;
2673089Swyllys }
2683089Swyllys break;
2693089Swyllys case 'r':
2703089Swyllys plc.VAL_OCSP_URI_FROM_CERT =
2713089Swyllys get_boolean(optarg_av);
2723089Swyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
2733089Swyllys (void) fprintf(stderr,
2743089Swyllys gettext("Error boolean input.\n"));
2753089Swyllys rv = KC_ERR_USAGE;
2763089Swyllys } else {
2773089Swyllys flags |= KC_OCSP_URI_FROM_CERT;
2783089Swyllys ocsp_set_attr++;
2793089Swyllys }
2803089Swyllys break;
2813089Swyllys case 'T':
2823089Swyllys plc.VAL_OCSP_RESP_LIFETIME =
2833089Swyllys get_string(optarg_av, &rv);
2843089Swyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
2853089Swyllys (void) fprintf(stderr,
2863089Swyllys gettext("Error time input.\n"));
2873089Swyllys } else {
2883089Swyllys uint32_t adj;
2893089Swyllys /* for syntax checking */
2903089Swyllys if (str2lifetime(
2913089Swyllys plc.VAL_OCSP_RESP_LIFETIME,
2923089Swyllys &adj) < 0) {
2933089Swyllys (void) fprintf(stderr,
2943089Swyllys gettext("Error time "
2953089Swyllys "input.\n"));
2963089Swyllys rv = KC_ERR_USAGE;
2973089Swyllys } else {
2983089Swyllys flags |= KC_OCSP_RESP_LIFETIME;
2993089Swyllys ocsp_set_attr++;
3003089Swyllys }
3013089Swyllys }
3023089Swyllys break;
3033089Swyllys case 'R':
3043089Swyllys plc.VAL_OCSP_IGNORE_RESP_SIGN =
3053089Swyllys get_boolean(optarg_av);
3063089Swyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
3073089Swyllys (void) fprintf(stderr,
3083089Swyllys gettext("Error boolean input.\n"));
3093089Swyllys rv = KC_ERR_USAGE;
3103089Swyllys } else {
3113089Swyllys flags |= KC_OCSP_IGNORE_RESP_SIGN;
3123089Swyllys ocsp_set_attr++;
3133089Swyllys }
3143089Swyllys break;
3153089Swyllys case 'n':
3163089Swyllys plc.VAL_OCSP_RESP_CERT_NAME =
3173089Swyllys get_string(optarg_av, &rv);
3183089Swyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
3193089Swyllys (void) fprintf(stderr,
3203089Swyllys gettext("Error name input.\n"));
3213089Swyllys } else {
3223089Swyllys KMF_X509_NAME respDN;
3233089Swyllys /* for syntax checking */
3245051Swyllys if (kmf_dn_parser(
3253089Swyllys plc.VAL_OCSP_RESP_CERT_NAME,
3263089Swyllys &respDN) != KMF_OK) {
3273089Swyllys (void) fprintf(stderr,
3283089Swyllys gettext("Error name "
3293089Swyllys "input.\n"));
3303089Swyllys rv = KC_ERR_USAGE;
3313089Swyllys } else {
3325051Swyllys kmf_free_dn(&respDN);
3333089Swyllys flags |= KC_OCSP_RESP_CERT_NAME;
3343089Swyllys ocsp_set_attr++;
3353089Swyllys }
3363089Swyllys }
3373089Swyllys break;
3383089Swyllys case 'A':
3393089Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL =
3403089Swyllys get_string(optarg_av, &rv);
3413089Swyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
3423089Swyllys (void) fprintf(stderr,
3433089Swyllys gettext("Error serial input.\n"));
3443089Swyllys } else {
3453089Swyllys uchar_t *bytes = NULL;
3463089Swyllys size_t bytelen;
3473089Swyllys
3485051Swyllys ret = kmf_hexstr_to_bytes((uchar_t *)
3493089Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL,
3503089Swyllys &bytes, &bytelen);
3513089Swyllys if (ret != KMF_OK || bytes == NULL) {
3523089Swyllys (void) fprintf(stderr,
3533089Swyllys gettext("serial number "
3543089Swyllys "must be specified as a "
3553089Swyllys "hex number "
3563089Swyllys "(ex: 0x0102030405"
3573089Swyllys "ffeeddee)\n"));
3583089Swyllys rv = KC_ERR_USAGE;
3593089Swyllys break;
3603089Swyllys }
3613089Swyllys if (bytes != NULL)
3623089Swyllys free(bytes);
3633089Swyllys flags |= KC_OCSP_RESP_CERT_SERIAL;
3643089Swyllys ocsp_set_attr++;
3653089Swyllys }
3663089Swyllys break;
3673089Swyllys case 'y':
3683089Swyllys ocsp_none_opt = get_boolean(optarg_av);
3693089Swyllys if (ocsp_none_opt == -1) {
3703089Swyllys (void) fprintf(stderr,
3713089Swyllys gettext("Error boolean input.\n"));
3723089Swyllys rv = KC_ERR_USAGE;
3733089Swyllys } else {
3743089Swyllys flags |= KC_OCSP_NONE;
3753089Swyllys }
3763089Swyllys break;
3773089Swyllys case 'c':
3783089Swyllys plc.VAL_CRL_BASEFILENAME =
3793089Swyllys get_string(optarg_av, &rv);
3803089Swyllys if (plc.VAL_CRL_BASEFILENAME == NULL) {
3813089Swyllys (void) fprintf(stderr, gettext(
3823089Swyllys "Error basefilename input.\n"));
3833089Swyllys } else {
3843089Swyllys flags |= KC_CRL_BASEFILENAME;
3853089Swyllys crl_set_attr++;
3863089Swyllys }
3873089Swyllys break;
3883089Swyllys case 'I':
3893089Swyllys plc.VAL_CRL_DIRECTORY =
3903089Swyllys get_string(optarg_av, &rv);
3913089Swyllys if (plc.VAL_CRL_DIRECTORY == NULL) {
3923089Swyllys (void) fprintf(stderr,
3933089Swyllys gettext("Error boolean input.\n"));
3943089Swyllys } else {
3953089Swyllys flags |= KC_CRL_DIRECTORY;
3963089Swyllys crl_set_attr++;
3973089Swyllys }
3983089Swyllys break;
3993089Swyllys case 'g':
4003089Swyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
4013089Swyllys if (plc.VAL_CRL_GET_URI == -1) {
4023089Swyllys (void) fprintf(stderr,
4033089Swyllys gettext("Error boolean input.\n"));
4043089Swyllys rv = KC_ERR_USAGE;
4053089Swyllys } else {
4063089Swyllys flags |= KC_CRL_GET_URI;
4073089Swyllys crl_set_attr++;
4083089Swyllys }
4093089Swyllys break;
4103089Swyllys case 'X':
4113089Swyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
4123089Swyllys if (plc.VAL_CRL_PROXY == NULL) {
4133089Swyllys (void) fprintf(stderr,
4143089Swyllys gettext("Error proxy input.\n"));
4153089Swyllys } else {
4163089Swyllys flags |= KC_CRL_PROXY;
4173089Swyllys crl_set_attr++;
4183089Swyllys }
4193089Swyllys break;
4203089Swyllys case 'S':
4213089Swyllys plc.VAL_CRL_IGNORE_SIGN =
4223089Swyllys get_boolean(optarg_av);
4233089Swyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) {
4243089Swyllys (void) fprintf(stderr,
4253089Swyllys gettext("Error boolean input.\n"));
4263089Swyllys rv = KC_ERR_USAGE;
4273089Swyllys } else {
4283089Swyllys flags |= KC_CRL_IGNORE_SIGN;
4293089Swyllys crl_set_attr++;
4303089Swyllys }
4313089Swyllys break;
4323089Swyllys case 'D':
4333089Swyllys plc.VAL_CRL_IGNORE_DATE =
4345051Swyllys get_boolean(optarg_av);
4353089Swyllys if (plc.VAL_CRL_IGNORE_DATE == -1) {
4363089Swyllys (void) fprintf(stderr,
4373089Swyllys gettext("Error boolean input.\n"));
4383089Swyllys rv = KC_ERR_USAGE;
4393089Swyllys } else {
4403089Swyllys flags |= KC_CRL_IGNORE_DATE;
4413089Swyllys crl_set_attr++;
4423089Swyllys }
4433089Swyllys break;
4443089Swyllys case 'z':
4453089Swyllys crl_none_opt = get_boolean(optarg_av);
4463089Swyllys if (crl_none_opt == -1) {
4473089Swyllys (void) fprintf(stderr,
4483089Swyllys gettext("Error boolean input.\n"));
4493089Swyllys rv = KC_ERR_USAGE;
4503089Swyllys } else {
4513089Swyllys flags |= KC_CRL_NONE;
4523089Swyllys }
4533089Swyllys break;
4543089Swyllys case 'u':
4553089Swyllys plc.ku_bits = parseKUlist(optarg_av);
4563089Swyllys if (plc.ku_bits == 0) {
4573089Swyllys (void) fprintf(stderr, gettext(
4583089Swyllys "Error keyusage input.\n"));
4593089Swyllys rv = KC_ERR_USAGE;
4603089Swyllys } else {
4613089Swyllys flags |= KC_KEYUSAGE;
4623089Swyllys }
4633089Swyllys break;
4643089Swyllys case 'Y':
4653089Swyllys ku_none_opt = get_boolean(optarg_av);
4663089Swyllys if (ku_none_opt == -1) {
4673089Swyllys (void) fprintf(stderr,
4683089Swyllys gettext("Error boolean input.\n"));
4693089Swyllys rv = KC_ERR_USAGE;
4703089Swyllys } else {
4713089Swyllys flags |= KC_KEYUSAGE_NONE;
4723089Swyllys }
4733089Swyllys break;
4743089Swyllys case 'E':
4753089Swyllys if (parseEKUNames(optarg_av, &plc) != 0) {
4763089Swyllys (void) fprintf(stderr,
4773089Swyllys gettext("Error EKU input.\n"));
4783089Swyllys rv = KC_ERR_USAGE;
4793089Swyllys } else {
4803089Swyllys flags |= KC_EKUS;
4813089Swyllys }
4823089Swyllys break;
4833089Swyllys case 'O':
4843089Swyllys if (parseEKUOIDs(optarg_av, &plc) != 0) {
4853089Swyllys (void) fprintf(stderr,
4863089Swyllys gettext("Error EKU OID input.\n"));
4873089Swyllys rv = KC_ERR_USAGE;
4883089Swyllys } else {
4893089Swyllys flags |= KC_EKUS;
4903089Swyllys }
4913089Swyllys break;
4923089Swyllys case 'Z':
4933089Swyllys eku_none_opt = get_boolean(optarg_av);
4943089Swyllys if (eku_none_opt == -1) {
4953089Swyllys (void) fprintf(stderr,
4963089Swyllys gettext("Error boolean input.\n"));
4973089Swyllys rv = KC_ERR_USAGE;
4983089Swyllys } else {
4993089Swyllys flags |= KC_EKUS_NONE;
5003089Swyllys }
5013089Swyllys break;
50212611SJan.Pechanec@Sun.COM case 'm':
50312611SJan.Pechanec@Sun.COM mapper_name = get_string(optarg_av, &rv);
50412611SJan.Pechanec@Sun.COM if (mapper_name == NULL) {
50512611SJan.Pechanec@Sun.COM (void) fprintf(stderr,
50612611SJan.Pechanec@Sun.COM gettext("Error mapper-name "
50712611SJan.Pechanec@Sun.COM "input.\n"));
50812611SJan.Pechanec@Sun.COM }
50912611SJan.Pechanec@Sun.COM break;
51012611SJan.Pechanec@Sun.COM case 'M':
51112611SJan.Pechanec@Sun.COM mapper_dir = get_string(optarg_av, &rv);
51212611SJan.Pechanec@Sun.COM if (mapper_dir == NULL) {
51312611SJan.Pechanec@Sun.COM (void) fprintf(stderr,
51412611SJan.Pechanec@Sun.COM gettext("Error mapper-directory "
51512611SJan.Pechanec@Sun.COM "input.\n"));
51612611SJan.Pechanec@Sun.COM }
51712611SJan.Pechanec@Sun.COM break;
51812611SJan.Pechanec@Sun.COM case 'Q':
51912611SJan.Pechanec@Sun.COM mapper_pathname = get_string(optarg_av, &rv);
52012611SJan.Pechanec@Sun.COM if (mapper_pathname == NULL) {
52112611SJan.Pechanec@Sun.COM (void) fprintf(stderr,
52212611SJan.Pechanec@Sun.COM gettext("Error mapper-pathname "
52312611SJan.Pechanec@Sun.COM "input.\n"));
52412611SJan.Pechanec@Sun.COM }
52512611SJan.Pechanec@Sun.COM break;
52612611SJan.Pechanec@Sun.COM case 'q':
52712611SJan.Pechanec@Sun.COM plc.mapper.options = get_string(optarg_av, &rv);
52812611SJan.Pechanec@Sun.COM rv = 0; /* its ok for this to be NULL */
52912611SJan.Pechanec@Sun.COM flags |= KC_MAPPER_OPTIONS;
53012611SJan.Pechanec@Sun.COM break;
5313089Swyllys default:
5323089Swyllys (void) fprintf(stderr,
5333089Swyllys gettext("Error input option.\n"));
5343089Swyllys rv = KC_ERR_USAGE;
5353089Swyllys break;
5363089Swyllys }
5373089Swyllys if (rv != KC_OK)
5383089Swyllys goto out;
5393089Swyllys }
5403089Swyllys
5413089Swyllys /* No additional args allowed. */
5423089Swyllys argc -= optind_av;
5433089Swyllys if (argc) {
5443089Swyllys (void) fprintf(stderr,
5453089Swyllys gettext("Error input option\n"));
5463089Swyllys rv = KC_ERR_USAGE;
5473089Swyllys goto out;
5483089Swyllys }
5493089Swyllys
5503089Swyllys if (filename == NULL) {
5513089Swyllys filename = strdup(KMF_DEFAULT_POLICY_FILE);
5523089Swyllys if (filename == NULL) {
5533089Swyllys rv = KC_ERR_MEMORY;
5543089Swyllys goto out;
5553089Swyllys }
5563089Swyllys }
5573089Swyllys
5583089Swyllys /*
5593089Swyllys * Must have a policy name. The policy name can not be default
5603089Swyllys * if using the default policy file.
5613089Swyllys */
5623089Swyllys if (plc.name == NULL) {
5633089Swyllys (void) fprintf(stderr,
5643089Swyllys gettext("You must specify a policy name.\n"));
5653089Swyllys rv = KC_ERR_USAGE;
5663089Swyllys goto out;
5673089Swyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
5683089Swyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
5693089Swyllys (void) fprintf(stderr,
5703089Swyllys gettext("Can not modify the default policy in the default "
5713089Swyllys "policy file.\n"));
5723089Swyllys rv = KC_ERR_USAGE;
5733089Swyllys goto out;
5743089Swyllys }
5753089Swyllys
5763089Swyllys /* Check the access permission of the policy DB */
5773089Swyllys if (access(filename, W_OK) < 0) {
5783089Swyllys int err = errno;
5793089Swyllys (void) fprintf(stderr,
5803089Swyllys gettext("Cannot access \"%s\" for modify - %s\n"),
5813089Swyllys filename, strerror(err));
5823089Swyllys rv = KC_ERR_ACCESS;
5833089Swyllys goto out;
5843089Swyllys }
5853089Swyllys
5863089Swyllys /* Try to load the named policy from the DB */
5875051Swyllys ret = kmf_get_policy(filename, plc.name, &oplc);
5883089Swyllys if (ret != KMF_OK) {
5893089Swyllys (void) fprintf(stderr,
5903089Swyllys gettext("Error loading policy \"%s\" from %s\n"), filename,
5913089Swyllys plc.name);
5923089Swyllys return (KC_ERR_FIND_POLICY);
5933089Swyllys }
5943089Swyllys
5953089Swyllys /* Update the general policy attributes. */
5963089Swyllys if (flags & KC_IGNORE_DATE)
5973089Swyllys oplc.ignore_date = plc.ignore_date;
5983089Swyllys
5993089Swyllys if (flags & KC_IGNORE_UNKNOWN_EKUS)
6003089Swyllys oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus;
6013089Swyllys
6023089Swyllys if (flags & KC_IGNORE_TRUST_ANCHOR)
6033089Swyllys oplc.ignore_trust_anchor = plc.ignore_trust_anchor;
6043089Swyllys
6053089Swyllys if (flags & KC_VALIDITY_ADJUSTTIME) {
6063089Swyllys if (oplc.validity_adjusttime)
6073089Swyllys free(oplc.validity_adjusttime);
6083089Swyllys oplc.validity_adjusttime =
6095051Swyllys plc.validity_adjusttime;
6103089Swyllys }
6113089Swyllys
6123089Swyllys if (flags & KC_TA_NAME) {
6133089Swyllys if (oplc.ta_name)
6143089Swyllys free(oplc.ta_name);
6153089Swyllys oplc.ta_name = plc.ta_name;
6163089Swyllys }
6173089Swyllys if (flags & KC_TA_SERIAL) {
6183089Swyllys if (oplc.ta_serial)
6193089Swyllys free(oplc.ta_serial);
6203089Swyllys oplc.ta_serial = plc.ta_serial;
6213089Swyllys }
6223089Swyllys
62312611SJan.Pechanec@Sun.COM /*
62412611SJan.Pechanec@Sun.COM * There are some combinations of attributes that are not valid.
62512611SJan.Pechanec@Sun.COM *
62612611SJan.Pechanec@Sun.COM * First, setting mapper-name (with optional mapper-directory) and
62712611SJan.Pechanec@Sun.COM * mapper-pathname is mutually exclusive.
62812611SJan.Pechanec@Sun.COM */
62912611SJan.Pechanec@Sun.COM if ((mapper_name != NULL && mapper_pathname != NULL) ||
63012611SJan.Pechanec@Sun.COM (mapper_name != NULL && oplc.mapper.pathname != NULL) ||
63112611SJan.Pechanec@Sun.COM (mapper_pathname != NULL && oplc.mapper.mapname != NULL) ||
63212611SJan.Pechanec@Sun.COM /* Mapper directory can be set only if mapper name is set. */
63312611SJan.Pechanec@Sun.COM (mapper_dir != NULL && mapper_pathname != NULL) ||
63412611SJan.Pechanec@Sun.COM (mapper_dir != NULL && mapper_name == NULL &&
63512611SJan.Pechanec@Sun.COM oplc.mapper.mapname == NULL) ||
63612611SJan.Pechanec@Sun.COM (mapper_dir != NULL && oplc.mapper.pathname != NULL) ||
63712611SJan.Pechanec@Sun.COM /* Options can be set only if mapper name or pathname is set. */
63812611SJan.Pechanec@Sun.COM ((plc.mapper.options != NULL || oplc.mapper.options != NULL) &&
63912611SJan.Pechanec@Sun.COM (mapper_name == NULL && oplc.mapper.mapname == NULL &&
64012611SJan.Pechanec@Sun.COM mapper_pathname == NULL && oplc.mapper.pathname == NULL))) {
64112611SJan.Pechanec@Sun.COM (void) fprintf(stderr,
64212611SJan.Pechanec@Sun.COM gettext("Error in mapper input options\n"));
64312611SJan.Pechanec@Sun.COM if (mapper_name != NULL)
64412611SJan.Pechanec@Sun.COM free(mapper_name);
64512611SJan.Pechanec@Sun.COM if (mapper_pathname != NULL)
64612611SJan.Pechanec@Sun.COM free(mapper_pathname);
64712611SJan.Pechanec@Sun.COM if (mapper_dir != NULL)
64812611SJan.Pechanec@Sun.COM free(mapper_dir);
64912611SJan.Pechanec@Sun.COM if (flags & KC_MAPPER_OPTIONS && plc.mapper.options != NULL)
65012611SJan.Pechanec@Sun.COM free(plc.mapper.options);
65112611SJan.Pechanec@Sun.COM rv = KC_ERR_USAGE;
65212611SJan.Pechanec@Sun.COM goto out;
65312611SJan.Pechanec@Sun.COM } else {
65412611SJan.Pechanec@Sun.COM if (mapper_name != NULL)
65512611SJan.Pechanec@Sun.COM plc.mapper.mapname = mapper_name;
65612611SJan.Pechanec@Sun.COM if (mapper_pathname != NULL)
65712611SJan.Pechanec@Sun.COM plc.mapper.pathname = mapper_pathname;
65812611SJan.Pechanec@Sun.COM if (mapper_dir != NULL)
65912611SJan.Pechanec@Sun.COM plc.mapper.dir = mapper_dir;
66012611SJan.Pechanec@Sun.COM }
66112611SJan.Pechanec@Sun.COM
66212611SJan.Pechanec@Sun.COM UPDATE_IF_DIFFERENT(oplc.mapper.mapname, plc.mapper.mapname);
66312611SJan.Pechanec@Sun.COM UPDATE_IF_DIFFERENT(oplc.mapper.pathname, plc.mapper.pathname);
66412611SJan.Pechanec@Sun.COM UPDATE_IF_DIFFERENT(oplc.mapper.dir, plc.mapper.dir);
66512611SJan.Pechanec@Sun.COM
66612611SJan.Pechanec@Sun.COM if (flags & KC_MAPPER_OPTIONS) {
66712611SJan.Pechanec@Sun.COM if (oplc.mapper.options != NULL)
66812611SJan.Pechanec@Sun.COM free(oplc.mapper.options);
66912611SJan.Pechanec@Sun.COM oplc.mapper.options = plc.mapper.options;
67012611SJan.Pechanec@Sun.COM }
67112611SJan.Pechanec@Sun.COM
6723089Swyllys /* Update the OCSP policy */
6733089Swyllys if (ocsp_none_opt == B_TRUE) {
6743089Swyllys if (ocsp_set_attr > 0) {
6753089Swyllys (void) fprintf(stderr,
6763089Swyllys gettext("Can not set ocsp-none=true and other "
6773089Swyllys "OCSP attributes at the same time.\n"));
6783089Swyllys rv = KC_ERR_USAGE;
6793089Swyllys goto out;
6803089Swyllys }
6813089Swyllys
6823089Swyllys /*
6833089Swyllys * If the original policy does not have OCSP checking,
6843089Swyllys * then we do not need to do anything. If the original
6853089Swyllys * policy has the OCSP checking, then we need to release the
6863089Swyllys * space of OCSP attributes and turn the OCSP checking off.
6873089Swyllys */
6883089Swyllys if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) {
6893089Swyllys if (oplc.VAL_OCSP_BASIC.responderURI) {
6903089Swyllys free(oplc.VAL_OCSP_BASIC.responderURI);
6913089Swyllys oplc.VAL_OCSP_BASIC.responderURI = NULL;
6923089Swyllys }
6933089Swyllys
6943089Swyllys if (oplc.VAL_OCSP_BASIC.proxy) {
6953089Swyllys free(oplc.VAL_OCSP_BASIC.proxy);
6963089Swyllys oplc.VAL_OCSP_BASIC.proxy = NULL;
6973089Swyllys }
6983089Swyllys
6993089Swyllys if (oplc.VAL_OCSP_BASIC.response_lifetime) {
7003089Swyllys free(oplc.VAL_OCSP_BASIC.response_lifetime);
7013089Swyllys oplc.VAL_OCSP_BASIC.response_lifetime = NULL;
7023089Swyllys }
7033089Swyllys
7043089Swyllys if (flags & KC_OCSP_RESP_CERT_NAME) {
7053089Swyllys free(oplc.VAL_OCSP_RESP_CERT.name);
7063089Swyllys oplc.VAL_OCSP_RESP_CERT.name = NULL;
7073089Swyllys }
7083089Swyllys
7093089Swyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) {
7103089Swyllys free(oplc.VAL_OCSP_RESP_CERT.serial);
7113089Swyllys oplc.VAL_OCSP_RESP_CERT.serial = NULL;
7123089Swyllys }
7133089Swyllys
7143089Swyllys /* Turn off the OCSP checking */
7153089Swyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP;
7163089Swyllys }
7173089Swyllys
7183089Swyllys } else {
7193089Swyllys /*
7203089Swyllys * If the "ocsp-none" option is not set or is set to false,
7213089Swyllys * then we only need to do the modification if there is at
7223089Swyllys * least one OCSP attribute is specified.
7233089Swyllys */
7243089Swyllys if (ocsp_set_attr > 0) {
7253089Swyllys if (flags & KC_OCSP_RESPONDER_URI) {
7263089Swyllys if (oplc.VAL_OCSP_RESPONDER_URI)
7273089Swyllys free(oplc.VAL_OCSP_RESPONDER_URI);
7283089Swyllys oplc.VAL_OCSP_RESPONDER_URI =
7295051Swyllys plc.VAL_OCSP_RESPONDER_URI;
7303089Swyllys }
7313089Swyllys
7323089Swyllys if (flags & KC_OCSP_PROXY) {
7333089Swyllys if (oplc.VAL_OCSP_PROXY)
7343089Swyllys free(oplc.VAL_OCSP_PROXY);
7353089Swyllys oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY;
7363089Swyllys }
7373089Swyllys
7383089Swyllys if (flags & KC_OCSP_URI_FROM_CERT)
7393089Swyllys oplc.VAL_OCSP_URI_FROM_CERT =
7405051Swyllys plc.VAL_OCSP_URI_FROM_CERT;
7413089Swyllys
7423089Swyllys if (flags & KC_OCSP_RESP_LIFETIME) {
7433089Swyllys if (oplc.VAL_OCSP_RESP_LIFETIME)
7443089Swyllys free(oplc.VAL_OCSP_RESP_LIFETIME);
7453089Swyllys oplc.VAL_OCSP_RESP_LIFETIME =
7465051Swyllys plc.VAL_OCSP_RESP_LIFETIME;
7473089Swyllys }
7483089Swyllys
7493089Swyllys if (flags & KC_OCSP_IGNORE_RESP_SIGN)
7503089Swyllys oplc.VAL_OCSP_IGNORE_RESP_SIGN =
7515051Swyllys plc.VAL_OCSP_IGNORE_RESP_SIGN;
7523089Swyllys
7533089Swyllys if (flags & KC_OCSP_RESP_CERT_NAME) {
7543089Swyllys if (oplc.VAL_OCSP_RESP_CERT_NAME)
7553089Swyllys free(oplc.VAL_OCSP_RESP_CERT_NAME);
7563089Swyllys oplc.VAL_OCSP_RESP_CERT_NAME =
7575051Swyllys plc.VAL_OCSP_RESP_CERT_NAME;
7583089Swyllys }
7593089Swyllys
7603089Swyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) {
7613089Swyllys if (oplc.VAL_OCSP_RESP_CERT_SERIAL)
7623089Swyllys free(oplc.VAL_OCSP_RESP_CERT_SERIAL);
7633089Swyllys oplc.VAL_OCSP_RESP_CERT_SERIAL =
7645051Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL;
7653089Swyllys }
7663089Swyllys
7673089Swyllys if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL &&
7683089Swyllys oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL)
7693089Swyllys oplc.VAL_OCSP.has_resp_cert = B_TRUE;
7703089Swyllys else
7713089Swyllys oplc.VAL_OCSP.has_resp_cert = B_FALSE;
7723089Swyllys
7733089Swyllys /* Turn on the OCSP checking */
7743089Swyllys oplc.revocation |= KMF_REVOCATION_METHOD_OCSP;
7753089Swyllys }
7763089Swyllys }
7773089Swyllys
7783089Swyllys /* Update the CRL policy */
7793089Swyllys if (crl_none_opt == B_TRUE) {
7803089Swyllys if (crl_set_attr > 0) {
7813089Swyllys (void) fprintf(stderr,
7823089Swyllys gettext("Can not set crl-none=true and other CRL "
7833089Swyllys "attributes at the same time.\n"));
7843089Swyllys rv = KC_ERR_USAGE;
7853089Swyllys goto out;
7863089Swyllys }
7873089Swyllys
7883089Swyllys /*
7893089Swyllys * If the original policy does not have CRL checking,
7903089Swyllys * then we do not need to do anything. If the original
7913089Swyllys * policy has the CRL checking, then we need to release the
7923089Swyllys * space of CRL attributes and turn the CRL checking off.
7933089Swyllys */
7943089Swyllys if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) {
7953089Swyllys if (oplc.VAL_CRL_BASEFILENAME) {
7963089Swyllys free(oplc.VAL_CRL_BASEFILENAME);
7973089Swyllys oplc.VAL_CRL_BASEFILENAME = NULL;
7983089Swyllys }
7993089Swyllys
8003089Swyllys if (oplc.VAL_CRL_DIRECTORY) {
8013089Swyllys free(oplc.VAL_CRL_DIRECTORY);
8023089Swyllys oplc.VAL_CRL_DIRECTORY = NULL;
8033089Swyllys }
8043089Swyllys
8053089Swyllys if (oplc.VAL_CRL_PROXY) {
8063089Swyllys free(oplc.VAL_CRL_PROXY);
8073089Swyllys oplc.VAL_CRL_PROXY = NULL;
8083089Swyllys }
8093089Swyllys
8103089Swyllys /* Turn off the CRL checking */
8113089Swyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL;
8123089Swyllys }
8133089Swyllys } else {
8143089Swyllys /*
8153089Swyllys * If the "ocsp-none" option is not set or is set to false,
8163089Swyllys * then we only need to do the modification if there is at
8173089Swyllys * least one CRL attribute is specified.
8183089Swyllys */
8193089Swyllys if (crl_set_attr > 0) {
8203089Swyllys if (flags & KC_CRL_BASEFILENAME) {
8213089Swyllys if (oplc.VAL_CRL_BASEFILENAME)
8223089Swyllys free(oplc.VAL_CRL_BASEFILENAME);
8233089Swyllys oplc.VAL_CRL_BASEFILENAME =
8243089Swyllys plc.VAL_CRL_BASEFILENAME;
8253089Swyllys }
8263089Swyllys
8273089Swyllys if (flags & KC_CRL_DIRECTORY) {
8283089Swyllys if (oplc.VAL_CRL_DIRECTORY)
8293089Swyllys free(oplc.VAL_CRL_DIRECTORY);
8303089Swyllys oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY;
8313089Swyllys }
8323089Swyllys
8333089Swyllys if (flags & KC_CRL_GET_URI) {
8343089Swyllys oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI;
8353089Swyllys }
8363089Swyllys
8373089Swyllys if (flags & KC_CRL_PROXY) {
8383089Swyllys if (oplc.VAL_CRL_PROXY)
8393089Swyllys free(oplc.VAL_CRL_PROXY);
8403089Swyllys oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY;
8413089Swyllys }
8423089Swyllys
8433089Swyllys if (flags & KC_CRL_IGNORE_SIGN) {
8443089Swyllys oplc.VAL_CRL_IGNORE_SIGN =
8453089Swyllys plc.VAL_CRL_IGNORE_SIGN;
8463089Swyllys }
8473089Swyllys
8483089Swyllys if (flags & KC_CRL_IGNORE_DATE) {
8493089Swyllys oplc.VAL_CRL_IGNORE_DATE =
8503089Swyllys plc.VAL_CRL_IGNORE_DATE;
8513089Swyllys }
8523089Swyllys
8533089Swyllys /* Turn on the CRL checking */
8543089Swyllys oplc.revocation |= KMF_REVOCATION_METHOD_CRL;
8553089Swyllys }
8563089Swyllys }
8573089Swyllys
8583089Swyllys /* Update the Key Usage */
8593089Swyllys if (ku_none_opt == B_TRUE) {
8603089Swyllys if (flags & KC_KEYUSAGE) {
8613089Swyllys (void) fprintf(stderr,
8623089Swyllys gettext("Can not set keyusage-none=true and "
8633089Swyllys "modify the keyusage value at the same time.\n"));
8643089Swyllys rv = KC_ERR_USAGE;
8653089Swyllys goto out;
8663089Swyllys }
8673089Swyllys
8683089Swyllys oplc.ku_bits = 0;
8693089Swyllys } else {
8703089Swyllys /*
8713089Swyllys * If the "keyusage-none" option is not set or is set to
8723089Swyllys * false, then we only need to do the modification if
8733089Swyllys * the keyusage value is specified.
8743089Swyllys */
8753089Swyllys if (flags & KC_KEYUSAGE)
8763089Swyllys oplc.ku_bits = plc.ku_bits;
8773089Swyllys }
8783089Swyllys
8793089Swyllys
8803089Swyllys /* Update the Extended Key Usage */
8813089Swyllys if (eku_none_opt == B_TRUE) {
8823089Swyllys if (flags & KC_EKUS) {
8833089Swyllys (void) fprintf(stderr,
8843089Swyllys gettext("Can not set eku-none=true and modify "
8853089Swyllys "EKU values at the same time.\n"));
8863089Swyllys rv = KC_ERR_USAGE;
8873089Swyllys goto out;
8883089Swyllys }
8893089Swyllys
8903089Swyllys /* Release current EKU list (if any) */
8913089Swyllys if (oplc.eku_set.eku_count > 0) {
8925051Swyllys kmf_free_eku_policy(&oplc.eku_set);
8933089Swyllys oplc.eku_set.eku_count = 0;
8943089Swyllys oplc.eku_set.ekulist = NULL;
8953089Swyllys }
8963089Swyllys } else {
8973089Swyllys /*
8983089Swyllys * If the "eku-none" option is not set or is set to false,
8993089Swyllys * then we only need to do the modification if either
9003089Swyllys * "ekuname" or "ekuoids" is specified.
9013089Swyllys */
9023089Swyllys if (flags & KC_EKUS) {
9033089Swyllys /* Release current EKU list (if any) */
9045051Swyllys kmf_free_eku_policy(&oplc.eku_set);
9053089Swyllys oplc.eku_set = plc.eku_set;
9063089Swyllys }
9073089Swyllys }
9083089Swyllys
9093089Swyllys /* Do a sanity check on the modified policy */
9105051Swyllys ret = kmf_verify_policy(&oplc);
9113089Swyllys if (ret != KMF_OK) {
9123089Swyllys print_sanity_error(ret);
9133089Swyllys rv = KC_ERR_VERIFY_POLICY;
9143089Swyllys goto out;
9153089Swyllys }
9163089Swyllys
9173089Swyllys /* The modify operation is a delete followed by an add */
9185051Swyllys ret = kmf_delete_policy_from_db(oplc.name, filename);
9193089Swyllys if (ret != KMF_OK) {
9203089Swyllys rv = KC_ERR_DELETE_POLICY;
9213089Swyllys goto out;
9223089Swyllys }
9233089Swyllys
9243089Swyllys /*
9253089Swyllys * Now add the modified policy back to the DB.
9263089Swyllys */
9275051Swyllys ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE);
9283089Swyllys if (ret != KMF_OK) {
9293089Swyllys (void) fprintf(stderr,
9303089Swyllys gettext("Error adding policy to database: 0x%04x\n"), ret);
9313089Swyllys rv = KC_ERR_ADD_POLICY;
9323089Swyllys goto out;
9333089Swyllys }
9343089Swyllys
9353089Swyllys out:
9363089Swyllys if (filename != NULL)
9373089Swyllys free(filename);
9383089Swyllys
9395051Swyllys kmf_free_policy_record(&oplc);
9403089Swyllys
9413089Swyllys return (rv);
9423089Swyllys }
9435626Shylee
9445626Shylee static int
kc_modify_plugin(int argc,char * argv[])9455626Shylee kc_modify_plugin(int argc, char *argv[])
9465626Shylee {
9475626Shylee int rv = KC_OK;
9485626Shylee int opt;
9495626Shylee extern int optind_av;
9505626Shylee extern char *optarg_av;
9515626Shylee char *keystore_name = NULL;
9525626Shylee char *option = NULL;
9535626Shylee boolean_t modify_plugin = B_FALSE;
9545626Shylee boolean_t has_option_arg = B_FALSE;
9555626Shylee conf_entry_t *entry = NULL;
9565626Shylee FILE *pfile = NULL;
9575626Shylee FILE *pfile_tmp = NULL;
9585626Shylee char tmpfile_name[MAXPATHLEN];
9595626Shylee char buffer[MAXPATHLEN];
9605626Shylee char buffer2[MAXPATHLEN];
9615626Shylee
9625626Shylee while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)"))
9635626Shylee != EOF) {
9645626Shylee switch (opt) {
9655626Shylee case 'p':
9665626Shylee if (modify_plugin) {
9675626Shylee (void) fprintf(stderr,
9685626Shylee gettext("duplicate plugin input.\n"));
9695626Shylee rv = KC_ERR_USAGE;
9705626Shylee } else {
9715626Shylee modify_plugin = B_TRUE;
9725626Shylee }
9735626Shylee break;
9745626Shylee case 'k':
9755626Shylee if (keystore_name != NULL)
9765626Shylee rv = KC_ERR_USAGE;
9775626Shylee else {
9785626Shylee keystore_name = get_string(optarg_av, &rv);
9795626Shylee if (keystore_name == NULL) {
9805626Shylee (void) fprintf(stderr, gettext(
9815626Shylee "Error keystore input.\n"));
9825626Shylee rv = KC_ERR_USAGE;
9835626Shylee }
9845626Shylee }
9855626Shylee break;
9865626Shylee case 'o':
9875626Shylee if (has_option_arg) {
9885626Shylee (void) fprintf(stderr,
9895626Shylee gettext("duplicate option input.\n"));
9905626Shylee rv = KC_ERR_USAGE;
9915626Shylee } else {
9925626Shylee has_option_arg = B_TRUE;
9935626Shylee option = get_string(optarg_av, NULL);
9945626Shylee }
9955626Shylee break;
9965626Shylee default:
9975626Shylee (void) fprintf(stderr,
9985626Shylee gettext("Error input option.\n"));
9995626Shylee rv = KC_ERR_USAGE;
10005626Shylee break;
10015626Shylee }
10025626Shylee
10035626Shylee if (rv != KC_OK)
10045626Shylee goto out;
10055626Shylee }
10065626Shylee
10075626Shylee /* No additional args allowed. */
10085626Shylee argc -= optind_av;
10095626Shylee if (argc) {
10105626Shylee (void) fprintf(stderr,
10115626Shylee gettext("Error input option\n"));
10125626Shylee rv = KC_ERR_USAGE;
10135626Shylee goto out;
10145626Shylee }
10155626Shylee
10165626Shylee if (keystore_name == NULL || has_option_arg == B_FALSE) {
10175626Shylee (void) fprintf(stderr,
10185626Shylee gettext("Error input option\n"));
10195626Shylee rv = KC_ERR_USAGE;
10205626Shylee goto out;
10215626Shylee }
10225626Shylee
10235626Shylee if (strcasecmp(keystore_name, "nss") == 0 ||
10245626Shylee strcasecmp(keystore_name, "pkcs11") == 0 ||
10255626Shylee strcasecmp(keystore_name, "file") == 0) {
10265626Shylee (void) fprintf(stderr,
10275626Shylee gettext("Can not modify the built-in keystore %s\n"),
10285626Shylee keystore_name);
10295626Shylee rv = KC_ERR_USAGE;
10305626Shylee goto out;
10315626Shylee }
10325626Shylee
10335626Shylee entry = get_keystore_entry(keystore_name);
10345626Shylee if (entry == NULL) {
10355626Shylee (void) fprintf(stderr, gettext("%s does not exist.\n"),
10365626Shylee keystore_name);
10375626Shylee rv = KC_ERR_USAGE;
10385626Shylee goto out;
10395626Shylee }
10405626Shylee
10415626Shylee if ((entry->option == NULL && option == NULL) ||
10425626Shylee (entry->option != NULL && option != NULL &&
10435626Shylee strcmp(entry->option, option) == 0)) {
10445626Shylee (void) fprintf(stderr, gettext("No change - "
10455626Shylee "the new option is same as the old option.\n"));
10465626Shylee rv = KC_OK;
10475626Shylee goto out;
10485626Shylee }
10495626Shylee
10505626Shylee if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) {
10515626Shylee err = errno;
10525626Shylee (void) fprintf(stderr,
10535626Shylee gettext("failed to update the configuration - %s\n"),
10545626Shylee strerror(err));
10555626Shylee rv = KC_ERR_ACCESS;
10565626Shylee goto out;
10575626Shylee }
10585626Shylee
10595626Shylee if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
10605626Shylee err = errno;
10615626Shylee (void) fprintf(stderr,
10625626Shylee gettext("failed to lock the configuration - %s\n"),
10635626Shylee strerror(err));
10645626Shylee rv = KC_ERR_MODIFY_PLUGIN;
10655626Shylee goto out;
10665626Shylee }
10675626Shylee
10685626Shylee /*
10695626Shylee * Create a temporary file in the /etc/crypto directory.
10705626Shylee */
10715626Shylee (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name));
10725626Shylee if (mkstemp(tmpfile_name) == -1) {
10735626Shylee err = errno;
10745626Shylee (void) fprintf(stderr,
10755626Shylee gettext("failed to create a temporary file - %s\n"),
10765626Shylee strerror(err));
10775626Shylee rv = KC_ERR_MODIFY_PLUGIN;
10785626Shylee goto out;
10795626Shylee }
10805626Shylee
10815626Shylee if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
10825626Shylee err = errno;
10835626Shylee (void) fprintf(stderr,
10845626Shylee gettext("failed to open %s - %s\n"),
10855626Shylee tmpfile_name, strerror(err));
10865626Shylee rv = KC_ERR_MODIFY_PLUGIN;
10875626Shylee goto out;
10885626Shylee }
10895626Shylee
10905626Shylee /*
10915626Shylee * Loop thru the config file and update the entry.
10925626Shylee */
10935626Shylee while (fgets(buffer, MAXPATHLEN, pfile) != NULL) {
10945626Shylee char *name;
10955626Shylee int len;
10965626Shylee
10975626Shylee if (buffer[0] == '#') {
10985626Shylee if (fputs(buffer, pfile_tmp) == EOF) {
10995626Shylee rv = KC_ERR_MODIFY_PLUGIN;
11005626Shylee goto out;
11015626Shylee } else {
11025626Shylee continue;
11035626Shylee }
11045626Shylee }
11055626Shylee
11065626Shylee /*
11075626Shylee * make a copy of the original buffer to buffer2. Also get
11085626Shylee * rid of the trailing '\n' from buffer2.
11095626Shylee */
11105626Shylee (void) strlcpy(buffer2, buffer, MAXPATHLEN);
11115626Shylee len = strlen(buffer2);
11125626Shylee if (buffer2[len-1] == '\n') {
11135626Shylee len--;
11145626Shylee }
11155626Shylee buffer2[len] = '\0';
11165626Shylee
11175626Shylee if ((name = strtok(buffer2, SEP_COLON)) == NULL) {
11185626Shylee rv = KC_ERR_UNINSTALL;
11195626Shylee goto out;
11205626Shylee }
11215626Shylee
11225626Shylee if (strcmp(name, keystore_name) == 0) {
11235626Shylee /* found the entry */
11245626Shylee if (option == NULL)
11255626Shylee (void) snprintf(buffer, MAXPATHLEN,
11265626Shylee "%s:%s%s\n", keystore_name,
11275626Shylee CONF_MODULEPATH, entry->modulepath);
11285626Shylee else
11295626Shylee (void) snprintf(buffer, MAXPATHLEN,
11305626Shylee "%s:%s%s;%s%s\n", keystore_name,
11315626Shylee CONF_MODULEPATH, entry->modulepath,
11325626Shylee CONF_OPTION, option);
11335626Shylee
11345626Shylee if (fputs(buffer, pfile_tmp) == EOF) {
11355626Shylee err = errno;
11365626Shylee (void) fprintf(stderr, gettext(
11375626Shylee "failed to write to %s: %s\n"),
11385626Shylee tmpfile_name, strerror(err));
11395626Shylee rv = KC_ERR_MODIFY_PLUGIN;
11405626Shylee goto out;
11415626Shylee }
11425626Shylee } else {
11435626Shylee
11445626Shylee if (fputs(buffer, pfile_tmp) == EOF) {
11455626Shylee rv = KC_ERR_UNINSTALL;
11465626Shylee goto out;
11475626Shylee }
11485626Shylee }
11495626Shylee }
11505626Shylee
11515626Shylee if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) {
11525626Shylee err = errno;
11535626Shylee (void) fprintf(stderr, gettext(
11545626Shylee "failed to update the configuration - %s"), strerror(err));
11555626Shylee rv = KC_ERR_MODIFY_PLUGIN;
11565626Shylee goto out;
11575626Shylee }
11585626Shylee
11595626Shylee if (chmod(_PATH_KMF_CONF,
11605626Shylee S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
11615626Shylee err = errno;
11625626Shylee (void) fprintf(stderr, gettext(
11635626Shylee "failed to update the configuration - %s\n"),
11645626Shylee strerror(err));
11655626Shylee rv = KC_ERR_MODIFY_PLUGIN;
11665626Shylee goto out;
11675626Shylee }
11685626Shylee
11695626Shylee out:
11705626Shylee if (entry != NULL)
11715626Shylee free_entry(entry);
11725626Shylee
11735626Shylee if (pfile != NULL)
11745626Shylee (void) fclose(pfile);
11755626Shylee
11765626Shylee if (rv != KC_OK && pfile_tmp != NULL)
11775626Shylee (void) unlink(tmpfile_name);
11785626Shylee
11795626Shylee if (pfile_tmp != NULL)
11805626Shylee (void) fclose(pfile_tmp);
11815626Shylee
11825626Shylee return (rv);
11835626Shylee }
11845626Shylee
11855626Shylee
11865626Shylee int
kc_modify(int argc,char * argv[])11875626Shylee kc_modify(int argc, char *argv[])
11885626Shylee {
11895626Shylee if (argc > 2 &&
11905626Shylee strcmp(argv[0], "modify") == 0 &&
11915626Shylee strcmp(argv[1], "plugin") == 0) {
11925626Shylee return (kc_modify_plugin(argc, argv));
11935626Shylee } else {
11945626Shylee return (kc_modify_policy(argc, argv));
11955626Shylee }
11965626Shylee }
1197