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 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
32 #include <cryptoutil.h>
33 #include <security/cryptoki.h>
39 genkey_nss(KMF_HANDLE_T kmfhandle
, char *token
, char *dir
, char *prefix
,
40 char *keylabel
, KMF_KEY_ALG keyAlg
, int keylen
, KMF_CREDENTIAL
*tokencred
)
42 KMF_RETURN kmfrv
= KMF_OK
;
44 KMF_ATTRIBUTE attlist
[20];
46 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_NSS
;
50 if (keylabel
== NULL
) {
51 cryptoerror(LOG_STDERR
,
52 gettext("A key label must be specified \n"));
53 return (KMF_ERR_BAD_PARAMETER
);
56 kmfrv
= configure_nss(kmfhandle
, dir
, prefix
);
60 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
65 kmf_set_attr_at_index(attlist
, i
,
66 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
69 kmf_set_attr_at_index(attlist
, i
,
70 KMF_KEY_HANDLE_ATTR
, &key
, sizeof (KMF_KEY_HANDLE
));
73 kmf_set_attr_at_index(attlist
, i
,
74 KMF_KEYALG_ATTR
, &keytype
, sizeof (keytype
));
77 kmf_set_attr_at_index(attlist
, i
,
78 KMF_KEYLENGTH_ATTR
, &keylength
, sizeof (keylength
));
81 if (keylabel
!= NULL
) {
82 kmf_set_attr_at_index(attlist
, i
,
83 KMF_KEYLABEL_ATTR
, keylabel
,
88 if (tokencred
!= NULL
&& tokencred
->cred
!= NULL
) {
89 kmf_set_attr_at_index(attlist
, i
,
90 KMF_CREDENTIAL_ATTR
, tokencred
,
91 sizeof (KMF_CREDENTIAL
));
96 kmf_set_attr_at_index(attlist
, i
,
97 KMF_TOKEN_LABEL_ATTR
, token
,
102 kmfrv
= kmf_create_sym_key(kmfhandle
, i
, attlist
);
108 genkey_pkcs11(KMF_HANDLE_T kmfhandle
, char *token
,
109 char *keylabel
, KMF_KEY_ALG keyAlg
, int keylen
,
110 char *senstr
, char *extstr
, boolean_t print_hex
,
111 KMF_CREDENTIAL
*tokencred
)
113 KMF_RETURN kmfrv
= KMF_OK
;
115 KMF_RAW_SYM_KEY
*rkey
= NULL
;
116 boolean_t sensitive
= B_FALSE
;
117 boolean_t not_extractable
= B_FALSE
;
120 KMF_ATTRIBUTE attlist
[20];
122 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
126 if (keylabel
== NULL
) {
127 cryptoerror(LOG_STDERR
,
128 gettext("A key label must be specified \n"));
129 return (KMF_ERR_BAD_PARAMETER
);
132 /* Check the sensitive option value if specified. */
133 if (senstr
!= NULL
) {
134 if (tolower(senstr
[0]) == 'y')
136 else if (tolower(senstr
[0]) == 'n')
139 cryptoerror(LOG_STDERR
,
140 gettext("Incorrect sensitive option value.\n"));
141 return (KMF_ERR_BAD_PARAMETER
);
145 /* Check the extractable option value if specified. */
146 if (extstr
!= NULL
) {
147 if (tolower(extstr
[0]) == 'y')
148 not_extractable
= B_FALSE
;
149 else if (tolower(extstr
[0]) == 'n')
150 not_extractable
= B_TRUE
;
152 cryptoerror(LOG_STDERR
,
153 gettext("Incorrect extractable option value.\n"));
154 return (KMF_ERR_BAD_PARAMETER
);
158 /* Select a PKCS11 token first */
159 kmfrv
= select_token(kmfhandle
, token
, FALSE
);
160 if (kmfrv
!= KMF_OK
) {
164 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
167 keylength
= keylen
; /* bits */
169 kmf_set_attr_at_index(attlist
, i
,
170 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
173 kmf_set_attr_at_index(attlist
, i
,
174 KMF_KEY_HANDLE_ATTR
, &key
, sizeof (KMF_KEY_HANDLE
));
177 kmf_set_attr_at_index(attlist
, i
,
178 KMF_KEYALG_ATTR
, &keytype
, sizeof (keytype
));
181 kmf_set_attr_at_index(attlist
, i
,
182 KMF_KEYLENGTH_ATTR
, &keylength
, sizeof (keylength
));
185 if (keylabel
!= NULL
) {
186 kmf_set_attr_at_index(attlist
, i
,
187 KMF_KEYLABEL_ATTR
, keylabel
,
192 if (tokencred
!= NULL
&& tokencred
->cred
!= NULL
) {
193 kmf_set_attr_at_index(attlist
, i
,
194 KMF_CREDENTIAL_ATTR
, tokencred
,
195 sizeof (KMF_CREDENTIAL
));
199 kmf_set_attr_at_index(attlist
, i
,
200 KMF_SENSITIVE_BOOL_ATTR
, &sensitive
,
204 kmf_set_attr_at_index(attlist
, i
,
205 KMF_NON_EXTRACTABLE_BOOL_ATTR
, ¬_extractable
,
206 sizeof (not_extractable
));
209 kmfrv
= kmf_create_sym_key(kmfhandle
, i
, attlist
);
210 if (kmfrv
!= KMF_OK
) {
215 if (sensitive
== B_TRUE
|| not_extractable
== B_TRUE
) {
216 cryptoerror(LOG_STDERR
,
217 gettext("Warning: can not reveal the key value "
218 "for a sensitive or non-extractable key.\n"));
221 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
223 kmfrv
= KMF_ERR_MEMORY
;
226 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
227 kmfrv
= kmf_get_sym_key_value(kmfhandle
, &key
, rkey
);
228 if (kmfrv
!= KMF_OK
) {
231 hexstrlen
= 2 * rkey
->keydata
.len
+ 1;
232 hexstr
= malloc(hexstrlen
);
233 if (hexstr
== NULL
) {
234 kmfrv
= KMF_ERR_MEMORY
;
238 tohexstr(rkey
->keydata
.val
, rkey
->keydata
.len
, hexstr
,
240 (void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr
);
245 kmf_free_raw_sym_key(rkey
);
254 genkey_file(KMF_HANDLE_T kmfhandle
, KMF_KEY_ALG keyAlg
, int keylen
, char *dir
,
255 char *outkey
, boolean_t print_hex
)
257 KMF_RETURN kmfrv
= KMF_OK
;
259 KMF_RAW_SYM_KEY
*rkey
= NULL
;
262 KMF_ATTRIBUTE attlist
[20];
264 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
269 if (EMPTYSTRING(outkey
)) {
270 cryptoerror(LOG_STDERR
,
271 gettext("No output key file was specified for the key\n"));
272 return (KMF_ERR_BAD_PARAMETER
);
275 if (verify_file(outkey
)) {
276 cryptoerror(LOG_STDERR
,
277 gettext("Cannot write the indicated output "
278 "key file (%s).\n"), outkey
);
279 return (KMF_ERR_BAD_PARAMETER
);
282 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
289 kmf_set_attr_at_index(attlist
, i
,
290 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
293 kmf_set_attr_at_index(attlist
, i
,
294 KMF_KEY_HANDLE_ATTR
, &key
, sizeof (KMF_KEY_HANDLE
));
297 kmf_set_attr_at_index(attlist
, i
,
298 KMF_KEYALG_ATTR
, &keytype
, sizeof (keytype
));
301 kmf_set_attr_at_index(attlist
, i
,
302 KMF_KEYLENGTH_ATTR
, &keylength
, sizeof (keylength
));
305 if (dirpath
!= NULL
) {
306 kmf_set_attr_at_index(attlist
, i
,
307 KMF_DIRPATH_ATTR
, dirpath
,
312 if (outkey
!= NULL
) {
313 kmf_set_attr_at_index(attlist
, i
,
314 KMF_KEY_FILENAME_ATTR
, outkey
,
319 kmfrv
= kmf_create_sym_key(kmfhandle
, i
, attlist
);
320 if (kmfrv
!= KMF_OK
) {
325 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
327 kmfrv
= KMF_ERR_MEMORY
;
330 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
331 kmfrv
= kmf_get_sym_key_value(kmfhandle
, &key
, rkey
);
332 if (kmfrv
!= KMF_OK
) {
336 hexstrlen
= 2 * rkey
->keydata
.len
+ 1;
337 hexstr
= malloc(hexstrlen
);
338 if (hexstr
== NULL
) {
339 kmfrv
= KMF_ERR_MEMORY
;
342 tohexstr(rkey
->keydata
.val
, rkey
->keydata
.len
, hexstr
,
344 (void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr
);
348 kmf_free_raw_sym_key(rkey
);
356 pk_genkey(int argc
, char *argv
[])
360 extern int optind_av
;
361 extern char *optarg_av
;
362 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
363 char *tokenname
= NULL
;
366 char *keytype
= "generic";
367 char *keylenstr
= NULL
;
369 char *keylabel
= NULL
;
373 char *printstr
= NULL
;
374 KMF_HANDLE_T kmfhandle
= NULL
;
375 KMF_KEY_ALG keyAlg
= KMF_GENERIC_SECRET
;
376 boolean_t print_hex
= B_FALSE
;
377 KMF_CREDENTIAL tokencred
= { NULL
, 0 };
379 while ((opt
= getopt_av(argc
, argv
,
380 "k:(keystore)l:(label)T:(token)d:(dir)p:(prefix)"
381 "t:(keytype)y:(keylen)K:(outkey)P:(print)"
382 "s:(sensitive)e:(extractable)")) != EOF
) {
383 if (EMPTYSTRING(optarg_av
))
384 return (PK_ERR_USAGE
);
387 kstype
= KS2Int(optarg_av
);
389 return (PK_ERR_USAGE
);
393 return (PK_ERR_USAGE
);
394 keylabel
= optarg_av
;
398 return (PK_ERR_USAGE
);
399 tokenname
= optarg_av
;
403 return (PK_ERR_USAGE
);
408 return (PK_ERR_USAGE
);
416 return (PK_ERR_USAGE
);
417 keylenstr
= optarg_av
;
421 return (PK_ERR_USAGE
);
426 return (PK_ERR_USAGE
);
427 printstr
= optarg_av
;
431 return (PK_ERR_USAGE
);
436 return (PK_ERR_USAGE
);
440 return (PK_ERR_USAGE
);
444 /* No additional args allowed. */
448 return (PK_ERR_USAGE
);
451 /* Check keytype. If not specified, default to AES */
452 if (keytype
!= NULL
&& Str2SymKeyType(keytype
, &keyAlg
) != 0) {
453 cryptoerror(LOG_STDERR
, gettext("Unrecognized keytype(%s).\n"),
455 return (PK_ERR_USAGE
);
459 * Check and set the key length.
460 * - For DES and 3DES, the key size are fixed. Ingore the keylen
461 * option, even if it is specified.
462 * - For AES and ARCFOUR, if keylen is not specified, default to
465 if (keyAlg
== KMF_DES
)
466 keylen
= 64; /* fixed size; ignore input */
467 else if (keyAlg
== KMF_DES3
)
468 keylen
= 192; /* fixed size; ignore input */
469 else /* AES, ARCFOUR, or GENERIC SECRET */ {
470 if (keylenstr
== NULL
) {
471 cryptoerror(LOG_STDERR
,
472 gettext("Key length must be specified for "
473 "AES, ARCFOUR or GENERIC symmetric keys.\n"));
474 return (PK_ERR_USAGE
);
476 if (sscanf(keylenstr
, "%d", &keylen
) != 1) {
477 cryptoerror(LOG_STDERR
,
478 gettext("Unrecognized key length (%s).\n"),
480 return (PK_ERR_USAGE
);
482 if (keylen
== 0 || (keylen
% 8) != 0) {
483 cryptoerror(LOG_STDERR
,
484 gettext("Key length bitlength must be a "
485 "multiple of 8.\n"));
486 return (PK_ERR_USAGE
);
490 /* check the print option */
491 if (printstr
!= NULL
) {
492 if (kstype
== KMF_KEYSTORE_NSS
) {
493 cryptoerror(LOG_STDERR
,
494 gettext("The print option does not apply "
495 "to the NSS keystore.\n"));
496 return (PK_ERR_USAGE
);
499 if (tolower(printstr
[0]) == 'y')
501 else if (tolower(printstr
[0]) == 'n')
504 cryptoerror(LOG_STDERR
,
505 gettext("Incorrect print option value.\n"));
506 return (PK_ERR_USAGE
);
510 /* check the sensitive and extractable options */
511 if ((senstr
!= NULL
|| extstr
!= NULL
) &&
512 (kstype
== KMF_KEYSTORE_NSS
|| kstype
== KMF_KEYSTORE_OPENSSL
)) {
513 cryptoerror(LOG_STDERR
,
514 gettext("The sensitive or extractable option applies "
515 "to the PKCS11 keystore only.\n"));
516 return (PK_ERR_USAGE
);
519 if (kstype
== KMF_KEYSTORE_PK11TOKEN
&& tokenname
== NULL
) {
520 tokenname
= PK_DEFAULT_PK11TOKEN
;
521 } else if (kstype
== KMF_KEYSTORE_NSS
&& tokenname
== NULL
) {
522 tokenname
= DEFAULT_NSS_TOKEN
;
524 DIR_OPTION_CHECK(kstype
, dir
);
526 if (kstype
== KMF_KEYSTORE_PK11TOKEN
|| kstype
== KMF_KEYSTORE_NSS
)
527 (void) get_token_password(kstype
, tokenname
, &tokencred
);
529 if ((rv
= kmf_initialize(&kmfhandle
, NULL
, NULL
)) != KMF_OK
) {
530 cryptoerror(LOG_STDERR
, gettext("Error initializing KMF\n"));
534 if (kstype
== KMF_KEYSTORE_NSS
) {
535 rv
= genkey_nss(kmfhandle
, tokenname
, dir
, prefix
,
536 keylabel
, keyAlg
, keylen
, &tokencred
);
537 } else if (kstype
== KMF_KEYSTORE_OPENSSL
) {
538 rv
= genkey_file(kmfhandle
, keyAlg
, keylen
, dir
, outkey
,
541 rv
= genkey_pkcs11(kmfhandle
, tokenname
, keylabel
, keyAlg
,
542 keylen
, senstr
, extstr
, print_hex
, &tokencred
);
547 display_error(kmfhandle
, rv
,
548 gettext("Error generating key"));
550 free(tokencred
.cred
);
552 (void) kmf_finalize(kmfhandle
);
554 return (PK_ERR_USAGE
);