int GWEN_Padd_PaddWithPkcs1Bt1(GWEN_BUFFER *buf, int dstSize) { unsigned int diff; char *p; if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) { DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data"); return GWEN_ERROR_INVALID; } diff=dstSize-GWEN_Buffer_GetUsedBytes(buf); if (diff<11) { /* honour minimum padding length for BT 1 of 8 bytes, plus the * leading and the trailing zero and the block type identifier */ DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too many bytes (diff is <11)"); return GWEN_ERROR_INVALID; } /* reset position to 0 */ GWEN_Buffer_Rewind(buf); if (GWEN_Buffer_InsertRoom(buf, diff)) { DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff); return GWEN_ERROR_GENERIC; } p=GWEN_Buffer_GetStart(buf); *(p++)=0x00; *(p++)=0x01; /* block type 01 */ if (diff>3) { memset(p, 0xff, diff-3); p+=diff-3; } *(p++)=0x00; return 0; }
int GWEN_Padd_UnpaddWithIso9796_2(GWEN_BUFFER *buf) { uint32_t l; uint32_t realSize; const uint8_t *p; l=GWEN_Buffer_GetUsedBytes(buf); if (l<11) { DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too few bytes"); return GWEN_ERROR_INVALID; } p=(const uint8_t*)GWEN_Buffer_GetStart(buf); if (*p!=0x60) { DBG_ERROR(GWEN_LOGDOMAIN, "First byte is not a 0x60"); return GWEN_ERROR_BAD_DATA; } p++; l=0; while(*p==0x00) { l++; p++; } if (*p!=0x01) { /*DBG_ERROR(GWEN_LOGDOMAIN, "First byte after padding is not a 0x01");*/ return GWEN_ERROR_BAD_DATA; } realSize=GWEN_Buffer_GetUsedBytes(buf)-11-l; GWEN_Buffer_Crop(buf, 10+l, realSize); return 0; }
LC_CLIENT_RESULT LC_EgkCard_ReadRawPd(LC_CARD *card, GWEN_BUFFER *buf){ LC_EGKCARD *egk; LC_CLIENT_RESULT res; GWEN_BUFFER *lbuf; int size; const unsigned char *p; assert(card); egk=GWEN_INHERIT_GETDATA(LC_CARD, LC_EGKCARD, card); assert(egk); res=LC_Card_SelectEf(card, "EF_PD"); if (res!=LC_Client_ResultOk) return res; lbuf=GWEN_Buffer_new(0, 2, 0, 1); res=LC_Card_IsoReadBinary(card, 0, 0, 2, lbuf); if (res!=LC_Client_ResultOk) { GWEN_Buffer_free(lbuf); return res; } if (GWEN_Buffer_GetUsedBytes(lbuf)<2) { DBG_ERROR(LC_LOGDOMAIN, "Invalid response size (%d)", GWEN_Buffer_GetUsedBytes(lbuf)); GWEN_Buffer_free(lbuf); return LC_Client_ResultDataError; } p=(const unsigned char*)GWEN_Buffer_GetStart(lbuf); assert(p); size=(*(p++))<<8; size+=*p; if (size<2) { DBG_ERROR(LC_LOGDOMAIN, "Invalid size spec in data (%d)", size); GWEN_Buffer_free(lbuf); return LC_Client_ResultDataError; } size-=2; GWEN_Buffer_Reset(lbuf); if (size) { res=LC_Card_ReadBinary(card, 2, size, lbuf); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here (%d)", res); GWEN_Buffer_free(lbuf); return res; } } res=LC_EgkCard_Unzip(GWEN_Buffer_GetStart(lbuf), GWEN_Buffer_GetUsedBytes(lbuf), buf); GWEN_Buffer_free(lbuf); return res; }
int GWEN_Padd__UnpaddWithPkcs1Bt1Or2(GWEN_BUFFER *buf) { char *p; uint32_t len; uint32_t paddBytes; assert(buf); len=GWEN_Buffer_GetUsedBytes(buf); assert(len); p=GWEN_Buffer_GetStart(buf); if (*p==0) { p++; len--; } if (len<11) { DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes left (%d)", len); return GWEN_ERROR_INVALID; } if (*p!=0x01 && *p!=0x02) { DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported block type %02x", *p); return GWEN_ERROR_INVALID; } p++; len--; /* skip padding bytes */ paddBytes=0; while(*p!=0x00 && len) { p++; len--; paddBytes++; } if (*p!=0x00) { DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding"); return GWEN_ERROR_INVALID; } p++; len--; if (paddBytes<8) { /* at least 8 padding bytes are needed */ DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding (too few padding bytes)"); return GWEN_ERROR_INVALID; } GWEN_Buffer_Crop(buf, GWEN_Buffer_GetUsedBytes(buf)-len, len); return 0; }
int GWEN_CryptMgr_Decode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { GWEN_BUFFER *tbuf; int rv; tbuf=GWEN_Buffer_new(0, lData, 0, 1); /* decrypt encrypted object */ DBG_INFO(GWEN_LOGDOMAIN, "Decrypting data"); rv=GWEN_CryptMgr_Decrypt(cm, pData, lData, tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } /* verify signature, copy signed data to dbuf in the process */ DBG_INFO(GWEN_LOGDOMAIN, "Verifying data"); rv=GWEN_CryptMgr_Verify(cm, (const uint8_t*)GWEN_Buffer_GetStart(tbuf), GWEN_Buffer_GetUsedBytes(tbuf), dbuf); GWEN_Buffer_free(tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); return rv; } return 0; }
LC_CLIENT_RESULT LC_EgkCard_ReadInsuranceData(LC_CARD *card, LC_HI_INSURANCE_DATA **pData) { GWEN_BUFFER *dbuf; LC_CLIENT_RESULT res; dbuf=GWEN_Buffer_new(0, 256, 0, 1); res=LC_EgkCard_ReadVd(card, dbuf); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here (%d)", res); GWEN_Buffer_free(dbuf); return res; } else { GWEN_XMLNODE *root; root=GWEN_XMLNode_fromString(GWEN_Buffer_GetStart(dbuf), GWEN_Buffer_GetUsedBytes(dbuf), GWEN_XML_FLAGS_HANDLE_HEADERS | GWEN_XML_FLAGS_HANDLE_NAMESPACES); if (root==NULL) { DBG_INFO(LC_LOGDOMAIN, "Invalid XML string"); GWEN_Buffer_free(dbuf); return LC_Client_ResultDataError; } GWEN_Buffer_free(dbuf); GWEN_XMLNode_StripNamespaces(root); res=LC_EgkCard_ParseInsuranceData(root, pData); GWEN_XMLNode_free(root); return res; } }
const char *AB_ImExporterContext_GetLog(const AB_IMEXPORTER_CONTEXT *iec) { assert(iec); if (GWEN_Buffer_GetUsedBytes(iec->logs)) return GWEN_Buffer_GetStart(iec->logs); else return NULL; }
int GWEN_CryptMgr_Encode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) { GWEN_BUFFER *tbuf; int rv; tbuf=GWEN_Buffer_new(0, lData, 0, 1); /* create signed object */ DBG_INFO(GWEN_LOGDOMAIN, "Signing data"); rv=GWEN_CryptMgr_Sign(cm, pData, lData, tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } /* create encrypted object (containing a signed object in this case) */ DBG_INFO(GWEN_LOGDOMAIN, "Encrypting data"); rv=GWEN_CryptMgr_Encrypt(cm, (const uint8_t*)GWEN_Buffer_GetStart(tbuf), GWEN_Buffer_GetUsedBytes(tbuf), dbuf); GWEN_Buffer_free(tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); return rv; } return 0; }
int GWEN_Gui_CProgress_Log(GWEN_GUI_CPROGRESS *cp, GWEN_UNUSED GWEN_LOGGER_LEVEL level, const char *text) { assert(cp); assert(text); if (!(GWEN_Gui_GetFlags(cp->gui) & GWEN_GUI_FLAGS_NONINTERACTIVE)) { GWEN_BUFFER *tbuf; const char *t; tbuf=GWEN_Buffer_new(0, 256, 0, 1); GWEN_Gui_GetRawText(cp->gui, text, tbuf); t=GWEN_Buffer_GetStart(tbuf); if (t[GWEN_Buffer_GetUsedBytes(tbuf)-1]!='\n') { GWEN_Buffer_AppendByte(tbuf, '\n'); /* Just in case the buffer has been reallocated */ t=GWEN_Buffer_GetStart(tbuf); } GWEN_Gui_StdPrintf(cp->gui, stderr, "%s", t); GWEN_Buffer_AppendString(cp->logBuf, t); GWEN_Buffer_free(tbuf); tbuf=0; if (cp->aborted) return GWEN_ERROR_USER_ABORTED; } return 0; }
LC_CLIENT_RESULT LC_DDVCard_CryptBlock(LC_CARD *card, GWEN_BUFFER *ibuf, GWEN_BUFFER *obuf){ return LC_DDVCard_CryptCharBlock(card, GWEN_Buffer_GetStart(ibuf), GWEN_Buffer_GetUsedBytes(ibuf), obuf); }
int GWEN_Padd_PaddWithIso9796_2(GWEN_BUFFER *buf, int dstSize) { unsigned int diff; char *p; int i; if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)+12) { /*DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");*/ return GWEN_ERROR_INVALID; } /* add trailer */ GWEN_Buffer_AppendByte(buf, 0xbc); /* reset position to 0 */ GWEN_Buffer_Rewind(buf); /* insert room for header */ diff=dstSize-GWEN_Buffer_GetUsedBytes(buf)-11+1; if (GWEN_Buffer_InsertRoom(buf, 1+diff+1+8)) { DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", 1+diff+1+8); return GWEN_ERROR_GENERIC; } /* insert header and more-data-bit */ p=GWEN_Buffer_GetStart(buf); *(p++)=0x60; /* insert padding field */ for (i=0; i<diff; i++) *(p++)=0x0; *(p++)=0x01; /* insert 8 random bytes */ GWEN_Crypt_Random(2, (uint8_t*)p, 8); for (i=0; i<8; i++) { if (*p==0) /* TODO: Need to find a better but yet fast way */ *p=0xff; p++; } return 0; }
int GWEN_Padd_PaddWithAnsiX9_23ToMultipleOf(GWEN_BUFFER *src, int y) { unsigned char paddLength; unsigned int i; paddLength=y-(GWEN_Buffer_GetUsedBytes(src) % y); for (i=0; i<paddLength; i++) GWEN_Buffer_AppendByte(src, paddLength); return 0; }
int GWEN_Padd_UnpaddWithAnsiX9_23FromMultipleOf(GWEN_BUFFER *src, int y) { const char *p; unsigned int lastpos; unsigned char paddLength; lastpos=GWEN_Buffer_GetUsedBytes(src); if (lastpos<y) { DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small"); return -1; } lastpos--; p=GWEN_Buffer_GetStart(src)+lastpos; paddLength=*p; if (paddLength<1 || paddLength>y) { DBG_ERROR(GWEN_LOGDOMAIN, "Invalid padding (%d bytes ?)", paddLength); return -1; } GWEN_Buffer_Crop(src, 0, GWEN_Buffer_GetUsedBytes(src)-paddLength); GWEN_Buffer_SetPos(src, lastpos-paddLength); return 0; }
int GWEN_Padd_PaddWithPkcs1Bt2(GWEN_BUFFER *buf, int dstSize) { unsigned int diff; char *p; int i; if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) { DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data"); return GWEN_ERROR_INVALID; } diff=dstSize-GWEN_Buffer_GetUsedBytes(buf); if (diff<11) { /* honour minimum padding length for BT 1 of 8 bytes, plus the * leading and the trailing zero and the block type identifier */ DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too many bytes (diff is <11)"); return GWEN_ERROR_INVALID; } /* reset position to 0 */ GWEN_Buffer_Rewind(buf); if (GWEN_Buffer_InsertRoom(buf, diff)) { DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff); return GWEN_ERROR_GENERIC; } p=GWEN_Buffer_GetStart(buf); *(p++)=0x00; *(p++)=0x02; /* block type 02 */ GWEN_Crypt_Random(2, (uint8_t*)p, diff-3); for (i=0; i<diff-3; i++) { if (*p==0) /* TODO: Need to find a better but yet fast way */ *p=0xff; p++; } *(p++)=0x00; return 0; }
int AO_Provider__WrapRequest(AB_PROVIDER *pro, AB_USER *u, const char *mTypeName, const char *tTypeName, GWEN_BUFFER *buf) { GWEN_BUFFER *tbuf; GWEN_TIME *ti; tbuf=GWEN_Buffer_new(0, 512, 0, 1); /* begin: msg wrapper */ GWEN_Buffer_AppendString(tbuf, "<"); GWEN_Buffer_AppendString(tbuf, mTypeName); GWEN_Buffer_AppendString(tbuf, "MSGSRQV1>"); /* begin: transaction wrapper */ GWEN_Buffer_AppendString(tbuf, "<"); GWEN_Buffer_AppendString(tbuf, tTypeName); GWEN_Buffer_AppendString(tbuf, "TRNRQ>"); ti=GWEN_CurrentTime(); assert(ti); GWEN_Buffer_AppendString(tbuf, "<TRNUID>"); if (AO_User_GetFlags(u) & AO_USER_FLAGS_SEND_SHORT_DATE) GWEN_Time_toString(ti, "YYYYMMDDhhmmss", tbuf); else GWEN_Time_toString(ti, "YYYYMMDDhhmmss.000", tbuf); GWEN_Buffer_AppendString(tbuf, "<CLTCOOKIE>1"); /* append ends of elements to original buffer */ GWEN_Buffer_AppendString(buf, "</"); GWEN_Buffer_AppendString(buf, tTypeName); GWEN_Buffer_AppendString(buf, "TRNRQ>"); GWEN_Buffer_AppendString(buf, "</"); GWEN_Buffer_AppendString(buf, mTypeName); GWEN_Buffer_AppendString(buf, "MSGSRQV1>"); /* go to start of buffer and insert leading elements there */ GWEN_Buffer_SetPos(buf, 0); GWEN_Buffer_InsertBuffer(buf, tbuf); /* point to end of buffer */ GWEN_Buffer_SetPos(buf, GWEN_Buffer_GetUsedBytes(buf)); /* cleanup */ GWEN_Time_free(ti); GWEN_Buffer_free(tbuf); return 0; }
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; }
int HtmlGroup_Box_AddData(HTML_GROUP *g, const char *data) { GWEN_XML_CONTEXT *ctx; GWEN_BUFFER *buf; int rv; uint8_t *s; HTML_OBJECT *o; assert(g); ctx=HtmlGroup_GetXmlContext(g); if (data && *data) { buf=GWEN_Buffer_new(0, strlen(data), 0, 1); rv=HtmlCtx_SanitizeData(ctx, data, buf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(buf); return rv; } if (GWEN_Buffer_GetUsedBytes(buf)) { s=(uint8_t *)GWEN_Buffer_GetStart(buf); while (*s) { uint8_t *t; uint8_t c; /* find begin of word */ while (*s && isspace(*s)) s++; /* find end of word */ t=s; while (*t && !isspace(*t)) t++; c=*t; *t=0; o=HtmlObject_Word_new(ctx, (const char *) s); HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g)); HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o); *t=c; s=t; } } GWEN_Buffer_free(buf); } return 0; }
LC_CLIENT_RESULT LC_DDVCard_WriteInstituteData(LC_CARD *card, int idx, GWEN_DB_NODE *dbData){ LC_DDVCARD *ddv; LC_CLIENT_RESULT res; GWEN_BUFFER *buf; assert(card); ddv=GWEN_INHERIT_GETDATA(LC_CARD, LC_DDVCARD, card); assert(ddv); if (idx==0) { DBG_ERROR(LC_LOGDOMAIN, "Invalid index 0"); return LC_Client_ResultInvalid; } /* select EF_BNK */ res=LC_Card_SelectEf(card, "EF_BNK"); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } /* create record data */ buf=GWEN_Buffer_new(0, 256, 0, 1); if (LC_Card_CreateRecord(card, idx, buf, dbData)) { DBG_ERROR(LC_LOGDOMAIN, "Error creating record %d", idx); GWEN_Buffer_free(buf); return LC_Client_ResultDataError; } GWEN_Buffer_Rewind(buf); /* write record */ res=LC_Card_IsoUpdateRecord(card, LC_CARD_ISO_FLAGS_RECSEL_GIVEN, idx, GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetUsedBytes(buf)); GWEN_Buffer_free(buf); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } return LC_Client_ResultOk; }
int GWEN_XML__ReadData(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb, GWEN_UNUSED uint32_t flags) { int chr; unsigned char uc; GWEN_BUFFER *dbuf; dbuf=GWEN_Buffer_new(0, 256, 0, 1); for (;;) { GWEN_FASTBUFFER_PEEKBYTE(fb, chr); if (chr<0) { if (chr==GWEN_ERROR_EOF) break; else { GWEN_Buffer_free(dbuf); return chr; } } uc=(unsigned char) chr; if (uc=='<') break; fb->bufferReadPos++; GWEN_Buffer_AppendByte(dbuf, uc); } if (GWEN_Buffer_GetUsedBytes(dbuf)) { int rv; const char *s; s=GWEN_Buffer_GetStart(dbuf); if (*s) { rv=GWEN_XmlCtx_AddData(ctx, s); if (rv) { GWEN_Buffer_free(dbuf); return rv; } } } GWEN_Buffer_free(dbuf); return 0; }
int AO_Provider__WrapMessage(AB_PROVIDER *pro, AB_USER *u, GWEN_BUFFER *buf) { GWEN_BUFFER *tbuf; int rv; tbuf=GWEN_Buffer_new(0, 1024, 0, 1); /* add headers and "<OFX>" */ rv=AO_Provider__AddHeaders(pro, u, tbuf); if (rv<0) { DBG_ERROR(AQOFXCONNECT_LOGDOMAIN, "Error adding headers (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } GWEN_Buffer_AppendString(tbuf, "<OFX>"); rv=AO_Provider__AddSignOn(pro, u, tbuf); if (rv<0) { DBG_ERROR(AQOFXCONNECT_LOGDOMAIN, "Error adding signon element (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } /* append end of OFX element to original buffer */ GWEN_Buffer_AppendString(buf, "</OFX>"); /* go to start of buffer and insert leading elements there */ GWEN_Buffer_SetPos(buf, 0); GWEN_Buffer_InsertBuffer(buf, tbuf); /* point to end of buffer */ GWEN_Buffer_SetPos(buf, GWEN_Buffer_GetUsedBytes(buf)); /* cleanup */ GWEN_Buffer_free(tbuf); return 0; }
int AIO_OfxXmlCtx_SanitizeData(GWEN_XML_CONTEXT *ctx, const char *data, GWEN_BUFFER *buf) { AIO_OFX_XMLCTX *xctx; assert(ctx); xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, AIO_OFX_XMLCTX, ctx); assert(xctx); if (xctx->charset) { GWEN_BUFFER *tbuf; int rv; tbuf=GWEN_Buffer_new(0, 256, 0, 1); rv=AIO_OfxXmlCtx_CleanupData(ctx, data, tbuf); if (rv<0) { DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } rv=GWEN_Text_ConvertCharset(xctx->charset, "UTF-8", GWEN_Buffer_GetStart(tbuf), GWEN_Buffer_GetUsedBytes(tbuf), buf); if (rv<0) { DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } GWEN_Buffer_free(tbuf); return 0; } else return AIO_OfxXmlCtx_CleanupData(ctx, data, buf); }
void GWEN_DBIO__XmlDb_ReadDataTags(GWEN_XMLNODE *node, GWEN_BUFFER *buf) { GWEN_XMLNODE *ndata; GWEN_BUFFER *tbuf; int rv; tbuf=GWEN_Buffer_new(0, 256, 0, 1); ndata=GWEN_XMLNode_GetFirstData(node); while(ndata) { const char *s; s=GWEN_XMLNode_GetData(ndata); if (s) { if (GWEN_Buffer_GetUsedBytes(tbuf)) GWEN_Buffer_AppendByte(tbuf, ' '); GWEN_Buffer_AppendString(tbuf, s); } ndata=GWEN_XMLNode_GetNextData(node); } rv=GWEN_Text_UnescapeXmlToBuffer(GWEN_Buffer_GetStart(tbuf), buf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); } GWEN_Buffer_free(tbuf); }
int EBC_Provider_XchgHpdRequest(AB_PROVIDER *pro, GWEN_HTTP_SESSION *sess, AB_USER *u) { int rv; GWEN_BUFFER *buf; buf=GWEN_Buffer_new(0, 1024, 0, 1); rv=EBC_Provider_XchgDownloadRequest(pro, sess, u, "HPD", buf, 0, NULL, NULL); if (rv<0 || rv>=300) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(buf); return rv; } else { xmlDocPtr orderDoc=NULL; xmlNodePtr root_node=NULL; xmlNodePtr node=NULL; xmlNodePtr nodeX=NULL; const char *s; uint32_t uflags=0; /* parse XML document */ rv=EB_Xml_DocFromBuffer(GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetUsedBytes(buf), &orderDoc); GWEN_Buffer_free(buf); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); return rv; } /* get keys */ root_node=xmlDocGetRootElement(orderDoc); /* get auth key */ node=EB_Xml_GetNode(root_node, "ProtocolParams", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (node==NULL) { DBG_ERROR(AQEBICS_LOGDOMAIN, "No ProtocolParams found"); xmlFreeDoc(orderDoc); return GWEN_ERROR_BAD_DATA; } nodeX=EB_Xml_GetNode(node, "ClientDataDownload", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (nodeX) { s=(const char*)xmlGetProp(nodeX, BAD_CAST "supported"); if (s && strcasecmp(s, "true")==0) { DBG_INFO(AQEBICS_LOGDOMAIN, "Client data download supported"); uflags|=EBC_USER_FLAGS_CLIENT_DATA_DOWNLOAD_SPP; } } nodeX=EB_Xml_GetNode(node, "PreValidation", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (nodeX) { s=(const char*)xmlGetProp(nodeX, BAD_CAST "supported"); if (s && strcasecmp(s, "true")==0) { DBG_INFO(AQEBICS_LOGDOMAIN, "Prevalidation supported"); uflags|=EBC_USER_FLAGS_PREVALIDATION_SPP; } } nodeX=EB_Xml_GetNode(node, "Recovery", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (nodeX) { s=(const char*)xmlGetProp(nodeX, BAD_CAST "supported"); if (s && strcasecmp(s, "true")==0) { DBG_INFO(AQEBICS_LOGDOMAIN, "Recovery supported"); uflags|=EBC_USER_FLAGS_RECOVERY_SPP; } } EBC_User_AddFlags(u, uflags); xmlFreeDoc(orderDoc); return 0; } }
int addUser(AB_PROVIDER *pro, GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; int rv; GWEN_BUFFER *nameBuffer=NULL; const char *tokenName; const char *tokenType; const char *bankId; const char *userId; const char *customerId; const char *userName; const char *hostName; const char *server; const char *ebicsVersion; int importing; uint32_t cid; const GWEN_ARGS args[]= { { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "bankId", /* name */ 0, /* minnum */ 1, /* maxnum */ "b", /* short option */ "bank", /* long option */ "Specify the bank code", /* short description */ "Specify the bank code" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "userId", /* name */ 0, /* minnum */ 1, /* maxnum */ "u", /* short option */ "user", /* long option */ "Specify the user id (Benutzerkennung)", /* short description */ "Specify the user id (Benutzerkennung)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "customerId", /* name */ 0, /* minnum */ 1, /* maxnum */ "c", /* short option */ "customer", /* long option */ "Specify the customer id (Kundennummer)", /* short description */ "Specify the customer id (Kundennummer)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "tokenType", /* name */ 1, /* minnum */ 1, /* maxnum */ "t", /* short option */ "tokentype", /* long option */ "Specify the crypt token type", /* short description */ "Specify the crypt token type" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "tokenName", /* name */ 0, /* minnum */ 1, /* maxnum */ "n", /* short option */ "tokenname", /* long option */ "Specify the crypt token name", /* short description */ "Specify the crypt token name" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "serverAddr", /* name */ 0, /* minnum */ 1, /* maxnum */ "s", /* short option */ "server", /* long option */ "Specify the server URL", /* short description */ "Specify the server URL" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "hostName", /* name */ 1, /* minnum */ 1, /* maxnum */ "H", /* short option */ "hostname", /* long option */ "Specify the EBICS hostname", /* short description */ "Specify the EBICS hostname" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "userName", /* name */ 1, /* minnum */ 1, /* maxnum */ "N", /* short option */ "username", /* long option */ "Specify the realname of the user", /* short description */ "Specify the realname of the user" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "ebicsVersion", /* name */ 0, /* minnum */ 1, /* maxnum */ "E", /* short option */ "ebicsversion", /* long option */ "Specify the EBICS version to use (e.g. H002)", /* short description */ "Specify the EBICS version to use (e.g. H002)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Int, /* type */ "context", /* name */ 0, /* minnum */ 1, /* maxnum */ 0, /* short option */ "context", /* long option */ "Select a context on the medium", /* short description */ "Select a context on the medium" /* long description */ }, { 0, /* flags */ GWEN_ArgsType_Int, /* type */ "import", /* name */ 0, /* minnum */ 1, /* maxnum */ 0, /* short option */ "import", /* long option */ "Import a user which has already been in use (e.g. with previous versions)", "Import a user which has already been in use (e.g. with previous versions)" }, { GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */ GWEN_ArgsType_Int, /* type */ "help", /* name */ 0, /* minnum */ 0, /* maxnum */ "h", /* short option */ "help", /* long option */ "Show this help screen", /* short description */ "Show this help screen" /* long description */ } }; db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local"); rv=GWEN_Args_Check(argc, argv, 1, 0 /*GWEN_ARGS_MODE_ALLOW_FREEPARAM*/, args, db); if (rv==GWEN_ARGS_RESULT_ERROR) { fprintf(stderr, "ERROR: Could not parse arguments\n"); return 1; } else if (rv==GWEN_ARGS_RESULT_HELP) { GWEN_BUFFER *ubuf; ubuf=GWEN_Buffer_new(0, 1024, 0, 1); if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) { fprintf(stderr, "ERROR: Could not create help string\n"); return 1; } fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf)); GWEN_Buffer_free(ubuf); return 0; } tokenType=GWEN_DB_GetCharValue(db, "tokenType", 0, 0); tokenName=GWEN_DB_GetCharValue(db, "tokenName", 0, 0); bankId=GWEN_DB_GetCharValue(db, "bankId", 0, 0); userId=GWEN_DB_GetCharValue(db, "userId", 0, 0); customerId=GWEN_DB_GetCharValue(db, "customerId", 0, 0); hostName=GWEN_DB_GetCharValue(db, "hostName", 0, 0); userName=GWEN_DB_GetCharValue(db, "userName", 0, 0); server=GWEN_DB_GetCharValue(db, "serverAddr", 0, 0); cid=GWEN_DB_GetIntValue(db, "context", 0, 0); importing=GWEN_DB_GetIntValue(db, "import", 0, 0); ebicsVersion=GWEN_DB_GetCharValue(db, "ebicsVersion", 0, "H003"); if (1) { const char *lbankId; const char *luserId; const char *lcustomerId; const char *lserverAddr; GWEN_URL *url; GWEN_CRYPT_TOKEN_CONTEXT *ctx=NULL; AB_USER *user; if (1) { GWEN_PLUGIN_MANAGER *pm; GWEN_PLUGIN *pl; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *cctx; if (cid==0) { DBG_ERROR(0, "No context given."); return 1; } /* get crypt token */ pm=GWEN_PluginManager_FindPluginManager("ct"); if (pm==0) { DBG_ERROR(0, "Plugin manager not found"); return 3; } pl=GWEN_PluginManager_GetPlugin(pm, tokenType); if (pl==0) { DBG_ERROR(0, "Plugin not found"); return 3; } DBG_INFO(0, "Plugin found"); ct=GWEN_Crypt_Token_Plugin_CreateToken(pl, tokenName); if (ct==0) { DBG_ERROR(0, "Could not create crypt token"); return 3; } /* open crypt token */ rv=GWEN_Crypt_Token_Open(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not open token (%d)", rv); return 3; } /* get real token name */ nameBuffer=GWEN_Buffer_new(0, 64, 0, 1); GWEN_Buffer_AppendString(nameBuffer, GWEN_Crypt_Token_GetTokenName(ct)); tokenName=GWEN_Buffer_GetStart(nameBuffer); cctx=GWEN_Crypt_Token_GetContext(ct, cid, 0); if (cctx==NULL) { DBG_ERROR(0, "Context %02x not found", cid); return 3; } ctx=GWEN_Crypt_Token_Context_dup(cctx); lbankId=bankId?bankId:GWEN_Crypt_Token_Context_GetServiceId(ctx); luserId=userId?userId:GWEN_Crypt_Token_Context_GetUserId(ctx); lcustomerId=customerId?customerId:luserId; lserverAddr=server?server:GWEN_Crypt_Token_Context_GetAddress(ctx); rv=GWEN_Crypt_Token_Close(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not close token (%d)", rv); return 3; } GWEN_Crypt_Token_free(ct); } if (!lbankId || !*lbankId) { DBG_ERROR(0, "No bank id stored and none given"); return 3; } if (!luserId || !*luserId) { DBG_ERROR(0, "No user id (Benutzerkennung) stored and none given"); return 3; } /* TODO: Check for existing users to avoid duplicates */ #if 0 user=AB_Banking_FindUser(ab, EBC_PROVIDER_NAME, "de", lbankId, luserId, lcustomerId); if (user) { DBG_ERROR(0, "User %s already exists", luserId); return 3; } #endif user=AB_Provider_CreateUserObject(pro); assert(user); AB_User_SetCountry(user, "de"); AB_User_SetBankCode(user, lbankId); AB_User_SetUserId(user, luserId); AB_User_SetCustomerId(user, lcustomerId); EBC_User_SetPeerId(user, hostName); AB_User_SetUserName(user, userName); EBC_User_SetTokenType(user, tokenType); EBC_User_SetTokenName(user, tokenName); EBC_User_SetTokenContextId(user, cid); if (ebicsVersion) { if (strcasecmp(ebicsVersion, "H002")==0) { EBC_User_SetProtoVersion(user, "H002"); EBC_User_SetSignVersion(user, "A004"); EBC_User_SetAuthVersion(user, "X001"); EBC_User_SetCryptVersion(user, "E001"); } else if (strcasecmp(ebicsVersion, "H003")==0) { EBC_User_SetProtoVersion(user, "H003"); EBC_User_SetSignVersion(user, "A005"); EBC_User_SetAuthVersion(user, "X002"); EBC_User_SetCryptVersion(user, "E002"); } else if (strcasecmp(ebicsVersion, "H004")==0) { EBC_User_SetProtoVersion(user, "H004"); EBC_User_SetSignVersion(user, "A005"); EBC_User_SetAuthVersion(user, "X002"); EBC_User_SetCryptVersion(user, "E002"); } else { fprintf(stderr, "%s", I18N("Invalid protocol version.\n" "Possible versions are H002, H003 and H004.\n")); return 3; } } /* try to get server address from database if still unknown */ if (!lserverAddr || *lserverAddr==0) { GWEN_BUFFER *tbuf; tbuf=GWEN_Buffer_new(0, 256, 0, 1); if (getBankUrl(AB_Provider_GetBanking(pro), lbankId, tbuf)) { DBG_INFO(0, "Could not find server address for \"%s\"", lbankId); } if (GWEN_Buffer_GetUsedBytes(tbuf)==0) { DBG_ERROR(0, "No address given and none available in internal db"); return 3; } url=GWEN_Url_fromString(GWEN_Buffer_GetStart(tbuf)); if (url==NULL) { DBG_ERROR(0, "Bad URL \"%s\" in internal db", GWEN_Buffer_GetStart(tbuf)); return 3; } GWEN_Buffer_free(tbuf); } else { /* set address */ url=GWEN_Url_fromString(lserverAddr); if (url==NULL) { DBG_ERROR(0, "Bad URL \"%s\"", lserverAddr); return 3; } } GWEN_Url_SetProtocol(url, "https"); if (GWEN_Url_GetPort(url)==0) GWEN_Url_SetPort(url, 443); /* set url */ if (1) { GWEN_BUFFER *tbuf; tbuf=GWEN_Buffer_new(0, 256, 0, 1); rv=GWEN_Url_toString(url, tbuf); if (rv<0) { DBG_ERROR(0, "Internal error storing URL"); return 3; } EBC_User_SetServerUrl(user, GWEN_Buffer_GetStart(tbuf)); GWEN_Buffer_free(tbuf); } GWEN_Url_free(url); if (importing) { EBC_User_AddFlags(user, EBC_USER_FLAGS_INI | EBC_USER_FLAGS_HIA); EBC_User_SetStatus(user, EBC_UserStatus_Enabled); } rv=AB_Provider_AddUser(pro, user); if (rv<0) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Coud not add new user (%d)", rv); AB_User_free(user); return 4; } AB_User_free(user); /* context no longer needed */ GWEN_Crypt_Token_Context_free(ctx); } return 0; }
LC_CLIENT_RESULT LC_ZkaCard_Reopen(LC_CARD *card) { LC_CLIENT_RESULT res; LC_ZKACARD *xc; GWEN_BUFFER *mbuf; DBG_INFO(LC_LOGDOMAIN, "Opening ZkaCard card"); assert(card); xc=GWEN_INHERIT_GETDATA(LC_CARD, LC_ZKACARD, card); assert(xc); LC_Card_SetLastResult(card, 0, 0, 0, 0); GWEN_Buffer_free(xc->bin_ef_gd_0); xc->bin_ef_gd_0=NULL; GWEN_Buffer_free(xc->bin_ef_id); xc->bin_ef_id=NULL; GWEN_Buffer_free(xc->bin_ef_ssd); xc->bin_ef_ssd=NULL; res=LC_Card_SelectCard(card, "zkacard"); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } /* first select generic app for all ZKACARD HBCI cards */ res=LC_Card_SelectApp(card, "zkacard"); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } DBG_INFO(LC_LOGDOMAIN, "Selecting MF..."); res=LC_Card_SelectMf(card); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } /* read EF_ID */ DBG_INFO(LC_LOGDOMAIN, "Selecting EF_ID..."); res=LC_Card_SelectEf(card, "EF_ID"); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } DBG_INFO(LC_LOGDOMAIN, "Reading record..."); mbuf=GWEN_Buffer_new(0, 32, 0, 1); res=LC_Card_IsoReadRecord(card, LC_CARD_ISO_FLAGS_RECSEL_GIVEN, 1, mbuf); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); GWEN_Buffer_free(mbuf); return res; } xc->bin_ef_id=mbuf; /* read EG_GD0 */ DBG_INFO(LC_LOGDOMAIN, "Selecting EF_GD0..."); res=LC_Card_SelectEf(card, "EF_GD0"); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } DBG_INFO(LC_LOGDOMAIN, "Reading data..."); mbuf=GWEN_Buffer_new(0, 16, 0, 1); res=LC_Card_IsoReadBinary(card, 0, 0, 12, mbuf); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); GWEN_Buffer_free(mbuf); return res; } if (GWEN_Buffer_GetUsedBytes(mbuf)<12) { DBG_INFO(LC_LOGDOMAIN, "here"); GWEN_Buffer_free(mbuf); return LC_Client_ResultDataError; } xc->bin_ef_gd_0=mbuf; /* select DF_SIG */ DBG_INFO(LC_LOGDOMAIN, "Selecting DF_SIG..."); res=LC_Card_SelectDf(card, "DF_SIG"); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } /* read EG_SSD */ DBG_INFO(LC_LOGDOMAIN, "Selecting EF_SSD..."); res=LC_Card_SelectEf(card, "EF_SSD"); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here"); return res; } DBG_INFO(LC_LOGDOMAIN, "Reading data..."); mbuf=GWEN_Buffer_new(0, 16, 0, 1); res=LC_Card_ReadBinary(card, 0, 65535, mbuf); if (res!=LC_Client_ResultOk) { DBG_INFO(LC_LOGDOMAIN, "here (%d)", res); GWEN_Buffer_free(mbuf); return res; } xc->bin_ef_ssd=mbuf; return LC_Client_ResultOk; }
GWENHYWFAR_CB int GWEN_CryptMgrKeys_VerifyData(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, const uint8_t *pSignature, uint32_t lSignature) { GWEN_CRYPTMGR_KEYS *xcm; GWEN_MDIGEST *md; 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); /* the padding algo uses random numbers, so we must use the encrypt function and * compare the decoded and unpadded signature with the hash of the source data */ tbuf=GWEN_Buffer_new(0, ksize+16, 0, 1); l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf); rv=GWEN_Crypt_Key_Encipher(xcm->peerKey, pSignature, lSignature, (uint8_t*)GWEN_Buffer_GetPosPointer(tbuf), &l); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } GWEN_Buffer_IncrementPos(tbuf, l); GWEN_Buffer_AdjustUsedBytes(tbuf); /* unpadd */ rv=GWEN_Padd_UnpaddWithIso9796_2(tbuf); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); return rv; } /* tbuf now contains the hash */ /* hash source data */ md=GWEN_MDigest_Rmd160_new(); rv=GWEN_MDigest_Begin(md); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); GWEN_Buffer_free(tbuf); return rv; } rv=GWEN_MDigest_Update(md, pData, lData); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); GWEN_Buffer_free(tbuf); return rv; } rv=GWEN_MDigest_End(md); if (rv<0) { DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); GWEN_MDigest_free(md); GWEN_Buffer_free(tbuf); return rv; } if (GWEN_MDigest_GetDigestSize(md)!=GWEN_Buffer_GetUsedBytes(tbuf)) { DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature"); GWEN_MDigest_free(md); GWEN_Buffer_free(tbuf); return GWEN_ERROR_VERIFY; } if (memcmp(GWEN_MDigest_GetDigestPtr(md), GWEN_Buffer_GetStart(tbuf), GWEN_MDigest_GetDigestSize(md))!=0) { DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature"); GWEN_MDigest_free(md); GWEN_Buffer_free(tbuf); return GWEN_ERROR_VERIFY; } GWEN_MDigest_free(md); GWEN_Buffer_free(tbuf); 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; }
int AH_Msg_EncryptPinTan(AH_MSG *hmsg) { AH_HBCI *h; GWEN_XMLNODE *node; GWEN_DB_NODE *cfg; GWEN_BUFFER *hbuf; int rv; const char *p; GWEN_MSGENGINE *e; AB_USER *u; const char *peerId; // uint32_t uFlags; 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); /* create crypt head */ node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "CryptHead"); if (!node) { DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptHead\" not found"); return GWEN_ERROR_INTERNAL; } /* create CryptHead */ cfg=GWEN_DB_Group_new("crypthead"); GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", 998); rv=AH_MsgPinTan_PrepareCryptoSeg(hmsg, u, cfg, 1, 0); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv); GWEN_DB_Group_free(cfg); return rv; } /* store system id */ p=NULL; if (!hmsg->noSysId) p=AH_User_GetSystemId(u); if (!p) p="0"; GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p); /* store encrypted message key */ GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "CryptAlgo/MsgKey", "NOKEY", 5); hbuf=GWEN_Buffer_new(0, 256+GWEN_Buffer_GetUsedBytes(hmsg->buffer), 0, 1); rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptHead (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); return rv; } GWEN_DB_Group_free(cfg); /* create cryptdata */ cfg=GWEN_DB_Group_new("cryptdata"); GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", 999); GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "cryptdata", GWEN_Buffer_GetStart(hmsg->buffer), GWEN_Buffer_GetUsedBytes(hmsg->buffer)); node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "CryptData"); if (!node) { DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptData\"not found"); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); return -1; } rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptData (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); return rv; } /* replace existing buffer by encrypted one */ GWEN_Buffer_free(hmsg->buffer); hmsg->buffer=hbuf; GWEN_DB_Group_free(cfg); return 0; }
int AH_Msg_SignPinTan(AH_MSG *hmsg, GWEN_BUFFER *rawBuf, const char *signer) { AH_HBCI *h; GWEN_XMLNODE *node; GWEN_DB_NODE *cfg; GWEN_BUFFER *hbuf; int rv; char ctrlref[15]; const char *p; GWEN_MSGENGINE *e; AB_USER *su; uint32_t uFlags; char pin[64]; uint32_t tm; assert(hmsg); h=AH_Dialog_GetHbci(hmsg->dialog); assert(h); e=AH_Dialog_GetMsgEngine(hmsg->dialog); assert(e); GWEN_MsgEngine_SetMode(e, "pintan"); su=AB_Banking_FindUser(AH_HBCI_GetBankingApi(h), AH_PROVIDER_NAME, "de", "*", signer, "*"); if (!su) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Unknown user \"%s\"", signer); return GWEN_ERROR_NOT_FOUND; } uFlags=AH_User_GetFlags(su); node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "SigHead"); if (!node) { DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigHead\" not found"); return GWEN_ERROR_INTERNAL; } /* for iTAN mode: set selected mode (Sicherheitsfunktion, kodiert) */ tm=AH_Msg_GetItanMethod(hmsg); if (tm==0) { tm=AH_Dialog_GetItanMethod(hmsg->dialog); if (tm) /* this is needed by AH_MsgPinTan_PrepareCryptoSeg */ AH_Msg_SetItanMethod(hmsg, tm); } /* prepare config for segment */ cfg=GWEN_DB_Group_new("sighead"); rv=AH_MsgPinTan_PrepareCryptoSeg(hmsg, su, cfg, 0, 1); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv); GWEN_DB_Group_free(cfg); return rv; } /* set expected signer */ if (!(uFlags & AH_USER_FLAGS_BANK_DOESNT_SIGN)) { const char *remoteId; remoteId=AH_User_GetPeerId(su); if (!remoteId || *remoteId==0) remoteId=AB_User_GetUserId(su); assert(remoteId); assert(*remoteId); DBG_DEBUG(AQHBCI_LOGDOMAIN, "Expecting \"%s\" to sign the response", remoteId); AH_Msg_SetExpectedSigner(hmsg, remoteId); } /* store system id */ p=NULL; if (!hmsg->noSysId) p=AH_User_GetSystemId(su); if (!p) p="0"; GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p); if (tm) { GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "function", tm); } /* retrieve control reference for sigtail (to be used later) */ p=GWEN_DB_GetCharValue(cfg, "ctrlref", 0, ""); if (strlen(p)>=sizeof(ctrlref)) { DBG_INFO(AQHBCI_LOGDOMAIN, "Control reference too long (14 bytes maximum)"); GWEN_DB_Group_free(cfg); return -1; } strcpy(ctrlref, p); /* create SigHead */ hbuf=GWEN_Buffer_new(0, 128+GWEN_Buffer_GetUsedBytes(rawBuf), 0, 1); GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", hmsg->firstSegment-1); GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signseq", 1); /* create signature head segment */ rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg); GWEN_DB_Group_free(cfg); cfg=0; if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigHead"); GWEN_Buffer_free(hbuf); return rv; } /* insert new SigHead at beginning of message buffer */ DBG_DEBUG(AQHBCI_LOGDOMAIN, "Inserting signature head"); GWEN_Buffer_Rewind(hmsg->buffer); GWEN_Buffer_InsertBytes(hmsg->buffer, GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf)); /* create sigtail */ DBG_DEBUG(AQHBCI_LOGDOMAIN, "Completing signature tail"); cfg=GWEN_DB_Group_new("sigtail"); GWEN_Buffer_Reset(hbuf); GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", hmsg->lastSegment+1); /* store to DB */ GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signature", "NOSIGNATURE", 11); GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "ctrlref", ctrlref); /* handle pin */ memset(pin, 0, sizeof(pin)); rv=AH_User_InputPin(su, pin, 4, sizeof(pin), 0); if (rv<0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Error getting pin from medium (%d)", rv); GWEN_DB_Group_free(cfg); GWEN_Buffer_free(hbuf); memset(pin, 0, sizeof(pin)); return rv; } GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "pin", pin); AH_Msg_SetPin(hmsg, pin); memset(pin, 0, sizeof(pin)); /* handle tan */ if (hmsg->needTan) { DBG_NOTICE(AQHBCI_LOGDOMAIN, "This queue needs a TAN"); if (hmsg->usedTan) { DBG_NOTICE(AQHBCI_LOGDOMAIN, "Using existing TAN"); GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "tan", hmsg->usedTan); } else { char tan[16]; memset(tan, 0, sizeof(tan)); DBG_NOTICE(AQHBCI_LOGDOMAIN, "Asking for TAN"); rv=AH_User_InputTan(su, tan, 4, sizeof(tan)); if (rv<0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Error getting TAN from medium"); GWEN_DB_Group_free(cfg); GWEN_Buffer_free(hbuf); return rv; } GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "tan", tan); AH_Msg_SetTan(hmsg, tan); } } else { DBG_NOTICE(AQHBCI_LOGDOMAIN, "This queue doesn't need a TAN"); } /* get node */ node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "SigTail"); if (!node) { DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigTail\"not found"); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); return GWEN_ERROR_INTERNAL; } rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigTail (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); return rv; } /* append sigtail */ DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail"); if (GWEN_Buffer_AppendBuffer(hmsg->buffer, hbuf)) { DBG_INFO(AQHBCI_LOGDOMAIN, "here"); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); return GWEN_ERROR_MEMORY_FULL; } DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail: done"); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); /* adjust segment numbers (for next signature and message tail */ hmsg->firstSegment--; hmsg->lastSegment++; return 0; }
int EBC_Dialog_ExchangeMessages(GWEN_HTTP_SESSION *sess, EB_MSG *msg, EB_MSG **pResponse) { AB_USER *u; int rv; GWEN_BUFFER *sendBuf; GWEN_BUFFER *recvBuf; EB_MSG *mResponse; /* preparations */ u=AB_HttpSession_GetUser(sess); assert(u); sendBuf=GWEN_Buffer_new(0, 1024, 0, 1); recvBuf=GWEN_Buffer_new(0, 1024, 0, 1); /* convert message to buffer for sending */ EB_Msg_toBuffer(msg, sendBuf); #if 0 if (GWEN_Logger_GetLevel(AQEBICS_LOGDOMAIN)>=GWEN_LoggerLevel_Debug) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Sending this:"); fprintf(stderr, "====================================\n"); fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(sendBuf)); fprintf(stderr, "====================================\n"); } #endif /* send request */ rv=GWEN_HttpSession_SendPacket(sess, "POST", (const uint8_t*)GWEN_Buffer_GetStart(sendBuf), GWEN_Buffer_GetUsedBytes(sendBuf)); if (rv<0) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Error sending request (%d)", rv); GWEN_Buffer_free(recvBuf); GWEN_Buffer_free(sendBuf); return rv; } GWEN_Buffer_free(sendBuf); /* receive response */ rv=GWEN_HttpSession_RecvPacket(sess, recvBuf); if (rv<0 || rv>=300) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Error sending request (%d)", rv); GWEN_Buffer_free(recvBuf); return rv; } #if 0 if (GWEN_Logger_GetLevel(AQEBICS_LOGDOMAIN)>=GWEN_LoggerLevel_Debug) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Received this:"); fprintf(stderr, "====================================\n"); fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(recvBuf)); fprintf(stderr, "====================================\n"); } #endif /* convert buffer to EBICS message */ mResponse=EB_Msg_fromBuffer(GWEN_Buffer_GetStart(recvBuf), GWEN_Buffer_GetUsedBytes(recvBuf)); GWEN_Buffer_free(recvBuf); if (!mResponse) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Invalid response (no EBICS message)"); return GWEN_ERROR_BAD_DATA; } *pResponse=mResponse; return 0; }