1*99ebb4caSwyllys /* 2*99ebb4caSwyllys * CDDL HEADER START 3*99ebb4caSwyllys * 4*99ebb4caSwyllys * The contents of this file are subject to the terms of the 5*99ebb4caSwyllys * Common Development and Distribution License (the "License"). 6*99ebb4caSwyllys * You may not use this file except in compliance with the License. 7*99ebb4caSwyllys * 8*99ebb4caSwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*99ebb4caSwyllys * or http://www.opensolaris.org/os/licensing. 10*99ebb4caSwyllys * See the License for the specific language governing permissions 11*99ebb4caSwyllys * and limitations under the License. 12*99ebb4caSwyllys * 13*99ebb4caSwyllys * When distributing Covered Code, include this CDDL HEADER in each 14*99ebb4caSwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*99ebb4caSwyllys * If applicable, add the following below this CDDL HEADER, with the 16*99ebb4caSwyllys * fields enclosed by brackets "[]" replaced with your own identifying 17*99ebb4caSwyllys * information: Portions Copyright [yyyy] [name of copyright owner] 18*99ebb4caSwyllys * 19*99ebb4caSwyllys * CDDL HEADER END 20*99ebb4caSwyllys * 21*99ebb4caSwyllys * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 22*99ebb4caSwyllys * Use is subject to license terms. 23*99ebb4caSwyllys */ 24*99ebb4caSwyllys 25*99ebb4caSwyllys #pragma ident "%Z%%M% %I% %E% SMI" 26*99ebb4caSwyllys 27*99ebb4caSwyllys #include <stdio.h> 28*99ebb4caSwyllys #include <strings.h> 29*99ebb4caSwyllys #include <ctype.h> 30*99ebb4caSwyllys #include <libgen.h> 31*99ebb4caSwyllys #include <libintl.h> 32*99ebb4caSwyllys #include <errno.h> 33*99ebb4caSwyllys #include <kmfapiP.h> 34*99ebb4caSwyllys #include <cryptoutil.h> 35*99ebb4caSwyllys #include "util.h" 36*99ebb4caSwyllys 37*99ebb4caSwyllys #define KC_IGNORE_DATE 0x0000001 38*99ebb4caSwyllys #define KC_IGNORE_UNKNOWN_EKUS 0x0000002 39*99ebb4caSwyllys #define KC_IGNORE_TRUST_ANCHOR 0x0000004 40*99ebb4caSwyllys #define KC_VALIDITY_ADJUSTTIME 0x0000008 41*99ebb4caSwyllys #define KC_TA_NAME 0x0000010 42*99ebb4caSwyllys #define KC_TA_SERIAL 0x0000020 43*99ebb4caSwyllys #define KC_OCSP_RESPONDER_URI 0x0000040 44*99ebb4caSwyllys #define KC_OCSP_PROXY 0x0000080 45*99ebb4caSwyllys #define KC_OCSP_URI_FROM_CERT 0x0000100 46*99ebb4caSwyllys #define KC_OCSP_RESP_LIFETIME 0x0000200 47*99ebb4caSwyllys #define KC_OCSP_IGNORE_RESP_SIGN 0x0000400 48*99ebb4caSwyllys #define KC_OCSP_RESP_CERT_NAME 0x0000800 49*99ebb4caSwyllys #define KC_OCSP_RESP_CERT_SERIAL 0x0001000 50*99ebb4caSwyllys #define KC_OCSP_NONE 0x0002000 51*99ebb4caSwyllys #define KC_CRL_BASEFILENAME 0x0004000 52*99ebb4caSwyllys #define KC_CRL_DIRECTORY 0x0008000 53*99ebb4caSwyllys #define KC_CRL_GET_URI 0x0010000 54*99ebb4caSwyllys #define KC_CRL_PROXY 0x0020000 55*99ebb4caSwyllys #define KC_CRL_IGNORE_SIGN 0x0040000 56*99ebb4caSwyllys #define KC_CRL_IGNORE_DATE 0x0080000 57*99ebb4caSwyllys #define KC_CRL_NONE 0x0100000 58*99ebb4caSwyllys #define KC_KEYUSAGE 0x0200000 59*99ebb4caSwyllys #define KC_KEYUSAGE_NONE 0x0400000 60*99ebb4caSwyllys #define KC_EKUS 0x0800000 61*99ebb4caSwyllys #define KC_EKUS_NONE 0x1000000 62*99ebb4caSwyllys 63*99ebb4caSwyllys int 64*99ebb4caSwyllys kc_modify(int argc, char *argv[]) 65*99ebb4caSwyllys { 66*99ebb4caSwyllys KMF_RETURN ret; 67*99ebb4caSwyllys int rv = KC_OK; 68*99ebb4caSwyllys int opt; 69*99ebb4caSwyllys extern int optind_av; 70*99ebb4caSwyllys extern char *optarg_av; 71*99ebb4caSwyllys char *filename = NULL; 72*99ebb4caSwyllys uint32_t flags = 0; 73*99ebb4caSwyllys boolean_t ocsp_none_opt = B_FALSE; 74*99ebb4caSwyllys boolean_t crl_none_opt = B_FALSE; 75*99ebb4caSwyllys boolean_t ku_none_opt = B_FALSE; 76*99ebb4caSwyllys boolean_t eku_none_opt = B_FALSE; 77*99ebb4caSwyllys int ocsp_set_attr = 0; 78*99ebb4caSwyllys int crl_set_attr = 0; 79*99ebb4caSwyllys KMF_POLICY_RECORD oplc, plc; 80*99ebb4caSwyllys 81*99ebb4caSwyllys (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); 82*99ebb4caSwyllys (void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD)); 83*99ebb4caSwyllys 84*99ebb4caSwyllys while ((opt = getopt_av(argc, argv, 85*99ebb4caSwyllys "i:(dbfile)" 86*99ebb4caSwyllys "p:(policy)" 87*99ebb4caSwyllys "d:(ignore-date)" 88*99ebb4caSwyllys "e:(ignore-unknown-eku)" 89*99ebb4caSwyllys "a:(ignore-trust-anchor)" 90*99ebb4caSwyllys "v:(validity-adjusttime)" 91*99ebb4caSwyllys "t:(ta-name)" 92*99ebb4caSwyllys "s:(ta-serial)" 93*99ebb4caSwyllys "o:(ocsp-responder)" 94*99ebb4caSwyllys "P:(ocsp-proxy)" 95*99ebb4caSwyllys "r:(ocsp-use-cert-responder)" 96*99ebb4caSwyllys "T:(ocsp-response-lifetime)" 97*99ebb4caSwyllys "R:(ocsp-ignore-response-sign)" 98*99ebb4caSwyllys "n:(ocsp-responder-cert-name)" 99*99ebb4caSwyllys "A:(ocsp-responder-cert-serial)" 100*99ebb4caSwyllys "y:(ocsp-none)" 101*99ebb4caSwyllys "c:(crl-basefilename)" 102*99ebb4caSwyllys "I:(crl-directory)" 103*99ebb4caSwyllys "g:(crl-get-crl-uri)" 104*99ebb4caSwyllys "X:(crl-proxy)" 105*99ebb4caSwyllys "S:(crl-ignore-crl-sign)" 106*99ebb4caSwyllys "D:(crl-ignore-crl-date)" 107*99ebb4caSwyllys "z:(crl-none)" 108*99ebb4caSwyllys "u:(keyusage)" 109*99ebb4caSwyllys "Y:(keyusage-none)" 110*99ebb4caSwyllys "E:(ekunames)" 111*99ebb4caSwyllys "O:(ekuoids)" 112*99ebb4caSwyllys "Z:(eku-none)")) != EOF) { 113*99ebb4caSwyllys switch (opt) { 114*99ebb4caSwyllys case 'i': 115*99ebb4caSwyllys filename = get_string(optarg_av, &rv); 116*99ebb4caSwyllys if (filename == NULL) { 117*99ebb4caSwyllys (void) fprintf(stderr, 118*99ebb4caSwyllys gettext("Error dbfile input.\n")); 119*99ebb4caSwyllys } 120*99ebb4caSwyllys break; 121*99ebb4caSwyllys case 'p': 122*99ebb4caSwyllys plc.name = get_string(optarg_av, &rv); 123*99ebb4caSwyllys if (plc.name == NULL) { 124*99ebb4caSwyllys (void) fprintf(stderr, 125*99ebb4caSwyllys gettext("Error policy name.\n")); 126*99ebb4caSwyllys } 127*99ebb4caSwyllys break; 128*99ebb4caSwyllys case 'd': 129*99ebb4caSwyllys plc.ignore_date = get_boolean(optarg_av); 130*99ebb4caSwyllys if (plc.ignore_date == -1) { 131*99ebb4caSwyllys (void) fprintf(stderr, 132*99ebb4caSwyllys gettext("Error boolean input.\n")); 133*99ebb4caSwyllys rv = KC_ERR_USAGE; 134*99ebb4caSwyllys } else { 135*99ebb4caSwyllys flags |= KC_IGNORE_DATE; 136*99ebb4caSwyllys } 137*99ebb4caSwyllys break; 138*99ebb4caSwyllys case 'e': 139*99ebb4caSwyllys plc.ignore_unknown_ekus = 140*99ebb4caSwyllys get_boolean(optarg_av); 141*99ebb4caSwyllys if (plc.ignore_unknown_ekus == -1) { 142*99ebb4caSwyllys (void) fprintf(stderr, 143*99ebb4caSwyllys gettext("Error boolean input.\n")); 144*99ebb4caSwyllys rv = KC_ERR_USAGE; 145*99ebb4caSwyllys } else { 146*99ebb4caSwyllys flags |= KC_IGNORE_UNKNOWN_EKUS; 147*99ebb4caSwyllys } 148*99ebb4caSwyllys break; 149*99ebb4caSwyllys case 'a': 150*99ebb4caSwyllys plc.ignore_trust_anchor = 151*99ebb4caSwyllys get_boolean(optarg_av); 152*99ebb4caSwyllys if (plc.ignore_trust_anchor == -1) { 153*99ebb4caSwyllys (void) fprintf(stderr, 154*99ebb4caSwyllys gettext("Error boolean input.\n")); 155*99ebb4caSwyllys rv = KC_ERR_USAGE; 156*99ebb4caSwyllys } else { 157*99ebb4caSwyllys flags |= KC_IGNORE_TRUST_ANCHOR; 158*99ebb4caSwyllys } 159*99ebb4caSwyllys break; 160*99ebb4caSwyllys case 'v': 161*99ebb4caSwyllys plc.validity_adjusttime = 162*99ebb4caSwyllys get_string(optarg_av, &rv); 163*99ebb4caSwyllys if (plc.validity_adjusttime == NULL) { 164*99ebb4caSwyllys (void) fprintf(stderr, 165*99ebb4caSwyllys gettext("Error time input.\n")); 166*99ebb4caSwyllys } else { 167*99ebb4caSwyllys uint32_t adj; 168*99ebb4caSwyllys /* for syntax checking */ 169*99ebb4caSwyllys if (str2lifetime( 170*99ebb4caSwyllys plc.validity_adjusttime, 171*99ebb4caSwyllys &adj) < 0) { 172*99ebb4caSwyllys (void) fprintf(stderr, 173*99ebb4caSwyllys gettext("Error time " 174*99ebb4caSwyllys "input.\n")); 175*99ebb4caSwyllys rv = KC_ERR_USAGE; 176*99ebb4caSwyllys } else { 177*99ebb4caSwyllys flags |= KC_VALIDITY_ADJUSTTIME; 178*99ebb4caSwyllys } 179*99ebb4caSwyllys } 180*99ebb4caSwyllys break; 181*99ebb4caSwyllys case 't': 182*99ebb4caSwyllys plc.ta_name = get_string(optarg_av, &rv); 183*99ebb4caSwyllys if (plc.ta_name == NULL) { 184*99ebb4caSwyllys (void) fprintf(stderr, 185*99ebb4caSwyllys gettext("Error name input.\n")); 186*99ebb4caSwyllys } else { 187*99ebb4caSwyllys KMF_X509_NAME taDN; 188*99ebb4caSwyllys /* for syntax checking */ 189*99ebb4caSwyllys if (KMF_DNParser(plc.ta_name, 190*99ebb4caSwyllys &taDN) != KMF_OK) { 191*99ebb4caSwyllys (void) fprintf(stderr, 192*99ebb4caSwyllys gettext("Error name " 193*99ebb4caSwyllys "input.\n")); 194*99ebb4caSwyllys rv = KC_ERR_USAGE; 195*99ebb4caSwyllys } else { 196*99ebb4caSwyllys KMF_FreeDN(&taDN); 197*99ebb4caSwyllys flags |= KC_TA_NAME; 198*99ebb4caSwyllys } 199*99ebb4caSwyllys } 200*99ebb4caSwyllys break; 201*99ebb4caSwyllys case 's': 202*99ebb4caSwyllys plc.ta_serial = get_string(optarg_av, &rv); 203*99ebb4caSwyllys if (plc.ta_serial == NULL) { 204*99ebb4caSwyllys (void) fprintf(stderr, 205*99ebb4caSwyllys gettext("Error serial input.\n")); 206*99ebb4caSwyllys } else { 207*99ebb4caSwyllys uchar_t *bytes = NULL; 208*99ebb4caSwyllys size_t bytelen; 209*99ebb4caSwyllys 210*99ebb4caSwyllys ret = KMF_HexString2Bytes( 211*99ebb4caSwyllys (uchar_t *)plc.ta_serial, 212*99ebb4caSwyllys &bytes, &bytelen); 213*99ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 214*99ebb4caSwyllys (void) fprintf(stderr, 215*99ebb4caSwyllys gettext("serial number " 216*99ebb4caSwyllys "must be specified as a " 217*99ebb4caSwyllys "hex number " 218*99ebb4caSwyllys "(ex: 0x0102030405" 219*99ebb4caSwyllys "ffeeddee)\n")); 220*99ebb4caSwyllys rv = KC_ERR_USAGE; 221*99ebb4caSwyllys break; 222*99ebb4caSwyllys } 223*99ebb4caSwyllys if (bytes != NULL) 224*99ebb4caSwyllys free(bytes); 225*99ebb4caSwyllys flags |= KC_TA_SERIAL; 226*99ebb4caSwyllys } 227*99ebb4caSwyllys break; 228*99ebb4caSwyllys case 'o': 229*99ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI = 230*99ebb4caSwyllys get_string(optarg_av, &rv); 231*99ebb4caSwyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) { 232*99ebb4caSwyllys (void) fprintf(stderr, 233*99ebb4caSwyllys gettext("Error responder " 234*99ebb4caSwyllys "input.\n")); 235*99ebb4caSwyllys } else { 236*99ebb4caSwyllys flags |= KC_OCSP_RESPONDER_URI; 237*99ebb4caSwyllys ocsp_set_attr++; 238*99ebb4caSwyllys } 239*99ebb4caSwyllys break; 240*99ebb4caSwyllys case 'P': 241*99ebb4caSwyllys plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv); 242*99ebb4caSwyllys if (plc.VAL_OCSP_PROXY == NULL) { 243*99ebb4caSwyllys (void) fprintf(stderr, 244*99ebb4caSwyllys gettext("Error proxy input.\n")); 245*99ebb4caSwyllys } else { 246*99ebb4caSwyllys flags |= KC_OCSP_PROXY; 247*99ebb4caSwyllys ocsp_set_attr++; 248*99ebb4caSwyllys } 249*99ebb4caSwyllys break; 250*99ebb4caSwyllys case 'r': 251*99ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT = 252*99ebb4caSwyllys get_boolean(optarg_av); 253*99ebb4caSwyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) { 254*99ebb4caSwyllys (void) fprintf(stderr, 255*99ebb4caSwyllys gettext("Error boolean input.\n")); 256*99ebb4caSwyllys rv = KC_ERR_USAGE; 257*99ebb4caSwyllys } else { 258*99ebb4caSwyllys flags |= KC_OCSP_URI_FROM_CERT; 259*99ebb4caSwyllys ocsp_set_attr++; 260*99ebb4caSwyllys } 261*99ebb4caSwyllys break; 262*99ebb4caSwyllys case 'T': 263*99ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME = 264*99ebb4caSwyllys get_string(optarg_av, &rv); 265*99ebb4caSwyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { 266*99ebb4caSwyllys (void) fprintf(stderr, 267*99ebb4caSwyllys gettext("Error time input.\n")); 268*99ebb4caSwyllys } else { 269*99ebb4caSwyllys uint32_t adj; 270*99ebb4caSwyllys /* for syntax checking */ 271*99ebb4caSwyllys if (str2lifetime( 272*99ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME, 273*99ebb4caSwyllys &adj) < 0) { 274*99ebb4caSwyllys (void) fprintf(stderr, 275*99ebb4caSwyllys gettext("Error time " 276*99ebb4caSwyllys "input.\n")); 277*99ebb4caSwyllys rv = KC_ERR_USAGE; 278*99ebb4caSwyllys } else { 279*99ebb4caSwyllys flags |= KC_OCSP_RESP_LIFETIME; 280*99ebb4caSwyllys ocsp_set_attr++; 281*99ebb4caSwyllys } 282*99ebb4caSwyllys } 283*99ebb4caSwyllys break; 284*99ebb4caSwyllys case 'R': 285*99ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN = 286*99ebb4caSwyllys get_boolean(optarg_av); 287*99ebb4caSwyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { 288*99ebb4caSwyllys (void) fprintf(stderr, 289*99ebb4caSwyllys gettext("Error boolean input.\n")); 290*99ebb4caSwyllys rv = KC_ERR_USAGE; 291*99ebb4caSwyllys } else { 292*99ebb4caSwyllys flags |= KC_OCSP_IGNORE_RESP_SIGN; 293*99ebb4caSwyllys ocsp_set_attr++; 294*99ebb4caSwyllys } 295*99ebb4caSwyllys break; 296*99ebb4caSwyllys case 'n': 297*99ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME = 298*99ebb4caSwyllys get_string(optarg_av, &rv); 299*99ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { 300*99ebb4caSwyllys (void) fprintf(stderr, 301*99ebb4caSwyllys gettext("Error name input.\n")); 302*99ebb4caSwyllys } else { 303*99ebb4caSwyllys KMF_X509_NAME respDN; 304*99ebb4caSwyllys /* for syntax checking */ 305*99ebb4caSwyllys if (KMF_DNParser( 306*99ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME, 307*99ebb4caSwyllys &respDN) != KMF_OK) { 308*99ebb4caSwyllys (void) fprintf(stderr, 309*99ebb4caSwyllys gettext("Error name " 310*99ebb4caSwyllys "input.\n")); 311*99ebb4caSwyllys rv = KC_ERR_USAGE; 312*99ebb4caSwyllys } else { 313*99ebb4caSwyllys KMF_FreeDN(&respDN); 314*99ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_NAME; 315*99ebb4caSwyllys ocsp_set_attr++; 316*99ebb4caSwyllys } 317*99ebb4caSwyllys } 318*99ebb4caSwyllys break; 319*99ebb4caSwyllys case 'A': 320*99ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL = 321*99ebb4caSwyllys get_string(optarg_av, &rv); 322*99ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { 323*99ebb4caSwyllys (void) fprintf(stderr, 324*99ebb4caSwyllys gettext("Error serial input.\n")); 325*99ebb4caSwyllys } else { 326*99ebb4caSwyllys uchar_t *bytes = NULL; 327*99ebb4caSwyllys size_t bytelen; 328*99ebb4caSwyllys 329*99ebb4caSwyllys ret = KMF_HexString2Bytes((uchar_t *) 330*99ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL, 331*99ebb4caSwyllys &bytes, &bytelen); 332*99ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 333*99ebb4caSwyllys (void) fprintf(stderr, 334*99ebb4caSwyllys gettext("serial number " 335*99ebb4caSwyllys "must be specified as a " 336*99ebb4caSwyllys "hex number " 337*99ebb4caSwyllys "(ex: 0x0102030405" 338*99ebb4caSwyllys "ffeeddee)\n")); 339*99ebb4caSwyllys rv = KC_ERR_USAGE; 340*99ebb4caSwyllys break; 341*99ebb4caSwyllys } 342*99ebb4caSwyllys if (bytes != NULL) 343*99ebb4caSwyllys free(bytes); 344*99ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_SERIAL; 345*99ebb4caSwyllys ocsp_set_attr++; 346*99ebb4caSwyllys } 347*99ebb4caSwyllys break; 348*99ebb4caSwyllys case 'y': 349*99ebb4caSwyllys ocsp_none_opt = get_boolean(optarg_av); 350*99ebb4caSwyllys if (ocsp_none_opt == -1) { 351*99ebb4caSwyllys (void) fprintf(stderr, 352*99ebb4caSwyllys gettext("Error boolean input.\n")); 353*99ebb4caSwyllys rv = KC_ERR_USAGE; 354*99ebb4caSwyllys } else { 355*99ebb4caSwyllys flags |= KC_OCSP_NONE; 356*99ebb4caSwyllys } 357*99ebb4caSwyllys break; 358*99ebb4caSwyllys case 'c': 359*99ebb4caSwyllys plc.VAL_CRL_BASEFILENAME = 360*99ebb4caSwyllys get_string(optarg_av, &rv); 361*99ebb4caSwyllys if (plc.VAL_CRL_BASEFILENAME == NULL) { 362*99ebb4caSwyllys (void) fprintf(stderr, gettext( 363*99ebb4caSwyllys "Error basefilename input.\n")); 364*99ebb4caSwyllys } else { 365*99ebb4caSwyllys flags |= KC_CRL_BASEFILENAME; 366*99ebb4caSwyllys crl_set_attr++; 367*99ebb4caSwyllys } 368*99ebb4caSwyllys break; 369*99ebb4caSwyllys case 'I': 370*99ebb4caSwyllys plc.VAL_CRL_DIRECTORY = 371*99ebb4caSwyllys get_string(optarg_av, &rv); 372*99ebb4caSwyllys if (plc.VAL_CRL_DIRECTORY == NULL) { 373*99ebb4caSwyllys (void) fprintf(stderr, 374*99ebb4caSwyllys gettext("Error boolean input.\n")); 375*99ebb4caSwyllys } else { 376*99ebb4caSwyllys flags |= KC_CRL_DIRECTORY; 377*99ebb4caSwyllys crl_set_attr++; 378*99ebb4caSwyllys } 379*99ebb4caSwyllys break; 380*99ebb4caSwyllys case 'g': 381*99ebb4caSwyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av); 382*99ebb4caSwyllys if (plc.VAL_CRL_GET_URI == -1) { 383*99ebb4caSwyllys (void) fprintf(stderr, 384*99ebb4caSwyllys gettext("Error boolean input.\n")); 385*99ebb4caSwyllys rv = KC_ERR_USAGE; 386*99ebb4caSwyllys } else { 387*99ebb4caSwyllys flags |= KC_CRL_GET_URI; 388*99ebb4caSwyllys crl_set_attr++; 389*99ebb4caSwyllys } 390*99ebb4caSwyllys break; 391*99ebb4caSwyllys case 'X': 392*99ebb4caSwyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); 393*99ebb4caSwyllys if (plc.VAL_CRL_PROXY == NULL) { 394*99ebb4caSwyllys (void) fprintf(stderr, 395*99ebb4caSwyllys gettext("Error proxy input.\n")); 396*99ebb4caSwyllys } else { 397*99ebb4caSwyllys flags |= KC_CRL_PROXY; 398*99ebb4caSwyllys crl_set_attr++; 399*99ebb4caSwyllys } 400*99ebb4caSwyllys break; 401*99ebb4caSwyllys case 'S': 402*99ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN = 403*99ebb4caSwyllys get_boolean(optarg_av); 404*99ebb4caSwyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) { 405*99ebb4caSwyllys (void) fprintf(stderr, 406*99ebb4caSwyllys gettext("Error boolean input.\n")); 407*99ebb4caSwyllys rv = KC_ERR_USAGE; 408*99ebb4caSwyllys } else { 409*99ebb4caSwyllys flags |= KC_CRL_IGNORE_SIGN; 410*99ebb4caSwyllys crl_set_attr++; 411*99ebb4caSwyllys } 412*99ebb4caSwyllys break; 413*99ebb4caSwyllys case 'D': 414*99ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE = 415*99ebb4caSwyllys get_boolean(optarg_av); 416*99ebb4caSwyllys if (plc.VAL_CRL_IGNORE_DATE == -1) { 417*99ebb4caSwyllys (void) fprintf(stderr, 418*99ebb4caSwyllys gettext("Error boolean input.\n")); 419*99ebb4caSwyllys rv = KC_ERR_USAGE; 420*99ebb4caSwyllys } else { 421*99ebb4caSwyllys flags |= KC_CRL_IGNORE_DATE; 422*99ebb4caSwyllys crl_set_attr++; 423*99ebb4caSwyllys } 424*99ebb4caSwyllys break; 425*99ebb4caSwyllys case 'z': 426*99ebb4caSwyllys crl_none_opt = get_boolean(optarg_av); 427*99ebb4caSwyllys if (crl_none_opt == -1) { 428*99ebb4caSwyllys (void) fprintf(stderr, 429*99ebb4caSwyllys gettext("Error boolean input.\n")); 430*99ebb4caSwyllys rv = KC_ERR_USAGE; 431*99ebb4caSwyllys } else { 432*99ebb4caSwyllys flags |= KC_CRL_NONE; 433*99ebb4caSwyllys } 434*99ebb4caSwyllys break; 435*99ebb4caSwyllys case 'u': 436*99ebb4caSwyllys plc.ku_bits = parseKUlist(optarg_av); 437*99ebb4caSwyllys if (plc.ku_bits == 0) { 438*99ebb4caSwyllys (void) fprintf(stderr, gettext( 439*99ebb4caSwyllys "Error keyusage input.\n")); 440*99ebb4caSwyllys rv = KC_ERR_USAGE; 441*99ebb4caSwyllys } else { 442*99ebb4caSwyllys flags |= KC_KEYUSAGE; 443*99ebb4caSwyllys } 444*99ebb4caSwyllys break; 445*99ebb4caSwyllys case 'Y': 446*99ebb4caSwyllys ku_none_opt = get_boolean(optarg_av); 447*99ebb4caSwyllys if (ku_none_opt == -1) { 448*99ebb4caSwyllys (void) fprintf(stderr, 449*99ebb4caSwyllys gettext("Error boolean input.\n")); 450*99ebb4caSwyllys rv = KC_ERR_USAGE; 451*99ebb4caSwyllys } else { 452*99ebb4caSwyllys flags |= KC_KEYUSAGE_NONE; 453*99ebb4caSwyllys } 454*99ebb4caSwyllys break; 455*99ebb4caSwyllys case 'E': 456*99ebb4caSwyllys if (parseEKUNames(optarg_av, &plc) != 0) { 457*99ebb4caSwyllys (void) fprintf(stderr, 458*99ebb4caSwyllys gettext("Error EKU input.\n")); 459*99ebb4caSwyllys rv = KC_ERR_USAGE; 460*99ebb4caSwyllys } else { 461*99ebb4caSwyllys flags |= KC_EKUS; 462*99ebb4caSwyllys } 463*99ebb4caSwyllys break; 464*99ebb4caSwyllys case 'O': 465*99ebb4caSwyllys if (parseEKUOIDs(optarg_av, &plc) != 0) { 466*99ebb4caSwyllys (void) fprintf(stderr, 467*99ebb4caSwyllys gettext("Error EKU OID input.\n")); 468*99ebb4caSwyllys rv = KC_ERR_USAGE; 469*99ebb4caSwyllys } else { 470*99ebb4caSwyllys flags |= KC_EKUS; 471*99ebb4caSwyllys } 472*99ebb4caSwyllys break; 473*99ebb4caSwyllys case 'Z': 474*99ebb4caSwyllys eku_none_opt = get_boolean(optarg_av); 475*99ebb4caSwyllys if (eku_none_opt == -1) { 476*99ebb4caSwyllys (void) fprintf(stderr, 477*99ebb4caSwyllys gettext("Error boolean input.\n")); 478*99ebb4caSwyllys rv = KC_ERR_USAGE; 479*99ebb4caSwyllys } else { 480*99ebb4caSwyllys flags |= KC_EKUS_NONE; 481*99ebb4caSwyllys } 482*99ebb4caSwyllys break; 483*99ebb4caSwyllys default: 484*99ebb4caSwyllys (void) fprintf(stderr, 485*99ebb4caSwyllys gettext("Error input option.\n")); 486*99ebb4caSwyllys rv = KC_ERR_USAGE; 487*99ebb4caSwyllys break; 488*99ebb4caSwyllys } 489*99ebb4caSwyllys if (rv != KC_OK) 490*99ebb4caSwyllys goto out; 491*99ebb4caSwyllys } 492*99ebb4caSwyllys 493*99ebb4caSwyllys /* No additional args allowed. */ 494*99ebb4caSwyllys argc -= optind_av; 495*99ebb4caSwyllys if (argc) { 496*99ebb4caSwyllys (void) fprintf(stderr, 497*99ebb4caSwyllys gettext("Error input option\n")); 498*99ebb4caSwyllys rv = KC_ERR_USAGE; 499*99ebb4caSwyllys goto out; 500*99ebb4caSwyllys } 501*99ebb4caSwyllys 502*99ebb4caSwyllys if (filename == NULL) { 503*99ebb4caSwyllys filename = strdup(KMF_DEFAULT_POLICY_FILE); 504*99ebb4caSwyllys if (filename == NULL) { 505*99ebb4caSwyllys rv = KC_ERR_MEMORY; 506*99ebb4caSwyllys goto out; 507*99ebb4caSwyllys } 508*99ebb4caSwyllys } 509*99ebb4caSwyllys 510*99ebb4caSwyllys /* 511*99ebb4caSwyllys * Must have a policy name. The policy name can not be default 512*99ebb4caSwyllys * if using the default policy file. 513*99ebb4caSwyllys */ 514*99ebb4caSwyllys if (plc.name == NULL) { 515*99ebb4caSwyllys (void) fprintf(stderr, 516*99ebb4caSwyllys gettext("You must specify a policy name.\n")); 517*99ebb4caSwyllys rv = KC_ERR_USAGE; 518*99ebb4caSwyllys goto out; 519*99ebb4caSwyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && 520*99ebb4caSwyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { 521*99ebb4caSwyllys (void) fprintf(stderr, 522*99ebb4caSwyllys gettext("Can not modify the default policy in the default " 523*99ebb4caSwyllys "policy file.\n")); 524*99ebb4caSwyllys rv = KC_ERR_USAGE; 525*99ebb4caSwyllys goto out; 526*99ebb4caSwyllys } 527*99ebb4caSwyllys 528*99ebb4caSwyllys /* Check the access permission of the policy DB */ 529*99ebb4caSwyllys if (access(filename, W_OK) < 0) { 530*99ebb4caSwyllys int err = errno; 531*99ebb4caSwyllys (void) fprintf(stderr, 532*99ebb4caSwyllys gettext("Cannot access \"%s\" for modify - %s\n"), 533*99ebb4caSwyllys filename, strerror(err)); 534*99ebb4caSwyllys rv = KC_ERR_ACCESS; 535*99ebb4caSwyllys goto out; 536*99ebb4caSwyllys } 537*99ebb4caSwyllys 538*99ebb4caSwyllys /* Try to load the named policy from the DB */ 539*99ebb4caSwyllys ret = KMF_GetPolicy(filename, plc.name, &oplc); 540*99ebb4caSwyllys if (ret != KMF_OK) { 541*99ebb4caSwyllys (void) fprintf(stderr, 542*99ebb4caSwyllys gettext("Error loading policy \"%s\" from %s\n"), filename, 543*99ebb4caSwyllys plc.name); 544*99ebb4caSwyllys return (KC_ERR_FIND_POLICY); 545*99ebb4caSwyllys } 546*99ebb4caSwyllys 547*99ebb4caSwyllys /* Update the general policy attributes. */ 548*99ebb4caSwyllys if (flags & KC_IGNORE_DATE) 549*99ebb4caSwyllys oplc.ignore_date = plc.ignore_date; 550*99ebb4caSwyllys 551*99ebb4caSwyllys if (flags & KC_IGNORE_UNKNOWN_EKUS) 552*99ebb4caSwyllys oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus; 553*99ebb4caSwyllys 554*99ebb4caSwyllys if (flags & KC_IGNORE_TRUST_ANCHOR) 555*99ebb4caSwyllys oplc.ignore_trust_anchor = plc.ignore_trust_anchor; 556*99ebb4caSwyllys 557*99ebb4caSwyllys if (flags & KC_VALIDITY_ADJUSTTIME) { 558*99ebb4caSwyllys if (oplc.validity_adjusttime) 559*99ebb4caSwyllys free(oplc.validity_adjusttime); 560*99ebb4caSwyllys oplc.validity_adjusttime = 561*99ebb4caSwyllys plc.validity_adjusttime; 562*99ebb4caSwyllys } 563*99ebb4caSwyllys 564*99ebb4caSwyllys if (flags & KC_TA_NAME) { 565*99ebb4caSwyllys if (oplc.ta_name) 566*99ebb4caSwyllys free(oplc.ta_name); 567*99ebb4caSwyllys oplc.ta_name = plc.ta_name; 568*99ebb4caSwyllys } 569*99ebb4caSwyllys if (flags & KC_TA_SERIAL) { 570*99ebb4caSwyllys if (oplc.ta_serial) 571*99ebb4caSwyllys free(oplc.ta_serial); 572*99ebb4caSwyllys oplc.ta_serial = plc.ta_serial; 573*99ebb4caSwyllys } 574*99ebb4caSwyllys 575*99ebb4caSwyllys /* Update the OCSP policy */ 576*99ebb4caSwyllys if (ocsp_none_opt == B_TRUE) { 577*99ebb4caSwyllys if (ocsp_set_attr > 0) { 578*99ebb4caSwyllys (void) fprintf(stderr, 579*99ebb4caSwyllys gettext("Can not set ocsp-none=true and other " 580*99ebb4caSwyllys "OCSP attributes at the same time.\n")); 581*99ebb4caSwyllys rv = KC_ERR_USAGE; 582*99ebb4caSwyllys goto out; 583*99ebb4caSwyllys } 584*99ebb4caSwyllys 585*99ebb4caSwyllys /* 586*99ebb4caSwyllys * If the original policy does not have OCSP checking, 587*99ebb4caSwyllys * then we do not need to do anything. If the original 588*99ebb4caSwyllys * policy has the OCSP checking, then we need to release the 589*99ebb4caSwyllys * space of OCSP attributes and turn the OCSP checking off. 590*99ebb4caSwyllys */ 591*99ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) { 592*99ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.responderURI) { 593*99ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.responderURI); 594*99ebb4caSwyllys oplc.VAL_OCSP_BASIC.responderURI = NULL; 595*99ebb4caSwyllys } 596*99ebb4caSwyllys 597*99ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.proxy) { 598*99ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.proxy); 599*99ebb4caSwyllys oplc.VAL_OCSP_BASIC.proxy = NULL; 600*99ebb4caSwyllys } 601*99ebb4caSwyllys 602*99ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.response_lifetime) { 603*99ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.response_lifetime); 604*99ebb4caSwyllys oplc.VAL_OCSP_BASIC.response_lifetime = NULL; 605*99ebb4caSwyllys } 606*99ebb4caSwyllys 607*99ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 608*99ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.name); 609*99ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.name = NULL; 610*99ebb4caSwyllys } 611*99ebb4caSwyllys 612*99ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 613*99ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.serial); 614*99ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.serial = NULL; 615*99ebb4caSwyllys } 616*99ebb4caSwyllys 617*99ebb4caSwyllys /* Turn off the OCSP checking */ 618*99ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP; 619*99ebb4caSwyllys } 620*99ebb4caSwyllys 621*99ebb4caSwyllys } else { 622*99ebb4caSwyllys /* 623*99ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 624*99ebb4caSwyllys * then we only need to do the modification if there is at 625*99ebb4caSwyllys * least one OCSP attribute is specified. 626*99ebb4caSwyllys */ 627*99ebb4caSwyllys if (ocsp_set_attr > 0) { 628*99ebb4caSwyllys if (flags & KC_OCSP_RESPONDER_URI) { 629*99ebb4caSwyllys if (oplc.VAL_OCSP_RESPONDER_URI) 630*99ebb4caSwyllys free(oplc.VAL_OCSP_RESPONDER_URI); 631*99ebb4caSwyllys oplc.VAL_OCSP_RESPONDER_URI = 632*99ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI; 633*99ebb4caSwyllys } 634*99ebb4caSwyllys 635*99ebb4caSwyllys if (flags & KC_OCSP_PROXY) { 636*99ebb4caSwyllys if (oplc.VAL_OCSP_PROXY) 637*99ebb4caSwyllys free(oplc.VAL_OCSP_PROXY); 638*99ebb4caSwyllys oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY; 639*99ebb4caSwyllys } 640*99ebb4caSwyllys 641*99ebb4caSwyllys if (flags & KC_OCSP_URI_FROM_CERT) 642*99ebb4caSwyllys oplc.VAL_OCSP_URI_FROM_CERT = 643*99ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT; 644*99ebb4caSwyllys 645*99ebb4caSwyllys if (flags & KC_OCSP_RESP_LIFETIME) { 646*99ebb4caSwyllys if (oplc.VAL_OCSP_RESP_LIFETIME) 647*99ebb4caSwyllys free(oplc.VAL_OCSP_RESP_LIFETIME); 648*99ebb4caSwyllys oplc.VAL_OCSP_RESP_LIFETIME = 649*99ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME; 650*99ebb4caSwyllys } 651*99ebb4caSwyllys 652*99ebb4caSwyllys if (flags & KC_OCSP_IGNORE_RESP_SIGN) 653*99ebb4caSwyllys oplc.VAL_OCSP_IGNORE_RESP_SIGN = 654*99ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN; 655*99ebb4caSwyllys 656*99ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 657*99ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME) 658*99ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_NAME); 659*99ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_NAME = 660*99ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME; 661*99ebb4caSwyllys } 662*99ebb4caSwyllys 663*99ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 664*99ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_SERIAL) 665*99ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_SERIAL); 666*99ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL = 667*99ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL; 668*99ebb4caSwyllys } 669*99ebb4caSwyllys 670*99ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL && 671*99ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL) 672*99ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_TRUE; 673*99ebb4caSwyllys else 674*99ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_FALSE; 675*99ebb4caSwyllys 676*99ebb4caSwyllys /* Turn on the OCSP checking */ 677*99ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_OCSP; 678*99ebb4caSwyllys } 679*99ebb4caSwyllys } 680*99ebb4caSwyllys 681*99ebb4caSwyllys /* Update the CRL policy */ 682*99ebb4caSwyllys if (crl_none_opt == B_TRUE) { 683*99ebb4caSwyllys if (crl_set_attr > 0) { 684*99ebb4caSwyllys (void) fprintf(stderr, 685*99ebb4caSwyllys gettext("Can not set crl-none=true and other CRL " 686*99ebb4caSwyllys "attributes at the same time.\n")); 687*99ebb4caSwyllys rv = KC_ERR_USAGE; 688*99ebb4caSwyllys goto out; 689*99ebb4caSwyllys } 690*99ebb4caSwyllys 691*99ebb4caSwyllys /* 692*99ebb4caSwyllys * If the original policy does not have CRL checking, 693*99ebb4caSwyllys * then we do not need to do anything. If the original 694*99ebb4caSwyllys * policy has the CRL checking, then we need to release the 695*99ebb4caSwyllys * space of CRL attributes and turn the CRL checking off. 696*99ebb4caSwyllys */ 697*99ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) { 698*99ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) { 699*99ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 700*99ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = NULL; 701*99ebb4caSwyllys } 702*99ebb4caSwyllys 703*99ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) { 704*99ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 705*99ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = NULL; 706*99ebb4caSwyllys } 707*99ebb4caSwyllys 708*99ebb4caSwyllys if (oplc.VAL_CRL_PROXY) { 709*99ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 710*99ebb4caSwyllys oplc.VAL_CRL_PROXY = NULL; 711*99ebb4caSwyllys } 712*99ebb4caSwyllys 713*99ebb4caSwyllys /* Turn off the CRL checking */ 714*99ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL; 715*99ebb4caSwyllys } 716*99ebb4caSwyllys } else { 717*99ebb4caSwyllys /* 718*99ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 719*99ebb4caSwyllys * then we only need to do the modification if there is at 720*99ebb4caSwyllys * least one CRL attribute is specified. 721*99ebb4caSwyllys */ 722*99ebb4caSwyllys if (crl_set_attr > 0) { 723*99ebb4caSwyllys if (flags & KC_CRL_BASEFILENAME) { 724*99ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) 725*99ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 726*99ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = 727*99ebb4caSwyllys plc.VAL_CRL_BASEFILENAME; 728*99ebb4caSwyllys } 729*99ebb4caSwyllys 730*99ebb4caSwyllys if (flags & KC_CRL_DIRECTORY) { 731*99ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) 732*99ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 733*99ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY; 734*99ebb4caSwyllys } 735*99ebb4caSwyllys 736*99ebb4caSwyllys if (flags & KC_CRL_GET_URI) { 737*99ebb4caSwyllys oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI; 738*99ebb4caSwyllys } 739*99ebb4caSwyllys 740*99ebb4caSwyllys if (flags & KC_CRL_PROXY) { 741*99ebb4caSwyllys if (oplc.VAL_CRL_PROXY) 742*99ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 743*99ebb4caSwyllys oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY; 744*99ebb4caSwyllys } 745*99ebb4caSwyllys 746*99ebb4caSwyllys if (flags & KC_CRL_IGNORE_SIGN) { 747*99ebb4caSwyllys oplc.VAL_CRL_IGNORE_SIGN = 748*99ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN; 749*99ebb4caSwyllys } 750*99ebb4caSwyllys 751*99ebb4caSwyllys if (flags & KC_CRL_IGNORE_DATE) { 752*99ebb4caSwyllys oplc.VAL_CRL_IGNORE_DATE = 753*99ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE; 754*99ebb4caSwyllys } 755*99ebb4caSwyllys 756*99ebb4caSwyllys /* Turn on the CRL checking */ 757*99ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_CRL; 758*99ebb4caSwyllys } 759*99ebb4caSwyllys } 760*99ebb4caSwyllys 761*99ebb4caSwyllys /* Update the Key Usage */ 762*99ebb4caSwyllys if (ku_none_opt == B_TRUE) { 763*99ebb4caSwyllys if (flags & KC_KEYUSAGE) { 764*99ebb4caSwyllys (void) fprintf(stderr, 765*99ebb4caSwyllys gettext("Can not set keyusage-none=true and " 766*99ebb4caSwyllys "modify the keyusage value at the same time.\n")); 767*99ebb4caSwyllys rv = KC_ERR_USAGE; 768*99ebb4caSwyllys goto out; 769*99ebb4caSwyllys } 770*99ebb4caSwyllys 771*99ebb4caSwyllys oplc.ku_bits = 0; 772*99ebb4caSwyllys } else { 773*99ebb4caSwyllys /* 774*99ebb4caSwyllys * If the "keyusage-none" option is not set or is set to 775*99ebb4caSwyllys * false, then we only need to do the modification if 776*99ebb4caSwyllys * the keyusage value is specified. 777*99ebb4caSwyllys */ 778*99ebb4caSwyllys if (flags & KC_KEYUSAGE) 779*99ebb4caSwyllys oplc.ku_bits = plc.ku_bits; 780*99ebb4caSwyllys } 781*99ebb4caSwyllys 782*99ebb4caSwyllys 783*99ebb4caSwyllys /* Update the Extended Key Usage */ 784*99ebb4caSwyllys if (eku_none_opt == B_TRUE) { 785*99ebb4caSwyllys if (flags & KC_EKUS) { 786*99ebb4caSwyllys (void) fprintf(stderr, 787*99ebb4caSwyllys gettext("Can not set eku-none=true and modify " 788*99ebb4caSwyllys "EKU values at the same time.\n")); 789*99ebb4caSwyllys rv = KC_ERR_USAGE; 790*99ebb4caSwyllys goto out; 791*99ebb4caSwyllys } 792*99ebb4caSwyllys 793*99ebb4caSwyllys /* Release current EKU list (if any) */ 794*99ebb4caSwyllys if (oplc.eku_set.eku_count > 0) { 795*99ebb4caSwyllys KMF_FreeEKUPolicy(&oplc.eku_set); 796*99ebb4caSwyllys oplc.eku_set.eku_count = 0; 797*99ebb4caSwyllys oplc.eku_set.ekulist = NULL; 798*99ebb4caSwyllys } 799*99ebb4caSwyllys } else { 800*99ebb4caSwyllys /* 801*99ebb4caSwyllys * If the "eku-none" option is not set or is set to false, 802*99ebb4caSwyllys * then we only need to do the modification if either 803*99ebb4caSwyllys * "ekuname" or "ekuoids" is specified. 804*99ebb4caSwyllys */ 805*99ebb4caSwyllys if (flags & KC_EKUS) { 806*99ebb4caSwyllys /* Release current EKU list (if any) */ 807*99ebb4caSwyllys KMF_FreeEKUPolicy(&oplc.eku_set); 808*99ebb4caSwyllys oplc.eku_set = plc.eku_set; 809*99ebb4caSwyllys } 810*99ebb4caSwyllys } 811*99ebb4caSwyllys 812*99ebb4caSwyllys /* Do a sanity check on the modified policy */ 813*99ebb4caSwyllys ret = KMF_VerifyPolicy(&oplc); 814*99ebb4caSwyllys if (ret != KMF_OK) { 815*99ebb4caSwyllys print_sanity_error(ret); 816*99ebb4caSwyllys rv = KC_ERR_VERIFY_POLICY; 817*99ebb4caSwyllys goto out; 818*99ebb4caSwyllys } 819*99ebb4caSwyllys 820*99ebb4caSwyllys /* The modify operation is a delete followed by an add */ 821*99ebb4caSwyllys ret = KMF_DeletePolicyFromDB(oplc.name, filename); 822*99ebb4caSwyllys if (ret != KMF_OK) { 823*99ebb4caSwyllys rv = KC_ERR_DELETE_POLICY; 824*99ebb4caSwyllys goto out; 825*99ebb4caSwyllys } 826*99ebb4caSwyllys 827*99ebb4caSwyllys /* 828*99ebb4caSwyllys * Now add the modified policy back to the DB. 829*99ebb4caSwyllys */ 830*99ebb4caSwyllys ret = KMF_AddPolicyToDB(&oplc, filename, B_FALSE); 831*99ebb4caSwyllys if (ret != KMF_OK) { 832*99ebb4caSwyllys (void) fprintf(stderr, 833*99ebb4caSwyllys gettext("Error adding policy to database: 0x%04x\n"), ret); 834*99ebb4caSwyllys rv = KC_ERR_ADD_POLICY; 835*99ebb4caSwyllys goto out; 836*99ebb4caSwyllys } 837*99ebb4caSwyllys 838*99ebb4caSwyllys out: 839*99ebb4caSwyllys if (filename != NULL) 840*99ebb4caSwyllys free(filename); 841*99ebb4caSwyllys 842*99ebb4caSwyllys KMF_FreePolicyRecord(&oplc); 843*99ebb4caSwyllys 844*99ebb4caSwyllys return (rv); 845*99ebb4caSwyllys } 846