xref: /titanic_44/usr/src/lib/libkmf/libkmf/common/generalop.c (revision 4b22b9337f359bfd063322244f5336cc7c6ffcfa)
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 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <dlfcn.h>
31 #include <link.h>
32 #include <fcntl.h>
33 #include <ctype.h>
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #include <thread.h>
42 
43 #include <ber_der.h>
44 #include <kmfapiP.h>
45 
46 #include <pem_encode.h>
47 #include <rdn_parser.h>
48 #include <libxml2/libxml/uri.h>
49 #include <libgen.h>
50 #include <cryptoutil.h>
51 
52 static uchar_t pkcs11_initialized = 0;
53 mutex_t init_lock = DEFAULTMUTEX;
54 extern int errno;
55 
56 typedef struct {
57 	KMF_RETURN code;
58 	char	*message;
59 } kmf_error_map;
60 
61 static kmf_error_map kmf_errcodes[] = {
62 	{KMF_OK,	"KMF_OK"},
63 	{KMF_ERR_BAD_PARAMETER,	"KMF_ERR_BAD_PARAMETER"},
64 	{KMF_ERR_BAD_KEY_FORMAT,	"KMF_ERR_BAD_KEY_FORMAT"},
65 	{KMF_ERR_BAD_ALGORITHM,	"KMF_ERR_BAD_ALGORITHM"},
66 	{KMF_ERR_MEMORY,	"KMF_ERR_MEMORY"},
67 	{KMF_ERR_ENCODING,	"KMF_ERR_ENCODING"},
68 	{KMF_ERR_PLUGIN_INIT,	"KMF_ERR_PLUGIN_INIT"},
69 	{KMF_ERR_PLUGIN_NOTFOUND,	"KMF_ERR_PLUGIN_NOTFOUND"},
70 	{KMF_ERR_INTERNAL,	"KMF_ERR_INTERNAL"},
71 	{KMF_ERR_BAD_CERT_FORMAT,	"KMF_ERR_BAD_CERT_FORMAT"},
72 	{KMF_ERR_KEYGEN_FAILED,	"KMF_ERR_KEYGEN_FAILED"},
73 	{KMF_ERR_UNINITIALIZED,	"KMF_ERR_UNINITIALIZED"},
74 	{KMF_ERR_ISSUER,	"KMF_ERR_ISSUER"},
75 	{KMF_ERR_NOT_REVOKED,	"KMF_ERR_NOT_REVOKED"},
76 	{KMF_ERR_CERT_NOT_FOUND,	"KMF_ERR_CERT_NOT_FOUND"},
77 	{KMF_ERR_CRL_NOT_FOUND,	"KMF_ERR_CRL_NOT_FOUND"},
78 	{KMF_ERR_RDN_PARSER,	"KMF_ERR_RDN_PARSER"},
79 	{KMF_ERR_RDN_ATTR,	"KMF_ERR_RDN_ATTR"},
80 	{KMF_ERR_SLOTNAME,	"KMF_ERR_SLOTNAME"},
81 	{KMF_ERR_EMPTY_CRL,	"KMF_ERR_EMPTY_CRL"},
82 	{KMF_ERR_BUFFER_SIZE,	"KMF_ERR_BUFFER_SIZE"},
83 	{KMF_ERR_AUTH_FAILED,	"KMF_ERR_AUTH_FAILED"},
84 	{KMF_ERR_TOKEN_SELECTED,	"KMF_ERR_TOKEN_SELECTED"},
85 	{KMF_ERR_NO_TOKEN_SELECTED,	"KMF_ERR_NO_TOKEN_SELECTED"},
86 	{KMF_ERR_TOKEN_NOT_PRESENT,	"KMF_ERR_TOKEN_NOT_PRESENT"},
87 	{KMF_ERR_EXTENSION_NOT_FOUND,	"KMF_ERR_EXTENSION_NOT_FOUND"},
88 	{KMF_ERR_POLICY_ENGINE,	"KMF_ERR_POLICY_ENGINE"},
89 	{KMF_ERR_POLICY_DB_FORMAT,	"KMF_ERR_POLICY_DB_FORMAT"},
90 	{KMF_ERR_POLICY_NOT_FOUND,	"KMF_ERR_POLICY_NOT_FOUND"},
91 	{KMF_ERR_POLICY_DB_FILE,	"KMF_ERR_POLICY_DB_FILE"},
92 	{KMF_ERR_POLICY_NAME,	"KMF_ERR_POLICY_NAME"},
93 	{KMF_ERR_OCSP_POLICY,	"KMF_ERR_OCSP_POLICY"},
94 	{KMF_ERR_TA_POLICY,	"KMF_ERR_TA_POLICY"},
95 	{KMF_ERR_KEY_NOT_FOUND,	"KMF_ERR_KEY_NOT_FOUND"},
96 	{KMF_ERR_OPEN_FILE,	"KMF_ERR_OPEN_FILE"},
97 	{KMF_ERR_OCSP_BAD_ISSUER,	"KMF_ERR_OCSP_BAD_ISSUER"},
98 	{KMF_ERR_OCSP_BAD_CERT,	"KMF_ERR_OCSP_BAD_CERT"},
99 	{KMF_ERR_OCSP_CREATE_REQUEST,	"KMF_ERR_OCSP_CREATE_REQUEST"},
100 	{KMF_ERR_CONNECT_SERVER,	"KMF_ERR_CONNECT_SERVER"},
101 	{KMF_ERR_SEND_REQUEST,	"KMF_ERR_SEND_REQUEST"},
102 	{KMF_ERR_OCSP_CERTID,	"KMF_ERR_OCSP_CERTID"},
103 	{KMF_ERR_OCSP_MALFORMED_RESPONSE, "KMF_ERR_OCSP_MALFORMED_RESPONSE"},
104 	{KMF_ERR_OCSP_RESPONSE_STATUS,	"KMF_ERR_OCSP_RESPONSE_STATUS"},
105 	{KMF_ERR_OCSP_NO_BASIC_RESPONSE, "KMF_ERR_OCSP_NO_BASIC_RESPONSE"},
106 	{KMF_ERR_OCSP_BAD_SIGNER,	"KMF_ERR_OCSP_BAD_SIGNER"},
107 	{KMF_ERR_OCSP_RESPONSE_SIGNATURE, "KMF_ERR_OCSP_RESPONSE_SIGNATURE"},
108 	{KMF_ERR_OCSP_UNKNOWN_CERT,	"KMF_ERR_OCSP_UNKNOWN_CERT"},
109 	{KMF_ERR_OCSP_STATUS_TIME_INVALID, "KMF_ERR_OCSP_STATUS_TIME_INVALID"},
110 	{KMF_ERR_BAD_HTTP_RESPONSE,	"KMF_ERR_BAD_HTTP_RESPONSE"},
111 	{KMF_ERR_RECV_RESPONSE,	"KMF_ERR_RECV_RESPONSE"},
112 	{KMF_ERR_RECV_TIMEOUT,	"KMF_ERR_RECV_TIMEOUT"},
113 	{KMF_ERR_DUPLICATE_KEYFILE,	"KMF_ERR_DUPLICATE_KEYFILE"},
114 	{KMF_ERR_AMBIGUOUS_PATHNAME,	"KMF_ERR_AMBIGUOUS_PATHNAME"},
115 	{KMF_ERR_FUNCTION_NOT_FOUND,	"KMF_ERR_FUNCTION_NOT_FOUND"},
116 	{KMF_ERR_PKCS12_FORMAT,	"KMF_ERR_PKCS12_FORMAT"},
117 	{KMF_ERR_BAD_KEY_TYPE,	"KMF_ERR_BAD_KEY_TYPE"},
118 	{KMF_ERR_BAD_KEY_CLASS,	"KMF_ERR_BAD_KEY_CLASS"},
119 	{KMF_ERR_BAD_KEY_SIZE,	"KMF_ERR_BAD_KEY_SIZE"},
120 	{KMF_ERR_BAD_HEX_STRING,	"KMF_ERR_BAD_HEX_STRING"},
121 	{KMF_ERR_KEYUSAGE,	"KMF_ERR_KEYUSAGE"},
122 	{KMF_ERR_VALIDITY_PERIOD,	"KMF_ERR_VALIDITY_PERIOD"},
123 	{KMF_ERR_OCSP_REVOKED,	"KMF_ERR_OCSP_REVOKED"},
124 	{KMF_ERR_CERT_MULTIPLE_FOUND,	"KMF_ERR_CERT_MULTIPLE_FOUND"},
125 	{KMF_ERR_WRITE_FILE,	"KMF_ERR_WRITE_FILE"},
126 	{KMF_ERR_BAD_URI,	"KMF_ERR_BAD_URI"},
127 	{KMF_ERR_BAD_CRLFILE,	"KMF_ERR_BAD_CRLFILE"},
128 	{KMF_ERR_BAD_CERTFILE,	"KMF_ERR_BAD_CERTFILE"},
129 	{KMF_ERR_GETKEYVALUE_FAILED,	"KMF_ERR_GETKEYVALUE_FAILED"},
130 	{KMF_ERR_BAD_KEYHANDLE,	"KMF_ERR_BAD_KEYHANDLE"},
131 	{KMF_ERR_BAD_OBJECT_TYPE,	"KMF_ERR_BAD_OBJECT_TYPE"},
132 	{KMF_ERR_OCSP_RESPONSE_LIFETIME, "KMF_ERR_OCSP_RESPONSE_LIFETIME"},
133 	{KMF_ERR_UNKNOWN_CSR_ATTRIBUTE,	"KMF_ERR_UNKNOWN_CSR_ATTRIBUTE"},
134 	{KMF_ERR_UNINITIALIZED_TOKEN,	"KMF_ERR_UNINITIALIZED_TOKEN"},
135 	{KMF_ERR_INCOMPLETE_TBS_CERT,	"KMF_ERR_INCOMPLETE_TBS_CERT"},
136 	{KMF_ERR_MISSING_ERRCODE,	"KMF_ERR_MISSING_ERRCODE"},
137 	{KMF_KEYSTORE_ALREADY_INITIALIZED, "KMF_KEYSTORE_ALREADY_INITIALIZED"},
138 	{KMF_ERR_SENSITIVE_KEY,		"KMF_ERR_SENSITIVE_KEY"},
139 	{KMF_ERR_UNEXTRACTABLE_KEY,	"KMF_ERR_UNEXTRACTABLE_KEY"},
140 	{KMF_ERR_KEY_MISMATCH,		"KMF_ERR_KEY_MISMATCH"}
141 };
142 
143 typedef struct {
144 	KMF_KEYSTORE_TYPE	kstype;
145 	char			*path;
146 	boolean_t		critical;
147 } KMF_PLUGIN_ITEM;
148 
149 KMF_PLUGIN_ITEM plugin_list[] = {
150 	{KMF_KEYSTORE_OPENSSL,	KMF_PLUGIN_PATH "kmf_openssl.so.1",  TRUE},
151 	{KMF_KEYSTORE_PK11TOKEN, KMF_PLUGIN_PATH "kmf_pkcs11.so.1",  TRUE},
152 	{KMF_KEYSTORE_NSS,	KMF_PLUGIN_PATH "kmf_nss.so.1",  FALSE}
153 };
154 
155 static void free_extensions(KMF_X509_EXTENSIONS *extns);
156 
157 KMF_RETURN
158 init_pk11()
159 {
160 	(void) mutex_lock(&init_lock);
161 	if (!pkcs11_initialized) {
162 		CK_RV rv = C_Initialize(NULL);
163 		if ((rv != CKR_OK) &&
164 		    (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
165 			(void) mutex_unlock(&init_lock);
166 			return (KMF_ERR_UNINITIALIZED);
167 		} else {
168 			pkcs11_initialized = 1;
169 		}
170 	}
171 	(void) mutex_unlock(&init_lock);
172 	return (KMF_OK);
173 }
174 
175 /*
176  * Private method for searching the plugin list for the correct
177  * Plugin to use.
178  */
179 KMF_PLUGIN *
180 FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype)
181 {
182 	KMF_PLUGIN_LIST *node;
183 
184 	if (handle == NULL)
185 		return (NULL);
186 
187 	node = handle->plugins;
188 
189 	while (node != NULL && node->plugin->type != kstype)
190 		node = node->next;
191 
192 	/* If it is NULL, that is indication enough of an error */
193 	return (node ? node->plugin : NULL);
194 }
195 
196 static KMF_RETURN
197 InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin)
198 {
199 	KMF_PLUGIN *p = NULL;
200 	KMF_PLUGIN_FUNCLIST *(*sym)();
201 
202 	if (path == NULL || plugin == NULL)
203 		return (KMF_ERR_BAD_PARAMETER);
204 
205 	*plugin = NULL;
206 
207 	p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN));
208 	if (p == NULL)
209 		return (KMF_ERR_MEMORY);
210 
211 	p->type = kstype;
212 	p->path = strdup(path);
213 	if (p->path == NULL) {
214 		free(p);
215 		return (KMF_ERR_MEMORY);
216 	}
217 	p->dldesc = dlopen(path, RTLD_NOW | RTLD_GROUP | RTLD_PARENT);
218 	if (p->dldesc == NULL) {
219 		free(p->path);
220 		free(p);
221 		return (KMF_ERR_PLUGIN_INIT);
222 	}
223 
224 	sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc,
225 		KMF_PLUGIN_INIT_SYMBOL);
226 	if (sym == NULL) {
227 		(void) dlclose(p->dldesc);
228 		free(p->path);
229 		free(p);
230 		return (KMF_ERR_PLUGIN_INIT);
231 	}
232 
233 	/* Get the function list */
234 	if ((p->funclist = (*sym)()) == NULL) {
235 		(void) dlclose(p->dldesc);
236 		free(p->path);
237 		free(p);
238 		return (KMF_ERR_PLUGIN_INIT);
239 	}
240 
241 	*plugin = p;
242 
243 	return (KMF_OK);
244 }
245 
246 static KMF_RETURN
247 AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin)
248 {
249 	KMF_PLUGIN_LIST *n;
250 
251 	if (handle == NULL || plugin == NULL)
252 		return (KMF_ERR_BAD_PARAMETER);
253 
254 	/* If the head is NULL, create it */
255 	if (handle->plugins == NULL) {
256 		handle->plugins = (KMF_PLUGIN_LIST *)malloc(
257 			sizeof (KMF_PLUGIN_LIST));
258 		if (handle->plugins == NULL)
259 			return (KMF_ERR_MEMORY);
260 		handle->plugins->plugin = plugin;
261 		handle->plugins->next = NULL;
262 	} else {
263 		/* walk the list to find the tail */
264 		n = handle->plugins;
265 		while (n->next != NULL)
266 			n = n->next;
267 		n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST));
268 		if (n->next == NULL)
269 			return (KMF_ERR_MEMORY);
270 
271 		n->next->plugin = plugin;
272 		n->next->next = NULL;
273 	}
274 	return (0);
275 }
276 
277 static void
278 DestroyPlugin(KMF_PLUGIN *plugin)
279 {
280 	if (plugin) {
281 		if (plugin->path)
282 			free(plugin->path);
283 		free(plugin);
284 	}
285 }
286 
287 static void
288 Cleanup_KMF_Handle(KMF_HANDLE_T handle)
289 {
290 	if (handle != NULL) {
291 		while (handle->plugins != NULL) {
292 			KMF_PLUGIN_LIST *next = handle->plugins->next;
293 
294 			DestroyPlugin(handle->plugins->plugin);
295 
296 			free(handle->plugins);
297 
298 			handle->plugins = next;
299 		}
300 
301 		KMF_FreePolicyRecord(handle->policy);
302 		free(handle->policy);
303 	}
304 	free(handle);
305 }
306 
307 void
308 Cleanup_PK11_Session(KMF_HANDLE_T handle)
309 {
310 	if (handle != NULL) {
311 		/* Close active session on a pkcs11 token */
312 		if (handle->pk11handle != NULL) {
313 			(void) C_CloseSession(handle->pk11handle);
314 			handle->pk11handle = NULL;
315 		}
316 	}
317 }
318 
319 KMF_RETURN
320 KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname)
321 {
322 	KMF_RETURN ret = KMF_OK;
323 	KMF_HANDLE *handle = NULL;
324 	KMF_PLUGIN *pluginrec = NULL;
325 	int i, numitems;
326 
327 	if (outhandle == NULL)
328 		return (KMF_ERR_BAD_PARAMETER);
329 
330 	*outhandle = NULL;
331 	handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE));
332 	if (handle == NULL)
333 		return (KMF_ERR_MEMORY);
334 
335 	(void) memset(handle, 0, sizeof (KMF_HANDLE));
336 	handle->plugins = NULL;
337 
338 	/* Initialize the handle with the policy */
339 	ret = KMF_SetPolicy((void *)handle,
340 	    policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile,
341 	    policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname);
342 	if (ret != KMF_OK)
343 		goto errout;
344 
345 	numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM);
346 	for (i = 0; i < numitems; i++) {
347 		ret = InitializePlugin(plugin_list[i].kstype,
348 			plugin_list[i].path, &pluginrec);
349 		if (ret != KMF_OK) {
350 			cryptoerror(
351 			    plugin_list[i].critical ? LOG_WARNING : LOG_DEBUG,
352 			    "KMF was unable to load %s plugin module %s\n",
353 			    plugin_list[i].critical ? "critical" : "optional",
354 			    plugin_list[i].path);
355 
356 			if (plugin_list[i].critical == FALSE)
357 				ret = KMF_OK;
358 			else
359 				goto errout;
360 		}
361 		if (pluginrec != NULL) {
362 			if ((ret = AddPlugin(handle, pluginrec)))
363 				goto errout;
364 		}
365 	}
366 
367 	CLEAR_ERROR(handle, ret);
368 errout:
369 	if (ret != KMF_OK) {
370 		Cleanup_KMF_Handle(handle);
371 		handle = NULL;
372 	}
373 
374 	*outhandle = (KMF_HANDLE_T)handle;
375 	return (ret);
376 }
377 
378 KMF_RETURN
379 KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params)
380 {
381 	KMF_PLUGIN *plugin;
382 	KMF_RETURN ret;
383 
384 	CLEAR_ERROR(handle, ret);
385 	if (ret != KMF_OK)
386 		return (ret);
387 
388 	if (params == NULL)
389 		return (KMF_ERR_BAD_PARAMETER);
390 
391 	plugin = FindPlugin(handle, params->kstype);
392 	if (plugin == NULL)
393 		return (KMF_ERR_PLUGIN_NOTFOUND);
394 
395 	if (plugin->funclist->ConfigureKeystore != NULL)
396 		return (plugin->funclist->ConfigureKeystore(handle, params));
397 	else
398 		/* return KMF_OK, if the plugin does not have an entry */
399 		return (KMF_OK);
400 }
401 
402 KMF_RETURN
403 KMF_Finalize(KMF_HANDLE_T handle)
404 {
405 	KMF_RETURN ret = KMF_OK;
406 
407 	CLEAR_ERROR(handle, ret);
408 	if (ret != KMF_OK)
409 		return (ret);
410 
411 	if (pkcs11_initialized) {
412 		Cleanup_PK11_Session(handle);
413 	}
414 	Cleanup_KMF_Handle(handle);
415 
416 	return (ret);
417 }
418 
419 KMF_RETURN
420 KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg)
421 {
422 	KMF_RETURN ret = KMF_OK;
423 	int i, maxerr;
424 
425 	if (errmsg == NULL)
426 		return (KMF_ERR_BAD_PARAMETER);
427 
428 	*errmsg = NULL;
429 	maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map);
430 
431 	for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++);
432 
433 	if (i == maxerr)
434 		return (KMF_ERR_MISSING_ERRCODE);
435 	else {
436 		*errmsg = strdup(kmf_errcodes[i].message);
437 		if ((*errmsg) == NULL)
438 			return (KMF_ERR_MEMORY);
439 	}
440 	return (ret);
441 }
442 
443 KMF_RETURN
444 KMF_GetPluginErrorString(KMF_HANDLE_T handle, char **msgstr)
445 {
446 	KMF_RETURN ret = KMF_OK;
447 	KMF_PLUGIN *plugin;
448 
449 	if (handle == NULL || msgstr == NULL)
450 		return (KMF_ERR_BAD_PARAMETER);
451 
452 	*msgstr = NULL;
453 
454 	if (handle->lasterr.errcode == 0) {
455 		return (KMF_ERR_MISSING_ERRCODE);
456 	}
457 
458 	if (handle->lasterr.kstype == -1) { /* System error */
459 		char *str = strerror(handle->lasterr.errcode);
460 		if (str != NULL) {
461 			*msgstr = strdup(str);
462 			if ((*msgstr) == NULL)
463 				return (KMF_ERR_MEMORY);
464 		}
465 		return (KMF_OK);
466 	}
467 
468 	plugin = FindPlugin(handle, handle->lasterr.kstype);
469 	if (plugin == NULL)
470 		return (KMF_ERR_PLUGIN_NOTFOUND);
471 
472 	if (plugin->funclist->GetErrorString != NULL) {
473 		ret = plugin->funclist->GetErrorString(handle, msgstr);
474 	} else {
475 		return (KMF_ERR_FUNCTION_NOT_FOUND);
476 	}
477 
478 	return (ret);
479 }
480 
481 KMF_RETURN
482 KMF_DNParser(char *string, KMF_X509_NAME *name)
483 {
484 	KMF_RETURN err;
485 
486 	if (string == NULL || name == NULL)
487 		return (KMF_ERR_BAD_PARAMETER);
488 
489 	err = ParseDistinguishedName(string, (int)strlen(string), name);
490 	return (err);
491 }
492 
493 KMF_RETURN
494 KMF_DN2Der(KMF_X509_NAME *dn, KMF_DATA *der)
495 {
496 	KMF_RETURN rv;
497 
498 	if (dn == NULL || der == NULL)
499 		return (KMF_ERR_BAD_PARAMETER);
500 
501 	rv = DerEncodeName(dn, der);
502 	return (rv);
503 }
504 
505 #define	SET_SYS_ERROR(h, c) if (h) {\
506 	h->lasterr.kstype = -1;\
507 	h->lasterr.errcode = c;\
508 }
509 
510 KMF_RETURN
511 KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename,  KMF_DATA *pdata)
512 {
513 	struct stat s;
514 	long nread, total = 0;
515 	int fd;
516 	unsigned char *buf = NULL;
517 	KMF_RETURN ret;
518 
519 	if (handle) {
520 		CLEAR_ERROR(handle, ret);
521 		if (ret != KMF_OK)
522 			return (ret);
523 	}
524 
525 	if (filename == NULL || pdata == NULL) {
526 		return (KMF_ERR_BAD_PARAMETER);
527 	}
528 
529 	if ((fd = open(filename, O_RDONLY)) < 0) {
530 		SET_SYS_ERROR(handle, errno);
531 		return (KMF_ERR_OPEN_FILE);
532 	}
533 
534 	if (fstat(fd, &s) < 0) {
535 		SET_SYS_ERROR(handle, errno);
536 		(void) close(fd);
537 		return (KMF_ERR_OPEN_FILE);
538 	}
539 
540 	if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) {
541 		(void) close(fd);
542 		return (KMF_ERR_MEMORY);
543 	}
544 
545 	do {
546 		nread = read(fd, buf+total, s.st_size-total);
547 		if (nread < 0) {
548 			SET_SYS_ERROR(handle, errno);
549 			(void) close(fd);
550 			free(buf);
551 			return (KMF_ERR_INTERNAL);
552 		}
553 		total += nread;
554 	} while (total < s.st_size);
555 
556 	pdata->Data = buf;
557 	pdata->Length = s.st_size;
558 	(void) close(fd);
559 	return (KMF_OK);
560 }
561 
562 /*
563  *
564  * Name: KMF_Der2Pem
565  *
566  * Description:
567  *   Function for converting DER encoded format to PEM encoded format
568  *
569  * Parameters:
570  *   type(input) - CERTIFICATE or CSR
571  *   data(input) - pointer to the DER encoded data
572  *   len(input)  - length of input data
573  *   out(output) - contains the output buffer address to be returned
574  *   outlen(output) - pointer to the returned output length
575  *
576  * Returns:
577  *   A KMF_RETURN value indicating success or specifying a particular
578  * error condition.
579  *   The value KMF_OK indicates success. All other values represent
580  * an error condition.
581  *
582  */
583 KMF_RETURN
584 KMF_Der2Pem(KMF_OBJECT_TYPE type, unsigned char *data,
585 	int len, unsigned char **out, int *outlen)
586 {
587 
588 	KMF_RETURN err;
589 	if (data == NULL || out == NULL || outlen == NULL)
590 		return (KMF_ERR_BAD_PARAMETER);
591 
592 	err = Der2Pem(type, data, len, out, outlen);
593 	return (err);
594 
595 }
596 
597 /*
598  *
599  * Name: KMF_Pem2Der
600  *
601  * Description:
602  *   Function for converting PEM encoded format to DER encoded format
603  *
604  * Parameters:
605  *   in(input) - pointer to the PEM encoded data
606  *   inlen(input)  - length of input data
607  *   out(output) - contains the output buffer address to be returned
608  *   outlen(output) - pointer to the returned output length
609  *
610  * Returns:
611  *   A KMF_RETURN value indicating success or specifying a particular
612  *   error condition.
613  *   The value KMF_OK indicates success. All other values represent
614  *   an error condition.
615  *
616  */
617 KMF_RETURN
618 KMF_Pem2Der(unsigned char *in, int inlen,
619 	unsigned char **out, int *outlen)
620 {
621 	KMF_RETURN err;
622 	if (in == NULL || out == NULL || outlen == NULL)
623 		return (KMF_ERR_BAD_PARAMETER);
624 
625 	err = Pem2Der(in, inlen, out, outlen);
626 	return (err);
627 }
628 
629 char *
630 KMF_OID2String(KMF_OID *oid)
631 {
632 	char numstr[128];
633 	uint32_t number;
634 	int numshift;
635 	uint32_t i, string_length;
636 	uchar_t *cp;
637 	char *bp;
638 
639 	/* First determine the size of the string */
640 	string_length = 0;
641 	number = 0;
642 	numshift = 0;
643 	cp = (unsigned char *)oid->Data;
644 
645 	number = (uint32_t)cp[0];
646 	(void) sprintf(numstr, "%d ", number/40);
647 
648 	string_length += strlen(numstr);
649 	(void) sprintf(numstr, "%d ", number%40);
650 
651 	string_length += strlen(numstr);
652 
653 	for (i = 1; i < oid->Length; i++) {
654 		if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) {
655 			number = (number << 7) | (cp[i] & 0x7f);
656 			numshift += 7;
657 		} else {
658 			return (NULL);
659 		}
660 
661 		if ((cp[i] & 0x80) == 0) {
662 			(void) sprintf(numstr, "%d ", number);
663 			string_length += strlen(numstr);
664 			number = 0;
665 			numshift = 0;
666 		}
667 	}
668 	/*
669 	 * If we get here, we've calculated the length of "n n n ... n ".  Add 4
670 	 * here for "{ " and "}\0".
671 	 */
672 	string_length += 4;
673 	if ((bp = (char *)malloc(string_length))) {
674 		number = (uint32_t)cp[0];
675 
676 		(void) sprintf(numstr, "%d.", number/40);
677 		(void) strcpy(bp, numstr);
678 
679 		(void) sprintf(numstr, "%d.", number%40);
680 		(void) strcat(bp, numstr);
681 
682 		number = 0;
683 		cp = (unsigned char *) oid->Data;
684 		for (i = 1; i < oid->Length; i++) {
685 			number = (number << 7) | (cp[i] & 0x7f);
686 			if ((cp[i] & 0x80) == 0) {
687 				(void) sprintf(numstr, "%d", number);
688 				(void) strcat(bp, numstr);
689 				number = 0;
690 				if (i+1 < oid->Length)
691 					(void) strcat(bp, ".");
692 			}
693 		}
694 	}
695 	return (bp);
696 }
697 
698 static boolean_t
699 check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt)
700 {
701 	char *p;
702 
703 	if (buf == NULL)
704 		return (FALSE);
705 
706 	if (memcmp(buf, "Bag Attr", 8) == 0) {
707 		*fmt = KMF_FORMAT_PEM_KEYPAIR;
708 		return (TRUE);
709 	}
710 
711 	/* Look for "-----BEGIN" right after a newline */
712 	p = strtok((char *)buf, "\n");
713 	while (p != NULL) {
714 		if (strstr(p, "-----BEGIN") != NULL) {
715 			*fmt = KMF_FORMAT_PEM;
716 			return (TRUE);
717 		}
718 		p = strtok(NULL, "\n");
719 	}
720 	return (FALSE);
721 }
722 
723 
724 static unsigned char pkcs12_version[3] = {0x02, 0x01, 0x03};
725 static unsigned char pkcs12_oid[11] =
726 {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01};
727 
728 /*
729  * This function takes a BER encoded string as input and checks the version
730  * and the oid in the the top-level ASN.1 structure to see if it complies to
731  * the PKCS#12 Syntax.
732  */
733 static boolean_t
734 check_for_pkcs12(uchar_t *buf, int buf_len)
735 {
736 	int index = 0;
737 	int length_octets;
738 
739 	if (buf == NULL || buf_len <= 0)
740 		return (FALSE);
741 
742 	/*
743 	 * The top level structure for a PKCS12 string:
744 	 *
745 	 * PFX ::= SEQUENCE {
746 	 *	version		INTEGER {v3(3)}(v3,...)
747 	 *	authSafe	ContentInfo
748 	 *	macData		MacData OPTIONAL
749 	 * }
750 	 *
751 	 * ContentInfo
752 	 *	FROM PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549)
753 	 *		pkcs(1) pkcs-7(7) modules(0) pkcs-7(1)}
754 	 *
755 	 * Therefore, the BER/DER dump of a PKCS#12 file for the first 2
756 	 * sequences up to the oid part is as following:
757 	 *
758 	 *	SEQUENCE {
759 	 *	    INTEGER 3
760 	 *	    SEQUENCE {
761 	 *		OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
762 	 */
763 
764 	/*
765 	 * Check the first sequence and calculate the number of bytes used
766 	 * to store the length.
767 	 */
768 	if (buf[index++] != 0x30)
769 		return (FALSE);
770 
771 	if (buf[index] & 0x80) {
772 		length_octets = buf[index++] & 0x0F;  /* long form */
773 	} else {
774 		length_octets = 1; /* short form */
775 	}
776 
777 	index += length_octets;
778 	if (index  >= buf_len)
779 		return (FALSE);
780 
781 	/* Skip the length octets and check the pkcs12 version */
782 	if (memcmp(buf + index, pkcs12_version, sizeof (pkcs12_version)) != 0)
783 		return (FALSE);
784 
785 	index += sizeof (pkcs12_version);
786 	if (index  >= buf_len)
787 		return (FALSE);
788 
789 	/*
790 	 * Check the 2nd sequence and calculate the number of bytes used
791 	 * to store the length.
792 	 */
793 	if ((buf[index++] & 0xFF) != 0x30)
794 		return (FALSE);
795 
796 	if (buf[index] & 0x80) {
797 		length_octets = buf[index++] & 0x0F;
798 	} else {
799 		length_octets = 1;
800 	}
801 
802 	index += length_octets;
803 	if (index + sizeof (pkcs12_oid) >= buf_len)
804 		return (FALSE);
805 
806 	/* Skip the length octets and check the oid */
807 	if (memcmp(buf + index, pkcs12_oid, sizeof (pkcs12_oid)) != 0)
808 		return (FALSE);
809 	else
810 		return (TRUE);
811 }
812 
813 KMF_RETURN
814 KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt)
815 {
816 	KMF_RETURN ret = KMF_OK;
817 	KMF_DATA filebuf = {NULL, 0};
818 	uchar_t *buf;
819 
820 	if (filename == NULL || !strlen(filename) || fmt == NULL)
821 		return (KMF_ERR_BAD_PARAMETER);
822 
823 	*fmt = 0;
824 	ret = KMF_ReadInputFile(NULL, filename, &filebuf);
825 	if (ret != KMF_OK)
826 		return (ret);
827 
828 	if (filebuf.Length < 8) {
829 		ret = KMF_ERR_ENCODING; /* too small */
830 		goto end;
831 	}
832 
833 	buf = filebuf.Data;
834 	if (check_for_pkcs12(buf, filebuf.Length) == TRUE) {
835 		*fmt = KMF_FORMAT_PKCS12;
836 	} else if (buf[0] == 0x30 && (buf[1] & 0x80)) {
837 		/* It is most likely a generic ASN.1 encoded file */
838 		*fmt = KMF_FORMAT_ASN1;
839 	} else if (check_for_pem(buf, fmt) == TRUE) {
840 		goto end;
841 	} else {
842 		/* Cannot determine this file format */
843 		*fmt = 0;
844 		ret = KMF_ERR_ENCODING;
845 	}
846 
847 end:
848 	KMF_FreeData(&filebuf);
849 	return (ret);
850 }
851 
852 KMF_RETURN
853 KMF_HexString2Bytes(unsigned char *hexstr, unsigned char **bytes,
854 	size_t *outlen)
855 {
856 	KMF_RETURN ret = KMF_OK;
857 	unsigned char *buf = NULL;
858 	int len, stringlen;
859 	int i;
860 	unsigned char ch;
861 
862 	if (hexstr == NULL) {
863 		return (KMF_ERR_BAD_PARAMETER);
864 	}
865 
866 	if (hexstr[0] == '0' &&
867 		((hexstr[1] == 'x') || (hexstr[1] == 'X')))
868 		hexstr += 2;
869 
870 	for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++);
871 	/*
872 	 * If all the characters are not legitimate hex chars,
873 	 * return an error.
874 	 */
875 	if (i != strlen((char *)hexstr))
876 		return (KMF_ERR_BAD_HEX_STRING);
877 	stringlen = i;
878 	len = (i / 2) + (i % 2);
879 
880 	buf = malloc(len);
881 	if (buf == NULL) {
882 		return (KMF_ERR_MEMORY);
883 	}
884 	(void) memset(buf, 0, len);
885 
886 	for (i = 0; i < stringlen; i++) {
887 		ch = (unsigned char) *hexstr;
888 		hexstr++;
889 		if ((ch >= '0') && (ch <= '9'))
890 			ch -= '0';
891 		else if ((ch >= 'A') && (ch <= 'F'))
892 			ch = ch - 'A' + 10;
893 		else if ((ch >= 'a') && (ch <= 'f'))
894 			ch = ch - 'a' + 10;
895 		else {
896 			ret = KMF_ERR_BAD_HEX_STRING;
897 			goto out;
898 		}
899 
900 		if (i & 1) {
901 			buf[i/2] |= ch;
902 		} else {
903 			buf[i/2] = (ch << 4);
904 		}
905 	}
906 
907 	*bytes = buf;
908 	*outlen = len;
909 out:
910 	if (buf != NULL && ret != KMF_OK) {
911 		free(buf);
912 	}
913 	return (ret);
914 }
915 
916 void
917 KMF_FreeDN(KMF_X509_NAME *name)
918 {
919 	KMF_X509_RDN 		*newrdn = NULL;
920 	KMF_X509_TYPE_VALUE_PAIR *av = NULL;
921 	int i, j;
922 
923 	if (name && name->numberOfRDNs) {
924 		for (i = 0; i < name->numberOfRDNs; i++) {
925 			newrdn = &name->RelativeDistinguishedName[i];
926 			for (j = 0; j < newrdn->numberOfPairs; j++) {
927 				av = &newrdn->AttributeTypeAndValue[j];
928 				KMF_FreeData(&av->type);
929 				KMF_FreeData(&av->value);
930 			}
931 			free(newrdn->AttributeTypeAndValue);
932 			newrdn->numberOfPairs = 0;
933 			newrdn->AttributeTypeAndValue = NULL;
934 		}
935 		free(name->RelativeDistinguishedName);
936 		name->numberOfRDNs = 0;
937 		name->RelativeDistinguishedName = NULL;
938 	}
939 }
940 
941 void
942 KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
943 {
944 	KMF_PLUGIN *plugin;
945 	KMF_RETURN ret;
946 
947 	CLEAR_ERROR(handle, ret);
948 	if (ret != KMF_OK)
949 		return;
950 
951 	if (kmf_cert == NULL)
952 		return;
953 
954 	plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type);
955 
956 	if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) {
957 		plugin->funclist->FreeKMFCert(handle, kmf_cert);
958 	}
959 }
960 
961 void
962 KMF_FreeData(KMF_DATA *datablock)
963 {
964 	if (datablock != NULL && datablock->Data != NULL) {
965 		free(datablock->Data);
966 		datablock->Data = NULL;
967 		datablock->Length = 0;
968 	}
969 }
970 
971 void
972 KMF_FreeAlgOID(KMF_X509_ALGORITHM_IDENTIFIER *algoid)
973 {
974 	if (algoid == NULL)
975 		return;
976 	KMF_FreeData(&algoid->algorithm);
977 	KMF_FreeData(&algoid->parameters);
978 }
979 
980 void
981 KMF_FreeExtension(KMF_X509_EXTENSION *exptr)
982 {
983 	if (exptr == NULL)
984 		return;
985 
986 	KMF_FreeData((KMF_DATA *)&exptr->extnId);
987 	KMF_FreeData(&exptr->BERvalue);
988 
989 	if (exptr->value.tagAndValue) {
990 		KMF_FreeData(&exptr->value.tagAndValue->value);
991 		free(exptr->value.tagAndValue);
992 	}
993 }
994 
995 void
996 KMF_FreeTBSCSR(KMF_TBS_CSR *tbscsr)
997 {
998 	if (tbscsr) {
999 		KMF_FreeData(&tbscsr->version);
1000 
1001 		KMF_FreeDN(&tbscsr->subject);
1002 
1003 		KMF_FreeAlgOID(&tbscsr->subjectPublicKeyInfo.algorithm);
1004 		KMF_FreeData(&tbscsr->subjectPublicKeyInfo.subjectPublicKey);
1005 
1006 		free_extensions(&tbscsr->extensions);
1007 	}
1008 }
1009 
1010 void
1011 KMF_FreeSignedCSR(KMF_CSR_DATA *csr)
1012 {
1013 	if (csr) {
1014 		KMF_FreeTBSCSR(&csr->csr);
1015 
1016 		KMF_FreeAlgOID(&csr->signature.algorithmIdentifier);
1017 		KMF_FreeData(&csr->signature.encrypted);
1018 	}
1019 }
1020 
1021 static void
1022 free_validity(KMF_X509_VALIDITY *validity)
1023 {
1024 	if (validity == NULL)
1025 		return;
1026 	KMF_FreeData(&validity->notBefore.time);
1027 	KMF_FreeData(&validity->notAfter.time);
1028 }
1029 
1030 static void
1031 free_extensions(KMF_X509_EXTENSIONS *extns)
1032 {
1033 	int i;
1034 	KMF_X509_EXTENSION *exptr;
1035 
1036 	if (extns && extns->numberOfExtensions > 0) {
1037 		for (i = 0; i < extns->numberOfExtensions; i++) {
1038 			exptr = &extns->extensions[i];
1039 			KMF_FreeExtension(exptr);
1040 		}
1041 		free(extns->extensions);
1042 		extns->numberOfExtensions = 0;
1043 		extns->extensions = NULL;
1044 	}
1045 }
1046 
1047 void
1048 KMF_FreeTBSCert(KMF_X509_TBS_CERT *tbscert)
1049 {
1050 	if (tbscert) {
1051 		KMF_FreeData(&tbscert->version);
1052 		KMF_FreeBigint(&tbscert->serialNumber);
1053 		KMF_FreeAlgOID(&tbscert->signature);
1054 
1055 		KMF_FreeDN(&tbscert->issuer);
1056 		KMF_FreeDN(&tbscert->subject);
1057 
1058 		free_validity(&tbscert->validity);
1059 
1060 		KMF_FreeData(&tbscert->issuerUniqueIdentifier);
1061 		KMF_FreeData(&tbscert->subjectUniqueIdentifier);
1062 
1063 		KMF_FreeAlgOID(&tbscert->subjectPublicKeyInfo.algorithm);
1064 		KMF_FreeData(&tbscert->subjectPublicKeyInfo.subjectPublicKey);
1065 
1066 		free_extensions(&tbscert->extensions);
1067 
1068 		KMF_FreeData(&tbscert->issuerUniqueIdentifier);
1069 		KMF_FreeData(&tbscert->subjectUniqueIdentifier);
1070 	}
1071 }
1072 
1073 void
1074 KMF_FreeSignedCert(KMF_X509_CERTIFICATE *certptr)
1075 {
1076 	if (!certptr)
1077 		return;
1078 
1079 	KMF_FreeTBSCert(&certptr->certificate);
1080 
1081 	KMF_FreeAlgOID(&certptr->signature.algorithmIdentifier);
1082 	KMF_FreeData(&certptr->signature.encrypted);
1083 }
1084 
1085 void
1086 KMF_FreeString(char *pstr)
1087 {
1088 	if (pstr != NULL)
1089 		free(pstr);
1090 }
1091 
1092 void
1093 free_keyidlist(KMF_OID *oidlist, int len)
1094 {
1095 	int i;
1096 	for (i = 0; i < len; i++) {
1097 		KMF_FreeData((KMF_DATA *)&oidlist[i]);
1098 	}
1099 	free(oidlist);
1100 }
1101 
1102 void
1103 KMF_FreeEKU(KMF_X509EXT_EKU *eptr)
1104 {
1105 	if (eptr && eptr->nEKUs > 0 &&
1106 		eptr->keyPurposeIdList != NULL)
1107 		free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs);
1108 }
1109 
1110 void
1111 KMF_FreeSPKI(KMF_X509_SPKI *spki)
1112 {
1113 	if (spki != NULL) {
1114 		KMF_FreeAlgOID(&spki->algorithm);
1115 		KMF_FreeData(&spki->subjectPublicKey);
1116 	}
1117 }
1118 
1119 void
1120 KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key)
1121 {
1122 	KMF_PLUGIN *plugin;
1123 	KMF_RETURN ret;
1124 
1125 	CLEAR_ERROR(handle, ret);
1126 	if (ret != KMF_OK)
1127 		return;
1128 
1129 	if (key == NULL)
1130 		return;
1131 
1132 	plugin = FindPlugin(handle, key->kstype);
1133 	if (plugin != NULL && plugin->funclist->DeleteKey != NULL) {
1134 		(void) plugin->funclist->DeleteKey(handle, NULL, key, FALSE);
1135 	}
1136 
1137 	if (key == NULL)
1138 		return;
1139 
1140 	if (key->keylabel)
1141 		free(key->keylabel);
1142 
1143 	if (key->israw) {
1144 		KMF_FreeRawKey(key->keyp);
1145 		free(key->keyp);
1146 	}
1147 
1148 	(void) memset(key, 0, sizeof (KMF_KEY_HANDLE));
1149 }
1150 
1151 void
1152 KMF_FreeBigint(KMF_BIGINT *big)
1153 {
1154 	if (big != NULL && big->val != NULL) {
1155 		/* Clear it out before returning it to the pool */
1156 		(void) memset(big->val, 0x00, big->len);
1157 		free(big->val);
1158 		big->val = NULL;
1159 		big->len = 0;
1160 	}
1161 }
1162 
1163 static void
1164 free_raw_rsa(KMF_RAW_RSA_KEY *key)
1165 {
1166 	if (key == NULL)
1167 		return;
1168 	KMF_FreeBigint(&key->mod);
1169 	KMF_FreeBigint(&key->pubexp);
1170 	KMF_FreeBigint(&key->priexp);
1171 	KMF_FreeBigint(&key->prime1);
1172 	KMF_FreeBigint(&key->prime2);
1173 	KMF_FreeBigint(&key->exp1);
1174 	KMF_FreeBigint(&key->exp2);
1175 	KMF_FreeBigint(&key->coef);
1176 }
1177 
1178 static void
1179 free_raw_dsa(KMF_RAW_DSA_KEY *key)
1180 {
1181 	if (key == NULL)
1182 		return;
1183 	KMF_FreeBigint(&key->prime);
1184 	KMF_FreeBigint(&key->subprime);
1185 	KMF_FreeBigint(&key->base);
1186 	KMF_FreeBigint(&key->value);
1187 }
1188 
1189 static void
1190 free_raw_sym(KMF_RAW_SYM_KEY *key)
1191 {
1192 	if (key == NULL)
1193 		return;
1194 	KMF_FreeBigint(&key->keydata);
1195 }
1196 
1197 void
1198 KMF_FreeRawKey(KMF_RAW_KEY_DATA *key)
1199 {
1200 	if (key == NULL)
1201 		return;
1202 
1203 	switch (key->keytype) {
1204 	case KMF_RSA:
1205 		free_raw_rsa(&key->rawdata.rsa);
1206 		break;
1207 	case KMF_DSA:
1208 		free_raw_dsa(&key->rawdata.dsa);
1209 		break;
1210 	case KMF_AES:
1211 	case KMF_RC4:
1212 	case KMF_DES:
1213 	case KMF_DES3:
1214 		free_raw_sym(&key->rawdata.sym);
1215 		break;
1216 	}
1217 }
1218 
1219 void
1220 KMF_FreeRawSymKey(KMF_RAW_SYM_KEY *key)
1221 {
1222 	if (key == NULL)
1223 		return;
1224 	KMF_FreeBigint(&key->keydata);
1225 	free(key);
1226 }
1227 
1228 /*
1229  * This function frees the space allocated for the name portion of a
1230  * KMF_CRL_DIST_POINT.
1231  */
1232 void
1233 free_dp_name(KMF_CRL_DIST_POINT *dp)
1234 {
1235 	KMF_GENERALNAMES *fullname;
1236 	KMF_DATA *urldata;
1237 	int i;
1238 
1239 	if (dp == NULL)
1240 		return;
1241 
1242 	/* For phase 1, we only need to free the fullname space. */
1243 	fullname = &(dp->name.full_name);
1244 	if (fullname->number == 0)
1245 		return;
1246 
1247 	for (i = 0; i < fullname->number; i++) {
1248 		urldata = &(fullname->namelist[fullname->number - 1].name);
1249 		KMF_FreeData(urldata);
1250 	}
1251 
1252 	free(fullname->namelist);
1253 }
1254 
1255 /*
1256  * This function frees the space allocated for a KMF_CRL_DIST_POINT.
1257  */
1258 void
1259 free_dp(KMF_CRL_DIST_POINT *dp)
1260 {
1261 	if (dp == NULL)
1262 		return;
1263 
1264 	free_dp_name(dp);
1265 	KMF_FreeData(&(dp->reasons));
1266 	/* Need not to free crl_issuer space at phase 1 */
1267 }
1268 
1269 /*
1270  * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally.
1271  */
1272 void
1273 KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *crl_dps)
1274 {
1275 	int i;
1276 
1277 	if (crl_dps == NULL)
1278 		return;
1279 
1280 	for (i = 0; i < crl_dps->number; i++)
1281 		free_dp(&(crl_dps->dplist[i]));
1282 
1283 	free(crl_dps->dplist);
1284 }
1285 
1286 KMF_RETURN
1287 KMF_CreateOCSPRequest(KMF_HANDLE_T handle,  KMF_OCSPREQUEST_PARAMS *params,
1288     char *reqfile)
1289 {
1290 	KMF_PLUGIN *plugin;
1291 	KMF_RETURN (*createReqFn)(void *, KMF_OCSPREQUEST_PARAMS *params,
1292 	    char *reqfile);
1293 	KMF_RETURN ret;
1294 
1295 	CLEAR_ERROR(handle, ret);
1296 	if (ret != KMF_OK)
1297 		return (ret);
1298 
1299 
1300 	if (params == NULL ||
1301 		reqfile == NULL)
1302 		return (KMF_ERR_BAD_PARAMETER);
1303 
1304 	/*
1305 	 * This framework function is actually implemented in the openssl
1306 	 * plugin library, so we find the function address and call it.
1307 	 */
1308 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
1309 	if (plugin == NULL || plugin->dldesc == NULL) {
1310 		return (KMF_ERR_PLUGIN_NOTFOUND);
1311 	}
1312 
1313 	createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
1314 	    "OpenSSL_CreateOCSPRequest");
1315 	if (createReqFn == NULL) {
1316 		return (KMF_ERR_FUNCTION_NOT_FOUND);
1317 	}
1318 
1319 	return (createReqFn(handle, params, reqfile));
1320 }
1321 
1322 KMF_RETURN
1323 KMF_GetOCSPStatusForCert(KMF_HANDLE_T handle,
1324     KMF_OCSPRESPONSE_PARAMS_INPUT *params_in,
1325     KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out)
1326 {
1327 	KMF_PLUGIN *plugin;
1328 	KMF_RETURN (*getCertStatusFn)(void *,
1329 	    KMF_OCSPRESPONSE_PARAMS_INPUT *params_in,
1330 	    KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out);
1331 	KMF_RETURN ret;
1332 
1333 	CLEAR_ERROR(handle, ret);
1334 	if (ret != KMF_OK)
1335 		return (ret);
1336 
1337 
1338 	if (params_in == NULL ||
1339 		params_out == NULL)
1340 		return (KMF_ERR_BAD_PARAMETER);
1341 
1342 	/*
1343 	 * This framework function is actually implemented in the openssl
1344 	 * plugin library, so we find the function address and call it.
1345 	 */
1346 	plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
1347 	if (plugin == NULL || plugin->dldesc == NULL) {
1348 		return (KMF_ERR_INTERNAL);
1349 	}
1350 
1351 	getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
1352 	    "OpenSSL_GetOCSPStatusForCert");
1353 	if (getCertStatusFn == NULL) {
1354 		return (KMF_ERR_INTERNAL);
1355 	}
1356 
1357 	return (getCertStatusFn(handle, params_in, params_out));
1358 }
1359 
1360 KMF_RETURN
1361 KMF_String2OID(char *oidstring, KMF_OID *oid)
1362 {
1363 	KMF_RETURN rv = KMF_OK;
1364 	char *cp, *bp, *startp;
1365 	int numbuf;
1366 	int onumbuf;
1367 	int nbytes, index;
1368 	int len;
1369 	unsigned char *op;
1370 
1371 	if (oidstring == NULL || oid == NULL)
1372 		return (KMF_ERR_BAD_PARAMETER);
1373 
1374 	len = strlen(oidstring);
1375 
1376 	bp = oidstring;
1377 	cp = bp;
1378 	/* Skip over leading space */
1379 	while ((bp < &cp[len]) && isspace(*bp))
1380 		bp++;
1381 
1382 	startp = bp;
1383 	nbytes = 0;
1384 
1385 	/*
1386 	 * The first two numbers are chewed up by the first octet.
1387 	 */
1388 	if (sscanf(bp, "%d", &numbuf) != 1)
1389 		return (KMF_ERR_BAD_PARAMETER);
1390 	while ((bp < &cp[len]) && isdigit(*bp))
1391 		bp++;
1392 	while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.'))
1393 		bp++;
1394 	if (sscanf(bp, "%d", &numbuf) != 1)
1395 		return (KMF_ERR_BAD_PARAMETER);
1396 	while ((bp < &cp[len]) && isdigit(*bp))
1397 		bp++;
1398 	while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.'))
1399 		bp++;
1400 	nbytes++;
1401 
1402 	while (isdigit(*bp)) {
1403 		if (sscanf(bp, "%d", &numbuf) != 1)
1404 			return (KMF_ERR_BAD_PARAMETER);
1405 		while (numbuf) {
1406 			nbytes++;
1407 			numbuf >>= 7;
1408 		}
1409 		while ((bp < &cp[len]) && isdigit(*bp))
1410 			bp++;
1411 		while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.'))
1412 			bp++;
1413 	}
1414 
1415 	oid->Length = nbytes;
1416 	oid->Data = malloc(oid->Length);
1417 	if (oid->Data == NULL) {
1418 		return (KMF_ERR_MEMORY);
1419 	}
1420 	(void) memset(oid->Data, 0, oid->Length);
1421 
1422 	op = oid->Data;
1423 
1424 	bp = startp;
1425 	(void) sscanf(bp, "%d", &numbuf);
1426 
1427 	while (isdigit(*bp)) bp++;
1428 	while (isspace(*bp) || *bp == '.') bp++;
1429 
1430 	onumbuf = 40 * numbuf;
1431 	(void) sscanf(bp, "%d", &numbuf);
1432 	onumbuf += numbuf;
1433 	*op = (unsigned char) onumbuf;
1434 	op++;
1435 
1436 	while (isdigit(*bp)) bp++;
1437 	while (isspace(*bp) || *bp == '.') bp++;
1438 	while (isdigit(*bp)) {
1439 		(void) sscanf(bp, "%d", &numbuf);
1440 		nbytes = 0;
1441 		/* Have to fill in the bytes msb-first */
1442 		onumbuf = numbuf;
1443 		while (numbuf) {
1444 			nbytes++;
1445 			numbuf >>= 7;
1446 		}
1447 		numbuf = onumbuf;
1448 		op += nbytes;
1449 		index = -1;
1450 		while (numbuf) {
1451 			op[index] = (unsigned char)numbuf & 0x7f;
1452 			if (index != -1)
1453 				op[index] |= 0x80;
1454 			index--;
1455 			numbuf >>= 7;
1456 		}
1457 		while (isdigit(*bp)) bp++;
1458 		while (isspace(*bp) || *bp == '.') bp++;
1459 	}
1460 
1461 	return (rv);
1462 }
1463 
1464 static KMF_RETURN
1465 encode_rid(char *name, KMF_DATA *derdata)
1466 {
1467 	KMF_RETURN rv = KMF_OK;
1468 
1469 	if (name == NULL || derdata == NULL)
1470 		return (KMF_ERR_BAD_PARAMETER);
1471 
1472 	rv = KMF_String2OID(name, (KMF_OID *)derdata);
1473 
1474 	return (rv);
1475 }
1476 
1477 static KMF_RETURN
1478 encode_ipaddr(char *name, KMF_DATA *derdata)
1479 {
1480 	KMF_RETURN rv = KMF_OK;
1481 	size_t len;
1482 	in_addr_t v4;
1483 	in6_addr_t v6;
1484 	uint8_t *ptr;
1485 
1486 	if (name == NULL || derdata == NULL)
1487 		return (KMF_ERR_BAD_PARAMETER);
1488 
1489 	v4 = inet_addr(name);
1490 	if (v4 == (in_addr_t)-1) {
1491 		ptr = (uint8_t *)&v6;
1492 		if (inet_pton(AF_INET6, name, ptr) != 1)
1493 			return (KMF_ERR_ENCODING);
1494 		len = sizeof (v6);
1495 	} else {
1496 		ptr = (uint8_t *)&v4;
1497 		len = sizeof (v4);
1498 	}
1499 
1500 	derdata->Data = malloc(len);
1501 	if (derdata->Data == NULL)
1502 		return (KMF_ERR_MEMORY);
1503 	(void) memcpy(derdata->Data, ptr, len);
1504 	derdata->Length = len;
1505 
1506 	return (rv);
1507 }
1508 
1509 static KMF_RETURN
1510 verify_uri_format(char *uristring)
1511 {
1512 	KMF_RETURN ret = KMF_OK;
1513 	xmlURIPtr   uriptr = NULL;
1514 
1515 	/* Parse the URI string; get the hostname and port */
1516 	uriptr = xmlParseURI(uristring);
1517 	if (uriptr == NULL) {
1518 		ret = KMF_ERR_BAD_URI;
1519 		goto out;
1520 	}
1521 
1522 	if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) {
1523 		ret = KMF_ERR_BAD_URI;
1524 		goto out;
1525 	}
1526 
1527 	if (uriptr->server == NULL || !strlen(uriptr->server)) {
1528 		ret = KMF_ERR_BAD_URI;
1529 		goto out;
1530 	}
1531 out:
1532 	if (uriptr != NULL)
1533 		xmlFreeURI(uriptr);
1534 	return (ret);
1535 }
1536 
1537 static KMF_RETURN
1538 encode_altname(char *namedata,
1539 	KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname)
1540 {
1541 	KMF_RETURN ret = KMF_OK;
1542 	KMF_X509_NAME dnname;
1543 	uchar_t tagval;
1544 	BerElement *asn1 = NULL;
1545 	BerValue *extdata;
1546 
1547 	if (namedata == NULL || encodedname == NULL)
1548 		return (KMF_ERR_BAD_PARAMETER);
1549 
1550 	/*
1551 	 * Encode the namedata according to rules in RFC 3280 for GeneralName.
1552 	 * The input "namedata" is assumed to be an ASCII string representation
1553 	 * of the AltName, we need to convert it to correct ASN.1 here before
1554 	 * adding it to the cert.
1555 	 */
1556 	switch (nametype) {
1557 		case GENNAME_RFC822NAME: /* rfc 822 */
1558 			/* IA5String, no encoding needed */
1559 			encodedname->Data = (uchar_t *)strdup(namedata);
1560 			if (encodedname->Data == NULL)
1561 				return (KMF_ERR_MEMORY);
1562 			encodedname->Length = strlen(namedata);
1563 			tagval = (0x80 | nametype);
1564 			break;
1565 		case GENNAME_DNSNAME: /* rfc 1034 */
1566 			encodedname->Data = (uchar_t *)strdup(namedata);
1567 			if (encodedname->Data == NULL)
1568 				return (KMF_ERR_MEMORY);
1569 			encodedname->Length = strlen(namedata);
1570 			tagval = (0x80 | nametype);
1571 			break;
1572 		case GENNAME_URI: /* rfc 1738 */
1573 			ret = verify_uri_format(namedata);
1574 			if (ret != KMF_OK)
1575 				return (ret);
1576 			/* IA5String, no encoding needed */
1577 			encodedname->Data = (uchar_t *)strdup(namedata);
1578 			if (encodedname->Data == NULL)
1579 				return (KMF_ERR_MEMORY);
1580 			encodedname->Length = strlen(namedata);
1581 			tagval = (0x80 | nametype);
1582 			break;
1583 		case GENNAME_IPADDRESS:
1584 			ret =  encode_ipaddr(namedata, encodedname);
1585 			tagval = (0x80 | nametype);
1586 			break;
1587 		case GENNAME_REGISTEREDID:
1588 			ret = encode_rid(namedata, encodedname);
1589 			tagval = (0x80 | nametype);
1590 			break;
1591 		case GENNAME_DIRECTORYNAME:
1592 			ret = KMF_DNParser(namedata, &dnname);
1593 			if (ret == KMF_OK) {
1594 				ret = KMF_DN2Der(&dnname, encodedname);
1595 			}
1596 			(void) KMF_FreeDN(&dnname);
1597 			tagval = (0xA0 | nametype);
1598 			break;
1599 		default:
1600 			/* unsupported */
1601 			return (KMF_ERR_BAD_PARAMETER);
1602 
1603 	}
1604 	if (ret != KMF_OK) {
1605 		KMF_FreeData(encodedname);
1606 		return (ret);
1607 	}
1608 
1609 	if ((asn1 = kmfder_alloc()) == NULL)
1610 		return (KMF_ERR_MEMORY);
1611 
1612 	if (kmfber_printf(asn1, "Tl",
1613 		tagval, encodedname->Length) == -1)
1614 		goto cleanup;
1615 
1616 	if (kmfber_write(asn1, (char *)encodedname->Data,
1617 		encodedname->Length, 0) == -1) {
1618 		ret = KMF_ERR_ENCODING;
1619 		goto cleanup;
1620 	}
1621 	if (kmfber_flatten(asn1, &extdata) == -1) {
1622 		ret = KMF_ERR_ENCODING;
1623 		goto cleanup;
1624 	}
1625 
1626 	KMF_FreeData(encodedname);
1627 	encodedname->Data = (uchar_t *)extdata->bv_val;
1628 	encodedname->Length = extdata->bv_len;
1629 
1630 	free(extdata);
1631 
1632 cleanup:
1633 	if (asn1)
1634 		kmfber_free(asn1, 1);
1635 
1636 	if (ret != KMF_OK)
1637 		KMF_FreeData(encodedname);
1638 
1639 	return (ret);
1640 }
1641 
1642 KMF_X509_EXTENSION *
1643 FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid)
1644 {
1645 	KMF_X509_EXTENSION *foundextn = NULL;
1646 	int i;
1647 
1648 	if (exts == NULL || oid == NULL)
1649 		return (NULL);
1650 
1651 	for (i = 0; i < exts->numberOfExtensions; i++) {
1652 		if (IsEqualOid(oid, &exts->extensions[i].extnId))  {
1653 			foundextn = &exts->extensions[i];
1654 			break;
1655 		}
1656 	}
1657 	return (foundextn);
1658 }
1659 
1660 KMF_RETURN
1661 GetSequenceContents(char *data, size_t len,
1662 	char **contents, size_t *outlen)
1663 {
1664 	KMF_RETURN ret = KMF_OK;
1665 	BerElement *exasn1 = NULL;
1666 	BerValue oldextn;
1667 	int tag;
1668 	size_t oldsize;
1669 	char *olddata = NULL;
1670 
1671 	if (data == NULL || contents == NULL || outlen == NULL)
1672 		return (KMF_ERR_BAD_PARAMETER);
1673 
1674 	/*
1675 	 * Decode the sequence of general names
1676 	 */
1677 	oldextn.bv_val = data;
1678 	oldextn.bv_len = len;
1679 
1680 	if ((exasn1 = kmfder_init(&oldextn)) == NULL) {
1681 		ret = KMF_ERR_MEMORY;
1682 		goto out;
1683 	}
1684 
1685 	/*
1686 	 * Unwrap the sequence to find the size of the block
1687 	 * of GeneralName items in the set.
1688 	 *
1689 	 * Peek at the tag and length ("tl"),
1690 	 * then consume them ("{").
1691 	 */
1692 	if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT ||
1693 		oldsize == 0) {
1694 		ret = KMF_ERR_ENCODING;
1695 		goto out;
1696 	}
1697 
1698 	olddata = malloc(oldsize);
1699 	if (olddata == NULL) {
1700 		ret = KMF_ERR_MEMORY;
1701 		goto out;
1702 	}
1703 	(void) memset(olddata, 0, oldsize);
1704 	/*
1705 	 * Read the entire blob of GeneralNames, we don't
1706 	 * need to interpret them now.
1707 	 */
1708 	if (kmfber_read(exasn1, olddata, oldsize) != oldsize) {
1709 		ret = KMF_ERR_ENCODING;
1710 		goto out;
1711 	}
1712 out:
1713 	if (exasn1 != NULL)
1714 		kmfber_free(exasn1, 1);
1715 
1716 	if (ret != KMF_OK) {
1717 		*contents = NULL;
1718 		*outlen = 0;
1719 		if (olddata != NULL)
1720 			free(olddata);
1721 	} else {
1722 		*contents = olddata;
1723 		*outlen = oldsize;
1724 	}
1725 	return (ret);
1726 }
1727 
1728 KMF_RETURN
1729 add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn)
1730 {
1731 	KMF_RETURN ret = KMF_OK;
1732 	KMF_X509_EXTENSION *extlist;
1733 
1734 	if (exts == NULL || newextn == NULL)
1735 		return (KMF_ERR_BAD_PARAMETER);
1736 
1737 	extlist = malloc(sizeof (KMF_X509_EXTENSION) *
1738 			(exts->numberOfExtensions + 1));
1739 	if (extlist == NULL)
1740 		return (KMF_ERR_MEMORY);
1741 
1742 	(void) memcpy(extlist, exts->extensions,
1743 	    exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION));
1744 
1745 	(void) memcpy(&extlist[exts->numberOfExtensions], newextn,
1746 		sizeof (KMF_X509_EXTENSION));
1747 
1748 	free(exts->extensions);
1749 	exts->numberOfExtensions++;
1750 	exts->extensions = extlist;
1751 
1752 	return (ret);
1753 }
1754 
1755 KMF_RETURN
1756 KMF_SetAltName(KMF_X509_EXTENSIONS *extensions,
1757 	KMF_OID *oid,
1758 	int critical,
1759 	KMF_GENERALNAMECHOICES nametype,
1760 	char *namedata)
1761 {
1762 	KMF_RETURN ret = KMF_OK;
1763 	KMF_X509_EXTENSION subjAltName;
1764 	KMF_DATA dername = { NULL, 0 };
1765 	BerElement *asn1 = NULL;
1766 	BerValue *extdata;
1767 	char *olddata = NULL;
1768 	KMF_X509_EXTENSION *foundextn = NULL;
1769 	size_t	oldsize = 0;
1770 
1771 	if (extensions == NULL || oid == NULL || namedata == NULL)
1772 		return (KMF_ERR_BAD_PARAMETER);
1773 
1774 	ret = encode_altname(namedata, nametype, &dername);
1775 
1776 	if (ret != KMF_OK)
1777 		return (ret);
1778 
1779 	(void) memset(&subjAltName, 0, sizeof (subjAltName));
1780 
1781 	ret = copy_data(&subjAltName.extnId, oid);
1782 	if (ret != KMF_OK)
1783 		goto out;
1784 	/*
1785 	 * Check to see if this cert already has a subjectAltName.
1786 	 */
1787 	foundextn = FindExtn(extensions, oid);
1788 
1789 	if (foundextn != NULL) {
1790 		ret = GetSequenceContents(
1791 				(char *)foundextn->BERvalue.Data,
1792 				foundextn->BERvalue.Length,
1793 				&olddata, &oldsize);
1794 		if (ret != KMF_OK)
1795 			goto out;
1796 	}
1797 
1798 	/*
1799 	 * Assume (!!) that the namedata given is already properly encoded.
1800 	 */
1801 	if ((asn1 = kmfder_alloc()) == NULL)
1802 		return (KMF_ERR_MEMORY);
1803 
1804 	if (kmfber_printf(asn1, "{") == -1) {
1805 		ret = KMF_ERR_ENCODING;
1806 		goto out;
1807 	}
1808 
1809 	/* Write the old extension data first */
1810 	if (olddata != NULL && oldsize > 0) {
1811 		if (kmfber_write(asn1, olddata, oldsize, 0) == -1) {
1812 			ret = KMF_ERR_ENCODING;
1813 			goto out;
1814 		}
1815 	}
1816 
1817 	/* Now add the new name to the list */
1818 	if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) {
1819 		ret = KMF_ERR_ENCODING;
1820 		goto out;
1821 	}
1822 
1823 	/* Now close the sequence */
1824 	if (kmfber_printf(asn1, "}") == -1) {
1825 		ret = KMF_ERR_ENCODING;
1826 		goto out;
1827 	}
1828 	if (kmfber_flatten(asn1, &extdata) == -1) {
1829 		ret = KMF_ERR_ENCODING;
1830 		goto out;
1831 	}
1832 
1833 	/*
1834 	 * If we are just adding to an existing list of altNames,
1835 	 * just replace the BER data associated with the found extension.
1836 	 */
1837 	if (foundextn != NULL) {
1838 		free(foundextn->BERvalue.Data);
1839 		foundextn->critical = critical;
1840 		foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val;
1841 		foundextn->BERvalue.Length = extdata->bv_len;
1842 	} else {
1843 		subjAltName.critical = critical;
1844 		subjAltName.format = KMF_X509_DATAFORMAT_ENCODED;
1845 		subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val;
1846 		subjAltName.BERvalue.Length = extdata->bv_len;
1847 		ret = add_an_extension(extensions, &subjAltName);
1848 		if (ret != KMF_OK)
1849 			free(subjAltName.BERvalue.Data);
1850 	}
1851 
1852 	free(extdata);
1853 out:
1854 	if (olddata != NULL)
1855 		free(olddata);
1856 
1857 	KMF_FreeData(&dername);
1858 	if (ret != KMF_OK)
1859 		KMF_FreeData(&subjAltName.extnId);
1860 	if (asn1 != NULL)
1861 		kmfber_free(asn1, 1);
1862 	return (ret);
1863 }
1864