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 * 21*30a5e8faSwyllys * 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> 3599ebb4caSwyllys #include "util.h" 3699ebb4caSwyllys 3799ebb4caSwyllys #define KC_IGNORE_DATE 0x0000001 3899ebb4caSwyllys #define KC_IGNORE_UNKNOWN_EKUS 0x0000002 3999ebb4caSwyllys #define KC_IGNORE_TRUST_ANCHOR 0x0000004 4099ebb4caSwyllys #define KC_VALIDITY_ADJUSTTIME 0x0000008 4199ebb4caSwyllys #define KC_TA_NAME 0x0000010 4299ebb4caSwyllys #define KC_TA_SERIAL 0x0000020 4399ebb4caSwyllys #define KC_OCSP_RESPONDER_URI 0x0000040 4499ebb4caSwyllys #define KC_OCSP_PROXY 0x0000080 4599ebb4caSwyllys #define KC_OCSP_URI_FROM_CERT 0x0000100 4699ebb4caSwyllys #define KC_OCSP_RESP_LIFETIME 0x0000200 4799ebb4caSwyllys #define KC_OCSP_IGNORE_RESP_SIGN 0x0000400 4899ebb4caSwyllys #define KC_OCSP_RESP_CERT_NAME 0x0000800 4999ebb4caSwyllys #define KC_OCSP_RESP_CERT_SERIAL 0x0001000 5099ebb4caSwyllys #define KC_OCSP_NONE 0x0002000 5199ebb4caSwyllys #define KC_CRL_BASEFILENAME 0x0004000 5299ebb4caSwyllys #define KC_CRL_DIRECTORY 0x0008000 5399ebb4caSwyllys #define KC_CRL_GET_URI 0x0010000 5499ebb4caSwyllys #define KC_CRL_PROXY 0x0020000 5599ebb4caSwyllys #define KC_CRL_IGNORE_SIGN 0x0040000 5699ebb4caSwyllys #define KC_CRL_IGNORE_DATE 0x0080000 5799ebb4caSwyllys #define KC_CRL_NONE 0x0100000 5899ebb4caSwyllys #define KC_KEYUSAGE 0x0200000 5999ebb4caSwyllys #define KC_KEYUSAGE_NONE 0x0400000 6099ebb4caSwyllys #define KC_EKUS 0x0800000 6199ebb4caSwyllys #define KC_EKUS_NONE 0x1000000 6299ebb4caSwyllys 6399ebb4caSwyllys int 6499ebb4caSwyllys kc_modify(int argc, char *argv[]) 6599ebb4caSwyllys { 6699ebb4caSwyllys KMF_RETURN ret; 6799ebb4caSwyllys int rv = KC_OK; 6899ebb4caSwyllys int opt; 6999ebb4caSwyllys extern int optind_av; 7099ebb4caSwyllys extern char *optarg_av; 7199ebb4caSwyllys char *filename = NULL; 7299ebb4caSwyllys uint32_t flags = 0; 7399ebb4caSwyllys boolean_t ocsp_none_opt = B_FALSE; 7499ebb4caSwyllys boolean_t crl_none_opt = B_FALSE; 7599ebb4caSwyllys boolean_t ku_none_opt = B_FALSE; 7699ebb4caSwyllys boolean_t eku_none_opt = B_FALSE; 7799ebb4caSwyllys int ocsp_set_attr = 0; 7899ebb4caSwyllys int crl_set_attr = 0; 7999ebb4caSwyllys KMF_POLICY_RECORD oplc, plc; 8099ebb4caSwyllys 8199ebb4caSwyllys (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); 8299ebb4caSwyllys (void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD)); 8399ebb4caSwyllys 8499ebb4caSwyllys while ((opt = getopt_av(argc, argv, 8599ebb4caSwyllys "i:(dbfile)" 8699ebb4caSwyllys "p:(policy)" 8799ebb4caSwyllys "d:(ignore-date)" 8899ebb4caSwyllys "e:(ignore-unknown-eku)" 8999ebb4caSwyllys "a:(ignore-trust-anchor)" 9099ebb4caSwyllys "v:(validity-adjusttime)" 9199ebb4caSwyllys "t:(ta-name)" 9299ebb4caSwyllys "s:(ta-serial)" 9399ebb4caSwyllys "o:(ocsp-responder)" 9499ebb4caSwyllys "P:(ocsp-proxy)" 9599ebb4caSwyllys "r:(ocsp-use-cert-responder)" 9699ebb4caSwyllys "T:(ocsp-response-lifetime)" 9799ebb4caSwyllys "R:(ocsp-ignore-response-sign)" 9899ebb4caSwyllys "n:(ocsp-responder-cert-name)" 9999ebb4caSwyllys "A:(ocsp-responder-cert-serial)" 10099ebb4caSwyllys "y:(ocsp-none)" 10199ebb4caSwyllys "c:(crl-basefilename)" 10299ebb4caSwyllys "I:(crl-directory)" 10399ebb4caSwyllys "g:(crl-get-crl-uri)" 10499ebb4caSwyllys "X:(crl-proxy)" 10599ebb4caSwyllys "S:(crl-ignore-crl-sign)" 10699ebb4caSwyllys "D:(crl-ignore-crl-date)" 10799ebb4caSwyllys "z:(crl-none)" 10899ebb4caSwyllys "u:(keyusage)" 10999ebb4caSwyllys "Y:(keyusage-none)" 11099ebb4caSwyllys "E:(ekunames)" 11199ebb4caSwyllys "O:(ekuoids)" 11299ebb4caSwyllys "Z:(eku-none)")) != EOF) { 11399ebb4caSwyllys switch (opt) { 11499ebb4caSwyllys case 'i': 11599ebb4caSwyllys filename = get_string(optarg_av, &rv); 11699ebb4caSwyllys if (filename == NULL) { 11799ebb4caSwyllys (void) fprintf(stderr, 11899ebb4caSwyllys gettext("Error dbfile input.\n")); 11999ebb4caSwyllys } 12099ebb4caSwyllys break; 12199ebb4caSwyllys case 'p': 12299ebb4caSwyllys plc.name = get_string(optarg_av, &rv); 12399ebb4caSwyllys if (plc.name == NULL) { 12499ebb4caSwyllys (void) fprintf(stderr, 12599ebb4caSwyllys gettext("Error policy name.\n")); 12699ebb4caSwyllys } 12799ebb4caSwyllys break; 12899ebb4caSwyllys case 'd': 12999ebb4caSwyllys plc.ignore_date = get_boolean(optarg_av); 13099ebb4caSwyllys if (plc.ignore_date == -1) { 13199ebb4caSwyllys (void) fprintf(stderr, 13299ebb4caSwyllys gettext("Error boolean input.\n")); 13399ebb4caSwyllys rv = KC_ERR_USAGE; 13499ebb4caSwyllys } else { 13599ebb4caSwyllys flags |= KC_IGNORE_DATE; 13699ebb4caSwyllys } 13799ebb4caSwyllys break; 13899ebb4caSwyllys case 'e': 13999ebb4caSwyllys plc.ignore_unknown_ekus = 14099ebb4caSwyllys get_boolean(optarg_av); 14199ebb4caSwyllys if (plc.ignore_unknown_ekus == -1) { 14299ebb4caSwyllys (void) fprintf(stderr, 14399ebb4caSwyllys gettext("Error boolean input.\n")); 14499ebb4caSwyllys rv = KC_ERR_USAGE; 14599ebb4caSwyllys } else { 14699ebb4caSwyllys flags |= KC_IGNORE_UNKNOWN_EKUS; 14799ebb4caSwyllys } 14899ebb4caSwyllys break; 14999ebb4caSwyllys case 'a': 15099ebb4caSwyllys plc.ignore_trust_anchor = 15199ebb4caSwyllys get_boolean(optarg_av); 15299ebb4caSwyllys if (plc.ignore_trust_anchor == -1) { 15399ebb4caSwyllys (void) fprintf(stderr, 15499ebb4caSwyllys gettext("Error boolean input.\n")); 15599ebb4caSwyllys rv = KC_ERR_USAGE; 15699ebb4caSwyllys } else { 15799ebb4caSwyllys flags |= KC_IGNORE_TRUST_ANCHOR; 15899ebb4caSwyllys } 15999ebb4caSwyllys break; 16099ebb4caSwyllys case 'v': 16199ebb4caSwyllys plc.validity_adjusttime = 16299ebb4caSwyllys get_string(optarg_av, &rv); 16399ebb4caSwyllys if (plc.validity_adjusttime == NULL) { 16499ebb4caSwyllys (void) fprintf(stderr, 16599ebb4caSwyllys gettext("Error time input.\n")); 16699ebb4caSwyllys } else { 16799ebb4caSwyllys uint32_t adj; 16899ebb4caSwyllys /* for syntax checking */ 16999ebb4caSwyllys if (str2lifetime( 17099ebb4caSwyllys plc.validity_adjusttime, 17199ebb4caSwyllys &adj) < 0) { 17299ebb4caSwyllys (void) fprintf(stderr, 17399ebb4caSwyllys gettext("Error time " 17499ebb4caSwyllys "input.\n")); 17599ebb4caSwyllys rv = KC_ERR_USAGE; 17699ebb4caSwyllys } else { 17799ebb4caSwyllys flags |= KC_VALIDITY_ADJUSTTIME; 17899ebb4caSwyllys } 17999ebb4caSwyllys } 18099ebb4caSwyllys break; 18199ebb4caSwyllys case 't': 18299ebb4caSwyllys plc.ta_name = get_string(optarg_av, &rv); 18399ebb4caSwyllys if (plc.ta_name == NULL) { 18499ebb4caSwyllys (void) fprintf(stderr, 18599ebb4caSwyllys gettext("Error name input.\n")); 18699ebb4caSwyllys } else { 18799ebb4caSwyllys KMF_X509_NAME taDN; 18899ebb4caSwyllys /* for syntax checking */ 189*30a5e8faSwyllys if (kmf_dn_parser(plc.ta_name, 19099ebb4caSwyllys &taDN) != KMF_OK) { 19199ebb4caSwyllys (void) fprintf(stderr, 19299ebb4caSwyllys gettext("Error name " 19399ebb4caSwyllys "input.\n")); 19499ebb4caSwyllys rv = KC_ERR_USAGE; 19599ebb4caSwyllys } else { 196*30a5e8faSwyllys kmf_free_dn(&taDN); 19799ebb4caSwyllys flags |= KC_TA_NAME; 19899ebb4caSwyllys } 19999ebb4caSwyllys } 20099ebb4caSwyllys break; 20199ebb4caSwyllys case 's': 20299ebb4caSwyllys plc.ta_serial = get_string(optarg_av, &rv); 20399ebb4caSwyllys if (plc.ta_serial == NULL) { 20499ebb4caSwyllys (void) fprintf(stderr, 20599ebb4caSwyllys gettext("Error serial input.\n")); 20699ebb4caSwyllys } else { 20799ebb4caSwyllys uchar_t *bytes = NULL; 20899ebb4caSwyllys size_t bytelen; 20999ebb4caSwyllys 210*30a5e8faSwyllys ret = kmf_hexstr_to_bytes( 21199ebb4caSwyllys (uchar_t *)plc.ta_serial, 21299ebb4caSwyllys &bytes, &bytelen); 21399ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 21499ebb4caSwyllys (void) fprintf(stderr, 21599ebb4caSwyllys gettext("serial number " 21699ebb4caSwyllys "must be specified as a " 21799ebb4caSwyllys "hex number " 21899ebb4caSwyllys "(ex: 0x0102030405" 21999ebb4caSwyllys "ffeeddee)\n")); 22099ebb4caSwyllys rv = KC_ERR_USAGE; 22199ebb4caSwyllys break; 22299ebb4caSwyllys } 22399ebb4caSwyllys if (bytes != NULL) 22499ebb4caSwyllys free(bytes); 22599ebb4caSwyllys flags |= KC_TA_SERIAL; 22699ebb4caSwyllys } 22799ebb4caSwyllys break; 22899ebb4caSwyllys case 'o': 22999ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI = 23099ebb4caSwyllys get_string(optarg_av, &rv); 23199ebb4caSwyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) { 23299ebb4caSwyllys (void) fprintf(stderr, 23399ebb4caSwyllys gettext("Error responder " 23499ebb4caSwyllys "input.\n")); 23599ebb4caSwyllys } else { 23699ebb4caSwyllys flags |= KC_OCSP_RESPONDER_URI; 23799ebb4caSwyllys ocsp_set_attr++; 23899ebb4caSwyllys } 23999ebb4caSwyllys break; 24099ebb4caSwyllys case 'P': 24199ebb4caSwyllys plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv); 24299ebb4caSwyllys if (plc.VAL_OCSP_PROXY == NULL) { 24399ebb4caSwyllys (void) fprintf(stderr, 24499ebb4caSwyllys gettext("Error proxy input.\n")); 24599ebb4caSwyllys } else { 24699ebb4caSwyllys flags |= KC_OCSP_PROXY; 24799ebb4caSwyllys ocsp_set_attr++; 24899ebb4caSwyllys } 24999ebb4caSwyllys break; 25099ebb4caSwyllys case 'r': 25199ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT = 25299ebb4caSwyllys get_boolean(optarg_av); 25399ebb4caSwyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) { 25499ebb4caSwyllys (void) fprintf(stderr, 25599ebb4caSwyllys gettext("Error boolean input.\n")); 25699ebb4caSwyllys rv = KC_ERR_USAGE; 25799ebb4caSwyllys } else { 25899ebb4caSwyllys flags |= KC_OCSP_URI_FROM_CERT; 25999ebb4caSwyllys ocsp_set_attr++; 26099ebb4caSwyllys } 26199ebb4caSwyllys break; 26299ebb4caSwyllys case 'T': 26399ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME = 26499ebb4caSwyllys get_string(optarg_av, &rv); 26599ebb4caSwyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { 26699ebb4caSwyllys (void) fprintf(stderr, 26799ebb4caSwyllys gettext("Error time input.\n")); 26899ebb4caSwyllys } else { 26999ebb4caSwyllys uint32_t adj; 27099ebb4caSwyllys /* for syntax checking */ 27199ebb4caSwyllys if (str2lifetime( 27299ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME, 27399ebb4caSwyllys &adj) < 0) { 27499ebb4caSwyllys (void) fprintf(stderr, 27599ebb4caSwyllys gettext("Error time " 27699ebb4caSwyllys "input.\n")); 27799ebb4caSwyllys rv = KC_ERR_USAGE; 27899ebb4caSwyllys } else { 27999ebb4caSwyllys flags |= KC_OCSP_RESP_LIFETIME; 28099ebb4caSwyllys ocsp_set_attr++; 28199ebb4caSwyllys } 28299ebb4caSwyllys } 28399ebb4caSwyllys break; 28499ebb4caSwyllys case 'R': 28599ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN = 28699ebb4caSwyllys get_boolean(optarg_av); 28799ebb4caSwyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { 28899ebb4caSwyllys (void) fprintf(stderr, 28999ebb4caSwyllys gettext("Error boolean input.\n")); 29099ebb4caSwyllys rv = KC_ERR_USAGE; 29199ebb4caSwyllys } else { 29299ebb4caSwyllys flags |= KC_OCSP_IGNORE_RESP_SIGN; 29399ebb4caSwyllys ocsp_set_attr++; 29499ebb4caSwyllys } 29599ebb4caSwyllys break; 29699ebb4caSwyllys case 'n': 29799ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME = 29899ebb4caSwyllys get_string(optarg_av, &rv); 29999ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { 30099ebb4caSwyllys (void) fprintf(stderr, 30199ebb4caSwyllys gettext("Error name input.\n")); 30299ebb4caSwyllys } else { 30399ebb4caSwyllys KMF_X509_NAME respDN; 30499ebb4caSwyllys /* for syntax checking */ 305*30a5e8faSwyllys if (kmf_dn_parser( 30699ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME, 30799ebb4caSwyllys &respDN) != KMF_OK) { 30899ebb4caSwyllys (void) fprintf(stderr, 30999ebb4caSwyllys gettext("Error name " 31099ebb4caSwyllys "input.\n")); 31199ebb4caSwyllys rv = KC_ERR_USAGE; 31299ebb4caSwyllys } else { 313*30a5e8faSwyllys kmf_free_dn(&respDN); 31499ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_NAME; 31599ebb4caSwyllys ocsp_set_attr++; 31699ebb4caSwyllys } 31799ebb4caSwyllys } 31899ebb4caSwyllys break; 31999ebb4caSwyllys case 'A': 32099ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL = 32199ebb4caSwyllys get_string(optarg_av, &rv); 32299ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { 32399ebb4caSwyllys (void) fprintf(stderr, 32499ebb4caSwyllys gettext("Error serial input.\n")); 32599ebb4caSwyllys } else { 32699ebb4caSwyllys uchar_t *bytes = NULL; 32799ebb4caSwyllys size_t bytelen; 32899ebb4caSwyllys 329*30a5e8faSwyllys ret = kmf_hexstr_to_bytes((uchar_t *) 33099ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL, 33199ebb4caSwyllys &bytes, &bytelen); 33299ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 33399ebb4caSwyllys (void) fprintf(stderr, 33499ebb4caSwyllys gettext("serial number " 33599ebb4caSwyllys "must be specified as a " 33699ebb4caSwyllys "hex number " 33799ebb4caSwyllys "(ex: 0x0102030405" 33899ebb4caSwyllys "ffeeddee)\n")); 33999ebb4caSwyllys rv = KC_ERR_USAGE; 34099ebb4caSwyllys break; 34199ebb4caSwyllys } 34299ebb4caSwyllys if (bytes != NULL) 34399ebb4caSwyllys free(bytes); 34499ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_SERIAL; 34599ebb4caSwyllys ocsp_set_attr++; 34699ebb4caSwyllys } 34799ebb4caSwyllys break; 34899ebb4caSwyllys case 'y': 34999ebb4caSwyllys ocsp_none_opt = get_boolean(optarg_av); 35099ebb4caSwyllys if (ocsp_none_opt == -1) { 35199ebb4caSwyllys (void) fprintf(stderr, 35299ebb4caSwyllys gettext("Error boolean input.\n")); 35399ebb4caSwyllys rv = KC_ERR_USAGE; 35499ebb4caSwyllys } else { 35599ebb4caSwyllys flags |= KC_OCSP_NONE; 35699ebb4caSwyllys } 35799ebb4caSwyllys break; 35899ebb4caSwyllys case 'c': 35999ebb4caSwyllys plc.VAL_CRL_BASEFILENAME = 36099ebb4caSwyllys get_string(optarg_av, &rv); 36199ebb4caSwyllys if (plc.VAL_CRL_BASEFILENAME == NULL) { 36299ebb4caSwyllys (void) fprintf(stderr, gettext( 36399ebb4caSwyllys "Error basefilename input.\n")); 36499ebb4caSwyllys } else { 36599ebb4caSwyllys flags |= KC_CRL_BASEFILENAME; 36699ebb4caSwyllys crl_set_attr++; 36799ebb4caSwyllys } 36899ebb4caSwyllys break; 36999ebb4caSwyllys case 'I': 37099ebb4caSwyllys plc.VAL_CRL_DIRECTORY = 37199ebb4caSwyllys get_string(optarg_av, &rv); 37299ebb4caSwyllys if (plc.VAL_CRL_DIRECTORY == NULL) { 37399ebb4caSwyllys (void) fprintf(stderr, 37499ebb4caSwyllys gettext("Error boolean input.\n")); 37599ebb4caSwyllys } else { 37699ebb4caSwyllys flags |= KC_CRL_DIRECTORY; 37799ebb4caSwyllys crl_set_attr++; 37899ebb4caSwyllys } 37999ebb4caSwyllys break; 38099ebb4caSwyllys case 'g': 38199ebb4caSwyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av); 38299ebb4caSwyllys if (plc.VAL_CRL_GET_URI == -1) { 38399ebb4caSwyllys (void) fprintf(stderr, 38499ebb4caSwyllys gettext("Error boolean input.\n")); 38599ebb4caSwyllys rv = KC_ERR_USAGE; 38699ebb4caSwyllys } else { 38799ebb4caSwyllys flags |= KC_CRL_GET_URI; 38899ebb4caSwyllys crl_set_attr++; 38999ebb4caSwyllys } 39099ebb4caSwyllys break; 39199ebb4caSwyllys case 'X': 39299ebb4caSwyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); 39399ebb4caSwyllys if (plc.VAL_CRL_PROXY == NULL) { 39499ebb4caSwyllys (void) fprintf(stderr, 39599ebb4caSwyllys gettext("Error proxy input.\n")); 39699ebb4caSwyllys } else { 39799ebb4caSwyllys flags |= KC_CRL_PROXY; 39899ebb4caSwyllys crl_set_attr++; 39999ebb4caSwyllys } 40099ebb4caSwyllys break; 40199ebb4caSwyllys case 'S': 40299ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN = 40399ebb4caSwyllys get_boolean(optarg_av); 40499ebb4caSwyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) { 40599ebb4caSwyllys (void) fprintf(stderr, 40699ebb4caSwyllys gettext("Error boolean input.\n")); 40799ebb4caSwyllys rv = KC_ERR_USAGE; 40899ebb4caSwyllys } else { 40999ebb4caSwyllys flags |= KC_CRL_IGNORE_SIGN; 41099ebb4caSwyllys crl_set_attr++; 41199ebb4caSwyllys } 41299ebb4caSwyllys break; 41399ebb4caSwyllys case 'D': 41499ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE = 41599ebb4caSwyllys get_boolean(optarg_av); 41699ebb4caSwyllys if (plc.VAL_CRL_IGNORE_DATE == -1) { 41799ebb4caSwyllys (void) fprintf(stderr, 41899ebb4caSwyllys gettext("Error boolean input.\n")); 41999ebb4caSwyllys rv = KC_ERR_USAGE; 42099ebb4caSwyllys } else { 42199ebb4caSwyllys flags |= KC_CRL_IGNORE_DATE; 42299ebb4caSwyllys crl_set_attr++; 42399ebb4caSwyllys } 42499ebb4caSwyllys break; 42599ebb4caSwyllys case 'z': 42699ebb4caSwyllys crl_none_opt = get_boolean(optarg_av); 42799ebb4caSwyllys if (crl_none_opt == -1) { 42899ebb4caSwyllys (void) fprintf(stderr, 42999ebb4caSwyllys gettext("Error boolean input.\n")); 43099ebb4caSwyllys rv = KC_ERR_USAGE; 43199ebb4caSwyllys } else { 43299ebb4caSwyllys flags |= KC_CRL_NONE; 43399ebb4caSwyllys } 43499ebb4caSwyllys break; 43599ebb4caSwyllys case 'u': 43699ebb4caSwyllys plc.ku_bits = parseKUlist(optarg_av); 43799ebb4caSwyllys if (plc.ku_bits == 0) { 43899ebb4caSwyllys (void) fprintf(stderr, gettext( 43999ebb4caSwyllys "Error keyusage input.\n")); 44099ebb4caSwyllys rv = KC_ERR_USAGE; 44199ebb4caSwyllys } else { 44299ebb4caSwyllys flags |= KC_KEYUSAGE; 44399ebb4caSwyllys } 44499ebb4caSwyllys break; 44599ebb4caSwyllys case 'Y': 44699ebb4caSwyllys ku_none_opt = get_boolean(optarg_av); 44799ebb4caSwyllys if (ku_none_opt == -1) { 44899ebb4caSwyllys (void) fprintf(stderr, 44999ebb4caSwyllys gettext("Error boolean input.\n")); 45099ebb4caSwyllys rv = KC_ERR_USAGE; 45199ebb4caSwyllys } else { 45299ebb4caSwyllys flags |= KC_KEYUSAGE_NONE; 45399ebb4caSwyllys } 45499ebb4caSwyllys break; 45599ebb4caSwyllys case 'E': 45699ebb4caSwyllys if (parseEKUNames(optarg_av, &plc) != 0) { 45799ebb4caSwyllys (void) fprintf(stderr, 45899ebb4caSwyllys gettext("Error EKU input.\n")); 45999ebb4caSwyllys rv = KC_ERR_USAGE; 46099ebb4caSwyllys } else { 46199ebb4caSwyllys flags |= KC_EKUS; 46299ebb4caSwyllys } 46399ebb4caSwyllys break; 46499ebb4caSwyllys case 'O': 46599ebb4caSwyllys if (parseEKUOIDs(optarg_av, &plc) != 0) { 46699ebb4caSwyllys (void) fprintf(stderr, 46799ebb4caSwyllys gettext("Error EKU OID input.\n")); 46899ebb4caSwyllys rv = KC_ERR_USAGE; 46999ebb4caSwyllys } else { 47099ebb4caSwyllys flags |= KC_EKUS; 47199ebb4caSwyllys } 47299ebb4caSwyllys break; 47399ebb4caSwyllys case 'Z': 47499ebb4caSwyllys eku_none_opt = get_boolean(optarg_av); 47599ebb4caSwyllys if (eku_none_opt == -1) { 47699ebb4caSwyllys (void) fprintf(stderr, 47799ebb4caSwyllys gettext("Error boolean input.\n")); 47899ebb4caSwyllys rv = KC_ERR_USAGE; 47999ebb4caSwyllys } else { 48099ebb4caSwyllys flags |= KC_EKUS_NONE; 48199ebb4caSwyllys } 48299ebb4caSwyllys break; 48399ebb4caSwyllys default: 48499ebb4caSwyllys (void) fprintf(stderr, 48599ebb4caSwyllys gettext("Error input option.\n")); 48699ebb4caSwyllys rv = KC_ERR_USAGE; 48799ebb4caSwyllys break; 48899ebb4caSwyllys } 48999ebb4caSwyllys if (rv != KC_OK) 49099ebb4caSwyllys goto out; 49199ebb4caSwyllys } 49299ebb4caSwyllys 49399ebb4caSwyllys /* No additional args allowed. */ 49499ebb4caSwyllys argc -= optind_av; 49599ebb4caSwyllys if (argc) { 49699ebb4caSwyllys (void) fprintf(stderr, 49799ebb4caSwyllys gettext("Error input option\n")); 49899ebb4caSwyllys rv = KC_ERR_USAGE; 49999ebb4caSwyllys goto out; 50099ebb4caSwyllys } 50199ebb4caSwyllys 50299ebb4caSwyllys if (filename == NULL) { 50399ebb4caSwyllys filename = strdup(KMF_DEFAULT_POLICY_FILE); 50499ebb4caSwyllys if (filename == NULL) { 50599ebb4caSwyllys rv = KC_ERR_MEMORY; 50699ebb4caSwyllys goto out; 50799ebb4caSwyllys } 50899ebb4caSwyllys } 50999ebb4caSwyllys 51099ebb4caSwyllys /* 51199ebb4caSwyllys * Must have a policy name. The policy name can not be default 51299ebb4caSwyllys * if using the default policy file. 51399ebb4caSwyllys */ 51499ebb4caSwyllys if (plc.name == NULL) { 51599ebb4caSwyllys (void) fprintf(stderr, 51699ebb4caSwyllys gettext("You must specify a policy name.\n")); 51799ebb4caSwyllys rv = KC_ERR_USAGE; 51899ebb4caSwyllys goto out; 51999ebb4caSwyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && 52099ebb4caSwyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { 52199ebb4caSwyllys (void) fprintf(stderr, 52299ebb4caSwyllys gettext("Can not modify the default policy in the default " 52399ebb4caSwyllys "policy file.\n")); 52499ebb4caSwyllys rv = KC_ERR_USAGE; 52599ebb4caSwyllys goto out; 52699ebb4caSwyllys } 52799ebb4caSwyllys 52899ebb4caSwyllys /* Check the access permission of the policy DB */ 52999ebb4caSwyllys if (access(filename, W_OK) < 0) { 53099ebb4caSwyllys int err = errno; 53199ebb4caSwyllys (void) fprintf(stderr, 53299ebb4caSwyllys gettext("Cannot access \"%s\" for modify - %s\n"), 53399ebb4caSwyllys filename, strerror(err)); 53499ebb4caSwyllys rv = KC_ERR_ACCESS; 53599ebb4caSwyllys goto out; 53699ebb4caSwyllys } 53799ebb4caSwyllys 53899ebb4caSwyllys /* Try to load the named policy from the DB */ 539*30a5e8faSwyllys ret = kmf_get_policy(filename, plc.name, &oplc); 54099ebb4caSwyllys if (ret != KMF_OK) { 54199ebb4caSwyllys (void) fprintf(stderr, 54299ebb4caSwyllys gettext("Error loading policy \"%s\" from %s\n"), filename, 54399ebb4caSwyllys plc.name); 54499ebb4caSwyllys return (KC_ERR_FIND_POLICY); 54599ebb4caSwyllys } 54699ebb4caSwyllys 54799ebb4caSwyllys /* Update the general policy attributes. */ 54899ebb4caSwyllys if (flags & KC_IGNORE_DATE) 54999ebb4caSwyllys oplc.ignore_date = plc.ignore_date; 55099ebb4caSwyllys 55199ebb4caSwyllys if (flags & KC_IGNORE_UNKNOWN_EKUS) 55299ebb4caSwyllys oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus; 55399ebb4caSwyllys 55499ebb4caSwyllys if (flags & KC_IGNORE_TRUST_ANCHOR) 55599ebb4caSwyllys oplc.ignore_trust_anchor = plc.ignore_trust_anchor; 55699ebb4caSwyllys 55799ebb4caSwyllys if (flags & KC_VALIDITY_ADJUSTTIME) { 55899ebb4caSwyllys if (oplc.validity_adjusttime) 55999ebb4caSwyllys free(oplc.validity_adjusttime); 56099ebb4caSwyllys oplc.validity_adjusttime = 56199ebb4caSwyllys plc.validity_adjusttime; 56299ebb4caSwyllys } 56399ebb4caSwyllys 56499ebb4caSwyllys if (flags & KC_TA_NAME) { 56599ebb4caSwyllys if (oplc.ta_name) 56699ebb4caSwyllys free(oplc.ta_name); 56799ebb4caSwyllys oplc.ta_name = plc.ta_name; 56899ebb4caSwyllys } 56999ebb4caSwyllys if (flags & KC_TA_SERIAL) { 57099ebb4caSwyllys if (oplc.ta_serial) 57199ebb4caSwyllys free(oplc.ta_serial); 57299ebb4caSwyllys oplc.ta_serial = plc.ta_serial; 57399ebb4caSwyllys } 57499ebb4caSwyllys 57599ebb4caSwyllys /* Update the OCSP policy */ 57699ebb4caSwyllys if (ocsp_none_opt == B_TRUE) { 57799ebb4caSwyllys if (ocsp_set_attr > 0) { 57899ebb4caSwyllys (void) fprintf(stderr, 57999ebb4caSwyllys gettext("Can not set ocsp-none=true and other " 58099ebb4caSwyllys "OCSP attributes at the same time.\n")); 58199ebb4caSwyllys rv = KC_ERR_USAGE; 58299ebb4caSwyllys goto out; 58399ebb4caSwyllys } 58499ebb4caSwyllys 58599ebb4caSwyllys /* 58699ebb4caSwyllys * If the original policy does not have OCSP checking, 58799ebb4caSwyllys * then we do not need to do anything. If the original 58899ebb4caSwyllys * policy has the OCSP checking, then we need to release the 58999ebb4caSwyllys * space of OCSP attributes and turn the OCSP checking off. 59099ebb4caSwyllys */ 59199ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) { 59299ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.responderURI) { 59399ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.responderURI); 59499ebb4caSwyllys oplc.VAL_OCSP_BASIC.responderURI = NULL; 59599ebb4caSwyllys } 59699ebb4caSwyllys 59799ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.proxy) { 59899ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.proxy); 59999ebb4caSwyllys oplc.VAL_OCSP_BASIC.proxy = NULL; 60099ebb4caSwyllys } 60199ebb4caSwyllys 60299ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.response_lifetime) { 60399ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.response_lifetime); 60499ebb4caSwyllys oplc.VAL_OCSP_BASIC.response_lifetime = NULL; 60599ebb4caSwyllys } 60699ebb4caSwyllys 60799ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 60899ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.name); 60999ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.name = NULL; 61099ebb4caSwyllys } 61199ebb4caSwyllys 61299ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 61399ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.serial); 61499ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.serial = NULL; 61599ebb4caSwyllys } 61699ebb4caSwyllys 61799ebb4caSwyllys /* Turn off the OCSP checking */ 61899ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP; 61999ebb4caSwyllys } 62099ebb4caSwyllys 62199ebb4caSwyllys } else { 62299ebb4caSwyllys /* 62399ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 62499ebb4caSwyllys * then we only need to do the modification if there is at 62599ebb4caSwyllys * least one OCSP attribute is specified. 62699ebb4caSwyllys */ 62799ebb4caSwyllys if (ocsp_set_attr > 0) { 62899ebb4caSwyllys if (flags & KC_OCSP_RESPONDER_URI) { 62999ebb4caSwyllys if (oplc.VAL_OCSP_RESPONDER_URI) 63099ebb4caSwyllys free(oplc.VAL_OCSP_RESPONDER_URI); 63199ebb4caSwyllys oplc.VAL_OCSP_RESPONDER_URI = 63299ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI; 63399ebb4caSwyllys } 63499ebb4caSwyllys 63599ebb4caSwyllys if (flags & KC_OCSP_PROXY) { 63699ebb4caSwyllys if (oplc.VAL_OCSP_PROXY) 63799ebb4caSwyllys free(oplc.VAL_OCSP_PROXY); 63899ebb4caSwyllys oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY; 63999ebb4caSwyllys } 64099ebb4caSwyllys 64199ebb4caSwyllys if (flags & KC_OCSP_URI_FROM_CERT) 64299ebb4caSwyllys oplc.VAL_OCSP_URI_FROM_CERT = 64399ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT; 64499ebb4caSwyllys 64599ebb4caSwyllys if (flags & KC_OCSP_RESP_LIFETIME) { 64699ebb4caSwyllys if (oplc.VAL_OCSP_RESP_LIFETIME) 64799ebb4caSwyllys free(oplc.VAL_OCSP_RESP_LIFETIME); 64899ebb4caSwyllys oplc.VAL_OCSP_RESP_LIFETIME = 64999ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME; 65099ebb4caSwyllys } 65199ebb4caSwyllys 65299ebb4caSwyllys if (flags & KC_OCSP_IGNORE_RESP_SIGN) 65399ebb4caSwyllys oplc.VAL_OCSP_IGNORE_RESP_SIGN = 65499ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN; 65599ebb4caSwyllys 65699ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 65799ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME) 65899ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_NAME); 65999ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_NAME = 66099ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME; 66199ebb4caSwyllys } 66299ebb4caSwyllys 66399ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 66499ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_SERIAL) 66599ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_SERIAL); 66699ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL = 66799ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL; 66899ebb4caSwyllys } 66999ebb4caSwyllys 67099ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL && 67199ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL) 67299ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_TRUE; 67399ebb4caSwyllys else 67499ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_FALSE; 67599ebb4caSwyllys 67699ebb4caSwyllys /* Turn on the OCSP checking */ 67799ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_OCSP; 67899ebb4caSwyllys } 67999ebb4caSwyllys } 68099ebb4caSwyllys 68199ebb4caSwyllys /* Update the CRL policy */ 68299ebb4caSwyllys if (crl_none_opt == B_TRUE) { 68399ebb4caSwyllys if (crl_set_attr > 0) { 68499ebb4caSwyllys (void) fprintf(stderr, 68599ebb4caSwyllys gettext("Can not set crl-none=true and other CRL " 68699ebb4caSwyllys "attributes at the same time.\n")); 68799ebb4caSwyllys rv = KC_ERR_USAGE; 68899ebb4caSwyllys goto out; 68999ebb4caSwyllys } 69099ebb4caSwyllys 69199ebb4caSwyllys /* 69299ebb4caSwyllys * If the original policy does not have CRL checking, 69399ebb4caSwyllys * then we do not need to do anything. If the original 69499ebb4caSwyllys * policy has the CRL checking, then we need to release the 69599ebb4caSwyllys * space of CRL attributes and turn the CRL checking off. 69699ebb4caSwyllys */ 69799ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) { 69899ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) { 69999ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 70099ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = NULL; 70199ebb4caSwyllys } 70299ebb4caSwyllys 70399ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) { 70499ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 70599ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = NULL; 70699ebb4caSwyllys } 70799ebb4caSwyllys 70899ebb4caSwyllys if (oplc.VAL_CRL_PROXY) { 70999ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 71099ebb4caSwyllys oplc.VAL_CRL_PROXY = NULL; 71199ebb4caSwyllys } 71299ebb4caSwyllys 71399ebb4caSwyllys /* Turn off the CRL checking */ 71499ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL; 71599ebb4caSwyllys } 71699ebb4caSwyllys } else { 71799ebb4caSwyllys /* 71899ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 71999ebb4caSwyllys * then we only need to do the modification if there is at 72099ebb4caSwyllys * least one CRL attribute is specified. 72199ebb4caSwyllys */ 72299ebb4caSwyllys if (crl_set_attr > 0) { 72399ebb4caSwyllys if (flags & KC_CRL_BASEFILENAME) { 72499ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) 72599ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 72699ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = 72799ebb4caSwyllys plc.VAL_CRL_BASEFILENAME; 72899ebb4caSwyllys } 72999ebb4caSwyllys 73099ebb4caSwyllys if (flags & KC_CRL_DIRECTORY) { 73199ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) 73299ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 73399ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY; 73499ebb4caSwyllys } 73599ebb4caSwyllys 73699ebb4caSwyllys if (flags & KC_CRL_GET_URI) { 73799ebb4caSwyllys oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI; 73899ebb4caSwyllys } 73999ebb4caSwyllys 74099ebb4caSwyllys if (flags & KC_CRL_PROXY) { 74199ebb4caSwyllys if (oplc.VAL_CRL_PROXY) 74299ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 74399ebb4caSwyllys oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY; 74499ebb4caSwyllys } 74599ebb4caSwyllys 74699ebb4caSwyllys if (flags & KC_CRL_IGNORE_SIGN) { 74799ebb4caSwyllys oplc.VAL_CRL_IGNORE_SIGN = 74899ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN; 74999ebb4caSwyllys } 75099ebb4caSwyllys 75199ebb4caSwyllys if (flags & KC_CRL_IGNORE_DATE) { 75299ebb4caSwyllys oplc.VAL_CRL_IGNORE_DATE = 75399ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE; 75499ebb4caSwyllys } 75599ebb4caSwyllys 75699ebb4caSwyllys /* Turn on the CRL checking */ 75799ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_CRL; 75899ebb4caSwyllys } 75999ebb4caSwyllys } 76099ebb4caSwyllys 76199ebb4caSwyllys /* Update the Key Usage */ 76299ebb4caSwyllys if (ku_none_opt == B_TRUE) { 76399ebb4caSwyllys if (flags & KC_KEYUSAGE) { 76499ebb4caSwyllys (void) fprintf(stderr, 76599ebb4caSwyllys gettext("Can not set keyusage-none=true and " 76699ebb4caSwyllys "modify the keyusage value at the same time.\n")); 76799ebb4caSwyllys rv = KC_ERR_USAGE; 76899ebb4caSwyllys goto out; 76999ebb4caSwyllys } 77099ebb4caSwyllys 77199ebb4caSwyllys oplc.ku_bits = 0; 77299ebb4caSwyllys } else { 77399ebb4caSwyllys /* 77499ebb4caSwyllys * If the "keyusage-none" option is not set or is set to 77599ebb4caSwyllys * false, then we only need to do the modification if 77699ebb4caSwyllys * the keyusage value is specified. 77799ebb4caSwyllys */ 77899ebb4caSwyllys if (flags & KC_KEYUSAGE) 77999ebb4caSwyllys oplc.ku_bits = plc.ku_bits; 78099ebb4caSwyllys } 78199ebb4caSwyllys 78299ebb4caSwyllys 78399ebb4caSwyllys /* Update the Extended Key Usage */ 78499ebb4caSwyllys if (eku_none_opt == B_TRUE) { 78599ebb4caSwyllys if (flags & KC_EKUS) { 78699ebb4caSwyllys (void) fprintf(stderr, 78799ebb4caSwyllys gettext("Can not set eku-none=true and modify " 78899ebb4caSwyllys "EKU values at the same time.\n")); 78999ebb4caSwyllys rv = KC_ERR_USAGE; 79099ebb4caSwyllys goto out; 79199ebb4caSwyllys } 79299ebb4caSwyllys 79399ebb4caSwyllys /* Release current EKU list (if any) */ 79499ebb4caSwyllys if (oplc.eku_set.eku_count > 0) { 795*30a5e8faSwyllys kmf_free_eku_policy(&oplc.eku_set); 79699ebb4caSwyllys oplc.eku_set.eku_count = 0; 79799ebb4caSwyllys oplc.eku_set.ekulist = NULL; 79899ebb4caSwyllys } 79999ebb4caSwyllys } else { 80099ebb4caSwyllys /* 80199ebb4caSwyllys * If the "eku-none" option is not set or is set to false, 80299ebb4caSwyllys * then we only need to do the modification if either 80399ebb4caSwyllys * "ekuname" or "ekuoids" is specified. 80499ebb4caSwyllys */ 80599ebb4caSwyllys if (flags & KC_EKUS) { 80699ebb4caSwyllys /* Release current EKU list (if any) */ 807*30a5e8faSwyllys kmf_free_eku_policy(&oplc.eku_set); 80899ebb4caSwyllys oplc.eku_set = plc.eku_set; 80999ebb4caSwyllys } 81099ebb4caSwyllys } 81199ebb4caSwyllys 81299ebb4caSwyllys /* Do a sanity check on the modified policy */ 813*30a5e8faSwyllys ret = kmf_verify_policy(&oplc); 81499ebb4caSwyllys if (ret != KMF_OK) { 81599ebb4caSwyllys print_sanity_error(ret); 81699ebb4caSwyllys rv = KC_ERR_VERIFY_POLICY; 81799ebb4caSwyllys goto out; 81899ebb4caSwyllys } 81999ebb4caSwyllys 82099ebb4caSwyllys /* The modify operation is a delete followed by an add */ 821*30a5e8faSwyllys ret = kmf_delete_policy_from_db(oplc.name, filename); 82299ebb4caSwyllys if (ret != KMF_OK) { 82399ebb4caSwyllys rv = KC_ERR_DELETE_POLICY; 82499ebb4caSwyllys goto out; 82599ebb4caSwyllys } 82699ebb4caSwyllys 82799ebb4caSwyllys /* 82899ebb4caSwyllys * Now add the modified policy back to the DB. 82999ebb4caSwyllys */ 830*30a5e8faSwyllys ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE); 83199ebb4caSwyllys if (ret != KMF_OK) { 83299ebb4caSwyllys (void) fprintf(stderr, 83399ebb4caSwyllys gettext("Error adding policy to database: 0x%04x\n"), ret); 83499ebb4caSwyllys rv = KC_ERR_ADD_POLICY; 83599ebb4caSwyllys goto out; 83699ebb4caSwyllys } 83799ebb4caSwyllys 83899ebb4caSwyllys out: 83999ebb4caSwyllys if (filename != NULL) 84099ebb4caSwyllys free(filename); 84199ebb4caSwyllys 842*30a5e8faSwyllys kmf_free_policy_record(&oplc); 84399ebb4caSwyllys 84499ebb4caSwyllys return (rv); 84599ebb4caSwyllys } 846