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