gwenhywfar
4.3.1
|
00001 /*************************************************************************** 00002 begin : Mon Dec 01 2008 00003 copyright : (C) 2008 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * Please see toplevel file COPYING for license details * 00008 ***************************************************************************/ 00009 00010 #ifdef HAVE_CONFIG_H 00011 # include <config.h> 00012 #endif 00013 00014 #define DISABLE_DEBUGLOG 00015 00016 00017 #include "cryptmgr_p.h" 00018 #include "i18n_l.h" 00019 #include <gwenhywfar/misc.h> 00020 #include <gwenhywfar/debug.h> 00021 #include <gwenhywfar/gwentime.h> 00022 00023 #include <gwenhywfar/crypthead.h> 00024 #include <gwenhywfar/sighead.h> 00025 #include <gwenhywfar/sigtail.h> 00026 #include <gwenhywfar/tag16.h> 00027 #include <gwenhywfar/cryptkeysym.h> 00028 #include <gwenhywfar/padd.h> 00029 00030 00031 00032 00033 GWEN_INHERIT_FUNCTIONS(GWEN_CRYPTMGR) 00034 00035 00036 00037 GWEN_CRYPTMGR *GWEN_CryptMgr_new(void) { 00038 GWEN_CRYPTMGR *cm; 00039 00040 GWEN_NEW_OBJECT(GWEN_CRYPTMGR, cm); 00041 GWEN_INHERIT_INIT(GWEN_CRYPTMGR, cm); 00042 00043 return cm; 00044 } 00045 00046 00047 00048 void GWEN_CryptMgr_free(GWEN_CRYPTMGR *cm) { 00049 if (cm) { 00050 GWEN_INHERIT_FINI(GWEN_CRYPTMGR, cm); 00051 free(cm->localKeyName); 00052 free(cm->peerKeyName); 00053 00054 GWEN_FREE_OBJECT(cm); 00055 } 00056 } 00057 00058 00059 00060 const char *GWEN_CryptMgr_GetLocalKeyName(const GWEN_CRYPTMGR *cm) { 00061 assert(cm); 00062 return cm->localKeyName; 00063 } 00064 00065 00066 00067 void GWEN_CryptMgr_SetLocalKeyName(GWEN_CRYPTMGR *cm, const char *s) { 00068 assert(cm); 00069 free(cm->localKeyName); 00070 if (s) cm->localKeyName=strdup(s); 00071 else cm->localKeyName=NULL; 00072 } 00073 00074 00075 00076 int GWEN_CryptMgr_GetLocalKeyNumber(const GWEN_CRYPTMGR *cm) { 00077 assert(cm); 00078 return cm->localKeyNumber; 00079 } 00080 00081 00082 00083 void GWEN_CryptMgr_SetLocalKeyNumber(GWEN_CRYPTMGR *cm, int i) { 00084 assert(cm); 00085 cm->localKeyNumber=i; 00086 } 00087 00088 00089 00090 int GWEN_CryptMgr_GetLocalKeyVersion(const GWEN_CRYPTMGR *cm) { 00091 assert(cm); 00092 return cm->localKeyVersion; 00093 } 00094 00095 00096 00097 void GWEN_CryptMgr_SetLocalKeyVersion(GWEN_CRYPTMGR *cm, int i) { 00098 assert(cm); 00099 cm->localKeyVersion=i; 00100 } 00101 00102 00103 00104 const char *GWEN_CryptMgr_GetPeerKeyName(const GWEN_CRYPTMGR *cm) { 00105 assert(cm); 00106 return cm->peerKeyName; 00107 } 00108 00109 00110 00111 void GWEN_CryptMgr_SetPeerKeyName(GWEN_CRYPTMGR *cm, const char *s) { 00112 assert(cm); 00113 free(cm->peerKeyName); 00114 if (s) cm->peerKeyName=strdup(s); 00115 else cm->peerKeyName=NULL; 00116 } 00117 00118 00119 00120 int GWEN_CryptMgr_GetPeerKeyNumber(const GWEN_CRYPTMGR *cm) { 00121 assert(cm); 00122 return cm->peerKeyNumber; 00123 } 00124 00125 00126 00127 void GWEN_CryptMgr_SetPeerKeyNumber(GWEN_CRYPTMGR *cm, int i) { 00128 assert(cm); 00129 cm->peerKeyNumber=i; 00130 } 00131 00132 00133 00134 int GWEN_CryptMgr_GetPeerKeyVersion(const GWEN_CRYPTMGR *cm) { 00135 assert(cm); 00136 return cm->peerKeyVersion; 00137 } 00138 00139 00140 00141 void GWEN_CryptMgr_SetPeerKeyVersion(GWEN_CRYPTMGR *cm, int i) { 00142 assert(cm); 00143 cm->peerKeyVersion=i; 00144 } 00145 00146 00147 00148 int GWEN_CryptMgr_GetCryptProfile(const GWEN_CRYPTMGR *cm) { 00149 assert(cm); 00150 return cm->cryptProfile; 00151 } 00152 00153 00154 00155 void GWEN_CryptMgr_SetCryptProfile(GWEN_CRYPTMGR *cm, int i) { 00156 assert(cm); 00157 cm->cryptProfile=i; 00158 } 00159 00160 00161 00162 int GWEN_CryptMgr_GetSignatureProfile(const GWEN_CRYPTMGR *cm) { 00163 assert(cm); 00164 return cm->signatureProfile; 00165 } 00166 00167 00168 00169 void GWEN_CryptMgr_SetSignatureProfile(GWEN_CRYPTMGR *cm, int i) { 00170 assert(cm); 00171 cm->signatureProfile=i; 00172 } 00173 00174 00175 00176 00177 00178 int GWEN_CryptMgr_SignData(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00179 assert(cm); 00180 if (cm->signDataFn) 00181 return cm->signDataFn(cm, pData, lData, dbuf); 00182 else 00183 return GWEN_ERROR_NOT_IMPLEMENTED; 00184 } 00185 00186 00187 00188 int GWEN_CryptMgr_EncryptKey(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00189 assert(cm); 00190 if (cm->encryptKeyFn) 00191 return cm->encryptKeyFn(cm, pData, lData, dbuf); 00192 else 00193 return GWEN_ERROR_NOT_IMPLEMENTED; 00194 } 00195 00196 00197 00198 int GWEN_CryptMgr_VerifyData(GWEN_CRYPTMGR *cm, 00199 const uint8_t *pData, uint32_t lData, 00200 const uint8_t *pSignature, uint32_t lSignature) { 00201 assert(cm); 00202 if (cm->verifyDataFn) 00203 return cm->verifyDataFn(cm, pData, lData, pSignature, lSignature); 00204 else 00205 return GWEN_ERROR_NOT_IMPLEMENTED; 00206 } 00207 00208 00209 00210 int GWEN_CryptMgr_DecryptKey(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00211 assert(cm); 00212 if (cm->decryptKeyFn) 00213 return cm->decryptKeyFn(cm, pData, lData, dbuf); 00214 else 00215 return GWEN_ERROR_NOT_IMPLEMENTED; 00216 } 00217 00218 00219 00220 GWEN_CRYPTMGR_SIGNDATA_FN GWEN_CryptMgr_SetSignDataFn(GWEN_CRYPTMGR *cm, 00221 GWEN_CRYPTMGR_SIGNDATA_FN f) { 00222 GWEN_CRYPTMGR_SIGNDATA_FN of; 00223 00224 assert(cm); 00225 of=cm->signDataFn; 00226 cm->signDataFn=f; 00227 return of; 00228 } 00229 00230 00231 00232 GWEN_CRYPTMGR_VERIFYDATA_FN GWEN_CryptMgr_SetVerifyDataFn(GWEN_CRYPTMGR *cm, 00233 GWEN_CRYPTMGR_VERIFYDATA_FN f) { 00234 GWEN_CRYPTMGR_VERIFYDATA_FN of; 00235 00236 assert(cm); 00237 of=cm->verifyDataFn; 00238 cm->verifyDataFn=f; 00239 return of; 00240 } 00241 00242 00243 00244 GWEN_CRYPTMGR_ENCRYPTKEY_FN GWEN_CryptMgr_SetEncryptKeyFn(GWEN_CRYPTMGR *cm, 00245 GWEN_CRYPTMGR_ENCRYPTKEY_FN f) { 00246 GWEN_CRYPTMGR_ENCRYPTKEY_FN of; 00247 00248 assert(cm); 00249 of=cm->encryptKeyFn; 00250 cm->encryptKeyFn=f; 00251 return of; 00252 } 00253 00254 00255 00256 GWEN_CRYPTMGR_DECRYPTKEY_FN GWEN_CryptMgr_SetDecryptKeyFn(GWEN_CRYPTMGR *cm, 00257 GWEN_CRYPTMGR_DECRYPTKEY_FN f) { 00258 GWEN_CRYPTMGR_DECRYPTKEY_FN of; 00259 00260 assert(cm); 00261 of=cm->decryptKeyFn; 00262 cm->decryptKeyFn=f; 00263 return of; 00264 } 00265 00266 00267 00268 int GWEN_CryptMgr_Sign(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00269 GWEN_SIGHEAD *sh; 00270 GWEN_SIGTAIL *st; 00271 GWEN_TIME *ti; 00272 uint32_t pos; 00273 uint32_t shPos; 00274 uint8_t *p; 00275 uint32_t l; 00276 int rv; 00277 GWEN_BUFFER *sigbuf; 00278 00279 assert(cm); 00280 GWEN_Buffer_AppendByte(dbuf, GWEN_CRYPTMGR_TLV_SIGNEDOBJECT); 00281 pos=GWEN_Buffer_GetPos(dbuf); 00282 GWEN_Buffer_AppendByte(dbuf, 0); 00283 GWEN_Buffer_AppendByte(dbuf, 0); 00284 00285 /* prepare signature head */ 00286 sh=GWEN_SigHead_new(); 00287 GWEN_SigHead_SetKeyName(sh, cm->localKeyName); 00288 GWEN_SigHead_SetKeyNumber(sh, cm->localKeyNumber); 00289 GWEN_SigHead_SetKeyVersion(sh, cm->localKeyVersion); 00290 ti=GWEN_CurrentTime(); 00291 GWEN_SigHead_SetDateTime(sh, ti); 00292 GWEN_Time_free(ti); 00293 GWEN_SigHead_SetSignatureProfile(sh, cm->signatureProfile); 00294 GWEN_SigHead_SetSignatureNumber(sh, 1); 00295 00296 /* write signature head to buffer */ 00297 shPos=GWEN_Buffer_GetPos(dbuf); 00298 rv=GWEN_SigHead_toBuffer(sh, dbuf, GWEN_CRYPTMGR_TLV_SIGHEAD); 00299 GWEN_SigHead_free(sh); 00300 if (rv<0) { 00301 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00302 return rv; 00303 } 00304 00305 /* write data to buffer */ 00306 if (pData && lData) 00307 GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPTMGR_TLV_SIGDATA, 00308 (const char*)pData, 00309 lData, 00310 dbuf); 00311 00312 /* sign data: signature head TLV + data TLV */ 00313 sigbuf=GWEN_Buffer_new(0, 300, 0, 1); 00314 p=((uint8_t*)GWEN_Buffer_GetStart(dbuf))+shPos; 00315 l=GWEN_Buffer_GetPos(dbuf)-shPos; 00316 rv=GWEN_CryptMgr_SignData(cm, p, l, sigbuf); 00317 if (rv<0) { 00318 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00319 GWEN_Buffer_free(sigbuf); 00320 return rv; 00321 } 00322 00323 /* create signature tail */ 00324 st=GWEN_SigTail_new(); 00325 GWEN_SigTail_SetSignature(st, 00326 (const uint8_t*)GWEN_Buffer_GetStart(sigbuf), 00327 GWEN_Buffer_GetUsedBytes(sigbuf)); 00328 GWEN_Buffer_free(sigbuf); 00329 GWEN_SigTail_SetSignatureNumber(st, 1); 00330 00331 /* write signature tail */ 00332 rv=GWEN_SigTail_toBuffer(st, dbuf, GWEN_CRYPTMGR_TLV_SIGTAIL); 00333 GWEN_SigTail_free(st); 00334 if (rv<0) { 00335 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00336 return rv; 00337 } 00338 00339 /* write complete size */ 00340 l=GWEN_Buffer_GetPos(dbuf)-pos-2; 00341 p=(uint8_t*)GWEN_Buffer_GetStart(dbuf)+pos; 00342 *(p++)=l & 0xff; 00343 *p=(l>>8) & 0xff; 00344 00345 return 0; 00346 } 00347 00348 00349 00350 int GWEN_CryptMgr_Encrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00351 GWEN_CRYPTHEAD *ch; 00352 uint32_t pos; 00353 uint8_t *p; 00354 uint32_t l; 00355 int rv; 00356 GWEN_BUFFER *cryptbuf; 00357 GWEN_BUFFER *tbuf; 00358 GWEN_CRYPT_KEY *mkey; 00359 00360 assert(cm); 00361 00362 /* generate a message key */ 00363 mkey=GWEN_Crypt_KeyBlowFish_Generate(GWEN_Crypt_CryptMode_Cbc, 256/8, 2); 00364 if (mkey==NULL) { 00365 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to generate BLOWFISH key"); 00366 return GWEN_ERROR_GENERIC; 00367 } 00368 00369 GWEN_Buffer_AppendByte(dbuf, GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT); 00370 pos=GWEN_Buffer_GetPos(dbuf); 00371 GWEN_Buffer_AppendByte(dbuf, 0); 00372 GWEN_Buffer_AppendByte(dbuf, 0); 00373 00374 /* prepare signature head */ 00375 ch=GWEN_CryptHead_new(); 00376 GWEN_CryptHead_SetKeyName(ch, cm->peerKeyName); 00377 GWEN_CryptHead_SetKeyNumber(ch, cm->peerKeyNumber); 00378 GWEN_CryptHead_SetKeyVersion(ch, cm->peerKeyVersion); 00379 GWEN_CryptHead_SetCryptProfile(ch, cm->signatureProfile); 00380 00381 /* encrypt key */ 00382 cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1); 00383 rv=GWEN_CryptMgr_EncryptKey(cm, 00384 GWEN_Crypt_KeyBlowFish_GetKeyDataPtr(mkey), 00385 GWEN_Crypt_KeyBlowFish_GetKeyDataLen(mkey), 00386 cryptbuf); 00387 if (rv<0) { 00388 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00389 GWEN_Buffer_free(cryptbuf); 00390 GWEN_CryptHead_free(ch); 00391 GWEN_Crypt_Key_free(mkey); 00392 return rv; 00393 } 00394 GWEN_CryptHead_SetKey(ch, 00395 (const uint8_t*)GWEN_Buffer_GetStart(cryptbuf), 00396 GWEN_Buffer_GetUsedBytes(cryptbuf)); 00397 GWEN_Buffer_free(cryptbuf); 00398 00399 /* write crypt head to buffer */ 00400 rv=GWEN_CryptHead_toBuffer(ch, dbuf, GWEN_CRYPTMGR_TLV_CRYPTHEAD); 00401 GWEN_CryptHead_free(ch); 00402 if (rv<0) { 00403 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00404 GWEN_Crypt_Key_free(mkey); 00405 return rv; 00406 } 00407 00408 /* padd plain text data */ 00409 tbuf=GWEN_Buffer_new(0, lData+256, 0, 1); 00410 GWEN_Buffer_AppendBytes(tbuf, (const char*)pData, lData); 00411 GWEN_Padd_PaddWithAnsiX9_23(tbuf); 00412 00413 /* encrypt with message key */ 00414 cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1); 00415 l=GWEN_Buffer_GetMaxUnsegmentedWrite(cryptbuf); 00416 rv=GWEN_Crypt_Key_Encipher(mkey, 00417 (const uint8_t*)GWEN_Buffer_GetStart(tbuf), 00418 GWEN_Buffer_GetUsedBytes(tbuf), 00419 (uint8_t*)GWEN_Buffer_GetStart(cryptbuf), 00420 &l); 00421 GWEN_Buffer_free(tbuf); 00422 if (rv<0) { 00423 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00424 GWEN_Buffer_free(cryptbuf); 00425 GWEN_Crypt_Key_free(mkey); 00426 return rv; 00427 } 00428 GWEN_Buffer_IncrementPos(cryptbuf, l); 00429 GWEN_Buffer_AdjustUsedBytes(cryptbuf); 00430 00431 /* write encrypted data */ 00432 GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPTMGR_TLV_CRYPTDATA, 00433 GWEN_Buffer_GetStart(cryptbuf), 00434 GWEN_Buffer_GetUsedBytes(cryptbuf), 00435 dbuf); 00436 GWEN_Buffer_free(cryptbuf); 00437 GWEN_Crypt_Key_free(mkey); 00438 00439 /* write complete size */ 00440 l=GWEN_Buffer_GetPos(dbuf)-pos-2; 00441 p=(uint8_t*)GWEN_Buffer_GetStart(dbuf)+pos; 00442 *(p++)=l & 0xff; 00443 *p=(l>>8) & 0xff; 00444 00445 return 0; 00446 } 00447 00448 00449 00450 int GWEN_CryptMgr_Verify(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00451 GWEN_TAG16 *tag; 00452 const uint8_t *p; 00453 uint32_t l; 00454 GWEN_SIGHEAD *sh=NULL; 00455 GWEN_SIGTAIL *st=NULL; 00456 const uint8_t *pSignedData=NULL; 00457 uint32_t lSignedData=0; 00458 int rv; 00459 00460 assert(cm); 00461 if (lData<3) { 00462 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes"); 00463 return GWEN_ERROR_BAD_DATA; 00464 } 00465 00466 tag=GWEN_Tag16_fromBuffer2(pData, lData, 0); 00467 if (tag==NULL) { 00468 DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV"); 00469 return GWEN_ERROR_BAD_DATA; 00470 } 00471 00472 if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_SIGNEDOBJECT) { 00473 DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain asigned object"); 00474 GWEN_Tag16_free(tag); 00475 return GWEN_ERROR_BAD_DATA; 00476 } 00477 00478 p=GWEN_Tag16_GetTagData(tag); 00479 l=GWEN_Tag16_GetTagLength(tag); 00480 00481 /* read sighead */ 00482 if (l) { 00483 GWEN_TAG16 *subtag; 00484 00485 subtag=GWEN_Tag16_fromBuffer2(p, l, 0); 00486 if (subtag) { 00487 if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGHEAD) { 00488 sh=GWEN_SigHead_fromBuffer(GWEN_Tag16_GetTagData(subtag), 00489 GWEN_Tag16_GetTagLength(subtag)); 00490 if (sh) { 00491 pSignedData=p; 00492 lSignedData=GWEN_Tag16_GetTagSize(subtag); 00493 } 00494 } 00495 p+=GWEN_Tag16_GetTagSize(subtag); 00496 l-=GWEN_Tag16_GetTagSize(subtag); 00497 GWEN_Tag16_free(subtag); 00498 } 00499 } 00500 00501 /* read and store signed data */ 00502 if (l) { 00503 GWEN_TAG16 *subtag; 00504 00505 subtag=GWEN_Tag16_fromBuffer2(p, l, 0); 00506 if (subtag) { 00507 if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGDATA) { 00508 GWEN_Buffer_AppendBytes(dbuf, 00509 GWEN_Tag16_GetTagData(subtag), 00510 GWEN_Tag16_GetTagLength(subtag)); 00511 if ((pSignedData+lSignedData)==p) { 00512 lSignedData+=GWEN_Tag16_GetTagSize(subtag); 00513 } 00514 else { 00515 DBG_ERROR(GWEN_LOGDOMAIN, "data TLV must follow sighead TLV"); 00516 GWEN_Tag16_free(subtag); 00517 GWEN_SigHead_free(sh); 00518 GWEN_Tag16_free(tag); 00519 return GWEN_ERROR_BAD_DATA; 00520 } 00521 } 00522 p+=GWEN_Tag16_GetTagSize(subtag); 00523 l-=GWEN_Tag16_GetTagSize(subtag); 00524 GWEN_Tag16_free(subtag); 00525 } 00526 } 00527 00528 /* read sigtail (contains the signature) */ 00529 if (l) { 00530 GWEN_TAG16 *subtag; 00531 00532 subtag=GWEN_Tag16_fromBuffer2(p, l, 0); 00533 if (subtag) { 00534 if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGTAIL) { 00535 st=GWEN_SigTail_fromBuffer(GWEN_Tag16_GetTagData(subtag), 00536 GWEN_Tag16_GetTagLength(subtag)); 00537 } 00538 p+=GWEN_Tag16_GetTagSize(subtag); 00539 l-=GWEN_Tag16_GetTagSize(subtag); 00540 GWEN_Tag16_free(subtag); 00541 } 00542 } 00543 00544 /* check for all needed components */ 00545 if (!(sh && st && pSignedData && lSignedData)) { 00546 DBG_ERROR(GWEN_LOGDOMAIN, "Signed object is not complete"); 00547 GWEN_SigTail_free(st); 00548 GWEN_SigHead_free(sh); 00549 GWEN_Tag16_free(tag); 00550 return GWEN_ERROR_BAD_DATA; 00551 } 00552 00553 if (GWEN_SigHead_GetSignatureNumber(sh)!=GWEN_SigTail_GetSignatureNumber(st)) { 00554 DBG_ERROR(GWEN_LOGDOMAIN, "Sighead doesn't match sigtail"); 00555 GWEN_SigTail_free(st); 00556 GWEN_SigHead_free(sh); 00557 GWEN_Tag16_free(tag); 00558 return GWEN_ERROR_BAD_DATA; 00559 } 00560 00561 /* store or check peer key info */ 00562 if (cm->peerKeyName==NULL) { 00563 /* store peer info */ 00564 GWEN_CryptMgr_SetPeerKeyName(cm, GWEN_SigHead_GetKeyName(sh)); 00565 GWEN_CryptMgr_SetPeerKeyNumber(cm, GWEN_SigHead_GetKeyNumber(sh)); 00566 GWEN_CryptMgr_SetPeerKeyVersion(cm, GWEN_SigHead_GetKeyVersion(sh)); 00567 } 00568 else { 00569 const char *s; 00570 00571 /* compare peer info with expected info */ 00572 s=GWEN_SigHead_GetKeyName(sh); 00573 if (!(cm->peerKeyName && s && (strcasecmp(cm->peerKeyName, s)==0) && 00574 (cm->peerKeyNumber==GWEN_SigHead_GetKeyNumber(sh)) && 00575 (cm->peerKeyVersion==GWEN_SigHead_GetKeyVersion(sh)))) { 00576 DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected peer key information in signature"); 00577 GWEN_SigTail_free(st); 00578 GWEN_SigHead_free(sh); 00579 GWEN_Tag16_free(tag); 00580 00581 return GWEN_ERROR_BAD_DATA; 00582 } 00583 } 00584 00585 /* verify signature */ 00586 rv=GWEN_CryptMgr_VerifyData(cm, 00587 pSignedData, lSignedData, 00588 GWEN_SigTail_GetSignaturePtr(st), 00589 GWEN_SigTail_GetSignatureLen(st)); 00590 GWEN_SigTail_free(st); 00591 GWEN_SigHead_free(sh); 00592 GWEN_Tag16_free(tag); 00593 00594 if (rv<0) { 00595 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00596 return rv; 00597 } 00598 00599 return 0; 00600 } 00601 00602 00603 00604 int GWEN_CryptMgr_Decrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00605 GWEN_TAG16 *tag; 00606 const uint8_t *p; 00607 uint32_t l; 00608 GWEN_CRYPTHEAD *ch=NULL; 00609 const uint8_t *pEncryptedData=NULL; 00610 uint32_t lEncryptedData=0; 00611 int rv; 00612 GWEN_BUFFER *tbuf; 00613 GWEN_CRYPT_KEY *mkey; 00614 00615 assert(cm); 00616 if (lData<3) { 00617 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes"); 00618 return GWEN_ERROR_BAD_DATA; 00619 } 00620 00621 tag=GWEN_Tag16_fromBuffer2(pData, lData, 0); 00622 if (tag==NULL) { 00623 DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV"); 00624 return GWEN_ERROR_BAD_DATA; 00625 } 00626 00627 if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT) { 00628 DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain an encrypted object"); 00629 GWEN_Tag16_free(tag); 00630 return GWEN_ERROR_BAD_DATA; 00631 } 00632 00633 p=GWEN_Tag16_GetTagData(tag); 00634 l=GWEN_Tag16_GetTagLength(tag); 00635 00636 /* read crypthead */ 00637 if (l) { 00638 GWEN_TAG16 *subtag; 00639 00640 subtag=GWEN_Tag16_fromBuffer2(p, l, 0); 00641 if (subtag) { 00642 if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTHEAD) { 00643 ch=GWEN_CryptHead_fromBuffer(GWEN_Tag16_GetTagData(subtag), 00644 GWEN_Tag16_GetTagLength(subtag)); 00645 } 00646 p+=GWEN_Tag16_GetTagSize(subtag); 00647 l-=GWEN_Tag16_GetTagSize(subtag); 00648 GWEN_Tag16_free(subtag); 00649 } 00650 } 00651 00652 /* read encrypted data */ 00653 if (l) { 00654 GWEN_TAG16 *subtag; 00655 00656 subtag=GWEN_Tag16_fromBuffer2(p, l, 0); 00657 if (subtag) { 00658 if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTDATA) { 00659 pEncryptedData=GWEN_Tag16_GetTagData(subtag); 00660 lEncryptedData=GWEN_Tag16_GetTagLength(subtag); 00661 } 00662 p+=GWEN_Tag16_GetTagSize(subtag); 00663 l-=GWEN_Tag16_GetTagSize(subtag); 00664 GWEN_Tag16_free(subtag); 00665 } 00666 } 00667 00668 /* check for all needed components */ 00669 if (!(ch && pEncryptedData && lEncryptedData)) { 00670 DBG_ERROR(GWEN_LOGDOMAIN, "Encrypted object is not complete"); 00671 GWEN_CryptHead_free(ch); 00672 GWEN_Tag16_free(tag); 00673 return GWEN_ERROR_BAD_DATA; 00674 } 00675 00676 /* store or check peer key info */ 00677 if (cm->localKeyName) { 00678 const char *s; 00679 00680 /* compare peer info with expected info */ 00681 s=GWEN_CryptHead_GetKeyName(ch); 00682 if (!(cm->localKeyName && s && (strcasecmp(cm->localKeyName, s)==0) && 00683 (cm->localKeyNumber==GWEN_CryptHead_GetKeyNumber(ch)) && 00684 (cm->localKeyVersion==GWEN_CryptHead_GetKeyVersion(ch)))) { 00685 DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected local key information in signature"); 00686 GWEN_CryptHead_free(ch); 00687 GWEN_Tag16_free(tag); 00688 00689 return GWEN_ERROR_BAD_DATA; 00690 } 00691 } 00692 00693 /* decrypt message key */ 00694 tbuf=GWEN_Buffer_new(0, GWEN_CryptHead_GetKeyLen(ch), 0, 1); 00695 rv=GWEN_CryptMgr_DecryptKey(cm, 00696 GWEN_CryptHead_GetKeyPtr(ch), 00697 GWEN_CryptHead_GetKeyLen(ch), 00698 tbuf); 00699 GWEN_CryptHead_free(ch); 00700 if (rv<0) { 00701 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00702 GWEN_Buffer_free(tbuf); 00703 GWEN_Tag16_free(tag); 00704 return rv; 00705 } 00706 00707 /* create message key */ 00708 mkey=GWEN_Crypt_KeyBlowFish_fromData(GWEN_Crypt_CryptMode_Cbc, 00709 256/8, 00710 (const uint8_t*) GWEN_Buffer_GetStart(tbuf), 00711 GWEN_Buffer_GetUsedBytes(tbuf)); 00712 GWEN_Buffer_free(tbuf); 00713 if (mkey==NULL) { 00714 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to create BLOWFISH key from received data"); 00715 GWEN_Tag16_free(tag); 00716 return GWEN_ERROR_BAD_DATA; 00717 } 00718 00719 00720 /* decrypt data with message key */ 00721 tbuf=GWEN_Buffer_new(0, lEncryptedData+256, 0, 1); 00722 l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf); 00723 rv=GWEN_Crypt_Key_Decipher(mkey, 00724 pEncryptedData, lEncryptedData, 00725 (uint8_t*)GWEN_Buffer_GetStart(tbuf), 00726 &l); 00727 if (rv<0) { 00728 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00729 GWEN_Buffer_free(tbuf); 00730 GWEN_Crypt_Key_free(mkey); 00731 GWEN_Tag16_free(tag); 00732 return rv; 00733 } 00734 GWEN_Buffer_IncrementPos(tbuf, l); 00735 GWEN_Buffer_AdjustUsedBytes(tbuf); 00736 00737 /* unpadd data */ 00738 rv=GWEN_Padd_UnpaddWithAnsiX9_23(tbuf); 00739 if (rv<0) { 00740 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00741 GWEN_Buffer_free(tbuf); 00742 GWEN_Crypt_Key_free(mkey); 00743 GWEN_Tag16_free(tag); 00744 return rv; 00745 } 00746 00747 /* store data */ 00748 GWEN_Buffer_AppendBuffer(dbuf, tbuf); 00749 00750 GWEN_Buffer_free(tbuf); 00751 GWEN_Crypt_Key_free(mkey); 00752 GWEN_Tag16_free(tag); 00753 00754 return 0; 00755 } 00756 00757 00758 00759 int GWEN_CryptMgr_Encode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00760 GWEN_BUFFER *tbuf; 00761 int rv; 00762 00763 tbuf=GWEN_Buffer_new(0, lData, 0, 1); 00764 00765 /* create signed object */ 00766 DBG_INFO(GWEN_LOGDOMAIN, "Signing data"); 00767 rv=GWEN_CryptMgr_Sign(cm, pData, lData, tbuf); 00768 if (rv<0) { 00769 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00770 GWEN_Buffer_free(tbuf); 00771 return rv; 00772 } 00773 00774 /* create encrypted object (containing a signed object in this case) */ 00775 DBG_INFO(GWEN_LOGDOMAIN, "Encrypting data"); 00776 rv=GWEN_CryptMgr_Encrypt(cm, 00777 (const uint8_t*)GWEN_Buffer_GetStart(tbuf), 00778 GWEN_Buffer_GetUsedBytes(tbuf), 00779 dbuf); 00780 GWEN_Buffer_free(tbuf); 00781 if (rv<0) { 00782 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00783 return rv; 00784 } 00785 00786 return 0; 00787 } 00788 00789 00790 00791 int GWEN_CryptMgr_Decode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { 00792 GWEN_BUFFER *tbuf; 00793 int rv; 00794 00795 tbuf=GWEN_Buffer_new(0, lData, 0, 1); 00796 00797 /* decrypt encrypted object */ 00798 DBG_INFO(GWEN_LOGDOMAIN, "Decrypting data"); 00799 rv=GWEN_CryptMgr_Decrypt(cm, pData, lData, tbuf); 00800 if (rv<0) { 00801 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00802 GWEN_Buffer_free(tbuf); 00803 return rv; 00804 } 00805 00806 /* verify signature, copy signed data to dbuf in the process */ 00807 DBG_INFO(GWEN_LOGDOMAIN, "Verifying data"); 00808 rv=GWEN_CryptMgr_Verify(cm, 00809 (const uint8_t*)GWEN_Buffer_GetStart(tbuf), 00810 GWEN_Buffer_GetUsedBytes(tbuf), 00811 dbuf); 00812 GWEN_Buffer_free(tbuf); 00813 if (rv<0) { 00814 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00815 return rv; 00816 } 00817 00818 return 0; 00819 } 00820 00821 00822 00823 00824