gwenhywfar  5.10.1
cryptdefs.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id: crypttoken.h 1113 2007-01-10 09:14:16Z martin $
5  begin : Wed Mar 16 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 
18 #include "cryptdefs_p.h"
19 #include <gwenhywfar/misc.h>
20 #include <gwenhywfar/debug.h>
21 
22 #include <gwenhywfar/mdigest.h>
23 
24 #include <gcrypt.h>
25 
26 
27 
28 
30 {
31  assert(s);
32  if (strcasecmp(s, "none")==0)
34  else if (strcasecmp(s, "access")==0)
36  else if (strcasecmp(s, "manage")==0)
39 }
40 
41 
42 
44 {
45  switch (pt) {
47  return "none";
49  return "access";
51  return "manage";
52  default:
53  return "unknown";
54  }
55 }
56 
57 
58 
60 {
61  assert(s);
62  if (strcasecmp(s, "none")==0)
64  else if (strcasecmp(s, "bin")==0)
66  else if (strcasecmp(s, "bcd")==0)
68  else if (strcasecmp(s, "ascii")==0)
70  else if (strcasecmp(s, "fpin2")==0)
73 }
74 
75 
76 
78 {
79  switch (pe) {
81  return "none";
83  return "bin";
85  return "bcd";
87  return "ascii";
89  return "fpin2";
90  default:
91  return "unknown";
92  }
93 }
94 
95 
96 
97 int GWEN_Crypt__TransformFromBCD(unsigned char *buffer,
98  unsigned int bufLength,
99  unsigned int *pinLength)
100 {
101  unsigned char *newBuf;
102  unsigned char *p;
103  unsigned int newSize;
104  unsigned int i;
105  unsigned int cnt=0;
106 
107  if (*pinLength==0)
108  return 0;
109 
110  newSize=*pinLength*2;
111  newBuf=(unsigned char *)malloc(newSize);
112  p=newBuf;
113  for (i=0; i<*pinLength; i++) {
114  unsigned char c1;
115  unsigned char c2;
116 
117  c1=buffer[i];
118  /* 1st digit */
119  c2=(c1 & 0xf0)>>4;
120  if (c2==0x0f)
121  break;
122  *(p++)=c2+'0';
123  cnt++;
124  /* 2nd digit */
125  c2=(c1 & 0x0f);
126  if (c2==0x0f)
127  break;
128  *(p++)=c2+'0';
129  cnt++;
130  }
131 
132  if (cnt>bufLength) {
133  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
134  cnt, bufLength);
135  free(newBuf);
137  }
138 
139  memset(buffer, 0, bufLength);
140  memmove(buffer, newBuf, cnt);
141  *pinLength=cnt;
142  free(newBuf);
143  return 0;
144 }
145 
146 
147 
148 int GWEN_Crypt__TransformFromFPIN2(unsigned char *buffer,
149  unsigned int bufLength,
150  unsigned int *pinLength)
151 {
152  unsigned char *newBuf;
153  unsigned char *p;
154  unsigned int newSize;
155  unsigned int i;
156  unsigned int cnt=0;
157  unsigned int len;
158 
159  if (*pinLength<8) {
160  DBG_ERROR(GWEN_LOGDOMAIN, "Pin too small to be a FPIN2 (%d<8)", *pinLength);
161  return GWEN_ERROR_INVALID;
162  }
163  len=(buffer[0] & 0x0f);
164  newSize=len*2;
165  newBuf=(unsigned char *)malloc(newSize);
166  p=newBuf;
167  for (i=1; i<8; i++) {
168  unsigned char c1;
169  unsigned char c2;
170 
171  if (cnt>=len)
172  break;
173 
174  c1=buffer[i];
175  /* 1st digit */
176  c2=(c1 & 0xf0)>>4;
177  if (c2==0x0f)
178  break;
179  *(p++)=c2+'0';
180  cnt++;
181  if (cnt>=len)
182  break;
183 
184  /* 2nd digit */
185  c2=(c1 & 0x0f);
186  if (c2==0x0f)
187  break;
188  *(p++)=c2+'0';
189  cnt++;
190  }
191 
192  if (cnt>bufLength) {
193  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
194  cnt, bufLength);
195  free(newBuf);
197  }
198 
199  memset(buffer, 0, bufLength);
200  memmove(buffer, newBuf, cnt);
201  *pinLength=cnt;
202  return 0;
203 }
204 
205 
206 
207 int GWEN_Crypt__TransformFromBin(unsigned char *buffer,
208  unsigned int bufLength,
209  unsigned int *pinLength)
210 {
211  unsigned int i;
212  unsigned char *newBuf;
213  unsigned char *p;
214  unsigned int newSize;
215 
216  if (*pinLength==0)
217  return 0;
218 
219  newSize=*pinLength;
220  newBuf=(unsigned char *)malloc(newSize);
221  p=newBuf;
222 
223  for (i=0; i<*pinLength; i++) {
224  unsigned char c;
225 
226  c=buffer[i];
227  if (c>9) {
228  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a digit > 9)");
229  free(newBuf);
230  return GWEN_ERROR_INVALID;
231  }
232  *p=c+'0';
233  }
234  memset(buffer, 0, bufLength);
235  memmove(buffer, newBuf, *pinLength);
236  free(newBuf);
237 
238  return 0;
239 }
240 
241 
242 
243 int GWEN_Crypt__TransformToBCD(unsigned char *buffer,
244  unsigned int bufLength,
245  unsigned int *pinLength)
246 {
247  unsigned char *newBuf;
248  unsigned char *p;
249  unsigned int newSize;
250  unsigned int i;
251  unsigned int cnt=0;
252 
253  newSize=*pinLength/2+1;
254  newBuf=(unsigned char *)malloc(newSize);
255  memset(newBuf, 0xff, newSize);
256  p=newBuf;
257  i=0;
258  while (i<*pinLength) {
259  unsigned char c1;
260  unsigned char c2;
261 
262  /* 1st digit */
263  c1=buffer[i];
264  if (c1<'0' || c1>'9') {
265  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
266  free(newBuf);
267  return GWEN_ERROR_INVALID;
268  }
269  c1-='0';
270  c1=c1<<4;
271  *p=c1+0x0f; /* don't incement yet */
272  cnt++; /* only increment once !! */
273  i++;
274  if (i>=*pinLength)
275  break;
276 
277  /* 2nd digit */
278  c2=buffer[i];
279  if (c2<'0' || c2>'9') {
280  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
281  free(newBuf);
282  return GWEN_ERROR_INVALID;
283  }
284  c2-='0';
285  c1|=(c2 & 0x0f);
286  *(p++)=c1;
287  i++;
288  }
289 
290  if (cnt>bufLength) {
291  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)",
292  cnt, bufLength);
293  free(newBuf);
295  }
296 
297  memset(buffer, 0, bufLength);
298  for (i=0; i<cnt; i++)
299  buffer[i]=newBuf[i];
300  *pinLength=cnt;
301  free(newBuf);
302  return 0;
303 }
304 
305 
306 
307 int GWEN_Crypt__TransformToFPIN2(unsigned char *buffer,
308  unsigned int bufLength,
309  unsigned int *pinLength)
310 {
311  unsigned char *newBuf;
312  unsigned char *p;
313  unsigned int newSize;
314  unsigned int i;
315 
316  if (*pinLength>14) {
317  DBG_ERROR(GWEN_LOGDOMAIN, "Pin too long for FPIN2 (%d>14)",
318  *pinLength);
319  return GWEN_ERROR_INVALID;
320  }
321  if (8>bufLength) {
322  DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (8>%d)",
323  bufLength);
325  }
326 
327  newSize=8;
328  newBuf=(unsigned char *)malloc(newSize);
329  memset(newBuf, 0xff, newSize);
330  p=newBuf;
331  *(p++)=0x20+*pinLength;
332  i=0;
333  while (i<*pinLength) {
334  unsigned char c1;
335  unsigned char c2;
336 
337  /* 1st digit */
338  c1=buffer[i];
339  if (c1<'0' || c1>'9') {
340  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
341  free(newBuf);
342  return GWEN_ERROR_INVALID;
343  }
344  c1-='0';
345  c1=c1<<4;
346  *p=c1+0x0f; /* don't incement yet */
347  i++;
348  if (i>=*pinLength)
349  break;
350 
351  /* 2nd digit */
352  c2=buffer[i];
353  if (c2<'0' || c2>'9') {
354  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
355  free(newBuf);
356  return GWEN_ERROR_INVALID;
357  }
358  c2-='0';
359  c1|=(c2 & 0x0f);
360  *(p++)=c1;
361  i++;
362  }
363 
364  memset(buffer, 0, bufLength);
365  for (i=0; i<8; i++)
366  buffer[i]=newBuf[i];
367  *pinLength=8;
368  free(newBuf);
369  return 0;
370 
371 }
372 
373 
374 
375 int GWEN_Crypt__TransformToBin(unsigned char *buffer,
376  unsigned int bufLength,
377  unsigned int *pinLength)
378 {
379  unsigned int i;
380  unsigned char *newBuf;
381  unsigned char *p;
382  unsigned int newSize;
383 
384  if (*pinLength==0)
385  return 0;
386 
387  newSize=*pinLength;
388  newBuf=(unsigned char *)malloc(newSize);
389  p=newBuf;
390 
391  for (i=0; i<*pinLength; i++) {
392  unsigned char c;
393 
394  c=buffer[i];
395  if (c<'0' || c>'9') {
396  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)");
397  free(newBuf);
398  return GWEN_ERROR_INVALID;
399  }
400  *(p++)=c-'0';
401  }
402  memset(buffer, 0, bufLength);
403  memmove(buffer, newBuf, *pinLength);
404  free(newBuf);
405 
406  return 0;
407 }
408 
409 
410 
413  unsigned char *buffer,
414  unsigned int bufLength,
415  unsigned int *pinLength)
416 {
417  int rv;
418 
419  if (peSrc==peDst)
420  return 0;
421 
422  switch (peSrc) {
424  rv=GWEN_Crypt__TransformFromBin(buffer, bufLength, pinLength);
425  break;
427  rv=GWEN_Crypt__TransformFromBCD(buffer, bufLength, pinLength);
428  break;
430  rv=0;
431  break;
433  rv=GWEN_Crypt__TransformFromFPIN2(buffer, bufLength, pinLength);
434  break;
435  default:
437  "Unhandled source encoding \"%s\"",
439  return GWEN_ERROR_INVALID;
440  }
441  if (rv) {
442  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
443  return rv;
444  }
445 
446  switch (peDst) {
448  rv=GWEN_Crypt__TransformToBin(buffer, bufLength, pinLength);
449  break;
451  rv=GWEN_Crypt__TransformToBCD(buffer, bufLength, pinLength);
452  break;
454  rv=0;
455  break;
457  rv=GWEN_Crypt__TransformToFPIN2(buffer, bufLength, pinLength);
458  break;
459  default:
461  "Unhandled destination encoding \"%s\"",
463  return GWEN_ERROR_INVALID;
464  }
465  if (rv) {
466  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
467  return rv;
468  }
469 
470  return 0;
471 }
472 
473 
474 
475 
476 static int GWEN_Crypt__KeyDataFromText(const char *text,
477  unsigned char *buffer,
478  unsigned int bufLength)
479 {
480  GWEN_MDIGEST *md;
481  int rv;
482 
483  assert(text);
484  assert(buffer);
485  assert(bufLength);
486 
487  switch (bufLength) {
488  case 16:
490  break;
491  case 20:
493  break;
494  default:
495  DBG_ERROR(GWEN_LOGDOMAIN, "Bad size (%d)", bufLength);
496  return GWEN_ERROR_BAD_SIZE;
497  }
498 
499  rv=GWEN_MDigest_Begin(md);
500  if (rv) {
501  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
502  GWEN_MDigest_free(md);
503  return rv;
504  }
505 
506  rv=GWEN_MDigest_Update(md,
507  (const uint8_t *)text,
508  strlen(text));
509  if (rv) {
510  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
511  GWEN_MDigest_free(md);
512  return rv;
513  }
514 
515  rv=GWEN_MDigest_End(md);
516  if (rv) {
517  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
518  GWEN_MDigest_free(md);
519  return rv;
520  }
521 
522  /* get hash, copy it to given buffer */
523  memmove(buffer, GWEN_MDigest_GetDigestPtr(md), bufLength);
524 
525  /* cleanup, return */
526  GWEN_MDigest_free(md);
527  return 0;
528 }
529 
530 
531 
532 int GWEN_Crypt_KeyDataFromText(const char *text,
533  unsigned char *buffer,
534  unsigned int bufLength)
535 {
536  if (bufLength==24) {
537  int rv;
538 
539  rv=GWEN_Crypt__KeyDataFromText(text, buffer, 16);
540  if (rv)
541  return rv;
542  memmove(buffer+16, buffer, 8);
543  return rv;
544  }
545  else
546  return GWEN_Crypt__KeyDataFromText(text, buffer, bufLength);
547 }
548 
549 
550 
551 void GWEN_Crypt_Random(int quality, uint8_t *buffer, uint32_t len)
552 {
553  enum gcry_random_level q;
554 
555  switch (quality) {
556  case 0:
557  q=GCRY_WEAK_RANDOM;
558  break;
559  case 1:
560  q=GCRY_STRONG_RANDOM;
561  break;
562  case 2:
563  default:
564  q=GCRY_VERY_STRONG_RANDOM;
565  break;
566  }
567 
568  gcry_randomize(buffer, len, q);
569 }
570 
571 
572 
573 
574 
575 
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition: mdigest.c:54
#define GWEN_ERROR_INVALID
Definition: error.h:67
int GWEN_Crypt__TransformToFPIN2(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition: cryptdefs.c:307
int GWEN_Crypt__TransformToBCD(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition: cryptdefs.c:243
int GWEN_Crypt_TransformPin(GWEN_CRYPT_PINENCODING peSrc, GWEN_CRYPT_PINENCODING peDst, unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition: cryptdefs.c:411
GWEN_CRYPT_PINTYPE
Definition: cryptdefs.h:26
const char * GWEN_Crypt_PinEncoding_toString(GWEN_CRYPT_PINENCODING pe)
Definition: cryptdefs.c:77
#define GWEN_LOGDOMAIN
Definition: logger.h:35
int GWEN_MDigest_Update(GWEN_MDIGEST *md, const uint8_t *buf, unsigned int l)
Definition: mdigest.c:153
#define GWEN_ERROR_BUFFER_OVERFLOW
Definition: error.h:79
GWEN_CRYPT_PINENCODING GWEN_Crypt_PinEncoding_fromString(const char *s)
Definition: cryptdefs.c:59
uint8_t * GWEN_MDigest_GetDigestPtr(GWEN_MDIGEST *md)
Definition: mdigest.c:81
int GWEN_MDigest_Begin(GWEN_MDIGEST *md)
Definition: mdigest.c:129
int GWEN_Crypt__TransformToBin(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition: cryptdefs.c:375
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Rmd160_new(void)
Definition: mdigestgc.c:158
const char * GWEN_Crypt_PinType_toString(GWEN_CRYPT_PINTYPE pt)
Definition: cryptdefs.c:43
int GWEN_Crypt__TransformFromBCD(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition: cryptdefs.c:97
struct GWEN_MDIGEST GWEN_MDIGEST
Definition: mdigest.h:25
void GWEN_Crypt_Random(int quality, uint8_t *buffer, uint32_t len)
Definition: cryptdefs.c:551
int GWEN_Crypt_KeyDataFromText(const char *text, unsigned char *buffer, unsigned int bufLength)
Definition: cryptdefs.c:532
int GWEN_MDigest_End(GWEN_MDIGEST *md)
Definition: mdigest.c:141
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Md5_new(void)
Definition: mdigestgc.c:140
static int GWEN_Crypt__KeyDataFromText(const char *text, unsigned char *buffer, unsigned int bufLength)
Definition: cryptdefs.c:476
GWEN_CRYPT_PINENCODING
Definition: cryptdefs.h:39
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
GWEN_CRYPT_PINTYPE GWEN_Crypt_PinType_fromString(const char *s)
Definition: cryptdefs.c:29
int GWEN_Crypt__TransformFromBin(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition: cryptdefs.c:207
#define GWEN_ERROR_BAD_SIZE
Definition: error.h:100
int GWEN_Crypt__TransformFromFPIN2(unsigned char *buffer, unsigned int bufLength, unsigned int *pinLength)
Definition: cryptdefs.c:148