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*269e59f9SJan 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> 3299ebb4caSwyllys #include "util.h" 3399ebb4caSwyllys 3499ebb4caSwyllys int 3599ebb4caSwyllys kc_create(int argc, char *argv[]) 3699ebb4caSwyllys { 3799ebb4caSwyllys KMF_RETURN ret; 3899ebb4caSwyllys int rv = KC_OK; 3999ebb4caSwyllys int opt; 4099ebb4caSwyllys extern int optind_av; 4199ebb4caSwyllys extern char *optarg_av; 4299ebb4caSwyllys char *filename = NULL; 4399ebb4caSwyllys int ocsp_set_attr = 0; 4499ebb4caSwyllys boolean_t crl_set_attr = 0; 4599ebb4caSwyllys KMF_POLICY_RECORD plc; 4699ebb4caSwyllys 4799ebb4caSwyllys (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD)); 4899ebb4caSwyllys 4999ebb4caSwyllys while ((opt = getopt_av(argc, argv, 5099ebb4caSwyllys "i:(dbfile)" 5199ebb4caSwyllys "p:(policy)" 5299ebb4caSwyllys "d:(ignore-date)" 5399ebb4caSwyllys "e:(ignore-unknown-eku)" 5499ebb4caSwyllys "a:(ignore-trust-anchor)" 5599ebb4caSwyllys "v:(validity-adjusttime)" 5699ebb4caSwyllys "t:(ta-name)" 5799ebb4caSwyllys "s:(ta-serial)" 5899ebb4caSwyllys "o:(ocsp-responder)" 5999ebb4caSwyllys "P:(ocsp-proxy)" 6099ebb4caSwyllys "r:(ocsp-use-cert-responder)" 6199ebb4caSwyllys "T:(ocsp-response-lifetime)" 6299ebb4caSwyllys "R:(ocsp-ignore-response-sign)" 6399ebb4caSwyllys "n:(ocsp-responder-cert-name)" 6499ebb4caSwyllys "A:(ocsp-responder-cert-serial)" 6599ebb4caSwyllys "c:(crl-basefilename)" 6699ebb4caSwyllys "I:(crl-directory)" 6799ebb4caSwyllys "g:(crl-get-crl-uri)" 6899ebb4caSwyllys "X:(crl-proxy)" 6999ebb4caSwyllys "S:(crl-ignore-crl-sign)" 7099ebb4caSwyllys "D:(crl-ignore-crl-date)" 71*269e59f9SJan Pechanec "m:(mapper-name)" 72*269e59f9SJan Pechanec "M:(mapper-directory)" 73*269e59f9SJan Pechanec "Q:(mapper-pathname)" 74*269e59f9SJan Pechanec "q:(mapper-options)" 7599ebb4caSwyllys "u:(keyusage)" 7699ebb4caSwyllys "E:(ekunames)" 7799ebb4caSwyllys "O:(ekuoids)")) != EOF) { 7899ebb4caSwyllys switch (opt) { 7999ebb4caSwyllys case 'i': 8099ebb4caSwyllys filename = get_string(optarg_av, &rv); 8199ebb4caSwyllys if (filename == NULL) { 8299ebb4caSwyllys (void) fprintf(stderr, 8399ebb4caSwyllys gettext("Error dbfile input.\n")); 8499ebb4caSwyllys } 8599ebb4caSwyllys break; 8699ebb4caSwyllys case 'p': 8799ebb4caSwyllys plc.name = get_string(optarg_av, &rv); 8899ebb4caSwyllys if (plc.name == NULL) { 8999ebb4caSwyllys (void) fprintf(stderr, 9099ebb4caSwyllys gettext("Error policy name.\n")); 9199ebb4caSwyllys } 9299ebb4caSwyllys break; 9399ebb4caSwyllys case 'd': 9499ebb4caSwyllys plc.ignore_date = get_boolean(optarg_av); 9599ebb4caSwyllys if (plc.ignore_date == -1) { 9699ebb4caSwyllys (void) fprintf(stderr, 9799ebb4caSwyllys gettext("Error boolean input.\n")); 9899ebb4caSwyllys rv = KC_ERR_USAGE; 9999ebb4caSwyllys } 10099ebb4caSwyllys break; 10199ebb4caSwyllys case 'e': 10299ebb4caSwyllys plc.ignore_unknown_ekus = 10399ebb4caSwyllys get_boolean(optarg_av); 10499ebb4caSwyllys if (plc.ignore_unknown_ekus == -1) { 10599ebb4caSwyllys (void) fprintf(stderr, 10699ebb4caSwyllys gettext("Error boolean input.\n")); 10799ebb4caSwyllys rv = KC_ERR_USAGE; 10899ebb4caSwyllys } 10999ebb4caSwyllys break; 11099ebb4caSwyllys case 'a': 11199ebb4caSwyllys plc.ignore_trust_anchor = 11299ebb4caSwyllys get_boolean(optarg_av); 11399ebb4caSwyllys if (plc.ignore_trust_anchor == -1) { 11499ebb4caSwyllys (void) fprintf(stderr, 11599ebb4caSwyllys gettext("Error boolean input.\n")); 11699ebb4caSwyllys rv = KC_ERR_USAGE; 11799ebb4caSwyllys } 11899ebb4caSwyllys break; 11999ebb4caSwyllys case 'v': 12099ebb4caSwyllys plc.validity_adjusttime = 12199ebb4caSwyllys get_string(optarg_av, &rv); 12299ebb4caSwyllys if (plc.validity_adjusttime == NULL) { 12399ebb4caSwyllys (void) fprintf(stderr, 12499ebb4caSwyllys gettext("Error time input.\n")); 12599ebb4caSwyllys } else { 12699ebb4caSwyllys uint32_t adj; 12799ebb4caSwyllys /* for syntax checking */ 12899ebb4caSwyllys if (str2lifetime( 12999ebb4caSwyllys plc.validity_adjusttime, 13099ebb4caSwyllys &adj) < 0) { 13199ebb4caSwyllys (void) fprintf(stderr, 13299ebb4caSwyllys gettext("Error time " 13399ebb4caSwyllys "input.\n")); 13499ebb4caSwyllys rv = KC_ERR_USAGE; 13599ebb4caSwyllys } 13699ebb4caSwyllys } 13799ebb4caSwyllys break; 13899ebb4caSwyllys case 't': 13999ebb4caSwyllys plc.ta_name = get_string(optarg_av, &rv); 14099ebb4caSwyllys if (plc.ta_name == NULL) { 14199ebb4caSwyllys (void) fprintf(stderr, 14299ebb4caSwyllys gettext("Error name input.\n")); 14399ebb4caSwyllys } else { 14499ebb4caSwyllys KMF_X509_NAME taDN; 14599ebb4caSwyllys /* for syntax checking */ 14630a5e8faSwyllys if (kmf_dn_parser(plc.ta_name, 14799ebb4caSwyllys &taDN) != KMF_OK) { 14899ebb4caSwyllys (void) fprintf(stderr, 14999ebb4caSwyllys gettext("Error name " 15099ebb4caSwyllys "input.\n")); 15199ebb4caSwyllys rv = KC_ERR_USAGE; 15299ebb4caSwyllys } else { 15330a5e8faSwyllys kmf_free_dn(&taDN); 15499ebb4caSwyllys } 15599ebb4caSwyllys } 15699ebb4caSwyllys break; 15799ebb4caSwyllys case 's': 15899ebb4caSwyllys plc.ta_serial = get_string(optarg_av, &rv); 15999ebb4caSwyllys if (plc.ta_serial == NULL) { 16099ebb4caSwyllys (void) fprintf(stderr, 16199ebb4caSwyllys gettext("Error serial input.\n")); 16299ebb4caSwyllys } else { 16399ebb4caSwyllys uchar_t *bytes = NULL; 16499ebb4caSwyllys size_t bytelen; 16599ebb4caSwyllys 16630a5e8faSwyllys ret = kmf_hexstr_to_bytes( 16799ebb4caSwyllys (uchar_t *)plc.ta_serial, 16899ebb4caSwyllys &bytes, &bytelen); 16999ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 17099ebb4caSwyllys (void) fprintf(stderr, 17199ebb4caSwyllys gettext("serial number " 17299ebb4caSwyllys "must be specified as a " 17399ebb4caSwyllys "hex number " 17499ebb4caSwyllys "(ex: 0x0102030405" 17599ebb4caSwyllys "ffeeddee)\n")); 17699ebb4caSwyllys rv = KC_ERR_USAGE; 17799ebb4caSwyllys } 17899ebb4caSwyllys if (bytes != NULL) 17999ebb4caSwyllys free(bytes); 18099ebb4caSwyllys } 18199ebb4caSwyllys break; 18299ebb4caSwyllys case 'o': 18399ebb4caSwyllys plc.VAL_OCSP_RESPONDER_URI = 18499ebb4caSwyllys get_string(optarg_av, &rv); 18599ebb4caSwyllys if (plc.VAL_OCSP_RESPONDER_URI == NULL) { 18699ebb4caSwyllys (void) fprintf(stderr, gettext( 18799ebb4caSwyllys "Error responder input.\n")); 18899ebb4caSwyllys } else { 18999ebb4caSwyllys ocsp_set_attr++; 19099ebb4caSwyllys } 19199ebb4caSwyllys break; 19299ebb4caSwyllys case 'P': 19399ebb4caSwyllys plc.VAL_OCSP_PROXY = 19499ebb4caSwyllys get_string(optarg_av, &rv); 19599ebb4caSwyllys if (plc.VAL_OCSP_PROXY == NULL) { 19699ebb4caSwyllys (void) fprintf(stderr, 19799ebb4caSwyllys gettext("Error proxy input.\n")); 19899ebb4caSwyllys } else { 19999ebb4caSwyllys ocsp_set_attr++; 20099ebb4caSwyllys } 20199ebb4caSwyllys break; 20299ebb4caSwyllys case 'r': 20399ebb4caSwyllys plc.VAL_OCSP_URI_FROM_CERT = 20499ebb4caSwyllys get_boolean(optarg_av); 20599ebb4caSwyllys if (plc.VAL_OCSP_URI_FROM_CERT == -1) { 20699ebb4caSwyllys (void) fprintf(stderr, 20799ebb4caSwyllys gettext("Error boolean input.\n")); 20899ebb4caSwyllys rv = KC_ERR_USAGE; 20999ebb4caSwyllys } else { 21099ebb4caSwyllys ocsp_set_attr++; 21199ebb4caSwyllys } 21299ebb4caSwyllys break; 21399ebb4caSwyllys case 'T': 21499ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME = 21599ebb4caSwyllys get_string(optarg_av, &rv); 21699ebb4caSwyllys if (plc.VAL_OCSP_RESP_LIFETIME == NULL) { 21799ebb4caSwyllys (void) fprintf(stderr, 21899ebb4caSwyllys gettext("Error time input.\n")); 21999ebb4caSwyllys } else { 22099ebb4caSwyllys uint32_t adj; 22199ebb4caSwyllys /* for syntax checking */ 22299ebb4caSwyllys if (str2lifetime( 22399ebb4caSwyllys plc.VAL_OCSP_RESP_LIFETIME, 22499ebb4caSwyllys &adj) < 0) { 22599ebb4caSwyllys (void) fprintf(stderr, 22699ebb4caSwyllys gettext("Error time " 22799ebb4caSwyllys "input.\n")); 22899ebb4caSwyllys rv = KC_ERR_USAGE; 22999ebb4caSwyllys } else { 23099ebb4caSwyllys ocsp_set_attr++; 23199ebb4caSwyllys } 23299ebb4caSwyllys } 23399ebb4caSwyllys break; 23499ebb4caSwyllys case 'R': 23599ebb4caSwyllys plc.VAL_OCSP_IGNORE_RESP_SIGN = 23699ebb4caSwyllys get_boolean(optarg_av); 23799ebb4caSwyllys if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) { 23899ebb4caSwyllys (void) fprintf(stderr, 23999ebb4caSwyllys gettext("Error boolean input.\n")); 24099ebb4caSwyllys rv = KC_ERR_USAGE; 24199ebb4caSwyllys } else { 24299ebb4caSwyllys ocsp_set_attr++; 24399ebb4caSwyllys } 24499ebb4caSwyllys break; 24599ebb4caSwyllys case 'n': 24699ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME = 24799ebb4caSwyllys get_string(optarg_av, &rv); 24899ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) { 24999ebb4caSwyllys (void) fprintf(stderr, 25099ebb4caSwyllys gettext("Error name input.\n")); 25199ebb4caSwyllys } else { 25299ebb4caSwyllys KMF_X509_NAME respDN; 25399ebb4caSwyllys /* for syntax checking */ 25430a5e8faSwyllys if (kmf_dn_parser( 25599ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_NAME, 25699ebb4caSwyllys &respDN) != KMF_OK) { 25799ebb4caSwyllys (void) fprintf(stderr, 25899ebb4caSwyllys gettext("Error name " 25999ebb4caSwyllys "input.\n")); 26099ebb4caSwyllys rv = KC_ERR_USAGE; 26199ebb4caSwyllys } else { 26230a5e8faSwyllys kmf_free_dn(&respDN); 26399ebb4caSwyllys ocsp_set_attr++; 26499ebb4caSwyllys } 26599ebb4caSwyllys } 26699ebb4caSwyllys break; 26799ebb4caSwyllys case 'A': 26899ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL = 26999ebb4caSwyllys get_string(optarg_av, &rv); 27099ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) { 27199ebb4caSwyllys (void) fprintf(stderr, 27299ebb4caSwyllys gettext("Error serial input.\n")); 27399ebb4caSwyllys } else { 27499ebb4caSwyllys uchar_t *bytes = NULL; 27599ebb4caSwyllys size_t bytelen; 27699ebb4caSwyllys 27730a5e8faSwyllys ret = kmf_hexstr_to_bytes((uchar_t *) 27899ebb4caSwyllys plc.VAL_OCSP_RESP_CERT_SERIAL, 27999ebb4caSwyllys &bytes, &bytelen); 28099ebb4caSwyllys if (ret != KMF_OK || bytes == NULL) { 28199ebb4caSwyllys (void) fprintf(stderr, 28299ebb4caSwyllys gettext("serial number " 28399ebb4caSwyllys "must be specified as a " 28499ebb4caSwyllys "hex number " 28599ebb4caSwyllys "(ex: 0x0102030405" 28699ebb4caSwyllys "ffeeddee)\n")); 28799ebb4caSwyllys rv = KC_ERR_USAGE; 28899ebb4caSwyllys break; 28999ebb4caSwyllys } 29099ebb4caSwyllys if (bytes != NULL) 29199ebb4caSwyllys free(bytes); 29299ebb4caSwyllys ocsp_set_attr++; 29399ebb4caSwyllys } 29499ebb4caSwyllys break; 29599ebb4caSwyllys case 'c': 29699ebb4caSwyllys plc.VAL_CRL_BASEFILENAME = 29799ebb4caSwyllys get_string(optarg_av, &rv); 29899ebb4caSwyllys if (plc.VAL_CRL_BASEFILENAME == NULL) { 29999ebb4caSwyllys (void) fprintf(stderr, 30099ebb4caSwyllys gettext("Error boolean input.\n")); 30199ebb4caSwyllys } else { 30299ebb4caSwyllys crl_set_attr++; 30399ebb4caSwyllys } 30499ebb4caSwyllys break; 30599ebb4caSwyllys case 'I': 30699ebb4caSwyllys plc.VAL_CRL_DIRECTORY = 30799ebb4caSwyllys get_string(optarg_av, &rv); 30899ebb4caSwyllys if (plc.VAL_CRL_DIRECTORY == NULL) { 30999ebb4caSwyllys (void) fprintf(stderr, 31099ebb4caSwyllys gettext("Error boolean input.\n")); 31199ebb4caSwyllys } else { 31299ebb4caSwyllys crl_set_attr++; 31399ebb4caSwyllys } 31499ebb4caSwyllys break; 31599ebb4caSwyllys case 'g': 31699ebb4caSwyllys plc.VAL_CRL_GET_URI = get_boolean(optarg_av); 31799ebb4caSwyllys if (plc.VAL_CRL_GET_URI == -1) { 31899ebb4caSwyllys (void) fprintf(stderr, 31999ebb4caSwyllys gettext("Error boolean input.\n")); 32099ebb4caSwyllys rv = KC_ERR_USAGE; 32199ebb4caSwyllys } else { 32299ebb4caSwyllys crl_set_attr++; 32399ebb4caSwyllys } 32499ebb4caSwyllys break; 32599ebb4caSwyllys case 'X': 32699ebb4caSwyllys plc.VAL_CRL_PROXY = get_string(optarg_av, &rv); 32799ebb4caSwyllys if (plc.VAL_CRL_PROXY == NULL) { 32899ebb4caSwyllys (void) fprintf(stderr, 32999ebb4caSwyllys gettext("Error proxy input.\n")); 33099ebb4caSwyllys } else { 33199ebb4caSwyllys crl_set_attr++; 33299ebb4caSwyllys } 33399ebb4caSwyllys break; 33499ebb4caSwyllys case 'S': 33599ebb4caSwyllys plc.VAL_CRL_IGNORE_SIGN = 33699ebb4caSwyllys get_boolean(optarg_av); 33799ebb4caSwyllys if (plc.VAL_CRL_IGNORE_SIGN == -1) { 33899ebb4caSwyllys (void) fprintf(stderr, 33999ebb4caSwyllys gettext("Error boolean input.\n")); 34099ebb4caSwyllys rv = KC_ERR_USAGE; 34199ebb4caSwyllys } else { 34299ebb4caSwyllys crl_set_attr++; 34399ebb4caSwyllys } 34499ebb4caSwyllys break; 34599ebb4caSwyllys case 'D': 34699ebb4caSwyllys plc.VAL_CRL_IGNORE_DATE = 34799ebb4caSwyllys get_boolean(optarg_av); 34899ebb4caSwyllys if (plc.VAL_CRL_IGNORE_DATE == -1) { 34999ebb4caSwyllys (void) fprintf(stderr, 35099ebb4caSwyllys gettext("Error boolean input.\n")); 35199ebb4caSwyllys rv = KC_ERR_USAGE; 35299ebb4caSwyllys } else { 35399ebb4caSwyllys crl_set_attr++; 35499ebb4caSwyllys } 35599ebb4caSwyllys break; 35699ebb4caSwyllys case 'u': 35799ebb4caSwyllys plc.ku_bits = parseKUlist(optarg_av); 35899ebb4caSwyllys if (plc.ku_bits == 0) { 35999ebb4caSwyllys (void) fprintf(stderr, gettext( 36099ebb4caSwyllys "Error keyusage input.\n")); 36199ebb4caSwyllys rv = KC_ERR_USAGE; 36299ebb4caSwyllys } 36399ebb4caSwyllys break; 36499ebb4caSwyllys case 'E': 36599ebb4caSwyllys if (parseEKUNames(optarg_av, &plc) != 0) { 36699ebb4caSwyllys (void) fprintf(stderr, 36799ebb4caSwyllys gettext("Error EKU input.\n")); 36899ebb4caSwyllys rv = KC_ERR_USAGE; 36999ebb4caSwyllys } 37099ebb4caSwyllys break; 37199ebb4caSwyllys case 'O': 37299ebb4caSwyllys if (parseEKUOIDs(optarg_av, &plc) != 0) { 37399ebb4caSwyllys (void) fprintf(stderr, 37499ebb4caSwyllys gettext("Error EKU OID input.\n")); 37599ebb4caSwyllys rv = KC_ERR_USAGE; 37699ebb4caSwyllys } 37799ebb4caSwyllys break; 378*269e59f9SJan Pechanec case 'm': 379*269e59f9SJan Pechanec plc.mapper.mapname = get_string(optarg_av, &rv); 380*269e59f9SJan Pechanec if (plc.mapper.mapname == NULL) { 381*269e59f9SJan Pechanec (void) fprintf(stderr, 382*269e59f9SJan Pechanec gettext("Error mapper-name " 383*269e59f9SJan Pechanec "input.\n")); 384*269e59f9SJan Pechanec } 385*269e59f9SJan Pechanec break; 386*269e59f9SJan Pechanec case 'M': 387*269e59f9SJan Pechanec plc.mapper.dir = get_string(optarg_av, &rv); 388*269e59f9SJan Pechanec if (plc.mapper.dir == NULL) { 389*269e59f9SJan Pechanec (void) fprintf(stderr, 390*269e59f9SJan Pechanec gettext("Error mapper-dir " 391*269e59f9SJan Pechanec "input.\n")); 392*269e59f9SJan Pechanec } 393*269e59f9SJan Pechanec break; 394*269e59f9SJan Pechanec case 'Q': 395*269e59f9SJan Pechanec plc.mapper.pathname = get_string(optarg_av, 396*269e59f9SJan Pechanec &rv); 397*269e59f9SJan Pechanec if (plc.mapper.pathname == NULL) { 398*269e59f9SJan Pechanec (void) fprintf(stderr, 399*269e59f9SJan Pechanec gettext("Error mapper-pathname " 400*269e59f9SJan Pechanec "input.\n")); 401*269e59f9SJan Pechanec } 402*269e59f9SJan Pechanec break; 403*269e59f9SJan Pechanec case 'q': 404*269e59f9SJan Pechanec plc.mapper.options = get_string(optarg_av, &rv); 405*269e59f9SJan Pechanec if (plc.mapper.options == NULL) { 406*269e59f9SJan Pechanec (void) fprintf(stderr, 407*269e59f9SJan Pechanec gettext("Error mapper-options " 408*269e59f9SJan Pechanec "input.\n")); 409*269e59f9SJan Pechanec } 410*269e59f9SJan Pechanec break; 41199ebb4caSwyllys default: 41299ebb4caSwyllys (void) fprintf(stderr, 41399ebb4caSwyllys gettext("Error input option.\n")); 41499ebb4caSwyllys rv = KC_ERR_USAGE; 41599ebb4caSwyllys break; 41699ebb4caSwyllys } 41799ebb4caSwyllys 41899ebb4caSwyllys if (rv != KC_OK) 41999ebb4caSwyllys goto out; 42099ebb4caSwyllys } 42199ebb4caSwyllys 42299ebb4caSwyllys /* No additional args allowed. */ 42399ebb4caSwyllys argc -= optind_av; 42499ebb4caSwyllys if (argc) { 42599ebb4caSwyllys (void) fprintf(stderr, 42699ebb4caSwyllys gettext("Error input option\n")); 42799ebb4caSwyllys rv = KC_ERR_USAGE; 42899ebb4caSwyllys goto out; 42999ebb4caSwyllys } 43099ebb4caSwyllys 43199ebb4caSwyllys if (filename == NULL) { 43299ebb4caSwyllys filename = strdup(KMF_DEFAULT_POLICY_FILE); 43399ebb4caSwyllys if (filename == NULL) { 43499ebb4caSwyllys rv = KC_ERR_MEMORY; 43599ebb4caSwyllys goto out; 43699ebb4caSwyllys } 43799ebb4caSwyllys } 43899ebb4caSwyllys 43999ebb4caSwyllys /* 44099ebb4caSwyllys * Must have a policy name. The policy name can not be default 44199ebb4caSwyllys * if using the default policy file. 44299ebb4caSwyllys */ 44399ebb4caSwyllys if (plc.name == NULL) { 44499ebb4caSwyllys (void) fprintf(stderr, 44599ebb4caSwyllys gettext("You must specify a policy name\n")); 44699ebb4caSwyllys rv = KC_ERR_USAGE; 44799ebb4caSwyllys goto out; 44899ebb4caSwyllys } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && 44999ebb4caSwyllys strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) { 45099ebb4caSwyllys (void) fprintf(stderr, 45199ebb4caSwyllys gettext("Can not create a default policy in the default " 45299ebb4caSwyllys "policy file\n")); 45399ebb4caSwyllys rv = KC_ERR_USAGE; 45499ebb4caSwyllys goto out; 45599ebb4caSwyllys } 45699ebb4caSwyllys 45799ebb4caSwyllys /* 45899ebb4caSwyllys * If the policy file exists and the policy is in the policy file 45999ebb4caSwyllys * already, we will not create it again. 46099ebb4caSwyllys */ 46199ebb4caSwyllys if (access(filename, R_OK) == 0) { 46299ebb4caSwyllys POLICY_LIST *plclist = NULL, *pnode; 46399ebb4caSwyllys int found = 0; 46499ebb4caSwyllys 46599ebb4caSwyllys rv = load_policies(filename, &plclist); 46699ebb4caSwyllys if (rv != KMF_OK) 46799ebb4caSwyllys goto out; 46899ebb4caSwyllys 46999ebb4caSwyllys pnode = plclist; 47099ebb4caSwyllys while (pnode != NULL && !found) { 47199ebb4caSwyllys if (strcmp(plc.name, pnode->plc.name) == 0) 47299ebb4caSwyllys found++; 47399ebb4caSwyllys pnode = pnode->next; 47499ebb4caSwyllys } 47599ebb4caSwyllys free_policy_list(plclist); 47699ebb4caSwyllys 47799ebb4caSwyllys if (found) { 47899ebb4caSwyllys (void) fprintf(stderr, 47999ebb4caSwyllys gettext("Could not create policy \"%s\" - exists " 48099ebb4caSwyllys "already\n"), plc.name); 48199ebb4caSwyllys rv = KC_ERR_USAGE; 48299ebb4caSwyllys goto out; 48399ebb4caSwyllys } 48499ebb4caSwyllys } 48599ebb4caSwyllys 48699ebb4caSwyllys /* 48799ebb4caSwyllys * If any OCSP attribute is set, turn on the OCSP checking flag. 48899ebb4caSwyllys * Also set "has_resp_cert" to be true, if the responder cert 48999ebb4caSwyllys * is provided. 49099ebb4caSwyllys */ 49199ebb4caSwyllys if (ocsp_set_attr > 0) 49299ebb4caSwyllys plc.revocation |= KMF_REVOCATION_METHOD_OCSP; 49399ebb4caSwyllys 49499ebb4caSwyllys if (plc.VAL_OCSP_RESP_CERT.name != NULL && 49599ebb4caSwyllys plc.VAL_OCSP_RESP_CERT.serial != NULL) { 49699ebb4caSwyllys plc.VAL_OCSP.has_resp_cert = B_TRUE; 49799ebb4caSwyllys } 49899ebb4caSwyllys 49999ebb4caSwyllys /* 500*269e59f9SJan Pechanec * Setting mapper-name (with optional mapper-dir) and mapper-pathname is 501*269e59f9SJan Pechanec * mutually exclusive. Also, you cannot set options only, you need the 502*269e59f9SJan Pechanec * name or pathname, and you can set the directory only with the name, 503*269e59f9SJan Pechanec * not the pathname. 504*269e59f9SJan Pechanec */ 505*269e59f9SJan Pechanec if ((plc.mapper.mapname != NULL && plc.mapper.pathname != NULL) || 506*269e59f9SJan Pechanec (plc.mapper.dir != NULL && plc.mapper.pathname != NULL) || 507*269e59f9SJan Pechanec (plc.mapper.dir != NULL && plc.mapper.mapname == NULL) || 508*269e59f9SJan Pechanec (plc.mapper.options != NULL && plc.mapper.mapname == NULL && 509*269e59f9SJan Pechanec plc.mapper.pathname == NULL)) { 510*269e59f9SJan Pechanec (void) fprintf(stderr, 511*269e59f9SJan Pechanec gettext("Error in mapper input options\n")); 512*269e59f9SJan Pechanec rv = KC_ERR_USAGE; 513*269e59f9SJan Pechanec goto out; 514*269e59f9SJan Pechanec } 515*269e59f9SJan Pechanec 516*269e59f9SJan Pechanec /* 51799ebb4caSwyllys * If any CRL attribute is set, turn on the CRL checking flag. 51899ebb4caSwyllys */ 51999ebb4caSwyllys if (crl_set_attr > 0) 52099ebb4caSwyllys plc.revocation |= KMF_REVOCATION_METHOD_CRL; 52199ebb4caSwyllys 52299ebb4caSwyllys /* 52399ebb4caSwyllys * Does a sanity check on the new policy. 52499ebb4caSwyllys */ 52530a5e8faSwyllys ret = kmf_verify_policy(&plc); 52699ebb4caSwyllys if (ret != KMF_OK) { 52799ebb4caSwyllys print_sanity_error(ret); 52899ebb4caSwyllys rv = KC_ERR_ADD_POLICY; 52999ebb4caSwyllys goto out; 53099ebb4caSwyllys } 53199ebb4caSwyllys 53299ebb4caSwyllys /* 53399ebb4caSwyllys * Add to the DB. 53499ebb4caSwyllys */ 53530a5e8faSwyllys ret = kmf_add_policy_to_db(&plc, filename, B_FALSE); 53699ebb4caSwyllys if (ret != KMF_OK) { 53799ebb4caSwyllys (void) fprintf(stderr, 53899ebb4caSwyllys gettext("Error adding policy to database: 0x%04x\n"), ret); 53999ebb4caSwyllys rv = KC_ERR_ADD_POLICY; 54099ebb4caSwyllys } 54199ebb4caSwyllys 54299ebb4caSwyllys out: 54399ebb4caSwyllys if (filename != NULL) 54499ebb4caSwyllys free(filename); 54599ebb4caSwyllys 54630a5e8faSwyllys kmf_free_policy_record(&plc); 54799ebb4caSwyllys 54899ebb4caSwyllys return (rv); 54999ebb4caSwyllys } 550