1 /***************************************************************************
2 begin : Mon Mar 01 2004
3 copyright : (C) 2019 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13
14
15
16 #include "provider_p.h"
17
18 #include "aqebics/aqebics_l.h"
19 #include "aqebics/client/user_l.h"
20 #include "aqebics/client/account_l.h"
21 #include "aqebics/requests/r_ini_l.h"
22 #include "aqebics/msg/xml.h"
23 #include "aqebics/msg/keys.h"
24 #include "aqebics/dialogs/dlg_edituser_l.h"
25 #include "aqebics/dialogs/dlg_newkeyfile_l.h"
26 #include "aqebics/control/control_l.h"
27
28 #include "aqbanking/backendsupport/provider_be.h"
29 #include "aqbanking/backendsupport/account.h"
30 #include "aqbanking/backendsupport/httpsession.h"
31
32 #include <aqbanking/banking_be.h>
33 #include <aqbanking/types/value.h>
34
35 #include <gwenhywfar/debug.h>
36 #include <gwenhywfar/inherit.h>
37 #include <gwenhywfar/base64.h>
38 #include <gwenhywfar/text.h>
39 #include <gwenhywfar/ct.h>
40 #include <gwenhywfar/gui.h>
41
42
43
GWEN_INHERIT(AB_PROVIDER,EBC_PROVIDER)44 GWEN_INHERIT(AB_PROVIDER, EBC_PROVIDER)
45
46
47
48 AB_PROVIDER *EBC_Provider_new(AB_BANKING *ab)
49 {
50 AB_PROVIDER *pro;
51 EBC_PROVIDER *dp;
52
53 pro=AB_Provider_new(ab, "aqebics");
54 GWEN_NEW_OBJECT(EBC_PROVIDER, dp);
55 GWEN_INHERIT_SETDATA(AB_PROVIDER, EBC_PROVIDER, pro, dp, EBC_Provider_FreeData);
56
57 AB_Provider_SetInitFn(pro, EBC_Provider_Init);
58 AB_Provider_SetFiniFn(pro, EBC_Provider_Fini);
59
60 AB_Provider_SetSendCommandsFn(pro, EBC_Provider_SendCommands);
61 AB_Provider_SetCreateAccountObjectsFn(pro, EBC_Provider_CreateAccountObject);
62 AB_Provider_SetCreateUserObjectsFn(pro, EBC_Provider_CreateUserObject);
63
64 AB_Provider_SetUpdateAccountSpecFn(pro, EBC_Provider_UpdateAccountSpec);
65 AB_Provider_SetControlFn(pro, EBC_Control);
66
67 AB_Provider_SetGetEditUserDialogFn(pro, EBC_Provider_GetEditUserDialog);
68 AB_Provider_AddFlags(pro, AB_PROVIDER_FLAGS_HAS_EDITUSER_DIALOG);
69
70 AB_Provider_SetGetNewUserDialogFn(pro, EBC_Provider_GetNewUserDialog);
71
72 AB_Provider_AddFlags(pro, AB_PROVIDER_FLAGS_HAS_NEWUSER_DIALOG);
73
74
75 return pro;
76 }
77
78
79
EBC_Provider_FreeData(GWEN_UNUSED void * bp,void * p)80 void GWENHYWFAR_CB EBC_Provider_FreeData(GWEN_UNUSED void *bp, void *p)
81 {
82 EBC_PROVIDER *dp;
83
84 dp=(EBC_PROVIDER *)p;
85 assert(dp);
86
87 GWEN_FREE_OBJECT(dp);
88 }
89
90
91
EBC_Provider_GetConnectTimeout(const AB_PROVIDER * pro)92 int EBC_Provider_GetConnectTimeout(const AB_PROVIDER *pro)
93 {
94 EBC_PROVIDER *dp;
95
96 assert(pro);
97 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
98 assert(dp);
99
100 return dp->connectTimeout;
101 }
102
103
104
EBC_Provider_GetTransferTimeout(const AB_PROVIDER * pro)105 int EBC_Provider_GetTransferTimeout(const AB_PROVIDER *pro)
106 {
107 EBC_PROVIDER *dp;
108
109 assert(pro);
110 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
111 assert(dp);
112
113 return dp->transferTimeout;
114 }
115
116
117
EBC_Provider_Init(AB_PROVIDER * pro,GWEN_DB_NODE * dbData)118 int EBC_Provider_Init(AB_PROVIDER *pro, GWEN_DB_NODE *dbData)
119 {
120 EBC_PROVIDER *dp;
121 const char *logLevelName;
122
123 assert(pro);
124 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
125 assert(dp);
126
127 if (!GWEN_Logger_IsOpen(AQEBICS_LOGDOMAIN)) {
128 GWEN_Logger_Open(AQEBICS_LOGDOMAIN,
129 "aqebics", 0,
130 GWEN_LoggerType_Console,
131 GWEN_LoggerFacility_User);
132 }
133
134 logLevelName=getenv("AQEBICS_LOGLEVEL");
135 if (logLevelName) {
136 GWEN_LOGGER_LEVEL ll;
137
138 ll=GWEN_Logger_Name2Level(logLevelName);
139 if (ll!=GWEN_LoggerLevel_Unknown) {
140 GWEN_Logger_SetLevel(AQEBICS_LOGDOMAIN, ll);
141 DBG_WARN(AQEBICS_LOGDOMAIN,
142 "Overriding loglevel for AqEBICS with \"%s\"",
143 logLevelName);
144 }
145 else {
146 DBG_ERROR(AQEBICS_LOGDOMAIN, "Unknown loglevel \"%s\"",
147 logLevelName);
148 }
149 }
150
151 DBG_NOTICE(AQEBICS_LOGDOMAIN, "Initializing AqEBICS backend");
152 dp->connectTimeout=GWEN_DB_GetIntValue(dbData, "connectTimeout", 0,
153 EBC_DEFAULT_CONNECT_TIMEOUT);
154 dp->transferTimeout=GWEN_DB_GetIntValue(dbData, "transferTimeout", 0,
155 EBC_DEFAULT_TRANSFER_TIMEOUT);
156
157 return 0;
158 }
159
160
161
EBC_Provider_Fini(AB_PROVIDER * pro,GWEN_DB_NODE * dbData)162 int EBC_Provider_Fini(AB_PROVIDER *pro, GWEN_DB_NODE *dbData)
163 {
164 EBC_PROVIDER *dp;
165 uint32_t currentVersion;
166
167 DBG_NOTICE(AQEBICS_LOGDOMAIN, "Deinitializing AqEBICS backend");
168
169 assert(pro);
170 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
171 assert(dp);
172
173 currentVersion=
174 (AQBANKING_VERSION_MAJOR<<24) |
175 (AQBANKING_VERSION_MINOR<<16) |
176 (AQBANKING_VERSION_PATCHLEVEL<<8) |
177 AQBANKING_VERSION_BUILD;
178
179 /* save configuration */
180 DBG_NOTICE(AQEBICS_LOGDOMAIN, "Setting version %08x",
181 currentVersion);
182 GWEN_DB_SetIntValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
183 "lastVersion", currentVersion);
184
185 GWEN_DB_SetIntValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
186 "connectTimeout", dp->connectTimeout);
187 GWEN_DB_SetIntValue(dbData, GWEN_DB_FLAGS_OVERWRITE_VARS,
188 "transferTimeout", dp->transferTimeout);
189
190 return 0;
191 }
192
193
194 #if 0
195 int EBC_Provider_UpdateJob(AB_PROVIDER *pro, AB_JOB *j)
196 {
197 EBC_PROVIDER *dp;
198 AB_ACCOUNT *a;
199 AB_USER *u;
200
201 assert(pro);
202 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
203 assert(dp);
204
205 a=AB_Job_GetAccount(j);
206 assert(a);
207
208 u=AB_Account_GetFirstUser(a);
209 if (u==NULL) {
210 DBG_ERROR(AQEBICS_LOGDOMAIN, "No user assigned to this account.");
211 GWEN_Gui_ProgressLog(0,
212 GWEN_LoggerLevel_Error,
213 I18N("No user assigned to this account."));
214 GWEN_Gui_ShowError(I18N("Setup Error"),
215 I18N("No user assigned to this account. Please assign one in the online banking setup dialog "
216 "for this account.\n"));
217 return GWEN_ERROR_INTERNAL;
218 }
219
220 switch (AB_Job_GetType(j)) {
221 case AB_Job_TypeTransfer: {
222 AB_TRANSACTION_LIMITS *lim;
223
224 lim=AB_TransactionLimits_new();
225 AB_TransactionLimits_SetMaxLenPurpose(lim, 27);
226 AB_TransactionLimits_SetMaxLenRemoteName(lim, 27);
227 AB_TransactionLimits_SetMaxLinesPurpose(lim, 2);
228
229 AB_Job_SetFieldLimits(j, lim);
230 AB_TransactionLimits_free(lim);
231
232 break;
233 }
234
235 case AB_Job_TypeDebitNote: {
236 AB_TRANSACTION_LIMITS *lim;
237
238 lim=AB_TransactionLimits_new();
239 AB_TransactionLimits_SetMaxLenPurpose(lim, 27);
240 AB_TransactionLimits_SetMaxLenRemoteName(lim, 27);
241 AB_TransactionLimits_SetMaxLinesPurpose(lim, 2);
242
243 AB_Job_SetFieldLimits(j, lim);
244 AB_TransactionLimits_free(lim);
245
246 break;
247 }
248
249 case AB_Job_TypeGetTransactions:
250 break;
251
252 case AB_Job_TypeGetBalance:
253 default:
254 DBG_INFO(AQEBICS_LOGDOMAIN,
255 "Job not yet supported (%d)",
256 AB_Job_GetType(j));
257 return GWEN_ERROR_NOT_SUPPORTED;
258 } /* switch */
259 return 0;
260 }
261 #endif
262
263
264
EBC_Provider_GetEditUserDialog(AB_PROVIDER * pro,AB_USER * u)265 GWEN_DIALOG *EBC_Provider_GetEditUserDialog(AB_PROVIDER *pro, AB_USER *u)
266 {
267 EBC_PROVIDER *xp;
268 GWEN_DIALOG *dlg;
269
270 assert(pro);
271 xp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
272 assert(xp);
273
274 dlg=EBC_EditUserDialog_new(pro, u, 1);
275 if (dlg==NULL) {
276 DBG_INFO(AQEBICS_LOGDOMAIN, "here (no dialog)");
277 return NULL;
278 }
279
280 return dlg;
281 }
282
283
284
EBC_Provider_GetNewUserDialog(AB_PROVIDER * pro,int i)285 GWEN_DIALOG *EBC_Provider_GetNewUserDialog(AB_PROVIDER *pro, int i)
286 {
287 EBC_PROVIDER *xp;
288 GWEN_DIALOG *dlg;
289
290 assert(pro);
291 xp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
292 assert(xp);
293
294 dlg=EBC_NewKeyFileDialog_new(pro);
295 if (dlg==NULL) {
296 DBG_INFO(AQEBICS_LOGDOMAIN, "here (no dialog)");
297 return NULL;
298 }
299
300 return dlg;
301 }
302
303
304
EBC_Provider_CreateAccountObject(AB_PROVIDER * pro)305 AB_ACCOUNT *EBC_Provider_CreateAccountObject(AB_PROVIDER *pro)
306 {
307 return EBC_Account_new(pro);
308 }
309
310
311
EBC_Provider_CreateUserObject(AB_PROVIDER * pro)312 AB_USER *EBC_Provider_CreateUserObject(AB_PROVIDER *pro)
313 {
314 return EBC_User_new(pro);
315 }
316
317
318
EBC_Provider_MountToken(AB_PROVIDER * pro,AB_USER * u,GWEN_CRYPT_TOKEN ** pCt,const GWEN_CRYPT_TOKEN_CONTEXT ** pCtx)319 int EBC_Provider_MountToken(AB_PROVIDER *pro,
320 AB_USER *u,
321 GWEN_CRYPT_TOKEN **pCt,
322 const GWEN_CRYPT_TOKEN_CONTEXT **pCtx)
323 {
324 EBC_PROVIDER *dp;
325 int rv;
326 GWEN_CRYPT_TOKEN *ct;
327 const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
328
329 assert(pro);
330 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
331 assert(dp);
332
333 /* get crypt token of signer */
334 rv=AB_Banking_GetCryptToken(AB_Provider_GetBanking(pro),
335 EBC_User_GetTokenType(u),
336 EBC_User_GetTokenName(u),
337 &ct);
338 if (rv) {
339 DBG_INFO(AQEBICS_LOGDOMAIN,
340 "Could not get crypt token for user \"%s\" (%d)",
341 AB_User_GetUserId(u), rv);
342 return rv;
343 }
344
345 /* make sure the right flags are set */
346 DBG_INFO(AQEBICS_LOGDOMAIN, "Adding mode \"direct sign\" to CryptToken");
347 GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN);
348
349 /* open CryptToken if necessary */
350 if (!GWEN_Crypt_Token_IsOpen(ct)) {
351 rv=GWEN_Crypt_Token_Open(ct, 0, 0);
352 if (rv) {
353 DBG_INFO(AQEBICS_LOGDOMAIN,
354 "Could not open crypt token for user \"%s\" (%d)",
355 AB_User_GetUserId(u), rv);
356 return rv;
357 }
358 }
359
360 /* get context and key info */
361 ctx=GWEN_Crypt_Token_GetContext(ct,
362 EBC_User_GetTokenContextId(u),
363 0);
364 if (ctx==NULL) {
365 DBG_INFO(AQEBICS_LOGDOMAIN,
366 "Context %d not found on crypt token [%s:%s]",
367 EBC_User_GetTokenContextId(u),
368 GWEN_Crypt_Token_GetTypeName(ct),
369 GWEN_Crypt_Token_GetTokenName(ct));
370 return GWEN_ERROR_NOT_FOUND;
371 }
372
373 *pCt=ct;
374 *pCtx=ctx;
375
376 return 0;
377 }
378
379
380
EBC_Provider_GenerateNonce(GWEN_UNUSED AB_PROVIDER * pro,GWEN_BUFFER * buf)381 int EBC_Provider_GenerateNonce(GWEN_UNUSED AB_PROVIDER *pro, GWEN_BUFFER *buf)
382 {
383 int rv;
384 uint8_t rbuf[16];
385
386 GWEN_Crypt_Random(2, rbuf, sizeof(rbuf));
387 rv=GWEN_Text_ToHexBuffer((const char *)rbuf, sizeof(rbuf), buf, 0, 0, 0);
388 if (rv) {
389 DBG_ERROR(AQEBICS_LOGDOMAIN,
390 "Could not convert NONCE to hex (%d)", rv);
391 return rv;
392 }
393
394 DBG_DEBUG(AQEBICS_LOGDOMAIN,
395 "Generated NONCE [%s]",
396 GWEN_Buffer_GetStart(buf));
397
398 return 0;
399 }
400
401
402
EBC_Provider_GenerateTimeStamp(GWEN_UNUSED AB_PROVIDER * pro,AB_USER * u,GWEN_BUFFER * buf)403 int EBC_Provider_GenerateTimeStamp(GWEN_UNUSED AB_PROVIDER *pro,
404 AB_USER *u,
405 GWEN_BUFFER *buf)
406 {
407 char timestamp[40];
408 time_t ti;
409 struct tm *t;
410
411 ti=time(0);
412 /*
413 if (EBC_User_GetFlags(u) & EBC_USER_FLAGS_TIMESTAMP_FIX1) {
414 */
415 t=gmtime(&ti);
416 snprintf(timestamp, sizeof(timestamp)-1,
417 "%04d-%02d-%02dT%02d:%02d:%02d.000Z",
418 t->tm_year+1900,
419 t->tm_mon+1,
420 t->tm_mday,
421 t->tm_hour,
422 t->tm_min,
423 t->tm_sec);
424 timestamp[sizeof(timestamp)-1]=0;
425 DBG_DEBUG(AQEBICS_LOGDOMAIN,
426 "Generated timestamp [%s]",
427 timestamp);
428 GWEN_Buffer_AppendString(buf, timestamp);
429 /*
430 }
431 else {
432 int thzone;
433
434 t=localtime(&ti);
435 thzone=-timezone/60;
436 if (t->tm_isdst>0)
437 thzone+=60;
438 snprintf(timestamp, sizeof(timestamp)-1,
439 "%04d-%02d-%02dT%02d:%02d:%02d.000%+03d:%02d",
440 t->tm_year+1900,
441 t->tm_mon+1,
442 t->tm_mday,
443 t->tm_hour,
444 t->tm_min,
445 t->tm_sec,
446 (int)(thzone/60),
447 abs(thzone%60));
448 timestamp[sizeof(timestamp)-1]=0;
449 DBG_DEBUG(AQEBICS_LOGDOMAIN,
450 "Generated timestamp [%s] (tz=%d, daylight=%d)",
451 timestamp, (int)timezone, t->tm_isdst);
452 GWEN_Buffer_AppendString(buf, timestamp);
453 }
454 */
455
456 return 0;
457 }
458
459
460
EBC_Provider_Generate_OrderId(AB_PROVIDER * pro,GWEN_BUFFER * buf)461 int EBC_Provider_Generate_OrderId(AB_PROVIDER *pro, GWEN_BUFFER *buf)
462 {
463 uint32_t id;
464 char rbuf[4];
465 char c;
466 uint32_t j;
467
468 GWEN_Buffer_AllocRoom(buf, 4);
469 id=AB_Banking_GetNamedUniqueId(AB_Provider_GetBanking(pro), "orderId", 1);
470 if (id==0)
471 return GWEN_ERROR_IO;
472
473 rbuf[3]=id%36;
474 j=id/36;
475 rbuf[2]=j%36;
476 j/=36;
477 rbuf[1]=j%36;
478 j/=36;
479 rbuf[0]=j%26;
480
481 c=rbuf[0];
482 c+='A';
483 GWEN_Buffer_AppendByte(buf, c);
484
485 c=rbuf[1];
486 if (c<10)
487 c+='0';
488 else
489 c+='A'-10;
490 GWEN_Buffer_AppendByte(buf, c);
491
492 c=rbuf[2];
493 if (c<10)
494 c+='0';
495 else
496 c+='A'-10;
497 GWEN_Buffer_AppendByte(buf, c);
498
499 c=rbuf[3];
500 if (c<10)
501 c+='0';
502 else
503 c+='A'-10;
504 GWEN_Buffer_AppendByte(buf, c);
505
506 return 0;
507 }
508
509
510
EBC_Provider_ResultCodeToLogLevel(GWEN_UNUSED AB_PROVIDER * pro,const char * s)511 GWEN_LOGGER_LEVEL EBC_Provider_ResultCodeToLogLevel(GWEN_UNUSED AB_PROVIDER *pro,
512 const char *s)
513 {
514 if (strlen(s)!=6) {
515 DBG_ERROR(AQEBICS_LOGDOMAIN, "Invalid error code [%s]", s);
516 return GWEN_LoggerLevel_Error;
517 }
518 else {
519 uint8_t c;
520 GWEN_LOGGER_LEVEL lev;
521
522 c=s[1]-'0';
523 switch (c) {
524 case 0:
525 lev=GWEN_LoggerLevel_Info;
526 break;
527 case 1:
528 lev=GWEN_LoggerLevel_Notice;
529 break;
530 case 3:
531 lev=GWEN_LoggerLevel_Warning;
532 break;
533 case 6:
534 case 9:
535 default:
536 lev=GWEN_LoggerLevel_Error;
537 break;
538 }
539
540 return lev;
541 }
542 }
543
544
545
EBC_Provider_TechnicalCodeToString(const char * s)546 const char *EBC_Provider_TechnicalCodeToString(const char *s)
547 {
548 unsigned int code;
549
550 if (sscanf(s, "%u", &code)!=1)
551 return NULL;
552
553 switch (code) {
554 case 0 :
555 return I18N("Ok");
556 case 11000:
557 return I18N("Download postproces done");
558 case 11001:
559 return I18N("Download postproces skipped");
560 case 11101:
561 return I18N("TX segment number underrun");
562 case 31001:
563 return I18N("Order params ignored");
564 case 61001:
565 return I18N("Authentication failed");
566 case 61002:
567 return I18N("Invalid request");
568 case 61099:
569 return I18N("Internal error");
570 case 61101:
571 return I18N("TX recovery sync");
572 case 91002:
573 return I18N("Invalid user or invalid user state");
574 case 91003:
575 return I18N("User unknown");
576 case 91004:
577 return I18N("Invalid user state");
578 case 91005:
579 return I18N("Invalid order type");
580 case 91006:
581 return I18N("Unsupported order type");
582 case 91007:
583 return I18N("Distributed signature authorisation failed");
584 case 91008:
585 return I18N("Bank pubkey update required");
586 case 91009:
587 return I18N("Segment size exceeded");
588 case 91010:
589 return I18N("Invalid XML");
590 case 91101:
591 return I18N("TX unknown transaction id");
592 case 91102:
593 return I18N("TX abort");
594 case 91103:
595 return I18N("TX message replay");
596 case 91104:
597 return I18N("TX segment number exceeded");
598 case 91112:
599 return I18N("Invalid order params");
600 case 91113:
601 return I18N("Invalid request content");
602 case 91117:
603 return I18N("Max order data size exceeded");
604 case 91118:
605 return I18N("Max segments exceeded");
606 case 91119:
607 return I18N("Max transactions exceeded");
608 case 91120:
609 return I18N("Partner id mismatch");
610 case 91121:
611 return I18N("Incompatible order attribute");
612 default:
613 return NULL;
614 }
615 }
616
617
618
EBC_Provider_BankCodeToString(const char * s)619 const char *EBC_Provider_BankCodeToString(const char *s)
620 {
621 unsigned int code;
622
623 if (sscanf(s, "%u", &code)!=1)
624 return NULL;
625
626 switch (code) {
627 case 0 :
628 return I18N("Ok");
629 case 11301:
630 return I18N("No online checks");
631 case 91001:
632 return I18N("Download signed only");
633 case 91002:
634 return I18N("Download unsigned only");
635 case 90003:
636 return I18N("Authorisation failed");
637 case 90004:
638 return I18N("Invalid order data format");
639 case 90005:
640 return I18N("No download data available");
641 case 90006:
642 return I18N("Unsupported request for order instance");
643 case 91105:
644 return I18N("Recovery not supported");
645 case 91111:
646 return I18N("Invalid signature file format");
647 case 91114:
648 return I18N("Order id unknown");
649 case 91115:
650 return I18N("Order id already exists");
651 case 91116:
652 return I18N("Processing error");
653 case 91201:
654 return I18N("Keymgmt unsupported version of signature");
655 case 91202:
656 return I18N("Keymgmt unsupported version of authentication");
657 case 91203:
658 return I18N("Keymgmt unsupported version of encryption");
659 case 91204:
660 return I18N("Keymgmt keylength error in signature");
661 case 91205:
662 return I18N("Keymgmt keylength error in authentication");
663 case 91206:
664 return I18N("Keymgmt keylength error in encryption");
665 case 91207:
666 return I18N("Keymgmt no X509 support");
667 case 91301:
668 return I18N("Signature verification failed");
669 case 91302:
670 return I18N("Account authorisation failed");
671 case 91303:
672 return I18N("Amount check failed");
673 case 91304:
674 return I18N("Signer unknown");
675 case 91305:
676 return I18N("Invalid signer state");
677 case 91306:
678 return I18N("Duplicate signature");
679 default:
680 return NULL;
681 }
682 }
683
684
685
EBC_Provider_LogRequestResults(AB_PROVIDER * pro,EB_MSG * mRsp,GWEN_BUFFER * logbuf)686 void EBC_Provider_LogRequestResults(AB_PROVIDER *pro,
687 EB_MSG *mRsp,
688 GWEN_BUFFER *logbuf)
689 {
690 const char *tcode;
691 const char *bcode;
692 const char *s;
693 GWEN_BUFFER *tbuf;
694
695 tcode=EB_Msg_GetCharValue(mRsp, "header/mutable/ReturnCode", NULL);
696 bcode=EB_Msg_GetCharValue(mRsp, "body/ReturnCode", NULL);
697
698 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
699 if (tcode) {
700 GWEN_Buffer_AppendString(tbuf, I18N("EBICS (Technical Code):"));
701 GWEN_Buffer_AppendString(tbuf, " ");
702 GWEN_Buffer_AppendString(tbuf, tcode);
703 s=EBC_Provider_TechnicalCodeToString(tcode);
704 if (s) {
705 GWEN_Buffer_AppendString(tbuf, " [");
706 GWEN_Buffer_AppendString(tbuf, s);
707 GWEN_Buffer_AppendString(tbuf, "]");
708 }
709 if (logbuf) {
710 GWEN_Buffer_AppendString(logbuf, "\t");
711 GWEN_Buffer_AppendBuffer(logbuf, tbuf);
712 }
713 GWEN_Gui_ProgressLog(0,
714 EBC_Provider_ResultCodeToLogLevel(pro, tcode),
715 GWEN_Buffer_GetStart(tbuf));
716 DBG_INFO(AQEBICS_LOGDOMAIN, "%s", GWEN_Buffer_GetStart(tbuf));
717 GWEN_Buffer_Reset(tbuf);
718 }
719
720 s=EB_Msg_GetCharValue(mRsp, "header/mutable/ReportText", NULL);
721 if (s) {
722 GWEN_Buffer_AppendString(tbuf, I18N("EBICS (Technical Report):"));
723 GWEN_Buffer_AppendString(tbuf, " ");
724 GWEN_Buffer_AppendString(tbuf, s);
725 if (logbuf) {
726 GWEN_Buffer_AppendString(logbuf, "\t");
727 GWEN_Buffer_AppendBuffer(logbuf, tbuf);
728 }
729 GWEN_Gui_ProgressLog(0,
730 GWEN_LoggerLevel_Notice,
731 GWEN_Buffer_GetStart(tbuf));
732 DBG_INFO(AQEBICS_LOGDOMAIN, "%s", GWEN_Buffer_GetStart(tbuf));
733 GWEN_Buffer_Reset(tbuf);
734 }
735
736 s=EB_Msg_GetCharValue(mRsp, "body/ReturnCode", NULL);
737 if (bcode) {
738 GWEN_Buffer_AppendString(tbuf, I18N("EBICS (Bank Code):"));
739 GWEN_Buffer_AppendString(tbuf, " ");
740 GWEN_Buffer_AppendString(tbuf, bcode);
741
742 s=EBC_Provider_BankCodeToString(bcode);
743 if (s) {
744 GWEN_Buffer_AppendString(tbuf, " [");
745 GWEN_Buffer_AppendString(tbuf, s);
746 GWEN_Buffer_AppendString(tbuf, "]");
747 }
748
749 if (logbuf) {
750 GWEN_Buffer_AppendString(logbuf, "\t");
751 GWEN_Buffer_AppendBuffer(logbuf, tbuf);
752 }
753
754 GWEN_Gui_ProgressLog(0,
755 EBC_Provider_ResultCodeToLogLevel(pro, bcode),
756 GWEN_Buffer_GetStart(tbuf));
757 DBG_INFO(AQEBICS_LOGDOMAIN, "%s", GWEN_Buffer_GetStart(tbuf));
758 GWEN_Buffer_Reset(tbuf);
759 }
760
761 GWEN_Buffer_free(tbuf);
762 }
763
764
765
EBC_Provider_AddBankPubKeyDigests(AB_PROVIDER * pro,AB_USER * u,xmlNodePtr node)766 int EBC_Provider_AddBankPubKeyDigests(AB_PROVIDER *pro, AB_USER *u, xmlNodePtr node)
767 {
768 EBC_PROVIDER *dp;
769 int rv;
770 GWEN_CRYPT_TOKEN *ct;
771 const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
772 const GWEN_CRYPT_TOKEN_KEYINFO *ki;
773 uint32_t keyId;
774 GWEN_BUFFER *hbuf;
775 xmlNodePtr nodeX = NULL;
776 const char *s;
777
778 assert(pro);
779 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
780 assert(dp);
781
782 /* get crypt token and context */
783 rv=EBC_Provider_MountToken(pro, u, &ct, &ctx);
784 if (rv<0) {
785 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
786 return rv;
787 }
788
789 /* get key id for server auth key */
790 keyId=GWEN_Crypt_Token_Context_GetAuthVerifyKeyId(ctx);
791 ki=GWEN_Crypt_Token_GetKeyInfo(ct,
792 keyId,
793 0xffffffff,
794 0);
795 if (ki==NULL) {
796 DBG_INFO(AQEBICS_LOGDOMAIN,
797 "Keyinfo %04x not found on crypt token [%s:%s]",
798 keyId,
799 GWEN_Crypt_Token_GetTypeName(ct),
800 GWEN_Crypt_Token_GetTokenName(ct));
801 GWEN_Crypt_Token_Close(ct, 0, 0);
802 return GWEN_ERROR_NOT_FOUND;
803 }
804
805 s=EBC_User_GetAuthVersion(u);
806 DBG_ERROR(0, "Auth Version: %s\n", s);
807 if (!(s && *s))
808 s="X001";
809 if (strcasecmp(s, "X001")==0) {
810 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
811 rv=EB_Key_Info_BuildHashSha1(ki, hbuf, 1);
812 if (rv<0) {
813 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
814 GWEN_Buffer_free(hbuf);
815 GWEN_Crypt_Token_Close(ct, 0, 0);
816 return rv;
817 }
818 nodeX=xmlNewTextChild(node, NULL,
819 BAD_CAST "Authentication",
820 BAD_CAST GWEN_Buffer_GetStart(hbuf));
821 GWEN_Buffer_free(hbuf);
822 assert(nodeX);
823 xmlNewProp(nodeX,
824 BAD_CAST "Version",
825 BAD_CAST "X001");
826 xmlNewProp(nodeX,
827 BAD_CAST "Algorithm",
828 BAD_CAST "http://www.w3.org/2000/09/xmldsig#sha1");
829 }
830 else if (strcasecmp(s, "X002")==0) {
831 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
832 rv=EB_Key_Info_BuildHashSha256(ki, hbuf, 1);
833 if (rv<0) {
834 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
835 GWEN_Buffer_free(hbuf);
836 GWEN_Crypt_Token_Close(ct, 0, 0);
837 return rv;
838 }
839 nodeX=xmlNewTextChild(node, NULL,
840 BAD_CAST "Authentication",
841 BAD_CAST GWEN_Buffer_GetStart(hbuf));
842 GWEN_Buffer_free(hbuf);
843 assert(nodeX);
844 xmlNewProp(nodeX,
845 BAD_CAST "Version",
846 BAD_CAST "X002");
847 xmlNewProp(nodeX,
848 BAD_CAST "Algorithm",
849 BAD_CAST "http://www.w3.org/2001/04/xmlenc#sha256");
850 }
851 else {
852 DBG_ERROR(AQEBICS_LOGDOMAIN, "Unsupported auth version [%s]", s);
853 GWEN_Crypt_Token_Close(ct, 0, 0);
854 return GWEN_ERROR_INTERNAL;
855 }
856
857 /* get key id for server crypt key */
858 keyId=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx);
859 ki=GWEN_Crypt_Token_GetKeyInfo(ct,
860 keyId,
861 0xffffffff,
862 0);
863 if (ki==NULL) {
864 DBG_INFO(AQEBICS_LOGDOMAIN,
865 "Keyinfo %04x not found on crypt token [%s:%s]",
866 keyId,
867 GWEN_Crypt_Token_GetTypeName(ct),
868 GWEN_Crypt_Token_GetTokenName(ct));
869 GWEN_Crypt_Token_Close(ct, 0, 0);
870 return GWEN_ERROR_NOT_FOUND;
871 }
872
873 s=EBC_User_GetCryptVersion(u);
874 if (!(s && *s))
875 s="E001";
876 if (strcasecmp(s, "E001")==0) {
877 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
878 rv=EB_Key_Info_BuildHashSha1(ki, hbuf, 1);
879 if (rv<0) {
880 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
881 GWEN_Buffer_free(hbuf);
882 GWEN_Crypt_Token_Close(ct, 0, 0);
883 return rv;
884 }
885 nodeX=xmlNewTextChild(node, NULL,
886 BAD_CAST "Encryption",
887 BAD_CAST GWEN_Buffer_GetStart(hbuf));
888 GWEN_Buffer_free(hbuf);
889 assert(nodeX);
890 xmlNewProp(nodeX,
891 BAD_CAST "Version",
892 BAD_CAST "E001");
893 xmlNewProp(nodeX,
894 BAD_CAST "Algorithm",
895 BAD_CAST "http://www.w3.org/2000/09/xmldsig#sha1");
896 }
897 else if (strcasecmp(s, "E002")==0) {
898 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
899 rv=EB_Key_Info_BuildHashSha256(ki, hbuf, 1);
900 if (rv<0) {
901 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
902 GWEN_Buffer_free(hbuf);
903 GWEN_Crypt_Token_Close(ct, 0, 0);
904 return rv;
905 }
906 nodeX=xmlNewTextChild(node, NULL,
907 BAD_CAST "Encryption",
908 BAD_CAST GWEN_Buffer_GetStart(hbuf));
909 GWEN_Buffer_free(hbuf);
910 assert(nodeX);
911 xmlNewProp(nodeX,
912 BAD_CAST "Version",
913 BAD_CAST "E002");
914 xmlNewProp(nodeX,
915 BAD_CAST "Algorithm",
916 BAD_CAST "http://www.w3.org/2001/04/xmlenc#sha256");
917 }
918 else {
919 DBG_ERROR(AQEBICS_LOGDOMAIN, "Unsupported crypt version [%s]", s);
920 GWEN_Crypt_Token_Close(ct, 0, 0);
921 return GWEN_ERROR_INTERNAL;
922 }
923
924 return 0;
925 }
926
927
928
EBC_Provider_FillDataEncryptionInfoNode(AB_PROVIDER * pro,AB_USER * u,const GWEN_CRYPT_KEY * skey,xmlNodePtr node)929 int EBC_Provider_FillDataEncryptionInfoNode(AB_PROVIDER *pro, AB_USER *u,
930 const GWEN_CRYPT_KEY *skey,
931 xmlNodePtr node)
932 {
933 EBC_PROVIDER *dp;
934 int rv;
935 GWEN_CRYPT_TOKEN *ct;
936 const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
937 const GWEN_CRYPT_TOKEN_KEYINFO *ki;
938 uint32_t keyId;
939 GWEN_BUFFER *hbuf;
940 xmlNodePtr nodeX = NULL;
941 const char *s;
942
943 assert(pro);
944 dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
945 assert(dp);
946
947 /* get crypt token and context */
948 rv=EBC_Provider_MountToken(pro, u, &ct, &ctx);
949 if (rv<0) {
950 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
951 return rv;
952 }
953
954 /* get key id for server crypt key */
955 keyId=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx);
956 ki=GWEN_Crypt_Token_GetKeyInfo(ct,
957 keyId,
958 0xffffffff,
959 0);
960 if (ki==NULL) {
961 DBG_INFO(AQEBICS_LOGDOMAIN,
962 "Keyinfo %04x not found on crypt token [%s:%s]",
963 keyId,
964 GWEN_Crypt_Token_GetTypeName(ct),
965 GWEN_Crypt_Token_GetTokenName(ct));
966 GWEN_Crypt_Token_Close(ct, 0, 0);
967 return GWEN_ERROR_NOT_FOUND;
968 }
969
970 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
971
972 s=EBC_User_GetCryptVersion(u);
973 if (!(s && *s))
974 s="E001";
975 if (strcasecmp(s, "E001")==0) {
976 rv=EB_Key_Info_BuildHashSha1(ki, hbuf, 1);
977 if (rv<0) {
978 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
979 GWEN_Buffer_free(hbuf);
980 GWEN_Crypt_Token_Close(ct, 0, 0);
981 return rv;
982 }
983 nodeX=xmlNewTextChild(node, NULL,
984 BAD_CAST "EncryptionPubKeyDigest",
985 BAD_CAST GWEN_Buffer_GetStart(hbuf));
986 GWEN_Buffer_free(hbuf);
987 assert(nodeX);
988
989 xmlNewProp(nodeX,
990 BAD_CAST "Version",
991 BAD_CAST "E001");
992 xmlNewProp(nodeX,
993 BAD_CAST "Algorithm",
994 BAD_CAST "http://www.w3.org/2000/09/xmldsig#sha1");
995 }
996 else if (strcasecmp(s, "E002")==0) {
997 rv=EB_Key_Info_BuildHashSha256(ki, hbuf, 1);
998 if (rv<0) {
999 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1000 GWEN_Buffer_free(hbuf);
1001 GWEN_Crypt_Token_Close(ct, 0, 0);
1002 return rv;
1003 }
1004 nodeX=xmlNewTextChild(node, NULL,
1005 BAD_CAST "EncryptionPubKeyDigest",
1006 BAD_CAST GWEN_Buffer_GetStart(hbuf));
1007 GWEN_Buffer_free(hbuf);
1008 assert(nodeX);
1009
1010 xmlNewProp(nodeX,
1011 BAD_CAST "Version",
1012 BAD_CAST "E002");
1013 xmlNewProp(nodeX,
1014 BAD_CAST "Algorithm",
1015 BAD_CAST "http://www.w3.org/2001/04/xmlenc#sha256");
1016 }
1017
1018
1019 /* add encrypted transactio key */
1020 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
1021 rv=EBC_Provider_EncryptKey(pro, u, skey, hbuf);
1022 if (rv<0) {
1023 DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1024 GWEN_Buffer_free(hbuf);
1025 GWEN_Crypt_Token_Close(ct, 0, 0);
1026 return rv;
1027 }
1028
1029 nodeX=xmlNewTextChild(node, NULL,
1030 BAD_CAST "TransactionKey",
1031 BAD_CAST GWEN_Buffer_GetStart(hbuf));
1032 GWEN_Buffer_free(hbuf);
1033 assert(nodeX);
1034
1035 return 0;
1036 }
1037
1038
1039
EBC_Provider_GetCert(AB_PROVIDER * pro,AB_USER * u)1040 int EBC_Provider_GetCert(AB_PROVIDER *pro, AB_USER *u)
1041 {
1042 GWEN_HTTP_SESSION *sess;
1043 int rv;
1044 AB_BANKING *ab;
1045
1046 sess=EBC_Dialog_new(pro, u);
1047
1048 ab=AB_Provider_GetBanking(pro);
1049 assert(ab);
1050
1051 /* create and open session */
1052 sess=EBC_Dialog_new(pro, u);
1053 rv=GWEN_HttpSession_Init(sess);
1054 if (rv<0) {
1055 DBG_INFO(AQEBICS_LOGDOMAIN, "Could not open session");
1056 GWEN_HttpSession_free(sess);
1057 return rv;
1058 }
1059
1060 /* try to connect */
1061 rv=GWEN_HttpSession_ConnectionTest(sess);
1062 if (rv<0) {
1063 DBG_INFO(AQEBICS_LOGDOMAIN, "Could not connect to server");
1064 GWEN_HttpSession_free(sess);
1065 return rv;
1066 }
1067
1068 GWEN_HttpSession_Fini(sess);
1069 GWEN_HttpSession_free(sess);
1070
1071 return 0;
1072 }
1073
1074
1075
EBC_Provider_DecodeAndDecryptData(AB_PROVIDER * pro,AB_USER * u,GWEN_CRYPT_KEY * skey,const char * sEncryptedData,GWEN_BUFFER * targetBuffer)1076 int EBC_Provider_DecodeAndDecryptData(AB_PROVIDER *pro,
1077 AB_USER *u,
1078 GWEN_CRYPT_KEY *skey,
1079 const char *sEncryptedData,
1080 GWEN_BUFFER *targetBuffer)
1081 {
1082 GWEN_BUFFER *buf1;
1083 int rv;
1084
1085 /* BASE64-decode receiced data */
1086 buf1=GWEN_Buffer_new(0, strlen(sEncryptedData), 0, 1);
1087 rv=GWEN_Base64_Decode((const uint8_t *)sEncryptedData, 0, buf1);
1088 if (rv<0) {
1089 DBG_INFO(AQEBICS_LOGDOMAIN, "Could not decode OrderData (%d)", rv);
1090 GWEN_Buffer_free(buf1);
1091 return rv;
1092 }
1093
1094 /* decrypt/unzip data */
1095 rv=EBC_Provider_DecryptData(pro, u, skey,
1096 (const uint8_t *)GWEN_Buffer_GetStart(buf1),
1097 GWEN_Buffer_GetUsedBytes(buf1),
1098 targetBuffer);
1099 if (rv<0) {
1100 DBG_INFO(AQEBICS_LOGDOMAIN, "Could not decrypt OrderData (%d)", rv);
1101 GWEN_Buffer_free(buf1);
1102 return rv;
1103 }
1104 GWEN_Buffer_free(buf1);
1105
1106 /*DBG_ERROR(0, "Got this data:");
1107 GWEN_Buffer_Dump(targetBuffer, stderr, 2);*/
1108
1109 return 0;
1110 }
1111
1112
1113
1114 #include "provider_sendcmd.c"
1115 #include "provider_accspec.c"
1116
1117 #include "p_sign_x001.c"
1118 #include "p_sign_x002.c"
1119 #include "p_sign.c"
1120 #include "p_decipher.c"
1121 #include "p_encipher_e001.c"
1122 #include "p_encipher_e002.c"
1123 #include "p_encipher.c"
1124 #include "p_eu_a004.c"
1125 #include "p_eu_a005.c"
1126 #include "p_eu.c"
1127 #include "p_tools.c"
1128
1129