gwenhywfar  4.99.8beta
cttest2.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id: main.c 1107 2007-01-07 21:17:05Z martin $
5  begin : Tue May 03 2005
6  copyright : (C) 2005 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * Please see toplevel file COPYING for license details *
11  ***************************************************************************/
12 
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
16 
17 #include <gwenhywfar/debug.h>
18 #include <gwenhywfar/pathmanager.h>
19 #include <gwenhywfar/cgui.h>
20 
21 #include <gwenhywfar/gwenhywfar.h>
22 #include <gwenhywfar/args.h>
23 #include <gwenhywfar/logger.h>
24 #include <gwenhywfar/db.h>
25 #include <gwenhywfar/misc.h>
26 #include <gwenhywfar/misc2.h>
27 #include <gwenhywfar/inherit.h>
28 #include <gwenhywfar/crypttoken.h>
29 #include <gwenhywfar/ct.h>
30 #include <gwenhywfar/ctplugin.h>
31 #include <gwenhywfar/text.h>
32 #include <gwenhywfar/mdigest.h>
33 
34 #include "src/base/i18n_l.h"
35 
36 #ifdef OS_WIN32
37 # define DIRSEP "\\"
38 #else
39 # define DIRSEP "/"
40 #endif
41 
42 #ifdef HAVE_I18N
43 # include <libintl.h>
44 # include <locale.h>
45 #endif
46 
47 
48 #define GCT_LOGDOMAIN "GCT"
49 
50 //#define DEBUG_GCT_TOOL
51 
52 
53 int signWithOld(GWEN_DB_NODE *dbArgs, int argc, char **argv) {
54  GWEN_DB_NODE *db;
55  const char *ttype;
56  const char *tname;
58  GWEN_PLUGIN *pl;
59  GWEN_CRYPTTOKEN *ct;
60  unsigned int ucid;
61  int rv;
62  const GWEN_ARGS args[]={
63  {
64  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
65  GWEN_ArgsType_Int, /* type */
66  "userContextId", /* name */
67  0, /* minnum */
68  1, /* maxnum */
69  "i", /* short option */
70  "id", /* long option */
71  "User context id (0 for any)",/* short description */
72  "User context id (0 for any)" /* long description */
73  },
74  {
75  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
76  GWEN_ArgsType_Char, /* type */
77  "tokenType", /* name */
78  1, /* minnum */
79  1, /* maxnum */
80  "t", /* short option */
81  "ttype", /* long option */
82  "Specify the crypt token type", /* short description */
83  "Specify the crypt token type" /* long description */
84  },
85  {
86  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
87  GWEN_ArgsType_Char, /* type */
88  "tokenName", /* name */
89  0, /* minnum */
90  1, /* maxnum */
91  "n", /* short option */
92  "tname", /* long option */
93  "Specify the crypt token name", /* short description */
94  "Specify the crypt token name" /* long description */
95  },
96  {
98  GWEN_ArgsType_Int, /* type */
99  "help", /* name */
100  0, /* minnum */
101  0, /* maxnum */
102  "h", /* short option */
103  "help", /* long option */
104  "Show this help screen", /* short description */
105  "Show this help screen" /* long description */
106  }
107  };
108 
109  db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
110  rv=GWEN_Args_Check(argc, argv, 1,
112  args,
113  db);
114  if (rv==GWEN_ARGS_RESULT_ERROR) {
115  fprintf(stderr, "ERROR: Could not parse arguments\n");
116  return 1;
117  }
118  else if (rv==GWEN_ARGS_RESULT_HELP) {
119  GWEN_BUFFER *ubuf;
120 
121  ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
122  if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
123  fprintf(stderr, "ERROR: Could not create help string\n");
124  return 1;
125  }
126  fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
127  GWEN_Buffer_free(ubuf);
128  return 0;
129  }
130 
131  ucid=GWEN_DB_GetIntValue(db, "userContextId", 0, 0);
132 
133  ttype=GWEN_DB_GetCharValue(db, "tokenType", 0, 0);
134  assert(ttype);
135 
136  tname=GWEN_DB_GetCharValue(db, "tokenName", 0, 0);
137 
138  /* get crypt token */
139  pm=GWEN_PluginManager_FindPluginManager("crypttoken");
140  if (pm==0) {
141  DBG_ERROR(0, "Plugin manager not found");
142  return 3;
143  }
144 
145  pl=GWEN_PluginManager_GetPlugin(pm, ttype);
146  if (pl==0) {
147  DBG_ERROR(0, "Plugin not found");
148  return 3;
149  }
150  DBG_INFO(0, "Plugin found");
151 
152  ct=GWEN_CryptToken_Plugin_CreateToken(pl, 0, tname);
153  if (ct==0) {
154  DBG_ERROR(0, "Could not create crypt token");
155  return 3;
156  }
157 
158  if (GWEN_DB_GetIntValue(dbArgs, "forcePin", 0, 0))
159  GWEN_CryptToken_AddModes(ct, GWEN_CRYPTTOKEN_MODES_FORCE_PIN_ENTRY);
160 
161  /* open crypt token for use */
162  rv=GWEN_CryptToken_Open(ct, 0);
163  if (rv) {
164  DBG_ERROR(0, "Could not open token");
165  return 3;
166  }
167  else {
168  GWEN_BUFFER *dstBuf;
169  const GWEN_CRYPTTOKEN_CONTEXT *octx;
170  GWEN_CRYPTTOKEN_CONTEXT *ctx;
171  GWEN_CRYPTTOKEN_SIGNINFO *si;
172  uint8_t clearText[96]={
173  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
174  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
175  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
176  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
177  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
178  0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
179  0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
180  0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
181  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
182  0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
183  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
184  0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60
185  };
186 
187  octx=GWEN_CryptToken_GetContextById(ct, 0x01);
188  if (octx==NULL) {
189  DBG_ERROR(0, "Context not found");
190  return 3;
191  }
192 
193  /* prepare context */
194  ctx=GWEN_CryptToken_Context_dup(octx);
195  si=GWEN_CryptToken_Context_GetSignInfo(ctx);
196  GWEN_CryptToken_SignInfo_SetHashAlgo(si, GWEN_CryptToken_HashAlgo_None);
197  GWEN_CryptToken_SignInfo_SetPaddAlgo(si, GWEN_CryptToken_PaddAlgo_None);
198 
199  dstBuf=GWEN_Buffer_new(0, 256, 0, 1);
200  rv=GWEN_CryptToken_Sign(ct, ctx, (const char*)clearText, 96, dstBuf);
201  if (rv) {
202  DBG_ERROR(0, "Could not sign data (%d)", rv);
203  return 3;
204  }
205  fprintf(stderr, "Signature is:\n");
207  GWEN_Buffer_GetUsedBytes(dstBuf),
208  stderr, 2);
209  GWEN_Buffer_free(dstBuf);
210  }
211 
212 
213  /* close crypt token */
214  rv=GWEN_CryptToken_Close(ct);
215  if (rv) {
216  DBG_ERROR(0, "Could not close token");
217  return 3;
218  }
219 
220  return 0;
221 }
222 
223 
224 
225 
226 int signWithNew(GWEN_DB_NODE *dbArgs, int argc, char **argv) {
227  GWEN_DB_NODE *db;
228  const char *ttype;
229  const char *tname;
231  GWEN_PLUGIN *pl;
232  GWEN_CRYPT_TOKEN *ct;
233  unsigned int cid;
234  int rv;
235  const GWEN_ARGS args[]={
236  {
237  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
238  GWEN_ArgsType_Int, /* type */
239  "contextId", /* name */
240  0, /* minnum */
241  1, /* maxnum */
242  "i", /* short option */
243  "id", /* long option */
244  "Context id (0 for any)", /* short description */
245  "Context id (0 for any)" /* long description */
246  },
247  {
248  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
249  GWEN_ArgsType_Char, /* type */
250  "tokenType", /* name */
251  1, /* minnum */
252  1, /* maxnum */
253  "t", /* short option */
254  "ttype", /* long option */
255  "Specify the crypt token type", /* short description */
256  "Specify the crypt token type" /* long description */
257  },
258  {
259  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
260  GWEN_ArgsType_Char, /* type */
261  "tokenName", /* name */
262  0, /* minnum */
263  1, /* maxnum */
264  "n", /* short option */
265  "tname", /* long option */
266  "Specify the crypt token name", /* short description */
267  "Specify the crypt token name" /* long description */
268  },
269  {
271  GWEN_ArgsType_Int, /* type */
272  "help", /* name */
273  0, /* minnum */
274  0, /* maxnum */
275  "h", /* short option */
276  "help", /* long option */
277  "Show this help screen", /* short description */
278  "Show this help screen" /* long description */
279  }
280  };
281 
282  db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
283  rv=GWEN_Args_Check(argc, argv, 1,
285  args,
286  db);
287  if (rv==GWEN_ARGS_RESULT_ERROR) {
288  fprintf(stderr, "ERROR: Could not parse arguments\n");
289  return 1;
290  }
291  else if (rv==GWEN_ARGS_RESULT_HELP) {
292  GWEN_BUFFER *ubuf;
293 
294  ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
295  if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
296  fprintf(stderr, "ERROR: Could not create help string\n");
297  return 1;
298  }
299  fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
300  GWEN_Buffer_free(ubuf);
301  return 0;
302  }
303 
304  cid=GWEN_DB_GetIntValue(db, "contextId", 0, 0);
305 
306  ttype=GWEN_DB_GetCharValue(db, "tokenType", 0, 0);
307  assert(ttype);
308 
309  tname=GWEN_DB_GetCharValue(db, "tokenName", 0, 0);
310 
311  /* get crypt token */
313  if (pm==0) {
314  DBG_ERROR(0, "Plugin manager not found");
315  return 3;
316  }
317 
318  pl=GWEN_PluginManager_GetPlugin(pm, ttype);
319  if (pl==0) {
320  DBG_ERROR(0, "Plugin not found");
321  return 3;
322  }
323  DBG_INFO(0, "Plugin found");
324 
326  if (ct==0) {
327  DBG_ERROR(0, "Could not create crypt token");
328  return 3;
329  }
330 
331  if (GWEN_DB_GetIntValue(dbArgs, "forcePin", 0, 0))
333 
334  /* open crypt token for use */
335  rv=GWEN_Crypt_Token_Open(ct, 0, 0);
336  if (rv) {
337  DBG_ERROR(0, "Could not open token");
338  return 3;
339  }
340  else {
341  uint8_t clearText[96]={
342  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
343  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
344  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
345  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
346  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
347  0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
348  0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
349  0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
350  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
351  0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
352  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
353  0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60
354  };
355  uint8_t signature[256];
356  uint32_t signLen;
357  GWEN_CRYPT_PADDALGO *algo;
358 
359  algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None);
360  signLen=sizeof(signature);
361  rv=GWEN_Crypt_Token_Sign(ct,
362  0x01, /* local sign key */
363  algo,
364  clearText,
365  96,
366  signature,
367  &signLen,
368  NULL,
369  0);
370  if (rv) {
371  DBG_ERROR(0, "Could not sign data (%d)", rv);
372  return 3;
373  }
374 
375  fprintf(stderr, "Signature is:\n");
376  GWEN_Text_DumpString((const char*) signature, signLen, stderr, 2);
377 
378  rv=GWEN_Crypt_Token_Verify(ct, 0x01,
379  algo,
380  clearText,
381  96,
382  signature,
383  signLen,
384  0,
385  0);
386  if (rv) {
387  DBG_ERROR(0, "Could not verify data (%d)", rv);
388  return 3;
389  }
390  fprintf(stderr, "Signature is ok.\n");
391 
392  }
393 
394  /* close crypt token */
395  rv=GWEN_Crypt_Token_Close(ct, 0, 0);
396  if (rv) {
397  DBG_ERROR(0, "Could not close token");
398  return 3;
399  }
400 
401  return 0;
402 }
403 
404 
405 
406 int cryptWithOld(GWEN_DB_NODE *dbArgs, int argc, char **argv) {
407  GWEN_DB_NODE *db;
408  const char *ttype;
409  const char *tname;
411  GWEN_PLUGIN *pl;
412  GWEN_CRYPTTOKEN *ct;
413  unsigned int ucid;
414  int rv;
415  const GWEN_ARGS args[]={
416  {
417  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
418  GWEN_ArgsType_Int, /* type */
419  "userContextId", /* name */
420  0, /* minnum */
421  1, /* maxnum */
422  "i", /* short option */
423  "id", /* long option */
424  "User context id (0 for any)",/* short description */
425  "User context id (0 for any)" /* long description */
426  },
427  {
428  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
429  GWEN_ArgsType_Char, /* type */
430  "tokenType", /* name */
431  1, /* minnum */
432  1, /* maxnum */
433  "t", /* short option */
434  "ttype", /* long option */
435  "Specify the crypt token type", /* short description */
436  "Specify the crypt token type" /* long description */
437  },
438  {
439  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
440  GWEN_ArgsType_Char, /* type */
441  "tokenName", /* name */
442  0, /* minnum */
443  1, /* maxnum */
444  "n", /* short option */
445  "tname", /* long option */
446  "Specify the crypt token name", /* short description */
447  "Specify the crypt token name" /* long description */
448  },
449  {
451  GWEN_ArgsType_Int, /* type */
452  "help", /* name */
453  0, /* minnum */
454  0, /* maxnum */
455  "h", /* short option */
456  "help", /* long option */
457  "Show this help screen", /* short description */
458  "Show this help screen" /* long description */
459  }
460  };
461 
462  db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
463  rv=GWEN_Args_Check(argc, argv, 1,
465  args,
466  db);
467  if (rv==GWEN_ARGS_RESULT_ERROR) {
468  fprintf(stderr, "ERROR: Could not parse arguments\n");
469  return 1;
470  }
471  else if (rv==GWEN_ARGS_RESULT_HELP) {
472  GWEN_BUFFER *ubuf;
473 
474  ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
475  if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
476  fprintf(stderr, "ERROR: Could not create help string\n");
477  return 1;
478  }
479  fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
480  GWEN_Buffer_free(ubuf);
481  return 0;
482  }
483 
484  ucid=GWEN_DB_GetIntValue(db, "userContextId", 0, 0);
485 
486  ttype=GWEN_DB_GetCharValue(db, "tokenType", 0, 0);
487  assert(ttype);
488 
489  tname=GWEN_DB_GetCharValue(db, "tokenName", 0, 0);
490 
491  /* get crypt token */
492  pm=GWEN_PluginManager_FindPluginManager("crypttoken");
493  if (pm==0) {
494  DBG_ERROR(0, "Plugin manager not found");
495  return 3;
496  }
497 
498  pl=GWEN_PluginManager_GetPlugin(pm, ttype);
499  if (pl==0) {
500  DBG_ERROR(0, "Plugin not found");
501  return 3;
502  }
503  DBG_INFO(0, "Plugin found");
504 
505  ct=GWEN_CryptToken_Plugin_CreateToken(pl, 0, tname);
506  if (ct==0) {
507  DBG_ERROR(0, "Could not create crypt token");
508  return 3;
509  }
510 
511  if (GWEN_DB_GetIntValue(dbArgs, "forcePin", 0, 0))
512  GWEN_CryptToken_AddModes(ct, GWEN_CRYPTTOKEN_MODES_FORCE_PIN_ENTRY);
513 
514  /* open crypt token for use */
515  rv=GWEN_CryptToken_Open(ct, 0);
516  if (rv) {
517  DBG_ERROR(0, "Could not open token");
518  return 3;
519  }
520  else {
521  GWEN_BUFFER *dstBuf;
522  const GWEN_CRYPTTOKEN_CONTEXT *octx;
523  GWEN_CRYPTTOKEN_CONTEXT *ctx;
524  GWEN_CRYPTTOKEN_CRYPTINFO *ci;
525  //GWEN_CRYPTTOKEN_KEYINFO *ki;
526  uint8_t clearText[96]={
527  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
528  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
529  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
530  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
531  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
532  0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
533  0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
534  0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
535  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
536  0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
537  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
538  0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60
539  };
540 
541  octx=GWEN_CryptToken_GetContextById(ct, 0x01);
542  if (octx==NULL) {
543  DBG_ERROR(0, "Context not found");
544  return 3;
545  }
546 
547  /* prepare context */
548  ctx=GWEN_CryptToken_Context_dup(octx);
549  ci=GWEN_CryptToken_Context_GetCryptInfo(ctx);
550  GWEN_CryptToken_CryptInfo_SetPaddAlgo(ci, GWEN_CryptToken_PaddAlgo_None);
551  //ki=GWEN_CryptToken_Context_GetEncryptKeyInfo(ctx);
552  //GWEN_CryptToken_KeyInfo_SetKeyId(ki, 0x02);
553 
554  dstBuf=GWEN_Buffer_new(0, 256, 0, 1);
555  rv=GWEN_CryptToken_Encrypt(ct, ctx, (const char*)clearText, 96, dstBuf);
556  if (rv) {
557  DBG_ERROR(0, "Could not encrypt data (%d)", rv);
558  return 3;
559  }
560  fprintf(stderr, "Result is:\n");
562  GWEN_Buffer_GetUsedBytes(dstBuf),
563  stderr, 2);
564  GWEN_Buffer_free(dstBuf);
565  }
566 
567 
568  /* close crypt token */
569  rv=GWEN_CryptToken_Close(ct);
570  if (rv) {
571  DBG_ERROR(0, "Could not close token");
572  return 3;
573  }
574 
575  return 0;
576 }
577 
578 
579 
580 int cryptWithNew(GWEN_DB_NODE *dbArgs, int argc, char **argv) {
581  GWEN_DB_NODE *db;
582  const char *ttype;
583  const char *tname;
585  GWEN_PLUGIN *pl;
586  GWEN_CRYPT_TOKEN *ct;
587  unsigned int cid;
588  int rv;
589  const GWEN_ARGS args[]={
590  {
591  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
592  GWEN_ArgsType_Int, /* type */
593  "contextId", /* name */
594  0, /* minnum */
595  1, /* maxnum */
596  "i", /* short option */
597  "id", /* long option */
598  "Context id (0 for any)", /* short description */
599  "Context id (0 for any)" /* long description */
600  },
601  {
602  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
603  GWEN_ArgsType_Char, /* type */
604  "tokenType", /* name */
605  1, /* minnum */
606  1, /* maxnum */
607  "t", /* short option */
608  "ttype", /* long option */
609  "Specify the crypt token type", /* short description */
610  "Specify the crypt token type" /* long description */
611  },
612  {
613  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
614  GWEN_ArgsType_Char, /* type */
615  "tokenName", /* name */
616  0, /* minnum */
617  1, /* maxnum */
618  "n", /* short option */
619  "tname", /* long option */
620  "Specify the crypt token name", /* short description */
621  "Specify the crypt token name" /* long description */
622  },
623  {
625  GWEN_ArgsType_Int, /* type */
626  "help", /* name */
627  0, /* minnum */
628  0, /* maxnum */
629  "h", /* short option */
630  "help", /* long option */
631  "Show this help screen", /* short description */
632  "Show this help screen" /* long description */
633  }
634  };
635 
636  db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
637  rv=GWEN_Args_Check(argc, argv, 1,
639  args,
640  db);
641  if (rv==GWEN_ARGS_RESULT_ERROR) {
642  fprintf(stderr, "ERROR: Could not parse arguments\n");
643  return 1;
644  }
645  else if (rv==GWEN_ARGS_RESULT_HELP) {
646  GWEN_BUFFER *ubuf;
647 
648  ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
649  if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
650  fprintf(stderr, "ERROR: Could not create help string\n");
651  return 1;
652  }
653  fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
654  GWEN_Buffer_free(ubuf);
655  return 0;
656  }
657 
658  cid=GWEN_DB_GetIntValue(db, "contextId", 0, 0);
659 
660  ttype=GWEN_DB_GetCharValue(db, "tokenType", 0, 0);
661  assert(ttype);
662 
663  tname=GWEN_DB_GetCharValue(db, "tokenName", 0, 0);
664 
665  /* get crypt token */
667  if (pm==0) {
668  DBG_ERROR(0, "Plugin manager not found");
669  return 3;
670  }
671 
672  pl=GWEN_PluginManager_GetPlugin(pm, ttype);
673  if (pl==0) {
674  DBG_ERROR(0, "Plugin not found");
675  return 3;
676  }
677  DBG_INFO(0, "Plugin found");
678 
680  if (ct==0) {
681  DBG_ERROR(0, "Could not create crypt token");
682  return 3;
683  }
684 
685  if (GWEN_DB_GetIntValue(dbArgs, "forcePin", 0, 0))
687 
688  /* open crypt token for use */
689  rv=GWEN_Crypt_Token_Open(ct, 0, 0);
690  if (rv) {
691  DBG_ERROR(0, "Could not open token");
692  return 3;
693  }
694  else {
695  uint8_t clearText[96]={
696  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
697  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
698  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
699  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
700  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
701  0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
702  0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
703  0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
704  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
705  0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
706  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
707  0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60
708  };
709  uint8_t encrypted[128];
710  uint32_t elen;
711  GWEN_CRYPT_PADDALGO *algo;
712 
713  algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None);
714  elen=sizeof(encrypted);
716  0x04,
717  algo,
718  clearText,
719  96,
720  encrypted,
721  &elen,
722  0);
723  if (rv) {
724  DBG_ERROR(0, "Could not encipher data (%d)", rv);
725  return 3;
726  }
727 
728  fprintf(stderr, "Encrypted data is:\n");
729  GWEN_Text_DumpString((const char*) encrypted, elen, stderr, 2);
730  }
731 
732  /* close crypt token */
733  rv=GWEN_Crypt_Token_Close(ct, 0, 0);
734  if (rv) {
735  DBG_ERROR(0, "Could not close token");
736  return 3;
737  }
738 
739  return 0;
740 }
741 
742 
743 
744 int cryptWithNew2(GWEN_DB_NODE *dbArgs, int argc, char **argv) {
745  GWEN_DB_NODE *db;
746  const char *ttype;
747  const char *tname;
749  GWEN_PLUGIN *pl;
750  GWEN_CRYPT_TOKEN *ct;
751  unsigned int cid;
752  int rv;
753  const GWEN_ARGS args[]={
754  {
755  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
756  GWEN_ArgsType_Int, /* type */
757  "contextId", /* name */
758  0, /* minnum */
759  1, /* maxnum */
760  "i", /* short option */
761  "id", /* long option */
762  "Context id (0 for any)", /* short description */
763  "Context id (0 for any)" /* long description */
764  },
765  {
766  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
767  GWEN_ArgsType_Char, /* type */
768  "tokenType", /* name */
769  1, /* minnum */
770  1, /* maxnum */
771  "t", /* short option */
772  "ttype", /* long option */
773  "Specify the crypt token type", /* short description */
774  "Specify the crypt token type" /* long description */
775  },
776  {
777  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
778  GWEN_ArgsType_Char, /* type */
779  "tokenName", /* name */
780  0, /* minnum */
781  1, /* maxnum */
782  "n", /* short option */
783  "tname", /* long option */
784  "Specify the crypt token name", /* short description */
785  "Specify the crypt token name" /* long description */
786  },
787  {
789  GWEN_ArgsType_Int, /* type */
790  "help", /* name */
791  0, /* minnum */
792  0, /* maxnum */
793  "h", /* short option */
794  "help", /* long option */
795  "Show this help screen", /* short description */
796  "Show this help screen" /* long description */
797  }
798  };
799 
800  db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
801  rv=GWEN_Args_Check(argc, argv, 1,
803  args,
804  db);
805  if (rv==GWEN_ARGS_RESULT_ERROR) {
806  fprintf(stderr, "ERROR: Could not parse arguments\n");
807  return 1;
808  }
809  else if (rv==GWEN_ARGS_RESULT_HELP) {
810  GWEN_BUFFER *ubuf;
811 
812  ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
813  if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
814  fprintf(stderr, "ERROR: Could not create help string\n");
815  return 1;
816  }
817  fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
818  GWEN_Buffer_free(ubuf);
819  return 0;
820  }
821 
822  cid=GWEN_DB_GetIntValue(db, "contextId", 0, 0);
823 
824  ttype=GWEN_DB_GetCharValue(db, "tokenType", 0, 0);
825  assert(ttype);
826 
827  tname=GWEN_DB_GetCharValue(db, "tokenName", 0, 0);
828 
829  /* get crypt token */
831  if (pm==0) {
832  DBG_ERROR(0, "Plugin manager not found");
833  return 3;
834  }
835 
836  pl=GWEN_PluginManager_GetPlugin(pm, ttype);
837  if (pl==0) {
838  DBG_ERROR(0, "Plugin not found");
839  return 3;
840  }
841  DBG_INFO(0, "Plugin found");
842 
844  if (ct==0) {
845  DBG_ERROR(0, "Could not create crypt token");
846  return 3;
847  }
848 
849  if (GWEN_DB_GetIntValue(dbArgs, "forcePin", 0, 0))
851 
852  /* open crypt token for use */
853  rv=GWEN_Crypt_Token_Open(ct, 0, 0);
854  if (rv) {
855  DBG_ERROR(0, "Could not open token");
856  return 3;
857  }
858  else {
859  uint8_t clearText[96]={
860  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
861  0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
862  0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
863  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
864  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
865  0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
866  0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
867  0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
868  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
869  0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
870  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
871  0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60
872  };
873  uint8_t encrypted[128];
874  uint32_t elen;
875  uint8_t decrypted[128];
876  uint32_t dlen;
877  GWEN_CRYPT_PADDALGO *algo;
878 
879  algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None);
880  elen=sizeof(encrypted);
882  0x02,
883  algo,
884  clearText,
885  96,
886  encrypted,
887  &elen,
888  0);
889  if (rv) {
890  DBG_ERROR(0, "Could not encipher data (%d)", rv);
891  return 3;
892  }
893 
894  fprintf(stderr, "Encrypted data is:\n");
895  GWEN_Text_DumpString((const char*) encrypted, elen, stderr, 2);
896 
897  dlen=sizeof(decrypted);
899  0x02,
900  algo,
901  encrypted,
902  elen,
903  decrypted,
904  &dlen,
905  0);
906  if (rv) {
907  DBG_ERROR(0, "Could not decipher data (%d)", rv);
908  return 3;
909  }
910 
911  if (memcmp(clearText, decrypted, dlen)) {
912  DBG_ERROR(0, "Deciphered data does not equal clear text(%d)", rv);
913  return 3;
914  }
915  fprintf(stderr, "Deciphered data is ok.\n");
916 
917  }
918 
919  /* close crypt token */
920  rv=GWEN_Crypt_Token_Close(ct, 0, 0);
921  if (rv) {
922  DBG_ERROR(0, "Could not close token");
923  return 3;
924  }
925 
926  return 0;
927 }
928 
929 
930 
931 
932 
933 
934 
935 
936 int main(int argc, char **argv) {
937  GWEN_DB_NODE *db;
938  const char *cmd;
939  int rv;
940  int err;
941  GWEN_GUI *gui;
942  const char *localedir;
943  GWEN_STRINGLIST *slist;
944  const GWEN_ARGS args[]={
945  {
946  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
947  GWEN_ArgsType_Char, /* type */
948  "cfgfile", /* name */
949  0, /* minnum */
950  1, /* maxnum */
951  "C", /* short option */
952  "cfgfile", /* long option */
953  "Specify the configuration file", /* short description */
954  "Specify the configuration file" /* long description */
955  },
956  {
957  0, /* flags */
958  GWEN_ArgsType_Int, /* type */
959  "forcePin", /* name */
960  0, /* minnum */
961  1, /* maxnum */
962  0, /* short option */
963  "forcepin", /* long option */
964  "force pin entry", /* short description */
965  "force pin entry even if the error counter is not zero"
966  },
967  {
969  GWEN_ArgsType_Int, /* type */
970  "help", /* name */
971  0, /* minnum */
972  0, /* maxnum */
973  "h", /* short option */
974  "help", /* long option */
975  "Show this help screen", /* short description */
976  "Show this help screen" /* long description */
977  }
978  };
979 
980  err=GWEN_Init();
981  if (err) {
982  fprintf(stderr, "Could not initialize Gwenhywfar.\n");
983  return 2;
984  }
985 
986  gui=GWEN_Gui_CGui_new();
987  GWEN_Gui_SetGui(gui);
988 
989  slist =
991 
992  assert(GWEN_StringList_Count(slist) > 0);
993  localedir = GWEN_StringList_FirstString(slist);
994 #ifdef HAVE_I18N
995  setlocale(LC_ALL,"");
996  if (bindtextdomain(PACKAGE, localedir)==0)
997  fprintf(stderr, "Error binding locale\n");
998 #endif
999  GWEN_StringList_free(slist);
1000 
1001  GWEN_Logger_Open(GCT_LOGDOMAIN, "gct-tool", 0,
1004 
1005 #ifdef DEBUG_GCT_TOOL
1009 #else
1013 #endif
1014 
1015 #ifdef GCT_IS_EXPERIMENTAL
1016  fprintf(stderr, "\n");
1017  fprintf(stderr, "\n");
1018  fprintf(stderr, "=================== WARNING ===================\n");
1019  fprintf(stderr, "This tool is still EXPERIMENTAL !!!\n");
1020  fprintf(stderr, "Please DON'T USE it with your daily key files !\n");
1021  fprintf(stderr, "===============================================\n");
1022  fprintf(stderr, "\n");
1023  fprintf(stderr, "\n");
1024 #endif
1025 
1026  db=GWEN_DB_Group_new("arguments");
1027  rv=GWEN_Args_Check(argc, argv, 1,
1030  args,
1031  db);
1032  if (rv==GWEN_ARGS_RESULT_ERROR) {
1033  fprintf(stderr, "ERROR: Could not parse arguments main\n");
1034  return -1;
1035  }
1036  else if (rv==GWEN_ARGS_RESULT_HELP) {
1037  GWEN_BUFFER *ubuf;
1038 
1039  ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
1041  I18N("Usage: "));
1042  GWEN_Buffer_AppendString(ubuf, argv[0]);
1044  I18N(" [GLOBAL OPTIONS] COMMAND "
1045  "[LOCAL OPTIONS]\n"));
1047  I18N("\nGlobal Options:\n"));
1048  if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
1049  fprintf(stderr, "ERROR: Could not create help string\n");
1050  return 1;
1051  }
1053  I18N("\nCommands:\n\n"));
1055  I18N(" create:\n"
1056  " This command creates a crypt token"
1057  "\n\n"));
1059  I18N(" showuser:\n"
1060  " Display user data stored on the "
1061  "token\n\n"));
1062 
1063  fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf));
1064  GWEN_Buffer_free(ubuf);
1065  return 0;
1066  }
1067  if (rv) {
1068  argc-=rv-1;
1069  argv+=rv-1;
1070  }
1071 
1072  cmd=GWEN_DB_GetCharValue(db, "params", 0, 0);
1073  if (!cmd) {
1074  fprintf(stderr, "ERROR: Command needed.\n");
1075  return 1;
1076  }
1077 
1078  if (strcasecmp(cmd, "sign1")==0) {
1079  rv=signWithOld(db, argc, argv);
1080  }
1081  else if (strcasecmp(cmd, "sign2")==0) {
1082  rv=signWithNew(db, argc, argv);
1083  }
1084  else if (strcasecmp(cmd, "crypt1")==0) {
1085  rv=cryptWithOld(db, argc, argv);
1086  }
1087  else if (strcasecmp(cmd, "crypt2")==0) {
1088  rv=cryptWithNew(db, argc, argv);
1089  }
1090  else if (strcasecmp(cmd, "crypt3")==0) {
1091  rv=cryptWithNew2(db, argc, argv);
1092  }
1093  else {
1094  fprintf(stderr, "ERROR: Unknown command \"%s\".\n", cmd);
1095  rv=1;
1096  }
1097 
1098  err=GWEN_Fini();
1099  if (err) {
1100  fprintf(stderr,
1101  "WARNING: Could not deinitialize Gwenhywfar.\n");
1102  }
1103 
1104  return rv;
1105 }
1106 
1107 
1108 
1109 
1110 
1111 
1112 
1113 
1114 
#define GWEN_CRYPT_TOKEN_MODE_FORCE_PIN_ENTRY
Definition: ct.h:59
struct GWEN_PLUGIN_MANAGER GWEN_PLUGIN_MANAGER
Definition: plugin.h:40
#define GCT_LOGDOMAIN
Definition: cttest2.c:48
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:223
#define I18N(m)
Definition: error.c:42
int signWithOld(GWEN_DB_NODE *dbArgs, int argc, char **argv)
Definition: cttest2.c:53
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
struct GWEN_PLUGIN GWEN_PLUGIN
Definition: plugin.h:39
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:266
void GWEN_Logger_SetLevel(const char *logDomain, GWEN_LOGGER_LEVEL l)
Definition: logger.c:604
int cryptWithNew2(GWEN_DB_NODE *dbArgs, int argc, char **argv)
Definition: cttest2.c:744
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition: text.c:1235
int signWithNew(GWEN_DB_NODE *dbArgs, int argc, char **argv)
Definition: cttest2.c:226
int GWEN_Crypt_Token_Sign(GWEN_CRYPT_TOKEN *ct, uint32_t keyId, GWEN_CRYPT_PADDALGO *a, const uint8_t *pInData, uint32_t inLen, uint8_t *pSignatureData, uint32_t *pSignatureLen, uint32_t *pSeqCounter, uint32_t gid)
Definition: ct.c:392
GWEN_CRYPT_PADDALGO * GWEN_Crypt_PaddAlgo_new(GWEN_CRYPT_PADDALGOID id)
Definition: paddalgo.c:88
#define NULL
Definition: binreloc.c:290
int GWEN_Crypt_Token_Encipher(GWEN_CRYPT_TOKEN *ct, uint32_t keyId, GWEN_CRYPT_PADDALGO *a, const uint8_t *pInData, uint32_t inLen, uint8_t *pOutData, uint32_t *pOutLen, uint32_t gid)
Definition: ct.c:440
int GWEN_Crypt_Token_Close(GWEN_CRYPT_TOKEN *ct, int abandon, uint32_t gid)
Definition: ct.c:247
int main(int argc, char **argv)
Definition: cttest2.c:936
int GWEN_Crypt_Token_Verify(GWEN_CRYPT_TOKEN *ct, uint32_t keyId, GWEN_CRYPT_PADDALGO *a, const uint8_t *pInData, uint32_t inLen, const uint8_t *pSignatureData, uint32_t signatureLen, uint32_t seqCounter, uint32_t gid)
Definition: ct.c:416
struct GWEN_CRYPT_PADDALGO GWEN_CRYPT_PADDALGO
Definition: paddalgo.h:21
GWEN_PLUGIN * GWEN_PluginManager_GetPlugin(GWEN_PLUGIN_MANAGER *pm, const char *s)
Definition: plugin.c:501
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_CRYPT_TOKEN * GWEN_Crypt_Token_Plugin_CreateToken(GWEN_PLUGIN *pl, const char *name)
Definition: ctplugin.c:138
#define GWEN_ARGS_FLAGS_HELP
Definition: src/base/args.h:52
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
GWEN_PLUGIN_MANAGER * GWEN_PluginManager_FindPluginManager(const char *s)
Definition: plugin.c:519
#define GWEN_ARGS_RESULT_HELP
Definition: src/base/args.h:58
#define GWEN_ARGS_RESULT_ERROR
Definition: src/base/args.h:57
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:57
#define GWEN_ARGS_MODE_STOP_AT_FREEPARAM
Definition: src/base/args.h:55
int GWEN_Args_Usage(const GWEN_ARGS *args, GWEN_BUFFER *ubuf, GWEN_ARGS_OUTTYPE ot)
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:54
#define GWEN_ARGS_MODE_ALLOW_FREEPARAM
Definition: src/base/args.h:54
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:897
GWEN_STRINGLIST * GWEN_PathManager_GetPaths(const char *destLib, const char *pathName)
Definition: pathmanager.c:483
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition: db.c:1260
int cryptWithOld(GWEN_DB_NODE *dbArgs, int argc, char **argv)
Definition: cttest2.c:406
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:83
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
int GWEN_Fini(void)
Definition: gwenhywfar.c:301
struct GWEN_CRYPT_TOKEN GWEN_CRYPT_TOKEN
Definition: ct.h:19
#define GWEN_ARGS_FLAGS_LAST
Definition: src/base/args.h:51
int GWEN_Crypt_Token_Open(GWEN_CRYPT_TOKEN *ct, int admin, uint32_t gid)
Definition: ct.c:206
int GWEN_Logger_Open(const char *logDomain, const char *ident, const char *file, GWEN_LOGGER_LOGTYPE logtype, GWEN_LOGGER_FACILITY facility)
Definition: logger.c:212
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:382
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
const char * GWEN_StringList_FirstString(const GWEN_STRINGLIST *l)
Definition: stringlist.c:525
int GWEN_Args_Check(int argc, char **argv, int startAt, uint32_t mode, const GWEN_ARGS *args, GWEN_DB_NODE *db)
Definition: src/base/args.c:45
#define GWEN_PM_LOCALEDIR
Definition: gwenhywfar.h:49
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:164
#define GWEN_PM_LIBNAME
Definition: gwenhywfar.h:42
int GWEN_Crypt_Token_Decipher(GWEN_CRYPT_TOKEN *ct, uint32_t keyId, GWEN_CRYPT_PADDALGO *a, const uint8_t *pInData, uint32_t inLen, uint8_t *pOutData, uint32_t *pOutLen, uint32_t gid)
Definition: ct.c:462
struct GWEN_GUI GWEN_GUI
Definition: gui.h:176
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1048
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:131
void GWEN_Gui_SetGui(GWEN_GUI *gui)
Definition: gui.c:152
int GWEN_Init(void)
Definition: gwenhywfar.c:92
GWEN_GUI * GWEN_Gui_CGui_new(void)
Definition: cgui.c:74
int cryptWithNew(GWEN_DB_NODE *dbArgs, int argc, char **argv)
Definition: cttest2.c:580
#define GWEN_ARGS_FLAGS_HAS_ARGUMENT
Definition: src/base/args.h:50
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1014
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
void GWEN_Crypt_Token_AddModes(GWEN_CRYPT_TOKEN *ct, uint32_t f)
Definition: ct.c:188