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/*
23 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <stdio.h>
30#include <assert.h>
31#include <strings.h>
32
33#include <kmfapi.h>
34#include "kssladm.h"
35
36/*
37 * Extract the Certificate and raw key data from a PKCS#12 file.
38 * The password needed for decrypting the PKCS#12 PDU is stored
39 * in plaintext in the given "password_file" parameter.
40 */
41int
42PKCS12_get_rsa_key_certs(KMF_HANDLE_T kmfh,
43    const char *filename, const char *password_file,
44    KMF_RAW_KEY_DATA **rsa, KMF_X509_DER_CERT **certs)
45{
46	char password_buf[1024];
47	KMF_RETURN rv = KMF_OK;
48	KMF_CREDENTIAL pk12cred;
49	KMF_X509_DER_CERT *tcerts;
50	KMF_RAW_KEY_DATA *keys;
51	int ncerts, nkeys;
52	char *err = NULL;
53
54	tcerts = NULL;
55	keys = NULL;
56	ncerts = 0;
57	nkeys = 0;
58
59	if (get_passphrase(password_file, password_buf,
60	    sizeof (password_buf)) <= 0) {
61		perror("Unable to read passphrase");
62		goto done;
63	}
64	pk12cred.cred = password_buf;
65	pk12cred.credlen = strlen(password_buf);
66
67	rv = kmf_import_objects(kmfh, (char *)filename, &pk12cred, &tcerts,
68	    &ncerts, &keys, &nkeys);
69	if (rv != KMF_OK) {
70		REPORT_KMF_ERROR(rv, "Error importing PKCS12 data", err);
71	}
72
73done:
74	if (rv != KMF_OK) {
75		int i;
76		if (tcerts != NULL) {
77			for (i = 0; i < ncerts; i++)
78				kmf_free_kmf_cert(kmfh, &tcerts[i]);
79			free(tcerts);
80		}
81		tcerts = NULL;
82		ncerts = 0;
83		if (keys != NULL) {
84			for (i = 0; i < nkeys; i++)
85				kmf_free_raw_key(&keys[i]);
86			free(keys);
87		}
88		keys = NULL;
89	}
90	*certs = tcerts;
91	*rsa = keys;
92
93	return (ncerts);
94}
95
96/*
97 * Parse a PEM file which should contain RSA private keys and
98 * their associated X.509v3 certificates.  More than 1 may
99 * be present in the file.
100 */
101int
102PEM_get_rsa_key_certs(KMF_HANDLE_T kmfh,
103    const char *filename, char *password_file,
104    KMF_RAW_KEY_DATA **rsa, KMF_X509_DER_CERT **certs)
105{
106	KMF_RETURN rv = KMF_OK;
107	KMF_CREDENTIAL creds;
108	KMF_X509_DER_CERT *tcerts;
109	KMF_RAW_KEY_DATA *keys;
110	int ncerts, nkeys;
111	char *err = NULL;
112	char password_buf[1024];
113
114	tcerts = NULL;
115	keys = NULL;
116	ncerts = 0;
117	nkeys = 0;
118
119	if (get_passphrase(password_file, password_buf,
120	    sizeof (password_buf)) <= 0) {
121		perror("Unable to read passphrase");
122		goto done;
123	}
124	creds.cred = password_buf;
125	creds.credlen = strlen(password_buf);
126
127	rv = kmf_import_objects(kmfh, (char *)filename, &creds, &tcerts,
128	    &ncerts, &keys, &nkeys);
129	if (rv != KMF_OK) {
130		REPORT_KMF_ERROR(rv, "Error importing key data", err);
131	}
132
133done:
134	if (rv != KMF_OK) {
135		int i;
136		if (tcerts != NULL) {
137			for (i = 0; i < ncerts; i++)
138				kmf_free_kmf_cert(kmfh, &tcerts[i]);
139			free(tcerts);
140		}
141		tcerts = NULL;
142		ncerts = 0;
143		if (keys != NULL) {
144			for (i = 0; i < nkeys; i++)
145				kmf_free_raw_key(&keys[i]);
146			free(keys);
147		}
148		keys = NULL;
149	}
150	if (certs != NULL)
151		*certs = tcerts;
152	if (rsa != NULL)
153		*rsa = keys;
154
155	return (ncerts);
156}
157