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 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
32 #include <cryptoutil.h>
33 #include <security/cryptoki.h>
38 #define SET_VALUE(f, s) \
40 if (kmfrv != KMF_OK) { \
41 cryptoerror(LOG_STDERR, \
42 gettext("Failed to set %s: 0x%02x\n"), \
48 genkeypair_pkcs11(KMF_HANDLE_T kmfhandle
,
49 char *token
, char *keylabel
, KMF_KEY_ALG keyAlg
,
50 int keylen
, KMF_CREDENTIAL
*tokencred
, KMF_OID
*curveoid
,
51 KMF_KEY_HANDLE
*outPriKey
, KMF_KEY_HANDLE
*outPubKey
)
53 KMF_RETURN kmfrv
= KMF_OK
;
54 KMF_KEY_HANDLE pubk
, prik
;
55 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
56 KMF_ATTRIBUTE attrlist
[16];
61 keylength
= keylen
; /* bits */
64 /* Select a PKCS11 token */
65 kmfrv
= select_token(kmfhandle
, token
, FALSE
);
69 kmf_set_attr_at_index(attrlist
, numattr
,
70 KMF_KEYSTORE_TYPE_ATTR
, &kstype
,
74 kmf_set_attr_at_index(attrlist
, numattr
,
75 KMF_KEYALG_ATTR
, &keytype
,
79 kmf_set_attr_at_index(attrlist
, numattr
,
80 KMF_KEYLENGTH_ATTR
, &keylength
,
84 if (keylabel
!= NULL
) {
85 kmf_set_attr_at_index(attrlist
, numattr
,
86 KMF_KEYLABEL_ATTR
, keylabel
,
91 if (tokencred
!= NULL
&& tokencred
->cred
!= NULL
) {
92 kmf_set_attr_at_index(attrlist
, numattr
,
93 KMF_CREDENTIAL_ATTR
, tokencred
,
94 sizeof (KMF_CREDENTIAL
));
98 kmf_set_attr_at_index(attrlist
, numattr
,
99 KMF_PRIVKEY_HANDLE_ATTR
, &prik
,
100 sizeof (KMF_KEY_HANDLE
));
103 kmf_set_attr_at_index(attrlist
, numattr
,
104 KMF_PUBKEY_HANDLE_ATTR
, &pubk
,
105 sizeof (KMF_KEY_HANDLE
));
108 if (keytype
== KMF_ECDSA
&& curveoid
!= NULL
) {
109 kmf_set_attr_at_index(attrlist
, numattr
,
110 KMF_ECC_CURVE_OID_ATTR
, curveoid
,
115 kmfrv
= kmf_create_keypair(kmfhandle
, numattr
, attrlist
);
116 if (kmfrv
!= KMF_OK
) {
121 if (kmfrv
== KMF_OK
) {
122 if (outPriKey
!= NULL
)
124 if (outPubKey
!= NULL
)
132 genkeypair_file(KMF_HANDLE_T kmfhandle
,
133 KMF_KEY_ALG keyAlg
, int keylen
, KMF_ENCODE_FORMAT fmt
,
135 KMF_KEY_HANDLE
*outPriKey
, KMF_KEY_HANDLE
*outPubKey
)
138 KMF_KEY_HANDLE pubk
, prik
;
139 char *fullkeypath
= NULL
;
140 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
141 KMF_ATTRIBUTE attrlist
[10];
145 KMF_ENCODE_FORMAT format
;
147 if (EMPTYSTRING(outkey
)) {
148 cryptoerror(LOG_STDERR
,
149 gettext("No output file was specified for "
151 return (PK_ERR_USAGE
);
154 fullkeypath
= strdup(outkey
);
155 if (verify_file(fullkeypath
)) {
156 cryptoerror(LOG_STDERR
,
157 gettext("Cannot write the indicated output "
158 "key file (%s).\n"), fullkeypath
);
160 return (PK_ERR_USAGE
);
163 keylength
= keylen
; /* bits */
167 kmf_set_attr_at_index(attrlist
, numattr
,
168 KMF_KEYSTORE_TYPE_ATTR
, &kstype
,
172 kmf_set_attr_at_index(attrlist
, numattr
,
173 KMF_KEYALG_ATTR
, &keytype
,
177 kmf_set_attr_at_index(attrlist
, numattr
,
178 KMF_KEYLENGTH_ATTR
, &keylength
,
182 if (fullkeypath
!= NULL
) {
183 kmf_set_attr_at_index(attrlist
, numattr
,
184 KMF_KEY_FILENAME_ATTR
, fullkeypath
,
185 strlen(fullkeypath
));
189 kmf_set_attr_at_index(attrlist
, numattr
,
190 KMF_ENCODE_FORMAT_ATTR
, &format
,
194 kmf_set_attr_at_index(attrlist
, numattr
,
195 KMF_PRIVKEY_HANDLE_ATTR
, &prik
,
196 sizeof (KMF_KEY_HANDLE
));
199 kmf_set_attr_at_index(attrlist
, numattr
,
200 KMF_PUBKEY_HANDLE_ATTR
, &pubk
,
201 sizeof (KMF_KEY_HANDLE
));
204 kmfrv
= kmf_create_keypair(kmfhandle
, numattr
, attrlist
);
205 if (kmfrv
!= KMF_OK
) {
210 if (fullkeypath
!= NULL
)
213 if (kmfrv
== KMF_OK
) {
214 if (outPriKey
!= NULL
)
216 if (outPubKey
!= NULL
)
224 genkeypair_nss(KMF_HANDLE_T kmfhandle
,
226 char *nickname
, char *dir
, char *prefix
,
228 int keylen
, KMF_CREDENTIAL
*tokencred
,
230 KMF_KEY_HANDLE
*outPriKey
, KMF_KEY_HANDLE
*outPubKey
)
233 KMF_KEY_HANDLE pubk
, prik
;
234 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_NSS
;
235 KMF_ATTRIBUTE attrlist
[16];
241 token
= DEFAULT_NSS_TOKEN
;
243 kmfrv
= configure_nss(kmfhandle
, dir
, prefix
);
247 keylength
= keylen
; /* bits */
250 kmf_set_attr_at_index(attrlist
, numattr
,
251 KMF_KEYSTORE_TYPE_ATTR
, &kstype
,
255 kmf_set_attr_at_index(attrlist
, numattr
,
256 KMF_KEYALG_ATTR
, &keytype
,
260 kmf_set_attr_at_index(attrlist
, numattr
,
261 KMF_KEYLENGTH_ATTR
, &keylength
,
265 if (nickname
!= NULL
) {
266 kmf_set_attr_at_index(attrlist
, numattr
,
267 KMF_KEYLABEL_ATTR
, nickname
,
272 if (tokencred
!= NULL
&& tokencred
->cred
!= NULL
) {
273 kmf_set_attr_at_index(attrlist
, numattr
,
274 KMF_CREDENTIAL_ATTR
, tokencred
,
275 sizeof (KMF_CREDENTIAL
));
280 kmf_set_attr_at_index(attrlist
, numattr
,
281 KMF_TOKEN_LABEL_ATTR
, token
,
286 kmf_set_attr_at_index(attrlist
, numattr
,
287 KMF_PRIVKEY_HANDLE_ATTR
, &prik
,
288 sizeof (KMF_KEY_HANDLE
));
291 kmf_set_attr_at_index(attrlist
, numattr
,
292 KMF_PUBKEY_HANDLE_ATTR
, &pubk
,
293 sizeof (KMF_KEY_HANDLE
));
296 if (keytype
== KMF_ECDSA
&& curveoid
!= NULL
) {
297 kmf_set_attr_at_index(attrlist
, numattr
,
298 KMF_ECC_CURVE_OID_ATTR
, curveoid
,
303 kmfrv
= kmf_create_keypair(kmfhandle
, numattr
, attrlist
);
304 if (kmfrv
!= KMF_OK
) {
308 if (kmfrv
== KMF_OK
) {
309 if (outPriKey
!= NULL
)
311 if (outPubKey
!= NULL
)
318 pk_genkeypair(int argc
, char *argv
[])
322 extern int optind_av
;
323 extern char *optarg_av
;
324 KMF_KEYSTORE_TYPE kstype
= 0;
325 char *tokenname
= NULL
;
328 char *keytype
= PK_DEFAULT_KEYTYPE
;
329 int keylen
= PK_DEFAULT_KEYLENGTH
;
333 KMF_HANDLE_T kmfhandle
= NULL
;
334 KMF_ENCODE_FORMAT fmt
= KMF_FORMAT_ASN1
;
335 KMF_KEY_ALG keyAlg
= KMF_RSA
;
336 KMF_ALGORITHM_INDEX sigAlg
;
337 KMF_CREDENTIAL tokencred
= { NULL
, 0 };
338 KMF_OID
*curveoid
= NULL
; /* ECC */
341 while ((opt
= getopt_av(argc
, argv
,
342 "k:(keystore)s:(subject)n:(nickname)"
343 "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
344 "l:(label)K:(outkey)F:(format)C:(curve)"
345 "E(listcurves)")) != EOF
) {
347 if (opt
!= 'i' && opt
!= 'E' && EMPTYSTRING(optarg_av
))
348 return (PK_ERR_USAGE
);
352 kstype
= KS2Int(optarg_av
);
354 return (PK_ERR_USAGE
);
359 return (PK_ERR_USAGE
);
364 return (PK_ERR_USAGE
);
365 tokenname
= optarg_av
;
369 return (PK_ERR_USAGE
);
374 return (PK_ERR_USAGE
);
381 if (sscanf(optarg_av
, "%d",
383 cryptoerror(LOG_STDERR
,
384 gettext("key length must be"
385 "a numeric value (%s)\n"),
387 return (PK_ERR_USAGE
);
393 return (PK_ERR_USAGE
);
398 return (PK_ERR_USAGE
);
402 curveoid
= ecc_name_to_oid(optarg_av
);
403 if (curveoid
== NULL
) {
404 cryptoerror(LOG_STDERR
,
406 "Unrecognized ECC curve.\n"));
407 return (PK_ERR_USAGE
);
414 return (PK_ERR_USAGE
);
418 /* No additional args allowed. */
422 return (PK_ERR_USAGE
);
425 if ((rv
= kmf_initialize(&kmfhandle
, NULL
, NULL
)) != KMF_OK
) {
426 cryptoerror(LOG_STDERR
, gettext("Error initializing KMF\n"));
427 return (PK_ERR_USAGE
);
430 /* Assume keystore = PKCS#11 if not specified. */
432 kstype
= KMF_KEYSTORE_PK11TOKEN
;
434 DIR_OPTION_CHECK(kstype
, dir
);
436 if (format
&& (fmt
= Str2Format(format
)) == KMF_FORMAT_UNDEF
) {
437 cryptoerror(LOG_STDERR
,
438 gettext("Error parsing format string (%s).\n"),
440 return (PK_ERR_USAGE
);
443 if (Str2KeyType(keytype
, NULL
, &keyAlg
, &sigAlg
) != 0) {
444 cryptoerror(LOG_STDERR
, gettext("Unrecognized keytype (%s).\n"),
446 return (PK_ERR_USAGE
);
448 if (curveoid
!= NULL
&& keyAlg
!= KMF_ECDSA
) {
449 cryptoerror(LOG_STDERR
, gettext("EC curves are only "
450 "valid for EC keytypes.\n"));
451 return (PK_ERR_USAGE
);
453 if (keyAlg
== KMF_ECDSA
&& curveoid
== NULL
) {
454 cryptoerror(LOG_STDERR
, gettext("A curve must be "
455 "specifed when using EC keys.\n"));
456 return (PK_ERR_USAGE
);
458 if (keyAlg
== KMF_ECDSA
&& kstype
== KMF_KEYSTORE_OPENSSL
) {
459 (void) fprintf(stderr
, gettext("ECC certificates are"
460 "only supported with the pkcs11 and nss keystores\n"));
464 /* Adjust default keylength for NSS and DSA */
465 if (keyAlg
== KMF_DSA
&& kstype
== KMF_KEYSTORE_NSS
) {
466 /* NSS only allows for 512-1024 bit DSA keys */
468 /* If nothing was given, default to 1024 */
470 else if (keylen
> 1024 || keylen
< 512) {
471 (void) fprintf(stderr
, gettext("NSS keystore only "
472 "supports DSA keylengths of 512 - 1024 bits\n"));
478 if (kstype
== KMF_KEYSTORE_NSS
|| kstype
== KMF_KEYSTORE_PK11TOKEN
) {
480 (void) fprintf(stderr
,
481 gettext("No key label specified\n"));
485 if (tokenname
== NULL
|| !strlen(tokenname
)) {
486 if (kstype
== KMF_KEYSTORE_NSS
) {
487 tokenname
= "internal";
489 tokenname
= PK_DEFAULT_PK11TOKEN
;
493 (void) get_token_password(kstype
, tokenname
, &tokencred
);
496 if (kstype
== KMF_KEYSTORE_NSS
) {
498 dir
= PK_DEFAULT_DIRECTORY
;
500 rv
= genkeypair_nss(kmfhandle
,
501 tokenname
, label
, dir
, prefix
, keyAlg
, keylen
,
502 &tokencred
, curveoid
, NULL
, NULL
);
504 } else if (kstype
== KMF_KEYSTORE_PK11TOKEN
) {
505 rv
= genkeypair_pkcs11(kmfhandle
,
506 tokenname
, label
, keyAlg
, keylen
,
507 &tokencred
, curveoid
, NULL
, NULL
);
509 } else if (kstype
== KMF_KEYSTORE_OPENSSL
) {
510 rv
= genkeypair_file(kmfhandle
, keyAlg
, keylen
,
511 fmt
, outkey
, NULL
, NULL
);
515 display_error(kmfhandle
, rv
,
516 gettext("Error creating and keypair"));
518 if (tokencred
.cred
!= NULL
)
519 free(tokencred
.cred
);
521 (void) kmf_finalize(kmfhandle
);