10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51914Scasper * Common Development and Distribution License (the "License"). 61914Scasper * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 221914Scasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <stdio.h> 290Sstevel@tonic-gate #include <errno.h> 300Sstevel@tonic-gate #include <strings.h> 310Sstevel@tonic-gate #include <locale.h> 320Sstevel@tonic-gate #include <stdlib.h> 330Sstevel@tonic-gate #include "cryptoutil.h" 340Sstevel@tonic-gate 350Sstevel@tonic-gate static int uef_interpret(char *, uentry_t **); 360Sstevel@tonic-gate static int parse_policylist(char *, uentry_t *); 370Sstevel@tonic-gate 380Sstevel@tonic-gate /* 390Sstevel@tonic-gate * Retrieve the user-level provider info from the pkcs11.conf file. 400Sstevel@tonic-gate * If successful, the result is returned from the ppliblist argument. 410Sstevel@tonic-gate * This function returns SUCCESS if successfully done; otherwise it returns 420Sstevel@tonic-gate * FAILURE. 430Sstevel@tonic-gate */ 440Sstevel@tonic-gate int 450Sstevel@tonic-gate get_pkcs11conf_info(uentrylist_t **ppliblist) 460Sstevel@tonic-gate { 470Sstevel@tonic-gate FILE *pfile; 480Sstevel@tonic-gate char buffer[BUFSIZ]; 490Sstevel@tonic-gate size_t len; 500Sstevel@tonic-gate uentry_t *pent; 510Sstevel@tonic-gate uentrylist_t *pentlist; 520Sstevel@tonic-gate uentrylist_t *pcur; 530Sstevel@tonic-gate int rc = SUCCESS; 540Sstevel@tonic-gate 550Sstevel@tonic-gate *ppliblist = NULL; 561914Scasper if ((pfile = fopen(_PATH_PKCS11_CONF, "rF")) == NULL) { 570Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to open %s.\n", _PATH_PKCS11_CONF); 580Sstevel@tonic-gate return (FAILURE); 590Sstevel@tonic-gate } 600Sstevel@tonic-gate 610Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) { 620Sstevel@tonic-gate if (buffer[0] == '#' || buffer[0] == ' ' || 630Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t') { 640Sstevel@tonic-gate continue; /* ignore comment lines */ 650Sstevel@tonic-gate } 660Sstevel@tonic-gate 670Sstevel@tonic-gate len = strlen(buffer); 680Sstevel@tonic-gate if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */ 690Sstevel@tonic-gate len--; 700Sstevel@tonic-gate } 710Sstevel@tonic-gate buffer[len] = '\0'; 720Sstevel@tonic-gate 730Sstevel@tonic-gate if ((rc = uef_interpret(buffer, &pent)) != SUCCESS) { 740Sstevel@tonic-gate break; 750Sstevel@tonic-gate } 760Sstevel@tonic-gate 770Sstevel@tonic-gate /* append pent into ppliblist */ 780Sstevel@tonic-gate pentlist = malloc(sizeof (uentrylist_t)); 790Sstevel@tonic-gate if (pentlist == NULL) { 800Sstevel@tonic-gate cryptoerror(LOG_ERR, "parsing %s, out of memory.\n", 810Sstevel@tonic-gate _PATH_PKCS11_CONF); 820Sstevel@tonic-gate free_uentry(pent); 830Sstevel@tonic-gate rc = FAILURE; 840Sstevel@tonic-gate break; 850Sstevel@tonic-gate } 860Sstevel@tonic-gate pentlist->puent = pent; 870Sstevel@tonic-gate pentlist->next = NULL; 880Sstevel@tonic-gate 890Sstevel@tonic-gate if (*ppliblist == NULL) { 900Sstevel@tonic-gate *ppliblist = pcur = pentlist; 910Sstevel@tonic-gate } else { 920Sstevel@tonic-gate pcur->next = pentlist; 930Sstevel@tonic-gate pcur = pcur->next; 940Sstevel@tonic-gate } 950Sstevel@tonic-gate } 960Sstevel@tonic-gate 970Sstevel@tonic-gate (void) fclose(pfile); 980Sstevel@tonic-gate 990Sstevel@tonic-gate if (rc != SUCCESS) { 1000Sstevel@tonic-gate free_uentrylist(*ppliblist); 1010Sstevel@tonic-gate *ppliblist = NULL; 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate return (rc); 1050Sstevel@tonic-gate } 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate /* 1090Sstevel@tonic-gate * This routine converts a char string into a uentry_t structure 1100Sstevel@tonic-gate * The input string "buf" should be one of the following: 1110Sstevel@tonic-gate * library_name 1120Sstevel@tonic-gate * library_name:NO_RANDOM 1130Sstevel@tonic-gate * library_name:disabledlist=m1,m2,...,mk 1140Sstevel@tonic-gate * library_name:disabledlist=m1,m2,...,mk;NO_RANDOM 1150Sstevel@tonic-gate * library_name:enabledlist= 1160Sstevel@tonic-gate * library_name:enabledlist=;NO_RANDOM 1170Sstevel@tonic-gate * library_name:enabledlist=m1,m2,...,mk 1180Sstevel@tonic-gate * library_name:enabledlist=m1,m2,...,mk;NO_RANDOM 1190Sstevel@tonic-gate * metaslot:status=enabled;enabledlist=m1,m2,....;slot=<slot-description>;\ 1200Sstevel@tonic-gate * token=<token-label> 1210Sstevel@tonic-gate * 1220Sstevel@tonic-gate * Note: 1230Sstevel@tonic-gate * The mechanisms m1,..mk are in hex form. For example, "0x00000210" 1240Sstevel@tonic-gate * for CKM_MD5. 1250Sstevel@tonic-gate * 1260Sstevel@tonic-gate * For the metaslot entry, "enabledlist", "slot", "auto_key_migrate" 1270Sstevel@tonic-gate * or "token" is optional 1280Sstevel@tonic-gate */ 1290Sstevel@tonic-gate static int 1300Sstevel@tonic-gate uef_interpret(char *buf, uentry_t **ppent) 1310Sstevel@tonic-gate { 1320Sstevel@tonic-gate uentry_t *pent; 1330Sstevel@tonic-gate char *token1; 1340Sstevel@tonic-gate char *token2; 1350Sstevel@tonic-gate char *lasts; 1360Sstevel@tonic-gate int rc; 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate *ppent = NULL; 1390Sstevel@tonic-gate if ((token1 = strtok_r(buf, SEP_COLON, &lasts)) == NULL) { 1400Sstevel@tonic-gate /* buf is NULL */ 1410Sstevel@tonic-gate return (FAILURE); 1420Sstevel@tonic-gate }; 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate pent = calloc(sizeof (uentry_t), 1); 1450Sstevel@tonic-gate if (pent == NULL) { 1460Sstevel@tonic-gate cryptoerror(LOG_ERR, "parsing %s, out of memory.\n", 1470Sstevel@tonic-gate _PATH_PKCS11_CONF); 1480Sstevel@tonic-gate return (FAILURE); 1490Sstevel@tonic-gate } 1500Sstevel@tonic-gate (void) strlcpy(pent->name, token1, sizeof (pent->name)); 1510Sstevel@tonic-gate /* 1520Sstevel@tonic-gate * in case metaslot_auto_key_migrate is not specified, it should 1530Sstevel@tonic-gate * be default to true 1540Sstevel@tonic-gate */ 1550Sstevel@tonic-gate pent->flag_metaslot_auto_key_migrate = B_TRUE; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate while ((token2 = strtok_r(NULL, SEP_SEMICOLON, &lasts)) != NULL) { 1580Sstevel@tonic-gate if ((rc = parse_policylist(token2, pent)) != SUCCESS) { 1590Sstevel@tonic-gate free_uentry(pent); 1600Sstevel@tonic-gate return (rc); 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate *ppent = pent; 1650Sstevel@tonic-gate return (SUCCESS); 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate /* 1700Sstevel@tonic-gate * This routine parses the policy list and stored the result in the argument 1710Sstevel@tonic-gate * pent. 1720Sstevel@tonic-gate * 1730Sstevel@tonic-gate * Arg buf: input only, its format should be one of the following: 1740Sstevel@tonic-gate * enabledlist= 1750Sstevel@tonic-gate * enabledlist=m1,m2,...,mk 1760Sstevel@tonic-gate * disabledlist=m1,m2,...,mk 1770Sstevel@tonic-gate * NO_RANDOM 1780Sstevel@tonic-gate * metaslot_status=enabled|disabled 1790Sstevel@tonic-gate * metaslot_token=<token-label> 1800Sstevel@tonic-gate * metaslot_slot=<slot-description. 1810Sstevel@tonic-gate * 1820Sstevel@tonic-gate * Arg pent: input/output 1830Sstevel@tonic-gate * 1840Sstevel@tonic-gate * return: SUCCESS or FAILURE 1850Sstevel@tonic-gate */ 1860Sstevel@tonic-gate static int 1870Sstevel@tonic-gate parse_policylist(char *buf, uentry_t *pent) 1880Sstevel@tonic-gate { 1890Sstevel@tonic-gate umechlist_t *phead = NULL; 1900Sstevel@tonic-gate umechlist_t *pcur = NULL; 1910Sstevel@tonic-gate umechlist_t *pmech; 1920Sstevel@tonic-gate char *next_token; 1930Sstevel@tonic-gate char *value; 1940Sstevel@tonic-gate char *lasts; 1950Sstevel@tonic-gate int count = 0; 1960Sstevel@tonic-gate int rc = SUCCESS; 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate if (pent == NULL) { 1990Sstevel@tonic-gate return (FAILURE); 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate if (strncmp(buf, EF_DISABLED, sizeof (EF_DISABLED) - 1) == 0) { 2030Sstevel@tonic-gate pent->flag_enabledlist = B_FALSE; 2040Sstevel@tonic-gate } else if (strncmp(buf, EF_ENABLED, sizeof (EF_ENABLED) - 1) == 0) { 2050Sstevel@tonic-gate pent->flag_enabledlist = B_TRUE; 2060Sstevel@tonic-gate } else if (strncmp(buf, EF_NORANDOM, sizeof (EF_NORANDOM) - 1) == 0) { 2070Sstevel@tonic-gate pent->flag_norandom = B_TRUE; 2080Sstevel@tonic-gate return (rc); 2090Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_TOKEN, 2100Sstevel@tonic-gate sizeof (METASLOT_TOKEN) - 1) == 0) { 2110Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) { 2120Sstevel@tonic-gate value++; /* get rid of = */ 2130Sstevel@tonic-gate (void) strlcpy((char *)pent->metaslot_ks_token, value, 214*3089Swyllys sizeof (pent->metaslot_ks_token)); 2150Sstevel@tonic-gate return (SUCCESS); 2160Sstevel@tonic-gate } else { 2170Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2180Sstevel@tonic-gate _PATH_PKCS11_CONF); 2190Sstevel@tonic-gate return (FAILURE); 2200Sstevel@tonic-gate } 2210Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_SLOT, 2220Sstevel@tonic-gate sizeof (METASLOT_SLOT) - 1) == 0) { 2230Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) { 2240Sstevel@tonic-gate value++; /* get rid of = */ 2250Sstevel@tonic-gate (void) strlcpy((char *)pent->metaslot_ks_slot, value, 226*3089Swyllys sizeof (pent->metaslot_ks_slot)); 2270Sstevel@tonic-gate return (SUCCESS); 2280Sstevel@tonic-gate } else { 2290Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2300Sstevel@tonic-gate _PATH_PKCS11_CONF); 2310Sstevel@tonic-gate return (FAILURE); 2320Sstevel@tonic-gate } 2330Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_STATUS, 2340Sstevel@tonic-gate sizeof (METASLOT_STATUS) - 1) == 0) { 2350Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) { 2360Sstevel@tonic-gate value++; /* get rid of = */ 2370Sstevel@tonic-gate if (strcmp(value, METASLOT_DISABLED) == 0) { 2380Sstevel@tonic-gate pent->flag_metaslot_enabled = B_FALSE; 2390Sstevel@tonic-gate } else if (strcmp(value, METASLOT_ENABLED) == 0) { 2400Sstevel@tonic-gate pent->flag_metaslot_enabled = B_TRUE; 2410Sstevel@tonic-gate } else { 2420Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2430Sstevel@tonic-gate _PATH_PKCS11_CONF); 2440Sstevel@tonic-gate return (FAILURE); 2450Sstevel@tonic-gate } 2460Sstevel@tonic-gate return (SUCCESS); 2470Sstevel@tonic-gate } else { 2480Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2490Sstevel@tonic-gate _PATH_PKCS11_CONF); 2500Sstevel@tonic-gate return (FAILURE); 2510Sstevel@tonic-gate } 2520Sstevel@tonic-gate } else if (strncmp(buf, METASLOT_AUTO_KEY_MIGRATE, 2530Sstevel@tonic-gate sizeof (METASLOT_AUTO_KEY_MIGRATE) - 1) == 0) { 2540Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) { 2550Sstevel@tonic-gate value++; /* get rid of = */ 2560Sstevel@tonic-gate if (strcmp(value, METASLOT_DISABLED) == 0) { 2570Sstevel@tonic-gate pent->flag_metaslot_auto_key_migrate = B_FALSE; 2580Sstevel@tonic-gate } else if (strcmp(value, METASLOT_ENABLED) == 0) { 2590Sstevel@tonic-gate pent->flag_metaslot_auto_key_migrate = B_TRUE; 2600Sstevel@tonic-gate } else { 2610Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2620Sstevel@tonic-gate _PATH_PKCS11_CONF); 2630Sstevel@tonic-gate return (FAILURE); 2640Sstevel@tonic-gate } 2650Sstevel@tonic-gate return (SUCCESS); 2660Sstevel@tonic-gate } else { 2670Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2680Sstevel@tonic-gate _PATH_PKCS11_CONF); 2690Sstevel@tonic-gate return (FAILURE); 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate } else { 2720Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2730Sstevel@tonic-gate _PATH_PKCS11_CONF); 2740Sstevel@tonic-gate return (FAILURE); 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) { 2780Sstevel@tonic-gate value++; /* get rid of = */ 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate if ((next_token = strtok_r(value, SEP_COMMA, &lasts)) == NULL) { 2820Sstevel@tonic-gate if (pent->flag_enabledlist) { 2830Sstevel@tonic-gate return (SUCCESS); 2840Sstevel@tonic-gate } else { 2850Sstevel@tonic-gate cryptoerror(LOG_ERR, "failed to parse %s.\n", 2860Sstevel@tonic-gate _PATH_PKCS11_CONF); 2870Sstevel@tonic-gate return (FAILURE); 2880Sstevel@tonic-gate } 2890Sstevel@tonic-gate } 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate while (next_token) { 2920Sstevel@tonic-gate if ((pmech = create_umech(next_token)) == NULL) { 2930Sstevel@tonic-gate cryptoerror(LOG_ERR, "parsing %s, out of memory.\n", 2940Sstevel@tonic-gate _PATH_PKCS11_CONF); 2950Sstevel@tonic-gate rc = FAILURE; 2960Sstevel@tonic-gate break; 2970Sstevel@tonic-gate } 2980Sstevel@tonic-gate 2990Sstevel@tonic-gate if (phead == NULL) { 3000Sstevel@tonic-gate phead = pcur = pmech; 3010Sstevel@tonic-gate } else { 3020Sstevel@tonic-gate pcur->next = pmech; 3030Sstevel@tonic-gate pcur = pcur->next; 3040Sstevel@tonic-gate } 3050Sstevel@tonic-gate count++; 3060Sstevel@tonic-gate next_token = strtok_r(NULL, SEP_COMMA, &lasts); 3070Sstevel@tonic-gate } 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate if (rc == SUCCESS) { 3100Sstevel@tonic-gate pent->policylist = phead; 3110Sstevel@tonic-gate pent->count = count; 3120Sstevel@tonic-gate } else { 3130Sstevel@tonic-gate free_umechlist(phead); 3140Sstevel@tonic-gate } 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate return (rc); 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate /* 3210Sstevel@tonic-gate * Create one item of type umechlist_t with the mechanism name. A NULL is 3220Sstevel@tonic-gate * returned when the input name is NULL or the heap memory is insufficient. 3230Sstevel@tonic-gate */ 3240Sstevel@tonic-gate umechlist_t * 3250Sstevel@tonic-gate create_umech(char *name) 3260Sstevel@tonic-gate { 3270Sstevel@tonic-gate umechlist_t *pmech = NULL; 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate if (name == NULL) { 3300Sstevel@tonic-gate return (NULL); 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate if ((pmech = malloc(sizeof (umechlist_t))) != NULL) { 3340Sstevel@tonic-gate (void) strlcpy(pmech->name, name, sizeof (pmech->name)); 3350Sstevel@tonic-gate pmech->next = NULL; 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate return (pmech); 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate void 3430Sstevel@tonic-gate free_umechlist(umechlist_t *plist) 3440Sstevel@tonic-gate { 3450Sstevel@tonic-gate umechlist_t *pnext; 3460Sstevel@tonic-gate 3470Sstevel@tonic-gate while (plist != NULL) { 3480Sstevel@tonic-gate pnext = plist->next; 3490Sstevel@tonic-gate free(plist); 3500Sstevel@tonic-gate plist = pnext; 3510Sstevel@tonic-gate } 3520Sstevel@tonic-gate } 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate void 3560Sstevel@tonic-gate free_uentry(uentry_t *pent) 3570Sstevel@tonic-gate { 3580Sstevel@tonic-gate if (pent == NULL) { 3590Sstevel@tonic-gate return; 3600Sstevel@tonic-gate } else { 3610Sstevel@tonic-gate free_umechlist(pent->policylist); 3620Sstevel@tonic-gate free(pent); 3630Sstevel@tonic-gate } 3640Sstevel@tonic-gate } 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate 3670Sstevel@tonic-gate void 3680Sstevel@tonic-gate free_uentrylist(uentrylist_t *entrylist) 3690Sstevel@tonic-gate { 3700Sstevel@tonic-gate uentrylist_t *pnext; 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate while (entrylist != NULL) { 3730Sstevel@tonic-gate pnext = entrylist->next; 3740Sstevel@tonic-gate free_uentry(entrylist->puent); 3750Sstevel@tonic-gate free(entrylist); 3760Sstevel@tonic-gate entrylist = pnext; 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate } 379*3089Swyllys 380*3089Swyllys 381*3089Swyllys 382*3089Swyllys /* 383*3089Swyllys * Duplicate an UEF mechanism list. A NULL pointer is returned if out of 384*3089Swyllys * memory or the input argument is NULL. 385*3089Swyllys */ 386*3089Swyllys static umechlist_t * 387*3089Swyllys dup_umechlist(umechlist_t *plist) 388*3089Swyllys { 389*3089Swyllys umechlist_t *pres = NULL; 390*3089Swyllys umechlist_t *pcur; 391*3089Swyllys umechlist_t *ptmp; 392*3089Swyllys int rc = SUCCESS; 393*3089Swyllys 394*3089Swyllys while (plist != NULL) { 395*3089Swyllys if (!(ptmp = create_umech(plist->name))) { 396*3089Swyllys rc = FAILURE; 397*3089Swyllys break; 398*3089Swyllys } 399*3089Swyllys 400*3089Swyllys if (pres == NULL) { 401*3089Swyllys pres = pcur = ptmp; 402*3089Swyllys } else { 403*3089Swyllys pcur->next = ptmp; 404*3089Swyllys pcur = pcur->next; 405*3089Swyllys } 406*3089Swyllys plist = plist->next; 407*3089Swyllys } 408*3089Swyllys 409*3089Swyllys if (rc != SUCCESS) { 410*3089Swyllys free_umechlist(pres); 411*3089Swyllys return (NULL); 412*3089Swyllys } 413*3089Swyllys 414*3089Swyllys return (pres); 415*3089Swyllys } 416*3089Swyllys 417*3089Swyllys 418*3089Swyllys /* 419*3089Swyllys * Duplicate an uentry. A NULL pointer is returned if out of memory 420*3089Swyllys * or the input argument is NULL. 421*3089Swyllys */ 422*3089Swyllys static uentry_t * 423*3089Swyllys dup_uentry(uentry_t *puent1) 424*3089Swyllys { 425*3089Swyllys uentry_t *puent2 = NULL; 426*3089Swyllys 427*3089Swyllys if (puent1 == NULL) { 428*3089Swyllys return (NULL); 429*3089Swyllys } 430*3089Swyllys 431*3089Swyllys if ((puent2 = malloc(sizeof (uentry_t))) == NULL) { 432*3089Swyllys cryptoerror(LOG_STDERR, gettext("out of memory.")); 433*3089Swyllys return (NULL); 434*3089Swyllys } else { 435*3089Swyllys (void) strlcpy(puent2->name, puent1->name, 436*3089Swyllys sizeof (puent2->name)); 437*3089Swyllys puent2->flag_norandom = puent1->flag_norandom; 438*3089Swyllys puent2->flag_enabledlist = puent1->flag_enabledlist; 439*3089Swyllys puent2->policylist = dup_umechlist(puent1->policylist); 440*3089Swyllys puent2->flag_metaslot_enabled = puent1->flag_metaslot_enabled; 441*3089Swyllys puent2->flag_metaslot_auto_key_migrate 442*3089Swyllys = puent1->flag_metaslot_auto_key_migrate; 443*3089Swyllys (void) memcpy(puent2->metaslot_ks_slot, 444*3089Swyllys puent1->metaslot_ks_slot, SLOT_DESCRIPTION_SIZE); 445*3089Swyllys (void) memcpy(puent2->metaslot_ks_token, 446*3089Swyllys puent1->metaslot_ks_token, TOKEN_LABEL_SIZE); 447*3089Swyllys puent2->count = puent1->count; 448*3089Swyllys return (puent2); 449*3089Swyllys } 450*3089Swyllys } 451*3089Swyllys 452*3089Swyllys /* 453*3089Swyllys * Find the entry in the "pkcs11.conf" file with "libname" as the provider 454*3089Swyllys * name. Return the entry if found, otherwise return NULL. 455*3089Swyllys */ 456*3089Swyllys uentry_t * 457*3089Swyllys getent_uef(char *libname) 458*3089Swyllys { 459*3089Swyllys uentrylist_t *pliblist = NULL; 460*3089Swyllys uentrylist_t *plib = NULL; 461*3089Swyllys uentry_t *puent = NULL; 462*3089Swyllys boolean_t found = B_FALSE; 463*3089Swyllys 464*3089Swyllys if (libname == NULL) { 465*3089Swyllys return (NULL); 466*3089Swyllys } 467*3089Swyllys 468*3089Swyllys if ((get_pkcs11conf_info(&pliblist)) == FAILURE) { 469*3089Swyllys return (NULL); 470*3089Swyllys } 471*3089Swyllys 472*3089Swyllys plib = pliblist; 473*3089Swyllys while (plib) { 474*3089Swyllys if (strcmp(plib->puent->name, libname) == 0) { 475*3089Swyllys found = B_TRUE; 476*3089Swyllys break; 477*3089Swyllys } else { 478*3089Swyllys plib = plib->next; 479*3089Swyllys } 480*3089Swyllys } 481*3089Swyllys 482*3089Swyllys if (found) { 483*3089Swyllys puent = dup_uentry(plib->puent); 484*3089Swyllys } 485*3089Swyllys 486*3089Swyllys free_uentrylist(pliblist); 487*3089Swyllys return (puent); 488*3089Swyllys } 489*3089Swyllys 490*3089Swyllys 491*3089Swyllys 492*3089Swyllys /* 493*3089Swyllys * Retrieve the metaslot information from the pkcs11.conf file. 494*3089Swyllys * This function returns SUCCESS if successfully done; otherwise it returns 495*3089Swyllys * FAILURE. If successful, the caller is responsible to free the space 496*3089Swyllys * allocated for objectstore_slot_info and objectstore_token_info. 497*3089Swyllys */ 498*3089Swyllys int 499*3089Swyllys get_metaslot_info(boolean_t *status_enabled, boolean_t *migrate_enabled, 500*3089Swyllys char **objectstore_slot_info, char **objectstore_token_info) 501*3089Swyllys { 502*3089Swyllys 503*3089Swyllys int rc = SUCCESS; 504*3089Swyllys uentry_t *puent; 505*3089Swyllys char *buf1 = NULL; 506*3089Swyllys char *buf2 = NULL; 507*3089Swyllys 508*3089Swyllys if ((puent = getent_uef(METASLOT_KEYWORD)) == NULL) { 509*3089Swyllys /* metaslot entry doesn't exist */ 510*3089Swyllys return (FAILURE); 511*3089Swyllys } 512*3089Swyllys 513*3089Swyllys *status_enabled = puent->flag_metaslot_enabled; 514*3089Swyllys *migrate_enabled = puent->flag_metaslot_auto_key_migrate; 515*3089Swyllys 516*3089Swyllys buf1 = malloc(SLOT_DESCRIPTION_SIZE); 517*3089Swyllys if (buf1 == NULL) { 518*3089Swyllys cryptoerror(LOG_ERR, "get_metaslot_info() - out of memory.\n"); 519*3089Swyllys rc = FAILURE; 520*3089Swyllys goto out; 521*3089Swyllys } 522*3089Swyllys (void) strcpy(buf1, (const char *) puent->metaslot_ks_slot); 523*3089Swyllys *objectstore_slot_info = buf1; 524*3089Swyllys 525*3089Swyllys buf2 = malloc(TOKEN_LABEL_SIZE); 526*3089Swyllys if (objectstore_slot_info == NULL) { 527*3089Swyllys cryptoerror(LOG_ERR, "get_metaslot_info() - out of memory.\n"); 528*3089Swyllys rc = FAILURE; 529*3089Swyllys goto out; 530*3089Swyllys } 531*3089Swyllys (void) strcpy(buf2, (const char *) puent->metaslot_ks_token); 532*3089Swyllys *objectstore_token_info = buf2; 533*3089Swyllys 534*3089Swyllys out: 535*3089Swyllys if (puent != NULL) { 536*3089Swyllys free_uentry(puent); 537*3089Swyllys } 538*3089Swyllys 539*3089Swyllys if (rc == FAILURE) { 540*3089Swyllys if (buf1 != NULL) { 541*3089Swyllys free(buf1); 542*3089Swyllys } 543*3089Swyllys if (buf2 != NULL) { 544*3089Swyllys free(buf2); 545*3089Swyllys } 546*3089Swyllys } 547*3089Swyllys 548*3089Swyllys return (rc); 549*3089Swyllys } 550