1/*
2 * Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/* $Id: win32.c,v 1.5 2009/10/26 23:47:35 tbox Exp $ */
18
19/* $Id */
20
21/*! \file */
22
23/* missing code for WIN32 */
24
25#include <windows.h>
26#include <string.h>
27
28#define HAVE_GETPASSPHRASE
29
30char *
31getpassphrase(const char *prompt)
32{
33	static char buf[128];
34	HANDLE h;
35	DWORD cc, mode;
36	int cnt;
37
38	h = GetStdHandle(STD_INPUT_HANDLE);
39	fputs(prompt, stderr);
40	fflush(stderr);
41	fflush(stdout);
42	FlushConsoleInputBuffer(h);
43	GetConsoleMode(h, &mode);
44	SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
45
46	for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
47	{
48		ReadFile(h, buf + cnt, 1, &cc, NULL);
49		if (buf[cnt] == '\r')
50			break;
51		fputc('*', stdout);
52		fflush(stderr);
53		fflush(stdout);
54	}
55
56	SetConsoleMode(h, mode);
57	buf[cnt] = '\0';
58	fputs("\n", stderr);
59	return buf;
60}
61
62/* From ISC isc_commandline_parse() */
63
64int optind = 1;		/* index into parent argv vector */
65int optopt;		/* character checked for validity */
66char *optarg;		/* argument associated with option */
67static char endopt = '\0';
68
69#define	BADOPT	(int)'?'
70#define	BADARG	(int)':'
71#define	ENDOPT	&endopt
72
73int
74getopt(int nargc, char * const nargv[], const char *ostr)
75{
76	static char *place = ENDOPT;		/* option letter processing */
77	char *option;				/* option letter list index */
78
79	if (*place == '\0') {			/* update scanning pointer */
80		place = nargv[optind];
81		if (optind >= nargc || *place++ != '-') {
82			/* index out of range or points to non-option */
83			place = ENDOPT;
84			return (-1);
85		}
86		optopt = *place++;
87		if (optopt == '-' && *place == '\0') {
88			/* "--" signals end of options */
89			++optind;
90			place = ENDOPT;
91			return (-1);
92		}
93	} else
94		optopt = *place++;
95
96	/* See if option letter is one the caller wanted... */
97	if (optopt == ':' || (option = strchr(ostr, optopt)) == NULL) {
98		if (*place == '\0')
99			++optind;
100		return (BADOPT);
101	}
102
103	if (*++option != ':') {
104		/* option doesn't take an argument */
105		optarg = NULL;
106		if (*place == '\0')
107			++optind;
108	} else {
109		/* option needs an argument */
110		if (*place != '\0')
111			/* -D1 style */
112			optarg = place;
113		else if (nargc > ++optind)
114			/* -D 1 style */
115			optarg = nargv[optind];
116		else {
117			/* needed but absent */
118			place = ENDOPT;
119			if (*ostr == ':')
120				return (BADARG);
121			return (BADOPT);
122		}
123		place = ENDOPT;
124		++optind;
125	}
126	return (optopt);
127}
128
129/* load PKCS11 DLL */
130
131#ifndef PK11_LIB_LOCATION
132#error "PK11_LIB_LOCATION is not defined"
133#endif
134
135const char *pk11_libname = PK11_LIB_LOCATION ".dll";
136
137HINSTANCE hPK11 = NULL;
138
139#define C_Initialize isc_C_Initialize
140
141CK_RV
142C_Initialize(CK_VOID_PTR pReserved)
143{
144	CK_C_Initialize sym;
145
146	if (pk11_libname == NULL)
147		return 0xfe;
148	/* Visual Studio convertion issue... */
149	if (*pk11_libname == ' ')
150		pk11_libname++;
151
152	hPK11 = LoadLibraryA(pk11_libname);
153
154	if (hPK11 == NULL)
155		return 0xfe;
156	sym = (CK_C_Initialize)GetProcAddress(hPK11, "C_Initialize");
157	if (sym == NULL)
158		return 0xff;
159	return (*sym)(pReserved);
160}
161
162#define C_Finalize isc_C_Finalize
163
164CK_RV
165C_Finalize(CK_VOID_PTR pReserved)
166{
167	CK_C_Finalize sym;
168
169	if (hPK11 == NULL)
170		return 0xfe;
171	sym = (CK_C_Finalize)GetProcAddress(hPK11, "C_Finalize");
172	if (sym == NULL)
173		return 0xff;
174	return (*sym)(pReserved);
175}
176
177#define C_OpenSession isc_C_OpenSession
178
179CK_RV
180C_OpenSession(CK_SLOT_ID slotID,
181	      CK_FLAGS flags,
182	      CK_VOID_PTR pApplication,
183	      CK_RV  (*Notify) (CK_SESSION_HANDLE hSession,
184				CK_NOTIFICATION event,
185				CK_VOID_PTR pApplication),
186	      CK_SESSION_HANDLE_PTR phSession)
187{
188	CK_C_OpenSession sym;
189
190	if (hPK11 == NULL)
191		hPK11 = LoadLibraryA(pk11_libname);
192	if (hPK11 == NULL)
193		return 0xfe;
194	sym = (CK_C_OpenSession)GetProcAddress(hPK11, "C_OpenSession");
195	if (sym == NULL)
196		return 0xff;
197	return (*sym)(slotID, flags, pApplication, Notify, phSession);
198}
199
200#define C_CloseSession isc_C_CloseSession
201
202CK_RV
203C_CloseSession(CK_SESSION_HANDLE hSession)
204{
205	CK_C_CloseSession sym;
206
207	if (hPK11 == NULL)
208		return 0xfe;
209	sym = (CK_C_CloseSession)GetProcAddress(hPK11, "C_CloseSession");
210	if (sym == NULL)
211		return 0xff;
212	return (*sym)(hSession);
213}
214
215#define C_Login isc_C_Login
216
217CK_RV
218C_Login(CK_SESSION_HANDLE hSession,
219	CK_USER_TYPE userType,
220	CK_CHAR_PTR pPin,
221	CK_ULONG usPinLen)
222{
223	CK_C_Login sym;
224
225	if (hPK11 == NULL)
226		return 0xfe;
227	sym = (CK_C_Login)GetProcAddress(hPK11, "C_Login");
228	if (sym == NULL)
229		return 0xff;
230	return (*sym)(hSession, userType, pPin, usPinLen);
231}
232
233#define C_CreateObject isc_C_CreateObject
234
235CK_RV
236C_CreateObject(CK_SESSION_HANDLE hSession,
237	       CK_ATTRIBUTE_PTR pTemplate,
238	       CK_ULONG usCount,
239	       CK_OBJECT_HANDLE_PTR phObject)
240{
241	CK_C_CreateObject sym;
242
243	if (hPK11 == NULL)
244		return 0xfe;
245	sym = (CK_C_CreateObject)GetProcAddress(hPK11, "C_CreateObject");
246	if (sym == NULL)
247		return 0xff;
248	return (*sym)(hSession, pTemplate, usCount, phObject);
249}
250
251#define C_DestroyObject isc_C_DestroyObject
252
253CK_RV
254C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
255{
256	CK_C_DestroyObject sym;
257
258	if (hPK11 == NULL)
259		return 0xfe;
260	sym = (CK_C_DestroyObject)GetProcAddress(hPK11, "C_DestroyObject");
261	if (sym == NULL)
262		return 0xff;
263	return (*sym)(hSession, hObject);
264}
265
266#define C_GetAttributeValue isc_C_GetAttributeValue
267
268CK_RV
269C_GetAttributeValue(CK_SESSION_HANDLE hSession,
270		    CK_OBJECT_HANDLE hObject,
271		    CK_ATTRIBUTE_PTR pTemplate,
272		    CK_ULONG usCount)
273{
274	CK_C_GetAttributeValue sym;
275
276	if (hPK11 == NULL)
277		return 0xfe;
278	sym = (CK_C_GetAttributeValue)GetProcAddress(hPK11,
279						     "C_GetAttributeValue");
280	if (sym == NULL)
281		return 0xff;
282	return (*sym)(hSession, hObject, pTemplate, usCount);
283}
284
285#define C_SetAttributeValue isc_C_SetAttributeValue
286
287CK_RV
288C_SetAttributeValue(CK_SESSION_HANDLE hSession,
289		    CK_OBJECT_HANDLE hObject,
290		    CK_ATTRIBUTE_PTR pTemplate,
291		    CK_ULONG usCount)
292{
293	CK_C_SetAttributeValue sym;
294
295	if (hPK11 == NULL)
296		return 0xfe;
297	sym = (CK_C_SetAttributeValue)GetProcAddress(hPK11,
298						     "C_SetAttributeValue");
299	if (sym == NULL)
300		return 0xff;
301	return (*sym)(hSession, hObject, pTemplate, usCount);
302}
303
304#define C_FindObjectsInit isc_C_FindObjectsInit
305
306CK_RV
307C_FindObjectsInit(CK_SESSION_HANDLE hSession,
308		  CK_ATTRIBUTE_PTR pTemplate,
309		  CK_ULONG usCount)
310{
311	CK_C_FindObjectsInit sym;
312
313	if (hPK11 == NULL)
314		return 0xfe;
315	sym = (CK_C_FindObjectsInit)GetProcAddress(hPK11,
316						   "C_FindObjectsInit");
317	if (sym == NULL)
318		return 0xff;
319	return (*sym)(hSession, pTemplate, usCount);
320}
321
322#define C_FindObjects isc_C_FindObjects
323
324CK_RV
325C_FindObjects(CK_SESSION_HANDLE hSession,
326	      CK_OBJECT_HANDLE_PTR phObject,
327	      CK_ULONG usMaxObjectCount,
328	      CK_ULONG_PTR pusObjectCount)
329{
330	CK_C_FindObjects sym;
331
332	if (hPK11 == NULL)
333		return 0xfe;
334	sym = (CK_C_FindObjects)GetProcAddress(hPK11, "C_FindObjects");
335	if (sym == NULL)
336		return 0xff;
337	return (*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount);
338}
339
340#define C_FindObjectsFinal isc_C_FindObjectsFinal
341
342CK_RV
343C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
344{
345	CK_C_FindObjectsFinal sym;
346
347	if (hPK11 == NULL)
348		return 0xfe;
349	sym = (CK_C_FindObjectsFinal)GetProcAddress(hPK11,
350						    "C_FindObjectsFinal");
351	if (sym == NULL)
352		return 0xff;
353	return (*sym)(hSession);
354}
355
356#define C_GenerateKeyPair isc_C_GenerateKeyPair
357
358CK_RV
359C_GenerateKeyPair(CK_SESSION_HANDLE hSession,
360		  CK_MECHANISM_PTR pMechanism,
361		  CK_ATTRIBUTE_PTR pPublicKeyTemplate,
362		  CK_ULONG usPublicKeyAttributeCount,
363		  CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
364		  CK_ULONG usPrivateKeyAttributeCount,
365		  CK_OBJECT_HANDLE_PTR phPrivateKey,
366		  CK_OBJECT_HANDLE_PTR phPublicKey)
367{
368	CK_C_GenerateKeyPair sym;
369
370	if (hPK11 == NULL)
371		return 0xfe;
372	sym = (CK_C_GenerateKeyPair)GetProcAddress(hPK11,
373						   "C_GenerateKeyPair");
374	if (sym == NULL)
375		return 0xff;
376	return (*sym)(hSession,
377		      pMechanism,
378		      pPublicKeyTemplate,
379		      usPublicKeyAttributeCount,
380		      pPrivateKeyTemplate,
381		      usPrivateKeyAttributeCount,
382		      phPrivateKey,
383		      phPublicKey);
384}
385