1#!perl
2#
3# This Source Code Form is subject to the terms of the Mozilla Public
4# License, v. 2.0. If a copy of the MPL was not distributed with this
5# file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7$copyright = '/* THIS IS A GENERATED FILE */
8/* This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11';
12
13$count = -1;
14$i = 0;
15
16open(INPUT, "<$ARGV[0]") || die "Can't open $ARGV[0]: $!";
17
18while(<INPUT>) {
19  s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
20  next if (/^\s*$/);
21
22#  print;
23
24  /^([\S]+)\s+([^"][\S]*|"[^"]*")/;
25  $name = $1;
26  $value = $2;
27
28  if( ($name =~ "FUNCTION") && !($name =~ "CK_FUNCTION") ) {
29    $count++;
30    $x[$count]{name} = $value;
31    $i = 0;
32  } else {
33    if( $count < 0 ) {
34      $value =~ s/"//g;
35      $g{$name} = $value;
36    } else {
37      $x[$count]{args}[$i]{type} = $name;
38      $x[$count]{args}[$i]{name} = $value;
39      $i++;
40      $x[$count]{nargs} = $i; # rewritten each time, oh well
41    }
42  }
43}
44
45close INPUT;
46
47# dodump();
48doprint();
49
50sub dodump {
51  for( $j = 0; $j <= $count; $j++ ) {
52    print "CK_RV CK_ENTRY $x[$j]{name}\n";
53    for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
54      print "  $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
55      if( $i == ($x[$j]{nargs} - 1) ) {
56        print "\n";
57      } else {
58        print ",\n";
59      }
60    }
61  }
62}
63
64sub doprint {
65open(PROTOTYPE, ">nssckg.h") || die "Can't open nssckg.h: $!";
66open(TYPEDEF, ">nssckft.h") || die "Can't open nssckft.h: $!";
67open(EPV, ">nssckepv.h") || die "Can't open nssckepv.h: $!";
68open(API, ">nssck.api") || die "Can't open nssck.api: $!";
69
70select PROTOTYPE;
71
72print $copyright;
73print <<EOD
74#ifndef NSSCKG_H
75#define NSSCKG_H
76
77/*
78 * nssckg.h
79 *
80 * This automatically-generated header file prototypes the Cryptoki
81 * functions specified by PKCS#11.
82 */
83
84#ifndef NSSCKT_H
85#include "nssckt.h"
86#endif /* NSSCKT_H */
87
88EOD
89    ;
90
91for( $j = 0; $j <= $count; $j++ ) {
92  print "CK_RV CK_ENTRY $x[$j]{name}\n";
93  print "(\n";
94  for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
95    print "  $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
96    if( $i == ($x[$j]{nargs} - 1) ) {
97      print "\n";
98    } else {
99      print ",\n";
100    }
101  }
102  print ");\n\n";
103}
104
105print <<EOD
106#endif /* NSSCKG_H */
107EOD
108    ;
109
110select TYPEDEF;
111
112print $copyright;
113print <<EOD
114#ifndef NSSCKFT_H
115#define NSSCKFT_H
116
117/*
118 * nssckft.h
119 *
120 * The automatically-generated header file declares a typedef
121 * each of the Cryptoki functions specified by PKCS#11.
122 */
123
124#ifndef NSSCKT_H
125#include "nssckt.h"
126#endif /* NSSCKT_H */
127
128EOD
129    ;
130
131for( $j = 0; $j <= $count; $j++ ) {
132#  print "typedef CK_RV (CK_ENTRY *CK_$x[$j]{name})(\n";
133  print "typedef CK_CALLBACK_FUNCTION(CK_RV, CK_$x[$j]{name})(\n";
134  for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
135    print "  $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
136    if( $i == ($x[$j]{nargs} - 1) ) {
137      print "\n";
138    } else {
139      print ",\n";
140    }
141  }
142  print ");\n\n";
143}
144
145print <<EOD
146#endif /* NSSCKFT_H */
147EOD
148    ;
149
150select EPV;
151
152print $copyright;
153print <<EOD
154#ifndef NSSCKEPV_H
155#define NSSCKEPV_H
156
157/*
158 * nssckepv.h
159 *
160 * This automatically-generated header file defines the type
161 * CK_FUNCTION_LIST specified by PKCS#11.
162 */
163
164#ifndef NSSCKT_H
165#include "nssckt.h"
166#endif /* NSSCKT_H */
167
168#ifndef NSSCKFT_H
169#include "nssckft.h"
170#endif /* NSSCKFT_H */
171
172#include "nssckp.h"
173
174struct CK_FUNCTION_LIST {
175  CK_VERSION version;
176EOD
177    ;
178
179for( $j = 0; $j <= $count; $j++ ) {
180  print "  CK_$x[$j]{name} $x[$j]{name};\n";
181}
182
183print <<EOD
184};
185
186#include "nsscku.h"
187
188#endif /* NSSCKEPV_H */
189EOD
190    ;
191
192select API;
193
194print $copyright;
195print <<EOD
196
197/*
198 * nssck.api
199 *
200 * This automatically-generated file is used to generate a set of
201 * Cryptoki entry points within the object space of a Module using
202 * the NSS Cryptoki Framework.
203 *
204 * The Module should have a .c file with the following:
205 *
206 *  #define MODULE_NAME name
207 *  #define INSTANCE_NAME instance
208 *  #include "nssck.api"
209 *
210 * where "name" is some module-specific name that can be used to
211 * disambiguate various modules.  This included file will then
212 * define the actual Cryptoki routines which pass through to the
213 * Framework calls.  All routines, except C_GetFunctionList, will
214 * be prefixed with the name; C_GetFunctionList will be generated
215 * to return an entry-point vector with these routines.  The
216 * instance specified should be the basic instance of NSSCKMDInstance.
217 *
218 * If, prior to including nssck.api, the .c file also specifies
219 *
220 *  #define DECLARE_STRICT_CRYTPOKI_NAMES
221 *
222 * Then a set of "stub" routines not prefixed with the name will
223 * be included.  This would allow the combined module and framework
224 * to be used in applications which are hard-coded to use the
225 * PKCS#11 names (instead of going through the EPV).  Please note
226 * that such applications should be careful resolving symbols when
227 * more than one PKCS#11 module is loaded.
228 */
229
230#ifndef MODULE_NAME
231#error "Error: MODULE_NAME must be defined."
232#endif /* MODULE_NAME */
233
234#ifndef INSTANCE_NAME
235#error "Error: INSTANCE_NAME must be defined."
236#endif /* INSTANCE_NAME */
237
238#ifndef NSSCKT_H
239#include "nssckt.h"
240#endif /* NSSCKT_H */
241
242#ifndef NSSCKFWT_H
243#include "nssckfwt.h"
244#endif /* NSSCKFWT_H */
245
246#ifndef NSSCKFWC_H
247#include "nssckfwc.h"
248#endif /* NSSCKFWC_H */
249
250#ifndef NSSCKEPV_H
251#include "nssckepv.h"
252#endif /* NSSCKEPV_H */
253
254#define ADJOIN(x,y) x##y
255
256#define __ADJOIN(x,y) ADJOIN(x,y)
257
258/*
259 * The anchor.  This object is used to store an "anchor" pointer in
260 * the Module's object space, so the wrapper functions can relate
261 * back to this instance.
262 */
263
264static NSSCKFWInstance *fwInstance = (NSSCKFWInstance *)0;
265
266static CK_RV CK_ENTRY
267__ADJOIN(MODULE_NAME,C_Initialize)
268(
269  CK_VOID_PTR pInitArgs
270)
271{
272  return NSSCKFWC_Initialize(&fwInstance, INSTANCE_NAME, pInitArgs);
273}
274
275#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
276CK_RV CK_ENTRY
277C_Initialize
278(
279  CK_VOID_PTR pInitArgs
280)
281{
282  return __ADJOIN(MODULE_NAME,C_Initialize)(pInitArgs);
283}
284#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
285
286static CK_RV CK_ENTRY
287__ADJOIN(MODULE_NAME,C_Finalize)
288(
289  CK_VOID_PTR pReserved
290)
291{
292  return NSSCKFWC_Finalize(&fwInstance);
293}
294
295#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
296CK_RV CK_ENTRY
297C_Finalize
298(
299  CK_VOID_PTR pReserved
300)
301{
302  return __ADJOIN(MODULE_NAME,C_Finalize)(pReserved);
303}
304#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
305
306static CK_RV CK_ENTRY
307__ADJOIN(MODULE_NAME,C_GetInfo)
308(
309  CK_INFO_PTR pInfo
310)
311{
312  return NSSCKFWC_GetInfo(fwInstance, pInfo);
313}
314
315#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
316CK_RV CK_ENTRY
317C_GetInfo
318(
319  CK_INFO_PTR pInfo
320)
321{
322  return __ADJOIN(MODULE_NAME,C_GetInfo)(pInfo);
323}
324#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
325
326/*
327 * C_GetFunctionList is defined at the end.
328 */
329
330EOD
331    ;
332
333for( $j = 4; $j <= $count; $j++ ) {
334  print "static CK_RV CK_ENTRY\n";
335  print "__ADJOIN(MODULE_NAME,$x[$j]{name})\n";
336  print "(\n";
337  for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
338    print "  $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
339    if( $i == ($x[$j]{nargs} - 1) ) {
340      print "\n";
341    } else {
342      print ",\n";
343    }
344  }
345  print ")\n";
346  print "{\n";
347  print "  return NSSCKFW$x[$j]{name}(fwInstance, ";
348  for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
349    print "$x[$j]{args}[$i]{name}";
350    if( $i == ($x[$j]{nargs} - 1) ) {
351      print ");\n";
352    } else {
353      print ", ";
354    }
355  }
356  print "}\n\n";
357
358  print "#ifdef DECLARE_STRICT_CRYPTOKI_NAMES\n";
359  print "CK_RV CK_ENTRY\n";
360  print "$x[$j]{name}\n";
361  print "(\n";
362  for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
363    print "  $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
364    if( $i == ($x[$j]{nargs} - 1) ) {
365      print "\n";
366    } else {
367      print ",\n";
368    }
369  }
370  print ")\n";
371  print "{\n";
372  print "  return __ADJOIN(MODULE_NAME,$x[$j]{name})(";
373  for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
374    print "$x[$j]{args}[$i]{name}";
375    if( $i == ($x[$j]{nargs} - 1) ) {
376      print ");\n";
377    } else {
378      print ", ";
379    }
380  }
381  print "}\n";
382  print "#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */\n\n";
383}
384
385print <<EOD
386static CK_RV CK_ENTRY
387__ADJOIN(MODULE_NAME,C_GetFunctionList)
388(
389  CK_FUNCTION_LIST_PTR_PTR ppFunctionList
390);
391
392static CK_FUNCTION_LIST FunctionList = {
393  { 2, 1 },
394EOD
395    ;
396
397for( $j = 0; $j <= $count; $j++ ) {
398  print "__ADJOIN(MODULE_NAME,$x[$j]{name})";
399  if( $j < $count ) {
400    print ",\n";
401  } else {
402    print "\n};\n\n";
403  }
404}
405
406print <<EOD
407static CK_RV CK_ENTRY
408__ADJOIN(MODULE_NAME,C_GetFunctionList)
409(
410  CK_FUNCTION_LIST_PTR_PTR ppFunctionList
411)
412{
413  *ppFunctionList = &FunctionList;
414  return CKR_OK;
415}
416
417/* This one is always present */
418CK_RV CK_ENTRY
419C_GetFunctionList
420(
421  CK_FUNCTION_LIST_PTR_PTR ppFunctionList
422)
423{
424  return __ADJOIN(MODULE_NAME,C_GetFunctionList)(ppFunctionList);
425}
426
427#undef __ADJOIN
428
429EOD
430    ;
431
432select STDOUT;
433
434}
435