1 /***************************************************************************
2     begin       : Tue Nov 25 2008
3     copyright   : (C) 2020 by Martin Preuss
4     email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 #include <gwenhywfar/text.h>
11 
12 #define AH_MSGRXH_MAXKEYBUF 4096
13 
14 typedef enum {
15   AH_Opmode_None=0,
16   AH_Opmode_Cbc=2,
17   AH_Opmode_Iso9796_1=16,
18   AH_Opmode_Iso9796_2=17,
19   AH_Opmode_Rsa_Pkcs1_v1_5=18,
20   AH_Opmode_Rsa_Pss=19,
21   AH_Opmode_Retail_MAC=999
22 } AH_OPMODE;
23 
24 typedef enum {
25   AH_HashAlg_None=0,
26   AH_HashAlg_Sha1=1,
27   AH_HashAlg_Sha256=3,
28   AH_HashAlg_Sha256Sha256=6,
29   AH_HashAlg_Ripmed160=999
30 } AH_HASH_ALG;
31 
32 typedef enum {
33   AH_SignAlg_DES=1,
34   AH_SignAlg_RSA=10
35 } AH_SIGN_ALG;
36 
37 typedef enum {
38   AH_CryptAlg_2_Key_Triple_Des=13,
39   AH_CryptAlg_AES256=14
40 } AH_CRYPT_ALG;
41 
42 typedef enum {
43   AH_UsageSign_None=0,
44   AH_UsageSign_OwnerSigning=6
45 } AH_USAGE_SIGN;
46 
47 typedef struct {
48   AH_CRYPT_MODE protocol;
49   uint8_t       protocolVersion;
50   AH_SIGN_ALG   signAlgo;         /* Signaturalgorithmus, kodiert */
51   AH_OPMODE     opmodSignS;       /* Operationsmodus bei Signatur (Signierschluessel) */
52   AH_OPMODE     opmodSignD;       /* Operationsmodus bei Signatur (Signaturschluessel) */
53   AH_USAGE_SIGN usageSign;        /* Verwendung des Signaturalgorithmus */
54   AH_HASH_ALG   hashAlgS;         /* Hashalgorithmus, kodiert (Signierschluessel) */
55   AH_HASH_ALG   hashAlgD;         /* Hashalgorithmus, kodiert (Signaturschluessel) */
56   AH_CRYPT_ALG  cryptAlg;         /* Verschluesselungsalgorithmus, kodiert */
57   AH_OPMODE     opmodCrypt;       /* Operationsmodus bei Verschluesselung */
58 } RXH_PARAMETER;
59 
60 RXH_PARAMETER  rdh1_parameter= {
61   AH_CryptMode_Rdh,
62   1,
63   AH_SignAlg_RSA,
64   AH_Opmode_Iso9796_1,
65   AH_Opmode_None,
66   AH_UsageSign_OwnerSigning,
67   AH_HashAlg_Ripmed160,
68   AH_HashAlg_None,
69   AH_CryptAlg_2_Key_Triple_Des,
70   AH_Opmode_Cbc
71 };
72 
73 RXH_PARAMETER  rdh2_parameter= {
74   AH_CryptMode_Rdh,
75   2,
76   AH_SignAlg_RSA,
77   AH_Opmode_Iso9796_2,
78   AH_Opmode_None,
79   AH_UsageSign_OwnerSigning,
80   AH_HashAlg_Ripmed160,
81   AH_HashAlg_None,
82   AH_CryptAlg_2_Key_Triple_Des,
83   AH_Opmode_Cbc
84 };
85 
86 RXH_PARAMETER  rdh3_parameter= {
87   AH_CryptMode_Rdh,
88   3,
89   AH_SignAlg_RSA,
90   AH_Opmode_Rsa_Pkcs1_v1_5,
91   AH_Opmode_Iso9796_2,
92   AH_UsageSign_OwnerSigning,
93   AH_HashAlg_Sha1,
94   AH_HashAlg_Ripmed160,
95   AH_CryptAlg_2_Key_Triple_Des,
96   AH_Opmode_Rsa_Pkcs1_v1_5
97 };
98 
99 RXH_PARAMETER  rdh5_parameter= {
100   AH_CryptMode_Rdh,
101   5,
102   AH_SignAlg_RSA,
103   AH_Opmode_Rsa_Pkcs1_v1_5,
104   AH_Opmode_None,
105   AH_UsageSign_OwnerSigning,
106   AH_HashAlg_Sha1,
107   AH_HashAlg_None,
108   AH_CryptAlg_2_Key_Triple_Des,
109   AH_Opmode_Rsa_Pkcs1_v1_5
110 };
111 
112 RXH_PARAMETER  rdh6_parameter= {
113   AH_CryptMode_Rdh,
114   6,
115   AH_SignAlg_RSA,
116   AH_Opmode_Rsa_Pkcs1_v1_5,
117   AH_Opmode_Rsa_Pkcs1_v1_5,
118   AH_UsageSign_OwnerSigning,
119   AH_HashAlg_Sha256,
120   AH_HashAlg_Sha256,
121   AH_CryptAlg_2_Key_Triple_Des,
122   AH_Opmode_Rsa_Pkcs1_v1_5
123 };
124 
125 RXH_PARAMETER  rdh7_parameter= {
126   AH_CryptMode_Rdh,
127   7,
128   AH_SignAlg_RSA,
129   AH_Opmode_Rsa_Pss,
130   AH_Opmode_Rsa_Pss,
131   AH_UsageSign_OwnerSigning,
132   AH_HashAlg_Sha256Sha256,
133   AH_HashAlg_Sha256,
134   AH_CryptAlg_2_Key_Triple_Des,
135   AH_Opmode_Rsa_Pkcs1_v1_5
136 };
137 
138 RXH_PARAMETER  rdh8_parameter= {
139   AH_CryptMode_Rdh,
140   8,
141   AH_SignAlg_RSA,
142   AH_Opmode_Rsa_Pkcs1_v1_5,
143   AH_Opmode_None,
144   AH_UsageSign_OwnerSigning,
145   AH_HashAlg_Sha256,
146   AH_HashAlg_None,
147   AH_CryptAlg_2_Key_Triple_Des,
148   AH_Opmode_Rsa_Pkcs1_v1_5
149 };
150 
151 RXH_PARAMETER  rdh9_parameter= {
152   AH_CryptMode_Rdh,
153   9,
154   AH_SignAlg_RSA,
155   AH_Opmode_Rsa_Pss,
156   AH_Opmode_None,
157   AH_UsageSign_OwnerSigning,
158   AH_HashAlg_Sha256Sha256,
159   AH_HashAlg_None,
160   AH_CryptAlg_2_Key_Triple_Des,
161   AH_Opmode_Rsa_Pkcs1_v1_5
162 };
163 
164 RXH_PARAMETER  rdh10_parameter= {
165   AH_CryptMode_Rdh,
166   10,
167   AH_SignAlg_RSA,
168   AH_Opmode_Rsa_Pss,
169   AH_Opmode_None,
170   AH_UsageSign_OwnerSigning,
171   AH_HashAlg_Sha256Sha256,
172   AH_HashAlg_None,
173   AH_CryptAlg_2_Key_Triple_Des,
174   AH_Opmode_Cbc
175 };
176 
177 RXH_PARAMETER *rdh_parameter[11]= {
178   NULL, /* 0 */
179   &rdh1_parameter, /* 1 */
180   &rdh2_parameter, /* 2 */
181   &rdh3_parameter, /* 3 */
182   NULL, /* 4 */
183   &rdh5_parameter, /* 5 */
184   &rdh6_parameter, /* 6 */
185   &rdh7_parameter, /* 7 */
186   &rdh8_parameter, /* 8 */
187   &rdh9_parameter, /* 9 */
188   &rdh10_parameter /* 10 */
189 };
190 
191 RXH_PARAMETER  rah7_parameter= {AH_CryptMode_Rah,
192                                 7,
193                                 AH_SignAlg_RSA,
194                                 AH_Opmode_Rsa_Pss,
195                                 AH_Opmode_Rsa_Pss,
196                                 AH_UsageSign_OwnerSigning,
197                                 AH_HashAlg_Sha256Sha256,
198                                 AH_HashAlg_Sha256,
199                                 AH_CryptAlg_AES256,
200                                 AH_Opmode_Rsa_Pkcs1_v1_5
201                                };
202 
203 RXH_PARAMETER  rah9_parameter= {AH_CryptMode_Rah,
204                                 9,
205                                 AH_SignAlg_RSA,
206                                 AH_Opmode_Rsa_Pss,
207                                 AH_Opmode_None,
208                                 AH_UsageSign_OwnerSigning,
209                                 AH_HashAlg_Sha256Sha256,
210                                 AH_HashAlg_None,
211                                 AH_CryptAlg_AES256,
212                                 AH_Opmode_Rsa_Pkcs1_v1_5
213                                };
214 
215 RXH_PARAMETER  rah10_parameter= {AH_CryptMode_Rah,
216                                  10,
217                                  AH_SignAlg_RSA,
218                                  AH_Opmode_Rsa_Pss,
219                                  AH_Opmode_None,
220                                  AH_UsageSign_OwnerSigning,
221                                  AH_HashAlg_Sha256Sha256,
222                                  AH_HashAlg_None,
223                                  AH_CryptAlg_AES256,
224                                  AH_Opmode_Cbc
225                                 };
226 
227 RXH_PARAMETER *rah_parameter[11]= {
228   NULL, /* 0 */
229   NULL, /* 1 */
230   NULL, /* 2 */
231   NULL, /* 3 */
232   NULL, /* 4 */
233   NULL, /* 5 */
234   NULL, /* 6 */
235   &rah7_parameter, /* 7 */
236   NULL, /* 8 */
237   &rah9_parameter, /* 9 */
238   &rah10_parameter /* 10 */
239 
240 };
241 
242 static
AH_MsgRxh_VerifyInitialSignKey(GWEN_CRYPT_TOKEN * ct,const GWEN_CRYPT_TOKEN_CONTEXT * ctx,AB_USER * user,GWEN_DB_NODE * gr)243 GWEN_CRYPT_KEY *AH_MsgRxh_VerifyInitialSignKey(GWEN_CRYPT_TOKEN *ct,
244                                                const GWEN_CRYPT_TOKEN_CONTEXT *ctx,
245                                                AB_USER *user,
246                                                GWEN_DB_NODE *gr)
247 {
248 
249   GWEN_DB_NODE *dbCurr;
250   int haveKey=0;
251   int verified;
252   GWEN_CRYPT_KEY *bpk = NULL;
253 
254   /* search for "GetKeyResponse" */
255   haveKey=0;
256   dbCurr=GWEN_DB_GetFirstGroup(gr);
257   while (dbCurr) {
258     GWEN_DB_NODE *dbKeyResponse;
259     const char *s;
260 
261     if (strcasecmp(GWEN_DB_GroupName(dbCurr), "GetKeyResponse")==0) {
262       unsigned int bs;
263       const uint8_t *p;
264       dbKeyResponse=dbCurr;
265       DBG_DEBUG(AQHBCI_LOGDOMAIN, "Got this key response:");
266       if (GWEN_Logger_GetLevel(AQHBCI_LOGDOMAIN)>=GWEN_LoggerLevel_Debug)
267         GWEN_DB_Dump(dbKeyResponse, 2);
268 
269       p=GWEN_DB_GetBinValue(dbKeyResponse, "key/modulus", 0, 0, 0, &bs);
270 
271       if (!p || !bs) {
272         DBG_ERROR(AQHBCI_LOGDOMAIN, "No modulus");
273         return NULL;
274       }
275       else {
276         /* :TODO: if no key hash is on the card, check if a certificate was sent with the
277          * key and verify that, if not, ask the user for the INI-Letter
278          */
279         const uint8_t *exponent;
280         unsigned int expLen;
281         int msgKeyNum;
282         int msgKeyVer;
283         uint16_t sentModulusLength;
284         int keySize;
285 
286         exponent=GWEN_DB_GetBinValue(dbKeyResponse, "key/exponent", 0, 0, 0, &expLen);
287         sentModulusLength=bs;
288         /* skip zero bytes if any */
289         while (bs && *p==0) {
290           p++;
291           bs--;
292         }
293 
294         /* calculate key size in bytes */
295         if (bs<=96)
296           keySize=96;
297         else {
298           keySize=bs;
299         }
300 
301         s=GWEN_DB_GetCharValue(dbKeyResponse, "keyname/keytype", 0, "V");
302         msgKeyNum=GWEN_DB_GetIntValue(dbKeyResponse, "keyname/keynum", 0, 0);
303         msgKeyVer=GWEN_DB_GetIntValue(dbKeyResponse, "keyname/keyversion", 0, 0);
304 
305 
306 
307         if (strcasecmp(s, "S")==0) {
308           bpk=GWEN_Crypt_KeyRsa_fromModExp(keySize, p, bs, exponent, expLen);
309           GWEN_Crypt_Key_SetKeyNumber(bpk, msgKeyNum);
310           GWEN_Crypt_Key_SetKeyVersion(bpk, msgKeyVer);
311           verified=AH_User_VerifyInitialKey(ct, ctx, user, bpk, sentModulusLength, "sign");
312           if (verified==1) {
313             GWEN_Crypt_KeyRsa_AddFlags(bpk, GWEN_CRYPT_KEYRSA_FLAGS_ISVERIFIED);
314             AH_User_SetBankPubSignKey(user, bpk);
315             /* reload */
316             bpk=AH_User_GetBankPubSignKey(user);
317           }
318           else {
319             return NULL;
320           }
321 
322         }
323       }
324       haveKey++;
325     } /* if we have one */
326     dbCurr=GWEN_DB_GetNextGroup(dbCurr);
327   } /* while */
328 
329 
330   return bpk;
331 }
332 
AH_MsgRxh_PrepareCryptoSeg(AH_MSG * hmsg,AB_USER * u,RXH_PARAMETER * rxh_parameter,int keyNum,int keyVer,const GWEN_CRYPT_TOKEN_KEYINFO * ki,GWEN_DB_NODE * cfg,int crypt,int createCtrlRef)333 static int AH_MsgRxh_PrepareCryptoSeg(AH_MSG *hmsg,
334                                       AB_USER *u,
335                                       RXH_PARAMETER *rxh_parameter,
336                                       int keyNum,
337                                       int keyVer,
338                                       const GWEN_CRYPT_TOKEN_KEYINFO *ki,
339                                       GWEN_DB_NODE *cfg,
340                                       int crypt,
341                                       int createCtrlRef)
342 {
343   char sdate[9];
344   char stime[7];
345   char ctrlref[15];
346   struct tm *lt;
347   time_t tt;
348   const char *userId;
349   const char *peerId;
350   int secProfile;
351   assert(hmsg);
352   assert(u);
353   assert(cfg);
354 
355   userId=AB_User_GetUserId(u);
356   secProfile = AH_Msg_GetSecurityProfile(hmsg);
357   assert(userId);
358   assert(*userId);
359   peerId=AH_User_GetPeerId(u);
360   if (!peerId || *peerId==0) {
361     DBG_INFO(AQHBCI_LOGDOMAIN, "No PeerId in user, using user id");
362     peerId=userId;
363   }
364 
365   tt=time(0);
366   lt=localtime(&tt);
367 
368   if (createCtrlRef) {
369     /* create control reference */
370     if (!strftime(ctrlref, sizeof(ctrlref), "%Y%m%d%H%M%S", lt)) {
371       DBG_INFO(AQHBCI_LOGDOMAIN, "CtrlRef string too long");
372       return GWEN_ERROR_INTERNAL;
373     }
374 
375     GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "ctrlref", ctrlref);
376   }
377 
378   /* create date */
379   if (!strftime(sdate, sizeof(sdate), "%Y%m%d", lt)) {
380     DBG_INFO(AQHBCI_LOGDOMAIN, "Date string too long");
381     return GWEN_ERROR_INTERNAL;
382   }
383   /* create time */
384   if (!strftime(stime, sizeof(stime), "%H%M%S", lt)) {
385     DBG_INFO(AQHBCI_LOGDOMAIN, "Date string too long");
386     return GWEN_ERROR_INTERNAL;
387   }
388 
389   GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/dir", 1);
390   GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecStamp/date", sdate);
391   GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecStamp/time", stime);
392   GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "key/bankcode", AB_User_GetBankCode(u));
393   GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "key/userid", crypt?peerId:userId);
394   GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "key/keytype", crypt?"V":(secProfile>2?"D":"S"));
395   if (crypt) {
396     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "key/keynum", keyNum);
397     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "key/keyversion", keyVer);
398   }
399   else {
400     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "key/keynum", keyNum);
401     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "key/keyversion", keyVer);
402   }
403   switch (rxh_parameter->protocol) {
404   case AH_CryptMode_Rdh:
405     GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "secProfile/code", "RDH");
406     break;
407   case AH_CryptMode_Rah:
408     GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "secProfile/code", "RAH");
409     break;
410   default:
411     return GWEN_ERROR_INTERNAL;
412   }
413   GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "secProfile/version", rxh_parameter->protocolVersion);
414   if (crypt) {
415     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "function", 4);        /* crypt */
416     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "cryptAlgo/algo", rxh_parameter->cryptAlg);
417     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "cryptAlgo/mode", rxh_parameter->opmodCrypt);
418   }
419   else {
420     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signAlgo/algo", rxh_parameter->signAlgo);
421     if (secProfile > 2) {
422       GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "function", 1);        /* sign with digital signature key */
423       assert(rxh_parameter->opmodSignD > 0);
424       assert(rxh_parameter->hashAlgD > 0);
425       GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signAlgo/mode", rxh_parameter->opmodSignD);
426       GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "hashAlgo/algo", rxh_parameter->hashAlgD);
427     }
428     else {
429       GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "function", 2);        /* sign with signature key */
430       GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signAlgo/mode", rxh_parameter->opmodSignS);
431       GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "hashAlgo/algo", rxh_parameter->hashAlgS);
432     }
433     if (secProfile > 1) {
434       /* add certificate TODO: we need to get the type of certificate from outside */
435       int certLen = GWEN_Crypt_Token_KeyInfo_GetCertificateLen(ki);
436       const uint8_t *certData = GWEN_Crypt_Token_KeyInfo_GetCertificateData(ki);
437       GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "cert/type", 3); /* X.509 */
438       GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "cert/cert", certData, certLen);
439     }
440   }
441 
442   return 0;
443 }
444 
AH_Msg_SignRxh(AH_MSG * hmsg,GWEN_BUFFER * rawBuf,const char * signer)445 int AH_Msg_SignRxh(AH_MSG *hmsg,
446                    GWEN_BUFFER *rawBuf,
447                    const char *signer)
448 {
449   AH_HBCI *h;
450   GWEN_XMLNODE *node;
451   GWEN_DB_NODE *cfg;
452   GWEN_BUFFER *sigbuf;
453   GWEN_BUFFER *hbuf;
454   unsigned int l;
455   int rv;
456   char ctrlref[15];
457   const char *p;
458   GWEN_MSGENGINE *e;
459   uint32_t uFlags;
460   GWEN_CRYPT_TOKEN *ct;
461   const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
462   const GWEN_CRYPT_TOKEN_KEYINFO *ki;
463   uint32_t keyId;
464   uint32_t gid;
465   int secProfile;
466   RXH_PARAMETER *rxh_parameter;
467   int rxhVersion;
468   AB_USER *su;
469 
470   assert(hmsg);
471 
472   su=AH_Msg_GetUser(hmsg, signer);
473   if (!su) {
474     DBG_ERROR(AQHBCI_LOGDOMAIN,
475               "Unknown user \"%s\"",
476               signer);
477     return GWEN_ERROR_NOT_FOUND;
478   }
479 
480   h=AH_Dialog_GetHbci(hmsg->dialog);
481   assert(h);
482   e=AH_Dialog_GetMsgEngine(hmsg->dialog);
483   assert(e);
484 
485   /* get correct parameters */
486   rxhVersion = AH_User_GetRdhType(su);
487   switch (AH_User_GetCryptMode(su)) {
488   case AH_CryptMode_Rdh:
489     rxh_parameter=rdh_parameter[rxhVersion];
490     if (rxh_parameter == NULL) {
491       DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
492       return AB_ERROR_NOT_INIT;
493     }
494     break;
495   case AH_CryptMode_Rah:
496     rxh_parameter=rah_parameter[rxhVersion];
497     if (rxh_parameter == NULL) {
498       DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RAH%d is not supported!", rxhVersion);
499       return AB_ERROR_NOT_INIT;
500     }
501     break;
502   default:
503     return AB_ERROR_NOT_INIT;
504 
505   }
506 
507   GWEN_MsgEngine_SetMode(e, AH_CryptMode_toString(rxh_parameter->protocol));
508   //GWEN_MsgEngine_SetMode(e,"rdh");
509   secProfile = AH_Msg_GetSecurityProfile(hmsg);
510   gid=0;
511 
512   uFlags=AH_User_GetFlags(su);
513 
514 
515 
516   /* get crypt token of signer */
517   rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
518                               AH_User_GetTokenType(su),
519                               AH_User_GetTokenName(su),
520                               &ct);
521   if (rv) {
522     DBG_INFO(AQHBCI_LOGDOMAIN,
523              "Could not get crypt token for user \"%s\" (%d)",
524              AB_User_GetUserId(su), rv);
525     return rv;
526   }
527 
528   /* open CryptToken if necessary */
529   if (!GWEN_Crypt_Token_IsOpen(ct)) {
530     GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN);
531     rv=GWEN_Crypt_Token_Open(ct, 0, gid);
532     if (rv) {
533       DBG_INFO(AQHBCI_LOGDOMAIN,
534                "Could not open crypt token for user \"%s\" (%d)",
535                AB_User_GetUserId(su), rv);
536       return rv;
537     }
538   }
539 
540   /* get context and key info */
541   ctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(su), gid);
542   if (ctx==NULL) {
543     DBG_INFO(AQHBCI_LOGDOMAIN,
544              "Context %d not found on crypt token [%s:%s]",
545              AH_User_GetTokenContextId(su),
546              GWEN_Crypt_Token_GetTypeName(ct),
547              GWEN_Crypt_Token_GetTokenName(ct));
548     return GWEN_ERROR_NOT_FOUND;
549   }
550 
551   if (secProfile > 2) {
552     keyId=GWEN_Crypt_Token_Context_GetAuthSignKeyId(ctx);
553     DBG_ERROR(AQHBCI_LOGDOMAIN, "AQHBCI does not yet support non-reputation!");
554     return AB_ERROR_NOT_INIT;
555   }
556   else {
557     keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx);
558   }
559 
560   ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, gid);
561   if (ki==NULL) {
562     DBG_INFO(AQHBCI_LOGDOMAIN,
563              "Keyinfo %04x not found on crypt token [%s:%s]",
564              keyId,
565              GWEN_Crypt_Token_GetTypeName(ct),
566              GWEN_Crypt_Token_GetTokenName(ct));
567     return GWEN_ERROR_NOT_FOUND;
568   }
569 
570   node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "SigHead");
571   if (!node) {
572     DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigHead\" not found");
573     return GWEN_ERROR_INTERNAL;
574   }
575 
576   /* prepare config for segment */
577   cfg=GWEN_DB_Group_new("sighead");
578   rv=AH_MsgRxh_PrepareCryptoSeg(hmsg, su, rxh_parameter, rxh_parameter->protocolVersion,
579                                 GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki), ki, cfg, 0, 1);
580   if (rv) {
581     DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
582     GWEN_DB_Group_free(cfg);
583     return rv;
584   }
585 
586   /* set expected signer */
587   if (!(uFlags & AH_USER_FLAGS_BANK_DOESNT_SIGN)) {
588     const char *remoteId;
589 
590     remoteId=AH_User_GetPeerId(su);
591     if (!remoteId || *remoteId==0)
592       remoteId=AB_User_GetUserId(su);
593     assert(remoteId);
594     assert(*remoteId);
595 
596     DBG_DEBUG(AQHBCI_LOGDOMAIN,
597               "Expecting \"%s\" to sign the response",
598               remoteId);
599     AH_Msg_SetExpectedSigner(hmsg, remoteId);
600   }
601 
602 
603 
604   /* store system id */
605   if (hmsg->noSysId) {
606     GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
607                          "SecDetails/SecId", "0");
608   }
609   else {
610     /* store CID if we use a card */
611     const uint8_t *cidData;
612     uint32_t cidLen=GWEN_Crypt_Token_Context_GetCidLen(ctx);
613     cidData=GWEN_Crypt_Token_Context_GetCidPtr(ctx);
614     if (cidLen > 0 && cidData != NULL) {
615       GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/CID", cidData, cidLen);
616     }
617     p=AH_User_GetSystemId(su);
618     if (p==NULL) {
619       p=GWEN_Crypt_Token_Context_GetSystemId(ctx);
620     }
621     if (p) {
622       GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p);
623     }
624     else {
625       GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0");
626     }
627 
628   }
629 
630   /* retrieve control reference for sigtail (to be used later) */
631   p=GWEN_DB_GetCharValue(cfg, "ctrlref", 0, "");
632   if (strlen(p)>=sizeof(ctrlref)) {
633     DBG_INFO(AQHBCI_LOGDOMAIN, "Control reference too long (14 bytes maximum)");
634     GWEN_DB_Group_free(cfg);
635     return -1;
636   }
637   strcpy(ctrlref, p);
638 
639   /* create SigHead */
640   hbuf=GWEN_Buffer_new(0, 128+GWEN_Buffer_GetUsedBytes(rawBuf), 0, 1);
641   GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", hmsg->firstSegment-1);
642   if (AH_Msg_SignSeqOne(hmsg)) {
643     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signseq", 1);
644   }
645   else {
646     GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signseq", GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki));
647   }
648 
649   /* create signature head segment */
650   rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
651   GWEN_DB_Group_free(cfg);
652   cfg=0;
653   if (rv) {
654     DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigHead");
655     GWEN_Buffer_free(hbuf);
656     return rv;
657   }
658 
659   /* remember size of sighead for now */
660   l=GWEN_Buffer_GetUsedBytes(hbuf);
661 
662   /* add raw data to to-sign data buffer */
663   GWEN_Buffer_AppendBuffer(hbuf, rawBuf);
664 
665   /* sign message */
666   sigbuf=GWEN_Buffer_new(0, 512, 0, 1);
667   {
668     uint32_t signLen;
669     GWEN_CRYPT_PADDALGO *algo;
670     GWEN_MDIGEST *md=NULL;
671     uint32_t seq;
672     AH_HASH_ALG hashAlg;
673     AH_OPMODE opMode;
674     uint8_t  *digestPtr;
675     unsigned int digestSize;
676     const char *tokenType = AH_User_GetTokenType(su);
677     uint8_t doSHA256inSW = 0;
678 
679     if (secProfile > 2) {
680       hashAlg = rxh_parameter->hashAlgD;
681       opMode= rxh_parameter->opmodSignD;
682     }
683     else {
684       hashAlg = rxh_parameter->hashAlgS;
685       opMode= rxh_parameter->opmodSignS;
686     }
687 
688     /* https://www.aquamaniac.de/rdm/issues/41 */
689     if (tokenType && !strcasecmp(tokenType, "ohbci"))
690       doSHA256inSW = 1;
691 
692     /* hash sighead + data */
693     switch (hashAlg) {
694     case AH_HashAlg_Sha1:
695       md=GWEN_MDigest_Sha1_new();
696       break;
697     case AH_HashAlg_Sha256:
698       break;
699     case AH_HashAlg_Sha256Sha256:
700       md=GWEN_MDigest_Sha256_new();
701       break;
702     case AH_HashAlg_Ripmed160:
703       md=GWEN_MDigest_Rmd160_new();
704       break;
705     default:
706       md=NULL;
707     }
708     if (md != NULL) {
709       rv=GWEN_MDigest_Begin(md);
710       if (rv==0)
711         rv=GWEN_MDigest_Update(md,
712                                (uint8_t *)GWEN_Buffer_GetStart(hbuf),
713                                GWEN_Buffer_GetUsedBytes(hbuf));
714       if (rv==0)
715         rv=GWEN_MDigest_End(md);
716       if (rv<0) {
717         DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
718         GWEN_MDigest_free(md);
719         GWEN_Buffer_free(sigbuf);
720         GWEN_Buffer_free(hbuf);
721         return rv;
722       }
723       if ((hashAlg == AH_HashAlg_Sha256Sha256) && doSHA256inSW) {
724         DBG_NOTICE(AQHBCI_LOGDOMAIN, "%s(): doSHA256inSW (2nd).", __FUNCTION__);
725         rv = GWEN_MDigest_Begin(md);
726         if (rv == 0) {
727           uint8_t h[32];
728           memcpy(h, GWEN_MDigest_GetDigestPtr(md), 32);
729           rv = GWEN_MDigest_Update(md, h, 32);
730           if (rv == 0)
731             rv = GWEN_MDigest_End(md);
732         }
733         if (rv < 0) {
734           DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error round 2 (%d)", rv);
735           GWEN_MDigest_free(md);
736           GWEN_Buffer_free(sigbuf);
737           GWEN_Buffer_free(hbuf);
738           return rv;
739         }
740       }
741       digestPtr=GWEN_MDigest_GetDigestPtr(md);
742       digestSize=GWEN_MDigest_GetDigestSize(md);
743     }
744     else {
745       digestPtr=(uint8_t *)GWEN_Buffer_GetStart(hbuf);
746       digestSize=GWEN_Buffer_GetUsedBytes(hbuf);
747     }
748 
749     /* sign hash */
750     switch (opMode) {
751     case AH_Opmode_Iso9796_1:
752       algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_1A4);
753       GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
754       break;
755 
756     case AH_Opmode_Iso9796_2:
757       algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2);
758       GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
759       break;
760 
761     case AH_Opmode_Rsa_Pkcs1_v1_5:
762       algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_2);
763       GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
764       break;
765 
766     case AH_Opmode_Rsa_Pss:
767       algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256);
768       GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
769       break;
770     default:
771       return GWEN_ERROR_INTERNAL;
772     }
773 
774     signLen=GWEN_Buffer_GetMaxUnsegmentedWrite(sigbuf);
775 
776 
777     rv=GWEN_Crypt_Token_Sign(ct, keyId,
778                              algo,
779                              digestPtr,
780                              digestSize,
781                              (uint8_t *)GWEN_Buffer_GetStart(sigbuf),
782                              &signLen,
783                              &seq,
784                              gid);
785 
786     GWEN_Crypt_PaddAlgo_free(algo);
787 
788     GWEN_MDigest_free(md);
789     if (rv) {
790       DBG_ERROR(AQHBCI_LOGDOMAIN,
791                 "Could not sign data with medium of user \"%s\" (%d)",
792                 AB_User_GetUserId(su), rv);
793       GWEN_Buffer_free(sigbuf);
794       GWEN_Buffer_free(hbuf);
795       return rv;
796     }
797     GWEN_Buffer_IncrementPos(sigbuf, signLen);
798     GWEN_Buffer_AdjustUsedBytes(sigbuf);
799   }
800   DBG_DEBUG(AQHBCI_LOGDOMAIN, "Signing done");
801 
802   /* insert new SigHead at beginning of message buffer */
803   DBG_DEBUG(AQHBCI_LOGDOMAIN, "Inserting signature head");
804   GWEN_Buffer_Rewind(hmsg->buffer);
805   GWEN_Buffer_InsertBytes(hmsg->buffer, GWEN_Buffer_GetStart(hbuf), l);
806 
807   /* create sigtail */
808   DBG_DEBUG(AQHBCI_LOGDOMAIN, "Completing signature tail");
809   cfg=GWEN_DB_Group_new("sigtail");
810   GWEN_Buffer_Reset(hbuf);
811   GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", hmsg->lastSegment+1);
812   /* store to DB */
813   GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT,
814                       "signature",
815                       GWEN_Buffer_GetStart(sigbuf),
816                       GWEN_Buffer_GetUsedBytes(sigbuf));
817   GWEN_Buffer_free(sigbuf);
818   GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "ctrlref", ctrlref);
819 
820   /* get node */
821   node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "SigTail");
822   if (!node) {
823     DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigTail\"not found");
824     GWEN_Buffer_free(hbuf);
825     GWEN_DB_Group_free(cfg);
826     return -1;
827   }
828   rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
829   if (rv) {
830     DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigTail");
831     GWEN_Buffer_free(hbuf);
832     GWEN_DB_Group_free(cfg);
833     return -1;
834   }
835 
836   /* append sigtail */
837   DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail");
838   if (GWEN_Buffer_AppendBuffer(hmsg->buffer, hbuf)) {
839     DBG_INFO(AQHBCI_LOGDOMAIN, "here");
840     GWEN_Buffer_free(hbuf);
841     GWEN_DB_Group_free(cfg);
842     return -1;
843   }
844   DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail: done");
845 
846   GWEN_Buffer_free(hbuf);
847   GWEN_DB_Group_free(cfg);
848 
849   /* adjust segment numbers (for next signature and message tail */
850   hmsg->firstSegment--;
851   hmsg->lastSegment++;
852 
853   return 0;
854 }
855 
AH_Msg_EncryptRxh(AH_MSG * hmsg)856 int AH_Msg_EncryptRxh(AH_MSG *hmsg)
857 {
858   AH_HBCI *h;
859   GWEN_XMLNODE *node;
860   GWEN_DB_NODE *cfg;
861   GWEN_BUFFER *mbuf;
862   GWEN_BUFFER *hbuf;
863   uint32_t l;
864   int rv;
865   const char *p;
866   GWEN_MSGENGINE *e;
867   AB_USER *u;
868   const char *peerId;
869   //uint32_t uFlags;
870   GWEN_CRYPT_TOKEN *ct;
871   const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
872   GWEN_CRYPT_KEY *sk, *ek;
873   uint8_t encKey[AH_MSGRXH_MAXKEYBUF+64];
874   int encKeyLen;
875   uint32_t gid;
876   uint8_t sessionKeySize;
877   RXH_PARAMETER *rxh_parameter;
878   int rxhVersion;
879 
880   DBG_NOTICE(AQHBCI_LOGDOMAIN, "RXH-encrypting message");
881 
882   u=AH_Dialog_GetDialogOwner(hmsg->dialog);
883 
884   /* get correct parameters */
885   rxhVersion = AH_User_GetRdhType(u);
886   switch (AH_User_GetCryptMode(u)) {
887   case AH_CryptMode_Rdh:
888     rxh_parameter=rdh_parameter[rxhVersion];
889     if (rxh_parameter == NULL) {
890       DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
891       return AB_ERROR_NOT_INIT;
892     }
893     break;
894   case AH_CryptMode_Rah:
895     rxh_parameter=rah_parameter[rxhVersion];
896     if (rxh_parameter == NULL) {
897       DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
898       return AB_ERROR_NOT_INIT;
899     }
900     break;
901   default:
902     return GWEN_ERROR_INTERNAL;
903   }
904 
905   assert(hmsg);
906   h=AH_Dialog_GetHbci(hmsg->dialog);
907   assert(h);
908   e=AH_Dialog_GetMsgEngine(hmsg->dialog);
909   assert(e);
910   GWEN_MsgEngine_SetMode(e, AH_CryptMode_toString(rxh_parameter->protocol));
911   //GWEN_MsgEngine_SetMode(e,"rdh");
912   gid=0;
913 
914 
915   //  uFlags=AH_User_GetFlags(u);
916 
917   peerId=AH_User_GetPeerId(u);
918   if (!peerId || *peerId==0)
919     peerId=AB_User_GetUserId(u);
920 
921   /* get crypt token of signer */
922   rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
923                               AH_User_GetTokenType(u),
924                               AH_User_GetTokenName(u),
925                               &ct);
926   if (rv) {
927     DBG_INFO(AQHBCI_LOGDOMAIN,
928              "Could not get crypt token for user \"%s\" (%d)",
929              AB_User_GetUserId(u), rv);
930     return rv;
931   }
932 
933   /* open CryptToken if necessary */
934   if (!GWEN_Crypt_Token_IsOpen(ct)) {
935     GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN);
936     rv=GWEN_Crypt_Token_Open(ct, 0, gid);
937     if (rv) {
938       DBG_INFO(AQHBCI_LOGDOMAIN,
939                "Could not open crypt token for user \"%s\" (%d)",
940                AB_User_GetUserId(u), rv);
941       return rv;
942     }
943   }
944 
945   /* get context and key info */
946   ctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(u), gid);
947   if (ctx==NULL) {
948     DBG_INFO(AQHBCI_LOGDOMAIN,
949              "Context %d not found on crypt token [%s:%s]",
950              AH_User_GetTokenContextId(u),
951              GWEN_Crypt_Token_GetTypeName(ct),
952              GWEN_Crypt_Token_GetTokenName(ct));
953     return GWEN_ERROR_NOT_FOUND;
954   }
955 
956   ek=AH_User_GetBankPubCryptKey(u);
957   if (!ek) {
958     DBG_ERROR(AQHBCI_LOGDOMAIN,
959               "Bank Public Key not available, please download it first, e.g. with aqhbci-tool4 getkeys -u %lu",
960               (unsigned long int) AB_User_GetUniqueId(u));
961     GWEN_Gui_ProgressLog2(0,
962                           GWEN_LoggerLevel_Error,
963                           I18N("The public key from the bank is not available, please download it first, e.g. with "
964                                "aqhbci-tool4 getkeys -u %lu"),
965                           (unsigned long int) AB_User_GetUniqueId(u));
966     return GWEN_ERROR_INTERNAL;
967   }
968 
969   switch (rxh_parameter->protocol) {
970   case AH_CryptMode_Rdh:
971     DBG_INFO(AQHBCI_LOGDOMAIN, "Padding message with ANSI X9.23");
972     rv=GWEN_Padd_PaddWithAnsiX9_23(hmsg->buffer);
973     if (rv) {
974       DBG_INFO(AQHBCI_LOGDOMAIN, "Error padding message with ANSI X9.23 (%d)", rv);
975       return rv;
976     }
977 
978     /* create session key */
979     sk=GWEN_Crypt_KeyDes3K_Generate(GWEN_Crypt_CryptMode_Cbc, 24, 2);
980     sessionKeySize=16;
981     if (sk==NULL) {
982       DBG_INFO(AQHBCI_LOGDOMAIN, "Could not generate DES key");
983       return GWEN_ERROR_INTERNAL;
984     }
985 
986     if (0) {
987       uint8_t *p;
988       uint32_t len;
989 
990       DBG_ERROR(AQHBCI_LOGDOMAIN, "DES key for message");
991       p=GWEN_Crypt_KeyDes3K_GetKeyDataPtr(sk);
992       len=GWEN_Crypt_KeyDes3K_GetKeyDataLen(sk);
993       GWEN_Text_LogString((const char *)p, len, AQHBCI_LOGDOMAIN, GWEN_LoggerLevel_Error);
994     }
995     break;
996 
997   case AH_CryptMode_Rah:
998     DBG_INFO(AQHBCI_LOGDOMAIN, "Padding message with ZKA method");
999     rv=GWEN_Padd_PaddWithZka(hmsg->buffer);
1000     if (rv) {
1001       DBG_INFO(AQHBCI_LOGDOMAIN,
1002                "Error padding message with ZKA padding (%d)", rv);
1003       return rv;
1004     }
1005 
1006     /* create session key */
1007     sk=GWEN_Crypt_KeyAes256_Generate(GWEN_Crypt_CryptMode_Cbc, 32, 2);
1008     sessionKeySize=32;
1009     if (sk==NULL) {
1010       DBG_INFO(AQHBCI_LOGDOMAIN, "Could not generate AES-256 key");
1011       return GWEN_ERROR_INTERNAL;
1012     }
1013     break;
1014 
1015   default:
1016     DBG_INFO(AQHBCI_LOGDOMAIN, "Protocol not supported!");
1017     return GWEN_ERROR_INTERNAL;
1018   }
1019   /* encrypt message with that session key */
1020   mbuf=GWEN_Buffer_new(0, GWEN_Buffer_GetUsedBytes(hmsg->buffer), 0, 1);
1021   l=GWEN_Buffer_GetUsedBytes(hmsg->buffer);
1022   rv=GWEN_Crypt_Key_Encipher(sk,
1023                              (uint8_t *)GWEN_Buffer_GetStart(hmsg->buffer),
1024                              GWEN_Buffer_GetUsedBytes(hmsg->buffer),
1025                              (uint8_t *)GWEN_Buffer_GetPosPointer(mbuf),
1026                              &l);
1027   if (rv<0) {
1028     DBG_INFO(AQHBCI_LOGDOMAIN,
1029              "Could not encipher with DES session key (%d)",
1030              rv);
1031     GWEN_Buffer_free(mbuf);
1032     GWEN_Crypt_Key_free(sk);
1033     return rv;
1034   }
1035   GWEN_Buffer_IncrementPos(mbuf, l);
1036   GWEN_Buffer_AdjustUsedBytes(mbuf);
1037 
1038 
1039   /* encrypt session key */
1040   if (1) {
1041     uint32_t elen;
1042     GWEN_BUFFER *skbuf;
1043     GWEN_CRYPT_PADDALGO *algo;
1044 
1045     skbuf=GWEN_Buffer_new(0, 512, 0, 1);
1046     switch (rxh_parameter->protocol) {
1047     case AH_CryptMode_Rdh:
1048       GWEN_Buffer_InsertBytes(skbuf, (const char *) GWEN_Crypt_KeyDes3K_GetKeyDataPtr(sk), sessionKeySize);
1049       break;
1050     case AH_CryptMode_Rah:
1051       GWEN_Buffer_InsertBytes(skbuf, (const char *) GWEN_Crypt_KeyAes256_GetKeyDataPtr(sk), sessionKeySize);
1052       break;
1053     default:
1054       return GWEN_ERROR_INTERNAL;
1055     }
1056     GWEN_Buffer_Rewind(skbuf);
1057 
1058     switch (rxh_parameter->opmodCrypt) {
1059     case AH_Opmode_Cbc:
1060       algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_LeftZero);
1061       break;
1062     case AH_Opmode_Rsa_Pkcs1_v1_5:
1063       algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_2);
1064       break;
1065     default:
1066       return GWEN_ERROR_INTERNAL;
1067     }
1068     GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(ek));
1069     /* padd according to given algo */
1070     rv=GWEN_Padd_ApplyPaddAlgo(algo, skbuf);
1071     GWEN_Crypt_PaddAlgo_free(algo);
1072     if (rv) {
1073       DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1074       GWEN_Buffer_free(skbuf);
1075       return rv;
1076     }
1077 
1078 
1079     elen=GWEN_Crypt_Key_GetKeySize(ek);
1080     rv=GWEN_Crypt_Key_Encipher(ek,
1081                                (const uint8_t *) GWEN_Buffer_GetStart(skbuf),
1082                                GWEN_Crypt_Key_GetKeySize(ek), encKey, &elen);
1083 
1084     if (rv<0) {
1085       DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1086       GWEN_Buffer_free(mbuf);
1087       GWEN_Buffer_free(skbuf);
1088       GWEN_Crypt_Key_free(sk);
1089       return rv;
1090     }
1091     encKeyLen=elen;
1092     GWEN_Buffer_free(skbuf);
1093   }
1094   GWEN_Crypt_Key_free(sk);
1095 
1096   /* create crypt head */
1097   node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "CryptHead");
1098   if (!node) {
1099     DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptHead\" not found");
1100     GWEN_Buffer_free(mbuf);
1101     GWEN_Crypt_Key_free(sk);
1102     return GWEN_ERROR_INTERNAL;
1103   }
1104 
1105   /* create CryptHead */
1106   cfg=GWEN_DB_Group_new("crypthead");
1107   GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", 998);
1108 
1109   rv=AH_MsgRxh_PrepareCryptoSeg(hmsg, u, rxh_parameter, GWEN_Crypt_Key_GetKeyNumber(ek), GWEN_Crypt_Key_GetKeyVersion(ek),
1110                                 NULL, cfg, 1, 0);
1111   if (rv) {
1112     DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1113     GWEN_DB_Group_free(cfg);
1114     GWEN_Buffer_free(mbuf);
1115     return rv;
1116   }
1117 
1118   /* store system id */
1119   if (hmsg->noSysId) {
1120     GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
1121                          "SecDetails/SecId", "0");
1122   }
1123   else {
1124     /* store CID if we use a card */
1125     const uint8_t *cidData;
1126     uint32_t cidLen=GWEN_Crypt_Token_Context_GetCidLen(ctx);
1127     cidData=GWEN_Crypt_Token_Context_GetCidPtr(ctx);
1128     if (cidLen > 0 && cidData != NULL) {
1129       GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/CID", cidData, cidLen);
1130     }
1131 
1132     p=AH_User_GetSystemId(u);
1133     if (p==NULL) {
1134       p=GWEN_Crypt_Token_Context_GetSystemId(ctx);
1135     }
1136     if (p) {
1137       GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p);
1138     }
1139     else {
1140       GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0");
1141     }
1142 
1143   }
1144 
1145   /* store encrypted message key */
1146   GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "CryptAlgo/MsgKey", encKey, encKeyLen);
1147 
1148   hbuf=GWEN_Buffer_new(0, 256+GWEN_Buffer_GetUsedBytes(mbuf), 0, 1);
1149   rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
1150   if (rv) {
1151     DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptHead (%d)", rv);
1152     GWEN_Buffer_free(hbuf);
1153     GWEN_DB_Group_free(cfg);
1154     GWEN_Buffer_free(mbuf);
1155     return rv;
1156   }
1157   GWEN_DB_Group_free(cfg);
1158 
1159   /* create cryptdata */
1160   cfg=GWEN_DB_Group_new("cryptdata");
1161   GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", 999);
1162   GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "cryptdata", GWEN_Buffer_GetStart(mbuf),
1163                       GWEN_Buffer_GetUsedBytes(mbuf));
1164   GWEN_Buffer_free(mbuf);
1165 
1166   node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "CryptData");
1167   if (!node) {
1168     DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptData\"not found");
1169     GWEN_Buffer_free(hbuf);
1170     GWEN_DB_Group_free(cfg);
1171     return -1;
1172   }
1173   rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
1174   if (rv) {
1175     DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptData (%d)", rv);
1176     GWEN_Buffer_free(hbuf);
1177     GWEN_DB_Group_free(cfg);
1178     return rv;
1179   }
1180 
1181   /* replace existing buffer by encrypted one */
1182   GWEN_Buffer_free(hmsg->buffer);
1183   hmsg->buffer=hbuf;
1184   GWEN_DB_Group_free(cfg);
1185 
1186   return 0;
1187 }
1188 
1189 
1190 
1191 static
AH_MsgRxh__Verify_Internal(GWEN_CRYPT_KEY * k,GWEN_CRYPT_PADDALGO * a,const uint8_t * pInData,uint32_t inLen,const uint8_t * pSignatureData,uint32_t signatureLen)1192 int AH_MsgRxh__Verify_Internal(GWEN_CRYPT_KEY *k,
1193                                GWEN_CRYPT_PADDALGO *a,
1194                                const uint8_t *pInData,
1195                                uint32_t inLen,
1196                                const uint8_t *pSignatureData,
1197                                uint32_t signatureLen)
1198 {
1199 
1200   int rv;
1201   GWEN_CRYPT_PADDALGOID aid;
1202 
1203   aid=GWEN_Crypt_PaddAlgo_GetId(a);
1204 
1205   if (aid==GWEN_Crypt_PaddAlgoId_Iso9796_2 ||
1206       aid==GWEN_Crypt_PaddAlgoId_Pkcs1_2 ||
1207       aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1208     GWEN_BUFFER *tbuf;
1209     uint32_t l;
1210 
1211     /* these algos add random numbers, we must use encrypt fn here and
1212      * compare the decrypted and unpadded data with the source data */
1213     tbuf=GWEN_Buffer_new(0, signatureLen+16, 0, 0);
1214     l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
1215     rv=GWEN_Crypt_Key_Encipher(k,
1216                                pSignatureData, signatureLen,
1217                                (uint8_t *)GWEN_Buffer_GetStart(tbuf),
1218                                &l);
1219     if (rv<0) {
1220       DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1221       GWEN_Buffer_free(tbuf);
1222       return rv;
1223     }
1224     GWEN_Buffer_IncrementPos(tbuf, l);
1225     GWEN_Buffer_AdjustUsedBytes(tbuf);
1226 
1227     if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1228       int nbits;
1229       uint8_t *modPtr;
1230       /* nasty hack, do something better later */
1231       uint8_t modBuffer[AH_MSGRXH_MAXKEYBUF];
1232       uint32_t modLen;
1233       GWEN_MDIGEST *md;
1234 
1235       modPtr=&modBuffer[0];
1236       modLen=AH_MSGRXH_MAXKEYBUF;
1237       /* calculate real number of bits */
1238       rv=GWEN_Crypt_KeyRsa_GetModulus(k, modPtr, &modLen);
1239 
1240       nbits=modLen*8;
1241       while (modLen && *modPtr==0) {
1242         nbits-=8;
1243         modLen--;
1244         modPtr++;
1245       }
1246       if (modLen) {
1247         uint8_t b=*modPtr;
1248         int i;
1249         uint8_t mask=0x80;
1250 
1251         for (i=0; i<8; i++) {
1252           if (b & mask)
1253             break;
1254           nbits--;
1255           mask>>=1;
1256         }
1257       }
1258 
1259       if (nbits==0) {
1260         DBG_ERROR(AQHBCI_LOGDOMAIN, "Empty modulus");
1261         GWEN_Buffer_free(tbuf);
1262         return GWEN_ERROR_GENERIC;
1263       }
1264 
1265       md=GWEN_MDigest_Sha256_new();
1266       rv=GWEN_Padd_VerifyPkcs1Pss((const uint8_t *) GWEN_Buffer_GetStart(tbuf),
1267                                   GWEN_Buffer_GetUsedBytes(tbuf),
1268                                   nbits,
1269                                   pInData, inLen,
1270                                   inLen,
1271                                   md);
1272       GWEN_MDigest_free(md);
1273       if (rv<0) {
1274         DBG_ERROR(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1275         DBG_ERROR(AQHBCI_LOGDOMAIN, "Error verifying this data:");
1276         GWEN_Buffer_Dump(tbuf, 2);
1277         GWEN_Buffer_free(tbuf);
1278         return rv;
1279       }
1280     }
1281     else {
1282       rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
1283       if (rv<0) {
1284         DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1285         GWEN_Buffer_free(tbuf);
1286         return rv;
1287       }
1288       l=GWEN_Buffer_GetUsedBytes(tbuf);
1289 
1290       if (l!=inLen) {
1291         DBG_ERROR(AQHBCI_LOGDOMAIN, "Signature length doesn't match");
1292         GWEN_Buffer_free(tbuf);
1293         return GWEN_ERROR_VERIFY;
1294       }
1295       if (memcmp(pInData, GWEN_Buffer_GetStart(tbuf), l)!=0) {
1296         DBG_ERROR(AQHBCI_LOGDOMAIN, "Signature doesn't match:");
1297         GWEN_Buffer_free(tbuf);
1298         return GWEN_ERROR_VERIFY;
1299       }
1300     }
1301     GWEN_Buffer_free(tbuf);
1302   }
1303   else {
1304     GWEN_BUFFER *srcBuf;
1305 
1306     /* copy to a buffer for padding */
1307     srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1308     GWEN_Buffer_AppendBytes(srcBuf, (const char *)pInData, inLen);
1309 
1310     /* padd according to given algo */
1311     rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1312     if (rv) {
1313       DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1314       GWEN_Buffer_free(srcBuf);
1315       return rv;
1316     }
1317 
1318     /* verify with key */
1319     rv=GWEN_Crypt_Key_Verify(k,
1320                              (const uint8_t *)GWEN_Buffer_GetStart(srcBuf),
1321                              GWEN_Buffer_GetUsedBytes(srcBuf),
1322                              pSignatureData,
1323                              signatureLen);
1324     GWEN_Buffer_free(srcBuf);
1325     if (rv) {
1326       DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1327       return rv;
1328     }
1329   }
1330 
1331 
1332 
1333   return 0;
1334 }
1335 
1336 
1337 
AH_Msg_VerifyRxh(AH_MSG * hmsg,GWEN_DB_NODE * gr)1338 int AH_Msg_VerifyRxh(AH_MSG *hmsg, GWEN_DB_NODE *gr)
1339 {
1340   AH_HBCI *h;
1341   GWEN_LIST *sigheads;
1342   GWEN_LIST *sigtails;
1343   GWEN_DB_NODE *n;
1344   int nonSigHeads;
1345   int nSigheads;
1346   unsigned int dataBegin;
1347   char *dataStart;
1348   unsigned int dataLength;
1349   unsigned int i;
1350   AB_USER *u;
1351   GWEN_CRYPT_TOKEN *ct;
1352   const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1353   int ksize;
1354   int rv;
1355   uint32_t gid;
1356   uint32_t hashLen;
1357   AH_HASH_ALG hashAlg;
1358   AH_OPMODE opMode;
1359   uint8_t rxhVersion;
1360   RXH_PARAMETER *rxh_parameter;
1361   GWEN_CRYPT_KEY *bankPubSignKey;
1362 
1363   /* get correct parameters */
1364   u=AH_Dialog_GetDialogOwner(hmsg->dialog);
1365   assert(u);
1366 
1367   rxhVersion = AH_User_GetRdhType(u);
1368   switch (AH_User_GetCryptMode(u)) {
1369   case AH_CryptMode_Rdh:
1370     rxh_parameter=rdh_parameter[rxhVersion];
1371     if (rxh_parameter == NULL) {
1372       DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
1373       return AB_ERROR_NOT_INIT;
1374     }
1375     break;
1376   case AH_CryptMode_Rah:
1377     rxh_parameter=rah_parameter[rxhVersion];
1378     if (rxh_parameter == NULL) {
1379       DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
1380       return AB_ERROR_NOT_INIT;
1381     }
1382     break;
1383   default:
1384     return GWEN_ERROR_INTERNAL;
1385   }
1386   assert(hmsg);
1387   h=AH_Dialog_GetHbci(hmsg->dialog);
1388   assert(h);
1389 
1390 
1391   gid=0;
1392 
1393 
1394   hashAlg = rxh_parameter->hashAlgS;
1395   opMode= rxh_parameter->opmodSignS;
1396 
1397   /* get crypt token of signer */
1398   rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
1399                               AH_User_GetTokenType(u),
1400                               AH_User_GetTokenName(u),
1401                               &ct);
1402   if (rv) {
1403     DBG_INFO(AQHBCI_LOGDOMAIN,
1404              "Could not get crypt token for user \"%s\" (%d)",
1405              AB_User_GetUserId(u), rv);
1406     return rv;
1407   }
1408 
1409   /* open CryptToken if necessary */
1410   if (!GWEN_Crypt_Token_IsOpen(ct)) {
1411     GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN);
1412     rv=GWEN_Crypt_Token_Open(ct, 0, gid);
1413     if (rv) {
1414       DBG_INFO(AQHBCI_LOGDOMAIN,
1415                "Could not open crypt token for user \"%s\" (%d)",
1416                AB_User_GetUserId(u), rv);
1417       return rv;
1418     }
1419   }
1420 
1421   /* get context and key info */
1422   ctx=GWEN_Crypt_Token_GetContext(ct,
1423                                   AH_User_GetTokenContextId(u),
1424                                   gid);
1425   if (ctx==NULL) {
1426     DBG_INFO(AQHBCI_LOGDOMAIN,
1427              "Context %d not found on crypt token [%s:%s]",
1428              AH_User_GetTokenContextId(u),
1429              GWEN_Crypt_Token_GetTypeName(ct),
1430              GWEN_Crypt_Token_GetTokenName(ct));
1431     return GWEN_ERROR_NOT_FOUND;
1432   }
1433 
1434   /* let's go */
1435   sigheads=GWEN_List_new();
1436 
1437   /* enumerate signature heads */
1438   nonSigHeads=0;
1439   nSigheads=0;
1440   n=GWEN_DB_GetFirstGroup(gr);
1441   while (n) {
1442     if (strcasecmp(GWEN_DB_GroupName(n), "SigHead")==0) {
1443       /* found a signature head */
1444       if (nonSigHeads) {
1445         DBG_ERROR(AQHBCI_LOGDOMAIN,
1446                   "Found some unsigned parts at the beginning");
1447         GWEN_List_free(sigheads);
1448         return GWEN_ERROR_BAD_DATA;
1449       }
1450       GWEN_List_PushBack(sigheads, n);
1451       nSigheads++;
1452     }
1453     else if (strcasecmp(GWEN_DB_GroupName(n), "MsgHead")!=0) {
1454       if (nSigheads)
1455         break;
1456       nonSigHeads++;
1457     }
1458     n=GWEN_DB_GetNextGroup(n);
1459   } /* while */
1460 
1461   if (!n) {
1462     if (nSigheads) {
1463       DBG_ERROR(AQHBCI_LOGDOMAIN,
1464                 "Found Signature heads but no other segments");
1465       GWEN_List_free(sigheads);
1466       return GWEN_ERROR_BAD_DATA;
1467     }
1468     DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signatures");
1469     GWEN_List_free(sigheads);
1470     return 0;
1471   }
1472 
1473   /* only now we need the verify key */
1474   /* the public sign key is not on the RDH card, but exchanged in the
1475    * initial key exchange and resides in the user information
1476    */
1477   bankPubSignKey=AH_User_GetBankPubSignKey(u);
1478   if (bankPubSignKey==NULL) {
1479     /* this may be the first message with the public keys from the bank server,
1480      * if its signed, the key is transmitted in the message and my be verified with
1481      * different methods ([HBCI] B.3.1.3, case A):
1482      * * the zka card contains the hash in EF_NOTEPAD
1483      * * a certificate is sent with the message to verify
1484      * * INI letter
1485      *
1486      * check message for "S"-KEy, look up if there is a hash on the chip card
1487      */
1488     bankPubSignKey=AH_MsgRxh_VerifyInitialSignKey(ct, ctx, u, gr);
1489 
1490     if (bankPubSignKey==NULL) {
1491       DBG_INFO(AQHBCI_LOGDOMAIN,
1492                "No public bank sign key for user [%s]",
1493                AB_User_GetUserName(u));
1494       return GWEN_ERROR_NOT_FOUND;
1495     }
1496   }
1497 
1498   ksize=GWEN_Crypt_Key_GetKeySize(bankPubSignKey);
1499   assert(ksize<=AH_MSGRXH_MAXKEYBUF);
1500 
1501   /* store begin of signed data */
1502   dataBegin=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0);
1503   if (!dataBegin) {
1504     DBG_ERROR(AQHBCI_LOGDOMAIN, "No position specifications in segment");
1505     GWEN_List_free(sigheads);
1506     return GWEN_ERROR_BAD_DATA;
1507   }
1508 
1509   /* now get first signature tail */
1510   while (n) {
1511     if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")==0) {
1512       unsigned int currpos;
1513 
1514       /* found a signature tail */
1515       currpos=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0);
1516       if (!currpos || dataBegin>currpos) {
1517         DBG_ERROR(AQHBCI_LOGDOMAIN, "Bad position specification in Signature tail");
1518         GWEN_List_free(sigheads);
1519         return GWEN_ERROR_BAD_DATA;
1520       }
1521       dataLength=currpos-dataBegin;
1522       break;
1523     }
1524     n=GWEN_DB_GetNextGroup(n);
1525   } /* while */
1526 
1527   if (!n) {
1528     DBG_ERROR(AQHBCI_LOGDOMAIN, "No signature tail found");
1529     GWEN_List_free(sigheads);
1530     return GWEN_ERROR_BAD_DATA;
1531   }
1532 
1533   sigtails=GWEN_List_new();
1534   while (n) {
1535     if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")!=0)
1536       break;
1537     GWEN_List_PushBack(sigtails, n);
1538     n=GWEN_DB_GetNextGroup(n);
1539   } /* while */
1540 
1541   if (!n) {
1542     DBG_ERROR(AQHBCI_LOGDOMAIN, "Message tail expected");
1543     GWEN_List_free(sigheads);
1544     GWEN_List_free(sigtails);
1545     return GWEN_ERROR_BAD_DATA;
1546   }
1547 
1548   if (strcasecmp(GWEN_DB_GroupName(n), "MsgTail")!=0) {
1549     DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (msg tail expected)");
1550     GWEN_List_free(sigheads);
1551     GWEN_List_free(sigtails);
1552     return GWEN_ERROR_BAD_DATA;
1553   }
1554 
1555   n=GWEN_DB_GetNextGroup(n);
1556   if (n) {
1557     DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (end expected)");
1558     GWEN_List_free(sigheads);
1559     GWEN_List_free(sigtails);
1560     return GWEN_ERROR_BAD_DATA;
1561   }
1562 
1563   if (GWEN_List_GetSize(sigheads)!=
1564       GWEN_List_GetSize(sigtails)) {
1565     DBG_ERROR(AQHBCI_LOGDOMAIN,
1566               "Number of signature heads (%d) does not match "
1567               "number of signature tails (%d)",
1568               GWEN_List_GetSize(sigheads),
1569               GWEN_List_GetSize(sigtails));
1570     GWEN_List_free(sigheads);
1571     GWEN_List_free(sigtails);
1572     return GWEN_ERROR_BAD_DATA;
1573   }
1574 
1575   /* ok, now verify all signatures */
1576   dataStart=GWEN_Buffer_GetStart(hmsg->buffer)+dataBegin;
1577   for (i=0; i< GWEN_List_GetSize(sigtails); i++) {
1578     GWEN_DB_NODE *sighead;
1579     GWEN_DB_NODE *sigtail;
1580     const uint8_t *p;
1581     uint32_t l;
1582     int rv;
1583     uint8_t hash[32];
1584     const char *signerId;
1585 
1586     /* get signature tail */
1587     sigtail=(GWEN_DB_NODE *)GWEN_List_GetBack(sigtails);
1588 
1589     /* get corresponding signature head */
1590     sighead=(GWEN_DB_NODE *)GWEN_List_GetFront(sigheads);
1591 
1592     if (!sighead || !sigtail) {
1593       DBG_ERROR(AQHBCI_LOGDOMAIN,
1594                 "No signature head/tail left (internal error)");
1595       GWEN_List_free(sigheads);
1596       GWEN_List_free(sigtails);
1597       return GWEN_ERROR_INTERNAL;
1598     }
1599 
1600     GWEN_List_PopBack(sigtails);
1601     GWEN_List_PopFront(sigheads);
1602 
1603     signerId=GWEN_DB_GetCharValue(sighead, "key/userid", 0,
1604                                   I18N("unknown"));
1605 
1606     /* some checks */
1607     if (strcasecmp(GWEN_DB_GetCharValue(sighead, "ctrlref", 0, ""),
1608                    GWEN_DB_GetCharValue(sigtail, "ctrlref", 0, ""))!=0) {
1609       DBG_ERROR(AQHBCI_LOGDOMAIN, "Non-matching signature tail");
1610       GWEN_List_free(sigheads);
1611       GWEN_List_free(sigtails);
1612       return GWEN_ERROR_BAD_DATA;
1613     }
1614 
1615     /* hash signature head and data */
1616     if (1) {
1617       GWEN_MDIGEST *md;
1618 
1619       /* hash sighead + data */
1620       p=(const uint8_t *)GWEN_Buffer_GetStart(hmsg->buffer);
1621       p+=GWEN_DB_GetIntValue(sighead,
1622                              "segment/pos",
1623                              0,
1624                              0);
1625       l=GWEN_DB_GetIntValue(sighead,
1626                             "segment/length",
1627                             0,
1628                             0);
1629       switch (hashAlg) {
1630       case AH_HashAlg_Sha1:
1631         md=GWEN_MDigest_Sha1_new();
1632         break;
1633       case AH_HashAlg_Sha256:
1634       case AH_HashAlg_Sha256Sha256:
1635         md=GWEN_MDigest_Sha256_new();
1636         break;
1637       case AH_HashAlg_Ripmed160:
1638         md=GWEN_MDigest_Rmd160_new();
1639         break;
1640       default:
1641         md=NULL;
1642       }
1643 
1644       /* first round */
1645       rv=GWEN_MDigest_Begin(md);
1646       if (rv==0)
1647         /* digest signature head */
1648         rv=GWEN_MDigest_Update(md, p, l);
1649       if (rv==0)
1650         /* digest data */
1651         rv=GWEN_MDigest_Update(md, (const uint8_t *)dataStart, dataLength);
1652       if (rv==0)
1653         rv=GWEN_MDigest_End(md);
1654       if (rv<0) {
1655         DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
1656         GWEN_MDigest_free(md);
1657         GWEN_List_free(sigheads);
1658         GWEN_List_free(sigtails);
1659         return rv;
1660       }
1661       memmove(hash,
1662               GWEN_MDigest_GetDigestPtr(md),
1663               GWEN_MDigest_GetDigestSize(md));
1664 
1665       /* second round */
1666       if (hashAlg==AH_HashAlg_Sha256Sha256) {
1667         uint8_t hash1[32];
1668         memmove(hash1,
1669                 hash,
1670                 GWEN_MDigest_GetDigestSize(md));
1671         rv=GWEN_MDigest_Begin(md);
1672         if (rv==0)
1673           /* digest signature head */
1674           rv=GWEN_MDigest_Update(md, hash1, sizeof(hash1));
1675         if (rv==0)
1676           rv=GWEN_MDigest_End(md);
1677         if (rv<0) {
1678           DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
1679           GWEN_MDigest_free(md);
1680           GWEN_List_free(sigheads);
1681           GWEN_List_free(sigtails);
1682           return rv;
1683         }
1684         memmove(hash,
1685                 GWEN_MDigest_GetDigestPtr(md),
1686                 GWEN_MDigest_GetDigestSize(md));
1687       }
1688       hashLen=GWEN_MDigest_GetDigestSize(md);
1689       GWEN_MDigest_free(md);
1690     }
1691 
1692     /* verify signature */
1693     p=GWEN_DB_GetBinValue(sigtail, "signature", 0, 0, 0, &l);
1694 
1695     if (p && l) {
1696 
1697       GWEN_CRYPT_PADDALGO *algo;
1698 
1699       switch (opMode) {
1700       case AH_Opmode_Iso9796_1:
1701         algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_1A4);
1702         GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1703         break;
1704 
1705       case AH_Opmode_Iso9796_2:
1706         algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2);
1707         GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1708         break;
1709 
1710       case AH_Opmode_Rsa_Pkcs1_v1_5:
1711         algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_2);
1712         GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1713         break;
1714 
1715       case AH_Opmode_Rsa_Pss:
1716         algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256);
1717         GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1718         break;
1719       default:
1720         return GWEN_ERROR_INTERNAL;
1721       }
1722 
1723       rv=AH_MsgRxh__Verify_Internal(bankPubSignKey, algo,
1724                                     hash, hashLen, p, l);
1725       GWEN_Crypt_PaddAlgo_free(algo);
1726 
1727       if (rv) {
1728         if (rv==GWEN_ERROR_NO_KEY) {
1729           DBG_ERROR(AQHBCI_LOGDOMAIN,
1730                     "Unable to verify signature of user \"%s\" (no key)",
1731                     signerId);
1732           GWEN_Gui_ProgressLog(gid,
1733                                GWEN_LoggerLevel_Error,
1734                                I18N("Unable to verify signature (no key)"));
1735         }
1736         else {
1737           GWEN_BUFFER *tbuf;
1738 
1739           tbuf=GWEN_Buffer_new(0, hashLen, 0, 1);
1740           if (rv==GWEN_ERROR_VERIFY) {
1741             DBG_ERROR(AQHBCI_LOGDOMAIN,
1742                       "Invalid signature of user \"%s\"", signerId);
1743             GWEN_Gui_ProgressLog(gid,
1744                                  GWEN_LoggerLevel_Error,
1745                                  I18N("Invalid signature!!!"));
1746             GWEN_Buffer_AppendString(tbuf, "!");
1747           }
1748           else {
1749             GWEN_Gui_ProgressLog(gid,
1750                                  GWEN_LoggerLevel_Error,
1751                                  I18N("Could not verify signature"));
1752             DBG_ERROR(AQHBCI_LOGDOMAIN,
1753                       "Could not verify data with medium of user \"%s\" (%d)",
1754                       AB_User_GetUserId(u), rv);
1755             GWEN_Buffer_AppendString(tbuf, "?");
1756           }
1757 
1758           GWEN_Buffer_AppendString(tbuf, signerId);
1759           AH_Msg_AddSignerId(hmsg, GWEN_Buffer_GetStart(tbuf));
1760           GWEN_Buffer_free(tbuf);
1761         }
1762       }
1763       else {
1764         DBG_INFO(AQHBCI_LOGDOMAIN, "Message signed by \"%s\"", signerId);
1765         AH_Msg_AddSignerId(hmsg, signerId);
1766       }
1767     }
1768     else {
1769       DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signature");
1770       GWEN_List_free(sigheads);
1771       GWEN_List_free(sigtails);
1772       return GWEN_ERROR_BAD_DATA;
1773     }
1774 
1775     DBG_DEBUG(AQHBCI_LOGDOMAIN, "Verification done");
1776   } /* for */
1777 
1778   GWEN_List_free(sigheads);
1779   GWEN_List_free(sigtails);
1780   return 0;
1781 }
1782 
1783 
1784 #include "msgcrypt_rxh_decrypt.c"
1785 
1786 
1787