gwenhywfar
4.3.1
|
00001 /*************************************************************************** 00002 $RCSfile$ 00003 ------------------- 00004 cvs : $Id: crypttoken.h 1113 2007-01-10 09:14:16Z martin $ 00005 begin : Wed Mar 16 2005 00006 copyright : (C) 2005 by Martin Preuss 00007 email : martin@libchipcard.de 00008 00009 *************************************************************************** 00010 * Please see toplevel file COPYING for license details * 00011 ***************************************************************************/ 00012 00013 #ifdef HAVE_CONFIG_H 00014 # include <config.h> 00015 #endif 00016 00017 00018 #include "cryptdefs_p.h" 00019 #include <gwenhywfar/misc.h> 00020 #include <gwenhywfar/debug.h> 00021 00022 #include <gwenhywfar/mdigest.h> 00023 00024 #include <gcrypt.h> 00025 00026 00027 00028 00029 GWEN_CRYPT_PINTYPE GWEN_Crypt_PinType_fromString(const char *s) { 00030 assert(s); 00031 if (strcasecmp(s, "none")==0) 00032 return GWEN_Crypt_PinType_None; 00033 else if (strcasecmp(s, "access")==0) 00034 return GWEN_Crypt_PinType_Access; 00035 else if (strcasecmp(s, "manage")==0) 00036 return GWEN_Crypt_PinType_Manage; 00037 return GWEN_Crypt_PinType_Unknown; 00038 } 00039 00040 00041 00042 const char *GWEN_Crypt_PinType_toString(GWEN_CRYPT_PINTYPE pt) { 00043 switch(pt) { 00044 case GWEN_Crypt_PinType_None: 00045 return "none"; 00046 case GWEN_Crypt_PinType_Access: 00047 return "access"; 00048 case GWEN_Crypt_PinType_Manage: 00049 return "manage"; 00050 default: 00051 return "unknown"; 00052 } 00053 } 00054 00055 00056 00057 GWEN_CRYPT_PINENCODING GWEN_Crypt_PinEncoding_fromString(const char *s) { 00058 assert(s); 00059 if (strcasecmp(s, "none")==0) 00060 return GWEN_Crypt_PinEncoding_None; 00061 else if (strcasecmp(s, "bin")==0) 00062 return GWEN_Crypt_PinEncoding_Bin; 00063 else if (strcasecmp(s, "bcd")==0) 00064 return GWEN_Crypt_PinEncoding_Bcd; 00065 else if (strcasecmp(s, "ascii")==0) 00066 return GWEN_Crypt_PinEncoding_Ascii; 00067 else if (strcasecmp(s, "fpin2")==0) 00068 return GWEN_Crypt_PinEncoding_FPin2; 00069 return GWEN_Crypt_PinEncoding_Unknown; 00070 } 00071 00072 00073 00074 const char *GWEN_Crypt_PinEncoding_toString(GWEN_CRYPT_PINENCODING pe) { 00075 switch(pe) { 00076 case GWEN_Crypt_PinEncoding_None: 00077 return "none"; 00078 case GWEN_Crypt_PinEncoding_Bin: 00079 return "bin"; 00080 case GWEN_Crypt_PinEncoding_Bcd: 00081 return "bcd"; 00082 case GWEN_Crypt_PinEncoding_Ascii: 00083 return "ascii"; 00084 case GWEN_Crypt_PinEncoding_FPin2: 00085 return "fpin2"; 00086 default: 00087 return "unknown"; 00088 } 00089 } 00090 00091 00092 00093 int GWEN_Crypt__TransformFromBCD(unsigned char *buffer, 00094 unsigned int bufLength, 00095 unsigned int *pinLength) { 00096 unsigned char *newBuf; 00097 unsigned char *p; 00098 unsigned int newSize; 00099 unsigned int i; 00100 unsigned int cnt=0; 00101 00102 if (*pinLength==0) 00103 return 0; 00104 00105 newSize=*pinLength*2; 00106 newBuf=(unsigned char*)malloc(newSize); 00107 p=newBuf; 00108 for (i=0; i<*pinLength; i++) { 00109 unsigned char c1; 00110 unsigned char c2; 00111 00112 c1=buffer[i]; 00113 /* 1st digit */ 00114 c2=(c1 & 0xf0)>>4; 00115 if (c2==0x0f) 00116 break; 00117 *(p++)=c2+'0'; 00118 cnt++; 00119 /* 2nd digit */ 00120 c2=(c1 & 0x0f); 00121 if (c2==0x0f) 00122 break; 00123 *(p++)=c2+'0'; 00124 cnt++; 00125 } 00126 00127 if (cnt>bufLength) { 00128 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)", 00129 cnt, bufLength); 00130 free(newBuf); 00131 return GWEN_ERROR_BUFFER_OVERFLOW; 00132 } 00133 00134 memset(buffer, 0, bufLength); 00135 memmove(buffer, newBuf, cnt); 00136 *pinLength=cnt; 00137 free(newBuf); 00138 return 0; 00139 } 00140 00141 00142 00143 int GWEN_Crypt__TransformFromFPIN2(unsigned char *buffer, 00144 unsigned int bufLength, 00145 unsigned int *pinLength) { 00146 unsigned char *newBuf; 00147 unsigned char *p; 00148 unsigned int newSize; 00149 unsigned int i; 00150 unsigned int cnt=0; 00151 unsigned int len; 00152 00153 if (*pinLength<8) { 00154 DBG_ERROR(GWEN_LOGDOMAIN, "Pin too small to be a FPIN2 (%d<8)", *pinLength); 00155 return GWEN_ERROR_INVALID; 00156 } 00157 len=(buffer[0] & 0x0f); 00158 newSize=len*2; 00159 newBuf=(unsigned char*)malloc(newSize); 00160 p=newBuf; 00161 for (i=1; i<8; i++) { 00162 unsigned char c1; 00163 unsigned char c2; 00164 00165 if (cnt>=len) 00166 break; 00167 00168 c1=buffer[i]; 00169 /* 1st digit */ 00170 c2=(c1 & 0xf0)>>4; 00171 if (c2==0x0f) 00172 break; 00173 *(p++)=c2+'0'; 00174 cnt++; 00175 if (cnt>=len) 00176 break; 00177 00178 /* 2nd digit */ 00179 c2=(c1 & 0x0f); 00180 if (c2==0x0f) 00181 break; 00182 *(p++)=c2+'0'; 00183 cnt++; 00184 } 00185 00186 if (cnt>bufLength) { 00187 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)", 00188 cnt, bufLength); 00189 free(newBuf); 00190 return GWEN_ERROR_BUFFER_OVERFLOW; 00191 } 00192 00193 memset(buffer, 0, bufLength); 00194 memmove(buffer, newBuf, cnt); 00195 *pinLength=cnt; 00196 return 0; 00197 } 00198 00199 00200 00201 int GWEN_Crypt__TransformFromBin(unsigned char *buffer, 00202 unsigned int bufLength, 00203 unsigned int *pinLength) { 00204 unsigned int i; 00205 unsigned char *newBuf; 00206 unsigned char *p; 00207 unsigned int newSize; 00208 00209 if (*pinLength==0) 00210 return 0; 00211 00212 newSize=*pinLength; 00213 newBuf=(unsigned char*)malloc(newSize); 00214 p=newBuf; 00215 00216 for (i=0; i<*pinLength; i++) { 00217 unsigned char c; 00218 00219 c=buffer[i]; 00220 if (c>9) { 00221 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a digit > 9)"); 00222 free(newBuf); 00223 return GWEN_ERROR_INVALID; 00224 } 00225 *p=c+'0'; 00226 } 00227 memset(buffer, 0, bufLength); 00228 memmove(buffer, newBuf, *pinLength); 00229 free(newBuf); 00230 00231 return 0; 00232 } 00233 00234 00235 00236 int GWEN_Crypt__TransformToBCD(unsigned char *buffer, 00237 unsigned int bufLength, 00238 unsigned int *pinLength) { 00239 unsigned char *newBuf; 00240 unsigned char *p; 00241 unsigned int newSize; 00242 unsigned int i; 00243 unsigned int cnt=0; 00244 00245 newSize=*pinLength/2+1; 00246 newBuf=(unsigned char*)malloc(newSize); 00247 memset(newBuf, 0xff, newSize); 00248 p=newBuf; 00249 i=0; 00250 while (i<*pinLength) { 00251 unsigned char c1; 00252 unsigned char c2; 00253 00254 /* 1st digit */ 00255 c1=buffer[i]; 00256 if (c1<'0' || c1>'9') { 00257 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)"); 00258 free(newBuf); 00259 return GWEN_ERROR_INVALID; 00260 } 00261 c1-='0'; 00262 c1=c1<<4; 00263 *p=c1+0x0f; /* don't incement yet */ 00264 cnt++; /* only increment once !! */ 00265 i++; 00266 if (i>=*pinLength) 00267 break; 00268 00269 /* 2nd digit */ 00270 c2=buffer[i]; 00271 if (c2<'0' || c2>'9') { 00272 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)"); 00273 free(newBuf); 00274 return GWEN_ERROR_INVALID; 00275 } 00276 c2-='0'; 00277 c1|=(c2 & 0x0f); 00278 *(p++)=c1; 00279 i++; 00280 } 00281 00282 if (cnt>bufLength) { 00283 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (%d>%d)", 00284 cnt, bufLength); 00285 free(newBuf); 00286 return GWEN_ERROR_BUFFER_OVERFLOW; 00287 } 00288 00289 memset(buffer, 0, bufLength); 00290 for (i=0; i<cnt; i++) 00291 buffer[i]=newBuf[i]; 00292 *pinLength=cnt; 00293 free(newBuf); 00294 return 0; 00295 } 00296 00297 00298 00299 int GWEN_Crypt__TransformToFPIN2(unsigned char *buffer, 00300 unsigned int bufLength, 00301 unsigned int *pinLength) { 00302 unsigned char *newBuf; 00303 unsigned char *p; 00304 unsigned int newSize; 00305 unsigned int i; 00306 00307 if (*pinLength>14) { 00308 DBG_ERROR(GWEN_LOGDOMAIN, "Pin too long for FPIN2 (%d>14)", 00309 *pinLength); 00310 return GWEN_ERROR_INVALID; 00311 } 00312 if (8>bufLength) { 00313 DBG_ERROR(GWEN_LOGDOMAIN, "Converted pin is too long (8>%d)", 00314 bufLength); 00315 return GWEN_ERROR_BUFFER_OVERFLOW; 00316 } 00317 00318 newSize=8; 00319 newBuf=(unsigned char*)malloc(newSize); 00320 memset(newBuf, 0xff, newSize); 00321 p=newBuf; 00322 *(p++)=0x20+*pinLength; 00323 i=0; 00324 while (i<*pinLength) { 00325 unsigned char c1; 00326 unsigned char c2; 00327 00328 /* 1st digit */ 00329 c1=buffer[i]; 00330 if (c1<'0' || c1>'9') { 00331 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)"); 00332 free(newBuf); 00333 return GWEN_ERROR_INVALID; 00334 } 00335 c1-='0'; 00336 c1=c1<<4; 00337 *p=c1+0x0f; /* don't incement yet */ 00338 i++; 00339 if (i>=*pinLength) 00340 break; 00341 00342 /* 2nd digit */ 00343 c2=buffer[i]; 00344 if (c2<'0' || c2>'9') { 00345 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)"); 00346 free(newBuf); 00347 return GWEN_ERROR_INVALID; 00348 } 00349 c2-='0'; 00350 c1|=(c2 & 0x0f); 00351 *(p++)=c1; 00352 i++; 00353 } 00354 00355 memset(buffer, 0, bufLength); 00356 for (i=0; i<8; i++) 00357 buffer[i]=newBuf[i]; 00358 *pinLength=8; 00359 free(newBuf); 00360 return 0; 00361 00362 } 00363 00364 00365 00366 int GWEN_Crypt__TransformToBin(unsigned char *buffer, 00367 unsigned int bufLength, 00368 unsigned int *pinLength) { 00369 unsigned int i; 00370 unsigned char *newBuf; 00371 unsigned char *p; 00372 unsigned int newSize; 00373 00374 if (*pinLength==0) 00375 return 0; 00376 00377 newSize=*pinLength; 00378 newBuf=(unsigned char*)malloc(newSize); 00379 p=newBuf; 00380 00381 for (i=0; i<*pinLength; i++) { 00382 unsigned char c; 00383 00384 c=buffer[i]; 00385 if (c<'0' || c>'9') { 00386 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid element in pin (a non-number character)"); 00387 free(newBuf); 00388 return GWEN_ERROR_INVALID; 00389 } 00390 *(p++)=c-'0'; 00391 } 00392 memset(buffer, 0, bufLength); 00393 memmove(buffer, newBuf, *pinLength); 00394 free(newBuf); 00395 00396 return 0; 00397 } 00398 00399 00400 00401 int GWEN_Crypt_TransformPin(GWEN_CRYPT_PINENCODING peSrc, 00402 GWEN_CRYPT_PINENCODING peDst, 00403 unsigned char *buffer, 00404 unsigned int bufLength, 00405 unsigned int *pinLength) { 00406 int rv; 00407 00408 if (peSrc==peDst) 00409 return 0; 00410 00411 switch(peSrc) { 00412 case GWEN_Crypt_PinEncoding_Bin: 00413 rv=GWEN_Crypt__TransformFromBin(buffer, bufLength, pinLength); 00414 break; 00415 case GWEN_Crypt_PinEncoding_Bcd: 00416 rv=GWEN_Crypt__TransformFromBCD(buffer, bufLength, pinLength); 00417 break; 00418 case GWEN_Crypt_PinEncoding_Ascii: 00419 rv=0; 00420 break; 00421 case GWEN_Crypt_PinEncoding_FPin2: 00422 rv=GWEN_Crypt__TransformFromFPIN2(buffer, bufLength, pinLength); 00423 break; 00424 default: 00425 DBG_ERROR(GWEN_LOGDOMAIN, 00426 "Unhandled source encoding \"%s\"", 00427 GWEN_Crypt_PinEncoding_toString(peSrc)); 00428 return GWEN_ERROR_INVALID; 00429 } 00430 if (rv) { 00431 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00432 return rv; 00433 } 00434 00435 switch(peDst) { 00436 case GWEN_Crypt_PinEncoding_Bin: 00437 rv=GWEN_Crypt__TransformToBin(buffer, bufLength, pinLength); 00438 break; 00439 case GWEN_Crypt_PinEncoding_Bcd: 00440 rv=GWEN_Crypt__TransformToBCD(buffer, bufLength, pinLength); 00441 break; 00442 case GWEN_Crypt_PinEncoding_Ascii: 00443 rv=0; 00444 break; 00445 case GWEN_Crypt_PinEncoding_FPin2: 00446 rv=GWEN_Crypt__TransformToFPIN2(buffer, bufLength, pinLength); 00447 break; 00448 default: 00449 DBG_ERROR(GWEN_LOGDOMAIN, 00450 "Unhandled destination encoding \"%s\"", 00451 GWEN_Crypt_PinEncoding_toString(peDst)); 00452 return GWEN_ERROR_INVALID; 00453 } 00454 if (rv) { 00455 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00456 return rv; 00457 } 00458 00459 return 0; 00460 } 00461 00462 00463 00464 00465 static int GWEN_Crypt__KeyDataFromText(const char *text, 00466 unsigned char *buffer, 00467 unsigned int bufLength) { 00468 GWEN_MDIGEST *md; 00469 int rv; 00470 00471 assert(text); 00472 assert(buffer); 00473 assert(bufLength); 00474 00475 switch(bufLength) { 00476 case 16: md=GWEN_MDigest_Md5_new(); break; 00477 case 20: md=GWEN_MDigest_Rmd160_new(); break; 00478 default: 00479 DBG_ERROR(GWEN_LOGDOMAIN, "Bad size (%d)", bufLength); 00480 return GWEN_ERROR_BAD_SIZE; 00481 } 00482 00483 rv=GWEN_MDigest_Begin(md); 00484 if (rv) { 00485 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00486 GWEN_MDigest_free(md); 00487 return rv; 00488 } 00489 00490 rv=GWEN_MDigest_Update(md, 00491 (const uint8_t*)text, 00492 strlen(text)); 00493 if (rv) { 00494 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00495 GWEN_MDigest_free(md); 00496 return rv; 00497 } 00498 00499 rv=GWEN_MDigest_End(md); 00500 if (rv) { 00501 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00502 GWEN_MDigest_free(md); 00503 return rv; 00504 } 00505 00506 /* get hash, copy it to given buffer */ 00507 memmove(buffer, GWEN_MDigest_GetDigestPtr(md), bufLength); 00508 00509 /* cleanup, return */ 00510 GWEN_MDigest_free(md); 00511 return 0; 00512 } 00513 00514 00515 00516 int GWEN_Crypt_KeyDataFromText(const char *text, 00517 unsigned char *buffer, 00518 unsigned int bufLength) { 00519 if (bufLength==24) { 00520 int rv; 00521 00522 rv=GWEN_Crypt__KeyDataFromText(text, buffer, 16); 00523 if (rv) 00524 return rv; 00525 memmove(buffer+16, buffer, 8); 00526 return rv; 00527 } 00528 else 00529 return GWEN_Crypt__KeyDataFromText(text, buffer, bufLength); 00530 } 00531 00532 00533 00534 void GWEN_Crypt_Random(int quality, uint8_t *buffer, uint32_t len) { 00535 uint8_t *data; 00536 enum gcry_random_level q; 00537 00538 switch(quality) { 00539 case 0: q=GCRY_WEAK_RANDOM; break; 00540 case 1: q=GCRY_STRONG_RANDOM; break; 00541 case 2: 00542 default: q=GCRY_VERY_STRONG_RANDOM; break; 00543 } 00544 00545 data=gcry_random_bytes(len, q); 00546 assert(data); 00547 memmove(buffer, data, len); 00548 memset(data, 0, len); 00549 free(data); 00550 } 00551 00552 00553 00554 00555 00556