1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * This file implements the import operation for this tool.
28 * The basic flow of the process is to decrypt the PKCS#12
29 * input file if it has a password, parse the elements in
30 * the file, find the soft token, log into it, import the
31 * PKCS#11 objects into the soft token, and log out.
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include "common.h"
43
44 #include <kmfapi.h>
45
46 #define NEW_ATTRLIST(a, n) \
47 { \
48 a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
49 if (a == NULL) { \
50 rv = KMF_ERR_MEMORY; \
51 goto end; \
52 } \
53 (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \
54 }
55
56 static KMF_RETURN
pk_import_pk12_files(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * cred,char * outfile,char * certfile,char * keyfile,KMF_ENCODE_FORMAT outformat)57 pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
58 char *outfile, char *certfile, char *keyfile,
59 KMF_ENCODE_FORMAT outformat)
60 {
61 KMF_RETURN rv = KMF_OK;
62 KMF_X509_DER_CERT *certs = NULL;
63 KMF_RAW_KEY_DATA *keys = NULL;
64 int ncerts = 0;
65 int nkeys = 0;
66 int i;
67 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
68 KMF_ATTRIBUTE *attrlist = NULL;
69 int numattr = 0;
70
71 rv = kmf_import_objects(kmfhandle, outfile, cred,
72 &certs, &ncerts, &keys, &nkeys);
73
74 if (rv == KMF_OK) {
75 (void) printf(gettext("Found %d certificate(s) and %d "
76 "key(s) in %s\n"), ncerts, nkeys, outfile);
77 }
78
79 if (rv == KMF_OK && ncerts > 0) {
80 char newcertfile[MAXPATHLEN];
81
82 NEW_ATTRLIST(attrlist, (3 + (3 * ncerts)));
83
84 kmf_set_attr_at_index(attrlist, numattr,
85 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
86 numattr++;
87
88 kmf_set_attr_at_index(attrlist, numattr,
89 KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
90 numattr++;
91
92 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
93 int num = numattr;
94
95 /*
96 * If storing more than 1 cert, gotta change
97 * the name so we don't overwrite the previous one.
98 * Just append a _# to the name.
99 */
100 if (i > 0) {
101 (void) snprintf(newcertfile,
102 sizeof (newcertfile), "%s_%d", certfile, i);
103
104 kmf_set_attr_at_index(attrlist, num,
105 KMF_CERT_FILENAME_ATTR, newcertfile,
106 strlen(newcertfile));
107 num++;
108 } else {
109 kmf_set_attr_at_index(attrlist, num,
110 KMF_CERT_FILENAME_ATTR, certfile,
111 strlen(certfile));
112 num++;
113 }
114
115 if (certs[i].kmf_private.label != NULL) {
116 kmf_set_attr_at_index(attrlist, num,
117 KMF_CERT_LABEL_ATTR,
118 certs[i].kmf_private.label,
119 strlen(certs[i].kmf_private.label));
120 num++;
121 }
122 kmf_set_attr_at_index(attrlist, num,
123 KMF_CERT_DATA_ATTR, &certs[i].certificate,
124 sizeof (KMF_DATA));
125 num++;
126 rv = kmf_store_cert(kmfhandle, num, attrlist);
127 }
128 free(attrlist);
129 }
130 if (rv == KMF_OK && nkeys > 0) {
131 char newkeyfile[MAXPATHLEN];
132 numattr = 0;
133 NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
134
135 kmf_set_attr_at_index(attrlist, numattr,
136 KMF_KEYSTORE_TYPE_ATTR, &kstype,
137 sizeof (kstype));
138 numattr++;
139
140 kmf_set_attr_at_index(attrlist, numattr,
141 KMF_ENCODE_FORMAT_ATTR, &outformat,
142 sizeof (outformat));
143 numattr++;
144
145 if (cred != NULL && cred->credlen > 0) {
146 kmf_set_attr_at_index(attrlist, numattr,
147 KMF_CREDENTIAL_ATTR, cred,
148 sizeof (KMF_CREDENTIAL));
149 numattr++;
150 }
151
152 /* The order of certificates and keys should match */
153 for (i = 0; rv == KMF_OK && i < nkeys; i++) {
154 int num = numattr;
155
156 if (i > 0) {
157 (void) snprintf(newkeyfile,
158 sizeof (newkeyfile), "%s_%d", keyfile, i);
159
160 kmf_set_attr_at_index(attrlist, num,
161 KMF_KEY_FILENAME_ATTR, newkeyfile,
162 strlen(newkeyfile));
163 num++;
164 } else {
165 kmf_set_attr_at_index(attrlist, num,
166 KMF_KEY_FILENAME_ATTR, keyfile,
167 strlen(keyfile));
168 num++;
169 }
170
171 if (i < ncerts) {
172 kmf_set_attr_at_index(attrlist, num,
173 KMF_CERT_DATA_ATTR, &certs[i],
174 sizeof (KMF_CERT_DATA_ATTR));
175 num++;
176 }
177
178 kmf_set_attr_at_index(attrlist, num,
179 KMF_RAW_KEY_ATTR, &keys[i],
180 sizeof (KMF_RAW_KEY_DATA));
181 num++;
182
183 rv = kmf_store_key(kmfhandle, num, attrlist);
184 }
185 free(attrlist);
186 }
187 end:
188 /*
189 * Cleanup memory.
190 */
191 if (certs) {
192 for (i = 0; i < ncerts; i++)
193 kmf_free_kmf_cert(kmfhandle, &certs[i]);
194 free(certs);
195 }
196 if (keys) {
197 for (i = 0; i < nkeys; i++)
198 kmf_free_raw_key(&keys[i]);
199 free(keys);
200 }
201
202
203 return (rv);
204 }
205
206
207 static KMF_RETURN
pk_import_pk12_nss(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * kmfcred,KMF_CREDENTIAL * tokencred,char * token_spec,char * dir,char * prefix,char * nickname,char * trustflags,char * filename)208 pk_import_pk12_nss(
209 KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
210 KMF_CREDENTIAL *tokencred,
211 char *token_spec, char *dir, char *prefix,
212 char *nickname, char *trustflags, char *filename)
213 {
214 KMF_RETURN rv = KMF_OK;
215 KMF_X509_DER_CERT *certs = NULL;
216 KMF_RAW_KEY_DATA *keys = NULL;
217 int ncerts = 0;
218 int nkeys = 0;
219 int i;
220 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
221 KMF_ATTRIBUTE *attrlist = NULL;
222 int numattr = 0;
223
224 rv = configure_nss(kmfhandle, dir, prefix);
225 if (rv != KMF_OK)
226 return (rv);
227
228 rv = kmf_import_objects(kmfhandle, filename, kmfcred,
229 &certs, &ncerts, &keys, &nkeys);
230
231 if (rv == KMF_OK)
232 (void) printf(gettext("Found %d certificate(s) and %d "
233 "key(s) in %s\n"), ncerts, nkeys, filename);
234
235 if (rv == KMF_OK) {
236 numattr = 0;
237 NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
238
239 kmf_set_attr_at_index(attrlist, numattr,
240 KMF_KEYSTORE_TYPE_ATTR, &kstype,
241 sizeof (kstype));
242 numattr++;
243
244 if (token_spec != NULL) {
245 kmf_set_attr_at_index(attrlist, numattr,
246 KMF_TOKEN_LABEL_ATTR, token_spec,
247 strlen(token_spec));
248 numattr++;
249 }
250
251 if (nickname != NULL) {
252 kmf_set_attr_at_index(attrlist, numattr,
253 KMF_KEYLABEL_ATTR, nickname,
254 strlen(nickname));
255 numattr++;
256 }
257
258 if (tokencred->credlen > 0) {
259 kmf_set_attr_at_index(attrlist, numattr,
260 KMF_CREDENTIAL_ATTR, tokencred,
261 sizeof (KMF_CREDENTIAL));
262 numattr++;
263 }
264
265 /* The order of certificates and keys should match */
266 for (i = 0; i < nkeys; i++) {
267 int num = numattr;
268
269 if (i < ncerts) {
270 kmf_set_attr_at_index(attrlist, num,
271 KMF_CERT_DATA_ATTR, &certs[i],
272 sizeof (KMF_DATA));
273 num++;
274 }
275
276 kmf_set_attr_at_index(attrlist, num,
277 KMF_RAW_KEY_ATTR, &keys[i],
278 sizeof (KMF_RAW_KEY_DATA));
279 num++;
280
281 rv = kmf_store_key(kmfhandle, num, attrlist);
282 }
283 free(attrlist);
284 attrlist = NULL;
285 }
286
287 if (rv == KMF_OK) {
288 numattr = 0;
289 NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
290
291 kmf_set_attr_at_index(attrlist, numattr,
292 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
293 numattr++;
294
295 if (token_spec != NULL) {
296 kmf_set_attr_at_index(attrlist, numattr,
297 KMF_TOKEN_LABEL_ATTR, token_spec,
298 strlen(token_spec));
299 numattr++;
300 }
301
302 if (trustflags != NULL) {
303 kmf_set_attr_at_index(attrlist, numattr,
304 KMF_TRUSTFLAG_ATTR, trustflags,
305 strlen(trustflags));
306 numattr++;
307 }
308
309 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
310 int num = numattr;
311
312 if (certs[i].kmf_private.label != NULL) {
313 kmf_set_attr_at_index(attrlist, num,
314 KMF_CERT_LABEL_ATTR,
315 certs[i].kmf_private.label,
316 strlen(certs[i].kmf_private.label));
317 num++;
318 } else if (i == 0 && nickname != NULL) {
319 kmf_set_attr_at_index(attrlist, num,
320 KMF_CERT_LABEL_ATTR, nickname,
321 strlen(nickname));
322 num++;
323 }
324
325 kmf_set_attr_at_index(attrlist, num,
326 KMF_CERT_DATA_ATTR,
327 &certs[i].certificate, sizeof (KMF_DATA));
328 num++;
329 rv = kmf_store_cert(kmfhandle, num, attrlist);
330 }
331 free(attrlist);
332 attrlist = NULL;
333 if (rv != KMF_OK) {
334 display_error(kmfhandle, rv,
335 gettext("Error storing certificate in NSS token"));
336 }
337 }
338
339 end:
340 /*
341 * Cleanup memory.
342 */
343 if (certs) {
344 for (i = 0; i < ncerts; i++)
345 kmf_free_kmf_cert(kmfhandle, &certs[i]);
346 free(certs);
347 }
348 if (keys) {
349 for (i = 0; i < nkeys; i++)
350 kmf_free_raw_key(&keys[i]);
351 free(keys);
352 }
353
354 return (rv);
355 }
356
357 static KMF_RETURN
pk_import_cert(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * label,char * token_spec,char * filename,char * dir,char * prefix,char * trustflags)358 pk_import_cert(
359 KMF_HANDLE_T kmfhandle,
360 KMF_KEYSTORE_TYPE kstype,
361 char *label, char *token_spec, char *filename,
362 char *dir, char *prefix, char *trustflags)
363 {
364 KMF_RETURN rv = KMF_OK;
365 KMF_ATTRIBUTE attrlist[32];
366 KMF_CREDENTIAL tokencred;
367 int i = 0;
368
369 if (kstype == KMF_KEYSTORE_PK11TOKEN) {
370 rv = select_token(kmfhandle, token_spec, FALSE);
371 } else if (kstype == KMF_KEYSTORE_NSS) {
372 rv = configure_nss(kmfhandle, dir, prefix);
373 }
374 if (rv != KMF_OK)
375 return (rv);
376
377 kmf_set_attr_at_index(attrlist, i,
378 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
379 i++;
380
381 kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
382 filename, strlen(filename));
383 i++;
384
385 if (label != NULL) {
386 kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
387 label, strlen(label));
388 i++;
389 }
390
391 if (kstype == KMF_KEYSTORE_NSS) {
392 if (trustflags != NULL) {
393 kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
394 trustflags, strlen(trustflags));
395 i++;
396 }
397
398 if (token_spec != NULL) {
399 kmf_set_attr_at_index(attrlist, i,
400 KMF_TOKEN_LABEL_ATTR,
401 token_spec, strlen(token_spec));
402 i++;
403 }
404 }
405
406 rv = kmf_import_cert(kmfhandle, i, attrlist);
407 if (rv == KMF_ERR_AUTH_FAILED) {
408 /*
409 * The token requires a credential, prompt and try again.
410 */
411 (void) get_token_password(kstype, token_spec, &tokencred);
412 kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
413 &tokencred, sizeof (KMF_CREDENTIAL));
414 i++;
415
416 rv = kmf_import_cert(kmfhandle, i, attrlist);
417
418 }
419 return (rv);
420 }
421
422 static KMF_RETURN
pk_import_file_crl(void * kmfhandle,char * infile,char * outfile,KMF_ENCODE_FORMAT outfmt)423 pk_import_file_crl(void *kmfhandle,
424 char *infile,
425 char *outfile,
426 KMF_ENCODE_FORMAT outfmt)
427 {
428 int numattr = 0;
429 KMF_ATTRIBUTE attrlist[8];
430 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
431
432 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
433 &kstype, sizeof (kstype));
434 numattr++;
435 if (infile) {
436 kmf_set_attr_at_index(attrlist, numattr,
437 KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
438 numattr++;
439 }
440 if (outfile) {
441 kmf_set_attr_at_index(attrlist, numattr,
442 KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
443 numattr++;
444 }
445 kmf_set_attr_at_index(attrlist, numattr,
446 KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
447 numattr++;
448
449 return (kmf_import_crl(kmfhandle, numattr, attrlist));
450 }
451
452 static KMF_RETURN
pk_import_nss_crl(void * kmfhandle,boolean_t verify_crl_flag,char * infile,char * outdir,char * prefix)453 pk_import_nss_crl(void *kmfhandle,
454 boolean_t verify_crl_flag,
455 char *infile,
456 char *outdir,
457 char *prefix)
458 {
459 KMF_RETURN rv;
460 int numattr = 0;
461 KMF_ATTRIBUTE attrlist[4];
462 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
463
464 rv = configure_nss(kmfhandle, outdir, prefix);
465 if (rv != KMF_OK)
466 return (rv);
467
468 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
469 &kstype, sizeof (kstype));
470 numattr++;
471 if (infile) {
472 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
473 infile, strlen(infile));
474 numattr++;
475 }
476 kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
477 &verify_crl_flag, sizeof (verify_crl_flag));
478 numattr++;
479
480 return (kmf_import_crl(kmfhandle, numattr, attrlist));
481
482 }
483
484 static KMF_RETURN
pk_import_pk12_pk11(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * p12cred,KMF_CREDENTIAL * tokencred,char * label,char * token_spec,char * filename)485 pk_import_pk12_pk11(
486 KMF_HANDLE_T kmfhandle,
487 KMF_CREDENTIAL *p12cred,
488 KMF_CREDENTIAL *tokencred,
489 char *label, char *token_spec,
490 char *filename)
491 {
492 KMF_RETURN rv = KMF_OK;
493 KMF_X509_DER_CERT *certs = NULL;
494 KMF_RAW_KEY_DATA *keys = NULL;
495 int ncerts = 0;
496 int nkeys = 0;
497 int i;
498 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
499 KMF_ATTRIBUTE *attrlist = NULL;
500 int numattr = 0;
501
502 rv = select_token(kmfhandle, token_spec, FALSE);
503
504 if (rv != KMF_OK) {
505 return (rv);
506 }
507
508 rv = kmf_import_objects(kmfhandle, filename, p12cred,
509 &certs, &ncerts, &keys, &nkeys);
510
511 if (rv == KMF_OK) {
512 NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
513
514 kmf_set_attr_at_index(attrlist, numattr,
515 KMF_KEYSTORE_TYPE_ATTR, &kstype,
516 sizeof (kstype));
517 numattr++;
518
519 if (label != NULL) {
520 kmf_set_attr_at_index(attrlist, numattr,
521 KMF_KEYLABEL_ATTR, label,
522 strlen(label));
523 numattr++;
524 }
525
526 if (tokencred != NULL && tokencred->credlen > 0) {
527 kmf_set_attr_at_index(attrlist, numattr,
528 KMF_CREDENTIAL_ATTR, tokencred,
529 sizeof (KMF_CREDENTIAL));
530 numattr++;
531 }
532
533 /* The order of certificates and keys should match */
534 for (i = 0; i < nkeys; i++) {
535 int num = numattr;
536
537 if (i < ncerts) {
538 kmf_set_attr_at_index(attrlist, num,
539 KMF_CERT_DATA_ATTR, &certs[i].certificate,
540 sizeof (KMF_DATA));
541 num++;
542 }
543
544 kmf_set_attr_at_index(attrlist, num,
545 KMF_RAW_KEY_ATTR, &keys[i],
546 sizeof (KMF_RAW_KEY_DATA));
547 num++;
548
549 rv = kmf_store_key(kmfhandle, num, attrlist);
550
551 }
552 free(attrlist);
553 }
554
555 if (rv == KMF_OK) {
556 numattr = 0;
557 NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
558
559 (void) printf(gettext("Found %d certificate(s) and %d "
560 "key(s) in %s\n"), ncerts, nkeys, filename);
561
562 kmf_set_attr_at_index(attrlist, numattr,
563 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
564 numattr++;
565
566 for (i = 0; rv == KMF_OK && i < ncerts; i++) {
567 int num = numattr;
568 if (certs[i].kmf_private.label != NULL) {
569 kmf_set_attr_at_index(attrlist, num,
570 KMF_CERT_LABEL_ATTR,
571 certs[i].kmf_private.label,
572 strlen(certs[i].kmf_private.label));
573 num++;
574 } else if (i == 0 && label != NULL) {
575 kmf_set_attr_at_index(attrlist, num,
576 KMF_CERT_LABEL_ATTR, label, strlen(label));
577 num++;
578 }
579
580 kmf_set_attr_at_index(attrlist, num,
581 KMF_CERT_DATA_ATTR, &certs[i].certificate,
582 sizeof (KMF_DATA));
583 num++;
584
585 rv = kmf_store_cert(kmfhandle, num, attrlist);
586 }
587 free(attrlist);
588 }
589
590 end:
591 /*
592 * Cleanup memory.
593 */
594 if (certs) {
595 for (i = 0; i < ncerts; i++)
596 kmf_free_kmf_cert(kmfhandle, &certs[i]);
597 free(certs);
598 }
599 if (keys) {
600 for (i = 0; i < nkeys; i++)
601 kmf_free_raw_key(&keys[i]);
602 free(keys);
603 }
604
605 return (rv);
606 }
607
608 /*ARGSUSED*/
609 static KMF_RETURN
pk_import_keys(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * token_spec,KMF_CREDENTIAL * cred,char * filename,char * label,char * senstr,char * extstr)610 pk_import_keys(KMF_HANDLE_T kmfhandle,
611 KMF_KEYSTORE_TYPE kstype, char *token_spec,
612 KMF_CREDENTIAL *cred, char *filename,
613 char *label, char *senstr, char *extstr)
614 {
615 KMF_RETURN rv = KMF_OK;
616 KMF_ATTRIBUTE attrlist[16];
617 KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
618 int numattr = 0;
619 KMF_KEY_HANDLE key;
620 KMF_RAW_KEY_DATA rawkey;
621 KMF_KEY_CLASS class = KMF_ASYM_PRI;
622 int numkeys = 1;
623
624 if (kstype == KMF_KEYSTORE_PK11TOKEN) {
625 rv = select_token(kmfhandle, token_spec, FALSE);
626 }
627 if (rv != KMF_OK)
628 return (rv);
629 /*
630 * First, set up to read the keyfile using the FILE plugin
631 * mechanisms.
632 */
633 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
634 &fileks, sizeof (fileks));
635 numattr++;
636
637 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
638 &numkeys, sizeof (numkeys));
639 numattr++;
640
641 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
642 &key, sizeof (key));
643 numattr++;
644
645 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
646 &rawkey, sizeof (rawkey));
647 numattr++;
648
649 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
650 &class, sizeof (class));
651 numattr++;
652
653 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
654 filename, strlen(filename));
655 numattr++;
656
657 rv = kmf_find_key(kmfhandle, numattr, attrlist);
658 if (rv == KMF_OK) {
659 numattr = 0;
660
661 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
662 &kstype, sizeof (kstype));
663 numattr++;
664
665 if (cred != NULL && cred->credlen > 0) {
666 kmf_set_attr_at_index(attrlist, numattr,
667 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
668 numattr++;
669 }
670
671 if (label != NULL) {
672 kmf_set_attr_at_index(attrlist, numattr,
673 KMF_KEYLABEL_ATTR, label, strlen(label));
674 numattr++;
675 }
676
677 kmf_set_attr_at_index(attrlist, numattr,
678 KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
679 numattr++;
680
681 rv = kmf_store_key(kmfhandle, numattr, attrlist);
682 if (rv == KMF_OK) {
683 (void) printf(gettext("Importing %d keys\n"), numkeys);
684 }
685
686 kmf_free_kmf_key(kmfhandle, &key);
687 kmf_free_raw_key(&rawkey);
688 } else {
689 cryptoerror(LOG_STDERR,
690 gettext("Failed to load key from file (%s)\n"),
691 filename);
692 }
693 return (rv);
694 }
695
696 static KMF_RETURN
pk_import_rawkey(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * token,KMF_CREDENTIAL * cred,char * filename,char * label,KMF_KEY_ALG keyAlg,char * senstr,char * extstr)697 pk_import_rawkey(KMF_HANDLE_T kmfhandle,
698 KMF_KEYSTORE_TYPE kstype, char *token,
699 KMF_CREDENTIAL *cred,
700 char *filename, char *label, KMF_KEY_ALG keyAlg,
701 char *senstr, char *extstr)
702 {
703 KMF_RETURN rv = KMF_OK;
704 KMF_ATTRIBUTE attrlist[16];
705 int numattr = 0;
706 uint32_t keylen;
707 boolean_t sensitive = B_FALSE;
708 boolean_t not_extractable = B_FALSE;
709 KMF_DATA keydata = {NULL, 0};
710 KMF_KEY_HANDLE rawkey;
711
712 rv = kmf_read_input_file(kmfhandle, filename, &keydata);
713 if (rv != KMF_OK)
714 return (rv);
715
716 rv = select_token(kmfhandle, token, FALSE);
717
718 if (rv != KMF_OK) {
719 return (rv);
720 }
721 if (senstr != NULL) {
722 if (tolower(senstr[0]) == 'y')
723 sensitive = B_TRUE;
724 else if (tolower(senstr[0]) == 'n')
725 sensitive = B_FALSE;
726 else {
727 cryptoerror(LOG_STDERR,
728 gettext("Incorrect sensitive option value.\n"));
729 return (KMF_ERR_BAD_PARAMETER);
730 }
731 }
732
733 if (extstr != NULL) {
734 if (tolower(extstr[0]) == 'y')
735 not_extractable = B_FALSE;
736 else if (tolower(extstr[0]) == 'n')
737 not_extractable = B_TRUE;
738 else {
739 cryptoerror(LOG_STDERR,
740 gettext("Incorrect extractable option value.\n"));
741 return (KMF_ERR_BAD_PARAMETER);
742 }
743 }
744 kmf_set_attr_at_index(attrlist, numattr,
745 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
746 numattr++;
747
748 kmf_set_attr_at_index(attrlist, numattr,
749 KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
750 numattr++;
751
752 kmf_set_attr_at_index(attrlist, numattr,
753 KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
754 numattr++;
755
756 kmf_set_attr_at_index(attrlist, numattr,
757 KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
758 numattr++;
759
760 /* Key length is given in bits not bytes */
761 keylen = keydata.Length * 8;
762 kmf_set_attr_at_index(attrlist, numattr,
763 KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
764 numattr++;
765
766 kmf_set_attr_at_index(attrlist, numattr,
767 KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
768 numattr++;
769
770 kmf_set_attr_at_index(attrlist, numattr,
771 KMF_NON_EXTRACTABLE_BOOL_ATTR, ¬_extractable,
772 sizeof (not_extractable));
773 numattr++;
774
775 if (label != NULL) {
776 kmf_set_attr_at_index(attrlist, numattr,
777 KMF_KEYLABEL_ATTR, label, strlen(label));
778 numattr++;
779 }
780 if (cred != NULL && cred->credlen > 0) {
781 kmf_set_attr_at_index(attrlist, numattr,
782 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
783 numattr++;
784 }
785 rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
786
787 return (rv);
788 }
789
790 /*
791 * Import objects from into KMF repositories.
792 */
793 int
pk_import(int argc,char * argv[])794 pk_import(int argc, char *argv[])
795 {
796 int opt;
797 extern int optind_av;
798 extern char *optarg_av;
799 char *token_spec = NULL;
800 char *filename = NULL;
801 char *keyfile = NULL;
802 char *certfile = NULL;
803 char *crlfile = NULL;
804 char *label = NULL;
805 char *dir = NULL;
806 char *prefix = NULL;
807 char *trustflags = NULL;
808 char *verify_crl = NULL;
809 char *keytype = "generic";
810 char *senstr = NULL;
811 char *extstr = NULL;
812 boolean_t verify_crl_flag = B_FALSE;
813 int oclass = 0;
814 KMF_KEYSTORE_TYPE kstype = 0;
815 KMF_ENCODE_FORMAT kfmt = 0;
816 KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1;
817 KMF_RETURN rv = KMF_OK;
818 KMF_CREDENTIAL pk12cred = { NULL, 0 };
819 KMF_CREDENTIAL tokencred = { NULL, 0 };
820 KMF_HANDLE_T kmfhandle = NULL;
821 KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET;
822
823 /* Parse command line options. Do NOT i18n/l10n. */
824 while ((opt = getopt_av(argc, argv,
825 "T:(token)i:(infile)"
826 "k:(keystore)y:(objtype)"
827 "d:(dir)p:(prefix)"
828 "n:(certlabel)N:(label)"
829 "K:(outkey)c:(outcert)"
830 "v:(verifycrl)l:(outcrl)"
831 "E:(keytype)s:(sensitive)x:(extractable)"
832 "t:(trust)F:(outformat)")) != EOF) {
833 if (EMPTYSTRING(optarg_av))
834 return (PK_ERR_USAGE);
835 switch (opt) {
836 case 'T': /* token specifier */
837 if (token_spec)
838 return (PK_ERR_USAGE);
839 token_spec = optarg_av;
840 break;
841 case 'c': /* output cert file name */
842 if (certfile)
843 return (PK_ERR_USAGE);
844 certfile = optarg_av;
845 break;
846 case 'l': /* output CRL file name */
847 if (crlfile)
848 return (PK_ERR_USAGE);
849 crlfile = optarg_av;
850 break;
851 case 'K': /* output key file name */
852 if (keyfile)
853 return (PK_ERR_USAGE);
854 keyfile = optarg_av;
855 break;
856 case 'i': /* input file name */
857 if (filename)
858 return (PK_ERR_USAGE);
859 filename = optarg_av;
860 break;
861 case 'k':
862 kstype = KS2Int(optarg_av);
863 if (kstype == 0)
864 return (PK_ERR_USAGE);
865 break;
866 case 'y':
867 oclass = OT2Int(optarg_av);
868 if (oclass == -1)
869 return (PK_ERR_USAGE);
870 break;
871 case 'd':
872 dir = optarg_av;
873 break;
874 case 'p':
875 if (prefix)
876 return (PK_ERR_USAGE);
877 prefix = optarg_av;
878 break;
879 case 'n':
880 case 'N':
881 if (label)
882 return (PK_ERR_USAGE);
883 label = optarg_av;
884 break;
885 case 'F':
886 okfmt = Str2Format(optarg_av);
887 if (okfmt == KMF_FORMAT_UNDEF)
888 return (PK_ERR_USAGE);
889 break;
890 case 't':
891 if (trustflags)
892 return (PK_ERR_USAGE);
893 trustflags = optarg_av;
894 break;
895 case 'v':
896 verify_crl = optarg_av;
897 if (tolower(verify_crl[0]) == 'y')
898 verify_crl_flag = B_TRUE;
899 else if (tolower(verify_crl[0]) == 'n')
900 verify_crl_flag = B_FALSE;
901 else
902 return (PK_ERR_USAGE);
903 break;
904 case 'E':
905 keytype = optarg_av;
906 break;
907 case 's':
908 if (senstr)
909 return (PK_ERR_USAGE);
910 senstr = optarg_av;
911 break;
912 case 'x':
913 if (extstr)
914 return (PK_ERR_USAGE);
915 extstr = optarg_av;
916 break;
917 default:
918 return (PK_ERR_USAGE);
919 break;
920 }
921 }
922
923 /* Assume keystore = PKCS#11 if not specified */
924 if (kstype == 0)
925 kstype = KMF_KEYSTORE_PK11TOKEN;
926
927 /* Filename arg is required. */
928 if (EMPTYSTRING(filename)) {
929 cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
930 "is required for the import operation.\n"));
931 return (PK_ERR_USAGE);
932 }
933
934 /* No additional args allowed. */
935 argc -= optind_av;
936 argv += optind_av;
937 if (argc)
938 return (PK_ERR_USAGE);
939
940 DIR_OPTION_CHECK(kstype, dir);
941
942 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
943 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
944 kstype != KMF_KEYSTORE_PK11TOKEN) {
945
946 (void) fprintf(stderr, gettext("The objtype parameter "
947 "is only relevant if keystore=pkcs11\n"));
948 return (PK_ERR_USAGE);
949 }
950
951 /*
952 * You must specify a certlabel (cert label) when importing
953 * into NSS or PKCS#11.
954 */
955 if (kstype == KMF_KEYSTORE_NSS &&
956 (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
957 cryptoerror(LOG_STDERR, gettext("The 'label' argument "
958 "is required for this operation\n"));
959 return (PK_ERR_USAGE);
960 }
961
962 if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
963 char *kmferrstr = NULL;
964 KMF_RETURN rv2;
965 /*
966 * Allow for raw key data to be imported.
967 */
968 if (rv == KMF_ERR_ENCODING) {
969 rv = KMF_OK;
970 kfmt = KMF_FORMAT_RAWKEY;
971 /*
972 * Set the object class only if it was not
973 * given on the command line or if it was
974 * specified as a symmetric key object.
975 */
976 if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
977 oclass = PK_SYMKEY_OBJ;
978 } else {
979 cryptoerror(LOG_STDERR, gettext(
980 "The input file does not contain the "
981 "object type indicated on command "
982 "line."));
983 return (KMF_ERR_BAD_PARAMETER);
984 }
985 } else {
986 if (rv == KMF_ERR_OPEN_FILE) {
987 cryptoerror(LOG_STDERR,
988 gettext("Cannot open file (%s)\n."),
989 filename);
990 } else {
991 rv2 = kmf_get_kmf_error_str(rv, &kmferrstr);
992 if (rv2 == KMF_OK && kmferrstr) {
993 cryptoerror(LOG_STDERR,
994 gettext("libkmf error: %s"),
995 kmferrstr);
996 kmf_free_str(kmferrstr);
997 }
998 }
999 return (rv);
1000 }
1001 }
1002
1003 /* Check parameters for raw key import operation */
1004 if (kfmt == KMF_FORMAT_RAWKEY) {
1005 if (keytype != NULL &&
1006 Str2SymKeyType(keytype, &keyAlg) != 0) {
1007 cryptoerror(LOG_STDERR,
1008 gettext("Unrecognized keytype(%s).\n"), keytype);
1009 return (PK_ERR_USAGE);
1010 }
1011 if (senstr != NULL && extstr != NULL &&
1012 kstype != KMF_KEYSTORE_PK11TOKEN) {
1013 cryptoerror(LOG_STDERR,
1014 gettext("The sensitive or extractable option "
1015 "applies only when importing a key from a file "
1016 "into a PKCS#11 keystore.\n"));
1017 return (PK_ERR_USAGE);
1018 }
1019 }
1020
1021 /* If no objtype was given, treat it as a certificate */
1022 if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
1023 kfmt == KMF_FORMAT_PEM))
1024 oclass = PK_CERT_OBJ;
1025
1026 if (kstype == KMF_KEYSTORE_NSS) {
1027 if (oclass == PK_CRL_OBJ &&
1028 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
1029 cryptoerror(LOG_STDERR, gettext(
1030 "CRL data can only be imported as DER or "
1031 "PEM format"));
1032 return (PK_ERR_USAGE);
1033 }
1034
1035 if (oclass == PK_CERT_OBJ &&
1036 (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
1037 cryptoerror(LOG_STDERR, gettext(
1038 "Certificates can only be imported as DER or "
1039 "PEM format"));
1040 return (PK_ERR_USAGE);
1041 }
1042
1043 /* we do not import private keys except in PKCS12 bundles */
1044 if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
1045 cryptoerror(LOG_STDERR, gettext(
1046 "Private key data can only be imported as part "
1047 "of a PKCS12 file.\n"));
1048 return (PK_ERR_USAGE);
1049 }
1050 }
1051
1052 if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
1053 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
1054 cryptoerror(LOG_STDERR, gettext(
1055 "The 'outkey' and 'outcert' parameters "
1056 "are required for the import operation "
1057 "when the 'file' keystore is used.\n"));
1058 return (PK_ERR_USAGE);
1059 }
1060 }
1061
1062 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
1063 token_spec = PK_DEFAULT_PK11TOKEN;
1064 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
1065 token_spec = DEFAULT_NSS_TOKEN;
1066
1067 if (kfmt == KMF_FORMAT_PKCS12) {
1068 (void) get_pk12_password(&pk12cred);
1069 }
1070
1071 if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
1072 (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
1073 (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
1074 (void) get_token_password(kstype, token_spec, &tokencred);
1075 }
1076
1077 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
1078 cryptoerror(LOG_STDERR, gettext("Error initializing "
1079 "KMF: 0x%02x\n"), rv);
1080 goto end;
1081 }
1082
1083 switch (kstype) {
1084 case KMF_KEYSTORE_PK11TOKEN:
1085 if (kfmt == KMF_FORMAT_PKCS12)
1086 rv = pk_import_pk12_pk11(
1087 kmfhandle, &pk12cred,
1088 &tokencred, label,
1089 token_spec, filename);
1090 else if (oclass == PK_CERT_OBJ)
1091 rv = pk_import_cert(
1092 kmfhandle, kstype,
1093 label, token_spec,
1094 filename,
1095 NULL, NULL, NULL);
1096 else if (oclass == PK_CRL_OBJ)
1097 rv = pk_import_file_crl(
1098 kmfhandle, filename,
1099 crlfile, okfmt);
1100 else if (kfmt == KMF_FORMAT_RAWKEY &&
1101 oclass == PK_SYMKEY_OBJ) {
1102 rv = pk_import_rawkey(kmfhandle,
1103 kstype, token_spec, &tokencred,
1104 filename, label,
1105 keyAlg, senstr, extstr);
1106 } else if (kfmt == KMF_FORMAT_PEM ||
1107 kfmt == KMF_FORMAT_PEM_KEYPAIR) {
1108 rv = pk_import_keys(kmfhandle,
1109 kstype, token_spec, &tokencred,
1110 filename, label, senstr, extstr);
1111 } else {
1112 rv = PK_ERR_USAGE;
1113 }
1114 break;
1115 case KMF_KEYSTORE_NSS:
1116 if (dir == NULL)
1117 dir = PK_DEFAULT_DIRECTORY;
1118 if (kfmt == KMF_FORMAT_PKCS12)
1119 rv = pk_import_pk12_nss(
1120 kmfhandle, &pk12cred,
1121 &tokencred,
1122 token_spec, dir, prefix,
1123 label, trustflags, filename);
1124 else if (oclass == PK_CERT_OBJ) {
1125 rv = pk_import_cert(
1126 kmfhandle, kstype,
1127 label, token_spec,
1128 filename, dir, prefix, trustflags);
1129 } else if (oclass == PK_CRL_OBJ) {
1130 rv = pk_import_nss_crl(
1131 kmfhandle, verify_crl_flag,
1132 filename, dir, prefix);
1133 }
1134 break;
1135 case KMF_KEYSTORE_OPENSSL:
1136 if (kfmt == KMF_FORMAT_PKCS12)
1137 rv = pk_import_pk12_files(
1138 kmfhandle, &pk12cred,
1139 filename, certfile, keyfile,
1140 okfmt);
1141 else if (oclass == PK_CRL_OBJ) {
1142 rv = pk_import_file_crl(
1143 kmfhandle, filename,
1144 crlfile, okfmt);
1145 } else
1146 /*
1147 * It doesn't make sense to import anything
1148 * else for the files plugin.
1149 */
1150 return (PK_ERR_USAGE);
1151 break;
1152 default:
1153 rv = PK_ERR_USAGE;
1154 break;
1155 }
1156
1157 end:
1158 if (rv != KMF_OK)
1159 display_error(kmfhandle, rv,
1160 gettext("Error importing objects"));
1161
1162 if (tokencred.cred != NULL)
1163 free(tokencred.cred);
1164
1165 if (pk12cred.cred != NULL)
1166 free(pk12cred.cred);
1167
1168 (void) kmf_finalize(kmfhandle);
1169
1170 if (rv != KMF_OK)
1171 return (PK_ERR_USAGE);
1172
1173 return (0);
1174 }
1175