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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
32 #include "cryptoutil.h"
34 static int uef_interpret(char *, uentry_t
**);
35 static int parse_policylist(char *, uentry_t
*);
36 static boolean_t
is_fips(char *);
39 * Retrieve the user-level provider info from the pkcs11.conf file.
40 * If successful, the result is returned from the ppliblist argument.
41 * This function returns SUCCESS if successfully done; otherwise it returns
45 get_pkcs11conf_info(uentrylist_t
**ppliblist
)
51 uentrylist_t
*pentlist
;
56 if ((pfile
= fopen(_PATH_PKCS11_CONF
, "rF")) == NULL
) {
57 cryptoerror(LOG_ERR
, "failed to open %s.\n", _PATH_PKCS11_CONF
);
61 while (fgets(buffer
, BUFSIZ
, pfile
) != NULL
) {
62 if (buffer
[0] == '#' || buffer
[0] == ' ' ||
63 buffer
[0] == '\n'|| buffer
[0] == '\t') {
64 continue; /* ignore comment lines */
68 if (buffer
[len
-1] == '\n') { /* get rid of trailing '\n' */
73 if ((rc
= uef_interpret(buffer
, &pent
)) != SUCCESS
) {
77 /* append pent into ppliblist */
78 pentlist
= malloc(sizeof (uentrylist_t
));
79 if (pentlist
== NULL
) {
80 cryptoerror(LOG_ERR
, "parsing %s, out of memory.\n",
86 pentlist
->puent
= pent
;
87 pentlist
->next
= NULL
;
89 if (*ppliblist
== NULL
) {
90 *ppliblist
= pcur
= pentlist
;
92 pcur
->next
= pentlist
;
100 free_uentrylist(*ppliblist
);
108 parse_fips_mode(char *buf
, boolean_t
*mode
)
112 if (strncmp(buf
, EF_FIPS_STATUS
, sizeof (EF_FIPS_STATUS
) - 1) == 0) {
113 if (value
= strpbrk(buf
, SEP_EQUAL
)) {
114 value
++; /* get rid of = */
115 if (strcmp(value
, DISABLED_KEYWORD
) == 0) {
117 } else if (strcmp(value
, ENABLED_KEYWORD
) == 0) {
120 cryptoerror(LOG_ERR
, gettext(
121 "Failed to parse pkcs11.conf file.\n"));
122 return (CKR_FUNCTION_FAILED
);
126 return (CKR_FUNCTION_FAILED
);
129 /* should not come here */
130 cryptoerror(LOG_ERR
, gettext(
131 "Failed to parse pkcs11.conf file.\n"));
132 return (CKR_FUNCTION_FAILED
);
138 * This routine converts a char string into a uentry_t structure
139 * The input string "buf" should be one of the following:
141 * library_name:NO_RANDOM
142 * library_name:disabledlist=m1,m2,...,mk
143 * library_name:disabledlist=m1,m2,...,mk;NO_RANDOM
144 * library_name:enabledlist=
145 * library_name:enabledlist=;NO_RANDOM
146 * library_name:enabledlist=m1,m2,...,mk
147 * library_name:enabledlist=m1,m2,...,mk;NO_RANDOM
148 * metaslot:status=enabled;enabledlist=m1,m2,....;slot=<slot-description>;\
149 * token=<token-label>
152 * The mechanisms m1,..mk are in hex form. For example, "0x00000210"
155 * For the metaslot entry, "enabledlist", "slot", "auto_key_migrate"
156 * or "token" is optional
159 uef_interpret(char *buf
, uentry_t
**ppent
)
168 if ((token1
= strtok_r(buf
, SEP_COLON
, &lasts
)) == NULL
) {
173 pent
= calloc(sizeof (uentry_t
), 1);
175 cryptoerror(LOG_ERR
, "parsing %s, out of memory.\n",
179 (void) strlcpy(pent
->name
, token1
, sizeof (pent
->name
));
181 if (is_fips(token1
)) {
182 if ((rc
= parse_fips_mode(buf
+ strlen(token1
) + 1,
183 &pent
->flag_fips_enabled
)) != SUCCESS
) {
193 * in case metaslot_auto_key_migrate is not specified, it should
196 pent
->flag_metaslot_auto_key_migrate
= B_TRUE
;
198 while ((token2
= strtok_r(NULL
, SEP_SEMICOLON
, &lasts
)) != NULL
) {
199 if ((rc
= parse_policylist(token2
, pent
)) != SUCCESS
) {
211 * This routine parses the policy list and stored the result in the argument
214 * Arg buf: input only, its format should be one of the following:
216 * enabledlist=m1,m2,...,mk
217 * disabledlist=m1,m2,...,mk
219 * metaslot_status=enabled|disabled
220 * metaslot_token=<token-label>
221 * metaslot_slot=<slot-description.
223 * Arg pent: input/output
225 * return: SUCCESS or FAILURE
228 parse_policylist(char *buf
, uentry_t
*pent
)
230 umechlist_t
*phead
= NULL
;
231 umechlist_t
*pcur
= NULL
;
243 if (strncmp(buf
, EF_DISABLED
, sizeof (EF_DISABLED
) - 1) == 0) {
244 pent
->flag_enabledlist
= B_FALSE
;
245 } else if (strncmp(buf
, EF_ENABLED
, sizeof (EF_ENABLED
) - 1) == 0) {
246 pent
->flag_enabledlist
= B_TRUE
;
247 } else if (strncmp(buf
, EF_NORANDOM
, sizeof (EF_NORANDOM
) - 1) == 0) {
248 pent
->flag_norandom
= B_TRUE
;
250 } else if (strncmp(buf
, METASLOT_TOKEN
,
251 sizeof (METASLOT_TOKEN
) - 1) == 0) {
252 if (value
= strpbrk(buf
, SEP_EQUAL
)) {
253 value
++; /* get rid of = */
254 (void) strlcpy((char *)pent
->metaslot_ks_token
, value
,
255 sizeof (pent
->metaslot_ks_token
));
258 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
262 } else if (strncmp(buf
, METASLOT_SLOT
,
263 sizeof (METASLOT_SLOT
) - 1) == 0) {
264 if (value
= strpbrk(buf
, SEP_EQUAL
)) {
265 value
++; /* get rid of = */
266 (void) strlcpy((char *)pent
->metaslot_ks_slot
, value
,
267 sizeof (pent
->metaslot_ks_slot
));
270 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
274 } else if (strncmp(buf
, METASLOT_STATUS
,
275 sizeof (METASLOT_STATUS
) - 1) == 0) {
276 if (value
= strpbrk(buf
, SEP_EQUAL
)) {
277 value
++; /* get rid of = */
278 if (strcmp(value
, DISABLED_KEYWORD
) == 0) {
279 pent
->flag_metaslot_enabled
= B_FALSE
;
280 } else if (strcmp(value
, ENABLED_KEYWORD
) == 0) {
281 pent
->flag_metaslot_enabled
= B_TRUE
;
283 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
289 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
293 } else if (strncmp(buf
, METASLOT_AUTO_KEY_MIGRATE
,
294 sizeof (METASLOT_AUTO_KEY_MIGRATE
) - 1) == 0) {
295 if (value
= strpbrk(buf
, SEP_EQUAL
)) {
296 value
++; /* get rid of = */
297 if (strcmp(value
, DISABLED_KEYWORD
) == 0) {
298 pent
->flag_metaslot_auto_key_migrate
= B_FALSE
;
299 } else if (strcmp(value
, ENABLED_KEYWORD
) == 0) {
300 pent
->flag_metaslot_auto_key_migrate
= B_TRUE
;
302 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
308 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
313 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
318 if (value
= strpbrk(buf
, SEP_EQUAL
)) {
319 value
++; /* get rid of = */
322 if ((next_token
= strtok_r(value
, SEP_COMMA
, &lasts
)) == NULL
) {
323 if (pent
->flag_enabledlist
) {
326 cryptoerror(LOG_ERR
, "failed to parse %s.\n",
333 if ((pmech
= create_umech(next_token
)) == NULL
) {
334 cryptoerror(LOG_ERR
, "parsing %s, out of memory.\n",
341 phead
= pcur
= pmech
;
347 next_token
= strtok_r(NULL
, SEP_COMMA
, &lasts
);
351 pent
->policylist
= phead
;
354 free_umechlist(phead
);
362 * Create one item of type umechlist_t with the mechanism name. A NULL is
363 * returned when the input name is NULL or the heap memory is insufficient.
366 create_umech(char *name
)
368 umechlist_t
*pmech
= NULL
;
374 if ((pmech
= malloc(sizeof (umechlist_t
))) != NULL
) {
375 (void) strlcpy(pmech
->name
, name
, sizeof (pmech
->name
));
384 free_umechlist(umechlist_t
*plist
)
388 while (plist
!= NULL
) {
397 free_uentry(uentry_t
*pent
)
402 free_umechlist(pent
->policylist
);
409 free_uentrylist(uentrylist_t
*entrylist
)
413 while (entrylist
!= NULL
) {
414 pnext
= entrylist
->next
;
415 free_uentry(entrylist
->puent
);
424 * Duplicate an UEF mechanism list. A NULL pointer is returned if out of
425 * memory or the input argument is NULL.
428 dup_umechlist(umechlist_t
*plist
)
430 umechlist_t
*pres
= NULL
;
435 while (plist
!= NULL
) {
436 if (!(ptmp
= create_umech(plist
->name
))) {
451 free_umechlist(pres
);
460 * Duplicate an uentry. A NULL pointer is returned if out of memory
461 * or the input argument is NULL.
464 dup_uentry(uentry_t
*puent1
)
466 uentry_t
*puent2
= NULL
;
468 if (puent1
== NULL
) {
472 if ((puent2
= malloc(sizeof (uentry_t
))) == NULL
) {
473 cryptoerror(LOG_STDERR
, gettext("out of memory."));
476 (void) strlcpy(puent2
->name
, puent1
->name
,
477 sizeof (puent2
->name
));
478 puent2
->flag_norandom
= puent1
->flag_norandom
;
479 puent2
->flag_enabledlist
= puent1
->flag_enabledlist
;
480 puent2
->policylist
= dup_umechlist(puent1
->policylist
);
481 puent2
->flag_metaslot_enabled
= puent1
->flag_metaslot_enabled
;
482 puent2
->flag_metaslot_auto_key_migrate
483 = puent1
->flag_metaslot_auto_key_migrate
;
484 (void) memcpy(puent2
->metaslot_ks_slot
,
485 puent1
->metaslot_ks_slot
, SLOT_DESCRIPTION_SIZE
);
486 (void) memcpy(puent2
->metaslot_ks_token
,
487 puent1
->metaslot_ks_token
, TOKEN_LABEL_SIZE
);
488 puent2
->count
= puent1
->count
;
489 puent2
->flag_fips_enabled
= puent1
->flag_fips_enabled
;
495 * Find the entry in the "pkcs11.conf" file with "libname" as the provider
496 * name. Return the entry if found, otherwise return NULL.
499 getent_uef(char *libname
)
501 uentrylist_t
*pliblist
= NULL
;
502 uentrylist_t
*plib
= NULL
;
503 uentry_t
*puent
= NULL
;
504 boolean_t found
= B_FALSE
;
506 if (libname
== NULL
) {
510 if ((get_pkcs11conf_info(&pliblist
)) == FAILURE
) {
516 if (strcmp(plib
->puent
->name
, libname
) == 0) {
525 puent
= dup_uentry(plib
->puent
);
528 free_uentrylist(pliblist
);
535 * Retrieve the metaslot information from the pkcs11.conf file.
536 * This function returns SUCCESS if successfully done; otherwise it returns
537 * FAILURE. If successful, the caller is responsible to free the space
538 * allocated for objectstore_slot_info and objectstore_token_info.
541 get_metaslot_info(boolean_t
*status_enabled
, boolean_t
*migrate_enabled
,
542 char **objectstore_slot_info
, char **objectstore_token_info
)
550 if ((puent
= getent_uef(METASLOT_KEYWORD
)) == NULL
) {
551 /* metaslot entry doesn't exist */
555 *status_enabled
= puent
->flag_metaslot_enabled
;
556 *migrate_enabled
= puent
->flag_metaslot_auto_key_migrate
;
558 buf1
= malloc(SLOT_DESCRIPTION_SIZE
);
560 cryptoerror(LOG_ERR
, "get_metaslot_info() - out of memory.\n");
564 (void) strcpy(buf1
, (const char *) puent
->metaslot_ks_slot
);
565 *objectstore_slot_info
= buf1
;
567 buf2
= malloc(TOKEN_LABEL_SIZE
);
568 if (objectstore_slot_info
== NULL
) {
569 cryptoerror(LOG_ERR
, "get_metaslot_info() - out of memory.\n");
573 (void) strcpy(buf2
, (const char *) puent
->metaslot_ks_token
);
574 *objectstore_token_info
= buf2
;
596 if (strcmp(name
, FIPS_KEYWORD
) == 0) {