17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5004388ebScasper * Common Development and Distribution License (the "License").
6004388ebScasper * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22b5a2d845SHai-May Chao * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <errno.h>
297c478bd9Sstevel@tonic-gate #include <strings.h>
307c478bd9Sstevel@tonic-gate #include <locale.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include "cryptoutil.h"
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate static int uef_interpret(char *, uentry_t **);
357c478bd9Sstevel@tonic-gate static int parse_policylist(char *, uentry_t *);
36*d616ad8eSHai-May Chao static boolean_t is_fips(char *);
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate * Retrieve the user-level provider info from the pkcs11.conf file.
407c478bd9Sstevel@tonic-gate * If successful, the result is returned from the ppliblist argument.
417c478bd9Sstevel@tonic-gate * This function returns SUCCESS if successfully done; otherwise it returns
427c478bd9Sstevel@tonic-gate * FAILURE.
437c478bd9Sstevel@tonic-gate */
447c478bd9Sstevel@tonic-gate int
get_pkcs11conf_info(uentrylist_t ** ppliblist)457c478bd9Sstevel@tonic-gate get_pkcs11conf_info(uentrylist_t **ppliblist)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate FILE *pfile;
487c478bd9Sstevel@tonic-gate char buffer[BUFSIZ];
497c478bd9Sstevel@tonic-gate size_t len;
507c478bd9Sstevel@tonic-gate uentry_t *pent;
517c478bd9Sstevel@tonic-gate uentrylist_t *pentlist;
527c478bd9Sstevel@tonic-gate uentrylist_t *pcur;
537c478bd9Sstevel@tonic-gate int rc = SUCCESS;
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate *ppliblist = NULL;
56004388ebScasper if ((pfile = fopen(_PATH_PKCS11_CONF, "rF")) == NULL) {
577c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to open %s.\n", _PATH_PKCS11_CONF);
587c478bd9Sstevel@tonic-gate return (FAILURE);
597c478bd9Sstevel@tonic-gate }
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) {
627c478bd9Sstevel@tonic-gate if (buffer[0] == '#' || buffer[0] == ' ' ||
637c478bd9Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t') {
647c478bd9Sstevel@tonic-gate continue; /* ignore comment lines */
657c478bd9Sstevel@tonic-gate }
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate len = strlen(buffer);
687c478bd9Sstevel@tonic-gate if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */
697c478bd9Sstevel@tonic-gate len--;
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate buffer[len] = '\0';
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate if ((rc = uef_interpret(buffer, &pent)) != SUCCESS) {
747c478bd9Sstevel@tonic-gate break;
757c478bd9Sstevel@tonic-gate }
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate /* append pent into ppliblist */
787c478bd9Sstevel@tonic-gate pentlist = malloc(sizeof (uentrylist_t));
797c478bd9Sstevel@tonic-gate if (pentlist == NULL) {
807c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "parsing %s, out of memory.\n",
817c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
827c478bd9Sstevel@tonic-gate free_uentry(pent);
837c478bd9Sstevel@tonic-gate rc = FAILURE;
847c478bd9Sstevel@tonic-gate break;
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate pentlist->puent = pent;
877c478bd9Sstevel@tonic-gate pentlist->next = NULL;
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate if (*ppliblist == NULL) {
907c478bd9Sstevel@tonic-gate *ppliblist = pcur = pentlist;
917c478bd9Sstevel@tonic-gate } else {
927c478bd9Sstevel@tonic-gate pcur->next = pentlist;
937c478bd9Sstevel@tonic-gate pcur = pcur->next;
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate (void) fclose(pfile);
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate if (rc != SUCCESS) {
1007c478bd9Sstevel@tonic-gate free_uentrylist(*ppliblist);
1017c478bd9Sstevel@tonic-gate *ppliblist = NULL;
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate return (rc);
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate
107*d616ad8eSHai-May Chao static int
parse_fips_mode(char * buf,boolean_t * mode)108*d616ad8eSHai-May Chao parse_fips_mode(char *buf, boolean_t *mode)
109*d616ad8eSHai-May Chao {
110*d616ad8eSHai-May Chao char *value;
111*d616ad8eSHai-May Chao
112*d616ad8eSHai-May Chao if (strncmp(buf, EF_FIPS_STATUS, sizeof (EF_FIPS_STATUS) - 1) == 0) {
113*d616ad8eSHai-May Chao if (value = strpbrk(buf, SEP_EQUAL)) {
114*d616ad8eSHai-May Chao value++; /* get rid of = */
115*d616ad8eSHai-May Chao if (strcmp(value, DISABLED_KEYWORD) == 0) {
116*d616ad8eSHai-May Chao *mode = B_FALSE;
117*d616ad8eSHai-May Chao } else if (strcmp(value, ENABLED_KEYWORD) == 0) {
118*d616ad8eSHai-May Chao *mode = B_TRUE;
119*d616ad8eSHai-May Chao } else {
120*d616ad8eSHai-May Chao cryptoerror(LOG_ERR, gettext(
121*d616ad8eSHai-May Chao "Failed to parse pkcs11.conf file.\n"));
122*d616ad8eSHai-May Chao return (CKR_FUNCTION_FAILED);
123*d616ad8eSHai-May Chao }
124*d616ad8eSHai-May Chao return (CKR_OK);
125*d616ad8eSHai-May Chao } else {
126*d616ad8eSHai-May Chao return (CKR_FUNCTION_FAILED);
127*d616ad8eSHai-May Chao }
128*d616ad8eSHai-May Chao } else {
129*d616ad8eSHai-May Chao /* should not come here */
130*d616ad8eSHai-May Chao cryptoerror(LOG_ERR, gettext(
131*d616ad8eSHai-May Chao "Failed to parse pkcs11.conf file.\n"));
132*d616ad8eSHai-May Chao return (CKR_FUNCTION_FAILED);
133*d616ad8eSHai-May Chao }
134*d616ad8eSHai-May Chao
135*d616ad8eSHai-May Chao }
1367c478bd9Sstevel@tonic-gate
1377c478bd9Sstevel@tonic-gate /*
1387c478bd9Sstevel@tonic-gate * This routine converts a char string into a uentry_t structure
1397c478bd9Sstevel@tonic-gate * The input string "buf" should be one of the following:
1407c478bd9Sstevel@tonic-gate * library_name
1417c478bd9Sstevel@tonic-gate * library_name:NO_RANDOM
1427c478bd9Sstevel@tonic-gate * library_name:disabledlist=m1,m2,...,mk
1437c478bd9Sstevel@tonic-gate * library_name:disabledlist=m1,m2,...,mk;NO_RANDOM
1447c478bd9Sstevel@tonic-gate * library_name:enabledlist=
1457c478bd9Sstevel@tonic-gate * library_name:enabledlist=;NO_RANDOM
1467c478bd9Sstevel@tonic-gate * library_name:enabledlist=m1,m2,...,mk
1477c478bd9Sstevel@tonic-gate * library_name:enabledlist=m1,m2,...,mk;NO_RANDOM
1487c478bd9Sstevel@tonic-gate * metaslot:status=enabled;enabledlist=m1,m2,....;slot=<slot-description>;\
1497c478bd9Sstevel@tonic-gate * token=<token-label>
1507c478bd9Sstevel@tonic-gate *
1517c478bd9Sstevel@tonic-gate * Note:
1527c478bd9Sstevel@tonic-gate * The mechanisms m1,..mk are in hex form. For example, "0x00000210"
1537c478bd9Sstevel@tonic-gate * for CKM_MD5.
1547c478bd9Sstevel@tonic-gate *
1557c478bd9Sstevel@tonic-gate * For the metaslot entry, "enabledlist", "slot", "auto_key_migrate"
1567c478bd9Sstevel@tonic-gate * or "token" is optional
1577c478bd9Sstevel@tonic-gate */
1587c478bd9Sstevel@tonic-gate static int
uef_interpret(char * buf,uentry_t ** ppent)1597c478bd9Sstevel@tonic-gate uef_interpret(char *buf, uentry_t **ppent)
1607c478bd9Sstevel@tonic-gate {
1617c478bd9Sstevel@tonic-gate uentry_t *pent;
1627c478bd9Sstevel@tonic-gate char *token1;
1637c478bd9Sstevel@tonic-gate char *token2;
1647c478bd9Sstevel@tonic-gate char *lasts;
1657c478bd9Sstevel@tonic-gate int rc;
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate *ppent = NULL;
1687c478bd9Sstevel@tonic-gate if ((token1 = strtok_r(buf, SEP_COLON, &lasts)) == NULL) {
1697c478bd9Sstevel@tonic-gate /* buf is NULL */
1707c478bd9Sstevel@tonic-gate return (FAILURE);
1717c478bd9Sstevel@tonic-gate };
1727c478bd9Sstevel@tonic-gate
1737c478bd9Sstevel@tonic-gate pent = calloc(sizeof (uentry_t), 1);
1747c478bd9Sstevel@tonic-gate if (pent == NULL) {
1757c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "parsing %s, out of memory.\n",
1767c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
1777c478bd9Sstevel@tonic-gate return (FAILURE);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate (void) strlcpy(pent->name, token1, sizeof (pent->name));
180*d616ad8eSHai-May Chao
181*d616ad8eSHai-May Chao if (is_fips(token1)) {
182*d616ad8eSHai-May Chao if ((rc = parse_fips_mode(buf + strlen(token1) + 1,
183*d616ad8eSHai-May Chao &pent->flag_fips_enabled)) != SUCCESS) {
184*d616ad8eSHai-May Chao free_uentry(pent);
185*d616ad8eSHai-May Chao return (rc);
186*d616ad8eSHai-May Chao }
187*d616ad8eSHai-May Chao
188*d616ad8eSHai-May Chao *ppent = pent;
189*d616ad8eSHai-May Chao return (SUCCESS);
190*d616ad8eSHai-May Chao }
191*d616ad8eSHai-May Chao
1927c478bd9Sstevel@tonic-gate /*
1937c478bd9Sstevel@tonic-gate * in case metaslot_auto_key_migrate is not specified, it should
1947c478bd9Sstevel@tonic-gate * be default to true
1957c478bd9Sstevel@tonic-gate */
1967c478bd9Sstevel@tonic-gate pent->flag_metaslot_auto_key_migrate = B_TRUE;
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate while ((token2 = strtok_r(NULL, SEP_SEMICOLON, &lasts)) != NULL) {
1997c478bd9Sstevel@tonic-gate if ((rc = parse_policylist(token2, pent)) != SUCCESS) {
2007c478bd9Sstevel@tonic-gate free_uentry(pent);
2017c478bd9Sstevel@tonic-gate return (rc);
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate *ppent = pent;
2067c478bd9Sstevel@tonic-gate return (SUCCESS);
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate /*
2117c478bd9Sstevel@tonic-gate * This routine parses the policy list and stored the result in the argument
2127c478bd9Sstevel@tonic-gate * pent.
2137c478bd9Sstevel@tonic-gate *
2147c478bd9Sstevel@tonic-gate * Arg buf: input only, its format should be one of the following:
2157c478bd9Sstevel@tonic-gate * enabledlist=
2167c478bd9Sstevel@tonic-gate * enabledlist=m1,m2,...,mk
2177c478bd9Sstevel@tonic-gate * disabledlist=m1,m2,...,mk
2187c478bd9Sstevel@tonic-gate * NO_RANDOM
2197c478bd9Sstevel@tonic-gate * metaslot_status=enabled|disabled
2207c478bd9Sstevel@tonic-gate * metaslot_token=<token-label>
2217c478bd9Sstevel@tonic-gate * metaslot_slot=<slot-description.
2227c478bd9Sstevel@tonic-gate *
2237c478bd9Sstevel@tonic-gate * Arg pent: input/output
2247c478bd9Sstevel@tonic-gate *
2257c478bd9Sstevel@tonic-gate * return: SUCCESS or FAILURE
2267c478bd9Sstevel@tonic-gate */
2277c478bd9Sstevel@tonic-gate static int
parse_policylist(char * buf,uentry_t * pent)2287c478bd9Sstevel@tonic-gate parse_policylist(char *buf, uentry_t *pent)
2297c478bd9Sstevel@tonic-gate {
2307c478bd9Sstevel@tonic-gate umechlist_t *phead = NULL;
2317c478bd9Sstevel@tonic-gate umechlist_t *pcur = NULL;
2327c478bd9Sstevel@tonic-gate umechlist_t *pmech;
2337c478bd9Sstevel@tonic-gate char *next_token;
2347c478bd9Sstevel@tonic-gate char *value;
2357c478bd9Sstevel@tonic-gate char *lasts;
2367c478bd9Sstevel@tonic-gate int count = 0;
2377c478bd9Sstevel@tonic-gate int rc = SUCCESS;
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate if (pent == NULL) {
2407c478bd9Sstevel@tonic-gate return (FAILURE);
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate if (strncmp(buf, EF_DISABLED, sizeof (EF_DISABLED) - 1) == 0) {
2447c478bd9Sstevel@tonic-gate pent->flag_enabledlist = B_FALSE;
2457c478bd9Sstevel@tonic-gate } else if (strncmp(buf, EF_ENABLED, sizeof (EF_ENABLED) - 1) == 0) {
2467c478bd9Sstevel@tonic-gate pent->flag_enabledlist = B_TRUE;
2477c478bd9Sstevel@tonic-gate } else if (strncmp(buf, EF_NORANDOM, sizeof (EF_NORANDOM) - 1) == 0) {
2487c478bd9Sstevel@tonic-gate pent->flag_norandom = B_TRUE;
2497c478bd9Sstevel@tonic-gate return (rc);
2507c478bd9Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_TOKEN,
2517c478bd9Sstevel@tonic-gate sizeof (METASLOT_TOKEN) - 1) == 0) {
2527c478bd9Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) {
2537c478bd9Sstevel@tonic-gate value++; /* get rid of = */
2547c478bd9Sstevel@tonic-gate (void) strlcpy((char *)pent->metaslot_ks_token, value,
25599ebb4caSwyllys sizeof (pent->metaslot_ks_token));
2567c478bd9Sstevel@tonic-gate return (SUCCESS);
2577c478bd9Sstevel@tonic-gate } else {
2587c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
2597c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
2607c478bd9Sstevel@tonic-gate return (FAILURE);
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_SLOT,
2637c478bd9Sstevel@tonic-gate sizeof (METASLOT_SLOT) - 1) == 0) {
2647c478bd9Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) {
2657c478bd9Sstevel@tonic-gate value++; /* get rid of = */
2667c478bd9Sstevel@tonic-gate (void) strlcpy((char *)pent->metaslot_ks_slot, value,
26799ebb4caSwyllys sizeof (pent->metaslot_ks_slot));
2687c478bd9Sstevel@tonic-gate return (SUCCESS);
2697c478bd9Sstevel@tonic-gate } else {
2707c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
2717c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
2727c478bd9Sstevel@tonic-gate return (FAILURE);
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_STATUS,
2757c478bd9Sstevel@tonic-gate sizeof (METASLOT_STATUS) - 1) == 0) {
2767c478bd9Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) {
2777c478bd9Sstevel@tonic-gate value++; /* get rid of = */
278b5a2d845SHai-May Chao if (strcmp(value, DISABLED_KEYWORD) == 0) {
2797c478bd9Sstevel@tonic-gate pent->flag_metaslot_enabled = B_FALSE;
280b5a2d845SHai-May Chao } else if (strcmp(value, ENABLED_KEYWORD) == 0) {
2817c478bd9Sstevel@tonic-gate pent->flag_metaslot_enabled = B_TRUE;
2827c478bd9Sstevel@tonic-gate } else {
2837c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
2847c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
2857c478bd9Sstevel@tonic-gate return (FAILURE);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate return (SUCCESS);
2887c478bd9Sstevel@tonic-gate } else {
2897c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
2907c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
2917c478bd9Sstevel@tonic-gate return (FAILURE);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_AUTO_KEY_MIGRATE,
2947c478bd9Sstevel@tonic-gate sizeof (METASLOT_AUTO_KEY_MIGRATE) - 1) == 0) {
2957c478bd9Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) {
2967c478bd9Sstevel@tonic-gate value++; /* get rid of = */
297b5a2d845SHai-May Chao if (strcmp(value, DISABLED_KEYWORD) == 0) {
2987c478bd9Sstevel@tonic-gate pent->flag_metaslot_auto_key_migrate = B_FALSE;
299b5a2d845SHai-May Chao } else if (strcmp(value, ENABLED_KEYWORD) == 0) {
3007c478bd9Sstevel@tonic-gate pent->flag_metaslot_auto_key_migrate = B_TRUE;
3017c478bd9Sstevel@tonic-gate } else {
3027c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
3037c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
3047c478bd9Sstevel@tonic-gate return (FAILURE);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate return (SUCCESS);
3077c478bd9Sstevel@tonic-gate } else {
3087c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
3097c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
3107c478bd9Sstevel@tonic-gate return (FAILURE);
3117c478bd9Sstevel@tonic-gate }
3127c478bd9Sstevel@tonic-gate } else {
3137c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
3147c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
3157c478bd9Sstevel@tonic-gate return (FAILURE);
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) {
3197c478bd9Sstevel@tonic-gate value++; /* get rid of = */
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate if ((next_token = strtok_r(value, SEP_COMMA, &lasts)) == NULL) {
3237c478bd9Sstevel@tonic-gate if (pent->flag_enabledlist) {
3247c478bd9Sstevel@tonic-gate return (SUCCESS);
3257c478bd9Sstevel@tonic-gate } else {
3267c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n",
3277c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
3287c478bd9Sstevel@tonic-gate return (FAILURE);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate while (next_token) {
3337c478bd9Sstevel@tonic-gate if ((pmech = create_umech(next_token)) == NULL) {
3347c478bd9Sstevel@tonic-gate cryptoerror(LOG_ERR, "parsing %s, out of memory.\n",
3357c478bd9Sstevel@tonic-gate _PATH_PKCS11_CONF);
3367c478bd9Sstevel@tonic-gate rc = FAILURE;
3377c478bd9Sstevel@tonic-gate break;
3387c478bd9Sstevel@tonic-gate }
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate if (phead == NULL) {
3417c478bd9Sstevel@tonic-gate phead = pcur = pmech;
3427c478bd9Sstevel@tonic-gate } else {
3437c478bd9Sstevel@tonic-gate pcur->next = pmech;
3447c478bd9Sstevel@tonic-gate pcur = pcur->next;
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate count++;
3477c478bd9Sstevel@tonic-gate next_token = strtok_r(NULL, SEP_COMMA, &lasts);
3487c478bd9Sstevel@tonic-gate }
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate if (rc == SUCCESS) {
3517c478bd9Sstevel@tonic-gate pent->policylist = phead;
3527c478bd9Sstevel@tonic-gate pent->count = count;
3537c478bd9Sstevel@tonic-gate } else {
3547c478bd9Sstevel@tonic-gate free_umechlist(phead);
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate
3577c478bd9Sstevel@tonic-gate return (rc);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate /*
3627c478bd9Sstevel@tonic-gate * Create one item of type umechlist_t with the mechanism name. A NULL is
3637c478bd9Sstevel@tonic-gate * returned when the input name is NULL or the heap memory is insufficient.
3647c478bd9Sstevel@tonic-gate */
3657c478bd9Sstevel@tonic-gate umechlist_t *
create_umech(char * name)3667c478bd9Sstevel@tonic-gate create_umech(char *name)
3677c478bd9Sstevel@tonic-gate {
3687c478bd9Sstevel@tonic-gate umechlist_t *pmech = NULL;
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate if (name == NULL) {
3717c478bd9Sstevel@tonic-gate return (NULL);
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate if ((pmech = malloc(sizeof (umechlist_t))) != NULL) {
3757c478bd9Sstevel@tonic-gate (void) strlcpy(pmech->name, name, sizeof (pmech->name));
3767c478bd9Sstevel@tonic-gate pmech->next = NULL;
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate return (pmech);
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate void
free_umechlist(umechlist_t * plist)3847c478bd9Sstevel@tonic-gate free_umechlist(umechlist_t *plist)
3857c478bd9Sstevel@tonic-gate {
3867c478bd9Sstevel@tonic-gate umechlist_t *pnext;
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate while (plist != NULL) {
3897c478bd9Sstevel@tonic-gate pnext = plist->next;
3907c478bd9Sstevel@tonic-gate free(plist);
3917c478bd9Sstevel@tonic-gate plist = pnext;
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate void
free_uentry(uentry_t * pent)3977c478bd9Sstevel@tonic-gate free_uentry(uentry_t *pent)
3987c478bd9Sstevel@tonic-gate {
3997c478bd9Sstevel@tonic-gate if (pent == NULL) {
4007c478bd9Sstevel@tonic-gate return;
4017c478bd9Sstevel@tonic-gate } else {
4027c478bd9Sstevel@tonic-gate free_umechlist(pent->policylist);
4037c478bd9Sstevel@tonic-gate free(pent);
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate void
free_uentrylist(uentrylist_t * entrylist)4097c478bd9Sstevel@tonic-gate free_uentrylist(uentrylist_t *entrylist)
4107c478bd9Sstevel@tonic-gate {
4117c478bd9Sstevel@tonic-gate uentrylist_t *pnext;
4127c478bd9Sstevel@tonic-gate
4137c478bd9Sstevel@tonic-gate while (entrylist != NULL) {
4147c478bd9Sstevel@tonic-gate pnext = entrylist->next;
4157c478bd9Sstevel@tonic-gate free_uentry(entrylist->puent);
4167c478bd9Sstevel@tonic-gate free(entrylist);
4177c478bd9Sstevel@tonic-gate entrylist = pnext;
4187c478bd9Sstevel@tonic-gate }
4197c478bd9Sstevel@tonic-gate }
42099ebb4caSwyllys
42199ebb4caSwyllys
42299ebb4caSwyllys
42399ebb4caSwyllys /*
42499ebb4caSwyllys * Duplicate an UEF mechanism list. A NULL pointer is returned if out of
42599ebb4caSwyllys * memory or the input argument is NULL.
42699ebb4caSwyllys */
42799ebb4caSwyllys static umechlist_t *
dup_umechlist(umechlist_t * plist)42899ebb4caSwyllys dup_umechlist(umechlist_t *plist)
42999ebb4caSwyllys {
43099ebb4caSwyllys umechlist_t *pres = NULL;
43199ebb4caSwyllys umechlist_t *pcur;
43299ebb4caSwyllys umechlist_t *ptmp;
43399ebb4caSwyllys int rc = SUCCESS;
43499ebb4caSwyllys
43599ebb4caSwyllys while (plist != NULL) {
43699ebb4caSwyllys if (!(ptmp = create_umech(plist->name))) {
43799ebb4caSwyllys rc = FAILURE;
43899ebb4caSwyllys break;
43999ebb4caSwyllys }
44099ebb4caSwyllys
44199ebb4caSwyllys if (pres == NULL) {
44299ebb4caSwyllys pres = pcur = ptmp;
44399ebb4caSwyllys } else {
44499ebb4caSwyllys pcur->next = ptmp;
44599ebb4caSwyllys pcur = pcur->next;
44699ebb4caSwyllys }
44799ebb4caSwyllys plist = plist->next;
44899ebb4caSwyllys }
44999ebb4caSwyllys
45099ebb4caSwyllys if (rc != SUCCESS) {
45199ebb4caSwyllys free_umechlist(pres);
45299ebb4caSwyllys return (NULL);
45399ebb4caSwyllys }
45499ebb4caSwyllys
45599ebb4caSwyllys return (pres);
45699ebb4caSwyllys }
45799ebb4caSwyllys
45899ebb4caSwyllys
45999ebb4caSwyllys /*
46099ebb4caSwyllys * Duplicate an uentry. A NULL pointer is returned if out of memory
46199ebb4caSwyllys * or the input argument is NULL.
46299ebb4caSwyllys */
46399ebb4caSwyllys static uentry_t *
dup_uentry(uentry_t * puent1)46499ebb4caSwyllys dup_uentry(uentry_t *puent1)
46599ebb4caSwyllys {
46699ebb4caSwyllys uentry_t *puent2 = NULL;
46799ebb4caSwyllys
46899ebb4caSwyllys if (puent1 == NULL) {
46999ebb4caSwyllys return (NULL);
47099ebb4caSwyllys }
47199ebb4caSwyllys
47299ebb4caSwyllys if ((puent2 = malloc(sizeof (uentry_t))) == NULL) {
47399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("out of memory."));
47499ebb4caSwyllys return (NULL);
47599ebb4caSwyllys } else {
47699ebb4caSwyllys (void) strlcpy(puent2->name, puent1->name,
47799ebb4caSwyllys sizeof (puent2->name));
47899ebb4caSwyllys puent2->flag_norandom = puent1->flag_norandom;
47999ebb4caSwyllys puent2->flag_enabledlist = puent1->flag_enabledlist;
48099ebb4caSwyllys puent2->policylist = dup_umechlist(puent1->policylist);
48199ebb4caSwyllys puent2->flag_metaslot_enabled = puent1->flag_metaslot_enabled;
48299ebb4caSwyllys puent2->flag_metaslot_auto_key_migrate
48399ebb4caSwyllys = puent1->flag_metaslot_auto_key_migrate;
48499ebb4caSwyllys (void) memcpy(puent2->metaslot_ks_slot,
48599ebb4caSwyllys puent1->metaslot_ks_slot, SLOT_DESCRIPTION_SIZE);
48699ebb4caSwyllys (void) memcpy(puent2->metaslot_ks_token,
48799ebb4caSwyllys puent1->metaslot_ks_token, TOKEN_LABEL_SIZE);
48899ebb4caSwyllys puent2->count = puent1->count;
489*d616ad8eSHai-May Chao puent2->flag_fips_enabled = puent1->flag_fips_enabled;
49099ebb4caSwyllys return (puent2);
49199ebb4caSwyllys }
49299ebb4caSwyllys }
49399ebb4caSwyllys
49499ebb4caSwyllys /*
49599ebb4caSwyllys * Find the entry in the "pkcs11.conf" file with "libname" as the provider
49699ebb4caSwyllys * name. Return the entry if found, otherwise return NULL.
49799ebb4caSwyllys */
49899ebb4caSwyllys uentry_t *
getent_uef(char * libname)49999ebb4caSwyllys getent_uef(char *libname)
50099ebb4caSwyllys {
50199ebb4caSwyllys uentrylist_t *pliblist = NULL;
50299ebb4caSwyllys uentrylist_t *plib = NULL;
50399ebb4caSwyllys uentry_t *puent = NULL;
50499ebb4caSwyllys boolean_t found = B_FALSE;
50599ebb4caSwyllys
50699ebb4caSwyllys if (libname == NULL) {
50799ebb4caSwyllys return (NULL);
50899ebb4caSwyllys }
50999ebb4caSwyllys
51099ebb4caSwyllys if ((get_pkcs11conf_info(&pliblist)) == FAILURE) {
51199ebb4caSwyllys return (NULL);
51299ebb4caSwyllys }
51399ebb4caSwyllys
51499ebb4caSwyllys plib = pliblist;
51599ebb4caSwyllys while (plib) {
51699ebb4caSwyllys if (strcmp(plib->puent->name, libname) == 0) {
51799ebb4caSwyllys found = B_TRUE;
51899ebb4caSwyllys break;
51999ebb4caSwyllys } else {
52099ebb4caSwyllys plib = plib->next;
52199ebb4caSwyllys }
52299ebb4caSwyllys }
52399ebb4caSwyllys
52499ebb4caSwyllys if (found) {
52599ebb4caSwyllys puent = dup_uentry(plib->puent);
52699ebb4caSwyllys }
52799ebb4caSwyllys
52899ebb4caSwyllys free_uentrylist(pliblist);
52999ebb4caSwyllys return (puent);
53099ebb4caSwyllys }
53199ebb4caSwyllys
53299ebb4caSwyllys
53399ebb4caSwyllys
53499ebb4caSwyllys /*
53599ebb4caSwyllys * Retrieve the metaslot information from the pkcs11.conf file.
53699ebb4caSwyllys * This function returns SUCCESS if successfully done; otherwise it returns
53799ebb4caSwyllys * FAILURE. If successful, the caller is responsible to free the space
53899ebb4caSwyllys * allocated for objectstore_slot_info and objectstore_token_info.
53999ebb4caSwyllys */
54099ebb4caSwyllys int
get_metaslot_info(boolean_t * status_enabled,boolean_t * migrate_enabled,char ** objectstore_slot_info,char ** objectstore_token_info)54199ebb4caSwyllys get_metaslot_info(boolean_t *status_enabled, boolean_t *migrate_enabled,
54299ebb4caSwyllys char **objectstore_slot_info, char **objectstore_token_info)
54399ebb4caSwyllys {
54499ebb4caSwyllys
54599ebb4caSwyllys int rc = SUCCESS;
54699ebb4caSwyllys uentry_t *puent;
54799ebb4caSwyllys char *buf1 = NULL;
54899ebb4caSwyllys char *buf2 = NULL;
54999ebb4caSwyllys
55099ebb4caSwyllys if ((puent = getent_uef(METASLOT_KEYWORD)) == NULL) {
55199ebb4caSwyllys /* metaslot entry doesn't exist */
55299ebb4caSwyllys return (FAILURE);
55399ebb4caSwyllys }
55499ebb4caSwyllys
55599ebb4caSwyllys *status_enabled = puent->flag_metaslot_enabled;
55699ebb4caSwyllys *migrate_enabled = puent->flag_metaslot_auto_key_migrate;
55799ebb4caSwyllys
55899ebb4caSwyllys buf1 = malloc(SLOT_DESCRIPTION_SIZE);
55999ebb4caSwyllys if (buf1 == NULL) {
56099ebb4caSwyllys cryptoerror(LOG_ERR, "get_metaslot_info() - out of memory.\n");
56199ebb4caSwyllys rc = FAILURE;
56299ebb4caSwyllys goto out;
56399ebb4caSwyllys }
56499ebb4caSwyllys (void) strcpy(buf1, (const char *) puent->metaslot_ks_slot);
56599ebb4caSwyllys *objectstore_slot_info = buf1;
56699ebb4caSwyllys
56799ebb4caSwyllys buf2 = malloc(TOKEN_LABEL_SIZE);
56899ebb4caSwyllys if (objectstore_slot_info == NULL) {
56999ebb4caSwyllys cryptoerror(LOG_ERR, "get_metaslot_info() - out of memory.\n");
57099ebb4caSwyllys rc = FAILURE;
57199ebb4caSwyllys goto out;
57299ebb4caSwyllys }
57399ebb4caSwyllys (void) strcpy(buf2, (const char *) puent->metaslot_ks_token);
57499ebb4caSwyllys *objectstore_token_info = buf2;
57599ebb4caSwyllys
57699ebb4caSwyllys out:
57799ebb4caSwyllys if (puent != NULL) {
57899ebb4caSwyllys free_uentry(puent);
57999ebb4caSwyllys }
58099ebb4caSwyllys
58199ebb4caSwyllys if (rc == FAILURE) {
58299ebb4caSwyllys if (buf1 != NULL) {
58399ebb4caSwyllys free(buf1);
58499ebb4caSwyllys }
58599ebb4caSwyllys if (buf2 != NULL) {
58699ebb4caSwyllys free(buf2);
58799ebb4caSwyllys }
58899ebb4caSwyllys }
58999ebb4caSwyllys
59099ebb4caSwyllys return (rc);
59199ebb4caSwyllys }
592b5a2d845SHai-May Chao
593b5a2d845SHai-May Chao static boolean_t
is_fips(char * name)594b5a2d845SHai-May Chao is_fips(char *name)
595b5a2d845SHai-May Chao {
596b5a2d845SHai-May Chao if (strcmp(name, FIPS_KEYWORD) == 0) {
597b5a2d845SHai-May Chao return (B_TRUE);
598b5a2d845SHai-May Chao } else {
599b5a2d845SHai-May Chao return (B_FALSE);
600b5a2d845SHai-May Chao }
601b5a2d845SHai-May Chao }
602