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