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 * 21269e59f9SJan Pechanec * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 2299ebb4caSwyllys */ 2399ebb4caSwyllys 2499ebb4caSwyllys #include <stdio.h> 2599ebb4caSwyllys #include <strings.h> 2699ebb4caSwyllys #include <ctype.h> 2799ebb4caSwyllys #include <libgen.h> 2899ebb4caSwyllys #include <libintl.h> 2999ebb4caSwyllys #include <errno.h> 3099ebb4caSwyllys #include <kmfapiP.h> 3199ebb4caSwyllys #include <cryptoutil.h> 32431deaa0Shylee #include <sys/stat.h> 33431deaa0Shylee #include <sys/param.h> 3499ebb4caSwyllys #include "util.h" 3599ebb4caSwyllys 3699ebb4caSwyllys #define KC_IGNORE_DATE 0x0000001 3799ebb4caSwyllys #define KC_IGNORE_UNKNOWN_EKUS 0x0000002 3899ebb4caSwyllys #define KC_IGNORE_TRUST_ANCHOR 0x0000004 3999ebb4caSwyllys #define KC_VALIDITY_ADJUSTTIME 0x0000008 4099ebb4caSwyllys #define KC_TA_NAME 0x0000010 4199ebb4caSwyllys #define KC_TA_SERIAL 0x0000020 4299ebb4caSwyllys #define KC_OCSP_RESPONDER_URI 0x0000040 4399ebb4caSwyllys #define KC_OCSP_PROXY 0x0000080 4499ebb4caSwyllys #define KC_OCSP_URI_FROM_CERT 0x0000100 4599ebb4caSwyllys #define KC_OCSP_RESP_LIFETIME 0x0000200 4699ebb4caSwyllys #define KC_OCSP_IGNORE_RESP_SIGN 0x0000400 4799ebb4caSwyllys #define KC_OCSP_RESP_CERT_NAME 0x0000800 4899ebb4caSwyllys #define KC_OCSP_RESP_CERT_SERIAL 0x0001000 4999ebb4caSwyllys #define KC_OCSP_NONE 0x0002000 5099ebb4caSwyllys #define KC_CRL_BASEFILENAME 0x0004000 5199ebb4caSwyllys #define KC_CRL_DIRECTORY 0x0008000 5299ebb4caSwyllys #define KC_CRL_GET_URI 0x0010000 5399ebb4caSwyllys #define KC_CRL_PROXY 0x0020000 5499ebb4caSwyllys #define KC_CRL_IGNORE_SIGN 0x0040000 5599ebb4caSwyllys #define KC_CRL_IGNORE_DATE 0x0080000 5699ebb4caSwyllys #define KC_CRL_NONE 0x0100000 5799ebb4caSwyllys #define KC_KEYUSAGE 0x0200000 5899ebb4caSwyllys #define KC_KEYUSAGE_NONE 0x0400000 5999ebb4caSwyllys #define KC_EKUS 0x0800000 6099ebb4caSwyllys #define KC_EKUS_NONE 0x1000000 61269e59f9SJan Pechanec #define KC_MAPPER_OPTIONS 0x2000000 6299ebb4caSwyllys 63431deaa0Shylee static int err; /* To store errno which may be overwritten by gettext() */ 64431deaa0Shylee 65269e59f9SJan Pechanec #define UPDATE_IF_DIFFERENT(old, new) \ 66269e59f9SJan Pechanec if ((old != NULL && new != NULL && strcmp(old, new) != 0) || \ 67269e59f9SJan Pechanec (old == NULL && new != NULL)) { \ 68269e59f9SJan Pechanec if (old != NULL) \ 69269e59f9SJan Pechanec free(old); \ 70269e59f9SJan Pechanec old = new; \ 71269e59f9SJan Pechanec } 72431deaa0Shylee 7399ebb4caSwyllys int 74431deaa0Shylee kc_modify_policy(int argc, char *argv[]) 7599ebb4caSwyllys { 7699ebb4caSwyllys KMF_RETURN ret; 7799ebb4caSwyllys int rv = KC_OK; 7899ebb4caSwyllys int opt; 7999ebb4caSwyllys extern int optind_av; 8099ebb4caSwyllys extern char *optarg_av; 8199ebb4caSwyllys char *filename = NULL; 82269e59f9SJan Pechanec char *mapper_name = NULL; 83269e59f9SJan Pechanec char *mapper_dir = NULL; 84269e59f9SJan Pechanec char *mapper_pathname = NULL; 8599ebb4caSwyllys uint32_t flags = 0; 8699ebb4caSwyllys boolean_t ocsp_none_opt = B_FALSE; 8799ebb4caSwyllys boolean_t crl_none_opt = B_FALSE; 8899ebb4caSwyllys boolean_t ku_none_opt = B_FALSE; 8999ebb4caSwyllys boolean_t eku_none_opt = B_FALSE; 9099ebb4caSwyllys int ocsp_set_attr = 0; 9199ebb4caSwyllys int crl_set_attr = 0; 9299ebb4caSwyllys KMF_POLICY_RECORD oplc, plc; 9399ebb4caSwyllys 9499ebb4caSwyllys (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); 9599ebb4caSwyllys (void) memset(&oplc, 0, sizeof (KMF_POLICY_RECORD)); 9699ebb4caSwyllys 9799ebb4caSwyllys while ((opt = getopt_av(argc, argv, 9899ebb4caSwyllys "i:(dbfile)" 9999ebb4caSwyllys "p:(policy)" 10099ebb4caSwyllys "d:(ignore-date)" 10199ebb4caSwyllys "e:(ignore-unknown-eku)" 10299ebb4caSwyllys "a:(ignore-trust-anchor)" 10399ebb4caSwyllys "v:(validity-adjusttime)" 10499ebb4caSwyllys "t:(ta-name)" 10599ebb4caSwyllys "s:(ta-serial)" 10699ebb4caSwyllys "o:(ocsp-responder)" 10799ebb4caSwyllys "P:(ocsp-proxy)" 10899ebb4caSwyllys "r:(ocsp-use-cert-responder)" 10999ebb4caSwyllys "T:(ocsp-response-lifetime)" 11099ebb4caSwyllys "R:(ocsp-ignore-response-sign)" 11199ebb4caSwyllys "n:(ocsp-responder-cert-name)" 11299ebb4caSwyllys "A:(ocsp-responder-cert-serial)" 11399ebb4caSwyllys "y:(ocsp-none)" 11499ebb4caSwyllys "c:(crl-basefilename)" 11599ebb4caSwyllys "I:(crl-directory)" 11699ebb4caSwyllys "g:(crl-get-crl-uri)" 11799ebb4caSwyllys "X:(crl-proxy)" 11899ebb4caSwyllys "S:(crl-ignore-crl-sign)" 11999ebb4caSwyllys "D:(crl-ignore-crl-date)" 12099ebb4caSwyllys "z:(crl-none)" 12199ebb4caSwyllys "u:(keyusage)" 12299ebb4caSwyllys "Y:(keyusage-none)" 12399ebb4caSwyllys "E:(ekunames)" 12499ebb4caSwyllys "O:(ekuoids)" 125269e59f9SJan Pechanec "m:(mapper-name)" 126269e59f9SJan Pechanec "M:(mapper-directory)" 127269e59f9SJan Pechanec "Q:(mapper-pathname)" 128269e59f9SJan Pechanec "q:(mapper-options)" 12999ebb4caSwyllys "Z:(eku-none)")) != EOF) { 13099ebb4caSwyllys switch (opt) { 13199ebb4caSwyllys case 'i': 13299ebb4caSwyllys filename = get_string(optarg_av, &rv); 13399ebb4caSwyllys if (filename == NULL) { 13499ebb4caSwyllys (void) fprintf(stderr, 13599ebb4caSwyllys gettext("Error dbfile input.\n")); 13699ebb4caSwyllys } 13799ebb4caSwyllys break; 13899ebb4caSwyllys case 'p': 13999ebb4caSwyllys plc.name = get_string(optarg_av, &rv); 14099ebb4caSwyllys if (plc.name == NULL) { 14199ebb4caSwyllys (void) fprintf(stderr, 14299ebb4caSwyllys gettext("Error policy name.\n")); 14399ebb4caSwyllys } 14499ebb4caSwyllys break; 14599ebb4caSwyllys case 'd': 14699ebb4caSwyllys plc.ignore_date = get_boolean(optarg_av); 14799ebb4caSwyllys if (plc.ignore_date == -1) { 14899ebb4caSwyllys (void) fprintf(stderr, 14999ebb4caSwyllys gettext("Error boolean input.\n")); 15099ebb4caSwyllys rv = KC_ERR_USAGE; 15199ebb4caSwyllys } else { 15299ebb4caSwyllys flags |= KC_IGNORE_DATE; 15399ebb4caSwyllys } 15499ebb4caSwyllys break; 15599ebb4caSwyllys case 'e': 15699ebb4caSwyllys plc.ignore_unknown_ekus = 15799ebb4caSwyllys get_boolean(optarg_av); 15899ebb4caSwyllys if (plc.ignore_unknown_ekus == -1) { 15999ebb4caSwyllys (void) fprintf(stderr, 16099ebb4caSwyllys gettext("Error boolean input.\n")); 16199ebb4caSwyllys rv = KC_ERR_USAGE; 16299ebb4caSwyllys } else { 16399ebb4caSwyllys flags |= KC_IGNORE_UNKNOWN_EKUS; 16499ebb4caSwyllys } 16599ebb4caSwyllys break; 16699ebb4caSwyllys case 'a': 16799ebb4caSwyllys plc.ignore_trust_anchor = 16899ebb4caSwyllys get_boolean(optarg_av); 16999ebb4caSwyllys if (plc.ignore_trust_anchor == -1) { 17099ebb4caSwyllys (void) fprintf(stderr, 17199ebb4caSwyllys gettext("Error boolean input.\n")); 17299ebb4caSwyllys rv = KC_ERR_USAGE; 17399ebb4caSwyllys } else { 17499ebb4caSwyllys flags |= KC_IGNORE_TRUST_ANCHOR; 17599ebb4caSwyllys } 17699ebb4caSwyllys break; 17799ebb4caSwyllys case 'v': 17899ebb4caSwyllys plc.validity_adjusttime = 17999ebb4caSwyllys get_string(optarg_av, &rv); 18099ebb4caSwyllys if (plc.validity_adjusttime == NULL) { 18199ebb4caSwyllys (void) fprintf(stderr, 18299ebb4caSwyllys gettext("Error time input.\n")); 18399ebb4caSwyllys } else { 18499ebb4caSwyllys uint32_t adj; 18599ebb4caSwyllys /* for syntax checking */ 18699ebb4caSwyllys if (str2lifetime( 18799ebb4caSwyllys plc.validity_adjusttime, 18899ebb4caSwyllys &adj) < 0) { 18999ebb4caSwyllys (void) fprintf(stderr, 19099ebb4caSwyllys gettext("Error time " 19199ebb4caSwyllys "input.\n")); 19299ebb4caSwyllys rv = KC_ERR_USAGE; 19399ebb4caSwyllys } else { 19499ebb4caSwyllys flags |= KC_VALIDITY_ADJUSTTIME; 19599ebb4caSwyllys } 19699ebb4caSwyllys } 19799ebb4caSwyllys break; 19899ebb4caSwyllys case 't': 19999ebb4caSwyllys plc.ta_name = get_string(optarg_av, &rv); 20099ebb4caSwyllys if (plc.ta_name == NULL) { 20199ebb4caSwyllys (void) fprintf(stderr, 20299ebb4caSwyllys gettext("Error name input.\n")); 203*fc2613b0SWyllys Ingersoll } else if (strcasecmp(plc.ta_name, "search")) { 20499ebb4caSwyllys KMF_X509_NAME taDN; 20599ebb4caSwyllys /* for syntax checking */ 20630a5e8faSwyllys if (kmf_dn_parser(plc.ta_name, 20799ebb4caSwyllys &taDN) != KMF_OK) { 20899ebb4caSwyllys (void) fprintf(stderr, 20999ebb4caSwyllys gettext("Error name " 21099ebb4caSwyllys "input.\n")); 21199ebb4caSwyllys rv = KC_ERR_USAGE; 21299ebb4caSwyllys } else { 21330a5e8faSwyllys kmf_free_dn(&taDN); 21499ebb4caSwyllys flags |= KC_TA_NAME; 21599ebb4caSwyllys } 216*fc2613b0SWyllys Ingersoll } else { 217*fc2613b0SWyllys Ingersoll flags |= KC_TA_NAME; 21899ebb4caSwyllys } 21999ebb4caSwyllys break; 22099ebb4caSwyllys case 's': 22199ebb4caSwyllys plc.ta_serial = get_string(optarg_av, &rv); 22299ebb4caSwyllys if (plc.ta_serial == NULL) { 22399ebb4caSwyllys (void) fprintf(stderr, 22499ebb4caSwyllys gettext("Error serial input.\n")); 22599ebb4caSwyllys } else { 22699ebb4caSwyllys uchar_t *bytes = NULL; 22799ebb4caSwyllys size_t bytelen; 22899ebb4caSwyllys 22930a5e8faSwyllys ret = kmf_hexstr_to_bytes( 23099ebb4caSwyllys (uchar_t *)plc.ta_serial, 23199ebb4caSwyllys &bytes, &bytelen); 23299ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 23399ebb4caSwyllys (void) fprintf(stderr, 23499ebb4caSwyllys gettext("serial number " 23599ebb4caSwyllys "must be specified as a " 23699ebb4caSwyllys "hex number " 23799ebb4caSwyllys "(ex: 0x0102030405" 23899ebb4caSwyllys "ffeeddee)\n")); 23999ebb4caSwyllys rv = KC_ERR_USAGE; 24099ebb4caSwyllys break; 24199ebb4caSwyllys } 24299ebb4caSwyllys if (bytes != NULL) 24399ebb4caSwyllys free(bytes); 24499ebb4caSwyllys flags |= KC_TA_SERIAL; 24599ebb4caSwyllys } 24699ebb4caSwyllys break; 24799ebb4caSwyllys case 'o': 24899ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI = 24999ebb4caSwyllys get_string(optarg_av, &rv); 25099ebb4caSwyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) { 25199ebb4caSwyllys (void) fprintf(stderr, 25299ebb4caSwyllys gettext("Error responder " 25399ebb4caSwyllys "input.\n")); 25499ebb4caSwyllys } else { 25599ebb4caSwyllys flags |= KC_OCSP_RESPONDER_URI; 25699ebb4caSwyllys ocsp_set_attr++; 25799ebb4caSwyllys } 25899ebb4caSwyllys break; 25999ebb4caSwyllys case 'P': 26099ebb4caSwyllys plc.VAL_OCSP_PROXY = get_string(optarg_av, &rv); 26199ebb4caSwyllys if (plc.VAL_OCSP_PROXY == NULL) { 26299ebb4caSwyllys (void) fprintf(stderr, 26399ebb4caSwyllys gettext("Error proxy input.\n")); 26499ebb4caSwyllys } else { 26599ebb4caSwyllys flags |= KC_OCSP_PROXY; 26699ebb4caSwyllys ocsp_set_attr++; 26799ebb4caSwyllys } 26899ebb4caSwyllys break; 26999ebb4caSwyllys case 'r': 27099ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT = 27199ebb4caSwyllys get_boolean(optarg_av); 27299ebb4caSwyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) { 27399ebb4caSwyllys (void) fprintf(stderr, 27499ebb4caSwyllys gettext("Error boolean input.\n")); 27599ebb4caSwyllys rv = KC_ERR_USAGE; 27699ebb4caSwyllys } else { 27799ebb4caSwyllys flags |= KC_OCSP_URI_FROM_CERT; 27899ebb4caSwyllys ocsp_set_attr++; 27999ebb4caSwyllys } 28099ebb4caSwyllys break; 28199ebb4caSwyllys case 'T': 28299ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME = 28399ebb4caSwyllys get_string(optarg_av, &rv); 28499ebb4caSwyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { 28599ebb4caSwyllys (void) fprintf(stderr, 28699ebb4caSwyllys gettext("Error time input.\n")); 28799ebb4caSwyllys } else { 28899ebb4caSwyllys uint32_t adj; 28999ebb4caSwyllys /* for syntax checking */ 29099ebb4caSwyllys if (str2lifetime( 29199ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME, 29299ebb4caSwyllys &adj) < 0) { 29399ebb4caSwyllys (void) fprintf(stderr, 29499ebb4caSwyllys gettext("Error time " 29599ebb4caSwyllys "input.\n")); 29699ebb4caSwyllys rv = KC_ERR_USAGE; 29799ebb4caSwyllys } else { 29899ebb4caSwyllys flags |= KC_OCSP_RESP_LIFETIME; 29999ebb4caSwyllys ocsp_set_attr++; 30099ebb4caSwyllys } 30199ebb4caSwyllys } 30299ebb4caSwyllys break; 30399ebb4caSwyllys case 'R': 30499ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN = 30599ebb4caSwyllys get_boolean(optarg_av); 30699ebb4caSwyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { 30799ebb4caSwyllys (void) fprintf(stderr, 30899ebb4caSwyllys gettext("Error boolean input.\n")); 30999ebb4caSwyllys rv = KC_ERR_USAGE; 31099ebb4caSwyllys } else { 31199ebb4caSwyllys flags |= KC_OCSP_IGNORE_RESP_SIGN; 31299ebb4caSwyllys ocsp_set_attr++; 31399ebb4caSwyllys } 31499ebb4caSwyllys break; 31599ebb4caSwyllys case 'n': 31699ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME = 31799ebb4caSwyllys get_string(optarg_av, &rv); 31899ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { 31999ebb4caSwyllys (void) fprintf(stderr, 32099ebb4caSwyllys gettext("Error name input.\n")); 32199ebb4caSwyllys } else { 32299ebb4caSwyllys KMF_X509_NAME respDN; 32399ebb4caSwyllys /* for syntax checking */ 32430a5e8faSwyllys if (kmf_dn_parser( 32599ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME, 32699ebb4caSwyllys &respDN) != KMF_OK) { 32799ebb4caSwyllys (void) fprintf(stderr, 32899ebb4caSwyllys gettext("Error name " 32999ebb4caSwyllys "input.\n")); 33099ebb4caSwyllys rv = KC_ERR_USAGE; 33199ebb4caSwyllys } else { 33230a5e8faSwyllys kmf_free_dn(&respDN); 33399ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_NAME; 33499ebb4caSwyllys ocsp_set_attr++; 33599ebb4caSwyllys } 33699ebb4caSwyllys } 33799ebb4caSwyllys break; 33899ebb4caSwyllys case 'A': 33999ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL = 34099ebb4caSwyllys get_string(optarg_av, &rv); 34199ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { 34299ebb4caSwyllys (void) fprintf(stderr, 34399ebb4caSwyllys gettext("Error serial input.\n")); 34499ebb4caSwyllys } else { 34599ebb4caSwyllys uchar_t *bytes = NULL; 34699ebb4caSwyllys size_t bytelen; 34799ebb4caSwyllys 34830a5e8faSwyllys ret = kmf_hexstr_to_bytes((uchar_t *) 34999ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL, 35099ebb4caSwyllys &bytes, &bytelen); 35199ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 35299ebb4caSwyllys (void) fprintf(stderr, 35399ebb4caSwyllys gettext("serial number " 35499ebb4caSwyllys "must be specified as a " 35599ebb4caSwyllys "hex number " 35699ebb4caSwyllys "(ex: 0x0102030405" 35799ebb4caSwyllys "ffeeddee)\n")); 35899ebb4caSwyllys rv = KC_ERR_USAGE; 35999ebb4caSwyllys break; 36099ebb4caSwyllys } 36199ebb4caSwyllys if (bytes != NULL) 36299ebb4caSwyllys free(bytes); 36399ebb4caSwyllys flags |= KC_OCSP_RESP_CERT_SERIAL; 36499ebb4caSwyllys ocsp_set_attr++; 36599ebb4caSwyllys } 36699ebb4caSwyllys break; 36799ebb4caSwyllys case 'y': 36899ebb4caSwyllys ocsp_none_opt = get_boolean(optarg_av); 36999ebb4caSwyllys if (ocsp_none_opt == -1) { 37099ebb4caSwyllys (void) fprintf(stderr, 37199ebb4caSwyllys gettext("Error boolean input.\n")); 37299ebb4caSwyllys rv = KC_ERR_USAGE; 37399ebb4caSwyllys } else { 37499ebb4caSwyllys flags |= KC_OCSP_NONE; 37599ebb4caSwyllys } 37699ebb4caSwyllys break; 37799ebb4caSwyllys case 'c': 37899ebb4caSwyllys plc.VAL_CRL_BASEFILENAME = 37999ebb4caSwyllys get_string(optarg_av, &rv); 38099ebb4caSwyllys if (plc.VAL_CRL_BASEFILENAME == NULL) { 38199ebb4caSwyllys (void) fprintf(stderr, gettext( 38299ebb4caSwyllys "Error basefilename input.\n")); 38399ebb4caSwyllys } else { 38499ebb4caSwyllys flags |= KC_CRL_BASEFILENAME; 38599ebb4caSwyllys crl_set_attr++; 38699ebb4caSwyllys } 38799ebb4caSwyllys break; 38899ebb4caSwyllys case 'I': 38999ebb4caSwyllys plc.VAL_CRL_DIRECTORY = 39099ebb4caSwyllys get_string(optarg_av, &rv); 39199ebb4caSwyllys if (plc.VAL_CRL_DIRECTORY == NULL) { 39299ebb4caSwyllys (void) fprintf(stderr, 39399ebb4caSwyllys gettext("Error boolean input.\n")); 39499ebb4caSwyllys } else { 39599ebb4caSwyllys flags |= KC_CRL_DIRECTORY; 39699ebb4caSwyllys crl_set_attr++; 39799ebb4caSwyllys } 39899ebb4caSwyllys break; 39999ebb4caSwyllys case 'g': 40099ebb4caSwyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av); 40199ebb4caSwyllys if (plc.VAL_CRL_GET_URI == -1) { 40299ebb4caSwyllys (void) fprintf(stderr, 40399ebb4caSwyllys gettext("Error boolean input.\n")); 40499ebb4caSwyllys rv = KC_ERR_USAGE; 40599ebb4caSwyllys } else { 40699ebb4caSwyllys flags |= KC_CRL_GET_URI; 40799ebb4caSwyllys crl_set_attr++; 40899ebb4caSwyllys } 40999ebb4caSwyllys break; 41099ebb4caSwyllys case 'X': 41199ebb4caSwyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); 41299ebb4caSwyllys if (plc.VAL_CRL_PROXY == NULL) { 41399ebb4caSwyllys (void) fprintf(stderr, 41499ebb4caSwyllys gettext("Error proxy input.\n")); 41599ebb4caSwyllys } else { 41699ebb4caSwyllys flags |= KC_CRL_PROXY; 41799ebb4caSwyllys crl_set_attr++; 41899ebb4caSwyllys } 41999ebb4caSwyllys break; 42099ebb4caSwyllys case 'S': 42199ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN = 42299ebb4caSwyllys get_boolean(optarg_av); 42399ebb4caSwyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) { 42499ebb4caSwyllys (void) fprintf(stderr, 42599ebb4caSwyllys gettext("Error boolean input.\n")); 42699ebb4caSwyllys rv = KC_ERR_USAGE; 42799ebb4caSwyllys } else { 42899ebb4caSwyllys flags |= KC_CRL_IGNORE_SIGN; 42999ebb4caSwyllys crl_set_attr++; 43099ebb4caSwyllys } 43199ebb4caSwyllys break; 43299ebb4caSwyllys case 'D': 43399ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE = 43499ebb4caSwyllys get_boolean(optarg_av); 43599ebb4caSwyllys if (plc.VAL_CRL_IGNORE_DATE == -1) { 43699ebb4caSwyllys (void) fprintf(stderr, 43799ebb4caSwyllys gettext("Error boolean input.\n")); 43899ebb4caSwyllys rv = KC_ERR_USAGE; 43999ebb4caSwyllys } else { 44099ebb4caSwyllys flags |= KC_CRL_IGNORE_DATE; 44199ebb4caSwyllys crl_set_attr++; 44299ebb4caSwyllys } 44399ebb4caSwyllys break; 44499ebb4caSwyllys case 'z': 44599ebb4caSwyllys crl_none_opt = get_boolean(optarg_av); 44699ebb4caSwyllys if (crl_none_opt == -1) { 44799ebb4caSwyllys (void) fprintf(stderr, 44899ebb4caSwyllys gettext("Error boolean input.\n")); 44999ebb4caSwyllys rv = KC_ERR_USAGE; 45099ebb4caSwyllys } else { 45199ebb4caSwyllys flags |= KC_CRL_NONE; 45299ebb4caSwyllys } 45399ebb4caSwyllys break; 45499ebb4caSwyllys case 'u': 45599ebb4caSwyllys plc.ku_bits = parseKUlist(optarg_av); 45699ebb4caSwyllys if (plc.ku_bits == 0) { 45799ebb4caSwyllys (void) fprintf(stderr, gettext( 45899ebb4caSwyllys "Error keyusage input.\n")); 45999ebb4caSwyllys rv = KC_ERR_USAGE; 46099ebb4caSwyllys } else { 46199ebb4caSwyllys flags |= KC_KEYUSAGE; 46299ebb4caSwyllys } 46399ebb4caSwyllys break; 46499ebb4caSwyllys case 'Y': 46599ebb4caSwyllys ku_none_opt = get_boolean(optarg_av); 46699ebb4caSwyllys if (ku_none_opt == -1) { 46799ebb4caSwyllys (void) fprintf(stderr, 46899ebb4caSwyllys gettext("Error boolean input.\n")); 46999ebb4caSwyllys rv = KC_ERR_USAGE; 47099ebb4caSwyllys } else { 47199ebb4caSwyllys flags |= KC_KEYUSAGE_NONE; 47299ebb4caSwyllys } 47399ebb4caSwyllys break; 47499ebb4caSwyllys case 'E': 47599ebb4caSwyllys if (parseEKUNames(optarg_av, &plc) != 0) { 47699ebb4caSwyllys (void) fprintf(stderr, 47799ebb4caSwyllys gettext("Error EKU input.\n")); 47899ebb4caSwyllys rv = KC_ERR_USAGE; 47999ebb4caSwyllys } else { 48099ebb4caSwyllys flags |= KC_EKUS; 48199ebb4caSwyllys } 48299ebb4caSwyllys break; 48399ebb4caSwyllys case 'O': 48499ebb4caSwyllys if (parseEKUOIDs(optarg_av, &plc) != 0) { 48599ebb4caSwyllys (void) fprintf(stderr, 48699ebb4caSwyllys gettext("Error EKU OID input.\n")); 48799ebb4caSwyllys rv = KC_ERR_USAGE; 48899ebb4caSwyllys } else { 48999ebb4caSwyllys flags |= KC_EKUS; 49099ebb4caSwyllys } 49199ebb4caSwyllys break; 49299ebb4caSwyllys case 'Z': 49399ebb4caSwyllys eku_none_opt = get_boolean(optarg_av); 49499ebb4caSwyllys if (eku_none_opt == -1) { 49599ebb4caSwyllys (void) fprintf(stderr, 49699ebb4caSwyllys gettext("Error boolean input.\n")); 49799ebb4caSwyllys rv = KC_ERR_USAGE; 49899ebb4caSwyllys } else { 49999ebb4caSwyllys flags |= KC_EKUS_NONE; 50099ebb4caSwyllys } 50199ebb4caSwyllys break; 502269e59f9SJan Pechanec case 'm': 503269e59f9SJan Pechanec mapper_name = get_string(optarg_av, &rv); 504269e59f9SJan Pechanec if (mapper_name == NULL) { 505269e59f9SJan Pechanec (void) fprintf(stderr, 506269e59f9SJan Pechanec gettext("Error mapper-name " 507269e59f9SJan Pechanec "input.\n")); 508269e59f9SJan Pechanec } 509269e59f9SJan Pechanec break; 510269e59f9SJan Pechanec case 'M': 511269e59f9SJan Pechanec mapper_dir = get_string(optarg_av, &rv); 512269e59f9SJan Pechanec if (mapper_dir == NULL) { 513269e59f9SJan Pechanec (void) fprintf(stderr, 514269e59f9SJan Pechanec gettext("Error mapper-directory " 515269e59f9SJan Pechanec "input.\n")); 516269e59f9SJan Pechanec } 517269e59f9SJan Pechanec break; 518269e59f9SJan Pechanec case 'Q': 519269e59f9SJan Pechanec mapper_pathname = get_string(optarg_av, &rv); 520269e59f9SJan Pechanec if (mapper_pathname == NULL) { 521269e59f9SJan Pechanec (void) fprintf(stderr, 522269e59f9SJan Pechanec gettext("Error mapper-pathname " 523269e59f9SJan Pechanec "input.\n")); 524269e59f9SJan Pechanec } 525269e59f9SJan Pechanec break; 526269e59f9SJan Pechanec case 'q': 527269e59f9SJan Pechanec plc.mapper.options = get_string(optarg_av, &rv); 528269e59f9SJan Pechanec rv = 0; /* its ok for this to be NULL */ 529269e59f9SJan Pechanec flags |= KC_MAPPER_OPTIONS; 530269e59f9SJan Pechanec break; 53199ebb4caSwyllys default: 53299ebb4caSwyllys (void) fprintf(stderr, 53399ebb4caSwyllys gettext("Error input option.\n")); 53499ebb4caSwyllys rv = KC_ERR_USAGE; 53599ebb4caSwyllys break; 53699ebb4caSwyllys } 53799ebb4caSwyllys if (rv != KC_OK) 53899ebb4caSwyllys goto out; 53999ebb4caSwyllys } 54099ebb4caSwyllys 54199ebb4caSwyllys /* No additional args allowed. */ 54299ebb4caSwyllys argc -= optind_av; 54399ebb4caSwyllys if (argc) { 54499ebb4caSwyllys (void) fprintf(stderr, 54599ebb4caSwyllys gettext("Error input option\n")); 54699ebb4caSwyllys rv = KC_ERR_USAGE; 54799ebb4caSwyllys goto out; 54899ebb4caSwyllys } 54999ebb4caSwyllys 55099ebb4caSwyllys if (filename == NULL) { 55199ebb4caSwyllys filename = strdup(KMF_DEFAULT_POLICY_FILE); 55299ebb4caSwyllys if (filename == NULL) { 55399ebb4caSwyllys rv = KC_ERR_MEMORY; 55499ebb4caSwyllys goto out; 55599ebb4caSwyllys } 55699ebb4caSwyllys } 55799ebb4caSwyllys 55899ebb4caSwyllys /* 55999ebb4caSwyllys * Must have a policy name. The policy name can not be default 56099ebb4caSwyllys * if using the default policy file. 56199ebb4caSwyllys */ 56299ebb4caSwyllys if (plc.name == NULL) { 56399ebb4caSwyllys (void) fprintf(stderr, 56499ebb4caSwyllys gettext("You must specify a policy name.\n")); 56599ebb4caSwyllys rv = KC_ERR_USAGE; 56699ebb4caSwyllys goto out; 56799ebb4caSwyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && 56899ebb4caSwyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { 56999ebb4caSwyllys (void) fprintf(stderr, 57099ebb4caSwyllys gettext("Can not modify the default policy in the default " 57199ebb4caSwyllys "policy file.\n")); 57299ebb4caSwyllys rv = KC_ERR_USAGE; 57399ebb4caSwyllys goto out; 57499ebb4caSwyllys } 57599ebb4caSwyllys 57699ebb4caSwyllys /* Check the access permission of the policy DB */ 57799ebb4caSwyllys if (access(filename, W_OK) < 0) { 57899ebb4caSwyllys int err = errno; 57999ebb4caSwyllys (void) fprintf(stderr, 58099ebb4caSwyllys gettext("Cannot access \"%s\" for modify - %s\n"), 58199ebb4caSwyllys filename, strerror(err)); 58299ebb4caSwyllys rv = KC_ERR_ACCESS; 58399ebb4caSwyllys goto out; 58499ebb4caSwyllys } 58599ebb4caSwyllys 58699ebb4caSwyllys /* Try to load the named policy from the DB */ 58730a5e8faSwyllys ret = kmf_get_policy(filename, plc.name, &oplc); 58899ebb4caSwyllys if (ret != KMF_OK) { 58999ebb4caSwyllys (void) fprintf(stderr, 59099ebb4caSwyllys gettext("Error loading policy \"%s\" from %s\n"), filename, 59199ebb4caSwyllys plc.name); 59299ebb4caSwyllys return (KC_ERR_FIND_POLICY); 59399ebb4caSwyllys } 59499ebb4caSwyllys 59599ebb4caSwyllys /* Update the general policy attributes. */ 59699ebb4caSwyllys if (flags & KC_IGNORE_DATE) 59799ebb4caSwyllys oplc.ignore_date = plc.ignore_date; 59899ebb4caSwyllys 59999ebb4caSwyllys if (flags & KC_IGNORE_UNKNOWN_EKUS) 60099ebb4caSwyllys oplc.ignore_unknown_ekus = plc.ignore_unknown_ekus; 60199ebb4caSwyllys 60299ebb4caSwyllys if (flags & KC_IGNORE_TRUST_ANCHOR) 60399ebb4caSwyllys oplc.ignore_trust_anchor = plc.ignore_trust_anchor; 60499ebb4caSwyllys 60599ebb4caSwyllys if (flags & KC_VALIDITY_ADJUSTTIME) { 60699ebb4caSwyllys if (oplc.validity_adjusttime) 60799ebb4caSwyllys free(oplc.validity_adjusttime); 60899ebb4caSwyllys oplc.validity_adjusttime = 60999ebb4caSwyllys plc.validity_adjusttime; 61099ebb4caSwyllys } 61199ebb4caSwyllys 61299ebb4caSwyllys if (flags & KC_TA_NAME) { 61399ebb4caSwyllys if (oplc.ta_name) 61499ebb4caSwyllys free(oplc.ta_name); 61599ebb4caSwyllys oplc.ta_name = plc.ta_name; 61699ebb4caSwyllys } 61799ebb4caSwyllys if (flags & KC_TA_SERIAL) { 61899ebb4caSwyllys if (oplc.ta_serial) 61999ebb4caSwyllys free(oplc.ta_serial); 62099ebb4caSwyllys oplc.ta_serial = plc.ta_serial; 62199ebb4caSwyllys } 62299ebb4caSwyllys 623269e59f9SJan Pechanec /* 624269e59f9SJan Pechanec * There are some combinations of attributes that are not valid. 625269e59f9SJan Pechanec * 626269e59f9SJan Pechanec * First, setting mapper-name (with optional mapper-directory) and 627269e59f9SJan Pechanec * mapper-pathname is mutually exclusive. 628269e59f9SJan Pechanec */ 629269e59f9SJan Pechanec if ((mapper_name != NULL && mapper_pathname != NULL) || 630269e59f9SJan Pechanec (mapper_name != NULL && oplc.mapper.pathname != NULL) || 631269e59f9SJan Pechanec (mapper_pathname != NULL && oplc.mapper.mapname != NULL) || 632269e59f9SJan Pechanec /* Mapper directory can be set only if mapper name is set. */ 633269e59f9SJan Pechanec (mapper_dir != NULL && mapper_pathname != NULL) || 634269e59f9SJan Pechanec (mapper_dir != NULL && mapper_name == NULL && 635269e59f9SJan Pechanec oplc.mapper.mapname == NULL) || 636269e59f9SJan Pechanec (mapper_dir != NULL && oplc.mapper.pathname != NULL) || 637269e59f9SJan Pechanec /* Options can be set only if mapper name or pathname is set. */ 638269e59f9SJan Pechanec ((plc.mapper.options != NULL || oplc.mapper.options != NULL) && 639269e59f9SJan Pechanec (mapper_name == NULL && oplc.mapper.mapname == NULL && 640269e59f9SJan Pechanec mapper_pathname == NULL && oplc.mapper.pathname == NULL))) { 641269e59f9SJan Pechanec (void) fprintf(stderr, 642269e59f9SJan Pechanec gettext("Error in mapper input options\n")); 643269e59f9SJan Pechanec if (mapper_name != NULL) 644269e59f9SJan Pechanec free(mapper_name); 645269e59f9SJan Pechanec if (mapper_pathname != NULL) 646269e59f9SJan Pechanec free(mapper_pathname); 647269e59f9SJan Pechanec if (mapper_dir != NULL) 648269e59f9SJan Pechanec free(mapper_dir); 649269e59f9SJan Pechanec if (flags & KC_MAPPER_OPTIONS && plc.mapper.options != NULL) 650269e59f9SJan Pechanec free(plc.mapper.options); 651269e59f9SJan Pechanec rv = KC_ERR_USAGE; 652269e59f9SJan Pechanec goto out; 653269e59f9SJan Pechanec } else { 654269e59f9SJan Pechanec if (mapper_name != NULL) 655269e59f9SJan Pechanec plc.mapper.mapname = mapper_name; 656269e59f9SJan Pechanec if (mapper_pathname != NULL) 657269e59f9SJan Pechanec plc.mapper.pathname = mapper_pathname; 658269e59f9SJan Pechanec if (mapper_dir != NULL) 659269e59f9SJan Pechanec plc.mapper.dir = mapper_dir; 660269e59f9SJan Pechanec } 661269e59f9SJan Pechanec 662269e59f9SJan Pechanec UPDATE_IF_DIFFERENT(oplc.mapper.mapname, plc.mapper.mapname); 663269e59f9SJan Pechanec UPDATE_IF_DIFFERENT(oplc.mapper.pathname, plc.mapper.pathname); 664269e59f9SJan Pechanec UPDATE_IF_DIFFERENT(oplc.mapper.dir, plc.mapper.dir); 665269e59f9SJan Pechanec 666269e59f9SJan Pechanec if (flags & KC_MAPPER_OPTIONS) { 667269e59f9SJan Pechanec if (oplc.mapper.options != NULL) 668269e59f9SJan Pechanec free(oplc.mapper.options); 669269e59f9SJan Pechanec oplc.mapper.options = plc.mapper.options; 670269e59f9SJan Pechanec } 671269e59f9SJan Pechanec 67299ebb4caSwyllys /* Update the OCSP policy */ 67399ebb4caSwyllys if (ocsp_none_opt == B_TRUE) { 67499ebb4caSwyllys if (ocsp_set_attr > 0) { 67599ebb4caSwyllys (void) fprintf(stderr, 67699ebb4caSwyllys gettext("Can not set ocsp-none=true and other " 67799ebb4caSwyllys "OCSP attributes at the same time.\n")); 67899ebb4caSwyllys rv = KC_ERR_USAGE; 67999ebb4caSwyllys goto out; 68099ebb4caSwyllys } 68199ebb4caSwyllys 68299ebb4caSwyllys /* 68399ebb4caSwyllys * If the original policy does not have OCSP checking, 68499ebb4caSwyllys * then we do not need to do anything. If the original 68599ebb4caSwyllys * policy has the OCSP checking, then we need to release the 68699ebb4caSwyllys * space of OCSP attributes and turn the OCSP checking off. 68799ebb4caSwyllys */ 68899ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_OCSP) { 68999ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.responderURI) { 69099ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.responderURI); 69199ebb4caSwyllys oplc.VAL_OCSP_BASIC.responderURI = NULL; 69299ebb4caSwyllys } 69399ebb4caSwyllys 69499ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.proxy) { 69599ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.proxy); 69699ebb4caSwyllys oplc.VAL_OCSP_BASIC.proxy = NULL; 69799ebb4caSwyllys } 69899ebb4caSwyllys 69999ebb4caSwyllys if (oplc.VAL_OCSP_BASIC.response_lifetime) { 70099ebb4caSwyllys free(oplc.VAL_OCSP_BASIC.response_lifetime); 70199ebb4caSwyllys oplc.VAL_OCSP_BASIC.response_lifetime = NULL; 70299ebb4caSwyllys } 70399ebb4caSwyllys 70499ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 70599ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.name); 70699ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.name = NULL; 70799ebb4caSwyllys } 70899ebb4caSwyllys 70999ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 71099ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT.serial); 71199ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT.serial = NULL; 71299ebb4caSwyllys } 71399ebb4caSwyllys 71499ebb4caSwyllys /* Turn off the OCSP checking */ 71599ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_OCSP; 71699ebb4caSwyllys } 71799ebb4caSwyllys 71899ebb4caSwyllys } else { 71999ebb4caSwyllys /* 72099ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 72199ebb4caSwyllys * then we only need to do the modification if there is at 72299ebb4caSwyllys * least one OCSP attribute is specified. 72399ebb4caSwyllys */ 72499ebb4caSwyllys if (ocsp_set_attr > 0) { 72599ebb4caSwyllys if (flags & KC_OCSP_RESPONDER_URI) { 72699ebb4caSwyllys if (oplc.VAL_OCSP_RESPONDER_URI) 72799ebb4caSwyllys free(oplc.VAL_OCSP_RESPONDER_URI); 72899ebb4caSwyllys oplc.VAL_OCSP_RESPONDER_URI = 72999ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI; 73099ebb4caSwyllys } 73199ebb4caSwyllys 73299ebb4caSwyllys if (flags & KC_OCSP_PROXY) { 73399ebb4caSwyllys if (oplc.VAL_OCSP_PROXY) 73499ebb4caSwyllys free(oplc.VAL_OCSP_PROXY); 73599ebb4caSwyllys oplc.VAL_OCSP_PROXY = plc.VAL_OCSP_PROXY; 73699ebb4caSwyllys } 73799ebb4caSwyllys 73899ebb4caSwyllys if (flags & KC_OCSP_URI_FROM_CERT) 73999ebb4caSwyllys oplc.VAL_OCSP_URI_FROM_CERT = 74099ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT; 74199ebb4caSwyllys 74299ebb4caSwyllys if (flags & KC_OCSP_RESP_LIFETIME) { 74399ebb4caSwyllys if (oplc.VAL_OCSP_RESP_LIFETIME) 74499ebb4caSwyllys free(oplc.VAL_OCSP_RESP_LIFETIME); 74599ebb4caSwyllys oplc.VAL_OCSP_RESP_LIFETIME = 74699ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME; 74799ebb4caSwyllys } 74899ebb4caSwyllys 74999ebb4caSwyllys if (flags & KC_OCSP_IGNORE_RESP_SIGN) 75099ebb4caSwyllys oplc.VAL_OCSP_IGNORE_RESP_SIGN = 75199ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN; 75299ebb4caSwyllys 75399ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_NAME) { 75499ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME) 75599ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_NAME); 75699ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_NAME = 75799ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME; 75899ebb4caSwyllys } 75999ebb4caSwyllys 76099ebb4caSwyllys if (flags & KC_OCSP_RESP_CERT_SERIAL) { 76199ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_SERIAL) 76299ebb4caSwyllys free(oplc.VAL_OCSP_RESP_CERT_SERIAL); 76399ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL = 76499ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL; 76599ebb4caSwyllys } 76699ebb4caSwyllys 76799ebb4caSwyllys if (oplc.VAL_OCSP_RESP_CERT_NAME != NULL && 76899ebb4caSwyllys oplc.VAL_OCSP_RESP_CERT_SERIAL != NULL) 76999ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_TRUE; 77099ebb4caSwyllys else 77199ebb4caSwyllys oplc.VAL_OCSP.has_resp_cert = B_FALSE; 77299ebb4caSwyllys 77399ebb4caSwyllys /* Turn on the OCSP checking */ 77499ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_OCSP; 77599ebb4caSwyllys } 77699ebb4caSwyllys } 77799ebb4caSwyllys 77899ebb4caSwyllys /* Update the CRL policy */ 77999ebb4caSwyllys if (crl_none_opt == B_TRUE) { 78099ebb4caSwyllys if (crl_set_attr > 0) { 78199ebb4caSwyllys (void) fprintf(stderr, 78299ebb4caSwyllys gettext("Can not set crl-none=true and other CRL " 78399ebb4caSwyllys "attributes at the same time.\n")); 78499ebb4caSwyllys rv = KC_ERR_USAGE; 78599ebb4caSwyllys goto out; 78699ebb4caSwyllys } 78799ebb4caSwyllys 78899ebb4caSwyllys /* 78999ebb4caSwyllys * If the original policy does not have CRL checking, 79099ebb4caSwyllys * then we do not need to do anything. If the original 79199ebb4caSwyllys * policy has the CRL checking, then we need to release the 79299ebb4caSwyllys * space of CRL attributes and turn the CRL checking off. 79399ebb4caSwyllys */ 79499ebb4caSwyllys if (oplc.revocation & KMF_REVOCATION_METHOD_CRL) { 79599ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) { 79699ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 79799ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = NULL; 79899ebb4caSwyllys } 79999ebb4caSwyllys 80099ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) { 80199ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 80299ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = NULL; 80399ebb4caSwyllys } 80499ebb4caSwyllys 80599ebb4caSwyllys if (oplc.VAL_CRL_PROXY) { 80699ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 80799ebb4caSwyllys oplc.VAL_CRL_PROXY = NULL; 80899ebb4caSwyllys } 80999ebb4caSwyllys 81099ebb4caSwyllys /* Turn off the CRL checking */ 81199ebb4caSwyllys oplc.revocation &= ~KMF_REVOCATION_METHOD_CRL; 81299ebb4caSwyllys } 81399ebb4caSwyllys } else { 81499ebb4caSwyllys /* 81599ebb4caSwyllys * If the "ocsp-none" option is not set or is set to false, 81699ebb4caSwyllys * then we only need to do the modification if there is at 81799ebb4caSwyllys * least one CRL attribute is specified. 81899ebb4caSwyllys */ 81999ebb4caSwyllys if (crl_set_attr > 0) { 82099ebb4caSwyllys if (flags & KC_CRL_BASEFILENAME) { 82199ebb4caSwyllys if (oplc.VAL_CRL_BASEFILENAME) 82299ebb4caSwyllys free(oplc.VAL_CRL_BASEFILENAME); 82399ebb4caSwyllys oplc.VAL_CRL_BASEFILENAME = 82499ebb4caSwyllys plc.VAL_CRL_BASEFILENAME; 82599ebb4caSwyllys } 82699ebb4caSwyllys 82799ebb4caSwyllys if (flags & KC_CRL_DIRECTORY) { 82899ebb4caSwyllys if (oplc.VAL_CRL_DIRECTORY) 82999ebb4caSwyllys free(oplc.VAL_CRL_DIRECTORY); 83099ebb4caSwyllys oplc.VAL_CRL_DIRECTORY = plc.VAL_CRL_DIRECTORY; 83199ebb4caSwyllys } 83299ebb4caSwyllys 83399ebb4caSwyllys if (flags & KC_CRL_GET_URI) { 83499ebb4caSwyllys oplc.VAL_CRL_GET_URI = plc.VAL_CRL_GET_URI; 83599ebb4caSwyllys } 83699ebb4caSwyllys 83799ebb4caSwyllys if (flags & KC_CRL_PROXY) { 83899ebb4caSwyllys if (oplc.VAL_CRL_PROXY) 83999ebb4caSwyllys free(oplc.VAL_CRL_PROXY); 84099ebb4caSwyllys oplc.VAL_CRL_PROXY = plc.VAL_CRL_PROXY; 84199ebb4caSwyllys } 84299ebb4caSwyllys 84399ebb4caSwyllys if (flags & KC_CRL_IGNORE_SIGN) { 84499ebb4caSwyllys oplc.VAL_CRL_IGNORE_SIGN = 84599ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN; 84699ebb4caSwyllys } 84799ebb4caSwyllys 84899ebb4caSwyllys if (flags & KC_CRL_IGNORE_DATE) { 84999ebb4caSwyllys oplc.VAL_CRL_IGNORE_DATE = 85099ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE; 85199ebb4caSwyllys } 85299ebb4caSwyllys 85399ebb4caSwyllys /* Turn on the CRL checking */ 85499ebb4caSwyllys oplc.revocation |= KMF_REVOCATION_METHOD_CRL; 85599ebb4caSwyllys } 85699ebb4caSwyllys } 85799ebb4caSwyllys 85899ebb4caSwyllys /* Update the Key Usage */ 85999ebb4caSwyllys if (ku_none_opt == B_TRUE) { 86099ebb4caSwyllys if (flags & KC_KEYUSAGE) { 86199ebb4caSwyllys (void) fprintf(stderr, 86299ebb4caSwyllys gettext("Can not set keyusage-none=true and " 86399ebb4caSwyllys "modify the keyusage value at the same time.\n")); 86499ebb4caSwyllys rv = KC_ERR_USAGE; 86599ebb4caSwyllys goto out; 86699ebb4caSwyllys } 86799ebb4caSwyllys 86899ebb4caSwyllys oplc.ku_bits = 0; 86999ebb4caSwyllys } else { 87099ebb4caSwyllys /* 87199ebb4caSwyllys * If the "keyusage-none" option is not set or is set to 87299ebb4caSwyllys * false, then we only need to do the modification if 87399ebb4caSwyllys * the keyusage value is specified. 87499ebb4caSwyllys */ 87599ebb4caSwyllys if (flags & KC_KEYUSAGE) 87699ebb4caSwyllys oplc.ku_bits = plc.ku_bits; 87799ebb4caSwyllys } 87899ebb4caSwyllys 87999ebb4caSwyllys 88099ebb4caSwyllys /* Update the Extended Key Usage */ 88199ebb4caSwyllys if (eku_none_opt == B_TRUE) { 88299ebb4caSwyllys if (flags & KC_EKUS) { 88399ebb4caSwyllys (void) fprintf(stderr, 88499ebb4caSwyllys gettext("Can not set eku-none=true and modify " 88599ebb4caSwyllys "EKU values at the same time.\n")); 88699ebb4caSwyllys rv = KC_ERR_USAGE; 88799ebb4caSwyllys goto out; 88899ebb4caSwyllys } 88999ebb4caSwyllys 89099ebb4caSwyllys /* Release current EKU list (if any) */ 89199ebb4caSwyllys if (oplc.eku_set.eku_count > 0) { 89230a5e8faSwyllys kmf_free_eku_policy(&oplc.eku_set); 89399ebb4caSwyllys oplc.eku_set.eku_count = 0; 89499ebb4caSwyllys oplc.eku_set.ekulist = NULL; 89599ebb4caSwyllys } 89699ebb4caSwyllys } else { 89799ebb4caSwyllys /* 89899ebb4caSwyllys * If the "eku-none" option is not set or is set to false, 89999ebb4caSwyllys * then we only need to do the modification if either 90099ebb4caSwyllys * "ekuname" or "ekuoids" is specified. 90199ebb4caSwyllys */ 90299ebb4caSwyllys if (flags & KC_EKUS) { 90399ebb4caSwyllys /* Release current EKU list (if any) */ 90430a5e8faSwyllys kmf_free_eku_policy(&oplc.eku_set); 90599ebb4caSwyllys oplc.eku_set = plc.eku_set; 90699ebb4caSwyllys } 90799ebb4caSwyllys } 90899ebb4caSwyllys 90999ebb4caSwyllys /* Do a sanity check on the modified policy */ 91030a5e8faSwyllys ret = kmf_verify_policy(&oplc); 91199ebb4caSwyllys if (ret != KMF_OK) { 91299ebb4caSwyllys print_sanity_error(ret); 91399ebb4caSwyllys rv = KC_ERR_VERIFY_POLICY; 91499ebb4caSwyllys goto out; 91599ebb4caSwyllys } 91699ebb4caSwyllys 91799ebb4caSwyllys /* The modify operation is a delete followed by an add */ 91830a5e8faSwyllys ret = kmf_delete_policy_from_db(oplc.name, filename); 91999ebb4caSwyllys if (ret != KMF_OK) { 92099ebb4caSwyllys rv = KC_ERR_DELETE_POLICY; 92199ebb4caSwyllys goto out; 92299ebb4caSwyllys } 92399ebb4caSwyllys 92499ebb4caSwyllys /* 92599ebb4caSwyllys * Now add the modified policy back to the DB. 92699ebb4caSwyllys */ 92730a5e8faSwyllys ret = kmf_add_policy_to_db(&oplc, filename, B_FALSE); 92899ebb4caSwyllys if (ret != KMF_OK) { 92999ebb4caSwyllys (void) fprintf(stderr, 93099ebb4caSwyllys gettext("Error adding policy to database: 0x%04x\n"), ret); 93199ebb4caSwyllys rv = KC_ERR_ADD_POLICY; 93299ebb4caSwyllys goto out; 93399ebb4caSwyllys } 93499ebb4caSwyllys 93599ebb4caSwyllys out: 93699ebb4caSwyllys if (filename != NULL) 93799ebb4caSwyllys free(filename); 93899ebb4caSwyllys 93930a5e8faSwyllys kmf_free_policy_record(&oplc); 94099ebb4caSwyllys 94199ebb4caSwyllys return (rv); 94299ebb4caSwyllys } 943431deaa0Shylee 944431deaa0Shylee static int 945431deaa0Shylee kc_modify_plugin(int argc, char *argv[]) 946431deaa0Shylee { 947431deaa0Shylee int rv = KC_OK; 948431deaa0Shylee int opt; 949431deaa0Shylee extern int optind_av; 950431deaa0Shylee extern char *optarg_av; 951431deaa0Shylee char *keystore_name = NULL; 952431deaa0Shylee char *option = NULL; 953431deaa0Shylee boolean_t modify_plugin = B_FALSE; 954431deaa0Shylee boolean_t has_option_arg = B_FALSE; 955431deaa0Shylee conf_entry_t *entry = NULL; 956431deaa0Shylee FILE *pfile = NULL; 957431deaa0Shylee FILE *pfile_tmp = NULL; 958431deaa0Shylee char tmpfile_name[MAXPATHLEN]; 959431deaa0Shylee char buffer[MAXPATHLEN]; 960431deaa0Shylee char buffer2[MAXPATHLEN]; 961431deaa0Shylee 962431deaa0Shylee while ((opt = getopt_av(argc, argv, "p(plugin)k:(keystore)o:(option)")) 963431deaa0Shylee != EOF) { 964431deaa0Shylee switch (opt) { 965431deaa0Shylee case 'p': 966431deaa0Shylee if (modify_plugin) { 967431deaa0Shylee (void) fprintf(stderr, 968431deaa0Shylee gettext("duplicate plugin input.\n")); 969431deaa0Shylee rv = KC_ERR_USAGE; 970431deaa0Shylee } else { 971431deaa0Shylee modify_plugin = B_TRUE; 972431deaa0Shylee } 973431deaa0Shylee break; 974431deaa0Shylee case 'k': 975431deaa0Shylee if (keystore_name != NULL) 976431deaa0Shylee rv = KC_ERR_USAGE; 977431deaa0Shylee else { 978431deaa0Shylee keystore_name = get_string(optarg_av, &rv); 979431deaa0Shylee if (keystore_name == NULL) { 980431deaa0Shylee (void) fprintf(stderr, gettext( 981431deaa0Shylee "Error keystore input.\n")); 982431deaa0Shylee rv = KC_ERR_USAGE; 983431deaa0Shylee } 984431deaa0Shylee } 985431deaa0Shylee break; 986431deaa0Shylee case 'o': 987431deaa0Shylee if (has_option_arg) { 988431deaa0Shylee (void) fprintf(stderr, 989431deaa0Shylee gettext("duplicate option input.\n")); 990431deaa0Shylee rv = KC_ERR_USAGE; 991431deaa0Shylee } else { 992431deaa0Shylee has_option_arg = B_TRUE; 993431deaa0Shylee option = get_string(optarg_av, NULL); 994431deaa0Shylee } 995431deaa0Shylee break; 996431deaa0Shylee default: 997431deaa0Shylee (void) fprintf(stderr, 998431deaa0Shylee gettext("Error input option.\n")); 999431deaa0Shylee rv = KC_ERR_USAGE; 1000431deaa0Shylee break; 1001431deaa0Shylee } 1002431deaa0Shylee 1003431deaa0Shylee if (rv != KC_OK) 1004431deaa0Shylee goto out; 1005431deaa0Shylee } 1006431deaa0Shylee 1007431deaa0Shylee /* No additional args allowed. */ 1008431deaa0Shylee argc -= optind_av; 1009431deaa0Shylee if (argc) { 1010431deaa0Shylee (void) fprintf(stderr, 1011431deaa0Shylee gettext("Error input option\n")); 1012431deaa0Shylee rv = KC_ERR_USAGE; 1013431deaa0Shylee goto out; 1014431deaa0Shylee } 1015431deaa0Shylee 1016431deaa0Shylee if (keystore_name == NULL || has_option_arg == B_FALSE) { 1017431deaa0Shylee (void) fprintf(stderr, 1018431deaa0Shylee gettext("Error input option\n")); 1019431deaa0Shylee rv = KC_ERR_USAGE; 1020431deaa0Shylee goto out; 1021431deaa0Shylee } 1022431deaa0Shylee 1023431deaa0Shylee if (strcasecmp(keystore_name, "nss") == 0 || 1024431deaa0Shylee strcasecmp(keystore_name, "pkcs11") == 0 || 1025431deaa0Shylee strcasecmp(keystore_name, "file") == 0) { 1026431deaa0Shylee (void) fprintf(stderr, 1027431deaa0Shylee gettext("Can not modify the built-in keystore %s\n"), 1028431deaa0Shylee keystore_name); 1029431deaa0Shylee rv = KC_ERR_USAGE; 1030431deaa0Shylee goto out; 1031431deaa0Shylee } 1032431deaa0Shylee 1033431deaa0Shylee entry = get_keystore_entry(keystore_name); 1034431deaa0Shylee if (entry == NULL) { 1035431deaa0Shylee (void) fprintf(stderr, gettext("%s does not exist.\n"), 1036431deaa0Shylee keystore_name); 1037431deaa0Shylee rv = KC_ERR_USAGE; 1038431deaa0Shylee goto out; 1039431deaa0Shylee } 1040431deaa0Shylee 1041431deaa0Shylee if ((entry->option == NULL && option == NULL) || 1042431deaa0Shylee (entry->option != NULL && option != NULL && 1043431deaa0Shylee strcmp(entry->option, option) == 0)) { 1044431deaa0Shylee (void) fprintf(stderr, gettext("No change - " 1045431deaa0Shylee "the new option is same as the old option.\n")); 1046431deaa0Shylee rv = KC_OK; 1047431deaa0Shylee goto out; 1048431deaa0Shylee } 1049431deaa0Shylee 1050431deaa0Shylee if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) { 1051431deaa0Shylee err = errno; 1052431deaa0Shylee (void) fprintf(stderr, 1053431deaa0Shylee gettext("failed to update the configuration - %s\n"), 1054431deaa0Shylee strerror(err)); 1055431deaa0Shylee rv = KC_ERR_ACCESS; 1056431deaa0Shylee goto out; 1057431deaa0Shylee } 1058431deaa0Shylee 1059431deaa0Shylee if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 1060431deaa0Shylee err = errno; 1061431deaa0Shylee (void) fprintf(stderr, 1062431deaa0Shylee gettext("failed to lock the configuration - %s\n"), 1063431deaa0Shylee strerror(err)); 1064431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1065431deaa0Shylee goto out; 1066431deaa0Shylee } 1067431deaa0Shylee 1068431deaa0Shylee /* 1069431deaa0Shylee * Create a temporary file in the /etc/crypto directory. 1070431deaa0Shylee */ 1071431deaa0Shylee (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name)); 1072431deaa0Shylee if (mkstemp(tmpfile_name) == -1) { 1073431deaa0Shylee err = errno; 1074431deaa0Shylee (void) fprintf(stderr, 1075431deaa0Shylee gettext("failed to create a temporary file - %s\n"), 1076431deaa0Shylee strerror(err)); 1077431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1078431deaa0Shylee goto out; 1079431deaa0Shylee } 1080431deaa0Shylee 1081431deaa0Shylee if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 1082431deaa0Shylee err = errno; 1083431deaa0Shylee (void) fprintf(stderr, 1084431deaa0Shylee gettext("failed to open %s - %s\n"), 1085431deaa0Shylee tmpfile_name, strerror(err)); 1086431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1087431deaa0Shylee goto out; 1088431deaa0Shylee } 1089431deaa0Shylee 1090431deaa0Shylee /* 1091431deaa0Shylee * Loop thru the config file and update the entry. 1092431deaa0Shylee */ 1093431deaa0Shylee while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 1094431deaa0Shylee char *name; 1095431deaa0Shylee int len; 1096431deaa0Shylee 1097431deaa0Shylee if (buffer[0] == '#') { 1098431deaa0Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1099431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1100431deaa0Shylee goto out; 1101431deaa0Shylee } else { 1102431deaa0Shylee continue; 1103431deaa0Shylee } 1104431deaa0Shylee } 1105431deaa0Shylee 1106431deaa0Shylee /* 1107431deaa0Shylee * make a copy of the original buffer to buffer2. Also get 1108431deaa0Shylee * rid of the trailing '\n' from buffer2. 1109431deaa0Shylee */ 1110431deaa0Shylee (void) strlcpy(buffer2, buffer, MAXPATHLEN); 1111431deaa0Shylee len = strlen(buffer2); 1112431deaa0Shylee if (buffer2[len-1] == '\n') { 1113431deaa0Shylee len--; 1114431deaa0Shylee } 1115431deaa0Shylee buffer2[len] = '\0'; 1116431deaa0Shylee 1117431deaa0Shylee if ((name = strtok(buffer2, SEP_COLON)) == NULL) { 1118431deaa0Shylee rv = KC_ERR_UNINSTALL; 1119431deaa0Shylee goto out; 1120431deaa0Shylee } 1121431deaa0Shylee 1122431deaa0Shylee if (strcmp(name, keystore_name) == 0) { 1123431deaa0Shylee /* found the entry */ 1124431deaa0Shylee if (option == NULL) 1125431deaa0Shylee (void) snprintf(buffer, MAXPATHLEN, 1126431deaa0Shylee "%s:%s%s\n", keystore_name, 1127431deaa0Shylee CONF_MODULEPATH, entry->modulepath); 1128431deaa0Shylee else 1129431deaa0Shylee (void) snprintf(buffer, MAXPATHLEN, 1130431deaa0Shylee "%s:%s%s;%s%s\n", keystore_name, 1131431deaa0Shylee CONF_MODULEPATH, entry->modulepath, 1132431deaa0Shylee CONF_OPTION, option); 1133431deaa0Shylee 1134431deaa0Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1135431deaa0Shylee err = errno; 1136431deaa0Shylee (void) fprintf(stderr, gettext( 1137431deaa0Shylee "failed to write to %s: %s\n"), 1138431deaa0Shylee tmpfile_name, strerror(err)); 1139431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1140431deaa0Shylee goto out; 1141431deaa0Shylee } 1142431deaa0Shylee } else { 1143431deaa0Shylee 1144431deaa0Shylee if (fputs(buffer, pfile_tmp) == EOF) { 1145431deaa0Shylee rv = KC_ERR_UNINSTALL; 1146431deaa0Shylee goto out; 1147431deaa0Shylee } 1148431deaa0Shylee } 1149431deaa0Shylee } 1150431deaa0Shylee 1151431deaa0Shylee if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) { 1152431deaa0Shylee err = errno; 1153431deaa0Shylee (void) fprintf(stderr, gettext( 1154431deaa0Shylee "failed to update the configuration - %s"), strerror(err)); 1155431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1156431deaa0Shylee goto out; 1157431deaa0Shylee } 1158431deaa0Shylee 1159431deaa0Shylee if (chmod(_PATH_KMF_CONF, 1160431deaa0Shylee S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 1161431deaa0Shylee err = errno; 1162431deaa0Shylee (void) fprintf(stderr, gettext( 1163431deaa0Shylee "failed to update the configuration - %s\n"), 1164431deaa0Shylee strerror(err)); 1165431deaa0Shylee rv = KC_ERR_MODIFY_PLUGIN; 1166431deaa0Shylee goto out; 1167431deaa0Shylee } 1168431deaa0Shylee 1169431deaa0Shylee out: 1170431deaa0Shylee if (entry != NULL) 1171431deaa0Shylee free_entry(entry); 1172431deaa0Shylee 1173431deaa0Shylee if (pfile != NULL) 1174431deaa0Shylee (void) fclose(pfile); 1175431deaa0Shylee 1176431deaa0Shylee if (rv != KC_OK && pfile_tmp != NULL) 1177431deaa0Shylee (void) unlink(tmpfile_name); 1178431deaa0Shylee 1179431deaa0Shylee if (pfile_tmp != NULL) 1180431deaa0Shylee (void) fclose(pfile_tmp); 1181431deaa0Shylee 1182431deaa0Shylee return (rv); 1183431deaa0Shylee } 1184431deaa0Shylee 1185431deaa0Shylee 1186431deaa0Shylee int 1187431deaa0Shylee kc_modify(int argc, char *argv[]) 1188431deaa0Shylee { 1189431deaa0Shylee if (argc > 2 && 1190431deaa0Shylee strcmp(argv[0], "modify") == 0 && 1191431deaa0Shylee strcmp(argv[1], "plugin") == 0) { 1192431deaa0Shylee return (kc_modify_plugin(argc, argv)); 1193431deaa0Shylee } else { 1194431deaa0Shylee return (kc_modify_policy(argc, argv)); 1195431deaa0Shylee } 1196431deaa0Shylee } 1197