xref: /illumos-gate/usr/src/lib/libkmf/libkmf/common/keyop.c (revision b07ce584f4e28873b8927d7f83d9d3275a0f3ed2)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <stdio.h>
29 #include <link.h>
30 #include <fcntl.h>
31 #include <ctype.h>
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <ber_der.h>
36 #include <kmfapiP.h>
37 #include <libgen.h>
38 #include <cryptoutil.h>
39 
40 KMF_RETURN
41 kmf_create_keypair(KMF_HANDLE_T handle,
42 	int	num_args,
43 	KMF_ATTRIBUTE	*attrlist)
44 {
45 	KMF_RETURN ret = KMF_OK;
46 	KMF_PLUGIN *plugin;
47 	KMF_KEYSTORE_TYPE kstype;
48 	uint32_t len;
49 
50 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
51 		{KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
52 		{KMF_PRIVKEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE),
53 			sizeof (KMF_KEY_HANDLE)},
54 		{KMF_PUBKEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE),
55 			sizeof (KMF_KEY_HANDLE)},
56 	};
57 
58 	int num_req_attrs = sizeof (required_attrs) /
59 	    sizeof (KMF_ATTRIBUTE_TESTER);
60 
61 	if (handle == NULL)
62 		return (KMF_ERR_BAD_PARAMETER);
63 
64 	CLEAR_ERROR(handle, ret);
65 
66 	ret = test_attributes(num_req_attrs, required_attrs,
67 	    0, NULL, num_args, attrlist);
68 
69 	if (ret != KMF_OK)
70 		return (ret);
71 
72 	len = sizeof (kstype);
73 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
74 	    &kstype, &len);
75 	if (ret != KMF_OK)
76 		return (ret);
77 
78 	plugin = FindPlugin(handle, kstype);
79 	if (plugin != NULL && plugin->funclist->CreateKeypair != NULL) {
80 		return (plugin->funclist->CreateKeypair(handle, num_args,
81 		    attrlist));
82 	} else {
83 		return (KMF_ERR_PLUGIN_NOTFOUND);
84 	}
85 }
86 
87 KMF_RETURN
88 kmf_delete_key_from_keystore(KMF_HANDLE_T handle,
89 	int	num_args,
90 	KMF_ATTRIBUTE	*attrlist)
91 {
92 	KMF_RETURN ret = KMF_OK;
93 	KMF_PLUGIN *plugin;
94 	KMF_KEYSTORE_TYPE kstype;
95 	uint32_t len;
96 	KMF_KEY_HANDLE *key;
97 
98 
99 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
100 		{KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
101 		{KMF_KEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE),
102 			sizeof (KMF_KEY_HANDLE)},
103 	};
104 
105 	int num_req_attrs = sizeof (required_attrs) /
106 	    sizeof (KMF_ATTRIBUTE_TESTER);
107 
108 	if (handle == NULL)
109 		return (KMF_ERR_BAD_PARAMETER);
110 
111 	CLEAR_ERROR(handle, ret);
112 
113 	ret = test_attributes(num_req_attrs, required_attrs,
114 	    0, NULL, num_args, attrlist);
115 
116 	if (ret != KMF_OK)
117 		return (ret);
118 
119 	len = sizeof (kstype);
120 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
121 	    &kstype, &len);
122 	if (ret != KMF_OK)
123 		return (ret);
124 
125 	plugin = FindPlugin(handle, kstype);
126 	if (plugin != NULL && plugin->funclist->DeleteKey != NULL) {
127 		ret = plugin->funclist->DeleteKey(handle, num_args, attrlist);
128 	} else {
129 		ret = KMF_ERR_PLUGIN_NOTFOUND;
130 	}
131 
132 	if (ret == KMF_OK) {
133 		key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, num_args);
134 		if (key == NULL)
135 			return (KMF_ERR_BAD_PARAMETER);
136 		if (key->keylabel != NULL)
137 			free(key->keylabel);
138 
139 		if (key->israw && key->keyp != NULL) {
140 			if (key->keyclass ==  KMF_ASYM_PUB ||
141 			    key->keyclass == KMF_ASYM_PRI) {
142 				kmf_free_raw_key(key->keyp);
143 				free(key->keyp);
144 			} else if (key->keyclass == KMF_SYMMETRIC) {
145 				kmf_free_raw_sym_key(key->keyp);
146 			}
147 			/* Else we don't know how to free the memory. */
148 		}
149 
150 		(void) memset(key, 0, sizeof (KMF_KEY_HANDLE));
151 	}
152 
153 	return (ret);
154 }
155 
156 KMF_RETURN
157 kmf_find_key(KMF_HANDLE_T handle,
158 	int	num_args,
159 	KMF_ATTRIBUTE	*attrlist)
160 {
161 	KMF_RETURN ret = KMF_OK;
162 	KMF_PLUGIN *plugin;
163 	KMF_KEYSTORE_TYPE kstype;
164 	uint32_t len;
165 
166 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
167 		{KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
168 		{KMF_COUNT_ATTR, FALSE, sizeof (uint32_t),
169 			sizeof (uint32_t)}
170 	};
171 
172 	int num_req_attrs = sizeof (required_attrs) /
173 	    sizeof (KMF_ATTRIBUTE_TESTER);
174 
175 	if (handle == NULL)
176 		return (KMF_ERR_BAD_PARAMETER);
177 
178 	CLEAR_ERROR(handle, ret);
179 
180 	ret = test_attributes(num_req_attrs, required_attrs,
181 	    0, NULL, num_args, attrlist);
182 
183 	if (ret != KMF_OK)
184 		return (ret);
185 
186 	len = sizeof (kstype);
187 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
188 	    &kstype, &len);
189 	if (ret != KMF_OK)
190 		return (ret);
191 
192 	plugin = FindPlugin(handle, kstype);
193 	if (plugin != NULL && plugin->funclist->FindKey != NULL) {
194 		return (plugin->funclist->FindKey(handle, num_args, attrlist));
195 	}
196 
197 	return (KMF_ERR_PLUGIN_NOTFOUND);
198 }
199 
200 KMF_RETURN
201 kmf_create_sym_key(KMF_HANDLE_T handle,
202 	int	num_args,
203 	KMF_ATTRIBUTE	*attrlist)
204 {
205 	KMF_RETURN ret = KMF_OK;
206 	KMF_PLUGIN *plugin;
207 	KMF_KEYSTORE_TYPE kstype;
208 	uint32_t len;
209 
210 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
211 		{KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
212 		{KMF_KEY_HANDLE_ATTR, FALSE, sizeof (KMF_KEY_HANDLE),
213 			sizeof (KMF_KEY_HANDLE)},
214 		{KMF_KEYALG_ATTR, FALSE, 1, sizeof (KMF_KEY_ALG)},
215 	};
216 
217 	int num_req_attrs = sizeof (required_attrs) /
218 	    sizeof (KMF_ATTRIBUTE_TESTER);
219 
220 	if (handle == NULL)
221 		return (KMF_ERR_BAD_PARAMETER);
222 
223 	CLEAR_ERROR(handle, ret);
224 
225 	ret = test_attributes(num_req_attrs, required_attrs,
226 	    0, NULL, num_args, attrlist);
227 
228 	if (ret != KMF_OK)
229 		return (ret);
230 
231 	len = sizeof (kstype);
232 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
233 	    &kstype, &len);
234 	if (ret != KMF_OK)
235 		return (ret);
236 
237 	plugin = FindPlugin(handle, kstype);
238 	if (plugin != NULL && plugin->funclist->CreateSymKey != NULL) {
239 		return (plugin->funclist->CreateSymKey(handle, num_args,
240 		    attrlist));
241 	} else {
242 		return (KMF_ERR_PLUGIN_NOTFOUND);
243 	}
244 }
245 
246 KMF_RETURN
247 kmf_get_sym_key_value(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
248 	KMF_RAW_SYM_KEY *rkey)
249 {
250 	KMF_PLUGIN *plugin;
251 	KMF_RETURN ret;
252 
253 	CLEAR_ERROR(handle, ret);
254 	if (ret != KMF_OK)
255 		return (ret);
256 
257 	if (symkey == NULL || rkey == NULL)
258 		return (KMF_ERR_BAD_PARAMETER);
259 
260 	plugin = FindPlugin(handle, symkey->kstype);
261 	if (plugin != NULL &&
262 	    plugin->funclist->GetSymKeyValue != NULL) {
263 		return (plugin->funclist->GetSymKeyValue(handle,
264 		    symkey, rkey));
265 	} else {
266 		return (KMF_ERR_PLUGIN_NOTFOUND);
267 	}
268 }
269 
270 KMF_RETURN
271 kmf_store_key(KMF_HANDLE_T handle,
272 	int	numattr,
273 	KMF_ATTRIBUTE	*attrlist)
274 {
275 	KMF_RETURN ret = KMF_OK;
276 	KMF_PLUGIN *plugin;
277 	KMF_KEYSTORE_TYPE kstype;
278 
279 	KMF_ATTRIBUTE_TESTER required_attrs[] = {
280 		{KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
281 	};
282 
283 	int num_req_attrs = sizeof (required_attrs) /
284 	    sizeof (KMF_ATTRIBUTE_TESTER);
285 
286 	if (handle == NULL)
287 		return (KMF_ERR_BAD_PARAMETER);
288 
289 	CLEAR_ERROR(handle, ret);
290 
291 	ret = test_attributes(num_req_attrs, required_attrs,
292 	    0, NULL, numattr, attrlist);
293 
294 	if (ret != KMF_OK)
295 		return (ret);
296 
297 	ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
298 	    &kstype, NULL);
299 	if (ret != KMF_OK)
300 		return (ret);
301 
302 	plugin = FindPlugin(handle, kstype);
303 	if (plugin != NULL) {
304 		if (plugin->funclist->StoreKey != NULL)
305 			return (plugin->funclist->StoreKey(handle,
306 			    numattr, attrlist));
307 		else
308 			return (KMF_ERR_FUNCTION_NOT_FOUND);
309 	}
310 	return (KMF_ERR_PLUGIN_NOTFOUND);
311 }
312 
313 /*
314  * The following are Phase 1 APIs still needed to maintain compat with elfsign.
315  */
316 
317 /*
318  * Name: KMF_SignDataWithKey
319  *
320  * Description:
321  *   This function signs a block of data using the private key
322  * and returns the signature in output
323  *
324  * Parameters:
325  *   handle(input) - opaque handle for KMF session
326  *   key(input) - contains private key handle needed for signing
327  *   AlgOID(input) - contains algorithm to be used for signing
328  *   tobesigned(input) - pointer to a KMF_DATA structure containing
329  *		the data to be signed
330  *   output(output) - pointer to the KMF_DATA structure containing the
331  *		signed data
332  *
333  * Returns:
334  *   A KMF_RETURN value indicating success or specifying a particular
335  * error condition.
336  *   The value KMF_OK indicates success. All other values represent
337  * an error condition.
338  *
339  */
340 KMF_RETURN
341 KMF_SignDataWithKey(KMF_HANDLE_T handle,
342 	KMF_KEY_HANDLE *key,
343 	KMF_OID *AlgOID,
344 	KMF_DATA *tobesigned,
345 	KMF_DATA *output)
346 {
347 	KMF_ATTRIBUTE attlist[5]; /* only 5 attrs for SignData */
348 	int i = 0;
349 
350 	if (key == NULL || AlgOID == NULL ||
351 	    tobesigned == NULL || output == NULL)
352 		return (KMF_ERR_BAD_PARAMETER);
353 
354 	kmf_set_attr_at_index(attlist, i,
355 	    KMF_KEYSTORE_TYPE_ATTR, &key->kstype, sizeof (key->kstype));
356 	i++;
357 
358 	kmf_set_attr_at_index(attlist, i,
359 	    KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
360 	i++;
361 
362 	kmf_set_attr_at_index(attlist, i,
363 	    KMF_OID_ATTR, AlgOID, sizeof (KMF_OID));
364 	i++;
365 
366 	kmf_set_attr_at_index(attlist, i,
367 	    KMF_DATA_ATTR, tobesigned, sizeof (KMF_DATA));
368 	i++;
369 
370 	kmf_set_attr_at_index(attlist, i,
371 	    KMF_OUT_DATA_ATTR, output, sizeof (KMF_DATA));
372 	i++;
373 
374 	return (kmf_sign_data(handle, i, attlist));
375 }
376 
377 
378 KMF_RETURN
379 KMF_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params,
380 	KMF_KEY_HANDLE *keys, uint32_t *numkeys)
381 {
382 	KMF_ATTRIBUTE attlist[16]; /* Max 16 attributes used here */
383 	int i = 0;
384 
385 	if (params == NULL || numkeys == NULL)
386 		return (KMF_ERR_BAD_PARAMETER);
387 
388 	kmf_set_attr_at_index(attlist, i,
389 	    KMF_KEYSTORE_TYPE_ATTR, &params->kstype, sizeof (params->kstype));
390 	i++;
391 
392 	if (keys) {
393 		kmf_set_attr_at_index(attlist, i,
394 		    KMF_KEY_HANDLE_ATTR, keys, sizeof (KMF_KEY_HANDLE));
395 		i++;
396 	}
397 
398 	kmf_set_attr_at_index(attlist, i,
399 	    KMF_COUNT_ATTR, numkeys, sizeof (uint32_t));
400 	i++;
401 
402 	kmf_set_attr_at_index(attlist, i,
403 	    KMF_KEYALG_ATTR, &params->keytype, sizeof (params->keytype));
404 	i++;
405 
406 	kmf_set_attr_at_index(attlist, i,
407 	    KMF_KEYCLASS_ATTR, &params->keyclass, sizeof (params->keyclass));
408 	i++;
409 
410 	kmf_set_attr_at_index(attlist, i,
411 	    KMF_ENCODE_FORMAT_ATTR, &params->format, sizeof (params->format));
412 	i++;
413 
414 	if (params->findLabel != NULL) {
415 		kmf_set_attr_at_index(attlist, i,
416 		    KMF_KEYLABEL_ATTR, params->findLabel,
417 		    strlen(params->findLabel));
418 		i++;
419 	}
420 
421 	if (params->idstr != NULL) {
422 		kmf_set_attr_at_index(attlist, i,
423 		    KMF_IDSTR_ATTR, params->idstr,
424 		    strlen(params->idstr));
425 		i++;
426 	}
427 
428 	if (params->cred.credlen > 0) {
429 		kmf_set_attr_at_index(attlist, i,
430 		    KMF_CREDENTIAL_ATTR, &params->cred,
431 		    sizeof (KMF_CREDENTIAL));
432 		i++;
433 	}
434 
435 	if (params->kstype == KMF_KEYSTORE_NSS) {
436 		if (params->nssparms.slotlabel != NULL) {
437 			kmf_set_attr_at_index(attlist, i,
438 			    KMF_TOKEN_LABEL_ATTR,
439 			    params->nssparms.slotlabel,
440 			    strlen(params->nssparms.slotlabel));
441 			i++;
442 		}
443 	} else if (params->kstype == KMF_KEYSTORE_OPENSSL) {
444 		if (params->sslparms.dirpath != NULL) {
445 			kmf_set_attr_at_index(attlist, i,
446 			    KMF_DIRPATH_ATTR,
447 			    params->sslparms.dirpath,
448 			    strlen(params->sslparms.dirpath));
449 			i++;
450 		}
451 		if (params->sslparms.keyfile != NULL) {
452 			kmf_set_attr_at_index(attlist, i,
453 			    KMF_KEY_FILENAME_ATTR,
454 			    params->sslparms.keyfile,
455 			    strlen(params->sslparms.keyfile));
456 			i++;
457 		}
458 		kmf_set_attr_at_index(attlist, i,
459 		    KMF_ENCODE_FORMAT_ATTR,
460 		    &params->sslparms.format,
461 		    sizeof (params->sslparms.format));
462 		i++;
463 	} else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) {
464 		kmf_set_attr_at_index(attlist, i,
465 		    KMF_TOKEN_BOOL_ATTR,
466 		    &params->pkcs11parms.token,
467 		    sizeof (params->pkcs11parms.token));
468 		i++;
469 		kmf_set_attr_at_index(attlist, i,
470 		    KMF_PRIVATE_BOOL_ATTR,
471 		    &params->pkcs11parms.private,
472 		    sizeof (params->pkcs11parms.private));
473 		i++;
474 	}
475 	return (kmf_find_key(handle, i, attlist));
476 }
477 
478 KMF_RETURN
479 KMF_CreateKeypair(KMF_HANDLE_T handle,
480 	KMF_CREATEKEYPAIR_PARAMS *params,
481 	KMF_KEY_HANDLE *privKey,
482 	KMF_KEY_HANDLE *pubKey)
483 {
484 	KMF_ATTRIBUTE attlist[12]; /* max 12 attrs used here */
485 	int i = 0;
486 
487 	if (handle == NULL || params == NULL ||
488 	    privKey == NULL || pubKey == NULL)
489 		return (KMF_ERR_BAD_PARAMETER);
490 
491 	(void) memset(privKey, 0, sizeof (KMF_KEY_HANDLE));
492 	(void) memset(pubKey, 0, sizeof (KMF_KEY_HANDLE));
493 
494 	kmf_set_attr_at_index(attlist, i,
495 	    KMF_KEYSTORE_TYPE_ATTR, &params->kstype, sizeof (params->kstype));
496 	i++;
497 	kmf_set_attr_at_index(attlist, i,
498 	    KMF_KEYALG_ATTR, &params->keytype, sizeof (params->keytype));
499 	i++;
500 	kmf_set_attr_at_index(attlist, i,
501 	    KMF_KEYLENGTH_ATTR, &params->keylength, sizeof (params->keylength));
502 	i++;
503 	if (params->keylabel != NULL) {
504 		kmf_set_attr_at_index(attlist, i,
505 		    KMF_KEYLABEL_ATTR, params->keylabel,
506 		    strlen(params->keylabel));
507 		i++;
508 	}
509 	if (params->cred.credlen > 0) {
510 		kmf_set_attr_at_index(attlist, i,
511 		    KMF_CREDENTIAL_ATTR, &params->cred,
512 		    sizeof (KMF_CREDENTIAL));
513 		i++;
514 	}
515 
516 	if (params->rsa_exponent.len > 0) {
517 		kmf_set_attr_at_index(attlist, i,
518 		    KMF_RSAEXP_ATTR, &params->cred,
519 		    sizeof (KMF_BIGINT));
520 		i++;
521 	}
522 	kmf_set_attr_at_index(attlist, i, KMF_PRIVKEY_HANDLE_ATTR, privKey,
523 	    sizeof (KMF_KEY_HANDLE));
524 	i++;
525 	kmf_set_attr_at_index(attlist, i, KMF_PUBKEY_HANDLE_ATTR, pubKey,
526 	    sizeof (KMF_KEY_HANDLE));
527 	i++;
528 
529 	if (params->kstype == KMF_KEYSTORE_NSS) {
530 		if (params->nssparms.slotlabel != NULL) {
531 			kmf_set_attr_at_index(attlist, i,
532 			    KMF_TOKEN_LABEL_ATTR,
533 			    params->nssparms.slotlabel,
534 			    strlen(params->nssparms.slotlabel));
535 			i++;
536 		}
537 	} else if (params->kstype == KMF_KEYSTORE_OPENSSL) {
538 		if (params->sslparms.dirpath != NULL) {
539 			kmf_set_attr_at_index(attlist, i,
540 			    KMF_DIRPATH_ATTR,
541 			    params->sslparms.dirpath,
542 			    strlen(params->sslparms.dirpath));
543 			i++;
544 		}
545 		if (params->sslparms.keyfile != NULL) {
546 			kmf_set_attr_at_index(attlist, i,
547 			    KMF_KEY_FILENAME_ATTR,
548 			    params->sslparms.keyfile,
549 			    strlen(params->sslparms.keyfile));
550 			i++;
551 		}
552 		kmf_set_attr_at_index(attlist, i,
553 		    KMF_ENCODE_FORMAT_ATTR,
554 		    &params->sslparms.format,
555 		    sizeof (params->sslparms.format));
556 		i++;
557 	}
558 	return (kmf_create_keypair(handle, i, attlist));
559 }
560