void EB_Msg_toBuffer(EB_MSG *m, GWEN_BUFFER *buf) { xmlChar *xmlbuff; int buffersize; assert(m); assert(m->usage); xmlDocDumpFormatMemory(m->doc, &xmlbuff, &buffersize, 0); GWEN_Buffer_AppendBytes(buf, (const char*)xmlbuff, (uint32_t)buffersize); xmlFree(xmlbuff); }
LC_CLIENT_RESULT LC_DDVCard_CryptCharBlock(LC_CARD *card, const char *data, unsigned int dlen, GWEN_BUFFER *obuf){ LC_DDVCARD *ddv; GWEN_DB_NODE *dbReq; GWEN_DB_NODE *dbResp; LC_CLIENT_RESULT res; const void *p; unsigned int bs; assert(card); ddv=GWEN_INHERIT_GETDATA(LC_CARD, LC_DDVCARD, card); assert(ddv); if (dlen!=8) { DBG_ERROR(LC_LOGDOMAIN, "In-block must exactly be 8 bytes in length (is %d)", dlen); return LC_Client_ResultDataError; } dbReq=GWEN_DB_Group_new("CryptBlock"); dbResp=GWEN_DB_Group_new("response"); GWEN_DB_SetBinValue(dbReq, GWEN_DB_FLAGS_DEFAULT, "in", data, dlen); res=LC_Card_ExecCommand(card, "CryptBlock", dbReq, dbResp); if (res!=LC_Client_ResultOk) { GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return res; } p=GWEN_DB_GetBinValue(dbResp, "response/out", 0, 0, 0, &bs); if ( p && bs==8) GWEN_Buffer_AppendBytes(obuf, p, bs); else { DBG_ERROR(LC_LOGDOMAIN, "Expected 8 bytes response, got %d bytes", bs); GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return LC_Client_ResultDataError; } GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return LC_Client_ResultOk; }
GWENHYWFAR_CB int GWEN_CryptMgrKeys_EncryptKey(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { GWEN_CRYPTMGR_KEYS *xcm; int rv; GWEN_BUFFER *tbuf; int ksize; uint32_t l; assert(cm); xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm); assert(xcm); if (xcm->peerKey==NULL) { DBG_ERROR(GWEN_LOGDOMAIN, "No peer key"); return GWEN_ERROR_GENERIC; } ksize=GWEN_Crypt_Key_GetKeySize(xcm->peerKey); /* padd key data */ tbuf=GWEN_Buffer_new(0, ksize, 0, 1); GWEN_Buffer_AppendBytes(tbuf, (const char*) pData, lData); rv=GWEN_Padd_PaddWithIso9796_2(tbuf, ksize); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } GWEN_Buffer_AllocRoom(dbuf, ksize); l=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf); rv=GWEN_Crypt_Key_Encipher(xcm->peerKey, (const uint8_t*)GWEN_Buffer_GetStart(tbuf), GWEN_Buffer_GetUsedBytes(tbuf), (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf), &l); GWEN_Buffer_free(tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); return rv; } GWEN_Buffer_IncrementPos(dbuf, l); GWEN_Buffer_AdjustUsedBytes(dbuf); return 0; }
LC_CLIENT_RESULT LC_DDVCard_GetChallenge(LC_CARD *card, GWEN_BUFFER *mbuf){ LC_DDVCARD *ddv; GWEN_DB_NODE *dbReq; GWEN_DB_NODE *dbResp; LC_CLIENT_RESULT res; const void *p; unsigned int bs; assert(card); ddv=GWEN_INHERIT_GETDATA(LC_CARD, LC_DDVCARD, card); assert(ddv); dbReq=GWEN_DB_Group_new("GetChallenge"); dbResp=GWEN_DB_Group_new("response"); res=LC_Card_ExecCommand(card, "GetChallenge", dbReq, dbResp); if (res!=LC_Client_ResultOk) { GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return res; } p=GWEN_DB_GetBinValue(dbResp, "response/challenge", 0, 0, 0, &bs); if (p && bs==8) { GWEN_Buffer_AppendBytes(mbuf, p, bs); } else { DBG_ERROR(LC_LOGDOMAIN, "Expected 8 bytes response, got %d bytes", bs); GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return LC_Client_ResultDataError; } GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return res; }
/* --------------------------------------------------------------- FUNCTION */ int AH_Job_SepaStandingOrdersGet__ReadSto(AH_JOB *j, AB_IMEXPORTER_CONTEXT *ctx, const uint8_t *ptr, uint32_t len, const char *fiId){ int rv; AB_IMEXPORTER_CONTEXT *tmpCtx; GWEN_BUFFER *tbuf; AB_IMEXPORTER_ACCOUNTINFO *ai; tmpCtx=AB_ImExporterContext_new(); tbuf=GWEN_Buffer_new(0, 256, 0, 1); GWEN_Buffer_AppendBytes(tbuf, (const char*) ptr, len); rv=AB_Banking_ImportBuffer(AH_Job_GetBankingApi(j), tmpCtx, "sepa", "default", tbuf); if (rv<0) { DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); AB_ImExporterContext_free(tmpCtx); return rv; } GWEN_Buffer_free(tbuf); ai=AB_ImExporterContext_GetFirstAccountInfo(tmpCtx); if (ai) { AB_TRANSACTION *t; while( (t=AB_ImExporterAccountInfo_GetFirstTransaction(ai)) ) { AB_Transaction_List_Del(t); AB_Transaction_SetFiId(t, fiId); /* add to real im/exporter context */ AB_ImExporterContext_AddTransaction(ctx, t); } } AB_ImExporterContext_free(tmpCtx); return 0; }
int AH_Msg_DecryptPinTan(AH_MSG *hmsg, GWEN_DB_NODE *gr){ AH_HBCI *h; GWEN_BUFFER *mbuf; uint32_t l; const uint8_t *p; GWEN_MSGENGINE *e; AB_USER *u; const char *peerId; // uint32_t uFlags; GWEN_DB_NODE *nhead=NULL; GWEN_DB_NODE *ndata=NULL; const char *crypterId; assert(hmsg); h=AH_Dialog_GetHbci(hmsg->dialog); assert(h); e=AH_Dialog_GetMsgEngine(hmsg->dialog); assert(e); GWEN_MsgEngine_SetMode(e, "pintan"); u=AH_Dialog_GetDialogOwner(hmsg->dialog); // uFlags=AH_User_GetFlags(u); peerId=AH_User_GetPeerId(u); if (!peerId || *peerId==0) peerId=AB_User_GetUserId(u); /* get encrypted session key */ nhead=GWEN_DB_GetGroup(gr, GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_NAMEMUSTEXIST, "CryptHead"); if (!nhead) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt head"); return GWEN_ERROR_BAD_DATA; } ndata=GWEN_DB_GetGroup(gr, GWEN_DB_FLAGS_DEFAULT | GWEN_PATH_FLAGS_NAMEMUSTEXIST, "CryptData"); if (!ndata) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt data"); return GWEN_ERROR_BAD_DATA; } crypterId=GWEN_DB_GetCharValue(nhead, "key/userId", 0, I18N("unknown")); /* get encrypted data */ p=GWEN_DB_GetBinValue(ndata, "CryptData", 0, 0,0, &l); if (!p || !l) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt data"); return GWEN_ERROR_BAD_DATA; } /* decipher message with session key */ mbuf=GWEN_Buffer_new(0, l, 0, 1); GWEN_Buffer_AppendBytes(mbuf, (const char*)p, l); /* store crypter id */ AH_Msg_SetCrypterId(hmsg, crypterId); /* store new buffer inside message */ GWEN_Buffer_free(hmsg->origbuffer); hmsg->origbuffer=hmsg->buffer; GWEN_Buffer_Rewind(mbuf); hmsg->buffer=mbuf; return 0; }
int Gtk2Gui_GetRawText(const char *text, GWEN_BUFFER *tbuf) { const char *p=0; const char *p2=0; if (text==NULL) return 0; /* find begin of HTML area */ p=text; while ((p=strchr(p, '<'))) { const char *t; t=p; t++; if (toupper(*t)=='H') { t++; if (toupper(*t)=='T') { t++; if (toupper(*t)=='M') { t++; if (toupper(*t)=='L') { t++; if (toupper(*t)=='>') { break; } } } } } p++; } /* while */ /* find end of HTML area */ if (p) { p2=p; p2+=6; /* skip "<html>" */ while ((p2=strchr(p2, '<'))) { const char *t; t=p2; t++; if (toupper(*t)=='/') { t++; if (toupper(*t)=='H') { t++; if (toupper(*t)=='T') { t++; if (toupper(*t)=='M') { t++; if (toupper(*t)=='L') { t++; if (toupper(*t)=='>') { break; } } } } } } p2++; } /* while */ } if (p && p2) { int startPos; int endPos; p2+=7; /* skip "</html>" */ startPos=(p-text); endPos=(p2-text); /* append stuff before startPos */ if (startPos) GWEN_Buffer_AppendBytes(tbuf, text, startPos); if (*p2) GWEN_Buffer_AppendString(tbuf, p2); return 0; } else { GWEN_Buffer_AppendString(tbuf, text); return 0; } }
int GWEN_CryptMgr_Verify(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { GWEN_TAG16 *tag; const uint8_t *p; uint32_t l; GWEN_SIGHEAD *sh=NULL; GWEN_SIGTAIL *st=NULL; const uint8_t *pSignedData=NULL; uint32_t lSignedData=0; int rv; assert(cm); if (lData<3) { DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes"); return GWEN_ERROR_BAD_DATA; } tag=GWEN_Tag16_fromBuffer2(pData, lData, 0); if (tag==NULL) { DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV"); return GWEN_ERROR_BAD_DATA; } if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_SIGNEDOBJECT) { DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain asigned object"); GWEN_Tag16_free(tag); return GWEN_ERROR_BAD_DATA; } p=GWEN_Tag16_GetTagData(tag); l=GWEN_Tag16_GetTagLength(tag); /* read sighead */ if (l) { GWEN_TAG16 *subtag; subtag=GWEN_Tag16_fromBuffer2(p, l, 0); if (subtag) { if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGHEAD) { sh=GWEN_SigHead_fromBuffer(GWEN_Tag16_GetTagData(subtag), GWEN_Tag16_GetTagLength(subtag)); if (sh) { pSignedData=p; lSignedData=GWEN_Tag16_GetTagSize(subtag); } } p+=GWEN_Tag16_GetTagSize(subtag); l-=GWEN_Tag16_GetTagSize(subtag); GWEN_Tag16_free(subtag); } } /* read and store signed data */ if (l) { GWEN_TAG16 *subtag; subtag=GWEN_Tag16_fromBuffer2(p, l, 0); if (subtag) { if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGDATA) { GWEN_Buffer_AppendBytes(dbuf, GWEN_Tag16_GetTagData(subtag), GWEN_Tag16_GetTagLength(subtag)); if ((pSignedData+lSignedData)==p) { lSignedData+=GWEN_Tag16_GetTagSize(subtag); } else { DBG_ERROR(GWEN_LOGDOMAIN, "data TLV must follow sighead TLV"); GWEN_Tag16_free(subtag); GWEN_SigHead_free(sh); GWEN_Tag16_free(tag); return GWEN_ERROR_BAD_DATA; } } p+=GWEN_Tag16_GetTagSize(subtag); l-=GWEN_Tag16_GetTagSize(subtag); GWEN_Tag16_free(subtag); } } /* read sigtail (contains the signature) */ if (l) { GWEN_TAG16 *subtag; subtag=GWEN_Tag16_fromBuffer2(p, l, 0); if (subtag) { if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGTAIL) { st=GWEN_SigTail_fromBuffer(GWEN_Tag16_GetTagData(subtag), GWEN_Tag16_GetTagLength(subtag)); } p+=GWEN_Tag16_GetTagSize(subtag); l-=GWEN_Tag16_GetTagSize(subtag); GWEN_Tag16_free(subtag); } } /* check for all needed components */ if (!(sh && st && pSignedData && lSignedData)) { DBG_ERROR(GWEN_LOGDOMAIN, "Signed object is not complete"); GWEN_SigTail_free(st); GWEN_SigHead_free(sh); GWEN_Tag16_free(tag); return GWEN_ERROR_BAD_DATA; } if (GWEN_SigHead_GetSignatureNumber(sh)!=GWEN_SigTail_GetSignatureNumber(st)) { DBG_ERROR(GWEN_LOGDOMAIN, "Sighead doesn't match sigtail"); GWEN_SigTail_free(st); GWEN_SigHead_free(sh); GWEN_Tag16_free(tag); return GWEN_ERROR_BAD_DATA; } /* store or check peer key info */ if (cm->peerKeyName==NULL) { /* store peer info */ GWEN_CryptMgr_SetPeerKeyName(cm, GWEN_SigHead_GetKeyName(sh)); GWEN_CryptMgr_SetPeerKeyNumber(cm, GWEN_SigHead_GetKeyNumber(sh)); GWEN_CryptMgr_SetPeerKeyVersion(cm, GWEN_SigHead_GetKeyVersion(sh)); } else { const char *s; /* compare peer info with expected info */ s=GWEN_SigHead_GetKeyName(sh); if (!(cm->peerKeyName && s && (strcasecmp(cm->peerKeyName, s)==0) && (cm->peerKeyNumber==GWEN_SigHead_GetKeyNumber(sh)) && (cm->peerKeyVersion==GWEN_SigHead_GetKeyVersion(sh)))) { DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected peer key information in signature"); GWEN_SigTail_free(st); GWEN_SigHead_free(sh); GWEN_Tag16_free(tag); return GWEN_ERROR_BAD_DATA; } } /* verify signature */ rv=GWEN_CryptMgr_VerifyData(cm, pSignedData, lSignedData, GWEN_SigTail_GetSignaturePtr(st), GWEN_SigTail_GetSignatureLen(st)); GWEN_SigTail_free(st); GWEN_SigHead_free(sh); GWEN_Tag16_free(tag); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); return rv; } return 0; }
int GWEN_CryptMgr_Encrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { GWEN_CRYPTHEAD *ch; uint32_t pos; uint8_t *p; uint32_t l; int rv; GWEN_BUFFER *cryptbuf; GWEN_BUFFER *tbuf; GWEN_CRYPT_KEY *mkey; assert(cm); /* generate a message key */ mkey=GWEN_Crypt_KeyBlowFish_Generate(GWEN_Crypt_CryptMode_Cbc, 256/8, 2); if (mkey==NULL) { DBG_ERROR(GWEN_LOGDOMAIN, "Unable to generate BLOWFISH key"); return GWEN_ERROR_GENERIC; } GWEN_Buffer_AppendByte(dbuf, GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT); pos=GWEN_Buffer_GetPos(dbuf); GWEN_Buffer_AppendByte(dbuf, 0); GWEN_Buffer_AppendByte(dbuf, 0); /* prepare signature head */ ch=GWEN_CryptHead_new(); GWEN_CryptHead_SetKeyName(ch, cm->peerKeyName); GWEN_CryptHead_SetKeyNumber(ch, cm->peerKeyNumber); GWEN_CryptHead_SetKeyVersion(ch, cm->peerKeyVersion); GWEN_CryptHead_SetCryptProfile(ch, cm->signatureProfile); /* encrypt key */ cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1); rv=GWEN_CryptMgr_EncryptKey(cm, GWEN_Crypt_KeyBlowFish_GetKeyDataPtr(mkey), GWEN_Crypt_KeyBlowFish_GetKeyDataLen(mkey), cryptbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(cryptbuf); GWEN_CryptHead_free(ch); GWEN_Crypt_Key_free(mkey); return rv; } GWEN_CryptHead_SetKey(ch, (const uint8_t*)GWEN_Buffer_GetStart(cryptbuf), GWEN_Buffer_GetUsedBytes(cryptbuf)); GWEN_Buffer_free(cryptbuf); /* write crypt head to buffer */ rv=GWEN_CryptHead_toBuffer(ch, dbuf, GWEN_CRYPTMGR_TLV_CRYPTHEAD); GWEN_CryptHead_free(ch); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Crypt_Key_free(mkey); return rv; } /* padd plain text data */ tbuf=GWEN_Buffer_new(0, lData+256, 0, 1); GWEN_Buffer_AppendBytes(tbuf, (const char*)pData, lData); GWEN_Padd_PaddWithAnsiX9_23(tbuf); /* encrypt with message key */ cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1); l=GWEN_Buffer_GetMaxUnsegmentedWrite(cryptbuf); rv=GWEN_Crypt_Key_Encipher(mkey, (const uint8_t*)GWEN_Buffer_GetStart(tbuf), GWEN_Buffer_GetUsedBytes(tbuf), (uint8_t*)GWEN_Buffer_GetStart(cryptbuf), &l); GWEN_Buffer_free(tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(cryptbuf); GWEN_Crypt_Key_free(mkey); return rv; } GWEN_Buffer_IncrementPos(cryptbuf, l); GWEN_Buffer_AdjustUsedBytes(cryptbuf); /* write encrypted data */ GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPTMGR_TLV_CRYPTDATA, GWEN_Buffer_GetStart(cryptbuf), GWEN_Buffer_GetUsedBytes(cryptbuf), dbuf); GWEN_Buffer_free(cryptbuf); GWEN_Crypt_Key_free(mkey); /* write complete size */ l=GWEN_Buffer_GetPos(dbuf)-pos-2; p=(uint8_t*)GWEN_Buffer_GetStart(dbuf)+pos; *(p++)=l & 0xff; *p=(l>>8) & 0xff; return 0; }
LC_CLIENT_RESULT LC_Client_ExecApdu(LC_CLIENT *cl, LC_CARD *card, const char *apdu, unsigned int apdulen, GWEN_BUFFER *rbuf, LC_CLIENT_CMDTARGET t) { LONG rv; unsigned char rbuffer[300]; DWORD rblen; assert(cl); assert(card); assert(apdu); assert(apdulen>3); if (t==LC_Client_CmdTargetReader) { int feature; uint32_t controlCode; feature=apdu[0]; controlCode= (apdu[1]<<24)+ (apdu[2]<<16)+ (apdu[3]<<8)+ apdu[4]; if (feature && controlCode==0) controlCode=LC_Card_GetFeatureCode(card, feature); if (controlCode==0) { DBG_ERROR(LC_LOGDOMAIN, "Bad control code for feature %d of reader \"%s\"", feature, LC_Card_GetReaderName(card)); return LC_Client_ResultInvalid; } DBG_DEBUG(LC_LOGDOMAIN, "Sending command to reader (control: %08x):", controlCode); GWEN_Text_LogString((const char*)apdu+5, apdulen-5, LC_LOGDOMAIN, GWEN_LoggerLevel_Debug); rblen=sizeof(rbuffer); rv=SCardControl(LC_Card_GetSCardHandle(card), controlCode, apdu+5, apdulen-5, rbuffer, sizeof(rbuffer), &rblen); if (rv!=SCARD_S_SUCCESS) { DBG_ERROR(LC_LOGDOMAIN, "SCardControl: %04lx", (long unsigned int) rv); return LC_Client_ResultIoError; } if (rblen) { GWEN_Buffer_AppendBytes(rbuf, (const char*)rbuffer, rblen); if (rblen>1) { LC_Card_SetLastResult(card, "ok", "SCardControl succeeded", rbuffer[rblen-2], rbuffer[rblen-1]); } } return LC_Client_ResultOk; } else { SCARD_IO_REQUEST txHeader; SCARD_IO_REQUEST rxHeader; DBG_DEBUG(LC_LOGDOMAIN, "Sending command to card:"); GWEN_Text_LogString((const char*)apdu, apdulen, LC_LOGDOMAIN, GWEN_LoggerLevel_Debug); txHeader.dwProtocol=LC_Card_GetProtocol(card); //txHeader.dwProtocol=1; txHeader.cbPciLength=sizeof(txHeader); rxHeader.cbPciLength=sizeof(rxHeader); rblen=sizeof(rbuffer); rv=SCardTransmit(LC_Card_GetSCardHandle(card), &txHeader, (LPCBYTE) apdu, apdulen, &rxHeader, rbuffer, &rblen); if (rv!=SCARD_S_SUCCESS) { DBG_ERROR(LC_LOGDOMAIN, "SCardControl: %04lx", (long unsigned int) rv); return LC_Client_ResultIoError; } DBG_DEBUG(LC_LOGDOMAIN, "Received response:"); GWEN_Text_LogString((const char*)rbuffer, rblen, LC_LOGDOMAIN, GWEN_LoggerLevel_Debug); if (rblen) { GWEN_Buffer_AppendBytes(rbuf, (const char*)rbuffer, rblen); if (rblen>1) { LC_Card_SetLastResult(card, "ok", "SCardTransmit succeeded", rbuffer[rblen-2], rbuffer[rblen-1]); } } else { DBG_DEBUG(LC_LOGDOMAIN, "Empty response"); } return LC_Client_ResultOk; } }
int check2() { AB_BANKING *ab; AB_PROVIDER *pro; int rv; AH_MEDIUM *medium=0; GWEN_CRYPTKEY *localCryptKey=0; GWEN_CRYPTKEY *msgKey=0; int err; char keybuffer[16]; unsigned int bsize; AH_MEDIUM_RESULT res; GWEN_BUFFER *plainKeyBuf; GWEN_BUFFER *encKeyBuf; GWEN_BUFFER *decKeyBuf; const char *p1, *p2; int i; GWEN_GUI *gui; fprintf(stderr, "Check2:\n"); gui=GWEN_Gui_CGui_new(); GWEN_Gui_SetGetPasswordFn(gui, _getPin); unlink("check2.medium"); ab=AB_Banking_new("hbci-check1", 0, 0); rv=AB_Banking_Init(ab); if (rv) { DBG_ERROR(0, "Error on init (%d)", rv); return 2; } pro=AB_Banking_GetProvider(ab, "aqhbci"); assert(pro); medium=AH_Provider_MediumFactory(pro, "ohbci", 0, "check2.medium"); if (!medium) { DBG_ERROR(0, "Could not create medium object"); AB_Banking_Fini(ab); return 3; } fprintf(stderr, " Creating medium ...\n"); rv=AH_Medium_Create(medium); if (rv) { DBG_ERROR(0, "Could not create medium (%d)", rv); return 3; } fprintf(stderr, " Mounting medium ...\n"); rv=AH_Medium_Mount(medium); if (rv) { DBG_ERROR(0, "Could not mount medium (%d)", rv); return 3; } fprintf(stderr, " Selecting context ...\n"); rv=AH_Medium_SelectContext(medium, 0); if (rv) { DBG_ERROR(0, "Could not select context (%d)", rv); return 3; } fprintf(stderr, " Creating keys ...\n"); rv=AH_Medium_CreateKeys(medium); if (rv) { DBG_ERROR(0, "Could not create keys (%d)", rv); return 3; } localCryptKey=AH_Medium_GetLocalPubCryptKey(medium); if (!localCryptKey) { DBG_ERROR(0, "No local crypt key."); return 3; } fprintf(stderr, " Storing remote public key ...\n"); rv=AH_Medium_SetPubCryptKey(medium, localCryptKey); if (rv) { DBG_ERROR(0, "Could not store remote crypt key (%d)", rv); return 3; } fprintf(stderr, " Creating DES key object ...\n"); msgKey=GWEN_CryptKey_Factory("DES"); if (!msgKey) { DBG_ERROR(0, "Could not create message key (%d)", rv); return 3; } fprintf(stderr, " Generating DES message key ...\n"); err=GWEN_CryptKey_Generate(msgKey, 16); if (err) { DBG_ERROR_ERR(0, err); return 3; } fprintf(stderr, " Getting data of message key ...\n"); bsize=sizeof(keybuffer); err=GWEN_CryptKey_GetData(msgKey, keybuffer, &bsize); if (err) { DBG_ERROR_ERR(0, err); return 3; } fprintf(stderr, " Encrypting message key ...\n"); plainKeyBuf=GWEN_Buffer_new(0, 256, 0, 1); GWEN_Buffer_AppendBytes(plainKeyBuf, keybuffer, bsize); encKeyBuf=GWEN_Buffer_new(0, 256, 0, 1); res=AH_Medium_EncryptKey(medium, plainKeyBuf, encKeyBuf, 1); if (res!=AH_MediumResultOk) { DBG_ERROR(0, "Error %d", res); return 3; } fprintf(stderr, " Decrypting message key ...\n"); decKeyBuf=GWEN_Buffer_new(0, 256, 0, 1); res=AH_Medium_DecryptKey(medium, encKeyBuf, decKeyBuf, 1); if (res!=AH_MediumResultOk) { DBG_ERROR(0, "Error %d", res); return 3; } fprintf(stderr, " Comparing message key ...\n"); p1=GWEN_Buffer_GetStart(plainKeyBuf); p2=GWEN_Buffer_GetStart(decKeyBuf); rv=0; for (i=0; i<GWEN_Buffer_GetUsedBytes(plainKeyBuf); i++) { if (p1[i]!=p2[i]) { fprintf(stderr, "Buffer1:\n"); GWEN_Buffer_Dump(plainKeyBuf, stderr, 2); fprintf(stderr, "Buffer2:\n"); GWEN_Buffer_Dump(decKeyBuf, stderr, 2); fprintf(stderr, "Differ at %d (%04x)\n", i, i); rv=-1; break; } } if (rv) { fprintf(stderr, "Data differs in content\n"); return 3; } fprintf(stderr, " Unmounting medium ...\n"); rv=AH_Medium_Unmount(medium, 1); if (rv) { DBG_ERROR(0, "Could not unmount medium (%d)", rv); return 3; } rv=AB_Banking_Fini(ab); if (rv) { DBG_ERROR(0, "Could not deinit banking (%d)", rv); return 3; } unlink("check2.medium"); fprintf(stderr, "Check2: PASSED\n"); return 0; }
GWENHYWFAR_CB int GWEN_CryptMgrKeys_SignData(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { GWEN_CRYPTMGR_KEYS *xcm; GWEN_MDIGEST *md; int rv; GWEN_BUFFER *tbuf; int ksize; uint32_t signatureLen; assert(cm); xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm); assert(xcm); if (xcm->localKey==NULL) { DBG_ERROR(GWEN_LOGDOMAIN, "No local key"); return GWEN_ERROR_GENERIC; } ksize=GWEN_Crypt_Key_GetKeySize(xcm->localKey); /* hash pData */ md=GWEN_MDigest_Rmd160_new(); rv=GWEN_MDigest_Begin(md); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); return rv; } rv=GWEN_MDigest_Update(md, pData, lData); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); return rv; } rv=GWEN_MDigest_End(md); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); return rv; } /* padd */ tbuf=GWEN_Buffer_new(0, ksize, 0, 1); GWEN_Buffer_AppendBytes(tbuf, (const char*)GWEN_MDigest_GetDigestPtr(md), GWEN_MDigest_GetDigestSize(md)); GWEN_MDigest_free(md); GWEN_Padd_PaddWithIso9796_2(tbuf, ksize); /* sign */ GWEN_Buffer_AllocRoom(dbuf, ksize); signatureLen=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf); rv=GWEN_Crypt_Key_Sign(xcm->localKey, (uint8_t*)GWEN_Buffer_GetStart(tbuf), GWEN_Buffer_GetUsedBytes(tbuf), (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf), &signatureLen); GWEN_Buffer_free(tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); return rv; } GWEN_Buffer_IncrementPos(dbuf, signatureLen); GWEN_Buffer_AdjustUsedBytes(dbuf); return 0; }
GWEN_URL *GWEN_Url_fromString(const char *str) { GWEN_URL *url; GWEN_DB_NODE *dbVars; const char *s; const char *p; int starts_with_drive_letter = 0; url=GWEN_Url_new(); dbVars=GWEN_DB_Group_new("vars"); GWEN_Url_SetVars(url, dbVars); GWEN_DB_Group_free(dbVars); dbVars=0; s=str; /* Check for a drive letter, which occurs on windows, but this will always be one single alpha character followed by a colon followed by a directory separator. */ if (s && isalpha(s[0]) && s[1] == ':' && (s[2] == '/' || s[2] == '\\')) { starts_with_drive_letter = 1; } /* read protocol (if any) */ p = starts_with_drive_letter ? s : strchr(s, ':'); if (p) { if (p[1]=='/' && p[2]=='/') { char *buf; /* got protocol settings */ buf=(char*)malloc(p-s+1); assert(buf); memmove(buf, s, p-s+1); buf[p-s]=0; GWEN_Url_SetProtocol(url, buf); free(buf); s=p+3; } } if (!*s) { DBG_ERROR(GWEN_LOGDOMAIN, "No server or path given in url \"%s\"", str); GWEN_Url_free(url); return 0; } /* read user/password */ p=strchr(s, '@'); if (p) { char *upw; char *pw; char *pat; upw=(char*)malloc(p-s+1); assert(upw); memmove(upw, s, p-s); upw[p-s]=0; pw=strchr(upw, ':'); if (pw) { /* there is also a password */ *pw=0; pw++; } pat=strchr(upw, '%'); if (pat) *pat='@'; GWEN_Url_SetUserName(url, upw); if (pw) GWEN_Url_SetPassword(url, pw); free(upw); s=p+1; } /* Do we now have a drive letter? (After the protocol?) */ if (!starts_with_drive_letter && s && isalpha(s[0]) && s[1] == ':' && (s[2] == '/' || s[2] == '\\')) { starts_with_drive_letter = 1; } /* read server */ if (!*s) { DBG_ERROR(GWEN_LOGDOMAIN, "No server given in url \"%s\"", str); GWEN_Url_free(url); return 0; } p=s; while(!starts_with_drive_letter && *p && *p!=':' && *p!='/' && *p!='?') p++; if (p!=s) { char *buf; /* got server */ buf=(char*)malloc(p-s+1); assert(buf); memmove(buf, s, p-s+1); buf[p-s]=0; GWEN_Url_SetServer(url, buf); DBG_DEBUG(GWEN_LOGDOMAIN, "Server: [%s]", buf); free(buf); s=p; } /* get port */ if (*s==':') { p=++s; while(*p && *p!='?' && *p!='/') p++; if (p!=s) { char *buf; int port; /* got port */ buf=(char*)malloc(p-s+1); assert(buf); memmove(buf, s, p-s+1); buf[p-s]=0; if (sscanf(buf, "%d", &port)!=1) { DBG_ERROR(GWEN_LOGDOMAIN, "Bad port (%s) in url \"%s\"", buf, str); free(buf); GWEN_Url_free(url); return 0; } url->port=port; free(buf); s=p; } } else { if (url->protocol) { if (strcasecmp(url->protocol, "http")==0) url->port=80; else if (strcasecmp(url->protocol, "https")==0) url->port=443; } } /* get path */ if (starts_with_drive_letter || *s=='/') { p=s; while(*p && *p!='?') p++; if (p!=s) { char *buf; /* got path */ buf=(char*)malloc(p-s+1); assert(buf); memmove(buf, s, p-s+1); buf[p-s]=0; GWEN_Url_SetPath(url, buf); DBG_DEBUG(GWEN_LOGDOMAIN, "Path: [%s]", buf); free(buf); s=p; } } else { GWEN_Url_SetPath(url, "/"); if (*s) s++; } /* read vars */ while(*s && *s=='?') { GWEN_BUFFER *bName; GWEN_BUFFER *bValue; bName=GWEN_Buffer_new(0, 256, 0, 1); bValue=GWEN_Buffer_new(0, 256, 0, 1); s++; p=s; while(*p && *p!='?' && *p!='=') p++; if (p!=s) GWEN_Buffer_AppendBytes(bName, s, (p-s)); s=p; if (*p=='=') { s++; p=s; while(*p && *p!='?') p++; if (p!=s) GWEN_Buffer_AppendBytes(bValue, s, (p-s)); s=p; } /* store variable/value pair */ if (GWEN_Buffer_GetUsedBytes(bName)) GWEN_DB_SetCharValue(GWEN_Url_GetVars(url), GWEN_DB_FLAGS_DEFAULT, GWEN_Buffer_GetStart(bName), GWEN_Buffer_GetStart(bValue)); GWEN_Buffer_free(bValue); GWEN_Buffer_free(bName); } url->url=strdup(str); url->_modified=0; return url; }
int EBC_Provider_EuSign_A005(AB_PROVIDER *pro, AB_USER *u, const char *requestType, const uint8_t *pMsg, uint32_t lMsg, GWEN_BUFFER *sbuf) { EBC_PROVIDER *dp; GWEN_BUFFER *xbuf; GWEN_BUFFER *hbuf; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; int ksize; uint32_t l; GWEN_CRYPT_PADDALGO *algo; int rv; int numPaddBytes=0; const uint8_t digestInfo[]= { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; assert(pro); dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro); assert(dp); /* get crypt token and context */ rv=EBC_Provider_MountToken(pro, u, &ct, &ctx); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); return rv; } /* get key id */ keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx); ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, 0); if (ki==NULL) { DBG_INFO(AQEBICS_LOGDOMAIN, "Keyinfo %04x not found on crypt token [%s:%s]", keyId, GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); GWEN_Crypt_Token_Close(ct, 0, 0); return GWEN_ERROR_NOT_FOUND; } xbuf=GWEN_Buffer_new(0, 40, 0, 1); EBC_Provider_Sha256(pMsg, lMsg, xbuf); /* add digestInfo to hash of SignedInfo */ hbuf=GWEN_Buffer_new(0, 256, 0, 1); ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki); GWEN_Buffer_AppendByte(hbuf, 0x01); /* block type */ numPaddBytes=ksize-3-sizeof(digestInfo)-GWEN_Buffer_GetUsedBytes(xbuf); if (numPaddBytes<1) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Invalid number of padd bytes, key too small (%d)", numPaddBytes); GWEN_Buffer_free(xbuf); GWEN_Buffer_free(hbuf); return GWEN_ERROR_INTERNAL; } GWEN_Buffer_FillWithBytes(hbuf, 0xff, numPaddBytes); GWEN_Buffer_AppendByte(hbuf, 0x01); /* separator */ GWEN_Buffer_AppendBytes(hbuf, (const char *)digestInfo, sizeof(digestInfo)); /* digest info */ GWEN_Buffer_AppendBytes(hbuf, GWEN_Buffer_GetStart(xbuf), GWEN_Buffer_GetUsedBytes(xbuf)); /* hash */ GWEN_Buffer_free(xbuf); /* select padd algo */ algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize); /* actually sign */ GWEN_Buffer_AllocRoom(sbuf, ksize+16); l=GWEN_Buffer_GetMaxUnsegmentedWrite(sbuf); rv=GWEN_Crypt_Token_Sign(ct, keyId, algo, (const uint8_t *)GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf), (uint8_t *)GWEN_Buffer_GetPosPointer(sbuf), &l, NULL, /* ignore seq counter */ 0); GWEN_Crypt_PaddAlgo_free(algo); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(hbuf); return rv; } GWEN_Buffer_IncrementPos(sbuf, l); GWEN_Buffer_AdjustUsedBytes(sbuf); GWEN_Buffer_free(hbuf); return 0; }
/* * The original code (in C++) has been written by Fabian Kaiser for OpenHBCI * (file rsakey.cpp). Translated to C by Martin Preuss */ int GWEN_Padd_PaddWithISO9796(GWEN_BUFFER *src) { unsigned char *p; unsigned int l; unsigned int i; unsigned char buffer[GWEN_PADD_ISO9796_KEYSIZE]; unsigned char hash[20]; unsigned char c; p=(unsigned char*)GWEN_Buffer_GetStart(src); l=GWEN_Buffer_GetUsedBytes(src); memmove(hash, p, l); /* src+src+src */ if (GWEN_Buffer_AppendBytes(src, (const char*)hash, l)) { DBG_INFO(GWEN_LOGDOMAIN, "here"); return -1; } if (GWEN_Buffer_AppendBytes(src, (const char*)hash, l)) { DBG_INFO(GWEN_LOGDOMAIN, "here"); return -1; } /* src=src(20,40) */ if (GWEN_Buffer_Crop(src, 20, 40)) { DBG_INFO(GWEN_LOGDOMAIN, "here"); return -1; } memset(buffer, 0, sizeof(buffer)); /* append redundancy */ p=(unsigned char*)GWEN_Buffer_GetStart(src); for (i=0; i<=47; i++) { int j1, j2, j3; j1=1 + sizeof(buffer) - (2*i); j2=40-i; j3=sizeof(buffer) - (2*i); if (j1>=0 && j1<(int)sizeof(buffer) && j2>=0) { buffer[j1]=p[j2]; } if (j3>=0 && j3<(int)sizeof(buffer) && j2>=0) { buffer[j3]=GWEN_Padd_permutate(p[j2]); } } /* for */ /* copy last 16 bytes to the beginning */ memmove(buffer, buffer+(sizeof(buffer)-16), 16); p=buffer; /* finish */ c=p[sizeof(buffer)-1]; c = (c & 15) * 16; c += 6; p[sizeof(buffer)-1]=c; p[0] = p[0] & 127; p[0] = p[0] | 64; p[sizeof(buffer) - 40] = p[sizeof(buffer) - 40] ^ 1; GWEN_Buffer_Reset(src); if (GWEN_Buffer_AppendBytes(src, (const char*)buffer, sizeof(buffer))) { DBG_INFO(GWEN_LOGDOMAIN, "here"); return -1; } return 0; }
static int _readLogFile(const char *fname, GWEN_DB_NODE *db) { GWEN_SYNCIO *sio; GWEN_FAST_BUFFER *fb; int rv; GWEN_BUFFER *tbuf = NULL; sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting); GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ); rv=GWEN_SyncIo_Connect(sio); if (rv<0) { DBG_ERROR(0, "Error opening file [%s] (%d)", fname, rv); return rv; } /* create fast buffer around io layer */ fb=GWEN_FastBuffer_new(1024, sio); for (;;) { GWEN_DB_NODE *dbMsg; GWEN_DB_NODE *dbHeader; unsigned int size; /* read header */ dbMsg=GWEN_DB_Group_new("Message"); dbHeader=GWEN_DB_GetGroup(dbMsg, GWEN_DB_FLAGS_DEFAULT, "header"); rv=GWEN_DB_ReadFromFastBuffer(dbHeader, fb, GWEN_DB_FLAGS_HTTP | GWEN_DB_FLAGS_UNTIL_EMPTY_LINE); if (rv<0) { if (rv==GWEN_ERROR_EOF) break; else { GWEN_DB_Group_free(dbMsg); GWEN_FastBuffer_free(fb); GWEN_SyncIo_Disconnect(sio); GWEN_SyncIo_free(sio); DBG_ERROR(0, "Error reading header from file [%s] (%d)", fname, rv); GWEN_DB_Dump(db, 2); return rv; } } /* read body */ size=GWEN_DB_GetIntValue(dbHeader, "size", 0, 0); tbuf=GWEN_Buffer_new(0, 2048, 0, 1); while(size) { unsigned int lsize; uint8_t buffer[1024]; lsize=size; if (lsize>sizeof(buffer)) lsize=sizeof(buffer); GWEN_FASTBUFFER_READFORCED(fb, rv, buffer, lsize); if (rv<0) { GWEN_DB_Group_free(dbMsg); GWEN_FastBuffer_free(fb); GWEN_SyncIo_Disconnect(sio); GWEN_SyncIo_free(sio); DBG_ERROR(0, "Error reading body from file [%s] (%d)", fname, rv); return rv; } GWEN_Buffer_AppendBytes(tbuf, (const char*)buffer, lsize); size-=lsize; } // while GWEN_DB_SetBinValue(dbMsg, GWEN_DB_FLAGS_OVERWRITE_VARS, "body", GWEN_Buffer_GetStart(tbuf), GWEN_Buffer_GetUsedBytes(tbuf)); GWEN_Buffer_Reset(tbuf); GWEN_DB_AddGroup(db, dbMsg); } GWEN_Buffer_free(tbuf); GWEN_FastBuffer_free(fb); GWEN_SyncIo_Disconnect(sio); GWEN_SyncIo_free(sio); return 0; }
/* --------------------------------------------------------------- FUNCTION */ int AH_Job_GetTransactions_Process(AH_JOB *j, AB_IMEXPORTER_CONTEXT *ctx) { AH_JOB_GETTRANSACTIONS *aj; AB_ACCOUNT *a; AB_IMEXPORTER_ACCOUNTINFO *ai; GWEN_DB_NODE *dbResponses; GWEN_DB_NODE *dbCurr; GWEN_BUFFER *tbooked; GWEN_BUFFER *tnoted; int rv; DBG_INFO(AQHBCI_LOGDOMAIN, "Processing JobGetTransactions"); assert(j); aj=GWEN_INHERIT_GETDATA(AH_JOB, AH_JOB_GETTRANSACTIONS, j); assert(aj); tbooked=GWEN_Buffer_new(0, 1024, 0, 1); tnoted=GWEN_Buffer_new(0, 1024, 0, 1); dbResponses=AH_Job_GetResponses(j); assert(dbResponses); /* search for "Transactions" */ dbCurr=GWEN_DB_GetFirstGroup(dbResponses); while (dbCurr) { GWEN_DB_NODE *dbXA; rv=AH_Job_CheckEncryption(j, dbCurr); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (encryption)"); GWEN_Buffer_free(tbooked); GWEN_Buffer_free(tnoted); AH_Job_SetStatus(j, AH_JobStatusError); return rv; } rv=AH_Job_CheckSignature(j, dbCurr); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Compromised security (signature)"); GWEN_Buffer_free(tbooked); GWEN_Buffer_free(tnoted); AH_Job_SetStatus(j, AH_JobStatusError); return rv; } dbXA=GWEN_DB_GetGroup(dbCurr, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "data/transactions"); if (dbXA) { const void *p; unsigned int bs; if (GWEN_Logger_GetLevel(0)>=GWEN_LoggerLevel_Debug) GWEN_DB_Dump(dbXA, 2); p=GWEN_DB_GetBinValue(dbXA, "booked", 0, 0, 0, &bs); if (p && bs) GWEN_Buffer_AppendBytes(tbooked, p, bs); p=GWEN_DB_GetBinValue(dbXA, "noted", 0, 0, 0, &bs); if (p && bs) GWEN_Buffer_AppendBytes(tnoted, p, bs); } /* if "Transactions" */ dbCurr=GWEN_DB_GetNextGroup(dbCurr); } GWEN_Buffer_Rewind(tbooked); GWEN_Buffer_Rewind(tnoted); /* now the buffers contain data to be parsed by DBIOs */ a=AH_AccountJob_GetAccount(j); assert(a); ai=AB_ImExporterContext_GetOrAddAccountInfo(ctx, AB_Account_GetUniqueId(a), AB_Account_GetIban(a), AB_Account_GetBankCode(a), AB_Account_GetAccountNumber(a), AB_Account_GetAccountType(a)); assert(ai); /* read booked transactions */ if (GWEN_Buffer_GetUsedBytes(tbooked)) { if (getenv("AQHBCI_LOGBOOKED")) { FILE *f; f=fopen("/tmp/booked.mt", "w+"); if (f) { if (fwrite(GWEN_Buffer_GetStart(tbooked), GWEN_Buffer_GetUsedBytes(tbooked), 1, f)!=1) { DBG_ERROR(AQHBCI_LOGDOMAIN, "fwrite: %s", strerror(errno)); } if (fclose(f)) { DBG_ERROR(AQHBCI_LOGDOMAIN, "fclose: %s", strerror(errno)); } } } if (AH_Job_GetTransactions__ReadTransactions(j, ai, "SWIFT-MT940", AB_Transaction_TypeStatement, (const uint8_t *) GWEN_Buffer_GetStart(tbooked), GWEN_Buffer_GetUsedBytes(tbooked))) { GWEN_Buffer_free(tbooked); GWEN_Buffer_free(tnoted); DBG_INFO(AQHBCI_LOGDOMAIN, "Error parsing booked transactions"); AH_Job_SetStatus(j, AH_JobStatusError); return -1; } } /* read noted transactions */ if (GWEN_Buffer_GetUsedBytes(tnoted)) { if (getenv("AQHBCI_LOGNOTED")) { FILE *f; f=fopen("/tmp/noted.mt", "w+"); if (f) { if (fwrite(GWEN_Buffer_GetStart(tnoted), GWEN_Buffer_GetUsedBytes(tnoted), 1, f)!=1) { DBG_ERROR(AQHBCI_LOGDOMAIN, "fwrite: %s", strerror(errno)); } if (fclose(f)) { DBG_ERROR(AQHBCI_LOGDOMAIN, "fclose: %s", strerror(errno)); } } } if (AH_Job_GetTransactions__ReadTransactions(j, ai, "SWIFT-MT942", AB_Transaction_TypeNotedStatement, (const uint8_t *) GWEN_Buffer_GetStart(tnoted), GWEN_Buffer_GetUsedBytes(tnoted))) { GWEN_Buffer_free(tbooked); GWEN_Buffer_free(tnoted); DBG_INFO(AQHBCI_LOGDOMAIN, "Error parsing noted transactions"); AH_Job_SetStatus(j, AH_JobStatusError); return -1; } } if (GWEN_Logger_GetLevel(AQHBCI_LOGDOMAIN)>=GWEN_LoggerLevel_Debug) { GWEN_DB_NODE *gn; AB_TRANSACTION *ttmp; DBG_INFO(AQHBCI_LOGDOMAIN, "*** Dumping transactions *******************"); ttmp=AB_ImExporterAccountInfo_GetFirstTransaction(ai, 0, 0); while (ttmp) { DBG_INFO(AQHBCI_LOGDOMAIN, "*** --------------------------------------"); gn=GWEN_DB_Group_new("transaction"); AB_Transaction_toDb(ttmp, gn); GWEN_DB_Dump(gn, 2); GWEN_DB_Group_free(gn); ttmp=AB_Transaction_List_Next(ttmp); } DBG_INFO(AQHBCI_LOGDOMAIN, "*** End dumping transactions ***************"); } GWEN_Buffer_free(tbooked); GWEN_Buffer_free(tnoted); return 0; }
LC_CLIENT_RESULT LC_EgkCard_Unzip(const char *src, unsigned int slen, GWEN_BUFFER *tbuf) { unsigned char buffer[256]; z_stream strm; int rv; int first=1; memset(&strm, 0, sizeof(strm)); strm.next_in=(Bytef*) src; strm.avail_in=slen; strm.next_out=buffer; strm.avail_out=sizeof(buffer); strm.opaque=Z_NULL; strm.zalloc=Z_NULL; strm.zfree=Z_NULL; strm.msg=NULL; rv=inflateInit2(&strm, 15+16); if (rv!=Z_OK) { switch(rv) { case Z_VERSION_ERROR: DBG_ERROR(LC_LOGDOMAIN, "Non-matching version of ZLIB"); return LC_Client_ResultGeneric; case Z_STREAM_ERROR: DBG_ERROR(LC_LOGDOMAIN, "inflateInit: stream error (%d, %s)", rv, (strm.msg)?strm.msg:"NULL"); return LC_Client_ResultDataError; default: DBG_ERROR(LC_LOGDOMAIN, "inflateInit: %d (%s)", rv, (strm.msg)?strm.msg:"NULL"); return LC_Client_ResultGeneric; } } for (;;) { unsigned int inflated; strm.next_out=buffer; strm.avail_out=sizeof(buffer); rv=inflate(&strm, Z_NO_FLUSH); inflated=sizeof(buffer)-strm.avail_out; if (inflated) GWEN_Buffer_AppendBytes(tbuf, (const char*)buffer, inflated); if (rv==Z_STREAM_END || rv==Z_BUF_ERROR) break; if (rv!=Z_OK) { DBG_ERROR(LC_LOGDOMAIN, "inflate: %d (%s)", rv, (strm.msg)?strm.msg:"NULL"); inflateEnd(&strm); return LC_Client_ResultIoError; } if (first) first=0; } rv=inflateEnd(&strm); if (rv!=Z_OK) { DBG_ERROR(LC_LOGDOMAIN, "inflateEnd: %d (%s)", rv, (strm.msg)?strm.msg:"NULL"); return LC_Client_ResultIoError; } return 0; }
int EBC_Provider_EuSign_A004(AB_PROVIDER *pro, AB_USER *u, const char *requestType, const uint8_t *pMsg, uint32_t lMsg, GWEN_BUFFER *sbuf) { EBC_PROVIDER *dp; GWEN_MDIGEST *md; GWEN_BUFFER *hbuf; GWEN_BUFFER *ebuf; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; int ksize; uint32_t l; GWEN_CRYPT_PADDALGO *algo; EB_EU *eu; GWEN_TIME *ti; int rv; const char *userId; assert(pro); dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro); assert(dp); userId=AB_User_GetUserId(u); md=GWEN_MDigest_Rmd160_new(); assert(md); rv=GWEN_MDigest_Begin(md); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); return rv; } rv=GWEN_MDigest_Update(md, pMsg, lMsg); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); return rv; } rv=GWEN_MDigest_End(md); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); return rv; } hbuf=GWEN_Buffer_new(0, GWEN_MDigest_GetDigestSize(md), 0, 1); GWEN_Buffer_AppendBytes(hbuf, (const char*)GWEN_MDigest_GetDigestPtr(md), GWEN_MDigest_GetDigestSize(md)); GWEN_MDigest_free(md); /* get crypt token and context */ rv=EBC_Provider_MountToken(pro, u, &ct, &ctx); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); return rv; } /* get key id */ keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx); ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, 0); if (ki==NULL) { DBG_INFO(AQEBICS_LOGDOMAIN, "Keyinfo %04x not found on crypt token [%s:%s]", keyId, GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); GWEN_Crypt_Token_Close(ct, 0, 0); GWEN_Buffer_free(hbuf); return GWEN_ERROR_NOT_FOUND; } ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki); /* select padd algo */ algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize); /* actually sign */ ebuf=GWEN_Buffer_new(0, ksize+16, 0, 1); l=GWEN_Buffer_GetMaxUnsegmentedWrite(ebuf); rv=GWEN_Crypt_Token_Sign(ct, keyId, algo, (const uint8_t*)GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf), (uint8_t*)GWEN_Buffer_GetPosPointer(ebuf), &l, NULL, /* ignore seq counter */ 0); GWEN_Crypt_PaddAlgo_free(algo); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(ebuf); GWEN_Buffer_free(hbuf); return rv; } GWEN_Buffer_IncrementPos(ebuf, l); GWEN_Buffer_AdjustUsedBytes(ebuf); GWEN_Buffer_free(hbuf); /* assemble EU */ eu=EB_Eu_new(); EB_Eu_SetVersion(eu, "A004"); EB_Eu_SetModLen(eu, ksize*8); EB_Eu_SetJobType(eu, requestType); EB_Eu_SetSignature(eu, (const uint8_t*) GWEN_Buffer_GetStart(ebuf), GWEN_Buffer_GetUsedBytes(ebuf)); GWEN_Buffer_free(ebuf); ti=GWEN_CurrentTime(); EB_Eu_SetCreationTime(eu, ti); EB_Eu_SetSignatureTime(eu, ti); GWEN_Time_free(ti); EB_Eu_SetUserId(eu, userId); /* store EU in given buffer */ EB_Eu_toBuffer(eu, sbuf); EB_Eu_free(eu); return 0; }
LC_CLIENT_RESULT LC_DDVCard_SignHash1(LC_CARD *card, GWEN_BUFFER *hbuf, GWEN_BUFFER *obuf){ LC_DDVCARD *ddv; GWEN_DB_NODE *dbReq; GWEN_DB_NODE *dbResp; LC_CLIENT_RESULT res; const void *p; unsigned int bs; assert(card); ddv=GWEN_INHERIT_GETDATA(LC_CARD, LC_DDVCARD, card); assert(ddv); if (GWEN_Buffer_GetUsedBytes(hbuf)!=20) { DBG_ERROR(LC_LOGDOMAIN, "Hash must exactly be 20 bytes in length (is %d)", GWEN_Buffer_GetUsedBytes(hbuf)); return LC_Client_ResultDataError; } /* write right part of the hash */ dbReq=GWEN_DB_Group_new("WriteHashR"); dbResp=GWEN_DB_Group_new("response"); GWEN_DB_SetBinValue(dbReq, GWEN_DB_FLAGS_DEFAULT, "hashR", GWEN_Buffer_GetStart(hbuf)+8, 12); res=LC_Card_ExecCommand(card, "WriteHashR", dbReq, dbResp); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "Error while executing WriteHashR"); GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return res; } GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); /* write left part of hash and retrieve signed hash */ dbReq=GWEN_DB_Group_new("SignHash"); dbResp=GWEN_DB_Group_new("response"); GWEN_DB_SetBinValue(dbReq, GWEN_DB_FLAGS_DEFAULT, "hashL", GWEN_Buffer_GetStart(hbuf), 8); res=LC_Card_ExecCommand(card, "SignHash", dbReq, dbResp); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "Error while executing SignHash"); GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return res; } p=GWEN_DB_GetBinValue(dbResp, "response/signedHash", 0, 0, 0, &bs); if ( p && bs==8) GWEN_Buffer_AppendBytes(obuf, p, bs); else { DBG_ERROR(LC_LOGDOMAIN, "Expected 8 bytes response, got %d bytes", bs); GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return LC_Client_ResultDataError; } GWEN_DB_Group_free(dbReq); GWEN_DB_Group_free(dbResp); return LC_Client_ResultOk; }
static int EBC_Provider_SignMessage_X001(AB_PROVIDER *pro, EB_MSG *msg, AB_USER *u, xmlNodePtr node) { EBC_PROVIDER *dp; int rv; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; GWEN_BUFFER *hbuf; GWEN_BUFFER *bbuf; xmlNodePtr nodeX = NULL; xmlNodePtr nodeXX = NULL; xmlNodePtr nodeXXX = NULL; xmlNodePtr nodeXXXX = NULL; xmlNsPtr ns; assert(pro); dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro); assert(dp); /* get crypt token and context */ rv=EBC_Provider_MountToken(pro, u, &ct, &ctx); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); return rv; } /* get key id */ keyId=GWEN_Crypt_Token_Context_GetAuthSignKeyId(ctx); ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, 0); if (ki==NULL) { DBG_INFO(AQEBICS_LOGDOMAIN, "Keyinfo %04x not found on crypt token [%s:%s]", keyId, GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); GWEN_Crypt_Token_Close(ct, 0, 0); return GWEN_ERROR_NOT_FOUND; } /* prepare signature nodes */ ns=xmlSearchNs(EB_Msg_GetDoc(msg), node, BAD_CAST "ds"); assert(ns); /* build hash */ bbuf=GWEN_Buffer_new(0, 256, 0, 1); rv=EB_Msg_BuildHashSha1(msg, bbuf); if (rv) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not build hash"); GWEN_Buffer_free(bbuf); return rv; } /* base64 encode */ hbuf=GWEN_Buffer_new(0, 256, 0, 1); rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(bbuf), GWEN_Buffer_GetUsedBytes(bbuf), hbuf, 0); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_Buffer_free(bbuf); return rv; } GWEN_Buffer_free(bbuf); /* create signature node */ nodeX=xmlNewChild(node, ns, BAD_CAST "SignedInfo", NULL); nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "CanonicalizationMethod", NULL); xmlNewProp(nodeXX, BAD_CAST "Algorithm", BAD_CAST "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"); nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "SignatureMethod", NULL); xmlNewProp(nodeXX, BAD_CAST "Algorithm", BAD_CAST "http://www.w3.org/2000/09/xmldsig#rsa-sha1"); nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "Reference", NULL); xmlNewProp(nodeXX, BAD_CAST "URI", BAD_CAST "#xpointer(//*[@authenticate='true'])"); nodeXXX=xmlNewChild(nodeXX, ns, BAD_CAST "Transforms", NULL); nodeXXXX=xmlNewChild(nodeXXX, ns, BAD_CAST "Transform", NULL); xmlNewProp(nodeXXXX, BAD_CAST "Algorithm", BAD_CAST "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"); nodeXXX=xmlNewChild(nodeXX, ns, BAD_CAST "DigestMethod", NULL); xmlNewProp(nodeXXX, BAD_CAST "Algorithm", BAD_CAST "http://www.w3.org/2000/09/xmldsig#sha1"); /* store hash value */ xmlNewTextChild(nodeXX, ns, BAD_CAST "DigestValue", BAD_CAST GWEN_Buffer_GetStart(hbuf)); GWEN_Buffer_free(hbuf); /* build hash over SignedInfo */ bbuf=GWEN_Buffer_new(0, 256, 0, 1); rv=EB_Xml_BuildNodeHashSha1(nodeX, "#xpointer(//*)", bbuf); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(bbuf); return rv; } /* sign hash */ if (1) { GWEN_CRYPT_PADDALGO *algo; int ksize; uint32_t l; const uint8_t prefix[]={ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; /* add prefix to hash of SignedInfo */ hbuf=GWEN_Buffer_new(0, 256, 0, 1); ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki); GWEN_Buffer_AppendBytes(hbuf, (const char*)prefix, sizeof(prefix)); GWEN_Buffer_AppendBuffer(hbuf, bbuf); GWEN_Buffer_Reset(bbuf); /* select padd algo */ algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_1); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize); /* actually sign */ GWEN_Buffer_AllocRoom(bbuf, ksize+16); l=GWEN_Buffer_GetMaxUnsegmentedWrite(bbuf); rv=GWEN_Crypt_Token_Sign(ct, keyId, algo, (const uint8_t*)GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf), (uint8_t*)GWEN_Buffer_GetPosPointer(bbuf), &l, NULL, /* ignore seq counter */ 0); GWEN_Crypt_PaddAlgo_free(algo); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(bbuf); GWEN_Buffer_free(hbuf); return rv; } GWEN_Buffer_IncrementPos(bbuf, l); GWEN_Buffer_AdjustUsedBytes(bbuf); /* base 64 encode signature */ GWEN_Buffer_Reset(hbuf); rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(bbuf), GWEN_Buffer_GetUsedBytes(bbuf), hbuf, 0); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_Buffer_free(bbuf); return rv; } GWEN_Buffer_free(bbuf); /* store signature */ xmlNewTextChild(node, ns, BAD_CAST "SignatureValue", BAD_CAST GWEN_Buffer_GetStart(hbuf)); GWEN_Buffer_free(hbuf); } return 0; }
int APY_Provider_ParseResponse(AB_PROVIDER *pro, const char *s, GWEN_DB_NODE *db) { /* read vars */ while (*s) { GWEN_BUFFER *bName; GWEN_BUFFER *bValue; const char *p; GWEN_DB_NODE *dbT; bName=GWEN_Buffer_new(0, 256, 0, 1); bValue=GWEN_Buffer_new(0, 256, 0, 1); p=s; while (*p && *p!='&' && *p!='=') p++; if (p!=s) GWEN_Buffer_AppendBytes(bName, s, (p-s)); s=p; if (*p=='=') { s++; p=s; while (*p && *p!='&') p++; if (p!=s) GWEN_Buffer_AppendBytes(bValue, s, (p-s)); s=p; } dbT=db; if (strncasecmp(GWEN_Buffer_GetStart(bName), "L_ERRORCODE", 11)!=0 && strncasecmp(GWEN_Buffer_GetStart(bName), "L_SHORTMESSAGE", 14)!=0 && strncasecmp(GWEN_Buffer_GetStart(bName), "L_LONGMESSAGE", 13)!=0 && strncasecmp(GWEN_Buffer_GetStart(bName), "L_SEVERITYCODE", 14)!=0 && strncasecmp(GWEN_Buffer_GetStart(bName), "SHIPTOSTREET2", 13)!=0) { int i; i=GWEN_Buffer_GetUsedBytes(bName)-1; if (i>0) { char *t; t=GWEN_Buffer_GetStart(bName)+i; while (i && isdigit(*t)) { i--; t--; } if (i>0) { t++; if (*t) { dbT=GWEN_DB_GetGroup(db, GWEN_DB_FLAGS_DEFAULT, t); *t=0; } } } } /* store variable/value pair */ if (strlen(GWEN_Buffer_GetStart(bName))) { GWEN_BUFFER *xbuf; xbuf=GWEN_Buffer_new(0, 256, 0, 1); GWEN_Text_UnescapeToBufferTolerant(GWEN_Buffer_GetStart(bValue), xbuf); GWEN_DB_SetCharValue(dbT, GWEN_DB_FLAGS_DEFAULT, GWEN_Buffer_GetStart(bName), GWEN_Buffer_GetStart(xbuf)); GWEN_Buffer_free(xbuf); } GWEN_Buffer_free(bValue); GWEN_Buffer_free(bName); if (*s!='&') break; s++; } return 0; }
GWEN_URL *GWEN_Url_fromCommandString(const char *str) { GWEN_URL *url; GWEN_DB_NODE *dbVars; const char *s; const char *p; url=GWEN_Url_new(); dbVars=GWEN_DB_Group_new("vars"); GWEN_Url_SetVars(url, dbVars); GWEN_DB_Group_free(dbVars); dbVars=0; s=str; /* get path */ if (*s=='/') { p=s; while(*p && *p!='?') p++; if (p!=s) { char *buf; /* got path */ buf=(char*)malloc(p-s+1); assert(buf); memmove(buf, s, p-s+1); buf[p-s]=0; GWEN_Url_SetPath(url, buf); free(buf); s=p; } } else { GWEN_Url_SetPath(url, "/"); if (*s) s++; } /* read vars */ while(*s && *s=='?') { GWEN_BUFFER *bName; GWEN_BUFFER *bValue; bName=GWEN_Buffer_new(0, 256, 0, 1); bValue=GWEN_Buffer_new(0, 256, 0, 1); s++; p=s; while(*p && *p!='?' && *p!='=') p++; if (p!=s) GWEN_Buffer_AppendBytes(bName, s, (p-s)); s=p; if (*p=='=') { s++; p=s; while(*p && *p!='?') p++; if (p!=s) GWEN_Buffer_AppendBytes(bValue, s, (p-s)); s=p; } /* store variable/value pair */ if (GWEN_Buffer_GetUsedBytes(bName)) GWEN_DB_SetCharValue(GWEN_Url_GetVars(url), GWEN_DB_FLAGS_DEFAULT, GWEN_Buffer_GetStart(bName), GWEN_Buffer_GetStart(bValue)); GWEN_Buffer_free(bValue); GWEN_Buffer_free(bName); } url->url=strdup(str); return url; }