Home | History | Annotate | Download | only in kmfcfg
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  *
     21  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     22  * Use is subject to license terms.
     23  */
     24 
     25 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     26 
     27 #include <stdio.h>
     28 #include <strings.h>
     29 #include <ctype.h>
     30 #include <libgen.h>
     31 #include <libintl.h>
     32 #include <errno.h>
     33 #include <sys/stat.h>
     34 #include <kmfapiP.h>
     35 #include "util.h"
     36 
     37 #define	LIB_NSS_PATH	"/usr/lib/mps/libnss3.so"
     38 #define	LIB_NSPR_PATH	"/usr/lib/mps/libnspr4.so"
     39 
     40 static void
     41 show_policy(KMF_POLICY_RECORD *plc)
     42 {
     43 	int i;
     44 	if (plc == NULL)
     45 		return;
     46 
     47 	(void) printf("Name: %s\n", plc->name);
     48 
     49 	(void) printf(gettext("Ignore Date: %s\n"),
     50 	    plc->ignore_date ? gettext("true") : gettext("false"));
     51 
     52 	(void) printf(gettext("Ignore Unknown EKUs: %s\n"),
     53 	    plc->ignore_unknown_ekus ? gettext("true") : gettext("false"));
     54 
     55 	(void) printf(gettext("Ignore TA: %s\n"),
     56 	    plc->ignore_trust_anchor ? gettext("true") : gettext("false"));
     57 
     58 	(void) printf(gettext("Validity Adjusted Time: %s\n"),
     59 	    plc->validity_adjusttime ? plc->validity_adjusttime : "<null>");
     60 
     61 	if (plc->ta_name == NULL && plc->ta_serial == NULL) {
     62 		(void) printf(gettext("Trust Anchor Certificate: <null>\n"));
     63 	} else {
     64 		(void) printf(gettext("Trust Anchor Certificate:\n"));
     65 		(void) printf(gettext("\tName: %s\n"),
     66 		    plc->ta_name ? plc->ta_name : "<null>");
     67 		(void) printf(gettext("\tSerial Number: %s\n"),
     68 		    plc->ta_serial ? plc->ta_serial : "<null>");
     69 	}
     70 
     71 	if (plc->ku_bits != 0) {
     72 		(void) printf(gettext("Key Usage Bits: "));
     73 		for (i = KULOWBIT; i <= KUHIGHBIT; i++) {
     74 			char *s = kmf_ku_to_string(
     75 			    (plc->ku_bits & (1<<i)));
     76 			if (s != NULL) {
     77 				(void) printf("%s ", s);
     78 			}
     79 		}
     80 		(void) printf("\n");
     81 	} else {
     82 		(void) printf(gettext("Key Usage Bits: 0\n"));
     83 	}
     84 
     85 	if (plc->eku_set.eku_count > 0) {
     86 		(void) printf(gettext("Extended Key Usage Values:\n"));
     87 		for (i = 0; i < plc->eku_set.eku_count; i++) {
     88 			char *s = kmf_oid_to_ekuname(
     89 			    &plc->eku_set.ekulist[i]);
     90 			(void) printf("\t%s\t(%s)\n",
     91 			    kmf_oid_to_string(&plc->eku_set.ekulist[i]),
     92 			    s ? s : "unknown");
     93 		}
     94 	} else {
     95 		(void) printf(gettext("Extended Key Usage Values: <null>\n"));
     96 	}
     97 
     98 	(void) printf(gettext("Validation Policy Information:\n"));
     99 
    100 	if (plc->revocation & KMF_REVOCATION_METHOD_OCSP) {
    101 		(void) printf(gettext("    OCSP:\n"));
    102 
    103 		(void) printf(gettext("\tResponder URI: %s\n"),
    104 		    plc->VAL_OCSP_BASIC.responderURI ?
    105 		    plc->VAL_OCSP_BASIC.responderURI : "<null>");
    106 
    107 		(void) printf(gettext("\tProxy: %s\n"),
    108 		    plc->VAL_OCSP_BASIC.proxy ?
    109 		    plc->VAL_OCSP_BASIC.proxy : "<null>");
    110 
    111 		(void) printf(gettext("\tUse ResponderURI from Certificate: "
    112 		    "%s\n"), plc->VAL_OCSP_BASIC.uri_from_cert ?
    113 		    gettext("true") : gettext("false"));
    114 
    115 		(void) printf(gettext("\tResponse lifetime: %s\n"),
    116 		    plc->VAL_OCSP_BASIC.response_lifetime ?
    117 		    plc->VAL_OCSP_BASIC.response_lifetime : "<null>");
    118 
    119 		(void) printf(gettext("\tIgnore Response signature: %s\n"),
    120 		    plc->VAL_OCSP_BASIC.ignore_response_sign ?
    121 		    gettext("true") : gettext("false"));
    122 
    123 		if (!plc->VAL_OCSP.has_resp_cert) {
    124 			(void) printf(gettext("\tResponder Certificate:"
    125 			    " <null>\n"));
    126 		} else {
    127 			(void) printf(gettext("\tResponder Certificate:\n"));
    128 			(void) printf(gettext("\t\tName: %s\n"),
    129 			    plc->VAL_OCSP_RESP_CERT.name ?
    130 			    plc->VAL_OCSP_RESP_CERT.name : "<null>");
    131 			(void) printf(gettext("\t\tSerial: %s\n"),
    132 			    plc->VAL_OCSP_RESP_CERT.serial ?
    133 			    plc->VAL_OCSP_RESP_CERT.serial : "<null>");
    134 		}
    135 	}
    136 
    137 	if (plc->revocation & KMF_REVOCATION_METHOD_CRL) {
    138 		(void) printf(gettext("    CRL:\n"));
    139 
    140 		(void) printf(gettext("\tBase filename: %s\n"),
    141 		    plc->validation_info.crl_info.basefilename ?
    142 		    plc->validation_info.crl_info.basefilename : "<null>");
    143 
    144 		(void) printf(gettext("\tDirectory: %s\n"),
    145 		    plc->validation_info.crl_info.directory ?
    146 		    plc->validation_info.crl_info.directory : "<null>");
    147 
    148 		(void) printf(gettext("\tDownload and cache CRL: %s\n"),
    149 		    plc->validation_info.crl_info.get_crl_uri ?
    150 		    gettext("true") : gettext("false"));
    151 
    152 		(void) printf(gettext("\tProxy: %s\n"),
    153 		    plc->validation_info.crl_info.proxy ?
    154 		    plc->validation_info.crl_info.proxy : "<null>");
    155 
    156 		(void) printf(gettext("\tIgnore CRL signature: %s\n"),
    157 		    plc->validation_info.crl_info.ignore_crl_sign ?
    158 		    gettext("true") : gettext("false"));
    159 
    160 		(void) printf(gettext("\tIgnore CRL validity date: %s\n"),
    161 		    plc->validation_info.crl_info.ignore_crl_date ?
    162 		    gettext("true") : gettext("false"));
    163 	}
    164 
    165 	(void) printf("\n");
    166 }
    167 
    168 void
    169 show_plugin(void)
    170 {
    171 	conf_entrylist_t *phead = NULL;
    172 	struct stat 	statbuf;
    173 
    174 	(void) printf(gettext("KMF plugin information:\n"));
    175 	(void) printf(gettext("-----------------------\n"));
    176 
    177 	/* List the built-in plugins */
    178 	(void) printf("pkcs11:kmf_pkcs11.so.1 (built-in)\n");
    179 	(void) printf("file:kmf_openssl.so.1 (built-in)\n");
    180 
    181 	/*
    182 	 * If the NSS libraries are not installed in the system,
    183 	 * then we will not show the nss plugin either.
    184 	 */
    185 	if (stat(LIB_NSS_PATH, &statbuf) == 0 &&
    186 	    stat(LIB_NSPR_PATH, &statbuf) == 0) {
    187 		(void) printf("nss:kmf_nss.so.1 (built-in)\n");
    188 	}
    189 
    190 	/* List non-default plugins, if there is any. */
    191 	if (get_entrylist(&phead) == KMF_OK) {
    192 		while (phead != NULL) {
    193 			(void) printf("%s:%s", phead->entry->keystore,
    194 			    phead->entry->modulepath);
    195 
    196 			if (phead->entry->option == NULL)
    197 				(void) printf("\n");
    198 			else
    199 				(void) printf(";option=%s\n",
    200 				    phead->entry->option);
    201 			phead = phead->next;
    202 		}
    203 		free_entrylist(phead);
    204 	}
    205 }
    206 
    207 
    208 int
    209 kc_list(int argc, char *argv[])
    210 {
    211 	int 		rv = KC_OK;
    212 	int		opt, found = 0;
    213 	extern int	optind_av;
    214 	extern char	*optarg_av;
    215 	char		*filename = NULL;
    216 	char		*policyname = NULL;
    217 	POLICY_LIST	*plclist = NULL, *pnode;
    218 	int		sanity_err = 0;
    219 	boolean_t	list_plugin = B_FALSE;
    220 
    221 	while ((opt = getopt_av(argc, argv, "i:(dbfile)p:(policy)m(plugin)"))
    222 	    != EOF) {
    223 		switch (opt) {
    224 		case 'i':
    225 			if (list_plugin)
    226 				rv = KC_ERR_USAGE;
    227 			else {
    228 				filename = get_string(optarg_av, &rv);
    229 				if (filename == NULL) {
    230 					(void) fprintf(stderr,
    231 					    gettext("Error dbfile input.\n"));
    232 				}
    233 			}
    234 			break;
    235 		case 'p':
    236 			if (list_plugin)
    237 				rv = KC_ERR_USAGE;
    238 			else {
    239 				policyname = get_string(optarg_av, &rv);
    240 				if (policyname == NULL) {
    241 					(void) fprintf(stderr,
    242 					    gettext("Error policy name.\n"));
    243 				}
    244 			}
    245 			break;
    246 		case 'm':
    247 			list_plugin = B_TRUE;
    248 			break;
    249 		default:
    250 			(void) fprintf(stderr,
    251 			    gettext("Error input option.\n"));
    252 			rv = KC_ERR_USAGE;
    253 			break;
    254 		}
    255 		if (rv != KC_OK)
    256 			goto out;
    257 	}
    258 
    259 	/* No additional args allowed. */
    260 	argc -= optind_av;
    261 	if (argc) {
    262 		(void) fprintf(stderr,
    263 		    gettext("Error input option\n"));
    264 		rv = KC_ERR_USAGE;
    265 		goto out;
    266 	}
    267 
    268 	if (list_plugin) {
    269 		show_plugin();
    270 		goto out;
    271 	}
    272 
    273 	if (filename == NULL) {
    274 		filename = strdup(KMF_DEFAULT_POLICY_FILE);
    275 		if (filename == NULL) {
    276 			rv = KC_ERR_MEMORY;
    277 			goto out;
    278 		}
    279 	}
    280 
    281 	/* Check the access permission of the policy DB */
    282 	if (access(filename, R_OK) < 0) {
    283 		int err = errno;
    284 		(void) fprintf(stderr,
    285 		    gettext("Cannot access \"%s\" for list - %s\n"), filename,
    286 		    strerror(err));
    287 		rv = KC_ERR_ACCESS;
    288 		goto out;
    289 	}
    290 
    291 	rv = load_policies(filename, &plclist);
    292 	if (rv != KMF_OK) {
    293 		goto out;
    294 	}
    295 
    296 	pnode = plclist;
    297 	while (pnode != NULL) {
    298 		if (policyname == NULL ||
    299 		    strcmp(policyname, pnode->plc.name) == 0) {
    300 			KMF_POLICY_RECORD *plc = &pnode->plc;
    301 
    302 			found++;
    303 			rv = kmf_verify_policy(plc);
    304 			if (rv != KMF_OK) {
    305 				(void) fprintf(stderr, gettext(
    306 				    "Policy Name: '%s' is invalid\n"),
    307 				    plc->name);
    308 				sanity_err++;
    309 			} else {
    310 				show_policy(&pnode->plc);
    311 			}
    312 		}
    313 		pnode = pnode->next;
    314 	}
    315 
    316 	free_policy_list(plclist);
    317 
    318 	if (!found) {
    319 		if (policyname)
    320 			(void) fprintf(stderr, gettext(
    321 			    "Cannot find policy '%s'\n"), policyname);
    322 		else
    323 			(void) fprintf(stderr, gettext("Cannot find "
    324 			    "any policies to display\n"));
    325 		rv = KC_ERR_FIND_POLICY;
    326 	} else if (sanity_err) {
    327 		rv = KC_ERR_VERIFY_POLICY;
    328 	}
    329 
    330 out:
    331 
    332 	if (filename != NULL)
    333 		free(filename);
    334 
    335 	if (policyname != NULL)
    336 		free(policyname);
    337 
    338 	return (rv);
    339 }
    340