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 * 21*12611SJan.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 61*12611SJan.Pechanec@Sun.COM #define KC_MAPPER_OPTIONS 0x2000000 623089Swyllys 635626Shylee static int err; /* To store errno which may be overwritten by gettext() */ 645626Shylee 65*12611SJan.Pechanec@Sun.COM #define UPDATE_IF_DIFFERENT(old, new) \ 66*12611SJan.Pechanec@Sun.COM if ((old != NULL && new != NULL && strcmp(old, new) != 0) || \ 67*12611SJan.Pechanec@Sun.COM (old == NULL && new != NULL)) { \ 68*12611SJan.Pechanec@Sun.COM if (old != NULL) \ 69*12611SJan.Pechanec@Sun.COM free(old); \ 70*12611SJan.Pechanec@Sun.COM old = new; \ 71*12611SJan.Pechanec@Sun.COM } 725626Shylee 733089Swyllys int 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; 82*12611SJan.Pechanec@Sun.COM char *mapper_name = NULL; 83*12611SJan.Pechanec@Sun.COM char *mapper_dir = NULL; 84*12611SJan.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)" 125*12611SJan.Pechanec@Sun.COM "m:(mapper-name)" 126*12611SJan.Pechanec@Sun.COM "M:(mapper-directory)" 127*12611SJan.Pechanec@Sun.COM "Q:(mapper-pathname)" 128*12611SJan.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")); 2033089Swyllys } else { 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 } 2163089Swyllys } 2173089Swyllys break; 2183089Swyllys case 's': 2193089Swyllys plc.ta_serial = get_string(optarg_av, &rv); 2203089Swyllys if (plc.ta_serial == NULL) { 2213089Swyllys (void) fprintf(stderr, 2223089Swyllys gettext("Error serial input.\n")); 2233089Swyllys } else { 2243089Swyllys uchar_t *bytes = NULL; 2253089Swyllys size_t bytelen; 2263089Swyllys 2275051Swyllys ret = kmf_hexstr_to_bytes( 2283089Swyllys (uchar_t *)plc.ta_serial, 2293089Swyllys &bytes, &bytelen); 2303089Swyllys if (ret != KMF_OK || bytes == NULL) { 2313089Swyllys (void) fprintf(stderr, 2323089Swyllys gettext("serial number " 2333089Swyllys "must be specified as a " 2343089Swyllys "hex number " 2353089Swyllys "(ex: 0x0102030405" 2363089Swyllys "ffeeddee)\n")); 2373089Swyllys rv = KC_ERR_USAGE; 2383089Swyllys break; 2393089Swyllys } 2403089Swyllys if (bytes != NULL) 2413089Swyllys free(bytes); 2423089Swyllys flags |= KC_TA_SERIAL; 2433089Swyllys } 2443089Swyllys break; 2453089Swyllys case 'o': 2463089Swyllys plc.VAL_OCSP_RESPONDER_URI = 2475051Swyllys get_string(optarg_av, &rv); 2483089Swyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) { 2493089Swyllys (void) fprintf(stderr, 2503089Swyllys gettext("Error responder " 2513089Swyllys "input.\n")); 2523089Swyllys } else { 2533089Swyllys flags |= KC_OCSP_RESPONDER_URI; 2543089Swyllys ocsp_set_attr++; 2553089Swyllys } 2563089Swyllys break; 2573089Swyllys case 'P': 2583089Swyllys plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv); 2593089Swyllys if (plc.VAL_OCSP_PROXY == NULL) { 2603089Swyllys (void) fprintf(stderr, 2613089Swyllys gettext("Error proxy input.\n")); 2623089Swyllys } else { 2633089Swyllys flags |= KC_OCSP_PROXY; 2643089Swyllys ocsp_set_attr++; 2653089Swyllys } 2663089Swyllys break; 2673089Swyllys case 'r': 2683089Swyllys plc.VAL_OCSP_URI_FROM_CERT = 2693089Swyllys get_boolean(optarg_av); 2703089Swyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) { 2713089Swyllys (void) fprintf(stderr, 2723089Swyllys gettext("Error boolean input.\n")); 2733089Swyllys rv = KC_ERR_USAGE; 2743089Swyllys } else { 2753089Swyllys flags |= KC_OCSP_URI_FROM_CERT; 2763089Swyllys ocsp_set_attr++; 2773089Swyllys } 2783089Swyllys break; 2793089Swyllys case 'T': 2803089Swyllys plc.VAL_OCSP_RESP_LIFETIME = 2813089Swyllys get_string(optarg_av, &rv); 2823089Swyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { 2833089Swyllys (void) fprintf(stderr, 2843089Swyllys gettext("Error time input.\n")); 2853089Swyllys } else { 2863089Swyllys uint32_t adj; 2873089Swyllys /* for syntax checking */ 2883089Swyllys if (str2lifetime( 2893089Swyllys plc.VAL_OCSP_RESP_LIFETIME, 2903089Swyllys &adj) < 0) { 2913089Swyllys (void) fprintf(stderr, 2923089Swyllys gettext("Error time " 2933089Swyllys "input.\n")); 2943089Swyllys rv = KC_ERR_USAGE; 2953089Swyllys } else { 2963089Swyllys flags |= KC_OCSP_RESP_LIFETIME; 2973089Swyllys ocsp_set_attr++; 2983089Swyllys } 2993089Swyllys } 3003089Swyllys break; 3013089Swyllys case 'R': 3023089Swyllys plc.VAL_OCSP_IGNORE_RESP_SIGN = 3033089Swyllys get_boolean(optarg_av); 3043089Swyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { 3053089Swyllys (void) fprintf(stderr, 3063089Swyllys gettext("Error boolean input.\n")); 3073089Swyllys rv = KC_ERR_USAGE; 3083089Swyllys } else { 3093089Swyllys flags |= KC_OCSP_IGNORE_RESP_SIGN; 3103089Swyllys ocsp_set_attr++; 3113089Swyllys } 3123089Swyllys break; 3133089Swyllys case 'n': 3143089Swyllys plc.VAL_OCSP_RESP_CERT_NAME = 3153089Swyllys get_string(optarg_av, &rv); 3163089Swyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { 3173089Swyllys (void) fprintf(stderr, 3183089Swyllys gettext("Error name input.\n")); 3193089Swyllys } else { 3203089Swyllys KMF_X509_NAME respDN; 3213089Swyllys /* for syntax checking */ 3225051Swyllys if (kmf_dn_parser( 3233089Swyllys plc.VAL_OCSP_RESP_CERT_NAME, 3243089Swyllys &respDN) != KMF_OK) { 3253089Swyllys (void) fprintf(stderr, 3263089Swyllys gettext("Error name " 3273089Swyllys "input.\n")); 3283089Swyllys rv = KC_ERR_USAGE; 3293089Swyllys } else { 3305051Swyllys kmf_free_dn(&respDN); 3313089Swyllys flags |= KC_OCSP_RESP_CERT_NAME; 3323089Swyllys ocsp_set_attr++; 3333089Swyllys } 3343089Swyllys } 3353089Swyllys break; 3363089Swyllys case 'A': 3373089Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL = 3383089Swyllys get_string(optarg_av, &rv); 3393089Swyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { 3403089Swyllys (void) fprintf(stderr, 3413089Swyllys gettext("Error serial input.\n")); 3423089Swyllys } else { 3433089Swyllys uchar_t *bytes = NULL; 3443089Swyllys size_t bytelen; 3453089Swyllys 3465051Swyllys ret = kmf_hexstr_to_bytes((uchar_t *) 3473089Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL, 3483089Swyllys &bytes, &bytelen); 3493089Swyllys if (ret != KMF_OK || bytes == NULL) { 3503089Swyllys (void) fprintf(stderr, 3513089Swyllys gettext("serial number " 3523089Swyllys "must be specified as a " 3533089Swyllys "hex number " 3543089Swyllys "(ex: 0x0102030405" 3553089Swyllys "ffeeddee)\n")); 3563089Swyllys rv = KC_ERR_USAGE; 3573089Swyllys break; 3583089Swyllys } 3593089Swyllys if (bytes != NULL) 3603089Swyllys free(bytes); 3613089Swyllys flags |= KC_OCSP_RESP_CERT_SERIAL; 3623089Swyllys ocsp_set_attr++; 3633089Swyllys } 3643089Swyllys break; 3653089Swyllys case 'y': 3663089Swyllys ocsp_none_opt = get_boolean(optarg_av); 3673089Swyllys if (ocsp_none_opt == -1) { 3683089Swyllys (void) fprintf(stderr, 3693089Swyllys gettext("Error boolean input.\n")); 3703089Swyllys rv = KC_ERR_USAGE; 3713089Swyllys } else { 3723089Swyllys flags |= KC_OCSP_NONE; 3733089Swyllys } 3743089Swyllys break; 3753089Swyllys case 'c': 3763089Swyllys plc.VAL_CRL_BASEFILENAME = 3773089Swyllys get_string(optarg_av, &rv); 3783089Swyllys if (plc.VAL_CRL_BASEFILENAME == NULL) { 3793089Swyllys (void) fprintf(stderr, gettext( 3803089Swyllys "Error basefilename input.\n")); 3813089Swyllys } else { 3823089Swyllys flags |= KC_CRL_BASEFILENAME; 3833089Swyllys crl_set_attr++; 3843089Swyllys } 3853089Swyllys break; 3863089Swyllys case 'I': 3873089Swyllys plc.VAL_CRL_DIRECTORY = 3883089Swyllys get_string(optarg_av, &rv); 3893089Swyllys if (plc.VAL_CRL_DIRECTORY == NULL) { 3903089Swyllys (void) fprintf(stderr, 3913089Swyllys gettext("Error boolean input.\n")); 3923089Swyllys } else { 3933089Swyllys flags |= KC_CRL_DIRECTORY; 3943089Swyllys crl_set_attr++; 3953089Swyllys } 3963089Swyllys break; 3973089Swyllys case 'g': 3983089Swyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av); 3993089Swyllys if (plc.VAL_CRL_GET_URI == -1) { 4003089Swyllys (void) fprintf(stderr, 4013089Swyllys gettext("Error boolean input.\n")); 4023089Swyllys rv = KC_ERR_USAGE; 4033089Swyllys } else { 4043089Swyllys flags |= KC_CRL_GET_URI; 4053089Swyllys crl_set_attr++; 4063089Swyllys } 4073089Swyllys break; 4083089Swyllys case 'X': 4093089Swyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); 4103089Swyllys if (plc.VAL_CRL_PROXY == NULL) { 4113089Swyllys (void) fprintf(stderr, 4123089Swyllys gettext("Error proxy input.\n")); 4133089Swyllys } else { 4143089Swyllys flags |= KC_CRL_PROXY; 4153089Swyllys crl_set_attr++; 4163089Swyllys } 4173089Swyllys break; 4183089Swyllys case 'S': 4193089Swyllys plc.VAL_CRL_IGNORE_SIGN = 4203089Swyllys get_boolean(optarg_av); 4213089Swyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) { 4223089Swyllys (void) fprintf(stderr, 4233089Swyllys gettext("Error boolean input.\n")); 4243089Swyllys rv = KC_ERR_USAGE; 4253089Swyllys } else { 4263089Swyllys flags |= KC_CRL_IGNORE_SIGN; 4273089Swyllys crl_set_attr++; 4283089Swyllys } 4293089Swyllys break; 4303089Swyllys case 'D': 4313089Swyllys plc.VAL_CRL_IGNORE_DATE = 4325051Swyllys get_boolean(optarg_av); 4333089Swyllys if (plc.VAL_CRL_IGNORE_DATE == -1) { 4343089Swyllys (void) fprintf(stderr, 4353089Swyllys gettext("Error boolean input.\n")); 4363089Swyllys rv = KC_ERR_USAGE; 4373089Swyllys } else { 4383089Swyllys flags |= KC_CRL_IGNORE_DATE; 4393089Swyllys crl_set_attr++; 4403089Swyllys } 4413089Swyllys break; 4423089Swyllys case 'z': 4433089Swyllys crl_none_opt = get_boolean(optarg_av); 4443089Swyllys if (crl_none_opt == -1) { 4453089Swyllys (void) fprintf(stderr, 4463089Swyllys gettext("Error boolean input.\n")); 4473089Swyllys rv = KC_ERR_USAGE; 4483089Swyllys } else { 4493089Swyllys flags |= KC_CRL_NONE; 4503089Swyllys } 4513089Swyllys break; 4523089Swyllys case 'u': 4533089Swyllys plc.ku_bits = parseKUlist(optarg_av); 4543089Swyllys if (plc.ku_bits == 0) { 4553089Swyllys (void) fprintf(stderr, gettext( 4563089Swyllys "Error keyusage input.\n")); 4573089Swyllys rv = KC_ERR_USAGE; 4583089Swyllys } else { 4593089Swyllys flags |= KC_KEYUSAGE; 4603089Swyllys } 4613089Swyllys break; 4623089Swyllys case 'Y': 4633089Swyllys ku_none_opt = get_boolean(optarg_av); 4643089Swyllys if (ku_none_opt == -1) { 4653089Swyllys (void) fprintf(stderr, 4663089Swyllys gettext("Error boolean input.\n")); 4673089Swyllys rv = KC_ERR_USAGE; 4683089Swyllys } else { 4693089Swyllys flags |= KC_KEYUSAGE_NONE; 4703089Swyllys } 4713089Swyllys break; 4723089Swyllys case 'E': 4733089Swyllys if (parseEKUNames(optarg_av, &plc) != 0) { 4743089Swyllys (void) fprintf(stderr, 4753089Swyllys gettext("Error EKU input.\n")); 4763089Swyllys rv = KC_ERR_USAGE; 4773089Swyllys } else { 4783089Swyllys flags |= KC_EKUS; 4793089Swyllys } 4803089Swyllys break; 4813089Swyllys case 'O': 4823089Swyllys if (parseEKUOIDs(optarg_av, &plc) != 0) { 4833089Swyllys (void) fprintf(stderr, 4843089Swyllys gettext("Error EKU OID input.\n")); 4853089Swyllys rv = KC_ERR_USAGE; 4863089Swyllys } else { 4873089Swyllys flags |= KC_EKUS; 4883089Swyllys } 4893089Swyllys break; 4903089Swyllys case 'Z': 4913089Swyllys eku_none_opt = get_boolean(optarg_av); 4923089Swyllys if (eku_none_opt == -1) { 4933089Swyllys (void) fprintf(stderr, 4943089Swyllys gettext("Error boolean input.\n")); 4953089Swyllys rv = KC_ERR_USAGE; 4963089Swyllys } else { 4973089Swyllys flags |= KC_EKUS_NONE; 4983089Swyllys } 4993089Swyllys break; 500*12611SJan.Pechanec@Sun.COM case 'm': 501*12611SJan.Pechanec@Sun.COM mapper_name = get_string(optarg_av, &rv); 502*12611SJan.Pechanec@Sun.COM if (mapper_name == NULL) { 503*12611SJan.Pechanec@Sun.COM (void) fprintf(stderr, 504*12611SJan.Pechanec@Sun.COM gettext("Error mapper-name " 505*12611SJan.Pechanec@Sun.COM "input.\n")); 506*12611SJan.Pechanec@Sun.COM } 507*12611SJan.Pechanec@Sun.COM break; 508*12611SJan.Pechanec@Sun.COM case 'M': 509*12611SJan.Pechanec@Sun.COM mapper_dir = get_string(optarg_av, &rv); 510*12611SJan.Pechanec@Sun.COM if (mapper_dir == NULL) { 511*12611SJan.Pechanec@Sun.COM (void) fprintf(stderr, 512*12611SJan.Pechanec@Sun.COM gettext("Error mapper-directory " 513*12611SJan.Pechanec@Sun.COM "input.\n")); 514*12611SJan.Pechanec@Sun.COM } 515*12611SJan.Pechanec@Sun.COM break; 516*12611SJan.Pechanec@Sun.COM case 'Q': 517*12611SJan.Pechanec@Sun.COM mapper_pathname = get_string(optarg_av, &rv); 518*12611SJan.Pechanec@Sun.COM if (mapper_pathname == NULL) { 519*12611SJan.Pechanec@Sun.COM (void) fprintf(stderr, 520*12611SJan.Pechanec@Sun.COM gettext("Error mapper-pathname " 521*12611SJan.Pechanec@Sun.COM "input.\n")); 522*12611SJan.Pechanec@Sun.COM } 523*12611SJan.Pechanec@Sun.COM break; 524*12611SJan.Pechanec@Sun.COM case 'q': 525*12611SJan.Pechanec@Sun.COM plc.mapper.options = get_string(optarg_av, &rv); 526*12611SJan.Pechanec@Sun.COM rv = 0; /* its ok for this to be NULL */ 527*12611SJan.Pechanec@Sun.COM flags |= KC_MAPPER_OPTIONS; 528*12611SJan.Pechanec@Sun.COM break; 5293089Swyllys default: 5303089Swyllys (void) fprintf(stderr, 5313089Swyllys gettext("Error input option.\n")); 5323089Swyllys rv = KC_ERR_USAGE; 5333089Swyllys break; 5343089Swyllys } 5353089Swyllys if (rv != KC_OK) 5363089Swyllys goto out; 5373089Swyllys } 5383089Swyllys 5393089Swyllys /* No additional args allowed. */ 5403089Swyllys argc -= optind_av; 5413089Swyllys if (argc) { 5423089Swyllys (void) fprintf(stderr, 5433089Swyllys gettext("Error input option\n")); 5443089Swyllys rv = KC_ERR_USAGE; 5453089Swyllys goto out; 5463089Swyllys } 5473089Swyllys 5483089Swyllys if (filename == NULL) { 5493089Swyllys filename = strdup(KMF_DEFAULT_POLICY_FILE); 5503089Swyllys if (filename == NULL) { 5513089Swyllys rv = KC_ERR_MEMORY; 5523089Swyllys goto out; 5533089Swyllys } 5543089Swyllys } 5553089Swyllys 5563089Swyllys /* 5573089Swyllys * Must have a policy name. The policy name can not be default 5583089Swyllys * if using the default policy file. 5593089Swyllys */ 5603089Swyllys if (plc.name == NULL) { 5613089Swyllys (void) fprintf(stderr, 5623089Swyllys gettext("You must specify a policy name.\n")); 5633089Swyllys rv = KC_ERR_USAGE; 5643089Swyllys goto out; 5653089Swyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && 5663089Swyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { 5673089Swyllys (void) fprintf(stderr, 5683089Swyllys gettext("Can not modify the default policy in the default " 5693089Swyllys "policy file.\n")); 5703089Swyllys rv = KC_ERR_USAGE; 5713089Swyllys goto out; 5723089Swyllys } 5733089Swyllys 5743089Swyllys /* Check the access permission of the policy DB */ 5753089Swyllys if (access(filename, W_OK) < 0) { 5763089Swyllys int err = errno; 5773089Swyllys (void) fprintf(stderr, 5783089Swyllys gettext("Cannot access \"%s\" for modify - %s\n"), 5793089Swyllys filename, strerror(err)); 5803089Swyllys rv = KC_ERR_ACCESS; 5813089Swyllys goto out; 5823089Swyllys } 5833089Swyllys 5843089Swyllys /* Try to load the named policy from the DB */ 5855051Swyllys ret = kmf_get_policy(filename, plc.name, &oplc); 5863089Swyllys if (ret != KMF_OK) { 5873089Swyllys (void) fprintf(stderr, 5883089Swyllys gettext("Error loading policy \"%s\" from %s\n"), filename, 5893089Swyllys plc.name); 5903089Swyllys return (KC_ERR_FIND_POLICY); 5913089Swyllys } 5923089Swyllys 5933089Swyllys /* Update the general policy attributes. */ 5943089Swyllys if (flags & KC_IGNORE_DATE) 5953089Swyllys oplc.ignore_date = plc.ignore_date; 5963089Swyllys 5973089Swyllys if (flags & KC_IGNORE_UNKNOWN_EKUS) 5983089Swyllys oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus; 5993089Swyllys 6003089Swyllys if (flags & KC_IGNORE_TRUST_ANCHOR) 6013089Swyllys oplc.ignore_trust_anchor = plc.ignore_trust_anchor; 6023089Swyllys 6033089Swyllys if (flags & KC_VALIDITY_ADJUSTTIME) { 6043089Swyllys if (oplc.validity_adjusttime) 6053089Swyllys free(oplc.validity_adjusttime); 6063089Swyllys oplc.validity_adjusttime = 6075051Swyllys plc.validity_adjusttime; 6083089Swyllys } 6093089Swyllys 6103089Swyllys if (flags & KC_TA_NAME) { 6113089Swyllys if (oplc.ta_name) 6123089Swyllys free(oplc.ta_name); 6133089Swyllys oplc.ta_name = plc.ta_name; 6143089Swyllys } 6153089Swyllys if (flags & KC_TA_SERIAL) { 6163089Swyllys if (oplc.ta_serial) 6173089Swyllys free(oplc.ta_serial); 6183089Swyllys oplc.ta_serial = plc.ta_serial; 6193089Swyllys } 6203089Swyllys 621*12611SJan.Pechanec@Sun.COM /* 622*12611SJan.Pechanec@Sun.COM * There are some combinations of attributes that are not valid. 623*12611SJan.Pechanec@Sun.COM * 624*12611SJan.Pechanec@Sun.COM * First, setting mapper-name (with optional mapper-directory) and 625*12611SJan.Pechanec@Sun.COM * mapper-pathname is mutually exclusive. 626*12611SJan.Pechanec@Sun.COM */ 627*12611SJan.Pechanec@Sun.COM if ((mapper_name != NULL && mapper_pathname != NULL) || 628*12611SJan.Pechanec@Sun.COM (mapper_name != NULL && oplc.mapper.pathname != NULL) || 629*12611SJan.Pechanec@Sun.COM (mapper_pathname != NULL && oplc.mapper.mapname != NULL) || 630*12611SJan.Pechanec@Sun.COM /* Mapper directory can be set only if mapper name is set. */ 631*12611SJan.Pechanec@Sun.COM (mapper_dir != NULL && mapper_pathname != NULL) || 632*12611SJan.Pechanec@Sun.COM (mapper_dir != NULL && mapper_name == NULL && 633*12611SJan.Pechanec@Sun.COM oplc.mapper.mapname == NULL) || 634*12611SJan.Pechanec@Sun.COM (mapper_dir != NULL && oplc.mapper.pathname != NULL) || 635*12611SJan.Pechanec@Sun.COM /* Options can be set only if mapper name or pathname is set. */ 636*12611SJan.Pechanec@Sun.COM ((plc.mapper.options != NULL || oplc.mapper.options != NULL) && 637*12611SJan.Pechanec@Sun.COM (mapper_name == NULL && oplc.mapper.mapname == NULL && 638*12611SJan.Pechanec@Sun.COM mapper_pathname == NULL && oplc.mapper.pathname == NULL))) { 639*12611SJan.Pechanec@Sun.COM (void) fprintf(stderr, 640*12611SJan.Pechanec@Sun.COM gettext("Error in mapper input options\n")); 641*12611SJan.Pechanec@Sun.COM if (mapper_name != NULL) 642*12611SJan.Pechanec@Sun.COM free(mapper_name); 643*12611SJan.Pechanec@Sun.COM if (mapper_pathname != NULL) 644*12611SJan.Pechanec@Sun.COM free(mapper_pathname); 645*12611SJan.Pechanec@Sun.COM if (mapper_dir != NULL) 646*12611SJan.Pechanec@Sun.COM free(mapper_dir); 647*12611SJan.Pechanec@Sun.COM if (flags & KC_MAPPER_OPTIONS && plc.mapper.options != NULL) 648*12611SJan.Pechanec@Sun.COM free(plc.mapper.options); 649*12611SJan.Pechanec@Sun.COM rv = KC_ERR_USAGE; 650*12611SJan.Pechanec@Sun.COM goto out; 651*12611SJan.Pechanec@Sun.COM } else { 652*12611SJan.Pechanec@Sun.COM if (mapper_name != NULL) 653*12611SJan.Pechanec@Sun.COM plc.mapper.mapname = mapper_name; 654*12611SJan.Pechanec@Sun.COM if (mapper_pathname != NULL) 655*12611SJan.Pechanec@Sun.COM plc.mapper.pathname = mapper_pathname; 656*12611SJan.Pechanec@Sun.COM if (mapper_dir != NULL) 657*12611SJan.Pechanec@Sun.COM plc.mapper.dir = mapper_dir; 658*12611SJan.Pechanec@Sun.COM } 659*12611SJan.Pechanec@Sun.COM 660*12611SJan.Pechanec@Sun.COM UPDATE_IF_DIFFERENT(oplc.mapper.mapname, plc.mapper.mapname); 661*12611SJan.Pechanec@Sun.COM UPDATE_IF_DIFFERENT(oplc.mapper.pathname, plc.mapper.pathname); 662*12611SJan.Pechanec@Sun.COM UPDATE_IF_DIFFERENT(oplc.mapper.dir, plc.mapper.dir); 663*12611SJan.Pechanec@Sun.COM 664*12611SJan.Pechanec@Sun.COM if (flags & KC_MAPPER_OPTIONS) { 665*12611SJan.Pechanec@Sun.COM if (oplc.mapper.options != NULL) 666*12611SJan.Pechanec@Sun.COM free(oplc.mapper.options); 667*12611SJan.Pechanec@Sun.COM oplc.mapper.options = plc.mapper.options; 668*12611SJan.Pechanec@Sun.COM } 669*12611SJan.Pechanec@Sun.COM 6703089Swyllys /* Update the OCSP policy */ 6713089Swyllys if (ocsp_none_opt == B_TRUE) { 6723089Swyllys if (ocsp_set_attr > 0) { 6733089Swyllys (void) fprintf(stderr, 6743089Swyllys gettext("Can not set ocsp-none=true and other " 6753089Swyllys "OCSP attributes at the same time.\n")); 6763089Swyllys rv = KC_ERR_USAGE; 6773089Swyllys goto out; 6783089Swyllys } 6793089Swyllys 6803089Swyllys /* 6813089Swyllys * If the original policy does not have OCSP checking, 6823089Swyllys * then we do not need to do anything. If the original 6833089Swyllys * policy has the OCSP checking, then we need to release the 6843089Swyllys * space of OCSP attributes and turn the OCSP checking off. 6853089Swyllys */ 6863089Swyllys if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) { 6873089Swyllys if (oplc.VAL_OCSP_BASIC.responderURI) { 6883089Swyllys free(oplc.VAL_OCSP_BASIC.responderURI); 6893089Swyllys oplc.VAL_OCSP_BASIC.responderURI = NULL; 6903089Swyllys } 6913089Swyllys 6923089Swyllys if (oplc.VAL_OCSP_BASIC.proxy) { 6933089Swyllys free(oplc.VAL_OCSP_BASIC.proxy); 6943089Swyllys oplc.VAL_OCSP_BASIC.proxy = NULL; 6953089Swyllys } 6963089Swyllys 6973089Swyllys if (oplc.VAL_OCSP_BASIC.response_lifetime) { 6983089Swyllys free(oplc.VAL_OCSP_BASIC.response_lifetime); 6993089Swyllys oplc.VAL_OCSP_BASIC.response_lifetime = NULL; 7003089Swyllys } 7013089Swyllys 7023089Swyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 7033089Swyllys free(oplc.VAL_OCSP_RESP_CERT.name); 7043089Swyllys oplc.VAL_OCSP_RESP_CERT.name = NULL; 7053089Swyllys } 7063089Swyllys 7073089Swyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 7083089Swyllys free(oplc.VAL_OCSP_RESP_CERT.serial); 7093089Swyllys oplc.VAL_OCSP_RESP_CERT.serial = NULL; 7103089Swyllys } 7113089Swyllys 7123089Swyllys /* Turn off the OCSP checking */ 7133089Swyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP; 7143089Swyllys } 7153089Swyllys 7163089Swyllys } else { 7173089Swyllys /* 7183089Swyllys * If the "ocsp-none" option is not set or is set to false, 7193089Swyllys * then we only need to do the modification if there is at 7203089Swyllys * least one OCSP attribute is specified. 7213089Swyllys */ 7223089Swyllys if (ocsp_set_attr > 0) { 7233089Swyllys if (flags & KC_OCSP_RESPONDER_URI) { 7243089Swyllys if (oplc.VAL_OCSP_RESPONDER_URI) 7253089Swyllys free(oplc.VAL_OCSP_RESPONDER_URI); 7263089Swyllys oplc.VAL_OCSP_RESPONDER_URI = 7275051Swyllys plc.VAL_OCSP_RESPONDER_URI; 7283089Swyllys } 7293089Swyllys 7303089Swyllys if (flags & KC_OCSP_PROXY) { 7313089Swyllys if (oplc.VAL_OCSP_PROXY) 7323089Swyllys free(oplc.VAL_OCSP_PROXY); 7333089Swyllys oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY; 7343089Swyllys } 7353089Swyllys 7363089Swyllys if (flags & KC_OCSP_URI_FROM_CERT) 7373089Swyllys oplc.VAL_OCSP_URI_FROM_CERT = 7385051Swyllys plc.VAL_OCSP_URI_FROM_CERT; 7393089Swyllys 7403089Swyllys if (flags & KC_OCSP_RESP_LIFETIME) { 7413089Swyllys if (oplc.VAL_OCSP_RESP_LIFETIME) 7423089Swyllys free(oplc.VAL_OCSP_RESP_LIFETIME); 7433089Swyllys oplc.VAL_OCSP_RESP_LIFETIME = 7445051Swyllys plc.VAL_OCSP_RESP_LIFETIME; 7453089Swyllys } 7463089Swyllys 7473089Swyllys if (flags & KC_OCSP_IGNORE_RESP_SIGN) 7483089Swyllys oplc.VAL_OCSP_IGNORE_RESP_SIGN = 7495051Swyllys plc.VAL_OCSP_IGNORE_RESP_SIGN; 7503089Swyllys 7513089Swyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 7523089Swyllys if (oplc.VAL_OCSP_RESP_CERT_NAME) 7533089Swyllys free(oplc.VAL_OCSP_RESP_CERT_NAME); 7543089Swyllys oplc.VAL_OCSP_RESP_CERT_NAME = 7555051Swyllys plc.VAL_OCSP_RESP_CERT_NAME; 7563089Swyllys } 7573089Swyllys 7583089Swyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 7593089Swyllys if (oplc.VAL_OCSP_RESP_CERT_SERIAL) 7603089Swyllys free(oplc.VAL_OCSP_RESP_CERT_SERIAL); 7613089Swyllys oplc.VAL_OCSP_RESP_CERT_SERIAL = 7625051Swyllys plc.VAL_OCSP_RESP_CERT_SERIAL; 7633089Swyllys } 7643089Swyllys 7653089Swyllys if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL && 7663089Swyllys oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL) 7673089Swyllys oplc.VAL_OCSP.has_resp_cert = B_TRUE; 7683089Swyllys else 7693089Swyllys oplc.VAL_OCSP.has_resp_cert = B_FALSE; 7703089Swyllys 7713089Swyllys /* Turn on the OCSP checking */ 7723089Swyllys oplc.revocation |= KMF_REVOCATION_METHOD_OCSP; 7733089Swyllys } 7743089Swyllys } 7753089Swyllys 7763089Swyllys /* Update the CRL policy */ 7773089Swyllys if (crl_none_opt == B_TRUE) { 7783089Swyllys if (crl_set_attr > 0) { 7793089Swyllys (void) fprintf(stderr, 7803089Swyllys gettext("Can not set crl-none=true and other CRL " 7813089Swyllys "attributes at the same time.\n")); 7823089Swyllys rv = KC_ERR_USAGE; 7833089Swyllys goto out; 7843089Swyllys } 7853089Swyllys 7863089Swyllys /* 7873089Swyllys * If the original policy does not have CRL checking, 7883089Swyllys * then we do not need to do anything. If the original 7893089Swyllys * policy has the CRL checking, then we need to release the 7903089Swyllys * space of CRL attributes and turn the CRL checking off. 7913089Swyllys */ 7923089Swyllys if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) { 7933089Swyllys if (oplc.VAL_CRL_BASEFILENAME) { 7943089Swyllys free(oplc.VAL_CRL_BASEFILENAME); 7953089Swyllys oplc.VAL_CRL_BASEFILENAME = NULL; 7963089Swyllys } 7973089Swyllys 7983089Swyllys if (oplc.VAL_CRL_DIRECTORY) { 7993089Swyllys free(oplc.VAL_CRL_DIRECTORY); 8003089Swyllys oplc.VAL_CRL_DIRECTORY = NULL; 8013089Swyllys } 8023089Swyllys 8033089Swyllys if (oplc.VAL_CRL_PROXY) { 8043089Swyllys free(oplc.VAL_CRL_PROXY); 8053089Swyllys oplc.VAL_CRL_PROXY = NULL; 8063089Swyllys } 8073089Swyllys 8083089Swyllys /* Turn off the CRL checking */ 8093089Swyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL; 8103089Swyllys } 8113089Swyllys } else { 8123089Swyllys /* 8133089Swyllys * If the "ocsp-none" option is not set or is set to false, 8143089Swyllys * then we only need to do the modification if there is at 8153089Swyllys * least one CRL attribute is specified. 8163089Swyllys */ 8173089Swyllys if (crl_set_attr > 0) { 8183089Swyllys if (flags & KC_CRL_BASEFILENAME) { 8193089Swyllys if (oplc.VAL_CRL_BASEFILENAME) 8203089Swyllys free(oplc.VAL_CRL_BASEFILENAME); 8213089Swyllys oplc.VAL_CRL_BASEFILENAME = 8223089Swyllys plc.VAL_CRL_BASEFILENAME; 8233089Swyllys } 8243089Swyllys 8253089Swyllys if (flags & KC_CRL_DIRECTORY) { 8263089Swyllys if (oplc.VAL_CRL_DIRECTORY) 8273089Swyllys free(oplc.VAL_CRL_DIRECTORY); 8283089Swyllys oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY; 8293089Swyllys } 8303089Swyllys 8313089Swyllys if (flags & KC_CRL_GET_URI) { 8323089Swyllys oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI; 8333089Swyllys } 8343089Swyllys 8353089Swyllys if (flags & KC_CRL_PROXY) { 8363089Swyllys if (oplc.VAL_CRL_PROXY) 8373089Swyllys free(oplc.VAL_CRL_PROXY); 8383089Swyllys oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY; 8393089Swyllys } 8403089Swyllys 8413089Swyllys if (flags & KC_CRL_IGNORE_SIGN) { 8423089Swyllys oplc.VAL_CRL_IGNORE_SIGN = 8433089Swyllys plc.VAL_CRL_IGNORE_SIGN; 8443089Swyllys } 8453089Swyllys 8463089Swyllys if (flags & KC_CRL_IGNORE_DATE) { 8473089Swyllys oplc.VAL_CRL_IGNORE_DATE = 8483089Swyllys plc.VAL_CRL_IGNORE_DATE; 8493089Swyllys } 8503089Swyllys 8513089Swyllys /* Turn on the CRL checking */ 8523089Swyllys oplc.revocation |= KMF_REVOCATION_METHOD_CRL; 8533089Swyllys } 8543089Swyllys } 8553089Swyllys 8563089Swyllys /* Update the Key Usage */ 8573089Swyllys if (ku_none_opt == B_TRUE) { 8583089Swyllys if (flags & KC_KEYUSAGE) { 8593089Swyllys (void) fprintf(stderr, 8603089Swyllys gettext("Can not set keyusage-none=true and " 8613089Swyllys "modify the keyusage value at the same time.\n")); 8623089Swyllys rv = KC_ERR_USAGE; 8633089Swyllys goto out; 8643089Swyllys } 8653089Swyllys 8663089Swyllys oplc.ku_bits = 0; 8673089Swyllys } else { 8683089Swyllys /* 8693089Swyllys * If the "keyusage-none" option is not set or is set to 8703089Swyllys * false, then we only need to do the modification if 8713089Swyllys * the keyusage value is specified. 8723089Swyllys */ 8733089Swyllys if (flags & KC_KEYUSAGE) 8743089Swyllys oplc.ku_bits = plc.ku_bits; 8753089Swyllys } 8763089Swyllys 8773089Swyllys 8783089Swyllys /* Update the Extended Key Usage */ 8793089Swyllys if (eku_none_opt == B_TRUE) { 8803089Swyllys if (flags & KC_EKUS) { 8813089Swyllys (void) fprintf(stderr, 8823089Swyllys gettext("Can not set eku-none=true and modify " 8833089Swyllys "EKU values at the same time.\n")); 8843089Swyllys rv = KC_ERR_USAGE; 8853089Swyllys goto out; 8863089Swyllys } 8873089Swyllys 8883089Swyllys /* Release current EKU list (if any) */ 8893089Swyllys if (oplc.eku_set.eku_count > 0) { 8905051Swyllys kmf_free_eku_policy(&oplc.eku_set); 8913089Swyllys oplc.eku_set.eku_count = 0; 8923089Swyllys oplc.eku_set.ekulist = NULL; 8933089Swyllys } 8943089Swyllys } else { 8953089Swyllys /* 8963089Swyllys * If the "eku-none" option is not set or is set to false, 8973089Swyllys * then we only need to do the modification if either 8983089Swyllys * "ekuname" or "ekuoids" is specified. 8993089Swyllys */ 9003089Swyllys if (flags & KC_EKUS) { 9013089Swyllys /* Release current EKU list (if any) */ 9025051Swyllys kmf_free_eku_policy(&oplc.eku_set); 9033089Swyllys oplc.eku_set = plc.eku_set; 9043089Swyllys } 9053089Swyllys } 9063089Swyllys 9073089Swyllys /* Do a sanity check on the modified policy */ 9085051Swyllys ret = kmf_verify_policy(&oplc); 9093089Swyllys if (ret != KMF_OK) { 9103089Swyllys print_sanity_error(ret); 9113089Swyllys rv = KC_ERR_VERIFY_POLICY; 9123089Swyllys goto out; 9133089Swyllys } 9143089Swyllys 9153089Swyllys /* The modify operation is a delete followed by an add */ 9165051Swyllys ret = kmf_delete_policy_from_db(oplc.name, filename); 9173089Swyllys if (ret != KMF_OK) { 9183089Swyllys rv = KC_ERR_DELETE_POLICY; 9193089Swyllys goto out; 9203089Swyllys } 9213089Swyllys 9223089Swyllys /* 9233089Swyllys * Now add the modified policy back to the DB. 9243089Swyllys */ 9255051Swyllys ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE); 9263089Swyllys if (ret != KMF_OK) { 9273089Swyllys (void) fprintf(stderr, 9283089Swyllys gettext("Error adding policy to database: 0x%04x\n"), ret); 9293089Swyllys rv = KC_ERR_ADD_POLICY; 9303089Swyllys goto out; 9313089Swyllys } 9323089Swyllys 9333089Swyllys out: 9343089Swyllys if (filename != NULL) 9353089Swyllys free(filename); 9363089Swyllys 9375051Swyllys kmf_free_policy_record(&oplc); 9383089Swyllys 9393089Swyllys return (rv); 9403089Swyllys } 9415626Shylee 9425626Shylee static int 9435626Shylee kc_modify_plugin(int argc, char *argv[]) 9445626Shylee { 9455626Shylee int rv = KC_OK; 9465626Shylee int opt; 9475626Shylee extern int optind_av; 9485626Shylee extern char *optarg_av; 9495626Shylee char *keystore_name = NULL; 9505626Shylee char *option = NULL; 9515626Shylee boolean_t modify_plugin = B_FALSE; 9525626Shylee boolean_t has_option_arg = B_FALSE; 9535626Shylee conf_entry_t *entry = NULL; 9545626Shylee FILE *pfile = NULL; 9555626Shylee FILE *pfile_tmp = NULL; 9565626Shylee char tmpfile_name[MAXPATHLEN]; 9575626Shylee char buffer[MAXPATHLEN]; 9585626Shylee char buffer2[MAXPATHLEN]; 9595626Shylee 9605626Shylee while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)")) 9615626Shylee != EOF) { 9625626Shylee switch (opt) { 9635626Shylee case 'p': 9645626Shylee if (modify_plugin) { 9655626Shylee (void) fprintf(stderr, 9665626Shylee gettext("duplicate plugin input.\n")); 9675626Shylee rv = KC_ERR_USAGE; 9685626Shylee } else { 9695626Shylee modify_plugin = B_TRUE; 9705626Shylee } 9715626Shylee break; 9725626Shylee case 'k': 9735626Shylee if (keystore_name != NULL) 9745626Shylee rv = KC_ERR_USAGE; 9755626Shylee else { 9765626Shylee keystore_name = get_string(optarg_av, &rv); 9775626Shylee if (keystore_name == NULL) { 9785626Shylee (void) fprintf(stderr, gettext( 9795626Shylee "Error keystore input.\n")); 9805626Shylee rv = KC_ERR_USAGE; 9815626Shylee } 9825626Shylee } 9835626Shylee break; 9845626Shylee case 'o': 9855626Shylee if (has_option_arg) { 9865626Shylee (void) fprintf(stderr, 9875626Shylee gettext("duplicate option input.\n")); 9885626Shylee rv = KC_ERR_USAGE; 9895626Shylee } else { 9905626Shylee has_option_arg = B_TRUE; 9915626Shylee option = get_string(optarg_av, NULL); 9925626Shylee } 9935626Shylee break; 9945626Shylee default: 9955626Shylee (void) fprintf(stderr, 9965626Shylee gettext("Error input option.\n")); 9975626Shylee rv = KC_ERR_USAGE; 9985626Shylee break; 9995626Shylee } 10005626Shylee 10015626Shylee if (rv != KC_OK) 10025626Shylee goto out; 10035626Shylee } 10045626Shylee 10055626Shylee /* No additional args allowed. */ 10065626Shylee argc -= optind_av; 10075626Shylee if (argc) { 10085626Shylee (void) fprintf(stderr, 10095626Shylee gettext("Error input option\n")); 10105626Shylee rv = KC_ERR_USAGE; 10115626Shylee goto out; 10125626Shylee } 10135626Shylee 10145626Shylee if (keystore_name == NULL || has_option_arg == B_FALSE) { 10155626Shylee (void) fprintf(stderr, 10165626Shylee gettext("Error input option\n")); 10175626Shylee rv = KC_ERR_USAGE; 10185626Shylee goto out; 10195626Shylee } 10205626Shylee 10215626Shylee if (strcasecmp(keystore_name, "nss") == 0 || 10225626Shylee strcasecmp(keystore_name, "pkcs11") == 0 || 10235626Shylee strcasecmp(keystore_name, "file") == 0) { 10245626Shylee (void) fprintf(stderr, 10255626Shylee gettext("Can not modify the built-in keystore %s\n"), 10265626Shylee keystore_name); 10275626Shylee rv = KC_ERR_USAGE; 10285626Shylee goto out; 10295626Shylee } 10305626Shylee 10315626Shylee entry = get_keystore_entry(keystore_name); 10325626Shylee if (entry == NULL) { 10335626Shylee (void) fprintf(stderr, gettext("%s does not exist.\n"), 10345626Shylee keystore_name); 10355626Shylee rv = KC_ERR_USAGE; 10365626Shylee goto out; 10375626Shylee } 10385626Shylee 10395626Shylee if ((entry->option == NULL && option == NULL) || 10405626Shylee (entry->option != NULL && option != NULL && 10415626Shylee strcmp(entry->option, option) == 0)) { 10425626Shylee (void) fprintf(stderr, gettext("No change - " 10435626Shylee "the new option is same as the old option.\n")); 10445626Shylee rv = KC_OK; 10455626Shylee goto out; 10465626Shylee } 10475626Shylee 10485626Shylee if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) { 10495626Shylee err = errno; 10505626Shylee (void) fprintf(stderr, 10515626Shylee gettext("failed to update the configuration - %s\n"), 10525626Shylee strerror(err)); 10535626Shylee rv = KC_ERR_ACCESS; 10545626Shylee goto out; 10555626Shylee } 10565626Shylee 10575626Shylee if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 10585626Shylee err = errno; 10595626Shylee (void) fprintf(stderr, 10605626Shylee gettext("failed to lock the configuration - %s\n"), 10615626Shylee strerror(err)); 10625626Shylee rv = KC_ERR_MODIFY_PLUGIN; 10635626Shylee goto out; 10645626Shylee } 10655626Shylee 10665626Shylee /* 10675626Shylee * Create a temporary file in the /etc/crypto directory. 10685626Shylee */ 10695626Shylee (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name)); 10705626Shylee if (mkstemp(tmpfile_name) == -1) { 10715626Shylee err = errno; 10725626Shylee (void) fprintf(stderr, 10735626Shylee gettext("failed to create a temporary file - %s\n"), 10745626Shylee strerror(err)); 10755626Shylee rv = KC_ERR_MODIFY_PLUGIN; 10765626Shylee goto out; 10775626Shylee } 10785626Shylee 10795626Shylee if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 10805626Shylee err = errno; 10815626Shylee (void) fprintf(stderr, 10825626Shylee gettext("failed to open %s - %s\n"), 10835626Shylee tmpfile_name, strerror(err)); 10845626Shylee rv = KC_ERR_MODIFY_PLUGIN; 10855626Shylee goto out; 10865626Shylee } 10875626Shylee 10885626Shylee /* 10895626Shylee * Loop thru the config file and update the entry. 10905626Shylee */ 10915626Shylee while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 10925626Shylee char *name; 10935626Shylee int len; 10945626Shylee 10955626Shylee if (buffer[0] == '#') { 10965626Shylee if (fputs(buffer, pfile_tmp) == EOF) { 10975626Shylee rv = KC_ERR_MODIFY_PLUGIN; 10985626Shylee goto out; 10995626Shylee } else { 11005626Shylee continue; 11015626Shylee } 11025626Shylee } 11035626Shylee 11045626Shylee /* 11055626Shylee * make a copy of the original buffer to buffer2. Also get 11065626Shylee * rid of the trailing '\n' from buffer2. 11075626Shylee */ 11085626Shylee (void) strlcpy(buffer2, buffer, MAXPATHLEN); 11095626Shylee len = strlen(buffer2); 11105626Shylee if (buffer2[len-1] == '\n') { 11115626Shylee len--; 11125626Shylee } 11135626Shylee buffer2[len] = '\0'; 11145626Shylee 11155626Shylee if ((name = strtok(buffer2, SEP_COLON)) == NULL) { 11165626Shylee rv = KC_ERR_UNINSTALL; 11175626Shylee goto out; 11185626Shylee } 11195626Shylee 11205626Shylee if (strcmp(name, keystore_name) == 0) { 11215626Shylee /* found the entry */ 11225626Shylee if (option == NULL) 11235626Shylee (void) snprintf(buffer, MAXPATHLEN, 11245626Shylee "%s:%s%s\n", keystore_name, 11255626Shylee CONF_MODULEPATH, entry->modulepath); 11265626Shylee else 11275626Shylee (void) snprintf(buffer, MAXPATHLEN, 11285626Shylee "%s:%s%s;%s%s\n", keystore_name, 11295626Shylee CONF_MODULEPATH, entry->modulepath, 11305626Shylee CONF_OPTION, option); 11315626Shylee 11325626Shylee if (fputs(buffer, pfile_tmp) == EOF) { 11335626Shylee err = errno; 11345626Shylee (void) fprintf(stderr, gettext( 11355626Shylee "failed to write to %s: %s\n"), 11365626Shylee tmpfile_name, strerror(err)); 11375626Shylee rv = KC_ERR_MODIFY_PLUGIN; 11385626Shylee goto out; 11395626Shylee } 11405626Shylee } else { 11415626Shylee 11425626Shylee if (fputs(buffer, pfile_tmp) == EOF) { 11435626Shylee rv = KC_ERR_UNINSTALL; 11445626Shylee goto out; 11455626Shylee } 11465626Shylee } 11475626Shylee } 11485626Shylee 11495626Shylee if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) { 11505626Shylee err = errno; 11515626Shylee (void) fprintf(stderr, gettext( 11525626Shylee "failed to update the configuration - %s"), strerror(err)); 11535626Shylee rv = KC_ERR_MODIFY_PLUGIN; 11545626Shylee goto out; 11555626Shylee } 11565626Shylee 11575626Shylee if (chmod(_PATH_KMF_CONF, 11585626Shylee S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 11595626Shylee err = errno; 11605626Shylee (void) fprintf(stderr, gettext( 11615626Shylee "failed to update the configuration - %s\n"), 11625626Shylee strerror(err)); 11635626Shylee rv = KC_ERR_MODIFY_PLUGIN; 11645626Shylee goto out; 11655626Shylee } 11665626Shylee 11675626Shylee out: 11685626Shylee if (entry != NULL) 11695626Shylee free_entry(entry); 11705626Shylee 11715626Shylee if (pfile != NULL) 11725626Shylee (void) fclose(pfile); 11735626Shylee 11745626Shylee if (rv != KC_OK && pfile_tmp != NULL) 11755626Shylee (void) unlink(tmpfile_name); 11765626Shylee 11775626Shylee if (pfile_tmp != NULL) 11785626Shylee (void) fclose(pfile_tmp); 11795626Shylee 11805626Shylee return (rv); 11815626Shylee } 11825626Shylee 11835626Shylee 11845626Shylee int 11855626Shylee kc_modify(int argc, char *argv[]) 11865626Shylee { 11875626Shylee if (argc > 2 && 11885626Shylee strcmp(argv[0], "modify") == 0 && 11895626Shylee strcmp(argv[1], "plugin") == 0) { 11905626Shylee return (kc_modify_plugin(argc, argv)); 11915626Shylee } else { 11925626Shylee return (kc_modify_policy(argc, argv)); 11935626Shylee } 11945626Shylee } 1195