int EBC_Provider_FillDataEncryptionInfoNode(AB_PROVIDER *pro, AB_USER *u, const GWEN_CRYPT_KEY *skey, 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; xmlNodePtr nodeX = NULL; const char *s; 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 for server crypt key */ keyId=GWEN_Crypt_Token_Context_GetEncipherKeyId(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; } hbuf=GWEN_Buffer_new(0, 256, 0, 1); s=EBC_User_GetCryptVersion(u); if (!(s && *s)) s="E001"; if (strcasecmp(s, "E001")==0) { rv=EB_Key_Info_BuildHashSha1(ki, hbuf, 1); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_Crypt_Token_Close(ct, 0, 0); return rv; } nodeX=xmlNewTextChild(node, NULL, BAD_CAST "EncryptionPubKeyDigest", BAD_CAST GWEN_Buffer_GetStart(hbuf)); GWEN_Buffer_free(hbuf); assert(nodeX); xmlNewProp(nodeX, BAD_CAST "Version", BAD_CAST "E001"); xmlNewProp(nodeX, BAD_CAST "Algorithm", BAD_CAST "http://www.w3.org/2000/09/xmldsig#sha1"); } else if (strcasecmp(s, "E002")==0) { rv=EB_Key_Info_BuildHashSha256(ki, hbuf, 1); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_Crypt_Token_Close(ct, 0, 0); return rv; } nodeX=xmlNewTextChild(node, NULL, BAD_CAST "EncryptionPubKeyDigest", BAD_CAST GWEN_Buffer_GetStart(hbuf)); GWEN_Buffer_free(hbuf); assert(nodeX); xmlNewProp(nodeX, BAD_CAST "Version", BAD_CAST "E002"); xmlNewProp(nodeX, BAD_CAST "Algorithm", BAD_CAST "http://www.w3.org/2001/04/xmlenc#sha256"); } /* add encrypted transactio key */ hbuf=GWEN_Buffer_new(0, 256, 0, 1); rv=EBC_Provider_EncryptKey(pro, u, skey, hbuf); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(hbuf); GWEN_Crypt_Token_Close(ct, 0, 0); return rv; } nodeX=xmlNewTextChild(node, NULL, BAD_CAST "TransactionKey", BAD_CAST GWEN_Buffer_GetStart(hbuf)); GWEN_Buffer_free(hbuf); assert(nodeX); return 0; }
int addUser(AB_BANKING *ab, GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; AB_PROVIDER *pro; int rv; GWEN_BUFFER *nameBuffer=NULL; const char *tokenName; const char *tokenType; const char *bankId; const char *userId; const char *customerId; const char *server; const char *userName; int hbciVersion; int rdhType; uint32_t cid; const GWEN_ARGS args[]={ { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "userName", /* name */ 1, /* minnum */ 1, /* maxnum */ "N", /* short option */ "username", /* long option */ "Specify the user name", /* short description */ "Specify the user name (not the userid!)" /* long description */ }, { 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_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 */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, GWEN_ArgsType_Int, "hbciversion", 0, 1, 0, "hbciversion", "Select the HBCI version", "Select the HBCI protocol version" }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, GWEN_ArgsType_Int, "rdhType", 0, 1, 0, "rdhtype", "Select the RDH profile type (1, 2, 3, 5, 10)", "Select the RDH profile type (1, 2, 3, 5, 10)" }, { 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(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf)); GWEN_Buffer_free(ubuf); return 0; } rv=AB_Banking_Init(ab); if (rv) { DBG_ERROR(0, "Error on init (%d)", rv); return 2; } rv=AB_Banking_OnlineInit(ab); if (rv) { DBG_ERROR(0, "Error on init (%d)", rv); return 2; } pro=AB_Banking_GetProvider(ab, "aqhbci"); assert(pro); 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); server=GWEN_DB_GetCharValue(db, "serverAddr", 0, 0); cid=GWEN_DB_GetIntValue(db, "context", 0, 1); hbciVersion=GWEN_DB_GetIntValue(db, "hbciVersion", 0, 0); rdhType=GWEN_DB_GetIntValue(db, "rdhType", 0, 1); userName=GWEN_DB_GetCharValue(db, "userName", 0, 0); assert(userName); /* generic check for some arguments */ if (hbciVersion>0 && rdhType>1) { if (hbciVersion<300 && rdhType>1) { DBG_ERROR(0, "RDH Types 2 and above only work with HBCI version 300 or later"); return 1; } } if (hbciVersion>0) { switch(hbciVersion) { case 201: case 210: case 220: case 300: /* supported */ break; default: DBG_ERROR(0, "HBCI/FinTS version %d not supported", hbciVersion); return 1; } } if (rdhType>0) { switch(rdhType) { case 1: case 2: case 10: /* supported */ break; case 3: case 4: case 5: case 6: case 7: case 8: case 9: default: DBG_ERROR(0, "RDH type %d not supported", rdhType); return 1; } } if (1) { const char *lbankId; const char *luserId; const char *lcustomerId; const char *lserverAddr; AH_CRYPT_MODE cm; GWEN_URL *url; GWEN_CRYPT_TOKEN_CONTEXT *ctx=NULL; AB_USER *user; if (strcasecmp(tokenType, "pintan")==0) { lbankId=bankId; luserId=userId; lcustomerId=customerId?customerId:luserId; lserverAddr=server; cm=AH_CryptMode_Pintan; } else { GWEN_PLUGIN_MANAGER *pm; GWEN_PLUGIN *pl; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *cctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; GWEN_CRYPT_CRYPTALGOID algo; 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); GWEN_Crypt_Token_free(ct); 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); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); 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); /* determine crypt mode */ keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx); if (keyId==0) keyId=GWEN_Crypt_Token_Context_GetVerifyKeyId(ctx); if (keyId==0) keyId=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx); if (keyId==0) keyId=GWEN_Crypt_Token_Context_GetDecipherKeyId(ctx); GWEN_Crypt_Token_Context_free(ctx); if (keyId==0) { DBG_ERROR(0, "No keys, unable to determine crypt mode"); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); return 3; } ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, 0); if (ki==NULL) { DBG_ERROR(0, "Could not get keyinfo for key %d, " "unable to determine crypt mode", keyId); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); return 3; } algo=GWEN_Crypt_Token_KeyInfo_GetCryptAlgoId(ki); if (algo==GWEN_Crypt_CryptAlgoId_Des3K) cm=AH_CryptMode_Ddv; else if (algo==GWEN_Crypt_CryptAlgoId_Rsa) cm=AH_CryptMode_Rdh; else { DBG_ERROR(0, "Unexpected crypt algorithm \"%s\", " "unable to determine crypt mode", GWEN_Crypt_CryptAlgoId_toString(algo)); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); return 3; } rv=GWEN_Crypt_Token_Close(ct, 0, 0); GWEN_Crypt_Token_free(ct); if (rv) { DBG_ERROR(0, "Could not close token (%d)", rv); GWEN_Buffer_free(nameBuffer); return 3; } } if (!lbankId || !*lbankId) { DBG_ERROR(0, "No bank id stored and none given"); GWEN_Buffer_free(nameBuffer); return 3; } if (!luserId || !*luserId) { DBG_ERROR(0, "No user id (Benutzerkennung) stored and none given"); GWEN_Buffer_free(nameBuffer); return 3; } user=AB_Banking_FindUser(ab, AH_PROVIDER_NAME, "de", lbankId, luserId, lcustomerId); if (user) { DBG_ERROR(0, "User %s already exists", luserId); return 3; } user=AB_Banking_CreateUser(ab, AH_PROVIDER_NAME); assert(user); AB_User_SetUserName(user, userName); AB_User_SetCountry(user, "de"); AB_User_SetBankCode(user, lbankId); AB_User_SetUserId(user, luserId); AB_User_SetCustomerId(user, lcustomerId); AH_User_SetTokenType(user, tokenType); AH_User_SetTokenName(user, tokenName); AH_User_SetTokenContextId(user, cid); AH_User_SetCryptMode(user, cm); if (rdhType>0) AH_User_SetRdhType(user, rdhType); GWEN_Buffer_free(nameBuffer); if (hbciVersion==0) { if (cm==AH_CryptMode_Pintan) AH_User_SetHbciVersion(user, 220); else { if (rdhType>1) AH_User_SetHbciVersion(user, 300); else AH_User_SetHbciVersion(user, 210); } } else { AH_User_SetHbciVersion(user, hbciVersion); } /* 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, cm, 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; } } if (cm==AH_CryptMode_Pintan) { GWEN_Url_SetProtocol(url, "https"); if (GWEN_Url_GetPort(url)==0) GWEN_Url_SetPort(url, 443); } else { GWEN_Url_SetProtocol(url, "hbci"); if (GWEN_Url_GetPort(url)==0) GWEN_Url_SetPort(url, 3000); } AH_User_SetServerUrl(user, url); GWEN_Url_free(url); if (cm==AH_CryptMode_Ddv) AH_User_SetStatus(user, AH_UserStatusEnabled); AB_Banking_AddUser(ab, user); } rv=AB_Banking_OnlineFini(ab); if (rv) { fprintf(stderr, "ERROR: Error on deinit (%d)\n", rv); return 5; } rv=AB_Banking_Fini(ab); if (rv) { fprintf(stderr, "ERROR: Error on deinit (%d)\n", rv); return 5; } return 0; }
int AH_Msg_EncryptRdh2(AH_MSG *hmsg) { AH_HBCI *h; GWEN_XMLNODE *node; GWEN_DB_NODE *cfg; GWEN_BUFFER *mbuf; GWEN_BUFFER *hbuf; uint32_t l; int rv; const char *p; GWEN_MSGENGINE *e; AB_USER *u; const char *peerId; // uint32_t uFlags; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; GWEN_CRYPT_KEY *sk; uint8_t encKey[300]; int encKeyLen; uint32_t gid; assert(hmsg); h=AH_Dialog_GetHbci(hmsg->dialog); assert(h); e=AH_Dialog_GetMsgEngine(hmsg->dialog); assert(e); GWEN_MsgEngine_SetMode(e, "rdh"); gid=0; 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 crypt token of signer */ rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h), AH_User_GetTokenType(u), AH_User_GetTokenName(u), &ct); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not get crypt token for user \"%s\" (%d)", AB_User_GetUserId(u), rv); return rv; } /* open CryptToken if necessary */ if (!GWEN_Crypt_Token_IsOpen(ct)) { GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN); rv=GWEN_Crypt_Token_Open(ct, 0, gid); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not open crypt token for user \"%s\" (%d)", AB_User_GetUserId(u), rv); return rv; } } /* get context and key info */ ctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(u), gid); if (ctx==NULL) { DBG_INFO(AQHBCI_LOGDOMAIN, "Context %d not found on crypt token [%s:%s]", AH_User_GetTokenContextId(u), GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); return GWEN_ERROR_NOT_FOUND; } keyId=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx); ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, gid); if (ki==NULL) { DBG_INFO(AQHBCI_LOGDOMAIN, "Keyinfo %04x not found on crypt token [%s:%s]", keyId, GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); return GWEN_ERROR_NOT_FOUND; } rv=GWEN_Padd_PaddWithAnsiX9_23(hmsg->buffer); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Error padding message with ANSI X9.23 (%d)", rv); return rv; } /* create session key */ sk=GWEN_Crypt_KeyDes3K_Generate(GWEN_Crypt_CryptMode_Cbc, 24, 2); if (sk==NULL) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not generate DES key"); return GWEN_ERROR_INTERNAL; } /* encrypt message with that session key */ mbuf=GWEN_Buffer_new(0, GWEN_Buffer_GetUsedBytes(hmsg->buffer), 0, 1); l=GWEN_Buffer_GetUsedBytes(hmsg->buffer); rv=GWEN_Crypt_Key_Encipher(sk, (uint8_t*)GWEN_Buffer_GetStart(hmsg->buffer), GWEN_Buffer_GetUsedBytes(hmsg->buffer), (uint8_t*)GWEN_Buffer_GetPosPointer(mbuf), &l); if (rv<0) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not encipher with DES session key (%d)", rv); GWEN_Buffer_free(mbuf); GWEN_Crypt_Key_free(sk); return rv; } GWEN_Buffer_IncrementPos(mbuf, l); GWEN_Buffer_AdjustUsedBytes(mbuf); /* encrypt session key */ if (1) { uint32_t elen; GWEN_CRYPT_PADDALGO *algo; algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_LeftZero); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki)); elen=sizeof(encKey); rv=GWEN_Crypt_Token_Encipher(ct, keyId, algo, GWEN_Crypt_KeyDes3K_GetKeyDataPtr(sk), 16, encKey, &elen, gid); GWEN_Crypt_PaddAlgo_free(algo); if (rv<0) { DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(mbuf); GWEN_Crypt_Key_free(sk); return rv; } encKeyLen=elen; } GWEN_Crypt_Key_free(sk); /* create crypt head */ node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "CryptHead"); if (!node) { DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptHead\" not found"); GWEN_Buffer_free(mbuf); GWEN_Crypt_Key_free(sk); 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_MsgRdh_PrepareCryptoSeg2(hmsg, u, ki, cfg, 1, 0); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv); GWEN_DB_Group_free(cfg); GWEN_Buffer_free(mbuf); return rv; } /* store system id */ if (hmsg->noSysId) { GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0"); } else { p=AH_User_GetSystemId(u); if (p==NULL) p=GWEN_Crypt_Token_Context_GetSystemId(ctx); if (p) GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p); else { DBG_INFO(AQHBCI_LOGDOMAIN, "No System id on RDH medium, using default"); GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0"); } } /* store encrypted message key */ GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "CryptAlgo/MsgKey", encKey, encKeyLen); hbuf=GWEN_Buffer_new(0, 256+GWEN_Buffer_GetUsedBytes(mbuf), 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); GWEN_Buffer_free(mbuf); 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(mbuf), GWEN_Buffer_GetUsedBytes(mbuf)); GWEN_Buffer_free(mbuf); 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; }
static int EBC_Provider_XchgHpbRequest_H003(AB_PROVIDER *pro, GWEN_HTTP_SESSION *sess, AB_USER *u) { EBC_PROVIDER *dp; int rv; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; uint32_t keyId; xmlNsPtr ns; EB_MSG *msg; EB_MSG *mRsp; EB_RC rc; xmlDocPtr doc; xmlNodePtr root_node = NULL; xmlNodePtr node = NULL; xmlNodePtr sigNode = NULL; GWEN_BUFFER *tbuf; const char *s; 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; } /* create request */ msg=EB_Msg_new(); doc=EB_Msg_GetDoc(msg); root_node=xmlNewNode(NULL, BAD_CAST "ebicsNoPubKeyDigestsRequest"); xmlDocSetRootElement(doc, root_node); ns=xmlNewNs(root_node, BAD_CAST "http://www.ebics.org/H003", NULL); assert(ns); ns=xmlNewNs(root_node, BAD_CAST "http://www.w3.org/2000/09/xmldsig#", BAD_CAST "ds"); assert(ns); ns=xmlNewNs(root_node, BAD_CAST "http://www.w3.org/2001/XMLSchema-instance", BAD_CAST "xsi"); xmlNewNsProp(root_node, ns, BAD_CAST "schemaLocation", /* xsi:schemaLocation */ BAD_CAST "http://www.ebics.org/H003 " "http://www.ebics.org/H003/ebics_keymgmt_request.xsd"); xmlNewProp(root_node, BAD_CAST "Version", BAD_CAST "H003"); xmlNewProp(root_node, BAD_CAST "Revision", BAD_CAST "1"); /* header */ node=xmlNewChild(root_node, NULL, BAD_CAST "header", NULL); xmlNewProp(node, BAD_CAST "authenticate", BAD_CAST "true"); xmlNewChild(node, NULL, BAD_CAST "static", NULL); xmlNewChild(node, NULL, BAD_CAST "mutable", NULL); sigNode=xmlNewChild(root_node, NULL, BAD_CAST "AuthSignature", NULL); /* body */ node=xmlNewChild(root_node, NULL, BAD_CAST "body", NULL); /* fill */ s=EBC_User_GetPeerId(u); if (s) EB_Msg_SetCharValue(msg, "header/static/HostID", s); /* generate Nonce */ tbuf=GWEN_Buffer_new(0, 128, 0, 1); rv=EBC_Provider_GenerateNonce(pro, tbuf); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); EB_Msg_free(msg); return rv; } EB_Msg_SetCharValue(msg, "header/static/Nonce", GWEN_Buffer_GetStart(tbuf)); GWEN_Buffer_Reset(tbuf); /* generate timestamp */ rv=EBC_Provider_GenerateTimeStamp(pro, u, tbuf); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(tbuf); EB_Msg_free(msg); return rv; } EB_Msg_SetCharValue(msg, "header/static/Timestamp", GWEN_Buffer_GetStart(tbuf)); GWEN_Buffer_free(tbuf); s=AB_User_GetCustomerId(u); if (s) EB_Msg_SetCharValue(msg, "header/static/PartnerID", s); EB_Msg_SetCharValue(msg, "header/static/UserID", AB_User_GetUserId(u)); EB_Msg_SetCharValue(msg, "header/static/OrderDetails/OrderType", "HPB"); EB_Msg_SetCharValue(msg, "header/static/OrderDetails/OrderAttribute", "DZHNN"); EB_Msg_SetCharValue(msg, "header/static/SecurityMedium", "0000"); /* sign */ rv=EBC_Provider_SignMessage(pro, msg, u, sigNode); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); EB_Msg_free(msg); return rv; } /* exchange requests */ rv=EBC_Dialog_ExchangeMessages(sess, msg, &mRsp); if (rv<0 || rv>=300) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Error exchanging messages (%d)", rv); EB_Msg_free(msg); return rv; } EB_Msg_free(msg); /* check response */ assert(mRsp); /* log results */ EBC_Provider_LogRequestResults(pro, mRsp, NULL); rc=EB_Msg_GetResultCode(mRsp); if ((rc & 0xff0000)==0x090000 || (rc & 0xff0000)==0x060000) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Error response: (%06x)", rc); EB_Msg_free(mRsp); return AB_ERROR_SECURITY; } rc=EB_Msg_GetBodyResultCode(mRsp); if (rc) { if ((rc & 0xff0000)==0x090000 || (rc & 0xff0000)==0x060000) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Error response: (%06x)", rc); EB_Msg_free(mRsp); if ((rc & 0xfff00)==0x091300 || (rc & 0xfff00)==0x091200) return AB_ERROR_SECURITY; else return GWEN_ERROR_GENERIC; } } if (1) { xmlDocPtr orderDoc=NULL; xmlNodePtr root_node=NULL; xmlNodePtr node=NULL; GWEN_CRYPT_KEY *skey=NULL; GWEN_BUFFER *buf1; GWEN_BUFFER *buf2; const char *s; /* extract keys and store them */ node=EB_Xml_GetNode(EB_Msg_GetRootNode(mRsp), "body/DataTransfer/DataEncryptionInfo", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (node==NULL) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Bad message from server: Missing session key"); EB_Msg_free(mRsp); return GWEN_ERROR_BAD_DATA; } rv=EBC_Provider_ExtractSessionKey(pro, u, node, &skey); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); EB_Msg_free(mRsp); return rv; } s=EB_Msg_GetCharValue(mRsp, "body/DataTransfer/OrderData", NULL); if (!s) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Bad message from server: Missing OrderData"); EB_Msg_free(mRsp); return GWEN_ERROR_BAD_DATA; } buf1=GWEN_Buffer_new(0, strlen(s), 0, 1); rv=GWEN_Base64_Decode((const uint8_t*)s, 0, buf1); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "Could not decode OrderData (%d)", rv); GWEN_Buffer_free(buf1); EB_Msg_free(mRsp); return rv; } /* decode data */ buf2=GWEN_Buffer_new(0, GWEN_Buffer_GetUsedBytes(buf1), 0, 1); rv=EBC_Provider_DecryptData(pro, u, skey, (const uint8_t*)GWEN_Buffer_GetStart(buf1), GWEN_Buffer_GetUsedBytes(buf1), buf2); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "Could not decrypt OrderData (%d)", rv); GWEN_Buffer_free(buf2); GWEN_Buffer_free(buf1); return rv; } /* parse XML document */ rv=EB_Xml_DocFromBuffer(GWEN_Buffer_GetStart(buf2), GWEN_Buffer_GetUsedBytes(buf2), &orderDoc); GWEN_Buffer_free(buf2); GWEN_Buffer_free(buf1); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); EB_Msg_free(mRsp); return rv; } /* get keys */ root_node=xmlDocGetRootElement(orderDoc); /* get auth key */ node=EB_Xml_GetNode(root_node, "AuthenticationPubKeyInfo", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (node==NULL) { DBG_ERROR(AQEBICS_LOGDOMAIN, "No authentication key found"); xmlFreeDoc(orderDoc); EB_Msg_free(mRsp); return GWEN_ERROR_BAD_DATA; } else { const GWEN_CRYPT_TOKEN_KEYINFO *cki; GWEN_CRYPT_TOKEN_KEYINFO *ki; keyId=GWEN_Crypt_Token_Context_GetAuthVerifyKeyId(ctx); cki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0, 0); if (cki) ki=GWEN_Crypt_Token_KeyInfo_dup(cki); else ki=GWEN_Crypt_Token_KeyInfo_new(keyId, GWEN_Crypt_CryptAlgoId_Rsa, 128); GWEN_Crypt_Token_KeyInfo_SetFlags(ki, 0); rc=EB_Key_Info_ReadXml(ki, node); if (rc) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%06x)", rc); GWEN_Crypt_Token_KeyInfo_free(ki); xmlFreeDoc(orderDoc); EB_Msg_free(mRsp); return GWEN_ERROR_BAD_DATA; } rv=GWEN_Crypt_Token_SetKeyInfo(ct, keyId, ki, 0); GWEN_Crypt_Token_KeyInfo_free(ki); if (rv) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); xmlFreeDoc(orderDoc); EB_Msg_free(mRsp); return rv; } DBG_NOTICE(AQEBICS_LOGDOMAIN, "Auth key stored"); } /* get crypt key */ node=EB_Xml_GetNode(root_node, "EncryptionPubKeyInfo", GWEN_PATH_FLAGS_NAMEMUSTEXIST); if (node==NULL) { DBG_ERROR(AQEBICS_LOGDOMAIN, "No encryption key found"); xmlFreeDoc(orderDoc); EB_Msg_free(mRsp); return GWEN_ERROR_BAD_DATA; } else { const GWEN_CRYPT_TOKEN_KEYINFO *cki; GWEN_CRYPT_TOKEN_KEYINFO *ki; keyId=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx); cki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0, 0); if (cki) ki=GWEN_Crypt_Token_KeyInfo_dup(cki); else ki=GWEN_Crypt_Token_KeyInfo_new(keyId, GWEN_Crypt_CryptAlgoId_Rsa, 128); GWEN_Crypt_Token_KeyInfo_SetFlags(ki, 0); rc=EB_Key_Info_ReadXml(ki, node); if (rc) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%06x)", rc); GWEN_Crypt_Token_KeyInfo_free(ki); xmlFreeDoc(orderDoc); EB_Msg_free(mRsp); return GWEN_ERROR_BAD_DATA; } rv=GWEN_Crypt_Token_SetKeyInfo(ct, keyId, ki, 0); GWEN_Crypt_Token_KeyInfo_free(ki); if (rv) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); xmlFreeDoc(orderDoc); EB_Msg_free(mRsp); return rv; } DBG_NOTICE(AQEBICS_LOGDOMAIN, "Crypt key stored"); } xmlFreeDoc(orderDoc); } EB_Msg_free(mRsp); /* adjust user status and flags */ DBG_NOTICE(AQEBICS_LOGDOMAIN, "Adjusting user flags"); if ((EBC_User_GetFlags(u) & (EBC_USER_FLAGS_INI | EBC_USER_FLAGS_HIA)) == (EBC_USER_FLAGS_INI | EBC_USER_FLAGS_HIA)) EBC_User_SetStatus(u, EBC_UserStatus_Enabled); return 0; }
int showUser(GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; const char *ttype; const char *tname; GWEN_CRYPT_TOKEN *ct; unsigned int cid; int shown=0; int rv; const GWEN_ARGS args[]= { { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Int, /* type */ "contextId", /* name */ 0, /* minnum */ 1, /* maxnum */ "i", /* short option */ "id", /* long option */ "Context id (0 for any)", /* short description */ "Context id (0 for any)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "tokenType", /* name */ 1, /* minnum */ 1, /* maxnum */ "t", /* short option */ "ttype", /* 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 */ "tname", /* long option */ "Specify the crypt token name", /* short description */ "Specify the crypt token name" /* long description */ }, { 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, 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(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf)); GWEN_Buffer_free(ubuf); return 0; } cid=GWEN_DB_GetIntValue(db, "contextId", 0, 0); ttype=GWEN_DB_GetCharValue(db, "tokenType", 0, 0); assert(ttype); tname=GWEN_DB_GetCharValue(db, "tokenName", 0, 0); /* get crypt token */ ct=getCryptToken(ttype, tname); if (ct==0) return 3; if (GWEN_DB_GetIntValue(dbArgs, "forcePin", 0, 0)) GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_FORCE_PIN_ENTRY); /* open crypt token for use */ rv=GWEN_Crypt_Token_Open(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not open token"); return 3; } else { uint32_t ctxIds[32]; uint32_t ctxCount; uint32_t i; ctxCount=32; rv=GWEN_Crypt_Token_GetContextIdList(ct, ctxIds, &ctxCount, 0); if (rv<0) { DBG_ERROR(0, "Error filling context list"); GWEN_Crypt_Token_Close(ct, 0, 0); return 3; } for (i=0; i<ctxCount; i++) { if (cid==0 || cid==ctxIds[i]) { const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const char *s; uint32_t kid; ctx=GWEN_Crypt_Token_GetContext(ct, ctxIds[i], 0); if (ctx) { fprintf(stdout, "-------------------------------------------------\n"); fprintf(stdout, "Context %u\n", (unsigned int)GWEN_Crypt_Token_Context_GetId(ctx)); s=GWEN_Crypt_Token_Context_GetServiceId(ctx); if (s) fprintf(stdout, "Service : %s\n", s); s=GWEN_Crypt_Token_Context_GetUserId(ctx); if (s) fprintf(stdout, "User Id : %s\n", s); s=GWEN_Crypt_Token_Context_GetCustomerId(ctx); if (s) fprintf(stdout, "Customer Id : %s\n", s); s=GWEN_Crypt_Token_Context_GetUserName(ctx); if (s) fprintf(stdout, "User Name : %s\n", s); s=GWEN_Crypt_Token_Context_GetPeerId(ctx); if (s) fprintf(stdout, "Peer Id : %s\n", s); s=GWEN_Crypt_Token_Context_GetPeerName(ctx); if (s) fprintf(stdout, "Peer Name : %s\n", s); s=GWEN_Crypt_Token_Context_GetAddress(ctx); if (s) fprintf(stdout, "Address : %s\n", s); fprintf(stdout, "Port : %d\n", GWEN_Crypt_Token_Context_GetPort(ctx)); s=GWEN_Crypt_Token_Context_GetSystemId(ctx); if (s) fprintf(stdout, "System Id : %s\n", s); kid=GWEN_Crypt_Token_Context_GetSignKeyId(ctx); if (kid!=0) fprintf(stdout, "Sign Key Id : %d\n", kid); kid=GWEN_Crypt_Token_Context_GetVerifyKeyId(ctx); if (kid!=0) fprintf(stdout, "Verify Key Id : %d\n", kid); kid=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx); if (kid!=0) fprintf(stdout, "Encipher Key Id: %d\n", kid); kid=GWEN_Crypt_Token_Context_GetDecipherKeyId(ctx); if (kid!=0) fprintf(stdout, "Decipher Key Id: %d\n", kid); shown++; } else { fprintf(stderr, "Context %d not found (%d)\n", i, ctxIds[i]); } } } } /* close crypt token */ rv=GWEN_Crypt_Token_Close(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not close token"); return 3; } if (!shown) { if (cid==0) { DBG_ERROR(0, "No context found"); } else { DBG_ERROR(0, "Context %u not found", cid); } return 1; } return 0; }