int EBC_Provider_MountToken(AB_PROVIDER *pro, AB_USER *u, GWEN_CRYPT_TOKEN **pCt, const GWEN_CRYPT_TOKEN_CONTEXT **pCtx) { EBC_PROVIDER *dp; int rv; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; assert(pro); dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro); assert(dp); /* get crypt token of signer */ rv=AB_Banking_GetCryptToken(AB_Provider_GetBanking(pro), EBC_User_GetTokenType(u), EBC_User_GetTokenName(u), &ct); if (rv) { DBG_INFO(AQEBICS_LOGDOMAIN, "Could not get crypt token for user \"%s\" (%d)", AB_User_GetUserId(u), rv); return rv; } /* make sure the right flags are set */ DBG_INFO(AQEBICS_LOGDOMAIN, "Adding mode \"direct sign\" to CryptToken"); GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN); /* open CryptToken if necessary */ if (!GWEN_Crypt_Token_IsOpen(ct)) { rv=GWEN_Crypt_Token_Open(ct, 0, 0); if (rv) { DBG_INFO(AQEBICS_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, EBC_User_GetTokenContextId(u), 0); if (ctx==NULL) { DBG_INFO(AQEBICS_LOGDOMAIN, "Context %d not found on crypt token [%s:%s]", EBC_User_GetTokenContextId(u), GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); return GWEN_ERROR_NOT_FOUND; } *pCt=ct; *pCtx=ctx; return 0; }
int activateKey(GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; const char *ttype; const char *tname; GWEN_CRYPT_TOKEN *ct; unsigned int keyId; int rv; const char *s; const GWEN_ARGS args[]={ { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Int, /* type */ "keyId", /* name */ 1, /* minnum */ 1, /* maxnum */ "k", /* short option */ "key", /* long option */ "Key id", /* short description */ "Key id" /* 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; } keyId=GWEN_DB_GetIntValue(db, "keyId", 0, 0); if (keyId==0) { DBG_ERROR(0, "Key Id must not be zero"); return 1; } s=GWEN_DB_GetCharValue(db, "algo", 0, "rsa"); if (!s) { DBG_ERROR(0, "Algo id missing"); return 1; } 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, 1, 0); if (rv) { DBG_ERROR(0, "Could not open token"); return 3; } else { /* activate key */ rv=GWEN_Crypt_Token_ActivateKey(ct, keyId, 0); if (rv) { DBG_ERROR(GWEN_LOGDOMAIN, "Error activating key (%d)", rv); return 3; } } /* close crypt token */ rv=GWEN_Crypt_Token_Close(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not close token"); return 3; } fprintf(stderr, "Key %d successfully activated.\n", keyId); return 0; }
int AH_Msg_VerifyRdh2(AH_MSG *hmsg, GWEN_DB_NODE *gr) { AH_HBCI *h; GWEN_LIST *sigheads; GWEN_LIST *sigtails; GWEN_DB_NODE *n; int nonSigHeads; int nSigheads; unsigned int dataBegin; char *dataStart; unsigned int dataLength; unsigned int i; AB_USER *u; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; int ksize; int rv; uint32_t gid; assert(hmsg); h=AH_Dialog_GetHbci(hmsg->dialog); assert(h); u=AH_Dialog_GetDialogOwner(hmsg->dialog); assert(u); gid=0; /* 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; } /* let's go */ sigheads=GWEN_List_new(); /* enumerate signature heads */ nonSigHeads=0; nSigheads=0; n=GWEN_DB_GetFirstGroup(gr); while(n) { if (strcasecmp(GWEN_DB_GroupName(n), "SigHead")==0) { /* found a signature head */ if (nonSigHeads) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Found some unsigned parts at the beginning"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } GWEN_List_PushBack(sigheads, n); nSigheads++; } else if (strcasecmp(GWEN_DB_GroupName(n), "MsgHead")!=0) { if (nSigheads) break; nonSigHeads++; } n=GWEN_DB_GetNextGroup(n); } /* while */ if (!n) { if (nSigheads) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Found Signature heads but no other segments"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signatures"); GWEN_List_free(sigheads); return 0; } /* only now we need the verify key */ keyId=GWEN_Crypt_Token_Context_GetVerifyKeyId(ctx); if (keyId==0) { DBG_INFO(AQHBCI_LOGDOMAIN, "No verify key id on crypt token [%s:%s]", GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); return GWEN_ERROR_NOT_FOUND; } 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)); /* no longer return an error, it might be ok to not have a key info * even if we do not propagate the error here the check functions will * later find out that the signature is missing */ return 0; } ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki); assert(ksize<=256); /* store begin of signed data */ dataBegin=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0); if (!dataBegin) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No position specifications in segment"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } /* now get first signature tail */ while(n) { if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")==0) { unsigned int currpos; /* found a signature tail */ currpos=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0); if (!currpos || dataBegin>currpos) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Bad position specification in Signature tail"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } dataLength=currpos-dataBegin; break; } n=GWEN_DB_GetNextGroup(n); } /* while */ if (!n) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No signature tail found"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } sigtails=GWEN_List_new(); while(n) { if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")!=0) break; GWEN_List_PushBack(sigtails, n); n=GWEN_DB_GetNextGroup(n); } /* while */ if (!n) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Message tail expected"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } if (strcasecmp(GWEN_DB_GroupName(n), "MsgTail")!=0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (msg tail expected)"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } n=GWEN_DB_GetNextGroup(n); if (n) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (end expected)"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } if (GWEN_List_GetSize(sigheads)!= GWEN_List_GetSize(sigtails)) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Number of signature heads (%d) does not match " "number of signature tails (%d)", GWEN_List_GetSize(sigheads), GWEN_List_GetSize(sigtails)); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } /* ok, now verify all signatures */ dataStart=GWEN_Buffer_GetStart(hmsg->buffer)+dataBegin; for (i=0; i< GWEN_List_GetSize(sigtails); i++) { GWEN_DB_NODE *sighead; GWEN_DB_NODE *sigtail; const uint8_t *p; uint32_t l; int rv; uint8_t hash[20]; const char *signerId; /* get signature tail */ sigtail=(GWEN_DB_NODE*)GWEN_List_GetBack(sigtails); /* get corresponding signature head */ sighead=(GWEN_DB_NODE*)GWEN_List_GetFront(sigheads); if (!sighead || !sigtail) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No signature head/tail left (internal error)"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_INTERNAL; } GWEN_List_PopBack(sigtails); GWEN_List_PopFront(sigheads); signerId=GWEN_DB_GetCharValue(sighead, "key/userid", 0, I18N("unknown")); /* some checks */ if (strcasecmp(GWEN_DB_GetCharValue(sighead, "ctrlref", 0, ""), GWEN_DB_GetCharValue(sigtail, "ctrlref", 0, ""))!=0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Non-matching signature tail"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } /* hash signature head and data */ if (1) { GWEN_MDIGEST *md; /* hash sighead + data */ p=(const uint8_t*)GWEN_Buffer_GetStart(hmsg->buffer); p+=GWEN_DB_GetIntValue(sighead, "segment/pos", 0, 0); l=GWEN_DB_GetIntValue(sighead, "segment/length", 0, 0); md=GWEN_MDigest_Rmd160_new(); rv=GWEN_MDigest_Begin(md); if (rv==0) /* digest signature head */ rv=GWEN_MDigest_Update(md, p, l); if (rv==0) /* digest data */ rv=GWEN_MDigest_Update(md, (const uint8_t*)dataStart, dataLength); if (rv==0) rv=GWEN_MDigest_End(md); if (rv<0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv); GWEN_MDigest_free(md); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return rv; } memmove(hash, GWEN_MDigest_GetDigestPtr(md), GWEN_MDigest_GetDigestSize(md)); GWEN_MDigest_free(md); } /* verify signature */ p=GWEN_DB_GetBinValue(sigtail, "signature", 0, 0, 0, &l); if (p && l) { GWEN_CRYPT_PADDALGO *algo; algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize); rv=GWEN_Crypt_Token_Verify(ct, keyId, algo, hash, 20, p, l, 0, gid); GWEN_Crypt_PaddAlgo_free(algo); if (rv) { if (rv==GWEN_ERROR_NO_KEY) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Unable to verify signature of user \"%s\" (no key)", signerId); GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Unable to verify signature (no key)")); } else { GWEN_BUFFER *tbuf; tbuf=GWEN_Buffer_new(0, 32, 0, 1); if (rv==GWEN_ERROR_VERIFY) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Invalid signature of user \"%s\"", signerId); GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Invalid signature!!!")); GWEN_Buffer_AppendString(tbuf, "!"); } else { GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Could not verify signature")); DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not verify data with medium of user \"%s\" (%d)", AB_User_GetUserId(u), rv); GWEN_Buffer_AppendString(tbuf, "?"); } GWEN_Buffer_AppendString(tbuf, signerId); AH_Msg_AddSignerId(hmsg, GWEN_Buffer_GetStart(tbuf)); GWEN_Buffer_free(tbuf); } } else { DBG_INFO(AQHBCI_LOGDOMAIN, "Message signed by \"%s\"", signerId); AH_Msg_AddSignerId(hmsg, signerId); } } else { DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signature"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } DBG_DEBUG(AQHBCI_LOGDOMAIN, "Verification done"); } /* for */ GWEN_List_free(sigheads); GWEN_List_free(sigtails); return 0; }
int cryptWithNew2(GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; const char *ttype; const char *tname; GWEN_PLUGIN_MANAGER *pm; GWEN_PLUGIN *pl; GWEN_CRYPT_TOKEN *ct; unsigned int cid; 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 */ pm=GWEN_PluginManager_FindPluginManager("ct"); if (pm==0) { DBG_ERROR(0, "Plugin manager not found"); return 3; } pl=GWEN_PluginManager_GetPlugin(pm, ttype); if (pl==0) { DBG_ERROR(0, "Plugin not found"); return 3; } DBG_INFO(0, "Plugin found"); ct=GWEN_Crypt_Token_Plugin_CreateToken(pl, tname); if (ct==0) { DBG_ERROR(0, "Could not create crypt token"); 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 { uint8_t clearText[96]={ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60 }; uint8_t encrypted[128]; uint32_t elen; uint8_t decrypted[128]; uint32_t dlen; GWEN_CRYPT_PADDALGO *algo; algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None); elen=sizeof(encrypted); rv=GWEN_Crypt_Token_Encipher(ct, 0x02, algo, clearText, 96, encrypted, &elen, 0); if (rv) { DBG_ERROR(0, "Could not encipher data (%d)", rv); return 3; } fprintf(stderr, "Encrypted data is:\n"); GWEN_Text_DumpString((const char*) encrypted, elen, stderr, 2); dlen=sizeof(decrypted); rv=GWEN_Crypt_Token_Decipher(ct, 0x02, algo, encrypted, elen, decrypted, &dlen, 0); if (rv) { DBG_ERROR(0, "Could not decipher data (%d)", rv); return 3; } if (memcmp(clearText, decrypted, dlen)) { DBG_ERROR(0, "Deciphered data does not equal clear text(%d)", rv); return 3; } fprintf(stderr, "Deciphered data is ok.\n"); } /* close crypt token */ rv=GWEN_Crypt_Token_Close(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not close token"); return 3; } return 0; }
int AH_Msg_DecryptRdh2(AH_MSG *hmsg, GWEN_DB_NODE *gr){ AH_HBCI *h; GWEN_BUFFER *mbuf; uint32_t l; int rv; const uint8_t *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=NULL; uint8_t decKey[300]; GWEN_DB_NODE *nhead=NULL; GWEN_DB_NODE *ndata=NULL; const char *crypterId; 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_GetDecipherKeyId(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; } /* 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")); p=GWEN_DB_GetBinValue(nhead, "CryptAlgo/MsgKey", 0, 0,0, &l); if (p && l) { uint32_t elen; GWEN_CRYPT_PADDALGO *algo; uint8_t encKey[300]; int ksize; ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki); if (ksize<l) { DBG_WARN(AQHBCI_LOGDOMAIN, "Keyinfo keysize is smaller than size of transmitted key, adjusting"); ksize=l; } assert(ksize<=256); /* fill encoded key with 0 */ memset(encKey, 0, sizeof(encKey)); memmove(encKey+(ksize-l), p, l); algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None); elen=sizeof(decKey); rv=GWEN_Crypt_Token_Decipher(ct, keyId, algo, encKey, ksize, decKey, &elen, gid); GWEN_Crypt_PaddAlgo_free(algo); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv); return rv; } /* unpadd key (take right-handed 16 bytes) */ p=decKey+(elen-16); sk=GWEN_Crypt_KeyDes3K_fromData(GWEN_Crypt_CryptMode_Cbc, 24, p, 16); if (sk==NULL) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not create DES key from data"); return GWEN_ERROR_BAD_DATA; } } else { DBG_ERROR(AQHBCI_LOGDOMAIN, "Missing message key"); return GWEN_ERROR_BAD_DATA; } /* get encrypted data */ p=GWEN_DB_GetBinValue(ndata, "CryptData", 0, 0,0, &l); if (!p || !l) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt data"); GWEN_Crypt_Key_free(sk); return GWEN_ERROR_BAD_DATA; } /* decipher message with session key */ mbuf=GWEN_Buffer_new(0, l, 0, 1); rv=GWEN_Crypt_Key_Decipher(sk, (const uint8_t*)p, l, (uint8_t*)GWEN_Buffer_GetPosPointer(mbuf), &l); GWEN_Crypt_Key_free(sk); if (rv<0) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not decipher with DES session key (%d)", rv); GWEN_Buffer_free(mbuf); return rv; } GWEN_Buffer_IncrementPos(mbuf, l); GWEN_Buffer_AdjustUsedBytes(mbuf); /* unpadd message */ rv=GWEN_Padd_UnpaddWithAnsiX9_23(mbuf); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Error unpadding message with ANSI X9.23 (%d)", rv); GWEN_Buffer_free(mbuf); return rv; } /* 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 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; }
int AH_Msg_SignRdh2(AH_MSG *hmsg, AB_USER *su, GWEN_BUFFER *rawBuf, const char *signer) { AH_HBCI *h; GWEN_XMLNODE *node; GWEN_DB_NODE *cfg; GWEN_BUFFER *sigbuf; GWEN_BUFFER *hbuf; unsigned int l; int rv; char ctrlref[15]; const char *p; GWEN_MSGENGINE *e; uint32_t uFlags; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; 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; uFlags=AH_User_GetFlags(su); /* get crypt token of signer */ rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h), AH_User_GetTokenType(su), AH_User_GetTokenName(su), &ct); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not get crypt token for user \"%s\" (%d)", AB_User_GetUserId(su), 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(su), rv); return rv; } } /* get context and key info */ ctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(su), gid); if (ctx==NULL) { DBG_INFO(AQHBCI_LOGDOMAIN, "Context %d not found on crypt token [%s:%s]", AH_User_GetTokenContextId(su), GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); return GWEN_ERROR_NOT_FOUND; } keyId=GWEN_Crypt_Token_Context_GetSignKeyId(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; } node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "SigHead"); if (!node) { DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigHead\" not found"); return GWEN_ERROR_INTERNAL; } /* prepare config for segment */ cfg=GWEN_DB_Group_new("sighead"); rv=AH_MsgRdh_PrepareCryptoSeg2(hmsg, su, ki, 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 */ if (hmsg->noSysId) { GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0"); } else { p=AH_User_GetSystemId(su); if (p==NULL) p=GWEN_Crypt_Token_Context_GetSystemId(ctx); if (p) GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p); else { GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0"); } } /* 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", GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki)); /* 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; } /* remember size of sighead for now */ l=GWEN_Buffer_GetUsedBytes(hbuf); /* add raw data to to-sign data buffer */ GWEN_Buffer_AppendBuffer(hbuf, rawBuf); /* sign message */ sigbuf=GWEN_Buffer_new(0, 512, 0, 1); if (1) { uint32_t signLen; GWEN_CRYPT_PADDALGO *algo; GWEN_MDIGEST *md; uint32_t seq; /* hash sighead + data */ md=GWEN_MDigest_Rmd160_new(); rv=GWEN_MDigest_Begin(md); if (rv==0) rv=GWEN_MDigest_Update(md, (uint8_t*)GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf)); if (rv==0) rv=GWEN_MDigest_End(md); if (rv<0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv); GWEN_MDigest_free(md); GWEN_Buffer_free(sigbuf); GWEN_Buffer_free(hbuf); return rv; } /* sign hash */ algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki)); signLen=GWEN_Buffer_GetMaxUnsegmentedWrite(sigbuf); rv=GWEN_Crypt_Token_Sign(ct, keyId, algo, GWEN_MDigest_GetDigestPtr(md), GWEN_MDigest_GetDigestSize(md), (uint8_t*)GWEN_Buffer_GetPosPointer(sigbuf), &signLen, &seq, gid); GWEN_Crypt_PaddAlgo_free(algo); GWEN_MDigest_free(md); if (rv) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not sign data with medium of user \"%s\" (%d)", AB_User_GetUserId(su), rv); GWEN_Buffer_free(sigbuf); GWEN_Buffer_free(hbuf); return rv; } GWEN_Buffer_IncrementPos(sigbuf, signLen); GWEN_Buffer_AdjustUsedBytes(sigbuf); } DBG_DEBUG(AQHBCI_LOGDOMAIN, "Signing done"); /* 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), l); /* 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", GWEN_Buffer_GetStart(sigbuf), GWEN_Buffer_GetUsedBytes(sigbuf)); GWEN_Buffer_free(sigbuf); GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "ctrlref", ctrlref); /* 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 -1; } rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigTail"); GWEN_Buffer_free(hbuf); GWEN_DB_Group_free(cfg); return -1; } /* 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 -1; } 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 genKey(GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; const char *ttype; const char *tname; GWEN_CRYPT_TOKEN *ct; unsigned int keyId; unsigned int keySize; GWEN_CRYPT_CRYPTALGOID algoId; int rv; const char *s; const GWEN_ARGS args[]={ { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Int, /* type */ "keyId", /* name */ 1, /* minnum */ 1, /* maxnum */ "k", /* short option */ "key", /* long option */ "Key id", /* short description */ "Key id" /* 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_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "algo", /* name */ 0, /* minnum */ 1, /* maxnum */ "a", /* short option */ "algo", /* long option */ "Specify the algorithm", /* short description */ "Specify the algorithm" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Int, /* type */ "keysize", /* name */ 0, /* minnum */ 1, /* maxnum */ "s", /* short option */ "keysize", /* long option */ "Key size in bytes", /* short description */ "Key size in bytes" /* long description */ }, { 0, /* flags */ GWEN_ArgsType_Int, /* type */ "exp65537", /* name */ 0, /* minnum */ 1, /* maxnum */ "e", /* short option */ "exp65537", /* long option */ "Use default exponent of 65537", /* short description */ "Use default exponent of 65537" /* 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; } keyId=GWEN_DB_GetIntValue(db, "keyId", 0, 0); if (keyId==0) { DBG_ERROR(0, "Key Id must not be zero"); return 1; } s=GWEN_DB_GetCharValue(db, "algo", 0, "rsa"); if (!s) { DBG_ERROR(0, "Algo id missing"); return 1; } algoId=GWEN_Crypt_CryptAlgoId_fromString(s); if (algoId==GWEN_Crypt_CryptAlgoId_Unknown) { DBG_ERROR(0, "Bad algo id [%s]", s); return 1; } keySize=GWEN_DB_GetIntValue(db, "keySize", 0, 96); if (keySize==0) { DBG_ERROR(0, "Invalid key size %d", keySize); return 1; } 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); if (GWEN_DB_GetIntValue(db, "exp65537", 0, 0)) GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_EXP_65537); /* open crypt token for use */ rv=GWEN_Crypt_Token_Open(ct, 1, 0); if (rv) { DBG_ERROR(0, "Could not open token"); return 3; } else { GWEN_CRYPT_CRYPTALGO *algo; algo=GWEN_Crypt_CryptAlgo_new(algoId, GWEN_Crypt_CryptMode_None); GWEN_Crypt_CryptAlgo_SetChunkSize(algo, keySize); /* generate key */ rv=GWEN_Crypt_Token_GenerateKey(ct, keyId, algo, 0); if (rv) { DBG_ERROR(GWEN_LOGDOMAIN, "Error generating key (%d)", rv); GWEN_Crypt_CryptAlgo_free(algo); return 3; } } /* close crypt token */ rv=GWEN_Crypt_Token_Close(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not close token"); return 3; } fprintf(stderr, "Key %d (%s, %d bytes) successfully generated.\n", keyId, GWEN_Crypt_CryptAlgoId_toString(algoId), keySize); 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; }