00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00114 c2=(c1 & 0xf0)>>4;
00115 if (c2==0x0f)
00116 break;
00117 *(p++)=c2+'0';
00118 cnt++;
00119
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
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
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
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;
00264 cnt++;
00265 i++;
00266 if (i>=*pinLength)
00267 break;
00268
00269
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
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;
00338 i++;
00339 if (i>=*pinLength)
00340 break;
00341
00342
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
00507 memmove(buffer, GWEN_MDigest_GetDigestPtr(md), bufLength);
00508
00509
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