1 
2 
3 #include "aqebics/client/user_l.h"
4 #include "aqebics/msg/keys.h"
5 
6 #include "aqebics/requests/r_hkd_htd_l.h"
7 #include "aqebics/requests/r_download_l.h"
8 #include "aqebics/requests/r_upload_l.h"
9 #include "aqebics/requests/r_ini_l.h"
10 #include "aqebics/requests/r_hia_l.h"
11 #include "aqebics/requests/r_pub_l.h"
12 #include "aqebics/requests/r_hpb_l.h"
13 #include "aqebics/requests/r_hpd_l.h"
14 
15 #include <gwenhywfar/url.h>
16 
17 
18 
EBC_Provider_Send_INI(AB_PROVIDER * pro,AB_USER * u,int doLock)19 int EBC_Provider_Send_INI(AB_PROVIDER *pro, AB_USER *u, int doLock)
20 {
21   EBC_PROVIDER *dp;
22   GWEN_HTTP_SESSION *sess;
23   int rv;
24   EBC_USER_STATUS ust;
25 
26   assert(pro);
27   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
28   assert(dp);
29 
30   if (EBC_User_GetFlags(u) & EBC_USER_FLAGS_INI) {
31     DBG_ERROR(AQEBICS_LOGDOMAIN, "INI already sent to the server");
32     return GWEN_ERROR_INVALID;
33   }
34 
35   ust=EBC_User_GetStatus(u);
36   if (ust!=EBC_UserStatus_New &&
37       ust!=EBC_UserStatus_Init1 &&
38       ust!=EBC_UserStatus_Disabled) {
39     DBG_ERROR(AQEBICS_LOGDOMAIN,
40               "Invalid status \"%s\" of user \"%s\"",
41               EBC_User_Status_toString(ust),
42               AB_User_GetUserId(u));
43     return GWEN_ERROR_INVALID;
44   }
45 
46   /* create and open session */
47   sess=EBC_Dialog_new(pro, u);
48   rv=GWEN_HttpSession_Init(sess);
49   if (rv<0) {
50     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
51     GWEN_HttpSession_free(sess);
52     return rv;
53   }
54 
55   /* lock user */
56   if (doLock) {
57     rv=AB_Provider_BeginExclUseUser(pro, u);
58     if (rv<0) {
59       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
60       GWEN_HttpSession_free(sess);
61       return rv;
62     }
63   }
64 
65   /* exchange request and response */
66   rv=EBC_Provider_XchgIniRequest(pro, sess, u);
67   if (rv) {
68     DBG_ERROR(AQEBICS_LOGDOMAIN,
69               "Error exchanging INI request (%d)", rv);
70     if (doLock)
71       AB_Provider_EndExclUseUser(pro, u, 1);
72     GWEN_HttpSession_free(sess);
73     return rv;
74   }
75 
76   /* unlock user */
77   if (doLock) {
78     rv=AB_Provider_EndExclUseUser(pro, u, 0);
79     if (rv<0) {
80       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
81       AB_Provider_EndExclUseUser(pro, u, 1);
82       GWEN_HttpSession_free(sess);
83       return rv;
84     }
85   }
86 
87   /* close and destroy session */
88   GWEN_HttpSession_Fini(sess);
89   GWEN_HttpSession_free(sess);
90 
91   return rv;
92 }
93 
94 
95 
EBC_Provider_Send_HIA(AB_PROVIDER * pro,AB_USER * u,int doLock)96 int EBC_Provider_Send_HIA(AB_PROVIDER *pro, AB_USER *u, int doLock)
97 {
98   EBC_PROVIDER *dp;
99   GWEN_HTTP_SESSION *sess;
100   int rv;
101   EBC_USER_STATUS ust;
102 
103   assert(pro);
104   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
105   assert(dp);
106 
107   if (EBC_User_GetFlags(u) & EBC_USER_FLAGS_HIA) {
108     DBG_ERROR(AQEBICS_LOGDOMAIN, "HIA already sent to the server");
109     return GWEN_ERROR_INVALID;
110   }
111 
112   ust=EBC_User_GetStatus(u);
113   if (ust!=EBC_UserStatus_New &&
114       ust!=EBC_UserStatus_Init1 &&
115       ust!=EBC_UserStatus_Disabled) {
116     DBG_ERROR(AQEBICS_LOGDOMAIN,
117               "Invalid status \"%s\" of user \"%s\"",
118               EBC_User_Status_toString(ust),
119               AB_User_GetUserId(u));
120     return GWEN_ERROR_INVALID;
121   }
122 
123   /* create and open session */
124   sess=EBC_Dialog_new(pro, u);
125   rv=GWEN_HttpSession_Init(sess);
126   if (rv<0) {
127     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
128     GWEN_HttpSession_free(sess);
129     return rv;
130   }
131 
132   /* lock user */
133   if (doLock) {
134     rv=AB_Provider_BeginExclUseUser(pro, u);
135     if (rv<0) {
136       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
137       GWEN_HttpSession_free(sess);
138       return rv;
139     }
140   }
141 
142   /* exchange request and response */
143   rv=EBC_Provider_XchgHiaRequest(pro, sess, u);
144   if (rv) {
145     DBG_ERROR(AQEBICS_LOGDOMAIN,
146               "Error exchanging HIA request (%d)", rv);
147     if (doLock)
148       AB_Provider_EndExclUseUser(pro, u, 1);
149     GWEN_HttpSession_free(sess);
150     return rv;
151   }
152 
153   /* unlock user */
154   if (doLock) {
155     rv=AB_Provider_EndExclUseUser(pro, u, 0);
156     if (rv<0) {
157       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
158       AB_Provider_EndExclUseUser(pro, u, 1);
159       GWEN_HttpSession_free(sess);
160       return rv;
161     }
162   }
163 
164   /* close and destroy session */
165   GWEN_HttpSession_Fini(sess);
166   GWEN_HttpSession_free(sess);
167 
168   return rv;
169 }
170 
171 
172 
EBC_Provider_Send_HPB(AB_PROVIDER * pro,AB_USER * u,int doLock)173 int EBC_Provider_Send_HPB(AB_PROVIDER *pro, AB_USER *u, int doLock)
174 {
175   EBC_PROVIDER *dp;
176   GWEN_HTTP_SESSION *sess;
177   int rv;
178   EBC_USER_STATUS ust;
179 
180   assert(pro);
181   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
182   assert(dp);
183 
184   ust=EBC_User_GetStatus(u);
185   if (ust!=EBC_UserStatus_Init2 &&
186       ust!=EBC_UserStatus_Enabled) {
187     DBG_ERROR(AQEBICS_LOGDOMAIN,
188               "Invalid status \"%s\" of user \"%s\"",
189               EBC_User_Status_toString(ust),
190               AB_User_GetUserId(u));
191     return GWEN_ERROR_INVALID;
192   }
193 
194   /* create and open session */
195   sess=EBC_Dialog_new(pro, u);
196   rv=GWEN_HttpSession_Init(sess);
197   if (rv<0) {
198     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
199     GWEN_HttpSession_free(sess);
200     return rv;
201   }
202 
203   /* lock user */
204   if (doLock) {
205     rv=AB_Provider_BeginExclUseUser(pro, u);
206     if (rv<0) {
207       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
208       GWEN_HttpSession_free(sess);
209       return rv;
210     }
211   }
212 
213   /* exchange request and response */
214   rv=EBC_Provider_XchgHpbRequest(pro, sess, u);
215   if (rv) {
216     DBG_ERROR(AQEBICS_LOGDOMAIN,
217               "Error exchanging HPB request (%d)", rv);
218     if (doLock)
219       AB_Provider_EndExclUseUser(pro, u, 1);
220     GWEN_HttpSession_free(sess);
221     return rv;
222   }
223 
224   /* unlock user */
225   if (doLock) {
226     rv=AB_Provider_EndExclUseUser(pro, u, 0);
227     if (rv<0) {
228       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
229       AB_Provider_EndExclUseUser(pro, u, 1);
230       GWEN_HttpSession_free(sess);
231       return rv;
232     }
233   }
234 
235   /* close and destroy session */
236   GWEN_HttpSession_Fini(sess);
237   GWEN_HttpSession_free(sess);
238 
239   return rv;
240 }
241 
242 
243 
EBC_Provider_Send_HPD(AB_PROVIDER * pro,AB_USER * u,int doLock)244 int EBC_Provider_Send_HPD(AB_PROVIDER *pro, AB_USER *u, int doLock)
245 {
246   EBC_PROVIDER *dp;
247   GWEN_HTTP_SESSION *sess;
248   int rv;
249   EBC_USER_STATUS ust;
250 
251   assert(pro);
252   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
253   assert(dp);
254 
255   ust=EBC_User_GetStatus(u);
256   if (ust!=EBC_UserStatus_Enabled) {
257     DBG_ERROR(AQEBICS_LOGDOMAIN,
258               "Invalid status \"%s\" of user \"%s\"",
259               EBC_User_Status_toString(ust),
260               AB_User_GetUserId(u));
261     return GWEN_ERROR_INVALID;
262   }
263 
264   /* create and open session */
265   sess=EBC_Dialog_new(pro, u);
266   rv=GWEN_HttpSession_Init(sess);
267   if (rv<0) {
268     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
269     GWEN_HttpSession_free(sess);
270     return rv;
271   }
272 
273   /* lock user */
274   if (doLock) {
275     rv=AB_Provider_BeginExclUseUser(pro, u);
276     if (rv<0) {
277       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
278       GWEN_HttpSession_free(sess);
279       return rv;
280     }
281   }
282 
283   /* exchange request and response */
284   rv=EBC_Provider_XchgHpdRequest(pro, sess, u);
285   if (rv) {
286     DBG_ERROR(AQEBICS_LOGDOMAIN,
287               "Error exchanging HPD request (%d)", rv);
288     if (doLock)
289       AB_Provider_EndExclUseUser(pro, u, 1);
290     GWEN_HttpSession_free(sess);
291     return rv;
292   }
293 
294   /* unlock user */
295   if (doLock) {
296     rv=AB_Provider_EndExclUseUser(pro, u, 0);
297     if (rv<0) {
298       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
299       AB_Provider_EndExclUseUser(pro, u, 1);
300       GWEN_HttpSession_free(sess);
301       return rv;
302     }
303   }
304 
305   /* close and destroy session */
306   GWEN_HttpSession_Fini(sess);
307   GWEN_HttpSession_free(sess);
308 
309   return rv;
310 }
311 
312 
313 
EBC_Provider_Send_HKD(AB_PROVIDER * pro,AB_USER * u,int doLock)314 int EBC_Provider_Send_HKD(AB_PROVIDER *pro, AB_USER *u, int doLock)
315 {
316   EBC_PROVIDER *dp;
317   GWEN_HTTP_SESSION *sess;
318   int rv;
319   EBC_USER_STATUS ust;
320 
321   assert(pro);
322   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
323   assert(dp);
324 
325   ust=EBC_User_GetStatus(u);
326   if (ust!=EBC_UserStatus_Enabled) {
327     DBG_ERROR(AQEBICS_LOGDOMAIN,
328               "Invalid status \"%s\" of user \"%s\"",
329               EBC_User_Status_toString(ust),
330               AB_User_GetUserId(u));
331     return GWEN_ERROR_INVALID;
332   }
333 
334   /* create and open session */
335   sess=EBC_Dialog_new(pro, u);
336   rv=GWEN_HttpSession_Init(sess);
337   if (rv<0) {
338     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
339     GWEN_HttpSession_free(sess);
340     return rv;
341   }
342 
343   /* lock user */
344   if (doLock) {
345     rv=AB_Provider_BeginExclUseUser(pro, u);
346     if (rv<0) {
347       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
348       GWEN_HttpSession_free(sess);
349       return rv;
350     }
351   }
352 
353   /* exchange request and response */
354   rv=EBC_Provider_XchgHkdRequest(pro, sess, u);
355   if (rv) {
356     DBG_ERROR(AQEBICS_LOGDOMAIN,
357               "Error exchanging HKD request (%d)", rv);
358     if (doLock)
359       AB_Provider_EndExclUseUser(pro, u, 1);
360     GWEN_HttpSession_free(sess);
361     return rv;
362   }
363 
364   /* unlock user */
365   if (doLock) {
366     rv=AB_Provider_EndExclUseUser(pro, u, 0);
367     if (rv<0) {
368       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
369       AB_Provider_EndExclUseUser(pro, u, 1);
370       GWEN_HttpSession_free(sess);
371       return rv;
372     }
373   }
374 
375   /* close and destroy session */
376   GWEN_HttpSession_Fini(sess);
377   GWEN_HttpSession_free(sess);
378 
379   return rv;
380 }
381 
382 
383 
EBC_Provider_Send_HTD(AB_PROVIDER * pro,AB_USER * u,int doLock)384 int EBC_Provider_Send_HTD(AB_PROVIDER *pro, AB_USER *u, int doLock)
385 {
386   EBC_PROVIDER *dp;
387   GWEN_HTTP_SESSION *sess;
388   int rv;
389   EBC_USER_STATUS ust;
390 
391   assert(pro);
392   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
393   assert(dp);
394 
395   ust=EBC_User_GetStatus(u);
396   if (ust!=EBC_UserStatus_Enabled) {
397     DBG_ERROR(AQEBICS_LOGDOMAIN,
398               "Invalid status \"%s\" of user \"%s\"",
399               EBC_User_Status_toString(ust),
400               AB_User_GetUserId(u));
401     return GWEN_ERROR_INVALID;
402   }
403 
404   /* create and open session */
405   sess=EBC_Dialog_new(pro, u);
406   rv=GWEN_HttpSession_Init(sess);
407   if (rv<0) {
408     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
409     GWEN_HttpSession_free(sess);
410     return rv;
411   }
412 
413   /* lock user */
414   if (doLock) {
415     rv=AB_Provider_BeginExclUseUser(pro, u);
416     if (rv<0) {
417       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
418       GWEN_HttpSession_free(sess);
419       return rv;
420     }
421   }
422 
423   /* exchange request and response */
424   rv=EBC_Provider_XchgHtdRequest(pro, sess, u);
425   if (rv) {
426     DBG_ERROR(AQEBICS_LOGDOMAIN,
427               "Error exchanging HTD request (%d)", rv);
428     if (doLock)
429       AB_Provider_EndExclUseUser(pro, u, 1);
430     GWEN_HttpSession_free(sess);
431     return rv;
432   }
433 
434   /* unlock user */
435   if (doLock) {
436     rv=AB_Provider_EndExclUseUser(pro, u, 0);
437     if (rv<0) {
438       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
439       AB_Provider_EndExclUseUser(pro, u, 1);
440       GWEN_HttpSession_free(sess);
441       return rv;
442     }
443   }
444 
445   /* close and destroy session */
446   GWEN_HttpSession_Fini(sess);
447   GWEN_HttpSession_free(sess);
448 
449   return rv;
450 }
451 
452 
453 
EBC_Provider_Send_PUB(AB_PROVIDER * pro,AB_USER * u,const char * signVersion,int doLock)454 int EBC_Provider_Send_PUB(AB_PROVIDER *pro, AB_USER *u, const char *signVersion, int doLock)
455 {
456   EBC_PROVIDER *dp;
457   GWEN_HTTP_SESSION *sess;
458   int rv;
459 
460   assert(pro);
461   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
462   assert(dp);
463 
464   /* create and open session */
465   sess=EBC_Dialog_new(pro, u);
466   rv=GWEN_HttpSession_Init(sess);
467   if (rv<0) {
468     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
469     GWEN_HttpSession_free(sess);
470     return rv;
471   }
472 
473   /* lock user */
474   if (doLock) {
475     rv=AB_Provider_BeginExclUseUser(pro, u);
476     if (rv<0) {
477       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
478       GWEN_HttpSession_free(sess);
479       return rv;
480     }
481   }
482 
483   /* exchange request and response */
484   rv=EBC_Provider_XchgPubRequest(pro, sess, u, signVersion);
485   if (rv) {
486     DBG_ERROR(AQEBICS_LOGDOMAIN,
487               "Error exchanging PUB request (%d)", rv);
488     if (doLock)
489       AB_Provider_EndExclUseUser(pro, u, 1);
490     GWEN_HttpSession_free(sess);
491     return rv;
492   }
493 
494   /* unlock user */
495   if (doLock) {
496     rv=AB_Provider_EndExclUseUser(pro, u, 0);
497     if (rv<0) {
498       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
499       AB_Provider_EndExclUseUser(pro, u, 1);
500       GWEN_HttpSession_free(sess);
501       return rv;
502     }
503   }
504 
505   /* close and destroy session */
506   GWEN_HttpSession_Fini(sess);
507   GWEN_HttpSession_free(sess);
508 
509   return rv;
510 }
511 
512 
513 
EBC_Provider_DownloadWithSession(AB_PROVIDER * pro,GWEN_HTTP_SESSION * sess,AB_USER * u,const char * rtype,GWEN_BUFFER * targetBuffer,int withReceipt,const GWEN_DATE * fromDate,const GWEN_DATE * toDate,int doLock)514 int EBC_Provider_DownloadWithSession(AB_PROVIDER *pro,
515                                      GWEN_HTTP_SESSION *sess,
516                                      AB_USER *u,
517                                      const char *rtype,
518                                      GWEN_BUFFER *targetBuffer,
519                                      int withReceipt,
520                                      const GWEN_DATE *fromDate,
521                                      const GWEN_DATE *toDate,
522                                      int doLock)
523 {
524   EBC_PROVIDER *dp;
525   int rv;
526   EBC_USER_STATUS ust;
527 
528   assert(pro);
529   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
530   assert(dp);
531 
532   ust=EBC_User_GetStatus(u);
533   if (ust!=EBC_UserStatus_Enabled) {
534     DBG_ERROR(AQEBICS_LOGDOMAIN,
535               "Invalid status \"%s\" of user \"%s\"",
536               EBC_User_Status_toString(ust),
537               AB_User_GetUserId(u));
538     return GWEN_ERROR_INVALID;
539   }
540 
541   /* lock user */
542   if (doLock) {
543     rv=AB_Provider_BeginExclUseUser(pro, u);
544     if (rv<0) {
545       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
546       return rv;
547     }
548   }
549 
550   /* exchange request and response */
551   rv=EBC_Provider_XchgDownloadRequest(pro, sess, u,
552                                       rtype, targetBuffer, withReceipt,
553                                       fromDate, toDate);
554   if (rv) {
555     DBG_ERROR(AQEBICS_LOGDOMAIN,
556               "Error exchanging download request (%d)", rv);
557     if (doLock)
558       AB_Provider_EndExclUseUser(pro, u, 1);
559     return rv;
560   }
561 
562   /* unlock user */
563   if (doLock) {
564     rv=AB_Provider_EndExclUseUser(pro, u, 0);
565     if (rv<0) {
566       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
567       AB_Provider_EndExclUseUser(pro, u, 1);
568       return rv;
569     }
570   }
571 
572   return rv;
573 }
574 
575 
576 
EBC_Provider_Download(AB_PROVIDER * pro,AB_USER * u,const char * rtype,GWEN_BUFFER * targetBuffer,int withReceipt,const GWEN_DATE * fromDate,const GWEN_DATE * toDate,int doLock)577 int EBC_Provider_Download(AB_PROVIDER *pro, AB_USER *u,
578                           const char *rtype,
579                           GWEN_BUFFER *targetBuffer,
580                           int withReceipt,
581                           const GWEN_DATE *fromDate,
582                           const GWEN_DATE *toDate,
583                           int doLock)
584 {
585   EBC_PROVIDER *dp;
586   GWEN_HTTP_SESSION *sess;
587   int rv;
588   EBC_USER_STATUS ust;
589 
590   assert(pro);
591   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
592   assert(dp);
593 
594   ust=EBC_User_GetStatus(u);
595   if (ust!=EBC_UserStatus_Enabled) {
596     DBG_ERROR(AQEBICS_LOGDOMAIN,
597               "Invalid status \"%s\" of user \"%s\"",
598               EBC_User_Status_toString(ust),
599               AB_User_GetUserId(u));
600     return GWEN_ERROR_INVALID;
601   }
602 
603   /* create and open session */
604   sess=EBC_Dialog_new(pro, u);
605   rv=GWEN_HttpSession_Init(sess);
606   if (rv<0) {
607     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
608     GWEN_HttpSession_free(sess);
609     return rv;
610   }
611 
612   rv=EBC_Provider_DownloadWithSession(pro, sess, u, rtype, targetBuffer, withReceipt, fromDate, toDate, doLock);
613   if (rv<0 || rv>=300) {
614     DBG_ERROR(AQEBICS_LOGDOMAIN, "here (%d)", rv);
615     GWEN_HttpSession_free(sess);
616     return rv;
617   }
618 
619   /* close and destroy session */
620   GWEN_HttpSession_Fini(sess);
621   GWEN_HttpSession_free(sess);
622 
623   return rv;
624 }
625 
626 
627 
EBC_Provider_DownloadIntoContext(AB_PROVIDER * pro,AB_USER * u,const char * rtype,int withReceipt,const GWEN_DATE * fromDate,const GWEN_DATE * toDate,const char * importerName,const char * profileName,AB_IMEXPORTER_CONTEXT * ctx,int doLock)628 int EBC_Provider_DownloadIntoContext(AB_PROVIDER *pro,
629                                      AB_USER *u,
630                                      const char *rtype,
631                                      int withReceipt,
632                                      const GWEN_DATE *fromDate,
633                                      const GWEN_DATE *toDate,
634                                      const char *importerName,
635                                      const char *profileName,
636                                      AB_IMEXPORTER_CONTEXT *ctx,
637                                      int doLock)
638 {
639   int rv;
640   GWEN_BUFFER *buf;
641 
642   buf=GWEN_Buffer_new(0, 1024, 0, 1);
643   GWEN_Buffer_SetHardLimit(buf, EBICS_BUFFER_MAX_HARD_LIMIT);
644 
645   DBG_INFO(AQEBICS_LOGDOMAIN, "Downloading data");
646   rv=EBC_Provider_Download(pro, u, rtype, buf, withReceipt, fromDate, toDate, doLock);
647   if (rv<0 || rv>=300) {
648     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
649     GWEN_Buffer_free(buf);
650     return rv;
651   }
652 
653   DBG_INFO(AQEBICS_LOGDOMAIN, "Importing data (%s : %s)", importerName, profileName);
654   rv=AB_Banking_ImportFromBufferLoadProfile(AB_Provider_GetBanking(pro),
655                                             importerName,
656                                             ctx,
657                                             profileName, NULL,
658                                             (const uint8_t *) GWEN_Buffer_GetStart(buf),
659                                             GWEN_Buffer_GetUsedBytes(buf));
660   GWEN_Buffer_free(buf);
661   if (rv<0) {
662     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
663     return rv;
664   }
665   DBG_INFO(AQEBICS_LOGDOMAIN, "Importing transactions: done");
666   return 0;
667 }
668 
669 
670 
EBC_Provider_DownloadIntoContextWithSession(AB_PROVIDER * pro,GWEN_HTTP_SESSION * sess,AB_USER * u,const char * rtype,int withReceipt,const GWEN_DATE * fromDate,const GWEN_DATE * toDate,const char * importerName,const char * profileName,AB_IMEXPORTER_CONTEXT * ctx,int doLock)671 int EBC_Provider_DownloadIntoContextWithSession(AB_PROVIDER *pro,
672                                                 GWEN_HTTP_SESSION *sess,
673                                                 AB_USER *u,
674                                                 const char *rtype,
675                                                 int withReceipt,
676                                                 const GWEN_DATE *fromDate,
677                                                 const GWEN_DATE *toDate,
678                                                 const char *importerName,
679                                                 const char *profileName,
680                                                 AB_IMEXPORTER_CONTEXT *ctx,
681                                                 int doLock)
682 {
683   int rv;
684   GWEN_BUFFER *buf;
685 
686   buf=GWEN_Buffer_new(0, 1024, 0, 1);
687   GWEN_Buffer_SetHardLimit(buf, EBICS_BUFFER_MAX_HARD_LIMIT);
688 
689   DBG_INFO(AQEBICS_LOGDOMAIN, "Downloading data");
690   rv=EBC_Provider_DownloadWithSession(pro, sess, u, rtype, buf, withReceipt, fromDate, toDate, doLock);
691   if (rv<0 || rv>=300) {
692     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
693     GWEN_Buffer_free(buf);
694     return rv;
695   }
696 
697   DBG_INFO(AQEBICS_LOGDOMAIN, "Importing data (%s : %s)", importerName, profileName);
698   rv=AB_Banking_ImportFromBufferLoadProfile(AB_Provider_GetBanking(pro),
699                                             importerName,
700                                             ctx,
701                                             profileName, NULL,
702                                             (const uint8_t *) GWEN_Buffer_GetStart(buf),
703                                             GWEN_Buffer_GetUsedBytes(buf));
704   GWEN_Buffer_free(buf);
705   if (rv<0) {
706     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
707     return rv;
708   }
709   DBG_INFO(AQEBICS_LOGDOMAIN, "Importing transactions: done");
710   return 0;
711 }
712 
713 
714 
EBC_Provider_Upload(AB_PROVIDER * pro,AB_USER * u,const char * rtype,const uint8_t * pData,uint32_t lData,int doLock)715 int EBC_Provider_Upload(AB_PROVIDER *pro, AB_USER *u,
716                         const char *rtype,
717                         const uint8_t *pData,
718                         uint32_t lData,
719                         int doLock)
720 {
721   EBC_PROVIDER *dp;
722   GWEN_HTTP_SESSION *sess;
723   int rv;
724   EBC_USER_STATUS ust;
725 
726   assert(pro);
727   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
728   assert(dp);
729 
730   ust=EBC_User_GetStatus(u);
731   if (ust!=EBC_UserStatus_Enabled) {
732     DBG_ERROR(AQEBICS_LOGDOMAIN,
733               "Invalid status \"%s\" of user \"%s\"",
734               EBC_User_Status_toString(ust),
735               AB_User_GetUserId(u));
736     return GWEN_ERROR_INVALID;
737   }
738 
739   /* create and open session */
740   sess=EBC_Dialog_new(pro, u);
741   rv=GWEN_HttpSession_Init(sess);
742   if (rv<0) {
743     DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not open session");
744     GWEN_HttpSession_free(sess);
745     return rv;
746   }
747 
748   /* lock user */
749   if (doLock) {
750     rv=AB_Provider_BeginExclUseUser(pro, u);
751     if (rv<0) {
752       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not lock customer");
753       GWEN_HttpSession_free(sess);
754       return rv;
755     }
756   }
757 
758   /* exchange request and response */
759   rv=EBC_Provider_XchgUploadRequest(pro, sess, u, rtype, pData, lData);
760   if (rv) {
761     DBG_ERROR(AQEBICS_LOGDOMAIN,
762               "Error exchanging upload request (%d)", rv);
763     if (doLock)
764       AB_Provider_EndExclUseUser(pro, u, 1);
765     GWEN_HttpSession_free(sess);
766     return rv;
767   }
768 
769   /* unlock user */
770   if (doLock) {
771     rv=AB_Provider_EndExclUseUser(pro, u, 0);
772     if (rv<0) {
773       DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not unlock customer");
774       AB_Provider_EndExclUseUser(pro, u, 1);
775       GWEN_HttpSession_free(sess);
776       return rv;
777     }
778   }
779 
780   /* close and destroy session */
781   GWEN_HttpSession_Fini(sess);
782   GWEN_HttpSession_free(sess);
783 
784   return rv;
785 }
786 
787 
788 
EBC_Provider_CreateKeys(AB_PROVIDER * pro,AB_USER * u,int cryptAndAuthKeySizeInBytes,int signKeySizeInBytes,int nounmount)789 int EBC_Provider_CreateKeys(AB_PROVIDER *pro,
790                             AB_USER *u,
791                             int cryptAndAuthKeySizeInBytes,
792                             int signKeySizeInBytes,
793                             int nounmount)
794 {
795   EBC_PROVIDER *dp;
796   GWEN_CRYPT_TOKEN *ct;
797   const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
798   uint32_t keyId;
799   GWEN_CRYPT_CRYPTALGO *algo;
800   int rv;
801 
802   assert(pro);
803   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
804   assert(dp);
805 
806   /* get token */
807   rv=AB_Banking_GetCryptToken(AB_Provider_GetBanking(pro),
808                               EBC_User_GetTokenType(u),
809                               EBC_User_GetTokenName(u),
810                               &ct);
811   if (rv) {
812     DBG_ERROR(AQEBICS_LOGDOMAIN,
813               "Error getting the user's crypt token (%d)", rv);
814     return rv;
815   }
816 
817   GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_EXP_65537);
818 
819   /* create algo */
820   algo=GWEN_Crypt_CryptAlgo_new(GWEN_Crypt_CryptAlgoId_Rsa,
821                                 GWEN_Crypt_CryptMode_None);
822   GWEN_Crypt_CryptAlgo_SetChunkSize(algo, cryptAndAuthKeySizeInBytes);
823 
824   /* open token for admin */
825   if (!GWEN_Crypt_Token_IsOpen(ct)) {
826     rv=GWEN_Crypt_Token_Open(ct, 1, 0);
827     if (rv) {
828       DBG_ERROR(AQEBICS_LOGDOMAIN,
829                 "Error opening crypt token (%d)", rv);
830       GWEN_Crypt_CryptAlgo_free(algo);
831       return rv;
832     }
833   }
834 
835   /* get context */
836   ctx=GWEN_Crypt_Token_GetContext(ct, EBC_User_GetTokenContextId(u), 0);
837   if (ctx==NULL) {
838     DBG_ERROR(AQEBICS_LOGDOMAIN,
839               "Could not get context %d", EBC_User_GetTokenContextId(u));
840     GWEN_Crypt_CryptAlgo_free(algo);
841     return GWEN_ERROR_INVALID;
842   }
843 
844   DBG_INFO(AQEBICS_LOGDOMAIN, "Creating keys, please wait...");
845 
846   /* get cipher key id */
847   keyId=GWEN_Crypt_Token_Context_GetDecipherKeyId(ctx);
848   if (keyId==0) {
849     DBG_ERROR(AQEBICS_LOGDOMAIN,
850               "No decipher key id specified (internal error)");
851     GWEN_Crypt_CryptAlgo_free(algo);
852     return GWEN_ERROR_INVALID;
853   }
854 
855   /* generate cipher key */
856   rv=GWEN_Crypt_Token_GenerateKey(ct, keyId, algo, 0);
857   if (rv) {
858     DBG_ERROR(AQEBICS_LOGDOMAIN,
859               "Error generating key (%d)", rv);
860     GWEN_Crypt_CryptAlgo_free(algo);
861     return rv;
862   }
863 
864   /* get auth sign key id */
865   keyId=GWEN_Crypt_Token_Context_GetAuthSignKeyId(ctx);
866   if (keyId) {
867     /* generate auth sign key */
868     rv=GWEN_Crypt_Token_GenerateKey(ct, keyId, algo, 0);
869     if (rv) {
870       DBG_ERROR(AQEBICS_LOGDOMAIN,
871                 "Error generating key (%d)", rv);
872       GWEN_Crypt_CryptAlgo_free(algo);
873       return rv;
874     }
875   }
876 
877   /* get sign key id */
878   keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx);
879   if (keyId==0) {
880     DBG_ERROR(AQEBICS_LOGDOMAIN,
881               "No sign key id specified (internal error)");
882     GWEN_Crypt_CryptAlgo_free(algo);
883     return GWEN_ERROR_INVALID;
884   }
885 
886   /* generate sign key */
887   GWEN_Crypt_CryptAlgo_SetChunkSize(algo, signKeySizeInBytes);
888   rv=GWEN_Crypt_Token_GenerateKey(ct, keyId, algo, 0);
889   if (rv) {
890     DBG_ERROR(AQEBICS_LOGDOMAIN,
891               "Error generating key (%d)", rv);
892     GWEN_Crypt_CryptAlgo_free(algo);
893     return rv;
894   }
895 
896   if (!nounmount) {
897     /* close token */
898     rv=GWEN_Crypt_Token_Close(ct, 0, 0);
899     if (rv) {
900       DBG_ERROR(AQEBICS_LOGDOMAIN,
901                 "Error closing crypt token (%d)", rv);
902       GWEN_Crypt_CryptAlgo_free(algo);
903       return rv;
904     }
905   }
906 
907   GWEN_Crypt_CryptAlgo_free(algo);
908   return 0;
909 }
910 
911 
912 
EBC_Provider_CreateTempKey(AB_PROVIDER * pro,AB_USER * u,int signKeySizeInBytes,int nounmount)913 int EBC_Provider_CreateTempKey(AB_PROVIDER *pro,
914                                AB_USER *u,
915                                int signKeySizeInBytes,
916                                int nounmount)
917 {
918   EBC_PROVIDER *dp;
919   GWEN_CRYPT_TOKEN *ct;
920   const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
921   uint32_t keyId;
922   GWEN_CRYPT_CRYPTALGO *algo;
923   int rv;
924 
925   assert(pro);
926   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
927   assert(dp);
928 
929   /* get token */
930   rv=AB_Banking_GetCryptToken(AB_Provider_GetBanking(pro),
931                               EBC_User_GetTokenType(u),
932                               EBC_User_GetTokenName(u),
933                               &ct);
934   if (rv) {
935     DBG_ERROR(AQEBICS_LOGDOMAIN,
936               "Error getting the user's crypt token (%d)", rv);
937     return rv;
938   }
939 
940   GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_EXP_65537);
941 
942   /* create algo */
943   algo=GWEN_Crypt_CryptAlgo_new(GWEN_Crypt_CryptAlgoId_Rsa,
944                                 GWEN_Crypt_CryptMode_None);
945 
946   /* open token for admin */
947   if (!GWEN_Crypt_Token_IsOpen(ct)) {
948     rv=GWEN_Crypt_Token_Open(ct, 1, 0);
949     if (rv) {
950       DBG_ERROR(AQEBICS_LOGDOMAIN,
951                 "Error opening crypt token (%d)", rv);
952       GWEN_Crypt_CryptAlgo_free(algo);
953       return rv;
954     }
955   }
956 
957   /* get context */
958   ctx=GWEN_Crypt_Token_GetContext(ct, EBC_User_GetTokenContextId(u), 0);
959   if (ctx==NULL) {
960     DBG_ERROR(AQEBICS_LOGDOMAIN,
961               "Could not get context %d", EBC_User_GetTokenContextId(u));
962     GWEN_Crypt_CryptAlgo_free(algo);
963     return GWEN_ERROR_INVALID;
964   }
965 
966   DBG_INFO(AQEBICS_LOGDOMAIN, "Creating keys, please wait...");
967 
968   /* get temp sign key id */
969   keyId=GWEN_Crypt_Token_Context_GetTempSignKeyId(ctx);
970   if (keyId==0) {
971     DBG_ERROR(AQEBICS_LOGDOMAIN,
972               "No sign key id specified (internal error)");
973     GWEN_Crypt_CryptAlgo_free(algo);
974     return GWEN_ERROR_INVALID;
975   }
976 
977   /* generate sign key */
978   GWEN_Crypt_CryptAlgo_SetChunkSize(algo, signKeySizeInBytes);
979   rv=GWEN_Crypt_Token_GenerateKey(ct, keyId, algo, 0);
980   if (rv) {
981     DBG_ERROR(AQEBICS_LOGDOMAIN,
982               "Error generating key (%d)", rv);
983     GWEN_Crypt_CryptAlgo_free(algo);
984     return rv;
985   }
986 
987   if (!nounmount) {
988     /* close token */
989     rv=GWEN_Crypt_Token_Close(ct, 0, 0);
990     if (rv) {
991       DBG_ERROR(AQEBICS_LOGDOMAIN,
992                 "Error closing crypt token (%d)", rv);
993       GWEN_Crypt_CryptAlgo_free(algo);
994       return rv;
995     }
996   }
997 
998   GWEN_Crypt_CryptAlgo_free(algo);
999   return 0;
1000 }
1001 
1002 
1003 
EBC_Provider_GetIniLetterTxt(AB_PROVIDER * pro,AB_USER * u,int useBankKey,GWEN_BUFFER * lbuf,int nounmount)1004 int EBC_Provider_GetIniLetterTxt(AB_PROVIDER *pro,
1005                                  AB_USER *u,
1006                                  int useBankKey,
1007                                  GWEN_BUFFER *lbuf,
1008                                  int nounmount)
1009 {
1010   AB_BANKING *ab;
1011   const void *p;
1012   unsigned int l;
1013   GWEN_BUFFER *bbuf;
1014   int i;
1015   GWEN_TIME *ti;
1016   int rv;
1017   EBC_PROVIDER *dp;
1018   GWEN_CRYPT_TOKEN *ct;
1019   const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1020   uint32_t kid;
1021   const GWEN_CRYPT_TOKEN_KEYINFO *ki=NULL;
1022   const char *signVersion;
1023 
1024   assert(pro);
1025   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
1026   assert(dp);
1027 
1028   assert(u);
1029 
1030   ab=AB_Provider_GetBanking(pro);
1031   assert(ab);
1032 
1033   signVersion=EBC_User_GetSignVersion(u);
1034   if (!(signVersion && *signVersion))
1035     signVersion="A005";
1036 
1037   /* get crypt token and context */
1038   rv=EBC_Provider_MountToken(pro, u, &ct, &ctx);
1039   if (rv<0) {
1040     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1041     return rv;
1042   }
1043 
1044   if (useBankKey) {
1045     /* get sign key info */
1046     kid=GWEN_Crypt_Token_Context_GetVerifyKeyId(ctx);
1047     if (kid) {
1048       ki=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
1049                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1050                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1051                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1052                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
1053                                      0);
1054     }
1055     if (!ki ||
1056         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) |
1057         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT)) {
1058       kid=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx);
1059       if (kid) {
1060         ki=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
1061                                        GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1062                                        GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1063                                        GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1064                                        GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
1065                                        0);
1066       }
1067     }
1068     if (!ki ||
1069         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) |
1070         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT)) {
1071       if (!nounmount)
1072         AB_Banking_ClearCryptTokenList(ab);
1073       DBG_ERROR(0, "Server keys missing, please get them first");
1074       GWEN_Gui_ProgressLog(0,
1075                            GWEN_LoggerLevel_Error,
1076                            I18N("Server keys missing, "
1077                                 "please get them first"));
1078       return GWEN_ERROR_NOT_FOUND;
1079     }
1080   }
1081   else {
1082     /* get sign key info */
1083     kid=GWEN_Crypt_Token_Context_GetSignKeyId(ctx);
1084     if (kid) {
1085       ki=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
1086                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1087                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1088                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1089                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
1090                                      0);
1091     }
1092     if (!ki ||
1093         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) |
1094         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT)) {
1095       if (!nounmount)
1096         AB_Banking_ClearCryptTokenList(ab);
1097       DBG_ERROR(0, "User keys missing, please generate them first");
1098       GWEN_Gui_ProgressLog(0,
1099                            GWEN_LoggerLevel_Error,
1100                            I18N("User keys missing, "
1101                                 "please generate them first"));
1102       return GWEN_ERROR_NOT_FOUND;
1103     }
1104   }
1105 
1106 
1107   /* prelude */
1108   GWEN_Buffer_AppendString(lbuf, I18N("\n\n\nINI-Letter DFUE ("));
1109 
1110   GWEN_Buffer_AppendString(lbuf, signVersion);
1111   GWEN_Buffer_AppendString(lbuf, ")\n\n");
1112   GWEN_Buffer_AppendString(lbuf,
1113                            I18N("Date           : "));
1114   ti=GWEN_CurrentTime();
1115   assert(ti);
1116   GWEN_Time_toString(ti, I18N("YYYY/MM/DD"), lbuf);
1117   GWEN_Buffer_AppendString(lbuf, "\n");
1118   GWEN_Buffer_AppendString(lbuf,
1119                            I18N("Time           : "));
1120   GWEN_Time_toString(ti, I18N("hh:mm:ss"), lbuf);
1121   GWEN_Buffer_AppendString(lbuf, "\n");
1122 
1123   if (useBankKey) {
1124     GWEN_Buffer_AppendString(lbuf,
1125                              I18N("Bank Code      : "));
1126     GWEN_Buffer_AppendString(lbuf, AB_User_GetBankCode(u));
1127     GWEN_Buffer_AppendString(lbuf, "\n");
1128   }
1129   else {
1130     const char *sUserId;
1131     const char *sCustomerId;
1132 
1133     sUserId=AB_User_GetUserId(u);
1134     sCustomerId=AB_User_GetCustomerId(u);
1135     GWEN_Buffer_AppendString(lbuf, I18N("EBICS|User           : "));
1136     GWEN_Buffer_AppendString(lbuf, sUserId?sUserId:"");
1137     GWEN_Buffer_AppendString(lbuf, "\n");
1138     GWEN_Buffer_AppendString(lbuf, I18N("EBICS|Customer       : "));
1139     GWEN_Buffer_AppendString(lbuf, sCustomerId?sCustomerId:"");
1140     GWEN_Buffer_AppendString(lbuf, "\n");
1141   }
1142 
1143   GWEN_Buffer_AppendString(lbuf,
1144                            I18N("Public key for electronic signature"));
1145   GWEN_Buffer_AppendString(lbuf, "\n\n");
1146 
1147   GWEN_Buffer_AppendString(lbuf, "  ");
1148   GWEN_Buffer_AppendString(lbuf,
1149                            I18N("Exponent"));
1150   GWEN_Buffer_AppendString(lbuf, "\n\n");
1151 
1152   /* exponent */
1153   p=GWEN_Crypt_Token_KeyInfo_GetExponentData(ki);
1154   l=GWEN_Crypt_Token_KeyInfo_GetExponentLen(ki);
1155   if (!p || !l) {
1156     DBG_ERROR(AQEBICS_LOGDOMAIN, "Bad key.");
1157     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error,
1158                          I18N("Bad key"));
1159     return GWEN_ERROR_BAD_DATA;
1160   }
1161 
1162   bbuf=GWEN_Buffer_new(0, 129, 0, 1);
1163   GWEN_Buffer_AppendBytes(bbuf, p, l);
1164   GWEN_Buffer_Rewind(bbuf);
1165   if (l<128)
1166     GWEN_Buffer_FillLeftWithBytes(bbuf, 0, 128-l);
1167   p=GWEN_Buffer_GetStart(bbuf);
1168   l=GWEN_Buffer_GetUsedBytes(bbuf);
1169   for (i=0; i<8; i++) {
1170     GWEN_Buffer_AppendString(lbuf, "  ");
1171     if (GWEN_Text_ToHexBuffer(p, 16, lbuf, 2, ' ', 0)) {
1172       DBG_ERROR(0, "Error converting to hex??");
1173       abort();
1174     }
1175     p+=16;
1176     GWEN_Buffer_AppendString(lbuf, "\n");
1177   }
1178   GWEN_Buffer_free(bbuf);
1179 
1180   /* modulus */
1181   GWEN_Buffer_AppendString(lbuf, "\n");
1182   GWEN_Buffer_AppendString(lbuf, "  ");
1183   GWEN_Buffer_AppendString(lbuf,
1184                            I18N("Modulus"));
1185   GWEN_Buffer_AppendString(lbuf, "\n\n");
1186   p=GWEN_Crypt_Token_KeyInfo_GetModulusData(ki);
1187   l=GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki);
1188   if (!p || !l) {
1189     DBG_ERROR(AQEBICS_LOGDOMAIN, "Bad key.");
1190     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error,
1191                          I18N("Bad key"));
1192     return GWEN_ERROR_BAD_DATA;
1193   }
1194 
1195   bbuf=GWEN_Buffer_new(0, 129, 0, 1);
1196   GWEN_Buffer_AppendBytes(bbuf, p, l);
1197   GWEN_Buffer_Rewind(bbuf);
1198   if (l<128)
1199     GWEN_Buffer_FillLeftWithBytes(bbuf, 0, 128-l);
1200   p=GWEN_Buffer_GetStart(bbuf);
1201   l=GWEN_Buffer_GetUsedBytes(bbuf);
1202   for (i=0; i<8; i++) {
1203     GWEN_Buffer_AppendString(lbuf, "  ");
1204     if (GWEN_Text_ToHexBuffer(p, 16, lbuf, 2, ' ', 0)) {
1205       DBG_ERROR(0, "Error converting to hex??");
1206       abort();
1207     }
1208     p+=16;
1209     GWEN_Buffer_AppendString(lbuf, "\n");
1210   }
1211   GWEN_Buffer_free(bbuf);
1212 
1213   GWEN_Buffer_AppendString(lbuf, "\n");
1214   GWEN_Buffer_AppendString(lbuf, "  ");
1215   GWEN_Buffer_AppendString(lbuf,
1216                            I18N("Hash"));
1217   GWEN_Buffer_AppendString(lbuf, "\n\n");
1218 
1219   bbuf=GWEN_Buffer_new(0, 21, 0, 1);
1220   if (strcasecmp(signVersion, "A004")==0) {
1221     rv=EB_Key_Info_BuildSigHash_Rmd160(ki, bbuf);
1222     if (rv<0) {
1223       DBG_ERROR(AQEBICS_LOGDOMAIN, "Error hashing (%d)", rv);
1224       abort();
1225     }
1226     p=GWEN_Buffer_GetStart(bbuf);
1227     l=GWEN_Buffer_GetUsedBytes(bbuf);
1228     for (i=0; i<2; i++) {
1229       GWEN_Buffer_AppendString(lbuf, "  ");
1230       if (GWEN_Text_ToHexBuffer(p, 10, lbuf, 2, ' ', 0)) {
1231         DBG_ERROR(0, "Error converting to hex??");
1232         abort();
1233       }
1234       p+=10;
1235       GWEN_Buffer_AppendString(lbuf, "\n");
1236     }
1237   }
1238   else {
1239     rv=EB_Key_Info_BuildSigHash_Sha256(ki, bbuf);
1240     if (rv<0) {
1241       DBG_ERROR(AQEBICS_LOGDOMAIN, "Error hashing (%d)", rv);
1242       abort();
1243     }
1244     p=GWEN_Buffer_GetStart(bbuf);
1245     l=GWEN_Buffer_GetUsedBytes(bbuf);
1246     for (i=0; i<2; i++) {
1247       GWEN_Buffer_AppendString(lbuf, "  ");
1248       if (GWEN_Text_ToHexBuffer(p, 16, lbuf, 2, ' ', 0)) {
1249         DBG_ERROR(0, "Error converting to hex??");
1250         abort();
1251       }
1252       p+=16;
1253       GWEN_Buffer_AppendString(lbuf, "\n");
1254     }
1255   }
1256 
1257   GWEN_Buffer_free(bbuf);
1258 
1259   if (!useBankKey) {
1260     GWEN_Buffer_AppendString(lbuf, "\n\n");
1261     GWEN_Buffer_AppendString(lbuf,
1262                              I18N("I confirm that I created the above key "
1263                                   "for my electronic signature.\n"));
1264     GWEN_Buffer_AppendString(lbuf, "\n\n");
1265     GWEN_Buffer_AppendString(lbuf,
1266                              I18N("____________________________  "
1267                                   "____________________________\n"
1268                                   "Place, date                   "
1269                                   "Signature\n"));
1270   }
1271 
1272   return 0;
1273 }
1274 
1275 
1276 
EBC_Provider__addKiTxt(GWEN_UNUSED AB_PROVIDER * pro,const GWEN_CRYPT_TOKEN_KEYINFO * ki,GWEN_BUFFER * lbuf,int version)1277 int EBC_Provider__addKiTxt(GWEN_UNUSED AB_PROVIDER *pro,
1278                            const GWEN_CRYPT_TOKEN_KEYINFO *ki,
1279                            GWEN_BUFFER *lbuf,
1280                            int version)
1281 {
1282   const uint8_t *p;
1283   unsigned int l;
1284   unsigned int nl;
1285   GWEN_BUFFER *bbuf;
1286   int i;
1287   int rv;
1288 
1289   GWEN_Buffer_AppendString(lbuf, "  ");
1290   GWEN_Buffer_AppendString(lbuf,
1291                            I18N("Exponent"));
1292   GWEN_Buffer_AppendString(lbuf, "\n\n");
1293 
1294   /* exponent */
1295   p=GWEN_Crypt_Token_KeyInfo_GetExponentData(ki);
1296   l=GWEN_Crypt_Token_KeyInfo_GetExponentLen(ki);
1297   if (!p || !l) {
1298     DBG_ERROR(AQEBICS_LOGDOMAIN, "Bad key.");
1299     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error,
1300                          I18N("Bad key"));
1301     return GWEN_ERROR_BAD_DATA;
1302   }
1303 
1304   /* skip null bytes */
1305   while (*p==0 && l>1) {
1306     p++;
1307     l--;
1308   }
1309 
1310   /* fill to next multiple of 16 */
1311   nl=((l+15)/16)*16;
1312   bbuf=GWEN_Buffer_new(0, nl+1, 0, 1);
1313   if (l<nl)
1314     GWEN_Buffer_FillWithBytes(bbuf, 0, nl-l);
1315   GWEN_Buffer_AppendBytes(bbuf, (const char *)p, l);
1316   p=(const uint8_t *)GWEN_Buffer_GetStart(bbuf);
1317   l=GWEN_Buffer_GetUsedBytes(bbuf);
1318 
1319   for (i=0; i<(nl/16); i++) {
1320     GWEN_Buffer_AppendString(lbuf, "  ");
1321     if (GWEN_Text_ToHexBuffer((const char *)p, 16, lbuf, 2, ' ', 0)) {
1322       DBG_ERROR(0, "Error converting to hex??");
1323       abort();
1324     }
1325     p+=16;
1326     GWEN_Buffer_AppendString(lbuf, "\n");
1327   }
1328   GWEN_Buffer_free(bbuf);
1329 
1330   /* modulus */
1331   GWEN_Buffer_AppendString(lbuf, "\n");
1332   GWEN_Buffer_AppendString(lbuf, "  ");
1333   GWEN_Buffer_AppendString(lbuf,
1334                            I18N("Modulus"));
1335   GWEN_Buffer_AppendString(lbuf, "\n\n");
1336   p=GWEN_Crypt_Token_KeyInfo_GetModulusData(ki);
1337   l=GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki);
1338   if (!p || !l) {
1339     DBG_ERROR(AQEBICS_LOGDOMAIN, "Bad key.");
1340     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Error,
1341                          I18N("Bad key"));
1342     return GWEN_ERROR_BAD_DATA;
1343   }
1344 
1345   nl=((l+15)/16)*16;
1346   bbuf=GWEN_Buffer_new(0, nl+1, 0, 1);
1347   if (l<nl)
1348     GWEN_Buffer_FillWithBytes(bbuf, 0, nl-l);
1349   GWEN_Buffer_AppendBytes(bbuf, (const char *)p, l);
1350   p=(const uint8_t *)GWEN_Buffer_GetStart(bbuf);
1351   l=GWEN_Buffer_GetUsedBytes(bbuf);
1352   for (i=0; i<(nl/16); i++) {
1353     GWEN_Buffer_AppendString(lbuf, "  ");
1354     if (GWEN_Text_ToHexBuffer((const char *)p, 16, lbuf, 2, ' ', 0)) {
1355       DBG_ERROR(0, "Error converting to hex??");
1356       abort();
1357     }
1358     p+=16;
1359     GWEN_Buffer_AppendString(lbuf, "\n");
1360   }
1361   GWEN_Buffer_free(bbuf);
1362 
1363   GWEN_Buffer_AppendString(lbuf, "\n");
1364   GWEN_Buffer_AppendString(lbuf, "  ");
1365   GWEN_Buffer_AppendString(lbuf,
1366                            I18N("Hash"));
1367   GWEN_Buffer_AppendString(lbuf, "\n\n");
1368 
1369   bbuf=GWEN_Buffer_new(0, 21, 0, 1);
1370   switch (version) {
1371   case 1:
1372     rv=EB_Key_Info_BuildHashSha1(ki, bbuf, 0);
1373     if (rv<0) {
1374       DBG_ERROR(AQEBICS_LOGDOMAIN, "Error hashing (%d)", rv);
1375       abort();
1376     }
1377 
1378     p=(const uint8_t *)GWEN_Buffer_GetStart(bbuf);
1379     l=GWEN_Buffer_GetUsedBytes(bbuf);
1380     for (i=0; i<2; i++) {
1381       GWEN_Buffer_AppendString(lbuf, "  ");
1382       if (GWEN_Text_ToHexBuffer((const char *)p, 10, lbuf, 2, ' ', 0)) {
1383         DBG_ERROR(0, "Error converting to hex??");
1384         abort();
1385       }
1386       p+=10;
1387       GWEN_Buffer_AppendString(lbuf, "\n");
1388     }
1389     break;
1390 
1391   case 2:
1392   default:
1393     rv=EB_Key_Info_BuildSigHash_Sha256(ki, bbuf);
1394     if (rv<0) {
1395       DBG_ERROR(AQEBICS_LOGDOMAIN, "Error hashing (%d)", rv);
1396       abort();
1397     }
1398     p=(const uint8_t *)GWEN_Buffer_GetStart(bbuf);
1399     l=GWEN_Buffer_GetUsedBytes(bbuf);
1400     for (i=0; i<2; i++) {
1401       GWEN_Buffer_AppendString(lbuf, "  ");
1402       if (GWEN_Text_ToHexBuffer((const char *)p, 16, lbuf, 2, ' ', 0)) {
1403         DBG_ERROR(0, "Error converting to hex??");
1404         abort();
1405       }
1406       p+=16;
1407       GWEN_Buffer_AppendString(lbuf, "\n");
1408     }
1409   }
1410   GWEN_Buffer_free(bbuf);
1411 
1412   return 0;
1413 }
1414 
1415 
1416 
EBC_Provider_GetHiaLetterTxt(AB_PROVIDER * pro,AB_USER * u,int useBankKey,GWEN_BUFFER * lbuf,int nounmount)1417 int EBC_Provider_GetHiaLetterTxt(AB_PROVIDER *pro,
1418                                  AB_USER *u,
1419                                  int useBankKey,
1420                                  GWEN_BUFFER *lbuf,
1421                                  int nounmount)
1422 {
1423   AB_BANKING *ab;
1424   GWEN_TIME *ti;
1425   int rv;
1426   EBC_PROVIDER *dp;
1427   GWEN_CRYPT_TOKEN *ct;
1428   const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1429   uint32_t kid;
1430   const GWEN_CRYPT_TOKEN_KEYINFO *ki=NULL;
1431   const char *authVersion;
1432   const char *cryptVersion;
1433   int i;
1434 
1435   assert(pro);
1436   dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
1437   assert(dp);
1438 
1439   assert(u);
1440 
1441   ab=AB_Provider_GetBanking(pro);
1442   assert(ab);
1443 
1444   cryptVersion=EBC_User_GetCryptVersion(u);
1445   if (!(cryptVersion && *cryptVersion))
1446     cryptVersion="E002";
1447   authVersion=EBC_User_GetAuthVersion(u);
1448   if (!(authVersion && *authVersion))
1449     authVersion="X002";
1450 
1451   /* get crypt token and context */
1452   rv=EBC_Provider_MountToken(pro, u, &ct, &ctx);
1453   if (rv<0) {
1454     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1455     return rv;
1456   }
1457 
1458   /* handle auth key */
1459   if (useBankKey) {
1460     /* get auth key info */
1461     kid=GWEN_Crypt_Token_Context_GetAuthVerifyKeyId(ctx);
1462     if (kid) {
1463       ki=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
1464                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1465                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1466                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1467                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
1468                                      0);
1469     }
1470     if (!ki ||
1471         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) |
1472         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT)) {
1473       if (!nounmount)
1474         AB_Banking_ClearCryptTokenList(ab);
1475       DBG_ERROR(0, "Server keys missing, please get them first");
1476       GWEN_Gui_ProgressLog(0,
1477                            GWEN_LoggerLevel_Error,
1478                            I18N("Server keys missing, "
1479                                 "please get them first"));
1480       return GWEN_ERROR_NOT_FOUND;
1481     }
1482   }
1483   else {
1484     /* get sign key info */
1485     kid=GWEN_Crypt_Token_Context_GetAuthSignKeyId(ctx);
1486     if (kid) {
1487       ki=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
1488                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1489                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1490                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1491                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
1492                                      0);
1493     }
1494     if (!ki ||
1495         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) |
1496         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT)) {
1497       if (!nounmount)
1498         AB_Banking_ClearCryptTokenList(ab);
1499       DBG_ERROR(0, "User keys missing, please generate them first");
1500       GWEN_Gui_ProgressLog(0,
1501                            GWEN_LoggerLevel_Error,
1502                            I18N("User keys missing, "
1503                                 "please generate them first"));
1504       return GWEN_ERROR_NOT_FOUND;
1505     }
1506   }
1507 
1508   /* prelude */
1509   GWEN_Buffer_AppendString(lbuf,
1510                            I18N("\n\n\nINI-Letter HIA\n\n"));
1511   GWEN_Buffer_AppendString(lbuf,
1512                            I18N("Date           : "));
1513   ti=GWEN_CurrentTime();
1514   assert(ti);
1515   GWEN_Time_toString(ti, I18N("YYYY/MM/DD"), lbuf);
1516   GWEN_Buffer_AppendString(lbuf, "\n");
1517   GWEN_Buffer_AppendString(lbuf,
1518                            I18N("Time           : "));
1519   GWEN_Time_toString(ti, I18N("hh:mm:ss"), lbuf);
1520   GWEN_Buffer_AppendString(lbuf, "\n");
1521 
1522   if (useBankKey) {
1523     GWEN_Buffer_AppendString(lbuf,
1524                              I18N("Bank Code      : "));
1525     GWEN_Buffer_AppendString(lbuf, AB_User_GetBankCode(u));
1526     GWEN_Buffer_AppendString(lbuf, "\n");
1527   }
1528   else {
1529     const char *sUserId;
1530     const char *sCustomerId;
1531 
1532     sUserId=AB_User_GetUserId(u);
1533     sCustomerId=AB_User_GetCustomerId(u);
1534     GWEN_Buffer_AppendString(lbuf, I18N("EBICS|User           : "));
1535     GWEN_Buffer_AppendString(lbuf, sUserId?sUserId:"");
1536     GWEN_Buffer_AppendString(lbuf, "\n");
1537     GWEN_Buffer_AppendString(lbuf, I18N("EBICS|Customer       : "));
1538     GWEN_Buffer_AppendString(lbuf, sCustomerId?sCustomerId:"");
1539     GWEN_Buffer_AppendString(lbuf, "\n");
1540   }
1541   GWEN_Buffer_AppendString(lbuf, "\n");
1542 
1543   /* add auth key */
1544   GWEN_Buffer_AppendString(lbuf, I18N("Public key for authentication signature ("));
1545   GWEN_Buffer_AppendString(lbuf, authVersion);
1546   GWEN_Buffer_AppendString(lbuf, ")\n\n");
1547 
1548   if (strcasecmp(authVersion, "X001")==0)
1549     i=1;
1550   else
1551     i=2;
1552   rv=EBC_Provider__addKiTxt(pro, ki, lbuf, i);
1553   if (rv<0) {
1554     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1555     return rv;
1556   }
1557 
1558   /* handle crypt key */
1559   ki=NULL;
1560   if (useBankKey) {
1561     /* get encipher key info */
1562     kid=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx);
1563     if (kid) {
1564       ki=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
1565                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1566                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1567                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1568                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
1569                                      0);
1570     }
1571     if (!ki ||
1572         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) |
1573         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT)) {
1574       if (!nounmount)
1575         AB_Banking_ClearCryptTokenList(ab);
1576       DBG_ERROR(0, "Server keys missing, please get them first");
1577       GWEN_Gui_ProgressLog(0,
1578                            GWEN_LoggerLevel_Error,
1579                            I18N("Server keys missing, "
1580                                 "please get them first"));
1581       return GWEN_ERROR_NOT_FOUND;
1582     }
1583   }
1584   else {
1585     /* get decipher key info */
1586     kid=GWEN_Crypt_Token_Context_GetDecipherKeyId(ctx);
1587     if (kid) {
1588       ki=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
1589                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1590                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1591                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1592                                      GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
1593                                      0);
1594     }
1595     if (!ki ||
1596         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) |
1597         !(GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT)) {
1598       if (!nounmount)
1599         AB_Banking_ClearCryptTokenList(ab);
1600       DBG_ERROR(0, "User keys missing, please generate them first");
1601       GWEN_Gui_ProgressLog(0,
1602                            GWEN_LoggerLevel_Error,
1603                            I18N("User keys missing, "
1604                                 "please generate them first"));
1605       return GWEN_ERROR_NOT_FOUND;
1606     }
1607   }
1608 
1609   /* add crypt key */
1610   GWEN_Buffer_AppendString(lbuf, "\n\n");
1611   GWEN_Buffer_AppendString(lbuf,
1612                            I18N("Public key for encryption ("));
1613   GWEN_Buffer_AppendString(lbuf, cryptVersion);
1614   GWEN_Buffer_AppendString(lbuf, ")\n\n");
1615 
1616   if (strcasecmp(cryptVersion, "E001")==0)
1617     i=1;
1618   else
1619     i=2;
1620   rv=EBC_Provider__addKiTxt(pro, ki, lbuf, i);
1621   if (rv<0) {
1622     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1623     return rv;
1624   }
1625 
1626   if (!useBankKey) {
1627     GWEN_Buffer_AppendString(lbuf, "\n\n");
1628     GWEN_Buffer_AppendString(lbuf,
1629                              I18N("I confirm that I created the above "
1630                                   "keys.\n"));
1631     GWEN_Buffer_AppendString(lbuf, "\n\n");
1632     GWEN_Buffer_AppendString(lbuf,
1633                              I18N("____________________________  "
1634                                   "____________________________\n"
1635                                   "Place, date                   "
1636                                   "Signature\n"));
1637   }
1638 
1639   return 0;
1640 }
1641 
1642 
1643 
EBC_Provider_Sha256(const uint8_t * pData,uint32_t lData,GWEN_BUFFER * hbuf)1644 int EBC_Provider_Sha256(const uint8_t *pData, uint32_t lData, GWEN_BUFFER *hbuf)
1645 {
1646   GWEN_BUFFER *tbuf;
1647   GWEN_MDIGEST *md;
1648   int rv;
1649 
1650   tbuf=GWEN_Buffer_new(0, lData, 0, 1);
1651   while (lData--) {
1652     uint8_t c;
1653 
1654     c=*(pData++);
1655     if (c!=13 && c!=10 && c!=26)
1656       GWEN_Buffer_AppendByte(tbuf, c);
1657   }
1658 
1659   /* hash (RMD160) */
1660   md=GWEN_MDigest_Sha256_new();
1661   rv=GWEN_MDigest_Begin(md);
1662   if (rv<0) {
1663     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1664     GWEN_MDigest_free(md);
1665     GWEN_Buffer_free(tbuf);
1666     return rv;
1667   }
1668   rv=GWEN_MDigest_Update(md,
1669                          (const uint8_t *)GWEN_Buffer_GetStart(tbuf),
1670                          GWEN_Buffer_GetUsedBytes(tbuf));
1671   if (rv<0) {
1672     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1673     GWEN_MDigest_free(md);
1674     GWEN_Buffer_free(tbuf);
1675     return rv;
1676   }
1677   rv=GWEN_MDigest_End(md);
1678   if (rv<0) {
1679     DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
1680     GWEN_MDigest_free(md);
1681     GWEN_Buffer_free(tbuf);
1682     return rv;
1683   }
1684   GWEN_Buffer_AppendBytes(hbuf,
1685                           (const char *)GWEN_MDigest_GetDigestPtr(md),
1686                           GWEN_MDigest_GetDigestSize(md));
1687   GWEN_MDigest_free(md);
1688   GWEN_Buffer_free(tbuf);
1689 
1690   return 0;
1691 }
1692 
1693 
1694 
1695