199ebb4caSwyllys /* 299ebb4caSwyllys * CDDL HEADER START 399ebb4caSwyllys * 499ebb4caSwyllys * The contents of this file are subject to the terms of the 599ebb4caSwyllys * Common Development and Distribution License (the "License"). 699ebb4caSwyllys * You may not use this file except in compliance with the License. 799ebb4caSwyllys * 899ebb4caSwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 999ebb4caSwyllys * or http://www.opensolaris.org/os/licensing. 1099ebb4caSwyllys * See the License for the specific language governing permissions 1199ebb4caSwyllys * and limitations under the License. 1299ebb4caSwyllys * 1399ebb4caSwyllys * When distributing Covered Code, include this CDDL HEADER in each 1499ebb4caSwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1599ebb4caSwyllys * If applicable, add the following below this CDDL HEADER, with the 1699ebb4caSwyllys * fields enclosed by brackets "[]" replaced with your own identifying 1799ebb4caSwyllys * information: Portions Copyright [yyyy] [name of copyright owner] 1899ebb4caSwyllys * 1999ebb4caSwyllys * CDDL HEADER END 2099ebb4caSwyllys * 2130a5e8faSwyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2299ebb4caSwyllys * Use is subject to license terms. 2399ebb4caSwyllys */ 2499ebb4caSwyllys 2599ebb4caSwyllys #pragma ident "%Z%%M% %I% %E% SMI" 2699ebb4caSwyllys 2799ebb4caSwyllys #include <stdio.h> 2899ebb4caSwyllys #include <strings.h> 2999ebb4caSwyllys #include <ctype.h> 3099ebb4caSwyllys #include <libgen.h> 3199ebb4caSwyllys #include <libintl.h> 3299ebb4caSwyllys #include <errno.h> 3399ebb4caSwyllys #include <kmfapiP.h> 3499ebb4caSwyllys #include <cryptoutil.h> 35*431deaa0Shylee #include <sys/stat.h> 36*431deaa0Shylee #include <sys/param.h> 3799ebb4caSwyllys #include "util.h" 3899ebb4caSwyllys 3999ebb4caSwyllys #define KC_IGNORE_DATE 0x0000001 4099ebb4caSwyllys #define KC_IGNORE_UNKNOWN_EKUS 0x0000002 4199ebb4caSwyllys #define KC_IGNORE_TRUST_ANCHOR 0x0000004 4299ebb4caSwyllys #define KC_VALIDITY_ADJUSTTIME 0x0000008 4399ebb4caSwyllys #define KC_TA_NAME 0x0000010 4499ebb4caSwyllys #define KC_TA_SERIAL 0x0000020 4599ebb4caSwyllys #define KC_OCSP_RESPONDER_URI 0x0000040 4699ebb4caSwyllys #define KC_OCSP_PROXY 0x0000080 4799ebb4caSwyllys #define KC_OCSP_URI_FROM_CERT 0x0000100 4899ebb4caSwyllys #define KC_OCSP_RESP_LIFETIME 0x0000200 4999ebb4caSwyllys #define KC_OCSP_IGNORE_RESP_SIGN 0x0000400 5099ebb4caSwyllys #define KC_OCSP_RESP_CERT_NAME 0x0000800 5199ebb4caSwyllys #define KC_OCSP_RESP_CERT_SERIAL 0x0001000 5299ebb4caSwyllys #define KC_OCSP_NONE 0x0002000 5399ebb4caSwyllys #define KC_CRL_BASEFILENAME 0x0004000 5499ebb4caSwyllys #define KC_CRL_DIRECTORY 0x0008000 5599ebb4caSwyllys #define KC_CRL_GET_URI 0x0010000 5699ebb4caSwyllys #define KC_CRL_PROXY 0x0020000 5799ebb4caSwyllys #define KC_CRL_IGNORE_SIGN 0x0040000 5899ebb4caSwyllys #define KC_CRL_IGNORE_DATE 0x0080000 5999ebb4caSwyllys #define KC_CRL_NONE 0x0100000 6099ebb4caSwyllys #define KC_KEYUSAGE 0x0200000 6199ebb4caSwyllys #define KC_KEYUSAGE_NONE 0x0400000 6299ebb4caSwyllys #define KC_EKUS 0x0800000 6399ebb4caSwyllys #define KC_EKUS_NONE 0x1000000 6499ebb4caSwyllys 65*431deaa0Shylee static int err; /* To store errno which may be overwritten by gettext() */ 66*431deaa0Shylee 67*431deaa0Shylee 6899ebb4caSwyllys int 69*431deaa0Shylee kc_modify_policy(int argc, char *argv[]) 7099ebb4caSwyllys { 7199ebb4caSwyllys KMF_RETURN ret; 7299ebb4caSwyllys int rv = KC_OK; 7399ebb4caSwyllys int opt; 7499ebb4caSwyllys extern int optind_av; 7599ebb4caSwyllys extern char *optarg_av; 7699ebb4caSwyllys char *filename = NULL; 7799ebb4caSwyllys uint32_t flags = 0; 7899ebb4caSwyllys boolean_t ocsp_none_opt = B_FALSE; 7999ebb4caSwyllys boolean_t crl_none_opt = B_FALSE; 8099ebb4caSwyllys boolean_t ku_none_opt = B_FALSE; 8199ebb4caSwyllys boolean_t eku_none_opt = B_FALSE; 8299ebb4caSwyllys int ocsp_set_attr = 0; 8399ebb4caSwyllys int crl_set_attr = 0; 8499ebb4caSwyllys KMF_POLICY_RECORD oplc, plc; 8599ebb4caSwyllys 8699ebb4caSwyllys (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); 8799ebb4caSwyllys (void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD)); 8899ebb4caSwyllys 8999ebb4caSwyllys while ((opt = getopt_av(argc, argv, 9099ebb4caSwyllys "i:(dbfile)" 9199ebb4caSwyllys "p:(policy)" 9299ebb4caSwyllys "d:(ignore-date)" 9399ebb4caSwyllys "e:(ignore-unknown-eku)" 9499ebb4caSwyllys "a:(ignore-trust-anchor)" 9599ebb4caSwyllys "v:(validity-adjusttime)" 9699ebb4caSwyllys "t:(ta-name)" 9799ebb4caSwyllys "s:(ta-serial)" 9899ebb4caSwyllys "o:(ocsp-responder)" 9999ebb4caSwyllys "P:(ocsp-proxy)" 10099ebb4caSwyllys "r:(ocsp-use-cert-responder)" 10199ebb4caSwyllys "T:(ocsp-response-lifetime)" 10299ebb4caSwyllys "R:(ocsp-ignore-response-sign)" 10399ebb4caSwyllys "n:(ocsp-responder-cert-name)" 10499ebb4caSwyllys "A:(ocsp-responder-cert-serial)" 10599ebb4caSwyllys "y:(ocsp-none)" 10699ebb4caSwyllys "c:(crl-basefilename)" 10799ebb4caSwyllys "I:(crl-directory)" 10899ebb4caSwyllys "g:(crl-get-crl-uri)" 10999ebb4caSwyllys "X:(crl-proxy)" 11099ebb4caSwyllys "S:(crl-ignore-crl-sign)" 11199ebb4caSwyllys "D:(crl-ignore-crl-date)" 11299ebb4caSwyllys "z:(crl-none)" 11399ebb4caSwyllys "u:(keyusage)" 11499ebb4caSwyllys "Y:(keyusage-none)" 11599ebb4caSwyllys "E:(ekunames)" 11699ebb4caSwyllys "O:(ekuoids)" 11799ebb4caSwyllys "Z:(eku-none)")) != EOF) { 11899ebb4caSwyllys switch (opt) { 11999ebb4caSwyllys case 'i': 12099ebb4caSwyllys filename = get_string(optarg_av, &rv); 12199ebb4caSwyllys if (filename == NULL) { 12299ebb4caSwyllys (void) fprintf(stderr, 12399ebb4caSwyllys gettext("Error dbfile input.\n")); 12499ebb4caSwyllys } 12599ebb4caSwyllys break; 12699ebb4caSwyllys case 'p': 12799ebb4caSwyllys plc.name = get_string(optarg_av, &rv); 12899ebb4caSwyllys if (plc.name == NULL) { 12999ebb4caSwyllys (void) fprintf(stderr, 13099ebb4caSwyllys gettext("Error policy name.\n")); 13199ebb4caSwyllys } 13299ebb4caSwyllys break; 13399ebb4caSwyllys case 'd': 13499ebb4caSwyllys plc.ignore_date = get_boolean(optarg_av); 13599ebb4caSwyllys if (plc.ignore_date == -1) { 13699ebb4caSwyllys (void) fprintf(stderr, 13799ebb4caSwyllys gettext("Error boolean input.\n")); 13899ebb4caSwyllys rv = KC_ERR_USAGE; 13999ebb4caSwyllys } else { 14099ebb4caSwyllys flags |= KC_IGNORE_DATE; 14199ebb4caSwyllys } 14299ebb4caSwyllys break; 14399ebb4caSwyllys case 'e': 14499ebb4caSwyllys plc.ignore_unknown_ekus = 14599ebb4caSwyllys get_boolean(optarg_av); 14699ebb4caSwyllys if (plc.ignore_unknown_ekus == -1) { 14799ebb4caSwyllys (void) fprintf(stderr, 14899ebb4caSwyllys gettext("Error boolean input.\n")); 14999ebb4caSwyllys rv = KC_ERR_USAGE; 15099ebb4caSwyllys } else { 15199ebb4caSwyllys flags |= KC_IGNORE_UNKNOWN_EKUS; 15299ebb4caSwyllys } 15399ebb4caSwyllys break; 15499ebb4caSwyllys case 'a': 15599ebb4caSwyllys plc.ignore_trust_anchor = 15699ebb4caSwyllys get_boolean(optarg_av); 15799ebb4caSwyllys if (plc.ignore_trust_anchor == -1) { 15899ebb4caSwyllys (void) fprintf(stderr, 15999ebb4caSwyllys gettext("Error boolean input.\n")); 16099ebb4caSwyllys rv = KC_ERR_USAGE; 16199ebb4caSwyllys } else { 16299ebb4caSwyllys flags |= KC_IGNORE_TRUST_ANCHOR; 16399ebb4caSwyllys } 16499ebb4caSwyllys break; 16599ebb4caSwyllys case 'v': 16699ebb4caSwyllys plc.validity_adjusttime = 16799ebb4caSwyllys get_string(optarg_av, &rv); 16899ebb4caSwyllys if (plc.validity_adjusttime == NULL) { 16999ebb4caSwyllys (void) fprintf(stderr, 17099ebb4caSwyllys gettext("Error time input.\n")); 17199ebb4caSwyllys } else { 17299ebb4caSwyllys uint32_t adj; 17399ebb4caSwyllys /* for syntax checking */ 17499ebb4caSwyllys if (str2lifetime( 17599ebb4caSwyllys plc.validity_adjusttime, 17699ebb4caSwyllys &adj) < 0) { 17799ebb4caSwyllys (void) fprintf(stderr, 17899ebb4caSwyllys gettext("Error time " 17999ebb4caSwyllys "input.\n")); 18099ebb4caSwyllys rv = KC_ERR_USAGE; 18199ebb4caSwyllys } else { 18299ebb4caSwyllys flags |= KC_VALIDITY_ADJUSTTIME; 18399ebb4caSwyllys } 18499ebb4caSwyllys } 18599ebb4caSwyllys break; 18699ebb4caSwyllys case 't': 18799ebb4caSwyllys plc.ta_name = get_string(optarg_av, &rv); 18899ebb4caSwyllys if (plc.ta_name == NULL) { 18999ebb4caSwyllys (void) fprintf(stderr, 19099ebb4caSwyllys gettext("Error name input.\n")); 19199ebb4caSwyllys } else { 19299ebb4caSwyllys KMF_X509_NAME taDN; 19399ebb4caSwyllys /* for syntax checking */ 19430a5e8faSwyllys if (kmf_dn_parser(plc.ta_name, 19599ebb4caSwyllys &taDN) != KMF_OK) { 19699ebb4caSwyllys (void) fprintf(stderr, 19799ebb4caSwyllys gettext("Error name " 19899ebb4caSwyllys "input.\n")); 19999ebb4caSwyllys rv = KC_ERR_USAGE; 20099ebb4caSwyllys } else { 20130a5e8faSwyllys kmf_free_dn(&taDN); 20299ebb4caSwyllys flags |= KC_TA_NAME; 20399ebb4caSwyllys } 20499ebb4caSwyllys } 20599ebb4caSwyllys break; 20699ebb4caSwyllys case 's': 20799ebb4caSwyllys plc.ta_serial = get_string(optarg_av, &rv); 20899ebb4caSwyllys if (plc.ta_serial == NULL) { 20999ebb4caSwyllys (void) fprintf(stderr, 21099ebb4caSwyllys gettext("Error serial input.\n")); 21199ebb4caSwyllys } else { 21299ebb4caSwyllys uchar_t *bytes = NULL; 21399ebb4caSwyllys size_t bytelen; 21499ebb4caSwyllys 21530a5e8faSwyllys ret = kmf_hexstr_to_bytes( 21699ebb4caSwyllys (uchar_t *)plc.ta_serial, 21799ebb4caSwyllys &bytes, &bytelen); 21899ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 21999ebb4caSwyllys (void) fprintf(stderr, 22099ebb4caSwyllys gettext("serial number " 22199ebb4caSwyllys "must be specified as a " 22299ebb4caSwyllys "hex number " 22399ebb4caSwyllys "(ex: 0x0102030405" 22499ebb4caSwyllys "ffeeddee)\n")); 22599ebb4caSwyllys rv = KC_ERR_USAGE; 22699ebb4caSwyllys break; 22799ebb4caSwyllys } 22899ebb4caSwyllys if (bytes != NULL) 22999ebb4caSwyllys free(bytes); 23099ebb4caSwyllys flags |= KC_TA_SERIAL; 23199ebb4caSwyllys } 23299ebb4caSwyllys break; 23399ebb4caSwyllys case 'o': 23499ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI = 23599ebb4caSwyllys get_string(optarg_av, &rv); 23699ebb4caSwyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) { 23799ebb4caSwyllys (void) fprintf(stderr, 23899ebb4caSwyllys gettext("Error responder " 23999ebb4caSwyllys "input.\n")); 24099ebb4caSwyllys } else { 24199ebb4caSwyllys flags |= KC_OCSP_RESPONDER_URI; 24299ebb4caSwyllys ocsp_set_attr++; 24399ebb4caSwyllys } 24499ebb4caSwyllys break; 24599ebb4caSwyllys case 'P': 24699ebb4caSwyllys plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv); 24799ebb4caSwyllys if (plc.VAL_OCSP_PROXY == NULL) { 24899ebb4caSwyllys (void) fprintf(stderr, 24999ebb4caSwyllys gettext("Error proxy input.\n")); 25099ebb4caSwyllys } else { 25199ebb4caSwyllys flags |= KC_OCSP_PROXY; 25299ebb4caSwyllys ocsp_set_attr++; 25399ebb4caSwyllys } 25499ebb4caSwyllys break; 25599ebb4caSwyllys case 'r': 25699ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT = 25799ebb4caSwyllys get_boolean(optarg_av); 25899ebb4caSwyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) { 25999ebb4caSwyllys (void) fprintf(stderr, 26099ebb4caSwyllys gettext("Error boolean input.\n")); 26199ebb4caSwyllys rv = KC_ERR_USAGE; 26299ebb4caSwyllys } else { 26399ebb4caSwyllys flags |= KC_OCSP_URI_FROM_CERT; 26499ebb4caSwyllys ocsp_set_attr++; 26599ebb4caSwyllys } 26699ebb4caSwyllys break; 26799ebb4caSwyllys case 'T': 26899ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME = 26999ebb4caSwyllys get_string(optarg_av, &rv); 27099ebb4caSwyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { 27199ebb4caSwyllys (void) fprintf(stderr, 27299ebb4caSwyllys gettext("Error time input.\n")); 27399ebb4caSwyllys } else { 27499ebb4caSwyllys uint32_t adj; 27599ebb4caSwyllys /* for syntax checking */ 27699ebb4caSwyllys if (str2lifetime( 27799ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME, 27899ebb4caSwyllys &adj) < 0) { 27999ebb4caSwyllys (void) fprintf(stderr, 28099ebb4caSwyllys gettext("Error time " 28199ebb4caSwyllys "input.\n")); 28299ebb4caSwyllys rv = KC_ERR_USAGE; 28399ebb4caSwyllys } else { 28499ebb4caSwyllys flags |= KC_OCSP_RESP_LIFETIME; 28599ebb4caSwyllys ocsp_set_attr++; 28699ebb4caSwyllys } 28799ebb4caSwyllys } 28899ebb4caSwyllys break; 28999ebb4caSwyllys case 'R': 29099ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN = 29199ebb4caSwyllys get_boolean(optarg_av); 29299ebb4caSwyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { 29399ebb4caSwyllys (void) fprintf(stderr, 29499ebb4caSwyllys gettext("Error boolean input.\n")); 29599ebb4caSwyllys rv = KC_ERR_USAGE; 29699ebb4caSwyllys } else { 29799ebb4caSwyllys flags |= KC_OCSP_IGNORE_RESP_SIGN; 29899ebb4caSwyllys ocsp_set_attr++; 29999ebb4caSwyllys } 30099ebb4caSwyllys break; 30199ebb4caSwyllys case 'n': 30299ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME = 30399ebb4caSwyllys get_string(optarg_av, &rv); 30499ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { 30599ebb4caSwyllys (void) fprintf(stderr, 30699ebb4caSwyllys gettext("Error name input.\n")); 30799ebb4caSwyllys } else { 30899ebb4caSwyllys KMF_X509_NAME respDN; 30999ebb4caSwyllys /* for syntax checking */ 31030a5e8faSwyllys if (kmf_dn_parser( 31199ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME, 31299ebb4caSwyllys &respDN) != KMF_OK) { 31399ebb4caSwyllys (void) fprintf(stderr, 31499ebb4caSwyllys gettext("Error name " 31599ebb4caSwyllys "input.\n")); 31699ebb4caSwyllys rv = KC_ERR_USAGE; 31799ebb4caSwyllys } else { 31830a5e8faSwyllys kmf_free_dn(&respDN); 31999ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_NAME; 32099ebb4caSwyllys ocsp_set_attr++; 32199ebb4caSwyllys } 32299ebb4caSwyllys } 32399ebb4caSwyllys break; 32499ebb4caSwyllys case 'A': 32599ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL = 32699ebb4caSwyllys get_string(optarg_av, &rv); 32799ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { 32899ebb4caSwyllys (void) fprintf(stderr, 32999ebb4caSwyllys gettext("Error serial input.\n")); 33099ebb4caSwyllys } else { 33199ebb4caSwyllys uchar_t *bytes = NULL; 33299ebb4caSwyllys size_t bytelen; 33399ebb4caSwyllys 33430a5e8faSwyllys ret = kmf_hexstr_to_bytes((uchar_t *) 33599ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL, 33699ebb4caSwyllys &bytes, &bytelen); 33799ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 33899ebb4caSwyllys (void) fprintf(stderr, 33999ebb4caSwyllys gettext("serial number " 34099ebb4caSwyllys "must be specified as a " 34199ebb4caSwyllys "hex number " 34299ebb4caSwyllys "(ex: 0x0102030405" 34399ebb4caSwyllys "ffeeddee)\n")); 34499ebb4caSwyllys rv = KC_ERR_USAGE; 34599ebb4caSwyllys break; 34699ebb4caSwyllys } 34799ebb4caSwyllys if (bytes != NULL) 34899ebb4caSwyllys free(bytes); 34999ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_SERIAL; 35099ebb4caSwyllys ocsp_set_attr++; 35199ebb4caSwyllys } 35299ebb4caSwyllys break; 35399ebb4caSwyllys case 'y': 35499ebb4caSwyllys ocsp_none_opt = get_boolean(optarg_av); 35599ebb4caSwyllys if (ocsp_none_opt == -1) { 35699ebb4caSwyllys (void) fprintf(stderr, 35799ebb4caSwyllys gettext("Error boolean input.\n")); 35899ebb4caSwyllys rv = KC_ERR_USAGE; 35999ebb4caSwyllys } else { 36099ebb4caSwyllys flags |= KC_OCSP_NONE; 36199ebb4caSwyllys } 36299ebb4caSwyllys break; 36399ebb4caSwyllys case 'c': 36499ebb4caSwyllys plc.VAL_CRL_BASEFILENAME = 36599ebb4caSwyllys get_string(optarg_av, &rv); 36699ebb4caSwyllys if (plc.VAL_CRL_BASEFILENAME == NULL) { 36799ebb4caSwyllys (void) fprintf(stderr, gettext( 36899ebb4caSwyllys "Error basefilename input.\n")); 36999ebb4caSwyllys } else { 37099ebb4caSwyllys flags |= KC_CRL_BASEFILENAME; 37199ebb4caSwyllys crl_set_attr++; 37299ebb4caSwyllys } 37399ebb4caSwyllys break; 37499ebb4caSwyllys case 'I': 37599ebb4caSwyllys plc.VAL_CRL_DIRECTORY = 37699ebb4caSwyllys get_string(optarg_av, &rv); 37799ebb4caSwyllys if (plc.VAL_CRL_DIRECTORY == NULL) { 37899ebb4caSwyllys (void) fprintf(stderr, 37999ebb4caSwyllys gettext("Error boolean input.\n")); 38099ebb4caSwyllys } else { 38199ebb4caSwyllys flags |= KC_CRL_DIRECTORY; 38299ebb4caSwyllys crl_set_attr++; 38399ebb4caSwyllys } 38499ebb4caSwyllys break; 38599ebb4caSwyllys case 'g': 38699ebb4caSwyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av); 38799ebb4caSwyllys if (plc.VAL_CRL_GET_URI == -1) { 38899ebb4caSwyllys (void) fprintf(stderr, 38999ebb4caSwyllys gettext("Error boolean input.\n")); 39099ebb4caSwyllys rv = KC_ERR_USAGE; 39199ebb4caSwyllys } else { 39299ebb4caSwyllys flags |= KC_CRL_GET_URI; 39399ebb4caSwyllys crl_set_attr++; 39499ebb4caSwyllys } 39599ebb4caSwyllys break; 39699ebb4caSwyllys case 'X': 39799ebb4caSwyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); 39899ebb4caSwyllys if (plc.VAL_CRL_PROXY == NULL) { 39999ebb4caSwyllys (void) fprintf(stderr, 40099ebb4caSwyllys gettext("Error proxy input.\n")); 40199ebb4caSwyllys } else { 40299ebb4caSwyllys flags |= KC_CRL_PROXY; 40399ebb4caSwyllys crl_set_attr++; 40499ebb4caSwyllys } 40599ebb4caSwyllys break; 40699ebb4caSwyllys case 'S': 40799ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN = 40899ebb4caSwyllys get_boolean(optarg_av); 40999ebb4caSwyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) { 41099ebb4caSwyllys (void) fprintf(stderr, 41199ebb4caSwyllys gettext("Error boolean input.\n")); 41299ebb4caSwyllys rv = KC_ERR_USAGE; 41399ebb4caSwyllys } else { 41499ebb4caSwyllys flags |= KC_CRL_IGNORE_SIGN; 41599ebb4caSwyllys crl_set_attr++; 41699ebb4caSwyllys } 41799ebb4caSwyllys break; 41899ebb4caSwyllys case 'D': 41999ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE = 42099ebb4caSwyllys get_boolean(optarg_av); 42199ebb4caSwyllys if (plc.VAL_CRL_IGNORE_DATE == -1) { 42299ebb4caSwyllys (void) fprintf(stderr, 42399ebb4caSwyllys gettext("Error boolean input.\n")); 42499ebb4caSwyllys rv = KC_ERR_USAGE; 42599ebb4caSwyllys } else { 42699ebb4caSwyllys flags |= KC_CRL_IGNORE_DATE; 42799ebb4caSwyllys crl_set_attr++; 42899ebb4caSwyllys } 42999ebb4caSwyllys break; 43099ebb4caSwyllys case 'z': 43199ebb4caSwyllys crl_none_opt = get_boolean(optarg_av); 43299ebb4caSwyllys if (crl_none_opt == -1) { 43399ebb4caSwyllys (void) fprintf(stderr, 43499ebb4caSwyllys gettext("Error boolean input.\n")); 43599ebb4caSwyllys rv = KC_ERR_USAGE; 43699ebb4caSwyllys } else { 43799ebb4caSwyllys flags |= KC_CRL_NONE; 43899ebb4caSwyllys } 43999ebb4caSwyllys break; 44099ebb4caSwyllys case 'u': 44199ebb4caSwyllys plc.ku_bits = parseKUlist(optarg_av); 44299ebb4caSwyllys if (plc.ku_bits == 0) { 44399ebb4caSwyllys (void) fprintf(stderr, gettext( 44499ebb4caSwyllys "Error keyusage input.\n")); 44599ebb4caSwyllys rv = KC_ERR_USAGE; 44699ebb4caSwyllys } else { 44799ebb4caSwyllys flags |= KC_KEYUSAGE; 44899ebb4caSwyllys } 44999ebb4caSwyllys break; 45099ebb4caSwyllys case 'Y': 45199ebb4caSwyllys ku_none_opt = get_boolean(optarg_av); 45299ebb4caSwyllys if (ku_none_opt == -1) { 45399ebb4caSwyllys (void) fprintf(stderr, 45499ebb4caSwyllys gettext("Error boolean input.\n")); 45599ebb4caSwyllys rv = KC_ERR_USAGE; 45699ebb4caSwyllys } else { 45799ebb4caSwyllys flags |= KC_KEYUSAGE_NONE; 45899ebb4caSwyllys } 45999ebb4caSwyllys break; 46099ebb4caSwyllys case 'E': 46199ebb4caSwyllys if (parseEKUNames(optarg_av, &plc) != 0) { 46299ebb4caSwyllys (void) fprintf(stderr, 46399ebb4caSwyllys gettext("Error EKU input.\n")); 46499ebb4caSwyllys rv = KC_ERR_USAGE; 46599ebb4caSwyllys } else { 46699ebb4caSwyllys flags |= KC_EKUS; 46799ebb4caSwyllys } 46899ebb4caSwyllys break; 46999ebb4caSwyllys case 'O': 47099ebb4caSwyllys if (parseEKUOIDs(optarg_av, &plc) != 0) { 47199ebb4caSwyllys (void) fprintf(stderr, 47299ebb4caSwyllys gettext("Error EKU OID input.\n")); 47399ebb4caSwyllys rv = KC_ERR_USAGE; 47499ebb4caSwyllys } else { 47599ebb4caSwyllys flags |= KC_EKUS; 47699ebb4caSwyllys } 47799ebb4caSwyllys break; 47899ebb4caSwyllys case 'Z': 47999ebb4caSwyllys eku_none_opt = get_boolean(optarg_av); 48099ebb4caSwyllys if (eku_none_opt == -1) { 48199ebb4caSwyllys (void) fprintf(stderr, 48299ebb4caSwyllys gettext("Error boolean input.\n")); 48399ebb4caSwyllys rv = KC_ERR_USAGE; 48499ebb4caSwyllys } else { 48599ebb4caSwyllys flags |= KC_EKUS_NONE; 48699ebb4caSwyllys } 48799ebb4caSwyllys break; 48899ebb4caSwyllys default: 48999ebb4caSwyllys (void) fprintf(stderr, 49099ebb4caSwyllys gettext("Error input option.\n")); 49199ebb4caSwyllys rv = KC_ERR_USAGE; 49299ebb4caSwyllys break; 49399ebb4caSwyllys } 49499ebb4caSwyllys if (rv != KC_OK) 49599ebb4caSwyllys goto out; 49699ebb4caSwyllys } 49799ebb4caSwyllys 49899ebb4caSwyllys /* No additional args allowed. */ 49999ebb4caSwyllys argc -= optind_av; 50099ebb4caSwyllys if (argc) { 50199ebb4caSwyllys (void) fprintf(stderr, 50299ebb4caSwyllys gettext("Error input option\n")); 50399ebb4caSwyllys rv = KC_ERR_USAGE; 50499ebb4caSwyllys goto out; 50599ebb4caSwyllys } 50699ebb4caSwyllys 50799ebb4caSwyllys if (filename == NULL) { 50899ebb4caSwyllys filename = strdup(KMF_DEFAULT_POLICY_FILE); 50999ebb4caSwyllys if (filename == NULL) { 51099ebb4caSwyllys rv = KC_ERR_MEMORY; 51199ebb4caSwyllys goto out; 51299ebb4caSwyllys } 51399ebb4caSwyllys } 51499ebb4caSwyllys 51599ebb4caSwyllys /* 51699ebb4caSwyllys * Must have a policy name. The policy name can not be default 51799ebb4caSwyllys * if using the default policy file. 51899ebb4caSwyllys */ 51999ebb4caSwyllys if (plc.name == NULL) { 52099ebb4caSwyllys (void) fprintf(stderr, 52199ebb4caSwyllys gettext("You must specify a policy name.\n")); 52299ebb4caSwyllys rv = KC_ERR_USAGE; 52399ebb4caSwyllys goto out; 52499ebb4caSwyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && 52599ebb4caSwyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { 52699ebb4caSwyllys (void) fprintf(stderr, 52799ebb4caSwyllys gettext("Can not modify the default policy in the default " 52899ebb4caSwyllys "policy file.\n")); 52999ebb4caSwyllys rv = KC_ERR_USAGE; 53099ebb4caSwyllys goto out; 53199ebb4caSwyllys } 53299ebb4caSwyllys 53399ebb4caSwyllys /* Check the access permission of the policy DB */ 53499ebb4caSwyllys if (access(filename, W_OK) < 0) { 53599ebb4caSwyllys int err = errno; 53699ebb4caSwyllys (void) fprintf(stderr, 53799ebb4caSwyllys gettext("Cannot access \"%s\" for modify - %s\n"), 53899ebb4caSwyllys filename, strerror(err)); 53999ebb4caSwyllys rv = KC_ERR_ACCESS; 54099ebb4caSwyllys goto out; 54199ebb4caSwyllys } 54299ebb4caSwyllys 54399ebb4caSwyllys /* Try to load the named policy from the DB */ 54430a5e8faSwyllys ret = kmf_get_policy(filename, plc.name, &oplc); 54599ebb4caSwyllys if (ret != KMF_OK) { 54699ebb4caSwyllys (void) fprintf(stderr, 54799ebb4caSwyllys gettext("Error loading policy \"%s\" from %s\n"), filename, 54899ebb4caSwyllys plc.name); 54999ebb4caSwyllys return (KC_ERR_FIND_POLICY); 55099ebb4caSwyllys } 55199ebb4caSwyllys 55299ebb4caSwyllys /* Update the general policy attributes. */ 55399ebb4caSwyllys if (flags & KC_IGNORE_DATE) 55499ebb4caSwyllys oplc.ignore_date = plc.ignore_date; 55599ebb4caSwyllys 55699ebb4caSwyllys if (flags & KC_IGNORE_UNKNOWN_EKUS) 55799ebb4caSwyllys oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus; 55899ebb4caSwyllys 55999ebb4caSwyllys if (flags & KC_IGNORE_TRUST_ANCHOR) 56099ebb4caSwyllys oplc.ignore_trust_anchor = plc.ignore_trust_anchor; 56199ebb4caSwyllys 56299ebb4caSwyllys if (flags & KC_VALIDITY_ADJUSTTIME) { 56399ebb4caSwyllys if (oplc.validity_adjusttime) 56499ebb4caSwyllys free(oplc.validity_adjusttime); 56599ebb4caSwyllys oplc.validity_adjusttime = 56699ebb4caSwyllys plc.validity_adjusttime; 56799ebb4caSwyllys } 56899ebb4caSwyllys 56999ebb4caSwyllys if (flags & KC_TA_NAME) { 57099ebb4caSwyllys if (oplc.ta_name) 57199ebb4caSwyllys free(oplc.ta_name); 57299ebb4caSwyllys oplc.ta_name = plc.ta_name; 57399ebb4caSwyllys } 57499ebb4caSwyllys if (flags & KC_TA_SERIAL) { 57599ebb4caSwyllys if (oplc.ta_serial) 57699ebb4caSwyllys free(oplc.ta_serial); 57799ebb4caSwyllys oplc.ta_serial = plc.ta_serial; 57899ebb4caSwyllys } 57999ebb4caSwyllys 58099ebb4caSwyllys /* Update the OCSP policy */ 58199ebb4caSwyllys if (ocsp_none_opt == B_TRUE) { 58299ebb4caSwyllys if (ocsp_set_attr > 0) { 58399ebb4caSwyllys (void) fprintf(stderr, 58499ebb4caSwyllys gettext("Can not set ocsp-none=true and other " 58599ebb4caSwyllys "OCSP attributes at the same time.\n")); 58699ebb4caSwyllys rv = KC_ERR_USAGE; 58799ebb4caSwyllys goto out; 58899ebb4caSwyllys } 58999ebb4caSwyllys 59099ebb4caSwyllys /* 59199ebb4caSwyllys * If the original policy does not have OCSP checking, 59299ebb4caSwyllys * then we do not need to do anything. If the original 59399ebb4caSwyllys * policy has the OCSP checking, then we need to release the 59499ebb4caSwyllys * space of OCSP attributes and turn the OCSP checking off. 59599ebb4caSwyllys */ 59699ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) { 59799ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.responderURI) { 59899ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.responderURI); 59999ebb4caSwyllys oplc.VAL_OCSP_BASIC.responderURI = NULL; 60099ebb4caSwyllys } 60199ebb4caSwyllys 60299ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.proxy) { 60399ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.proxy); 60499ebb4caSwyllys oplc.VAL_OCSP_BASIC.proxy = NULL; 60599ebb4caSwyllys } 60699ebb4caSwyllys 60799ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.response_lifetime) { 60899ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.response_lifetime); 60999ebb4caSwyllys oplc.VAL_OCSP_BASIC.response_lifetime = NULL; 61099ebb4caSwyllys } 61199ebb4caSwyllys 61299ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 61399ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.name); 61499ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.name = NULL; 61599ebb4caSwyllys } 61699ebb4caSwyllys 61799ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 61899ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.serial); 61999ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.serial = NULL; 62099ebb4caSwyllys } 62199ebb4caSwyllys 62299ebb4caSwyllys /* Turn off the OCSP checking */ 62399ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP; 62499ebb4caSwyllys } 62599ebb4caSwyllys 62699ebb4caSwyllys } else { 62799ebb4caSwyllys /* 62899ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 62999ebb4caSwyllys * then we only need to do the modification if there is at 63099ebb4caSwyllys * least one OCSP attribute is specified. 63199ebb4caSwyllys */ 63299ebb4caSwyllys if (ocsp_set_attr > 0) { 63399ebb4caSwyllys if (flags & KC_OCSP_RESPONDER_URI) { 63499ebb4caSwyllys if (oplc.VAL_OCSP_RESPONDER_URI) 63599ebb4caSwyllys free(oplc.VAL_OCSP_RESPONDER_URI); 63699ebb4caSwyllys oplc.VAL_OCSP_RESPONDER_URI = 63799ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI; 63899ebb4caSwyllys } 63999ebb4caSwyllys 64099ebb4caSwyllys if (flags & KC_OCSP_PROXY) { 64199ebb4caSwyllys if (oplc.VAL_OCSP_PROXY) 64299ebb4caSwyllys free(oplc.VAL_OCSP_PROXY); 64399ebb4caSwyllys oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY; 64499ebb4caSwyllys } 64599ebb4caSwyllys 64699ebb4caSwyllys if (flags & KC_OCSP_URI_FROM_CERT) 64799ebb4caSwyllys oplc.VAL_OCSP_URI_FROM_CERT = 64899ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT; 64999ebb4caSwyllys 65099ebb4caSwyllys if (flags & KC_OCSP_RESP_LIFETIME) { 65199ebb4caSwyllys if (oplc.VAL_OCSP_RESP_LIFETIME) 65299ebb4caSwyllys free(oplc.VAL_OCSP_RESP_LIFETIME); 65399ebb4caSwyllys oplc.VAL_OCSP_RESP_LIFETIME = 65499ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME; 65599ebb4caSwyllys } 65699ebb4caSwyllys 65799ebb4caSwyllys if (flags & KC_OCSP_IGNORE_RESP_SIGN) 65899ebb4caSwyllys oplc.VAL_OCSP_IGNORE_RESP_SIGN = 65999ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN; 66099ebb4caSwyllys 66199ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 66299ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME) 66399ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_NAME); 66499ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_NAME = 66599ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME; 66699ebb4caSwyllys } 66799ebb4caSwyllys 66899ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 66999ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_SERIAL) 67099ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_SERIAL); 67199ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL = 67299ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL; 67399ebb4caSwyllys } 67499ebb4caSwyllys 67599ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL && 67699ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL) 67799ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_TRUE; 67899ebb4caSwyllys else 67999ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_FALSE; 68099ebb4caSwyllys 68199ebb4caSwyllys /* Turn on the OCSP checking */ 68299ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_OCSP; 68399ebb4caSwyllys } 68499ebb4caSwyllys } 68599ebb4caSwyllys 68699ebb4caSwyllys /* Update the CRL policy */ 68799ebb4caSwyllys if (crl_none_opt == B_TRUE) { 68899ebb4caSwyllys if (crl_set_attr > 0) { 68999ebb4caSwyllys (void) fprintf(stderr, 69099ebb4caSwyllys gettext("Can not set crl-none=true and other CRL " 69199ebb4caSwyllys "attributes at the same time.\n")); 69299ebb4caSwyllys rv = KC_ERR_USAGE; 69399ebb4caSwyllys goto out; 69499ebb4caSwyllys } 69599ebb4caSwyllys 69699ebb4caSwyllys /* 69799ebb4caSwyllys * If the original policy does not have CRL checking, 69899ebb4caSwyllys * then we do not need to do anything. If the original 69999ebb4caSwyllys * policy has the CRL checking, then we need to release the 70099ebb4caSwyllys * space of CRL attributes and turn the CRL checking off. 70199ebb4caSwyllys */ 70299ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) { 70399ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) { 70499ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 70599ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = NULL; 70699ebb4caSwyllys } 70799ebb4caSwyllys 70899ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) { 70999ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 71099ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = NULL; 71199ebb4caSwyllys } 71299ebb4caSwyllys 71399ebb4caSwyllys if (oplc.VAL_CRL_PROXY) { 71499ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 71599ebb4caSwyllys oplc.VAL_CRL_PROXY = NULL; 71699ebb4caSwyllys } 71799ebb4caSwyllys 71899ebb4caSwyllys /* Turn off the CRL checking */ 71999ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL; 72099ebb4caSwyllys } 72199ebb4caSwyllys } else { 72299ebb4caSwyllys /* 72399ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 72499ebb4caSwyllys * then we only need to do the modification if there is at 72599ebb4caSwyllys * least one CRL attribute is specified. 72699ebb4caSwyllys */ 72799ebb4caSwyllys if (crl_set_attr > 0) { 72899ebb4caSwyllys if (flags & KC_CRL_BASEFILENAME) { 72999ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) 73099ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 73199ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = 73299ebb4caSwyllys plc.VAL_CRL_BASEFILENAME; 73399ebb4caSwyllys } 73499ebb4caSwyllys 73599ebb4caSwyllys if (flags & KC_CRL_DIRECTORY) { 73699ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) 73799ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 73899ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY; 73999ebb4caSwyllys } 74099ebb4caSwyllys 74199ebb4caSwyllys if (flags & KC_CRL_GET_URI) { 74299ebb4caSwyllys oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI; 74399ebb4caSwyllys } 74499ebb4caSwyllys 74599ebb4caSwyllys if (flags & KC_CRL_PROXY) { 74699ebb4caSwyllys if (oplc.VAL_CRL_PROXY) 74799ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 74899ebb4caSwyllys oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY; 74999ebb4caSwyllys } 75099ebb4caSwyllys 75199ebb4caSwyllys if (flags & KC_CRL_IGNORE_SIGN) { 75299ebb4caSwyllys oplc.VAL_CRL_IGNORE_SIGN = 75399ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN; 75499ebb4caSwyllys } 75599ebb4caSwyllys 75699ebb4caSwyllys if (flags & KC_CRL_IGNORE_DATE) { 75799ebb4caSwyllys oplc.VAL_CRL_IGNORE_DATE = 75899ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE; 75999ebb4caSwyllys } 76099ebb4caSwyllys 76199ebb4caSwyllys /* Turn on the CRL checking */ 76299ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_CRL; 76399ebb4caSwyllys } 76499ebb4caSwyllys } 76599ebb4caSwyllys 76699ebb4caSwyllys /* Update the Key Usage */ 76799ebb4caSwyllys if (ku_none_opt == B_TRUE) { 76899ebb4caSwyllys if (flags & KC_KEYUSAGE) { 76999ebb4caSwyllys (void) fprintf(stderr, 77099ebb4caSwyllys gettext("Can not set keyusage-none=true and " 77199ebb4caSwyllys "modify the keyusage value at the same time.\n")); 77299ebb4caSwyllys rv = KC_ERR_USAGE; 77399ebb4caSwyllys goto out; 77499ebb4caSwyllys } 77599ebb4caSwyllys 77699ebb4caSwyllys oplc.ku_bits = 0; 77799ebb4caSwyllys } else { 77899ebb4caSwyllys /* 77999ebb4caSwyllys * If the "keyusage-none" option is not set or is set to 78099ebb4caSwyllys * false, then we only need to do the modification if 78199ebb4caSwyllys * the keyusage value is specified. 78299ebb4caSwyllys */ 78399ebb4caSwyllys if (flags & KC_KEYUSAGE) 78499ebb4caSwyllys oplc.ku_bits = plc.ku_bits; 78599ebb4caSwyllys } 78699ebb4caSwyllys 78799ebb4caSwyllys 78899ebb4caSwyllys /* Update the Extended Key Usage */ 78999ebb4caSwyllys if (eku_none_opt == B_TRUE) { 79099ebb4caSwyllys if (flags & KC_EKUS) { 79199ebb4caSwyllys (void) fprintf(stderr, 79299ebb4caSwyllys gettext("Can not set eku-none=true and modify " 79399ebb4caSwyllys "EKU values at the same time.\n")); 79499ebb4caSwyllys rv = KC_ERR_USAGE; 79599ebb4caSwyllys goto out; 79699ebb4caSwyllys } 79799ebb4caSwyllys 79899ebb4caSwyllys /* Release current EKU list (if any) */ 79999ebb4caSwyllys if (oplc.eku_set.eku_count > 0) { 80030a5e8faSwyllys kmf_free_eku_policy(&oplc.eku_set); 80199ebb4caSwyllys oplc.eku_set.eku_count = 0; 80299ebb4caSwyllys oplc.eku_set.ekulist = NULL; 80399ebb4caSwyllys } 80499ebb4caSwyllys } else { 80599ebb4caSwyllys /* 80699ebb4caSwyllys * If the "eku-none" option is not set or is set to false, 80799ebb4caSwyllys * then we only need to do the modification if either 80899ebb4caSwyllys * "ekuname" or "ekuoids" is specified. 80999ebb4caSwyllys */ 81099ebb4caSwyllys if (flags & KC_EKUS) { 81199ebb4caSwyllys /* Release current EKU list (if any) */ 81230a5e8faSwyllys kmf_free_eku_policy(&oplc.eku_set); 81399ebb4caSwyllys oplc.eku_set = plc.eku_set; 81499ebb4caSwyllys } 81599ebb4caSwyllys } 81699ebb4caSwyllys 81799ebb4caSwyllys /* Do a sanity check on the modified policy */ 81830a5e8faSwyllys ret = kmf_verify_policy(&oplc); 81999ebb4caSwyllys if (ret != KMF_OK) { 82099ebb4caSwyllys print_sanity_error(ret); 82199ebb4caSwyllys rv = KC_ERR_VERIFY_POLICY; 82299ebb4caSwyllys goto out; 82399ebb4caSwyllys } 82499ebb4caSwyllys 82599ebb4caSwyllys /* The modify operation is a delete followed by an add */ 82630a5e8faSwyllys ret = kmf_delete_policy_from_db(oplc.name, filename); 82799ebb4caSwyllys if (ret != KMF_OK) { 82899ebb4caSwyllys rv = KC_ERR_DELETE_POLICY; 82999ebb4caSwyllys goto out; 83099ebb4caSwyllys } 83199ebb4caSwyllys 83299ebb4caSwyllys /* 83399ebb4caSwyllys * Now add the modified policy back to the DB. 83499ebb4caSwyllys */ 83530a5e8faSwyllys ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE); 83699ebb4caSwyllys if (ret != KMF_OK) { 83799ebb4caSwyllys (void) fprintf(stderr, 83899ebb4caSwyllys gettext("Error adding policy to database: 0x%04x\n"), ret); 83999ebb4caSwyllys rv = KC_ERR_ADD_POLICY; 84099ebb4caSwyllys goto out; 84199ebb4caSwyllys } 84299ebb4caSwyllys 84399ebb4caSwyllys out: 84499ebb4caSwyllys if (filename != NULL) 84599ebb4caSwyllys free(filename); 84699ebb4caSwyllys 84730a5e8faSwyllys kmf_free_policy_record(&oplc); 84899ebb4caSwyllys 84999ebb4caSwyllys return (rv); 85099ebb4caSwyllys } 851*431deaa0Shylee 852*431deaa0Shylee 853*431deaa0Shylee static int 854*431deaa0Shylee kc_modify_plugin(int argc, char *argv[]) 855*431deaa0Shylee { 856*431deaa0Shylee int rv = KC_OK; 857*431deaa0Shylee int opt; 858*431deaa0Shylee extern int optind_av; 859*431deaa0Shylee extern char *optarg_av; 860*431deaa0Shylee char *keystore_name = NULL; 861*431deaa0Shylee char *option = NULL; 862*431deaa0Shylee boolean_t modify_plugin = B_FALSE; 863*431deaa0Shylee boolean_t has_option_arg = B_FALSE; 864*431deaa0Shylee conf_entry_t *entry = NULL; 865*431deaa0Shylee FILE *pfile = NULL; 866*431deaa0Shylee FILE *pfile_tmp = NULL; 867*431deaa0Shylee char tmpfile_name[MAXPATHLEN]; 868*431deaa0Shylee char buffer[MAXPATHLEN]; 869*431deaa0Shylee char buffer2[MAXPATHLEN]; 870*431deaa0Shylee 871*431deaa0Shylee while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)")) 872*431deaa0Shylee != EOF) { 873*431deaa0Shylee switch (opt) { 874*431deaa0Shylee case 'p': 875*431deaa0Shylee if (modify_plugin) { 876*431deaa0Shylee (void) fprintf(stderr, 877*431deaa0Shylee gettext("duplicate plugin input.\n")); 878*431deaa0Shylee rv = KC_ERR_USAGE; 879*431deaa0Shylee } else { 880*431deaa0Shylee modify_plugin = B_TRUE; 881*431deaa0Shylee } 882*431deaa0Shylee break; 883*431deaa0Shylee case 'k': 884*431deaa0Shylee if (keystore_name != NULL) 885*431deaa0Shylee rv = KC_ERR_USAGE; 886*431deaa0Shylee else { 887*431deaa0Shylee keystore_name = get_string(optarg_av, &rv); 888*431deaa0Shylee if (keystore_name == NULL) { 889*431deaa0Shylee (void) fprintf(stderr, gettext( 890*431deaa0Shylee "Error keystore input.\n")); 891*431deaa0Shylee rv = KC_ERR_USAGE; 892*431deaa0Shylee } 893*431deaa0Shylee } 894*431deaa0Shylee break; 895*431deaa0Shylee case 'o': 896*431deaa0Shylee if (has_option_arg) { 897*431deaa0Shylee (void) fprintf(stderr, 898*431deaa0Shylee gettext("duplicate option input.\n")); 899*431deaa0Shylee rv = KC_ERR_USAGE; 900*431deaa0Shylee } else { 901*431deaa0Shylee has_option_arg = B_TRUE; 902*431deaa0Shylee option = get_string(optarg_av, NULL); 903*431deaa0Shylee } 904*431deaa0Shylee break; 905*431deaa0Shylee default: 906*431deaa0Shylee (void) fprintf(stderr, 907*431deaa0Shylee gettext("Error input option.\n")); 908*431deaa0Shylee rv = KC_ERR_USAGE; 909*431deaa0Shylee break; 910*431deaa0Shylee } 911*431deaa0Shylee 912*431deaa0Shylee if (rv != KC_OK) 913*431deaa0Shylee goto out; 914*431deaa0Shylee } 915*431deaa0Shylee 916*431deaa0Shylee /* No additional args allowed. */ 917*431deaa0Shylee argc -= optind_av; 918*431deaa0Shylee if (argc) { 919*431deaa0Shylee (void) fprintf(stderr, 920*431deaa0Shylee gettext("Error input option\n")); 921*431deaa0Shylee rv = KC_ERR_USAGE; 922*431deaa0Shylee goto out; 923*431deaa0Shylee } 924*431deaa0Shylee 925*431deaa0Shylee if (keystore_name == NULL || has_option_arg == B_FALSE) { 926*431deaa0Shylee (void) fprintf(stderr, 927*431deaa0Shylee gettext("Error input option\n")); 928*431deaa0Shylee rv = KC_ERR_USAGE; 929*431deaa0Shylee goto out; 930*431deaa0Shylee } 931*431deaa0Shylee 932*431deaa0Shylee if (strcasecmp(keystore_name, "nss") == 0 || 933*431deaa0Shylee strcasecmp(keystore_name, "pkcs11") == 0 || 934*431deaa0Shylee strcasecmp(keystore_name, "file") == 0) { 935*431deaa0Shylee (void) fprintf(stderr, 936*431deaa0Shylee gettext("Can not modify the built-in keystore %s\n"), 937*431deaa0Shylee keystore_name); 938*431deaa0Shylee rv = KC_ERR_USAGE; 939*431deaa0Shylee goto out; 940*431deaa0Shylee } 941*431deaa0Shylee 942*431deaa0Shylee entry = get_keystore_entry(keystore_name); 943*431deaa0Shylee if (entry == NULL) { 944*431deaa0Shylee (void) fprintf(stderr, gettext("%s does not exist.\n"), 945*431deaa0Shylee keystore_name); 946*431deaa0Shylee rv = KC_ERR_USAGE; 947*431deaa0Shylee goto out; 948*431deaa0Shylee } 949*431deaa0Shylee 950*431deaa0Shylee if ((entry->option == NULL && option == NULL) || 951*431deaa0Shylee (entry->option != NULL && option != NULL && 952*431deaa0Shylee strcmp(entry->option, option) == 0)) { 953*431deaa0Shylee (void) fprintf(stderr, gettext("No change - " 954*431deaa0Shylee "the new option is same as the old option.\n")); 955*431deaa0Shylee rv = KC_OK; 956*431deaa0Shylee goto out; 957*431deaa0Shylee } 958*431deaa0Shylee 959*431deaa0Shylee if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) { 960*431deaa0Shylee err = errno; 961*431deaa0Shylee (void) fprintf(stderr, 962*431deaa0Shylee gettext("failed to update the configuration - %s\n"), 963*431deaa0Shylee strerror(err)); 964*431deaa0Shylee rv = KC_ERR_ACCESS; 965*431deaa0Shylee goto out; 966*431deaa0Shylee } 967*431deaa0Shylee 968*431deaa0Shylee if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 969*431deaa0Shylee err = errno; 970*431deaa0Shylee (void) fprintf(stderr, 971*431deaa0Shylee gettext("failed to lock the configuration - %s\n"), 972*431deaa0Shylee strerror(err)); 973*431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 974*431deaa0Shylee goto out; 975*431deaa0Shylee } 976*431deaa0Shylee 977*431deaa0Shylee /* 978*431deaa0Shylee * Create a temporary file in the /etc/crypto directory. 979*431deaa0Shylee */ 980*431deaa0Shylee (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name)); 981*431deaa0Shylee if (mkstemp(tmpfile_name) == -1) { 982*431deaa0Shylee err = errno; 983*431deaa0Shylee (void) fprintf(stderr, 984*431deaa0Shylee gettext("failed to create a temporary file - %s\n"), 985*431deaa0Shylee strerror(err)); 986*431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 987*431deaa0Shylee goto out; 988*431deaa0Shylee } 989*431deaa0Shylee 990*431deaa0Shylee if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 991*431deaa0Shylee err = errno; 992*431deaa0Shylee (void) fprintf(stderr, 993*431deaa0Shylee gettext("failed to open %s - %s\n"), 994*431deaa0Shylee tmpfile_name, strerror(err)); 995*431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 996*431deaa0Shylee goto out; 997*431deaa0Shylee } 998*431deaa0Shylee 999*431deaa0Shylee /* 1000*431deaa0Shylee * Loop thru the config file and update the entry. 1001*431deaa0Shylee */ 1002*431deaa0Shylee while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 1003*431deaa0Shylee char *name; 1004*431deaa0Shylee int len; 1005*431deaa0Shylee 1006*431deaa0Shylee if (buffer[0] == '#') { 1007*431deaa0Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1008*431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1009*431deaa0Shylee goto out; 1010*431deaa0Shylee } else { 1011*431deaa0Shylee continue; 1012*431deaa0Shylee } 1013*431deaa0Shylee } 1014*431deaa0Shylee 1015*431deaa0Shylee /* 1016*431deaa0Shylee * make a copy of the original buffer to buffer2. Also get 1017*431deaa0Shylee * rid of the trailing '\n' from buffer2. 1018*431deaa0Shylee */ 1019*431deaa0Shylee (void) strlcpy(buffer2, buffer, MAXPATHLEN); 1020*431deaa0Shylee len = strlen(buffer2); 1021*431deaa0Shylee if (buffer2[len-1] == '\n') { 1022*431deaa0Shylee len--; 1023*431deaa0Shylee } 1024*431deaa0Shylee buffer2[len] = '\0'; 1025*431deaa0Shylee 1026*431deaa0Shylee if ((name = strtok(buffer2, SEP_COLON)) == NULL) { 1027*431deaa0Shylee rv = KC_ERR_UNINSTALL; 1028*431deaa0Shylee goto out; 1029*431deaa0Shylee } 1030*431deaa0Shylee 1031*431deaa0Shylee if (strcmp(name, keystore_name) == 0) { 1032*431deaa0Shylee /* found the entry */ 1033*431deaa0Shylee if (option == NULL) 1034*431deaa0Shylee (void) snprintf(buffer, MAXPATHLEN, 1035*431deaa0Shylee "%s:%s%s\n", keystore_name, 1036*431deaa0Shylee CONF_MODULEPATH, entry->modulepath); 1037*431deaa0Shylee else 1038*431deaa0Shylee (void) snprintf(buffer, MAXPATHLEN, 1039*431deaa0Shylee "%s:%s%s;%s%s\n", keystore_name, 1040*431deaa0Shylee CONF_MODULEPATH, entry->modulepath, 1041*431deaa0Shylee CONF_OPTION, option); 1042*431deaa0Shylee 1043*431deaa0Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1044*431deaa0Shylee err = errno; 1045*431deaa0Shylee (void) fprintf(stderr, gettext( 1046*431deaa0Shylee "failed to write to %s: %s\n"), 1047*431deaa0Shylee tmpfile_name, strerror(err)); 1048*431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1049*431deaa0Shylee goto out; 1050*431deaa0Shylee } 1051*431deaa0Shylee } else { 1052*431deaa0Shylee 1053*431deaa0Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1054*431deaa0Shylee rv = KC_ERR_UNINSTALL; 1055*431deaa0Shylee goto out; 1056*431deaa0Shylee } 1057*431deaa0Shylee } 1058*431deaa0Shylee } 1059*431deaa0Shylee 1060*431deaa0Shylee if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) { 1061*431deaa0Shylee err = errno; 1062*431deaa0Shylee (void) fprintf(stderr, gettext( 1063*431deaa0Shylee "failed to update the configuration - %s"), strerror(err)); 1064*431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1065*431deaa0Shylee goto out; 1066*431deaa0Shylee } 1067*431deaa0Shylee 1068*431deaa0Shylee if (chmod(_PATH_KMF_CONF, 1069*431deaa0Shylee S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 1070*431deaa0Shylee err = errno; 1071*431deaa0Shylee (void) fprintf(stderr, gettext( 1072*431deaa0Shylee "failed to update the configuration - %s\n"), 1073*431deaa0Shylee strerror(err)); 1074*431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1075*431deaa0Shylee goto out; 1076*431deaa0Shylee } 1077*431deaa0Shylee 1078*431deaa0Shylee out: 1079*431deaa0Shylee if (entry != NULL) 1080*431deaa0Shylee free_entry(entry); 1081*431deaa0Shylee 1082*431deaa0Shylee if (pfile != NULL) 1083*431deaa0Shylee (void) fclose(pfile); 1084*431deaa0Shylee 1085*431deaa0Shylee if (rv != KC_OK && pfile_tmp != NULL) 1086*431deaa0Shylee (void) unlink(tmpfile_name); 1087*431deaa0Shylee 1088*431deaa0Shylee if (pfile_tmp != NULL) 1089*431deaa0Shylee (void) fclose(pfile_tmp); 1090*431deaa0Shylee 1091*431deaa0Shylee return (rv); 1092*431deaa0Shylee } 1093*431deaa0Shylee 1094*431deaa0Shylee 1095*431deaa0Shylee int 1096*431deaa0Shylee kc_modify(int argc, char *argv[]) 1097*431deaa0Shylee { 1098*431deaa0Shylee if (argc > 2 && 1099*431deaa0Shylee strcmp(argv[0], "modify") == 0 && 1100*431deaa0Shylee strcmp(argv[1], "plugin") == 0) { 1101*431deaa0Shylee return (kc_modify_plugin(argc, argv)); 1102*431deaa0Shylee } else { 1103*431deaa0Shylee return (kc_modify_policy(argc, argv)); 1104*431deaa0Shylee } 1105*431deaa0Shylee } 1106