1*11973Swyllys.ingersoll@sun.com /*
2*11973Swyllys.ingersoll@sun.com * CDDL HEADER START
3*11973Swyllys.ingersoll@sun.com *
4*11973Swyllys.ingersoll@sun.com * The contents of this file are subject to the terms of the
5*11973Swyllys.ingersoll@sun.com * Common Development and Distribution License (the "License").
6*11973Swyllys.ingersoll@sun.com * You may not use this file except in compliance with the License.
7*11973Swyllys.ingersoll@sun.com *
8*11973Swyllys.ingersoll@sun.com * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11973Swyllys.ingersoll@sun.com * or http://www.opensolaris.org/os/licensing.
10*11973Swyllys.ingersoll@sun.com * See the License for the specific language governing permissions
11*11973Swyllys.ingersoll@sun.com * and limitations under the License.
12*11973Swyllys.ingersoll@sun.com *
13*11973Swyllys.ingersoll@sun.com * When distributing Covered Code, include this CDDL HEADER in each
14*11973Swyllys.ingersoll@sun.com * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11973Swyllys.ingersoll@sun.com * If applicable, add the following below this CDDL HEADER, with the
16*11973Swyllys.ingersoll@sun.com * fields enclosed by brackets "[]" replaced with your own identifying
17*11973Swyllys.ingersoll@sun.com * information: Portions Copyright [yyyy] [name of copyright owner]
18*11973Swyllys.ingersoll@sun.com *
19*11973Swyllys.ingersoll@sun.com * CDDL HEADER END
20*11973Swyllys.ingersoll@sun.com */
21*11973Swyllys.ingersoll@sun.com /*
22*11973Swyllys.ingersoll@sun.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23*11973Swyllys.ingersoll@sun.com * Use is subject to license terms.
24*11973Swyllys.ingersoll@sun.com */
25*11973Swyllys.ingersoll@sun.com
26*11973Swyllys.ingersoll@sun.com #include <stdio.h>
27*11973Swyllys.ingersoll@sun.com #include <string.h>
28*11973Swyllys.ingersoll@sun.com #include <ctype.h>
29*11973Swyllys.ingersoll@sun.com #include <malloc.h>
30*11973Swyllys.ingersoll@sun.com #include <libgen.h>
31*11973Swyllys.ingersoll@sun.com #include <errno.h>
32*11973Swyllys.ingersoll@sun.com #include <cryptoutil.h>
33*11973Swyllys.ingersoll@sun.com #include <security/cryptoki.h>
34*11973Swyllys.ingersoll@sun.com #include "common.h"
35*11973Swyllys.ingersoll@sun.com
36*11973Swyllys.ingersoll@sun.com #include <kmfapi.h>
37*11973Swyllys.ingersoll@sun.com
38*11973Swyllys.ingersoll@sun.com #define SET_VALUE(f, s) \
39*11973Swyllys.ingersoll@sun.com kmfrv = f; \
40*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK) { \
41*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, \
42*11973Swyllys.ingersoll@sun.com gettext("Failed to set %s: 0x%02x\n"), \
43*11973Swyllys.ingersoll@sun.com s, kmfrv); \
44*11973Swyllys.ingersoll@sun.com goto cleanup; \
45*11973Swyllys.ingersoll@sun.com }
46*11973Swyllys.ingersoll@sun.com
47*11973Swyllys.ingersoll@sun.com KMF_RETURN
genkeypair_pkcs11(KMF_HANDLE_T kmfhandle,char * token,char * keylabel,KMF_KEY_ALG keyAlg,int keylen,KMF_CREDENTIAL * tokencred,KMF_OID * curveoid,KMF_KEY_HANDLE * outPriKey,KMF_KEY_HANDLE * outPubKey)48*11973Swyllys.ingersoll@sun.com genkeypair_pkcs11(KMF_HANDLE_T kmfhandle,
49*11973Swyllys.ingersoll@sun.com char *token, char *keylabel, KMF_KEY_ALG keyAlg,
50*11973Swyllys.ingersoll@sun.com int keylen, KMF_CREDENTIAL *tokencred, KMF_OID *curveoid,
51*11973Swyllys.ingersoll@sun.com KMF_KEY_HANDLE *outPriKey, KMF_KEY_HANDLE *outPubKey)
52*11973Swyllys.ingersoll@sun.com {
53*11973Swyllys.ingersoll@sun.com KMF_RETURN kmfrv = KMF_OK;
54*11973Swyllys.ingersoll@sun.com KMF_KEY_HANDLE pubk, prik;
55*11973Swyllys.ingersoll@sun.com KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
56*11973Swyllys.ingersoll@sun.com KMF_ATTRIBUTE attrlist[16];
57*11973Swyllys.ingersoll@sun.com int numattr = 0;
58*11973Swyllys.ingersoll@sun.com KMF_KEY_ALG keytype;
59*11973Swyllys.ingersoll@sun.com uint32_t keylength;
60*11973Swyllys.ingersoll@sun.com
61*11973Swyllys.ingersoll@sun.com keylength = keylen; /* bits */
62*11973Swyllys.ingersoll@sun.com keytype = keyAlg;
63*11973Swyllys.ingersoll@sun.com
64*11973Swyllys.ingersoll@sun.com /* Select a PKCS11 token */
65*11973Swyllys.ingersoll@sun.com kmfrv = select_token(kmfhandle, token, FALSE);
66*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK)
67*11973Swyllys.ingersoll@sun.com return (kmfrv);
68*11973Swyllys.ingersoll@sun.com
69*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
70*11973Swyllys.ingersoll@sun.com KMF_KEYSTORE_TYPE_ATTR, &kstype,
71*11973Swyllys.ingersoll@sun.com sizeof (kstype));
72*11973Swyllys.ingersoll@sun.com numattr++;
73*11973Swyllys.ingersoll@sun.com
74*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
75*11973Swyllys.ingersoll@sun.com KMF_KEYALG_ATTR, &keytype,
76*11973Swyllys.ingersoll@sun.com sizeof (keytype));
77*11973Swyllys.ingersoll@sun.com numattr++;
78*11973Swyllys.ingersoll@sun.com
79*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
80*11973Swyllys.ingersoll@sun.com KMF_KEYLENGTH_ATTR, &keylength,
81*11973Swyllys.ingersoll@sun.com sizeof (keylength));
82*11973Swyllys.ingersoll@sun.com numattr++;
83*11973Swyllys.ingersoll@sun.com
84*11973Swyllys.ingersoll@sun.com if (keylabel != NULL) {
85*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
86*11973Swyllys.ingersoll@sun.com KMF_KEYLABEL_ATTR, keylabel,
87*11973Swyllys.ingersoll@sun.com strlen(keylabel));
88*11973Swyllys.ingersoll@sun.com numattr++;
89*11973Swyllys.ingersoll@sun.com }
90*11973Swyllys.ingersoll@sun.com
91*11973Swyllys.ingersoll@sun.com if (tokencred != NULL && tokencred->cred != NULL) {
92*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
93*11973Swyllys.ingersoll@sun.com KMF_CREDENTIAL_ATTR, tokencred,
94*11973Swyllys.ingersoll@sun.com sizeof (KMF_CREDENTIAL));
95*11973Swyllys.ingersoll@sun.com numattr++;
96*11973Swyllys.ingersoll@sun.com }
97*11973Swyllys.ingersoll@sun.com
98*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
99*11973Swyllys.ingersoll@sun.com KMF_PRIVKEY_HANDLE_ATTR, &prik,
100*11973Swyllys.ingersoll@sun.com sizeof (KMF_KEY_HANDLE));
101*11973Swyllys.ingersoll@sun.com numattr++;
102*11973Swyllys.ingersoll@sun.com
103*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
104*11973Swyllys.ingersoll@sun.com KMF_PUBKEY_HANDLE_ATTR, &pubk,
105*11973Swyllys.ingersoll@sun.com sizeof (KMF_KEY_HANDLE));
106*11973Swyllys.ingersoll@sun.com numattr++;
107*11973Swyllys.ingersoll@sun.com
108*11973Swyllys.ingersoll@sun.com if (keytype == KMF_ECDSA && curveoid != NULL) {
109*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
110*11973Swyllys.ingersoll@sun.com KMF_ECC_CURVE_OID_ATTR, curveoid,
111*11973Swyllys.ingersoll@sun.com sizeof (KMF_OID));
112*11973Swyllys.ingersoll@sun.com numattr++;
113*11973Swyllys.ingersoll@sun.com }
114*11973Swyllys.ingersoll@sun.com
115*11973Swyllys.ingersoll@sun.com kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
116*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK) {
117*11973Swyllys.ingersoll@sun.com return (kmfrv);
118*11973Swyllys.ingersoll@sun.com }
119*11973Swyllys.ingersoll@sun.com
120*11973Swyllys.ingersoll@sun.com cleanup:
121*11973Swyllys.ingersoll@sun.com if (kmfrv == KMF_OK) {
122*11973Swyllys.ingersoll@sun.com if (outPriKey != NULL)
123*11973Swyllys.ingersoll@sun.com *outPriKey = prik;
124*11973Swyllys.ingersoll@sun.com if (outPubKey != NULL)
125*11973Swyllys.ingersoll@sun.com *outPubKey = pubk;
126*11973Swyllys.ingersoll@sun.com }
127*11973Swyllys.ingersoll@sun.com
128*11973Swyllys.ingersoll@sun.com return (kmfrv);
129*11973Swyllys.ingersoll@sun.com }
130*11973Swyllys.ingersoll@sun.com
131*11973Swyllys.ingersoll@sun.com KMF_RETURN
genkeypair_file(KMF_HANDLE_T kmfhandle,KMF_KEY_ALG keyAlg,int keylen,KMF_ENCODE_FORMAT fmt,char * outkey,KMF_KEY_HANDLE * outPriKey,KMF_KEY_HANDLE * outPubKey)132*11973Swyllys.ingersoll@sun.com genkeypair_file(KMF_HANDLE_T kmfhandle,
133*11973Swyllys.ingersoll@sun.com KMF_KEY_ALG keyAlg, int keylen, KMF_ENCODE_FORMAT fmt,
134*11973Swyllys.ingersoll@sun.com char *outkey,
135*11973Swyllys.ingersoll@sun.com KMF_KEY_HANDLE *outPriKey, KMF_KEY_HANDLE *outPubKey)
136*11973Swyllys.ingersoll@sun.com {
137*11973Swyllys.ingersoll@sun.com KMF_RETURN kmfrv;
138*11973Swyllys.ingersoll@sun.com KMF_KEY_HANDLE pubk, prik;
139*11973Swyllys.ingersoll@sun.com char *fullkeypath = NULL;
140*11973Swyllys.ingersoll@sun.com KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
141*11973Swyllys.ingersoll@sun.com KMF_ATTRIBUTE attrlist[10];
142*11973Swyllys.ingersoll@sun.com int numattr = 0;
143*11973Swyllys.ingersoll@sun.com KMF_KEY_ALG keytype;
144*11973Swyllys.ingersoll@sun.com uint32_t keylength;
145*11973Swyllys.ingersoll@sun.com KMF_ENCODE_FORMAT format;
146*11973Swyllys.ingersoll@sun.com
147*11973Swyllys.ingersoll@sun.com if (EMPTYSTRING(outkey)) {
148*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
149*11973Swyllys.ingersoll@sun.com gettext("No output file was specified for "
150*11973Swyllys.ingersoll@sun.com "the key\n"));
151*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
152*11973Swyllys.ingersoll@sun.com }
153*11973Swyllys.ingersoll@sun.com
154*11973Swyllys.ingersoll@sun.com fullkeypath = strdup(outkey);
155*11973Swyllys.ingersoll@sun.com if (verify_file(fullkeypath)) {
156*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
157*11973Swyllys.ingersoll@sun.com gettext("Cannot write the indicated output "
158*11973Swyllys.ingersoll@sun.com "key file (%s).\n"), fullkeypath);
159*11973Swyllys.ingersoll@sun.com free(fullkeypath);
160*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
161*11973Swyllys.ingersoll@sun.com }
162*11973Swyllys.ingersoll@sun.com
163*11973Swyllys.ingersoll@sun.com keylength = keylen; /* bits */
164*11973Swyllys.ingersoll@sun.com keytype = keyAlg;
165*11973Swyllys.ingersoll@sun.com format = fmt;
166*11973Swyllys.ingersoll@sun.com
167*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
168*11973Swyllys.ingersoll@sun.com KMF_KEYSTORE_TYPE_ATTR, &kstype,
169*11973Swyllys.ingersoll@sun.com sizeof (kstype));
170*11973Swyllys.ingersoll@sun.com numattr++;
171*11973Swyllys.ingersoll@sun.com
172*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
173*11973Swyllys.ingersoll@sun.com KMF_KEYALG_ATTR, &keytype,
174*11973Swyllys.ingersoll@sun.com sizeof (keytype));
175*11973Swyllys.ingersoll@sun.com numattr++;
176*11973Swyllys.ingersoll@sun.com
177*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
178*11973Swyllys.ingersoll@sun.com KMF_KEYLENGTH_ATTR, &keylength,
179*11973Swyllys.ingersoll@sun.com sizeof (keylength));
180*11973Swyllys.ingersoll@sun.com numattr++;
181*11973Swyllys.ingersoll@sun.com
182*11973Swyllys.ingersoll@sun.com if (fullkeypath != NULL) {
183*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
184*11973Swyllys.ingersoll@sun.com KMF_KEY_FILENAME_ATTR, fullkeypath,
185*11973Swyllys.ingersoll@sun.com strlen(fullkeypath));
186*11973Swyllys.ingersoll@sun.com numattr++;
187*11973Swyllys.ingersoll@sun.com }
188*11973Swyllys.ingersoll@sun.com
189*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
190*11973Swyllys.ingersoll@sun.com KMF_ENCODE_FORMAT_ATTR, &format,
191*11973Swyllys.ingersoll@sun.com sizeof (format));
192*11973Swyllys.ingersoll@sun.com numattr++;
193*11973Swyllys.ingersoll@sun.com
194*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
195*11973Swyllys.ingersoll@sun.com KMF_PRIVKEY_HANDLE_ATTR, &prik,
196*11973Swyllys.ingersoll@sun.com sizeof (KMF_KEY_HANDLE));
197*11973Swyllys.ingersoll@sun.com numattr++;
198*11973Swyllys.ingersoll@sun.com
199*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
200*11973Swyllys.ingersoll@sun.com KMF_PUBKEY_HANDLE_ATTR, &pubk,
201*11973Swyllys.ingersoll@sun.com sizeof (KMF_KEY_HANDLE));
202*11973Swyllys.ingersoll@sun.com numattr++;
203*11973Swyllys.ingersoll@sun.com
204*11973Swyllys.ingersoll@sun.com kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
205*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK) {
206*11973Swyllys.ingersoll@sun.com goto cleanup;
207*11973Swyllys.ingersoll@sun.com }
208*11973Swyllys.ingersoll@sun.com
209*11973Swyllys.ingersoll@sun.com cleanup:
210*11973Swyllys.ingersoll@sun.com if (fullkeypath != NULL)
211*11973Swyllys.ingersoll@sun.com free(fullkeypath);
212*11973Swyllys.ingersoll@sun.com
213*11973Swyllys.ingersoll@sun.com if (kmfrv == KMF_OK) {
214*11973Swyllys.ingersoll@sun.com if (outPriKey != NULL)
215*11973Swyllys.ingersoll@sun.com *outPriKey = prik;
216*11973Swyllys.ingersoll@sun.com if (outPubKey != NULL)
217*11973Swyllys.ingersoll@sun.com *outPubKey = pubk;
218*11973Swyllys.ingersoll@sun.com }
219*11973Swyllys.ingersoll@sun.com
220*11973Swyllys.ingersoll@sun.com return (kmfrv);
221*11973Swyllys.ingersoll@sun.com }
222*11973Swyllys.ingersoll@sun.com
223*11973Swyllys.ingersoll@sun.com KMF_RETURN
genkeypair_nss(KMF_HANDLE_T kmfhandle,char * token,char * nickname,char * dir,char * prefix,KMF_KEY_ALG keyAlg,int keylen,KMF_CREDENTIAL * tokencred,KMF_OID * curveoid,KMF_KEY_HANDLE * outPriKey,KMF_KEY_HANDLE * outPubKey)224*11973Swyllys.ingersoll@sun.com genkeypair_nss(KMF_HANDLE_T kmfhandle,
225*11973Swyllys.ingersoll@sun.com char *token,
226*11973Swyllys.ingersoll@sun.com char *nickname, char *dir, char *prefix,
227*11973Swyllys.ingersoll@sun.com KMF_KEY_ALG keyAlg,
228*11973Swyllys.ingersoll@sun.com int keylen, KMF_CREDENTIAL *tokencred,
229*11973Swyllys.ingersoll@sun.com KMF_OID *curveoid,
230*11973Swyllys.ingersoll@sun.com KMF_KEY_HANDLE *outPriKey, KMF_KEY_HANDLE *outPubKey)
231*11973Swyllys.ingersoll@sun.com {
232*11973Swyllys.ingersoll@sun.com KMF_RETURN kmfrv;
233*11973Swyllys.ingersoll@sun.com KMF_KEY_HANDLE pubk, prik;
234*11973Swyllys.ingersoll@sun.com KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
235*11973Swyllys.ingersoll@sun.com KMF_ATTRIBUTE attrlist[16];
236*11973Swyllys.ingersoll@sun.com int numattr = 0;
237*11973Swyllys.ingersoll@sun.com KMF_KEY_ALG keytype;
238*11973Swyllys.ingersoll@sun.com uint32_t keylength;
239*11973Swyllys.ingersoll@sun.com
240*11973Swyllys.ingersoll@sun.com if (token == NULL)
241*11973Swyllys.ingersoll@sun.com token = DEFAULT_NSS_TOKEN;
242*11973Swyllys.ingersoll@sun.com
243*11973Swyllys.ingersoll@sun.com kmfrv = configure_nss(kmfhandle, dir, prefix);
244*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK)
245*11973Swyllys.ingersoll@sun.com return (kmfrv);
246*11973Swyllys.ingersoll@sun.com
247*11973Swyllys.ingersoll@sun.com keylength = keylen; /* bits */
248*11973Swyllys.ingersoll@sun.com keytype = keyAlg;
249*11973Swyllys.ingersoll@sun.com
250*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
251*11973Swyllys.ingersoll@sun.com KMF_KEYSTORE_TYPE_ATTR, &kstype,
252*11973Swyllys.ingersoll@sun.com sizeof (kstype));
253*11973Swyllys.ingersoll@sun.com numattr++;
254*11973Swyllys.ingersoll@sun.com
255*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
256*11973Swyllys.ingersoll@sun.com KMF_KEYALG_ATTR, &keytype,
257*11973Swyllys.ingersoll@sun.com sizeof (keytype));
258*11973Swyllys.ingersoll@sun.com numattr++;
259*11973Swyllys.ingersoll@sun.com
260*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
261*11973Swyllys.ingersoll@sun.com KMF_KEYLENGTH_ATTR, &keylength,
262*11973Swyllys.ingersoll@sun.com sizeof (keylength));
263*11973Swyllys.ingersoll@sun.com numattr++;
264*11973Swyllys.ingersoll@sun.com
265*11973Swyllys.ingersoll@sun.com if (nickname != NULL) {
266*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
267*11973Swyllys.ingersoll@sun.com KMF_KEYLABEL_ATTR, nickname,
268*11973Swyllys.ingersoll@sun.com strlen(nickname));
269*11973Swyllys.ingersoll@sun.com numattr++;
270*11973Swyllys.ingersoll@sun.com }
271*11973Swyllys.ingersoll@sun.com
272*11973Swyllys.ingersoll@sun.com if (tokencred != NULL && tokencred->cred != NULL) {
273*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
274*11973Swyllys.ingersoll@sun.com KMF_CREDENTIAL_ATTR, tokencred,
275*11973Swyllys.ingersoll@sun.com sizeof (KMF_CREDENTIAL));
276*11973Swyllys.ingersoll@sun.com numattr++;
277*11973Swyllys.ingersoll@sun.com }
278*11973Swyllys.ingersoll@sun.com
279*11973Swyllys.ingersoll@sun.com if (token != NULL) {
280*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
281*11973Swyllys.ingersoll@sun.com KMF_TOKEN_LABEL_ATTR, token,
282*11973Swyllys.ingersoll@sun.com strlen(token));
283*11973Swyllys.ingersoll@sun.com numattr++;
284*11973Swyllys.ingersoll@sun.com }
285*11973Swyllys.ingersoll@sun.com
286*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
287*11973Swyllys.ingersoll@sun.com KMF_PRIVKEY_HANDLE_ATTR, &prik,
288*11973Swyllys.ingersoll@sun.com sizeof (KMF_KEY_HANDLE));
289*11973Swyllys.ingersoll@sun.com numattr++;
290*11973Swyllys.ingersoll@sun.com
291*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
292*11973Swyllys.ingersoll@sun.com KMF_PUBKEY_HANDLE_ATTR, &pubk,
293*11973Swyllys.ingersoll@sun.com sizeof (KMF_KEY_HANDLE));
294*11973Swyllys.ingersoll@sun.com numattr++;
295*11973Swyllys.ingersoll@sun.com
296*11973Swyllys.ingersoll@sun.com if (keytype == KMF_ECDSA && curveoid != NULL) {
297*11973Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr,
298*11973Swyllys.ingersoll@sun.com KMF_ECC_CURVE_OID_ATTR, curveoid,
299*11973Swyllys.ingersoll@sun.com sizeof (KMF_OID));
300*11973Swyllys.ingersoll@sun.com numattr++;
301*11973Swyllys.ingersoll@sun.com }
302*11973Swyllys.ingersoll@sun.com
303*11973Swyllys.ingersoll@sun.com kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
304*11973Swyllys.ingersoll@sun.com if (kmfrv != KMF_OK) {
305*11973Swyllys.ingersoll@sun.com return (kmfrv);
306*11973Swyllys.ingersoll@sun.com }
307*11973Swyllys.ingersoll@sun.com cleanup:
308*11973Swyllys.ingersoll@sun.com if (kmfrv == KMF_OK) {
309*11973Swyllys.ingersoll@sun.com if (outPriKey != NULL)
310*11973Swyllys.ingersoll@sun.com *outPriKey = prik;
311*11973Swyllys.ingersoll@sun.com if (outPubKey != NULL)
312*11973Swyllys.ingersoll@sun.com *outPubKey = pubk;
313*11973Swyllys.ingersoll@sun.com }
314*11973Swyllys.ingersoll@sun.com return (kmfrv);
315*11973Swyllys.ingersoll@sun.com }
316*11973Swyllys.ingersoll@sun.com
317*11973Swyllys.ingersoll@sun.com int
pk_genkeypair(int argc,char * argv[])318*11973Swyllys.ingersoll@sun.com pk_genkeypair(int argc, char *argv[])
319*11973Swyllys.ingersoll@sun.com {
320*11973Swyllys.ingersoll@sun.com int rv;
321*11973Swyllys.ingersoll@sun.com int opt;
322*11973Swyllys.ingersoll@sun.com extern int optind_av;
323*11973Swyllys.ingersoll@sun.com extern char *optarg_av;
324*11973Swyllys.ingersoll@sun.com KMF_KEYSTORE_TYPE kstype = 0;
325*11973Swyllys.ingersoll@sun.com char *tokenname = NULL;
326*11973Swyllys.ingersoll@sun.com char *dir = NULL;
327*11973Swyllys.ingersoll@sun.com char *prefix = NULL;
328*11973Swyllys.ingersoll@sun.com char *keytype = PK_DEFAULT_KEYTYPE;
329*11973Swyllys.ingersoll@sun.com int keylen = PK_DEFAULT_KEYLENGTH;
330*11973Swyllys.ingersoll@sun.com char *label = NULL;
331*11973Swyllys.ingersoll@sun.com char *outkey = NULL;
332*11973Swyllys.ingersoll@sun.com char *format = NULL;
333*11973Swyllys.ingersoll@sun.com KMF_HANDLE_T kmfhandle = NULL;
334*11973Swyllys.ingersoll@sun.com KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
335*11973Swyllys.ingersoll@sun.com KMF_KEY_ALG keyAlg = KMF_RSA;
336*11973Swyllys.ingersoll@sun.com KMF_ALGORITHM_INDEX sigAlg;
337*11973Swyllys.ingersoll@sun.com KMF_CREDENTIAL tokencred = {NULL, 0};
338*11973Swyllys.ingersoll@sun.com KMF_OID *curveoid = NULL; /* ECC */
339*11973Swyllys.ingersoll@sun.com int y_flag = 0;
340*11973Swyllys.ingersoll@sun.com
341*11973Swyllys.ingersoll@sun.com while ((opt = getopt_av(argc, argv,
342*11973Swyllys.ingersoll@sun.com "k:(keystore)s:(subject)n:(nickname)"
343*11973Swyllys.ingersoll@sun.com "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
344*11973Swyllys.ingersoll@sun.com "l:(label)K:(outkey)F:(format)C:(curve)"
345*11973Swyllys.ingersoll@sun.com "E(listcurves)")) != EOF) {
346*11973Swyllys.ingersoll@sun.com
347*11973Swyllys.ingersoll@sun.com if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av))
348*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
349*11973Swyllys.ingersoll@sun.com
350*11973Swyllys.ingersoll@sun.com switch (opt) {
351*11973Swyllys.ingersoll@sun.com case 'k':
352*11973Swyllys.ingersoll@sun.com kstype = KS2Int(optarg_av);
353*11973Swyllys.ingersoll@sun.com if (kstype == 0)
354*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
355*11973Swyllys.ingersoll@sun.com break;
356*11973Swyllys.ingersoll@sun.com case 'l':
357*11973Swyllys.ingersoll@sun.com case 'n':
358*11973Swyllys.ingersoll@sun.com if (label)
359*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
360*11973Swyllys.ingersoll@sun.com label = optarg_av;
361*11973Swyllys.ingersoll@sun.com break;
362*11973Swyllys.ingersoll@sun.com case 'T':
363*11973Swyllys.ingersoll@sun.com if (tokenname)
364*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
365*11973Swyllys.ingersoll@sun.com tokenname = optarg_av;
366*11973Swyllys.ingersoll@sun.com break;
367*11973Swyllys.ingersoll@sun.com case 'd':
368*11973Swyllys.ingersoll@sun.com if (dir)
369*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
370*11973Swyllys.ingersoll@sun.com dir = optarg_av;
371*11973Swyllys.ingersoll@sun.com break;
372*11973Swyllys.ingersoll@sun.com case 'p':
373*11973Swyllys.ingersoll@sun.com if (prefix)
374*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
375*11973Swyllys.ingersoll@sun.com prefix = optarg_av;
376*11973Swyllys.ingersoll@sun.com break;
377*11973Swyllys.ingersoll@sun.com case 't':
378*11973Swyllys.ingersoll@sun.com keytype = optarg_av;
379*11973Swyllys.ingersoll@sun.com break;
380*11973Swyllys.ingersoll@sun.com case 'y':
381*11973Swyllys.ingersoll@sun.com if (sscanf(optarg_av, "%d",
382*11973Swyllys.ingersoll@sun.com &keylen) != 1) {
383*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
384*11973Swyllys.ingersoll@sun.com gettext("key length must be"
385*11973Swyllys.ingersoll@sun.com "a numeric value (%s)\n"),
386*11973Swyllys.ingersoll@sun.com optarg_av);
387*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
388*11973Swyllys.ingersoll@sun.com }
389*11973Swyllys.ingersoll@sun.com y_flag++;
390*11973Swyllys.ingersoll@sun.com break;
391*11973Swyllys.ingersoll@sun.com case 'K':
392*11973Swyllys.ingersoll@sun.com if (outkey)
393*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
394*11973Swyllys.ingersoll@sun.com outkey = optarg_av;
395*11973Swyllys.ingersoll@sun.com break;
396*11973Swyllys.ingersoll@sun.com case 'F':
397*11973Swyllys.ingersoll@sun.com if (format)
398*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
399*11973Swyllys.ingersoll@sun.com format = optarg_av;
400*11973Swyllys.ingersoll@sun.com break;
401*11973Swyllys.ingersoll@sun.com case 'C':
402*11973Swyllys.ingersoll@sun.com curveoid = ecc_name_to_oid(optarg_av);
403*11973Swyllys.ingersoll@sun.com if (curveoid == NULL) {
404*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
405*11973Swyllys.ingersoll@sun.com gettext(
406*11973Swyllys.ingersoll@sun.com "Unrecognized ECC curve.\n"));
407*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
408*11973Swyllys.ingersoll@sun.com }
409*11973Swyllys.ingersoll@sun.com break;
410*11973Swyllys.ingersoll@sun.com case 'E':
411*11973Swyllys.ingersoll@sun.com show_ecc_curves();
412*11973Swyllys.ingersoll@sun.com return (0);
413*11973Swyllys.ingersoll@sun.com default:
414*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
415*11973Swyllys.ingersoll@sun.com }
416*11973Swyllys.ingersoll@sun.com }
417*11973Swyllys.ingersoll@sun.com
418*11973Swyllys.ingersoll@sun.com /* No additional args allowed. */
419*11973Swyllys.ingersoll@sun.com argc -= optind_av;
420*11973Swyllys.ingersoll@sun.com argv += optind_av;
421*11973Swyllys.ingersoll@sun.com if (argc) {
422*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
423*11973Swyllys.ingersoll@sun.com }
424*11973Swyllys.ingersoll@sun.com
425*11973Swyllys.ingersoll@sun.com if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
426*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
427*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
428*11973Swyllys.ingersoll@sun.com }
429*11973Swyllys.ingersoll@sun.com
430*11973Swyllys.ingersoll@sun.com /* Assume keystore = PKCS#11 if not specified. */
431*11973Swyllys.ingersoll@sun.com if (kstype == 0)
432*11973Swyllys.ingersoll@sun.com kstype = KMF_KEYSTORE_PK11TOKEN;
433*11973Swyllys.ingersoll@sun.com
434*11973Swyllys.ingersoll@sun.com DIR_OPTION_CHECK(kstype, dir);
435*11973Swyllys.ingersoll@sun.com
436*11973Swyllys.ingersoll@sun.com if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
437*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR,
438*11973Swyllys.ingersoll@sun.com gettext("Error parsing format string (%s).\n"),
439*11973Swyllys.ingersoll@sun.com format);
440*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
441*11973Swyllys.ingersoll@sun.com }
442*11973Swyllys.ingersoll@sun.com
443*11973Swyllys.ingersoll@sun.com if (Str2KeyType(keytype, NULL, &keyAlg, &sigAlg) != 0) {
444*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"),
445*11973Swyllys.ingersoll@sun.com keytype);
446*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
447*11973Swyllys.ingersoll@sun.com }
448*11973Swyllys.ingersoll@sun.com if (curveoid != NULL && keyAlg != KMF_ECDSA) {
449*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("EC curves are only "
450*11973Swyllys.ingersoll@sun.com "valid for EC keytypes.\n"));
451*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
452*11973Swyllys.ingersoll@sun.com }
453*11973Swyllys.ingersoll@sun.com if (keyAlg == KMF_ECDSA && curveoid == NULL) {
454*11973Swyllys.ingersoll@sun.com cryptoerror(LOG_STDERR, gettext("A curve must be "
455*11973Swyllys.ingersoll@sun.com "specifed when using EC keys.\n"));
456*11973Swyllys.ingersoll@sun.com return (PK_ERR_USAGE);
457*11973Swyllys.ingersoll@sun.com }
458*11973Swyllys.ingersoll@sun.com if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
459*11973Swyllys.ingersoll@sun.com (void) fprintf(stderr, gettext("ECC certificates are"
460*11973Swyllys.ingersoll@sun.com "only supported with the pkcs11 and nss keystores\n"));
461*11973Swyllys.ingersoll@sun.com rv = PK_ERR_USAGE;
462*11973Swyllys.ingersoll@sun.com goto end;
463*11973Swyllys.ingersoll@sun.com }
464*11973Swyllys.ingersoll@sun.com /* Adjust default keylength for NSS and DSA */
465*11973Swyllys.ingersoll@sun.com if (keyAlg == KMF_DSA && kstype == KMF_KEYSTORE_NSS) {
466*11973Swyllys.ingersoll@sun.com /* NSS only allows for 512-1024 bit DSA keys */
467*11973Swyllys.ingersoll@sun.com if (!y_flag)
468*11973Swyllys.ingersoll@sun.com /* If nothing was given, default to 1024 */
469*11973Swyllys.ingersoll@sun.com keylen = 1024;
470*11973Swyllys.ingersoll@sun.com else if (keylen > 1024 || keylen < 512) {
471*11973Swyllys.ingersoll@sun.com (void) fprintf(stderr, gettext("NSS keystore only "
472*11973Swyllys.ingersoll@sun.com "supports DSA keylengths of 512 - 1024 bits\n"));
473*11973Swyllys.ingersoll@sun.com rv = PK_ERR_USAGE;
474*11973Swyllys.ingersoll@sun.com goto end;
475*11973Swyllys.ingersoll@sun.com }
476*11973Swyllys.ingersoll@sun.com }
477*11973Swyllys.ingersoll@sun.com
478*11973Swyllys.ingersoll@sun.com if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
479*11973Swyllys.ingersoll@sun.com if (label == NULL) {
480*11973Swyllys.ingersoll@sun.com (void) fprintf(stderr,
481*11973Swyllys.ingersoll@sun.com gettext("No key label specified\n"));
482*11973Swyllys.ingersoll@sun.com rv = PK_ERR_USAGE;
483*11973Swyllys.ingersoll@sun.com goto end;
484*11973Swyllys.ingersoll@sun.com }
485*11973Swyllys.ingersoll@sun.com if (tokenname == NULL || !strlen(tokenname)) {
486*11973Swyllys.ingersoll@sun.com if (kstype == KMF_KEYSTORE_NSS) {
487*11973Swyllys.ingersoll@sun.com tokenname = "internal";
488*11973Swyllys.ingersoll@sun.com } else {
489*11973Swyllys.ingersoll@sun.com tokenname = PK_DEFAULT_PK11TOKEN;
490*11973Swyllys.ingersoll@sun.com }
491*11973Swyllys.ingersoll@sun.com }
492*11973Swyllys.ingersoll@sun.com
493*11973Swyllys.ingersoll@sun.com (void) get_token_password(kstype, tokenname, &tokencred);
494*11973Swyllys.ingersoll@sun.com }
495*11973Swyllys.ingersoll@sun.com
496*11973Swyllys.ingersoll@sun.com if (kstype == KMF_KEYSTORE_NSS) {
497*11973Swyllys.ingersoll@sun.com if (dir == NULL)
498*11973Swyllys.ingersoll@sun.com dir = PK_DEFAULT_DIRECTORY;
499*11973Swyllys.ingersoll@sun.com
500*11973Swyllys.ingersoll@sun.com rv = genkeypair_nss(kmfhandle,
501*11973Swyllys.ingersoll@sun.com tokenname, label, dir, prefix, keyAlg, keylen,
502*11973Swyllys.ingersoll@sun.com &tokencred, curveoid, NULL, NULL);
503*11973Swyllys.ingersoll@sun.com
504*11973Swyllys.ingersoll@sun.com } else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
505*11973Swyllys.ingersoll@sun.com rv = genkeypair_pkcs11(kmfhandle,
506*11973Swyllys.ingersoll@sun.com tokenname, label, keyAlg, keylen,
507*11973Swyllys.ingersoll@sun.com &tokencred, curveoid, NULL, NULL);
508*11973Swyllys.ingersoll@sun.com
509*11973Swyllys.ingersoll@sun.com } else if (kstype == KMF_KEYSTORE_OPENSSL) {
510*11973Swyllys.ingersoll@sun.com rv = genkeypair_file(kmfhandle, keyAlg, keylen,
511*11973Swyllys.ingersoll@sun.com fmt, outkey, NULL, NULL);
512*11973Swyllys.ingersoll@sun.com }
513*11973Swyllys.ingersoll@sun.com
514*11973Swyllys.ingersoll@sun.com if (rv != KMF_OK)
515*11973Swyllys.ingersoll@sun.com display_error(kmfhandle, rv,
516*11973Swyllys.ingersoll@sun.com gettext("Error creating and keypair"));
517*11973Swyllys.ingersoll@sun.com end:
518*11973Swyllys.ingersoll@sun.com if (tokencred.cred != NULL)
519*11973Swyllys.ingersoll@sun.com free(tokencred.cred);
520*11973Swyllys.ingersoll@sun.com
521*11973Swyllys.ingersoll@sun.com (void) kmf_finalize(kmfhandle);
522*11973Swyllys.ingersoll@sun.com return (rv);
523*11973Swyllys.ingersoll@sun.com }
524