xref: /titanic_44/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c (revision b0fe7b8fa79924061f3bdf7f240ea116c2c0b704)
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  */
41 int
42 PKCS12_get_rsa_key_certs(const char *filename, const char *password_file,
43     KMF_RAW_KEY_DATA **rsa, KMF_DATA **certs)
44 {
45 	char password_buf[1024];
46 	KMF_HANDLE_T kmfh;
47 	KMF_RETURN rv = KMF_OK;
48 	KMF_CREDENTIAL pk12cred;
49 	KMF_DATA *tcerts;
50 	KMF_RAW_KEY_DATA *keys;
51 	int ncerts, nkeys;
52 	char *err = NULL;
53 
54 	rv = KMF_Initialize(&kmfh, NULL, NULL);
55 	if (rv != KMF_OK) {
56 		REPORT_KMF_ERROR(rv, "Error initializing KMF", err);
57 		return (0);
58 	}
59 
60 	tcerts = NULL;
61 	keys = NULL;
62 	ncerts = 0;
63 	nkeys = 0;
64 
65 	if (get_passphrase(password_file, password_buf,
66 		sizeof (password_buf)) <= 0) {
67 		perror("Unable to read passphrase");
68 		goto done;
69 	}
70 	pk12cred.cred = password_buf;
71 	pk12cred.credlen = strlen(password_buf);
72 
73 	rv = KMF_ImportPK12(kmfh, (char *)filename, &pk12cred, &tcerts, &ncerts,
74 		&keys, &nkeys);
75 	if (rv != KMF_OK) {
76 		REPORT_KMF_ERROR(rv, "Error importing PKCS12 data", err);
77 	}
78 
79 done:
80 	if (rv != KMF_OK) {
81 		int i;
82 		if (tcerts != NULL) {
83 			for (i = 0; i < ncerts; i++)
84 				KMF_FreeData(&tcerts[i]);
85 			free(tcerts);
86 		}
87 		tcerts = NULL;
88 		ncerts = 0;
89 		if (keys != NULL) {
90 			for (i = 0; i < nkeys; i++)
91 				KMF_FreeRawKey(&keys[i]);
92 			free(keys);
93 		}
94 		keys = NULL;
95 	}
96 	*certs = tcerts;
97 	*rsa = keys;
98 
99 	(void) KMF_Finalize(kmfh);
100 
101 	return (ncerts);
102 }
103 
104 /*
105  * Parse a PEM file which should contain RSA private keys and
106  * their associated X.509v3 certificates.  More than 1 may
107  * be present in the file.
108  */
109 int
110 PEM_get_rsa_key_certs(const char *filename, char *password_file,
111     KMF_RAW_KEY_DATA **rsa, KMF_DATA **certs)
112 {
113 	KMF_HANDLE_T kmfh;
114 	KMF_RETURN rv = KMF_OK;
115 	KMF_CREDENTIAL creds;
116 	KMF_DATA *tcerts;
117 	KMF_RAW_KEY_DATA *keys;
118 	int ncerts, nkeys;
119 	char *err = NULL;
120 	char password_buf[1024];
121 
122 	rv = KMF_Initialize(&kmfh, NULL, NULL);
123 	if (rv != KMF_OK) {
124 		REPORT_KMF_ERROR(rv, "Error initializing KMF", err);
125 		return (0);
126 	}
127 
128 	tcerts = NULL;
129 	keys = NULL;
130 	ncerts = 0;
131 	nkeys = 0;
132 
133 	if (get_passphrase(password_file, password_buf,
134 		sizeof (password_buf)) <= 0) {
135 		perror("Unable to read passphrase");
136 		goto done;
137 	}
138 	creds.cred = password_buf;
139 	creds.credlen = strlen(password_buf);
140 
141 	rv = KMF_ImportKeypair(kmfh, (char *)filename, &creds, &tcerts, &ncerts,
142 		&keys, &nkeys);
143 	if (rv != KMF_OK) {
144 		REPORT_KMF_ERROR(rv, "Error importing key data", err);
145 	}
146 
147 done:
148 	if (rv != KMF_OK) {
149 		int i;
150 		if (tcerts != NULL) {
151 			for (i = 0; i < ncerts; i++)
152 				KMF_FreeData(&tcerts[i]);
153 			free(tcerts);
154 		}
155 		tcerts = NULL;
156 		ncerts = 0;
157 		if (keys != NULL) {
158 			for (i = 0; i < nkeys; i++)
159 				KMF_FreeRawKey(&keys[i]);
160 			free(keys);
161 		}
162 		keys = NULL;
163 	}
164 	if (certs != NULL)
165 		*certs = tcerts;
166 	if (rsa != NULL)
167 		*rsa = keys;
168 
169 	(void) KMF_Finalize(kmfh);
170 
171 	return (ncerts);
172 }
173