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