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
);
255 genkey_file(KMF_HANDLE_T kmfhandle
, KMF_KEY_ALG keyAlg
, int keylen
, char *dir
,
256 char *outkey
, boolean_t print_hex
)
258 KMF_RETURN kmfrv
= KMF_OK
;
260 KMF_RAW_SYM_KEY
*rkey
= NULL
;
263 KMF_ATTRIBUTE attlist
[20];
265 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
270 if (EMPTYSTRING(outkey
)) {
271 cryptoerror(LOG_STDERR
,
272 gettext("No output key file was specified for the key\n"));
273 return (KMF_ERR_BAD_PARAMETER
);
276 if (verify_file(outkey
)) {
277 cryptoerror(LOG_STDERR
,
278 gettext("Cannot write the indicated output "
279 "key file (%s).\n"), outkey
);
280 return (KMF_ERR_BAD_PARAMETER
);
283 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
290 kmf_set_attr_at_index(attlist
, i
,
291 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
294 kmf_set_attr_at_index(attlist
, i
,
295 KMF_KEY_HANDLE_ATTR
, &key
, sizeof (KMF_KEY_HANDLE
));
298 kmf_set_attr_at_index(attlist
, i
,
299 KMF_KEYALG_ATTR
, &keytype
, sizeof (keytype
));
302 kmf_set_attr_at_index(attlist
, i
,
303 KMF_KEYLENGTH_ATTR
, &keylength
, sizeof (keylength
));
306 if (dirpath
!= NULL
) {
307 kmf_set_attr_at_index(attlist
, i
,
308 KMF_DIRPATH_ATTR
, dirpath
,
313 if (outkey
!= NULL
) {
314 kmf_set_attr_at_index(attlist
, i
,
315 KMF_KEY_FILENAME_ATTR
, outkey
,
320 kmfrv
= kmf_create_sym_key(kmfhandle
, i
, attlist
);
321 if (kmfrv
!= KMF_OK
) {
326 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
328 kmfrv
= KMF_ERR_MEMORY
;
331 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
332 kmfrv
= kmf_get_sym_key_value(kmfhandle
, &key
, rkey
);
333 if (kmfrv
!= KMF_OK
) {
337 hexstrlen
= 2 * rkey
->keydata
.len
+ 1;
338 hexstr
= malloc(hexstrlen
);
339 if (hexstr
== NULL
) {
340 kmfrv
= KMF_ERR_MEMORY
;
343 tohexstr(rkey
->keydata
.val
, rkey
->keydata
.len
, hexstr
,
345 (void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr
);
349 kmf_free_raw_sym_key(rkey
);
358 pk_genkey(int argc
, char *argv
[])
362 extern int optind_av
;
363 extern char *optarg_av
;
364 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
365 char *tokenname
= NULL
;
368 char *keytype
= "generic";
369 char *keylenstr
= NULL
;
371 char *keylabel
= NULL
;
375 char *printstr
= NULL
;
376 KMF_HANDLE_T kmfhandle
= NULL
;
377 KMF_KEY_ALG keyAlg
= KMF_GENERIC_SECRET
;
378 boolean_t print_hex
= B_FALSE
;
379 KMF_CREDENTIAL tokencred
= { NULL
, 0 };
381 while ((opt
= getopt_av(argc
, argv
,
382 "k:(keystore)l:(label)T:(token)d:(dir)p:(prefix)"
383 "t:(keytype)y:(keylen)K:(outkey)P:(print)"
384 "s:(sensitive)e:(extractable)")) != EOF
) {
385 if (EMPTYSTRING(optarg_av
))
386 return (PK_ERR_USAGE
);
389 kstype
= KS2Int(optarg_av
);
391 return (PK_ERR_USAGE
);
395 return (PK_ERR_USAGE
);
396 keylabel
= optarg_av
;
400 return (PK_ERR_USAGE
);
401 tokenname
= optarg_av
;
405 return (PK_ERR_USAGE
);
410 return (PK_ERR_USAGE
);
418 return (PK_ERR_USAGE
);
419 keylenstr
= optarg_av
;
423 return (PK_ERR_USAGE
);
428 return (PK_ERR_USAGE
);
429 printstr
= optarg_av
;
433 return (PK_ERR_USAGE
);
438 return (PK_ERR_USAGE
);
442 return (PK_ERR_USAGE
);
446 /* No additional args allowed. */
450 return (PK_ERR_USAGE
);
453 /* Check keytype. If not specified, default to AES */
454 if (keytype
!= NULL
&& Str2SymKeyType(keytype
, &keyAlg
) != 0) {
455 cryptoerror(LOG_STDERR
, gettext("Unrecognized keytype(%s).\n"),
457 return (PK_ERR_USAGE
);
461 * Check and set the key length.
462 * - For DES and 3DES, the key size are fixed. Ingore the keylen
463 * option, even if it is specified.
464 * - For AES and ARCFOUR, if keylen is not specified, default to
467 if (keyAlg
== KMF_DES
)
468 keylen
= 64; /* fixed size; ignore input */
469 else if (keyAlg
== KMF_DES3
)
470 keylen
= 192; /* fixed size; ignore input */
471 else /* AES, ARCFOUR, or GENERIC SECRET */ {
472 if (keylenstr
== NULL
) {
473 cryptoerror(LOG_STDERR
,
474 gettext("Key length must be specified for "
475 "AES, ARCFOUR or GENERIC symmetric keys.\n"));
476 return (PK_ERR_USAGE
);
478 if (sscanf(keylenstr
, "%d", &keylen
) != 1) {
479 cryptoerror(LOG_STDERR
,
480 gettext("Unrecognized key length (%s).\n"),
482 return (PK_ERR_USAGE
);
484 if (keylen
== 0 || (keylen
% 8) != 0) {
485 cryptoerror(LOG_STDERR
,
486 gettext("Key length bitlength must be a "
487 "multiple of 8.\n"));
488 return (PK_ERR_USAGE
);
492 /* check the print option */
493 if (printstr
!= NULL
) {
494 if (kstype
== KMF_KEYSTORE_NSS
) {
495 cryptoerror(LOG_STDERR
,
496 gettext("The print option does not apply "
497 "to the NSS keystore.\n"));
498 return (PK_ERR_USAGE
);
501 if (tolower(printstr
[0]) == 'y')
503 else if (tolower(printstr
[0]) == 'n')
506 cryptoerror(LOG_STDERR
,
507 gettext("Incorrect print option value.\n"));
508 return (PK_ERR_USAGE
);
512 /* check the sensitive and extractable options */
513 if ((senstr
!= NULL
|| extstr
!= NULL
) &&
514 (kstype
== KMF_KEYSTORE_NSS
|| kstype
== KMF_KEYSTORE_OPENSSL
)) {
515 cryptoerror(LOG_STDERR
,
516 gettext("The sensitive or extractable option applies "
517 "to the PKCS11 keystore only.\n"));
518 return (PK_ERR_USAGE
);
521 if (kstype
== KMF_KEYSTORE_PK11TOKEN
&& tokenname
== NULL
) {
522 tokenname
= PK_DEFAULT_PK11TOKEN
;
523 } else if (kstype
== KMF_KEYSTORE_NSS
&& tokenname
== NULL
) {
524 tokenname
= DEFAULT_NSS_TOKEN
;
526 DIR_OPTION_CHECK(kstype
, dir
);
528 if (kstype
== KMF_KEYSTORE_PK11TOKEN
|| kstype
== KMF_KEYSTORE_NSS
)
529 (void) get_token_password(kstype
, tokenname
, &tokencred
);
531 if ((rv
= kmf_initialize(&kmfhandle
, NULL
, NULL
)) != KMF_OK
) {
532 cryptoerror(LOG_STDERR
, gettext("Error initializing KMF\n"));
536 if (kstype
== KMF_KEYSTORE_NSS
) {
537 rv
= genkey_nss(kmfhandle
, tokenname
, dir
, prefix
,
538 keylabel
, keyAlg
, keylen
, &tokencred
);
539 } else if (kstype
== KMF_KEYSTORE_OPENSSL
) {
540 rv
= genkey_file(kmfhandle
, keyAlg
, keylen
, dir
, outkey
,
543 rv
= genkey_pkcs11(kmfhandle
, tokenname
, keylabel
, keyAlg
,
544 keylen
, senstr
, extstr
, print_hex
, &tokencred
);
549 display_error(kmfhandle
, rv
,
550 gettext("Error generating key"));
552 if (tokencred
.cred
!= NULL
)
553 free(tokencred
.cred
);
555 (void) kmf_finalize(kmfhandle
);
557 return (PK_ERR_USAGE
);