Revision c659021c
Von Holger Magnussen vor mehr als 6 Jahren hinzugefügt
src/libs/plugins/backends/aqhbci/banking/provider_online.c | ||
---|---|---|
return rv;
|
||
}
|
||
|
||
if (AH_Job_GetKeys_GetCryptKeyInfo(job)==NULL) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt key received");
|
||
/* Store crypt and sign keys in database */
|
||
if (AH_Job_GetKeys_GetCryptKeyInfo(job)==NULL && AH_Job_GetKeys_GetSignKeyInfo(job)==NULL) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt key and no sign key received");
|
||
GWEN_Gui_ProgressLog(0,
|
||
GWEN_LoggerLevel_Error,
|
||
I18N("No crypt key received."));
|
||
I18N("No crypt key and no sign key received."));
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
... | ... | |
I18N("Could not commit result"));
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
}
|
||
}
|
||
|
||
if (AH_Job_GetKeys_GetSignKeyInfo(job)==0) {
|
||
GWEN_Gui_ProgressLog(0,
|
||
GWEN_LoggerLevel_Notice,
|
||
I18N("Bank does not use a sign key."));
|
||
}
|
||
|
||
/* lock user */
|
||
if (doLock) {
|
||
rv=AB_Provider_BeginExclUseUser(pro, u);
|
||
... | ... | |
DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not lock user (%d)\n", rv);
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
}
|
||
}
|
||
... | ... | |
GWEN_CRYPT_TOKEN_KEYINFO *ki;
|
||
uint32_t kid;
|
||
|
||
/* store sign key (if any) */
|
||
/* store sign key on token (if any) */
|
||
kid=GWEN_Crypt_Token_Context_GetVerifyKeyId(cctx);
|
||
ki=AH_Job_GetKeys_GetSignKeyInfo(job);
|
||
if (kid && ki) {
|
||
... | ... | |
ki,
|
||
0);
|
||
if (rv) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
|
||
GWEN_Gui_ProgressLog(0,
|
||
GWEN_LoggerLevel_Error,
|
||
I18N("Error saving sign key"));
|
||
if (doLock)
|
||
AB_Provider_EndExclUseUser(pro, u, 0);
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
|
||
GWEN_Gui_ProgressLog(0,GWEN_LoggerLevel_Error,
|
||
I18N("Error saving sign key"));
|
||
if (doLock)
|
||
AB_Provider_EndExclUseUser(pro, u, 0);
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
}
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "Sign key saved");
|
||
}
|
||
|
||
/* store crypt key */
|
||
/* store crypt key on token */
|
||
kid=GWEN_Crypt_Token_Context_GetEncipherKeyId(cctx);
|
||
ki=AH_Job_GetKeys_GetCryptKeyInfo(job);
|
||
if (kid && ki) {
|
||
... | ... | |
ki,
|
||
0);
|
||
if (rv) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
|
||
GWEN_Gui_ProgressLog(0,
|
||
GWEN_LoggerLevel_Error,
|
||
I18N("Error saving crypt key"));
|
||
if (doLock)
|
||
AB_Provider_EndExclUseUser(pro, u, 0);
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
|
||
GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error,
|
||
I18N("Error saving crypt key"));
|
||
if (doLock)
|
||
AB_Provider_EndExclUseUser(pro, u, 0);
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
}
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "Crypt key saved");
|
||
}
|
||
|
||
/* store auth key (if any) */
|
||
/* store auth key on token (if any) */
|
||
kid=GWEN_Crypt_Token_Context_GetAuthVerifyKeyId(cctx);
|
||
ki=AH_Job_GetKeys_GetAuthKeyInfo(job);
|
||
if (kid && ki) {
|
||
... | ... | |
ki,
|
||
0);
|
||
if (rv) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
|
||
GWEN_Gui_ProgressLog(0,
|
||
GWEN_LoggerLevel_Error,
|
||
I18N("Error saving auth key"));
|
||
if (doLock)
|
||
AB_Provider_EndExclUseUser(pro, u, 0);
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
|
||
GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error,
|
||
I18N("Error saving auth key"));
|
||
if (doLock)
|
||
AB_Provider_EndExclUseUser(pro, u, 0);
|
||
AH_Job_free(job);
|
||
if (!nounmount)
|
||
AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
|
||
return rv;
|
||
}
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "Auth key saved");
|
||
}
|
src/libs/plugins/backends/aqhbci/joblayer/job_commit.c | ||
---|---|---|
else if (strcasecmp(GWEN_DB_GroupName(dbRd), "GetKeyResponse")==0){
|
||
const char *keytype;
|
||
|
||
keytype=GWEN_DB_GetCharValue(dbRd, "key/keyType", 0, NULL);
|
||
keytype=GWEN_DB_GetCharValue(dbRd, "keyname/keytype", 0, NULL);
|
||
if (keytype && *keytype) {
|
||
GWEN_CRYPT_KEY * bpk;
|
||
const void *expp, *modp;
|
||
unsigned int expl, modl;
|
||
int keynum, keyver;
|
||
|
||
/* TODO: Ask the user to accept the key received */
|
||
DBG_WARN(AQHBCI_LOGDOMAIN, "GetKeyResponse not yet processed!");
|
||
keynum=GWEN_DB_GetIntValue(dbRd, "key/keynum", 0, -1);
|
||
keyver=GWEN_DB_GetIntValue(dbRd, "key/keyversion", 0, -1);
|
||
int keynum, keyver, i;
|
||
char hashString[1024];
|
||
uint8_t keyExpMod[512];
|
||
GWEN_MDIGEST *md;
|
||
|
||
/* process received keys */
|
||
keynum=GWEN_DB_GetIntValue(dbRd, "keyname/keynum", 0, -1);
|
||
keyver=GWEN_DB_GetIntValue(dbRd, "keyname/keyversion", 0, -1);
|
||
modp=GWEN_DB_GetBinValue(dbRd, "key/modulus", 0, NULL, 0, &modl);
|
||
expp=GWEN_DB_GetBinValue(dbRd, "key/exponent", 0, NULL, 0, &expl);
|
||
bpk=GWEN_Crypt_KeyRsa_fromModExp(256, modp, modl, expp, expl);
|
||
if (strcasecmp(keytype, "S")==0) {
|
||
DBG_WARN(AQHBCI_LOGDOMAIN, "Received new server sign key, please verify! (num: %d, version: %d)", keynum, keyver);
|
||
GWEN_Crypt_Key_SetKeyNumber(bpk, keynum);
|
||
GWEN_Crypt_Key_SetKeyVersion(bpk, keyver);
|
||
|
||
/* calculate key hash */
|
||
memset(keyExpMod, 0, 512);
|
||
memcpy(keyExpMod+256-expl, expp, expl);
|
||
memcpy(keyExpMod+256, modp, 256);
|
||
|
||
md=GWEN_MDigest_Sha256_new();
|
||
rv=GWEN_MDigest_Begin(md);
|
||
if (rv==0) rv=GWEN_MDigest_Update(md, keyExpMod, 512);
|
||
if (rv==0) rv=GWEN_MDigest_End(md);
|
||
memset(hashString, 0, 1024);
|
||
for(i=0; i<GWEN_MDigest_GetDigestSize(md); i++)
|
||
sprintf(hashString+3*i, "%02x ", *(GWEN_MDigest_GetDigestPtr(md)+i));
|
||
GWEN_MDigest_free(md);
|
||
|
||
/* commit the new key */
|
||
if (strcasecmp(keytype, "S")==0) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Received new server sign key, please verify! (num: %d, version: %d, hash: %s)", keynum, keyver, hashString);
|
||
GWEN_Gui_ProgressLog2(0,
|
||
GWEN_LoggerLevel_Warning,
|
||
I18N("Received new server sign key, please verify! (num: %d, version: %d)"),
|
||
keynum, keyver);
|
||
AH_User_SetBankPubSignKey(u, bpk);
|
||
I18N("Received new server sign key, please verify! (num: %d, version: %d, hash: %s)"),
|
||
keynum, keyver, hashString);
|
||
|
||
rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_WARN | GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
|
||
I18N("Received Public Bank Sign Key"),
|
||
I18N("Do you really want to import this key?"),
|
||
I18N("Import"), I18N("Abort"), NULL, 0);
|
||
if (rv==1) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Imported sign key.");
|
||
AH_User_SetBankPubSignKey(u, bpk);
|
||
}
|
||
else {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Sign key not imported.");
|
||
}
|
||
}
|
||
else if (strcasecmp(keytype, "V")==0) {
|
||
DBG_WARN(AQHBCI_LOGDOMAIN, "Received new server crypt key, please verify! (num: %d, version: %d)", keynum, keyver);
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Received new server crypt key, please verify! (num: %d, version: %d, hash: %s)", keynum, keyver, hashString);
|
||
GWEN_Gui_ProgressLog2(0,
|
||
GWEN_LoggerLevel_Warning,
|
||
I18N("Received new server crypt key, please verify! (num: %d, version: %d)"),
|
||
keynum, keyver);
|
||
AH_User_SetBankPubCryptKey(u, bpk);
|
||
I18N("Received new server crypt key, please verify! (num: %d, version: %d, hash: %s)"),
|
||
keynum, keyver, hashString);
|
||
rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_WARN | GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
|
||
I18N("Received Public Bank Crypt Key"),
|
||
I18N("Do you really want to import this key?"),
|
||
I18N("Import"), I18N("Abort"), NULL, 0);
|
||
if (rv==1) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Imported crypt key.");
|
||
AH_User_SetBankPubCryptKey(u, bpk);
|
||
}
|
||
else {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Crypt key not imported.");
|
||
}
|
||
}
|
||
else {
|
||
DBG_WARN(AQHBCI_LOGDOMAIN, "Received unknown server key: type=%s, num=%d, version=%d", keytype, keynum, keyver);
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Received unknown server key: type=%s, num=%d, version=%d, hash=%s", keytype, keynum, keyver, hashString);
|
||
GWEN_Gui_ProgressLog2(0,
|
||
GWEN_LoggerLevel_Warning,
|
||
I18N("Received unknown server key: type=%s, num=%d, version=%d"),
|
||
keytype, keynum, keyver);
|
||
I18N("Received unknown server key: type=%s, num=%d, version=%d, hash=%s"),
|
||
keytype, keynum, keyver, hashString);
|
||
}
|
||
}
|
||
}
|
src/libs/plugins/backends/aqhbci/msglayer/msgcrypt_rdh9.c | ||
---|---|---|
|
||
int AH_MsgRdh_PrepareCryptoSeg9(AH_MSG *hmsg,
|
||
AB_USER *u,
|
||
const GWEN_CRYPT_TOKEN_KEYINFO *ki,
|
||
int keyNum,
|
||
int keyVer,
|
||
GWEN_DB_NODE *cfg,
|
||
int crypt,
|
||
int createCtrlRef) {
|
||
... | ... | |
"key/keytype",
|
||
crypt?"V":"S");
|
||
GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
|
||
"key/keynum",
|
||
9);
|
||
// GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
|
||
"key/keynum", keyNum);
|
||
GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
|
||
"key/keyversion",
|
||
1);
|
||
// GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
|
||
"key/keyversion", keyVer);
|
||
GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
|
||
"secProfile/code",
|
||
"RDH");
|
||
... | ... | |
|
||
/* prepare config for segment */
|
||
cfg=GWEN_DB_Group_new("sighead");
|
||
rv=AH_MsgRdh_PrepareCryptoSeg9(hmsg, su, ki, cfg, 0, 1);
|
||
rv=AH_MsgRdh_PrepareCryptoSeg9(hmsg, su, 9, 1, cfg, 0, 1);
|
||
if (rv) {
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
|
||
GWEN_DB_Group_free(cfg);
|
||
... | ... | |
GWEN_CRYPT_PADDALGO *algo;
|
||
GWEN_MDIGEST *md;
|
||
uint32_t seq;
|
||
//uint8_t hash1[32];
|
||
|
||
/* hash sighead + data */
|
||
md=GWEN_MDigest_Sha256_new();
|
||
... | ... | |
|
||
/* sign hash */
|
||
algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256);
|
||
//GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
|
||
signLen=GWEN_Buffer_GetMaxUnsegmentedWrite(sigbuf);
|
||
|
||
/*
|
||
for(int ii=0; ii<GWEN_MDigest_GetDigestSize(md); ii++)
|
||
fprintf(stderr, "%2x ", *(GWEN_MDigest_GetDigestPtr(md)+ii));
|
||
*/
|
||
|
||
// ToDo: algo rausnehmen (wird nicht benutzt)
|
||
rv=GWEN_Crypt_Token_Sign(ct, keyId,
|
||
algo,
|
||
GWEN_MDigest_GetDigestPtr(md),
|
||
... | ... | |
&signLen,
|
||
&seq,
|
||
gid);
|
||
//GWEN_Crypt_PaddAlgo_free(algo);
|
||
|
||
GWEN_MDigest_free(md);
|
||
if (rv) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN,
|
||
... | ... | |
}
|
||
|
||
|
||
|
||
int AH_Msg_EncryptRdh9(AH_MSG *hmsg) {
|
||
AH_HBCI *h;
|
||
GWEN_XMLNODE *node;
|
||
... | ... | |
}
|
||
GWEN_Crypt_Key_free(sk);
|
||
|
||
/* create crypt head */
|
||
/* find crypt head */
|
||
node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
|
||
"SEG",
|
||
"id",
|
||
... | ... | |
return GWEN_ERROR_INTERNAL;
|
||
}
|
||
|
||
/* create CryptHead */
|
||
/* create crypt head */
|
||
cfg=GWEN_DB_Group_new("crypthead");
|
||
GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
|
||
"head/seq", 998);
|
||
|
||
rv=AH_MsgRdh_PrepareCryptoSeg9(hmsg, u, ki, cfg, 1, 0);
|
||
rv=AH_MsgRdh_PrepareCryptoSeg9(hmsg, u, GWEN_Crypt_Key_GetKeyNumber(ek), GWEN_Crypt_Key_GetKeyVersion(ek), cfg, 1, 0);
|
||
if (rv) {
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
|
||
GWEN_DB_Group_free(cfg);
|
||
... | ... | |
GWEN_Buffer_free(mbuf);
|
||
return rv;
|
||
}
|
||
GWEN_DB_Group_free(cfg);
|
||
|
||
/* create cryptdata */
|
||
cfg=GWEN_DB_Group_new("cryptdata");
|
||
... | ... | |
uint32_t gid;
|
||
GWEN_CRYPT_KEY *bsk=NULL;
|
||
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "===> hm: called AH_Msg_VerifyRdh9 - hmsg, gr");
|
||
|
||
assert(hmsg);
|
||
h=AH_Dialog_GetHbci(hmsg->dialog);
|
||
assert(h);
|
||
... | ... | |
/* only now we need the verify key */
|
||
bsk=AH_User_GetBankPubSignKey(u);
|
||
if(!bsk) {
|
||
int rv;
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Bank public sign key not downloaded, please get it!");
|
||
GWEN_Gui_ProgressLog(gid,
|
||
GWEN_LoggerLevel_Warning,
|
||
I18N("Bank public signature key not yet downloaded/installed, cannot verify signature."));
|
||
if (!(AH_User_GetFlags(u) & AH_USER_FLAGS_VERIFY_NO_BANKSIGNKEY)) {
|
||
int rv;
|
||
|
||
rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_WARN | GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
|
||
I18N("No Public Bank Sign Key"),
|
||
I18N("We do not have the public signature key of the bank, so we can not verify "
|
||
"possible signatures."
|
||
"You can ignore this message if you are already retrieving the bank keys in this "
|
||
"dialog."),
|
||
I18N("Continue"), I18N("Abort"), NULL, 0);
|
||
if (rv!=1) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Aborted by user.");
|
||
|
||
rv=GWEN_Gui_MessageBox(GWEN_GUI_MSG_FLAGS_TYPE_WARN | GWEN_GUI_MSG_FLAGS_SEVERITY_DANGEROUS,
|
||
I18N("No Public Bank Sign Key"),
|
||
I18N("We do not have the public signature key of the bank, so we can not verify "
|
||
"possible signatures."
|
||
"You can ignore this message if you are already retrieving the bank keys in this "
|
||
"dialog."),
|
||
I18N("Continue"), I18N("Abort"), NULL, 0);
|
||
if (rv!=1) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Aborted by user.");
|
||
GWEN_List_free(sigheads);
|
||
return GWEN_ERROR_USER_ABORTED;
|
||
}
|
||
AH_User_AddFlags(u, AH_USER_FLAGS_VERIFY_NO_BANKSIGNKEY);
|
||
GWEN_List_free(sigheads);
|
||
return 0;
|
||
}
|
||
else {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Message about missing bank public sign key already shown, ignore.");
|
||
return 0;
|
||
}
|
||
GWEN_List_free(sigheads);
|
||
return 0;
|
||
}
|
||
|
||
/* TODO: replace the following code with code which verifies the signature using the stored key in "bsk" */
|
||
/* check keyId, should be always =0 for RDH9 */
|
||
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);
|
||
ksize=GWEN_Crypt_Key_GetKeySize(bsk);
|
||
assert(ksize<=AH_MSGRDH9_MAXKEYBUF);
|
||
|
||
/* store begin of signed data */
|
||
... | ... | |
GWEN_DB_NODE *sighead;
|
||
GWEN_DB_NODE *sigtail;
|
||
const uint8_t *p;
|
||
uint32_t l;
|
||
uint32_t l, lenDecryptedSignature;
|
||
int rv;
|
||
uint8_t hash[32];
|
||
uint8_t decryptedSignature[1024];
|
||
const char *signerId;
|
||
GWEN_MDIGEST *md;
|
||
|
||
/* get signature tail */
|
||
sigtail=(GWEN_DB_NODE*)GWEN_List_GetBack(sigtails);
|
||
... | ... | |
|
||
/* hash signature head and data */
|
||
if (1) {
|
||
GWEN_MDIGEST *md;
|
||
uint8_t hash1[32];
|
||
|
||
/* hash sighead + data */
|
||
... | ... | |
|
||
/* first round */
|
||
rv=GWEN_MDigest_Begin(md);
|
||
|
||
if (rv==0)
|
||
/* digest signature head */
|
||
rv=GWEN_MDigest_Update(md, p, l);
|
||
rv=GWEN_MDigest_Update(md, p, l);
|
||
|
||
if (rv==0)
|
||
/* digest data */
|
||
rv=GWEN_MDigest_Update(md, (const uint8_t*)dataStart, dataLength);
|
||
/* digest data */
|
||
rv=GWEN_MDigest_Update(md, (const uint8_t*)dataStart, dataLength);
|
||
|
||
if (rv==0)
|
||
rv=GWEN_MDigest_End(md);
|
||
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;
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
|
||
GWEN_MDigest_free(md);
|
||
GWEN_List_free(sigheads);
|
||
GWEN_List_free(sigtails);
|
||
return rv;
|
||
}
|
||
|
||
memmove(hash1,
|
||
GWEN_MDigest_GetDigestPtr(md),
|
||
GWEN_MDigest_GetDigestSize(md));
|
||
... | ... | |
/* second round */
|
||
rv=GWEN_MDigest_Begin(md);
|
||
if (rv==0)
|
||
/* digest signature head */
|
||
rv=GWEN_MDigest_Update(md, hash1, sizeof(hash1));
|
||
/* digest signature head */
|
||
rv=GWEN_MDigest_Update(md, hash1, sizeof(hash1));
|
||
|
||
if (rv==0)
|
||
rv=GWEN_MDigest_End(md);
|
||
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;
|
||
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));
|
||
... | ... | |
|
||
/* verify signature */
|
||
p=GWEN_DB_GetBinValue(sigtail, "signature", 0, 0, 0, &l);
|
||
|
||
if (p && l) {
|
||
GWEN_CRYPT_PADDALGO *algo;
|
||
/* decipher signature with public key bsk */
|
||
lenDecryptedSignature=l;
|
||
rv=GWEN_Crypt_Key_Encipher(bsk, p, l, decryptedSignature, &lenDecryptedSignature);
|
||
if (rv<0 || lenDecryptedSignature != 256) {
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Unable to decrypt signature of user \"%s\"", signerId);
|
||
GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Unable to decrypt signature)"));
|
||
GWEN_List_free(sigheads);
|
||
GWEN_List_free(sigtails);
|
||
return GWEN_ERROR_BAD_DATA;
|
||
}
|
||
|
||
algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256);
|
||
GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize);
|
||
rv=GWEN_Crypt_Token_Verify(ct, keyId,
|
||
algo,
|
||
hash, 32, p, l, 0, gid);
|
||
GWEN_Crypt_PaddAlgo_free(algo);
|
||
/* verify decrypted signature according to PKCS#1-PSS */
|
||
md=GWEN_MDigest_Sha256_new();
|
||
rv=GWEN_Padd_VerifyPkcs1Pss(decryptedSignature, lenDecryptedSignature,
|
||
2048, hash, sizeof(hash), 32, md);
|
||
|
||
GWEN_MDigest_free(md);
|
||
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);
|
||
}
|
||
DBG_ERROR(AQHBCI_LOGDOMAIN, "Unable to verify signature of user \"%s\"", signerId);
|
||
GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Unable to verify signature"));
|
||
GWEN_List_free(sigheads);
|
||
GWEN_List_free(sigtails);
|
||
return GWEN_ERROR_BAD_DATA;
|
||
}
|
||
else {
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "Message signed by \"%s\"", signerId);
|
||
AH_Msg_AddSignerId(hmsg, signerId);
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "Message signed by \"%s\"", signerId);
|
||
AH_Msg_AddSignerId(hmsg, signerId);
|
||
}
|
||
}
|
||
else {
|
||
... | ... | |
|
||
GWEN_List_free(sigheads);
|
||
GWEN_List_free(sigtails);
|
||
DBG_INFO(AQHBCI_LOGDOMAIN, "===> hm: successfully verified in AH_Msg_VerifyRdh9");
|
||
return 0;
|
||
}
|
Auch abrufbar als: Unified diff
1. src/libs/plugins/backends/aqhbci/msglayer/msgcrypt_rdh9.c * Verifizierung der Banksignatur (war ein ziemliches Gefrickel mit
langem Suchen in verschiedenen Standards) * Einbau eines Mechanismus, dass bei user-signierten Nachrichten
die richtigen keynum/keyver des öffentlichen bank crypt keys
eingebaut werden (war vorher fest auf 9/1 eingestellt, was die
Commerzbank anders als die DB bemängelt hat)
2. src/libs/plugins/backends/aqhbci/banking/provider_online.c * Anstoßen des commits, falls sign key oder crypt key empfangen wurden
3. src/libs/plugins/backends/aqhbci/joblayer/job_commit.c * Runtergeladene Schlüssel wurden erst nicht abgespeichert, weil
nach "key/keyType" statt nach "keyname/keytype" gesucht wurde * Berechnung des Key Hash von crypt und sign key und Anzeige,
Abfrage ob diese Schlüssel wirklich abgespeichert werden sollen