Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / plugins / backends / aqhbci / msglayer / msgcrypt_rxh_common.c @ 70260d0a

History | View | Annotate | Download (58.3 KB)

1
/***************************************************************************
2
    begin       : Tue Nov 25 2008
3
    copyright   : (C) 2004 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
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

    
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

    
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, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki), ki, cfg, 0, 1);
579
  if (rv) {
580
    DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
581
    GWEN_DB_Group_free(cfg);
582
    return rv;
583
  }
584

    
585
  /* set expected signer */
586
  if (!(uFlags & AH_USER_FLAGS_BANK_DOESNT_SIGN)) {
587
    const char *remoteId;
588

    
589
    remoteId=AH_User_GetPeerId(su);
590
    if (!remoteId || *remoteId==0)
591
      remoteId=AB_User_GetUserId(su);
592
    assert(remoteId);
593
    assert(*remoteId);
594

    
595
    DBG_DEBUG(AQHBCI_LOGDOMAIN,
596
              "Expecting \"%s\" to sign the response",
597
              remoteId);
598
    AH_Msg_SetExpectedSigner(hmsg, remoteId);
599
  }
600

    
601

    
602

    
603
  /* store system id */
604
  if (hmsg->noSysId) {
605
    GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
606
                         "SecDetails/SecId", "0");
607
  }
608
  else {
609
    /* store CID if we use a card */
610
    const uint8_t *cidData;
611
    uint32_t cidLen=GWEN_Crypt_Token_Context_GetCidLen(ctx);
612
    cidData=GWEN_Crypt_Token_Context_GetCidPtr(ctx);
613
    if (cidLen > 0 && cidData != NULL) {
614
      GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/CID", cidData, cidLen);
615
    }
616
    p=AH_User_GetSystemId(su);
617
    if (p==NULL) {
618
      p=GWEN_Crypt_Token_Context_GetSystemId(ctx);
619
    }
620
    if (p) {
621
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p);
622
    }
623
    else {
624
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0");
625
    }
626

    
627
  }
628

    
629
  /* retrieve control reference for sigtail (to be used later) */
630
  p=GWEN_DB_GetCharValue(cfg, "ctrlref", 0, "");
631
  if (strlen(p)>=sizeof(ctrlref)) {
632
    DBG_INFO(AQHBCI_LOGDOMAIN, "Control reference too long (14 bytes maximum)");
633
    GWEN_DB_Group_free(cfg);
634
    return -1;
635
  }
636
  strcpy(ctrlref, p);
637

    
638
  /* create SigHead */
639
  hbuf=GWEN_Buffer_new(0, 128+GWEN_Buffer_GetUsedBytes(rawBuf), 0, 1);
640
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", hmsg->firstSegment-1);
641
  if (AH_Msg_SignSeqOne(hmsg)) {
642
    GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signseq", 1);
643
  }
644
  else {
645
    GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "signseq", GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki));
646
  }
647

    
648
  /* create signature head segment */
649
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
650
  GWEN_DB_Group_free(cfg);
651
  cfg=0;
652
  if (rv) {
653
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigHead");
654
    GWEN_Buffer_free(hbuf);
655
    return rv;
656
  }
657

    
658
  /* remember size of sighead for now */
659
  l=GWEN_Buffer_GetUsedBytes(hbuf);
660

    
661
  /* add raw data to to-sign data buffer */
662
  GWEN_Buffer_AppendBuffer(hbuf, rawBuf);
663

    
664
  /* sign message */
665
  sigbuf=GWEN_Buffer_new(0, 512, 0, 1);
666
  {
667
    uint32_t signLen;
668
    GWEN_CRYPT_PADDALGO *algo;
669
    GWEN_MDIGEST *md=NULL;
670
    uint32_t seq;
671
    AH_HASH_ALG hashAlg;
672
    AH_OPMODE opMode;
673
    uint8_t  *digestPtr;
674
    unsigned int digestSize;
675
    const char *tokenType = AH_User_GetTokenType(su);
676
    uint8_t doSHA256inSW = 0;
677

    
678
    if (secProfile > 2) {
679
      hashAlg = rxh_parameter->hashAlgD;
680
      opMode= rxh_parameter->opmodSignD;
681
    }
682
    else {
683
      hashAlg = rxh_parameter->hashAlgS;
684
      opMode= rxh_parameter->opmodSignS;
685
    }
686

    
687
    /* https://www.aquamaniac.de/rdm/issues/41 */
688
    if (tokenType && !strcasecmp(tokenType, "ohbci"))
689
      doSHA256inSW = 1;
690

    
691
    /* hash sighead + data */
692
    switch (hashAlg) {
693
    case AH_HashAlg_Sha1:
694
      md=GWEN_MDigest_Sha1_new();
695
      break;
696
    case AH_HashAlg_Sha256:
697
      break;
698
    case AH_HashAlg_Sha256Sha256:
699
      md=GWEN_MDigest_Sha256_new();
700
      break;
701
    case AH_HashAlg_Ripmed160:
702
      md=GWEN_MDigest_Rmd160_new();
703
      break;
704
    default:
705
      md=NULL;
706
    }
707
    if (md != NULL) {
708
      rv=GWEN_MDigest_Begin(md);
709
      if (rv==0)
710
        rv=GWEN_MDigest_Update(md,
711
                               (uint8_t *)GWEN_Buffer_GetStart(hbuf),
712
                               GWEN_Buffer_GetUsedBytes(hbuf));
713
      if (rv==0)
714
        rv=GWEN_MDigest_End(md);
715
      if (rv<0) {
716
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
717
        GWEN_MDigest_free(md);
718
        GWEN_Buffer_free(sigbuf);
719
        GWEN_Buffer_free(hbuf);
720
        return rv;
721
      }
722
      if ((hashAlg == AH_HashAlg_Sha256Sha256) && doSHA256inSW) {
723
        DBG_NOTICE(AQHBCI_LOGDOMAIN, "%s(): doSHA256inSW (2nd).", __FUNCTION__);
724
        rv = GWEN_MDigest_Begin(md);
725
        if (rv == 0) {
726
          uint8_t h[32];
727
          memcpy(h, GWEN_MDigest_GetDigestPtr(md), 32);
728
          rv = GWEN_MDigest_Update(md, h, 32);
729
          if (rv == 0)
730
            rv = GWEN_MDigest_End(md);
731
        }
732
        if (rv < 0) {
733
          DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error round 2 (%d)", rv);
734
          GWEN_MDigest_free(md);
735
          GWEN_Buffer_free(sigbuf);
736
          GWEN_Buffer_free(hbuf);
737
          return rv;
738
        }
739
      }
740
      digestPtr=GWEN_MDigest_GetDigestPtr(md);
741
      digestSize=GWEN_MDigest_GetDigestSize(md);
742
    }
743
    else {
744
      digestPtr=(uint8_t *)GWEN_Buffer_GetStart(hbuf);
745
      digestSize=GWEN_Buffer_GetUsedBytes(hbuf);
746
    }
747

    
748
    /* sign hash */
749
    switch (opMode) {
750
    case AH_Opmode_Iso9796_1:
751
      algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_1A4);
752
      GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
753
      break;
754

    
755
    case AH_Opmode_Iso9796_2:
756
      algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2);
757
      GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
758
      break;
759

    
760
    case AH_Opmode_Rsa_Pkcs1_v1_5:
761
      algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_2);
762
      GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
763
      break;
764

    
765
    case AH_Opmode_Rsa_Pss:
766
      algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256);
767
      GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
768
      break;
769
    default:
770
      return GWEN_ERROR_INTERNAL;
771
    }
772

    
773
    signLen=GWEN_Buffer_GetMaxUnsegmentedWrite(sigbuf);
774

    
775

    
776
    rv=GWEN_Crypt_Token_Sign(ct, keyId,
777
                             algo,
778
                             digestPtr,
779
                             digestSize,
780
                             (uint8_t *)GWEN_Buffer_GetStart(sigbuf),
781
                             &signLen,
782
                             &seq,
783
                             gid);
784

    
785
    GWEN_Crypt_PaddAlgo_free(algo);
786

    
787
    GWEN_MDigest_free(md);
788
    if (rv) {
789
      DBG_ERROR(AQHBCI_LOGDOMAIN,
790
                "Could not sign data with medium of user \"%s\" (%d)",
791
                AB_User_GetUserId(su), rv);
792
      GWEN_Buffer_free(sigbuf);
793
      GWEN_Buffer_free(hbuf);
794
      return rv;
795
    }
796
    GWEN_Buffer_IncrementPos(sigbuf, signLen);
797
    GWEN_Buffer_AdjustUsedBytes(sigbuf);
798
  }
799
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Signing done");
800

    
801
  /* insert new SigHead at beginning of message buffer */
802
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Inserting signature head");
803
  GWEN_Buffer_Rewind(hmsg->buffer);
804
  GWEN_Buffer_InsertBytes(hmsg->buffer, GWEN_Buffer_GetStart(hbuf), l);
805

    
806
  /* create sigtail */
807
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Completing signature tail");
808
  cfg=GWEN_DB_Group_new("sigtail");
809
  GWEN_Buffer_Reset(hbuf);
810
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", hmsg->lastSegment+1);
811
  /* store to DB */
812
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT,
813
                      "signature",
814
                      GWEN_Buffer_GetStart(sigbuf),
815
                      GWEN_Buffer_GetUsedBytes(sigbuf));
816
  GWEN_Buffer_free(sigbuf);
817
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "ctrlref", ctrlref);
818

    
819
  /* get node */
820
  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "SigTail");
821
  if (!node) {
822
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigTail\"not found");
823
    GWEN_Buffer_free(hbuf);
824
    GWEN_DB_Group_free(cfg);
825
    return -1;
826
  }
827
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
828
  if (rv) {
829
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigTail");
830
    GWEN_Buffer_free(hbuf);
831
    GWEN_DB_Group_free(cfg);
832
    return -1;
833
  }
834

    
835
  /* append sigtail */
836
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail");
837
  if (GWEN_Buffer_AppendBuffer(hmsg->buffer, hbuf)) {
838
    DBG_INFO(AQHBCI_LOGDOMAIN, "here");
839
    GWEN_Buffer_free(hbuf);
840
    GWEN_DB_Group_free(cfg);
841
    return -1;
842
  }
843
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail: done");
844

    
845
  GWEN_Buffer_free(hbuf);
846
  GWEN_DB_Group_free(cfg);
847

    
848
  /* adjust segment numbers (for next signature and message tail */
849
  hmsg->firstSegment--;
850
  hmsg->lastSegment++;
851

    
852
  return 0;
853
}
854

    
855
int AH_Msg_EncryptRxh(AH_MSG *hmsg)
856
{
857
  AH_HBCI *h;
858
  GWEN_XMLNODE *node;
859
  GWEN_DB_NODE *cfg;
860
  GWEN_BUFFER *mbuf;
861
  GWEN_BUFFER *hbuf;
862
  uint32_t l;
863
  int rv;
864
  const char *p;
865
  GWEN_MSGENGINE *e;
866
  AB_USER *u;
867
  const char *peerId;
868
  //uint32_t uFlags;
869
  GWEN_CRYPT_TOKEN *ct;
870
  const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
871
  GWEN_CRYPT_KEY *sk, *ek;
872
  uint8_t encKey[AH_MSGRXH_MAXKEYBUF+64];
873
  int encKeyLen;
874
  uint32_t gid;
875
  uint8_t sessionKeySize;
876
  RXH_PARAMETER *rxh_parameter;
877
  int rxhVersion;
878

    
879
  u=AH_Dialog_GetDialogOwner(hmsg->dialog);
880

    
881
  /* get correct parameters */
882
  rxhVersion = AH_User_GetRdhType(u);
883
  switch (AH_User_GetCryptMode(u)) {
884
  case AH_CryptMode_Rdh:
885
    rxh_parameter=rdh_parameter[rxhVersion];
886
    if (rxh_parameter == NULL) {
887
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
888
      return AB_ERROR_NOT_INIT;
889
    }
890
    break;
891
  case AH_CryptMode_Rah:
892
    rxh_parameter=rah_parameter[rxhVersion];
893
    if (rxh_parameter == NULL) {
894
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
895
      return AB_ERROR_NOT_INIT;
896
    }
897
    break;
898
  default:
899
    return GWEN_ERROR_INTERNAL;
900
  }
901

    
902
  assert(hmsg);
903
  h=AH_Dialog_GetHbci(hmsg->dialog);
904
  assert(h);
905
  e=AH_Dialog_GetMsgEngine(hmsg->dialog);
906
  assert(e);
907
  GWEN_MsgEngine_SetMode(e, AH_CryptMode_toString(rxh_parameter->protocol));
908
  //GWEN_MsgEngine_SetMode(e,"rdh");
909
  gid=0;
910

    
911

    
912
  //  uFlags=AH_User_GetFlags(u);
913

    
914
  peerId=AH_User_GetPeerId(u);
915
  if (!peerId || *peerId==0)
916
    peerId=AB_User_GetUserId(u);
917

    
918
  /* get crypt token of signer */
919
  rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
920
                              AH_User_GetTokenType(u),
921
                              AH_User_GetTokenName(u),
922
                              &ct);
923
  if (rv) {
924
    DBG_INFO(AQHBCI_LOGDOMAIN,
925
             "Could not get crypt token for user \"%s\" (%d)",
926
             AB_User_GetUserId(u), rv);
927
    return rv;
928
  }
929

    
930
  /* open CryptToken if necessary */
931
  if (!GWEN_Crypt_Token_IsOpen(ct)) {
932
    GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN);
933
    rv=GWEN_Crypt_Token_Open(ct, 0, gid);
934
    if (rv) {
935
      DBG_INFO(AQHBCI_LOGDOMAIN,
936
               "Could not open crypt token for user \"%s\" (%d)",
937
               AB_User_GetUserId(u), rv);
938
      return rv;
939
    }
940
  }
941

    
942
  /* get context and key info */
943
  ctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(u), gid);
944
  if (ctx==NULL) {
945
    DBG_INFO(AQHBCI_LOGDOMAIN,
946
             "Context %d not found on crypt token [%s:%s]",
947
             AH_User_GetTokenContextId(u),
948
             GWEN_Crypt_Token_GetTypeName(ct),
949
             GWEN_Crypt_Token_GetTokenName(ct));
950
    return GWEN_ERROR_NOT_FOUND;
951
  }
952

    
953
  ek=AH_User_GetBankPubCryptKey(u);
954
  if (!ek) {
955
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Bank Public Key not downloaded, please get it!");
956
    GWEN_Gui_ProgressLog(0,
957
                         GWEN_LoggerLevel_Error,
958
                         I18N("The public key from the bank is not available, please download it. Aborting current dialog."));
959
    return GWEN_ERROR_INTERNAL;
960
  }
961

    
962
  switch (rxh_parameter->protocol) {
963
  case AH_CryptMode_Rdh:
964
    rv=GWEN_Padd_PaddWithAnsiX9_23(hmsg->buffer);
965
    if (rv) {
966
      DBG_INFO(AQHBCI_LOGDOMAIN, "Error padding message with ANSI X9.23 (%d)", rv);
967
      return rv;
968
    }
969

    
970
    /* create session key */
971
    sk=GWEN_Crypt_KeyDes3K_Generate(GWEN_Crypt_CryptMode_Cbc, 24, 2);
972
    sessionKeySize=16;
973
    if (sk==NULL) {
974
      DBG_INFO(AQHBCI_LOGDOMAIN, "Could not generate DES key");
975
      return GWEN_ERROR_INTERNAL;
976
    }
977
    break;
978
  case AH_CryptMode_Rah:
979
    rv=GWEN_Padd_PaddWithZka(hmsg->buffer);
980
    if (rv) {
981
      DBG_INFO(AQHBCI_LOGDOMAIN,
982
               "Error padding message with ZKA padding (%d)", rv);
983
      return rv;
984
    }
985

    
986
    /* create session key */
987
    sk=GWEN_Crypt_KeyAes256_Generate(GWEN_Crypt_CryptMode_Cbc, 32, 2);
988
    sessionKeySize=32;
989
    if (sk==NULL) {
990
      DBG_INFO(AQHBCI_LOGDOMAIN, "Could not generate AES-256 key");
991
      return GWEN_ERROR_INTERNAL;
992
    }
993
    break;
994
  default:
995
    DBG_INFO(AQHBCI_LOGDOMAIN, "Protocol not supported!");
996
    return GWEN_ERROR_INTERNAL;
997
  }
998
  /* encrypt message with that session key */
999
  mbuf=GWEN_Buffer_new(0, GWEN_Buffer_GetUsedBytes(hmsg->buffer), 0, 1);
1000
  l=GWEN_Buffer_GetUsedBytes(hmsg->buffer);
1001
  rv=GWEN_Crypt_Key_Encipher(sk,
1002
                             (uint8_t *)GWEN_Buffer_GetStart(hmsg->buffer),
1003
                             GWEN_Buffer_GetUsedBytes(hmsg->buffer),
1004
                             (uint8_t *)GWEN_Buffer_GetPosPointer(mbuf),
1005
                             &l);
1006
  if (rv<0) {
1007
    DBG_INFO(AQHBCI_LOGDOMAIN,
1008
             "Could not encipher with DES session key (%d)",
1009
             rv);
1010
    GWEN_Buffer_free(mbuf);
1011
    GWEN_Crypt_Key_free(sk);
1012
    return rv;
1013
  }
1014
  GWEN_Buffer_IncrementPos(mbuf, l);
1015
  GWEN_Buffer_AdjustUsedBytes(mbuf);
1016

    
1017

    
1018
  /* encrypt session key */
1019
  if (1) {
1020
    uint32_t elen;
1021
    GWEN_BUFFER *skbuf;
1022
    GWEN_CRYPT_PADDALGO *algo;
1023

    
1024
    skbuf=GWEN_Buffer_new(0, 512, 0, 1);
1025
    switch (rxh_parameter->protocol) {
1026
    case AH_CryptMode_Rdh:
1027
      GWEN_Buffer_InsertBytes(skbuf, (const char *) GWEN_Crypt_KeyDes3K_GetKeyDataPtr(sk), sessionKeySize);
1028
      break;
1029
    case AH_CryptMode_Rah:
1030
      GWEN_Buffer_InsertBytes(skbuf, (const char *) GWEN_Crypt_KeyAes256_GetKeyDataPtr(sk), sessionKeySize);
1031
      break;
1032
    default:
1033
      return GWEN_ERROR_INTERNAL;
1034
    }
1035
    GWEN_Buffer_Rewind(skbuf);
1036

    
1037
    switch (rxh_parameter->opmodCrypt) {
1038
    case AH_Opmode_Cbc:
1039
      algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_LeftZero);
1040
      break;
1041
    case AH_Opmode_Rsa_Pkcs1_v1_5:
1042
      algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_2);
1043
      break;
1044
    default:
1045
      return GWEN_ERROR_INTERNAL;
1046
    }
1047
    GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(ek));
1048
    /* padd according to given algo */
1049
    rv=GWEN_Padd_ApplyPaddAlgo(algo, skbuf);
1050
    GWEN_Crypt_PaddAlgo_free(algo);
1051
    if (rv) {
1052
      DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1053
      GWEN_Buffer_free(skbuf);
1054
      return rv;
1055
    }
1056

    
1057

    
1058
    elen=GWEN_Crypt_Key_GetKeySize(ek);
1059
    rv=GWEN_Crypt_Key_Encipher(ek,
1060
                               (const uint8_t *) GWEN_Buffer_GetStart(skbuf),
1061
                               GWEN_Crypt_Key_GetKeySize(ek), encKey, &elen);
1062

    
1063
    if (rv<0) {
1064
      DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1065
      GWEN_Buffer_free(mbuf);
1066
      GWEN_Buffer_free(skbuf);
1067
      GWEN_Crypt_Key_free(sk);
1068
      return rv;
1069
    }
1070
    encKeyLen=elen;
1071
    GWEN_Buffer_free(skbuf);
1072
  }
1073
  GWEN_Crypt_Key_free(sk);
1074

    
1075
  /* create crypt head */
1076
  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "CryptHead");
1077
  if (!node) {
1078
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptHead\" not found");
1079
    GWEN_Buffer_free(mbuf);
1080
    GWEN_Crypt_Key_free(sk);
1081
    return GWEN_ERROR_INTERNAL;
1082
  }
1083

    
1084
  /* create CryptHead */
1085
  cfg=GWEN_DB_Group_new("crypthead");
1086
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", 998);
1087

    
1088
  rv=AH_MsgRxh_PrepareCryptoSeg(hmsg, u, rxh_parameter, GWEN_Crypt_Key_GetKeyNumber(ek), GWEN_Crypt_Key_GetKeyVersion(ek),
1089
                                NULL, cfg, 1, 0);
1090
  if (rv) {
1091
    DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1092
    GWEN_DB_Group_free(cfg);
1093
    GWEN_Buffer_free(mbuf);
1094
    return rv;
1095
  }
1096

    
1097
  /* store system id */
1098
  if (hmsg->noSysId) {
1099
    GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
1100
                         "SecDetails/SecId", "0");
1101
  }
1102
  else {
1103
    /* store CID if we use a card */
1104
    const uint8_t *cidData;
1105
    uint32_t cidLen=GWEN_Crypt_Token_Context_GetCidLen(ctx);
1106
    cidData=GWEN_Crypt_Token_Context_GetCidPtr(ctx);
1107
    if (cidLen > 0 && cidData != NULL) {
1108
      GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/CID", cidData, cidLen);
1109
    }
1110

    
1111
    p=AH_User_GetSystemId(u);
1112
    if (p==NULL) {
1113
      p=GWEN_Crypt_Token_Context_GetSystemId(ctx);
1114
    }
1115
    if (p) {
1116
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p);
1117
    }
1118
    else {
1119
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", "0");
1120
    }
1121

    
1122
  }
1123

    
1124
  /* store encrypted message key */
1125
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "CryptAlgo/MsgKey", encKey, encKeyLen);
1126

    
1127
  hbuf=GWEN_Buffer_new(0, 256+GWEN_Buffer_GetUsedBytes(mbuf), 0, 1);
1128
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
1129
  if (rv) {
1130
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptHead (%d)", rv);
1131
    GWEN_Buffer_free(hbuf);
1132
    GWEN_DB_Group_free(cfg);
1133
    GWEN_Buffer_free(mbuf);
1134
    return rv;
1135
  }
1136
  GWEN_DB_Group_free(cfg);
1137

    
1138
  /* create cryptdata */
1139
  cfg=GWEN_DB_Group_new("cryptdata");
1140
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT, "head/seq", 999);
1141
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT, "cryptdata", GWEN_Buffer_GetStart(mbuf),
1142
                      GWEN_Buffer_GetUsedBytes(mbuf));
1143
  GWEN_Buffer_free(mbuf);
1144

    
1145
  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e, "SEG", "id", 0, "CryptData");
1146
  if (!node) {
1147
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptData\"not found");
1148
    GWEN_Buffer_free(hbuf);
1149
    GWEN_DB_Group_free(cfg);
1150
    return -1;
1151
  }
1152
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
1153
  if (rv) {
1154
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptData (%d)", rv);
1155
    GWEN_Buffer_free(hbuf);
1156
    GWEN_DB_Group_free(cfg);
1157
    return rv;
1158
  }
1159

    
1160
  /* replace existing buffer by encrypted one */
1161
  GWEN_Buffer_free(hmsg->buffer);
1162
  hmsg->buffer=hbuf;
1163
  GWEN_DB_Group_free(cfg);
1164

    
1165
  return 0;
1166
}
1167

    
1168
int AH_Msg_DecryptRxh(AH_MSG *hmsg, GWEN_DB_NODE *gr)
1169
{
1170
  AH_HBCI *h;
1171
  GWEN_BUFFER *mbuf;
1172
  uint32_t l;
1173
  int rv;
1174
  const uint8_t *p;
1175
  GWEN_MSGENGINE *e;
1176
  AB_USER *u;
1177
  const char *peerId;
1178
  //  uint32_t uFlags;
1179
  GWEN_CRYPT_TOKEN *ct;
1180
  const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1181
  const GWEN_CRYPT_TOKEN_KEYINFO *ki;
1182
  uint32_t keyId;
1183
  GWEN_CRYPT_KEY *sk=NULL;
1184
  uint8_t decKey[AH_MSGRXH_MAXKEYBUF+64];
1185
  GWEN_DB_NODE *nhead=NULL;
1186
  GWEN_DB_NODE *ndata=NULL;
1187
  const char *crypterId;
1188
  uint32_t gid;
1189
  RXH_PARAMETER *rxh_parameter;
1190
  int rxhVersion;
1191
  uint8_t decKeySize;
1192

    
1193

    
1194
  u=AH_Dialog_GetDialogOwner(hmsg->dialog);
1195
  /* get correct parameters */
1196
  rxhVersion = AH_User_GetRdhType(u);
1197
  switch (AH_User_GetCryptMode(u)) {
1198
  case AH_CryptMode_Rdh:
1199
    rxh_parameter=rdh_parameter[rxhVersion];
1200
    if (rxh_parameter == NULL) {
1201
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
1202
      return AB_ERROR_NOT_INIT;
1203
    }
1204
    break;
1205
  case AH_CryptMode_Rah:
1206
    rxh_parameter=rah_parameter[rxhVersion];
1207
    if (rxh_parameter == NULL) {
1208
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
1209
      return AB_ERROR_NOT_INIT;
1210
    }
1211
    break;
1212
  default:
1213
    return GWEN_ERROR_INTERNAL;
1214
  }
1215

    
1216
  assert(hmsg);
1217
  h=AH_Dialog_GetHbci(hmsg->dialog);
1218
  assert(h);
1219
  e=AH_Dialog_GetMsgEngine(hmsg->dialog);
1220
  assert(e);
1221
  //GWEN_MsgEngine_SetMode(e, "rdh");
1222
  GWEN_MsgEngine_SetMode(e, AH_CryptMode_toString(rxh_parameter->protocol));
1223
  gid=0;
1224

    
1225

    
1226
  //  uFlags=AH_User_GetFlags(u);
1227

    
1228
  peerId=AH_User_GetPeerId(u);
1229
  if (!peerId || *peerId==0)
1230
    peerId=AB_User_GetUserId(u);
1231

    
1232
  /* get crypt token of signer */
1233
  rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
1234
                              AH_User_GetTokenType(u),
1235
                              AH_User_GetTokenName(u),
1236
                              &ct);
1237
  if (rv) {
1238
    DBG_INFO(AQHBCI_LOGDOMAIN,
1239
             "Could not get crypt token for user \"%s\" (%d)",
1240
             AB_User_GetUserId(u), rv);
1241
    return rv;
1242
  }
1243

    
1244
  /* open CryptToken if necessary */
1245
  if (!GWEN_Crypt_Token_IsOpen(ct)) {
1246
    GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN);
1247
    rv=GWEN_Crypt_Token_Open(ct, 0, gid);
1248
    if (rv) {
1249
      DBG_INFO(AQHBCI_LOGDOMAIN,
1250
               "Could not open crypt token for user \"%s\" (%d)",
1251
               AB_User_GetUserId(u), rv);
1252
      return rv;
1253
    }
1254
  }
1255

    
1256
  /* get context and key info */
1257
  ctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(u), gid);
1258
  if (ctx==NULL) {
1259
    DBG_INFO(AQHBCI_LOGDOMAIN,
1260
             "Context %d not found on crypt token [%s:%s]",
1261
             AH_User_GetTokenContextId(u),
1262
             GWEN_Crypt_Token_GetTypeName(ct),
1263
             GWEN_Crypt_Token_GetTokenName(ct));
1264
    return GWEN_ERROR_NOT_FOUND;
1265
  }
1266

    
1267
  keyId=GWEN_Crypt_Token_Context_GetDecipherKeyId(ctx);
1268
  ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, gid);
1269
  if (ki==NULL) {
1270
    DBG_INFO(AQHBCI_LOGDOMAIN,
1271
             "Keyinfo %04x not found on crypt token [%s:%s]",
1272
             keyId,
1273
             GWEN_Crypt_Token_GetTypeName(ct),
1274
             GWEN_Crypt_Token_GetTokenName(ct));
1275
    return GWEN_ERROR_NOT_FOUND;
1276
  }
1277

    
1278
  /* get encrypted session key */
1279
  nhead=GWEN_DB_GetGroup(gr,
1280
                         GWEN_DB_FLAGS_DEFAULT |
1281
                         GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1282
                         "CryptHead");
1283
  if (!nhead) {
1284
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt head");
1285
    return GWEN_ERROR_BAD_DATA;
1286
  }
1287

    
1288
  ndata=GWEN_DB_GetGroup(gr,
1289
                         GWEN_DB_FLAGS_DEFAULT |
1290
                         GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1291
                         "CryptData");
1292
  if (!ndata) {
1293
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt data");
1294
    return GWEN_ERROR_BAD_DATA;
1295
  }
1296

    
1297
  crypterId=GWEN_DB_GetCharValue(nhead, "key/userId", 0, I18N("unknown"));
1298

    
1299
  p=GWEN_DB_GetBinValue(nhead, "CryptAlgo/MsgKey", 0, 0, 0, &l);
1300
  if (p && l) {
1301
    uint32_t elen;
1302
    GWEN_CRYPT_PADDALGO *algo;
1303
    uint8_t encKey[AH_MSGRXH_MAXKEYBUF+64];
1304
    int ksize;
1305

    
1306
    ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki);
1307
    if (ksize<l) {
1308
      DBG_WARN(AQHBCI_LOGDOMAIN, "Keyinfo keysize is smaller than size of transmitted key, adjusting");
1309
      ksize=l;
1310
    }
1311
    assert(ksize<=AH_MSGRXH_MAXKEYBUF);
1312

    
1313
    /* fill encoded key with 0 to the total length of our private key */
1314
    memset(encKey, 0, sizeof(encKey));
1315
    memmove(encKey+(ksize-l), p, l);
1316

    
1317
    algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None);
1318
    elen=sizeof(decKey);
1319
    rv=GWEN_Crypt_Token_Decipher(ct, keyId, algo, encKey, ksize, decKey, &elen, gid);
1320
    GWEN_Crypt_PaddAlgo_free(algo);
1321
    if (rv) {
1322
      DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
1323
      return rv;
1324
    }
1325

    
1326
    switch (rxh_parameter->protocol) {
1327
    case AH_CryptMode_Rdh:
1328
      decKeySize=16;
1329
      break;
1330
    case AH_CryptMode_Rah:
1331
      decKeySize=32;
1332
      break;
1333
    default:
1334
      return GWEN_ERROR_INTERNAL;
1335
    }
1336
    /* unpadd and generate key */
1337
    p=decKey+(elen-decKeySize);
1338
    switch (rxh_parameter->protocol) {
1339
    case AH_CryptMode_Rdh:
1340
      sk=GWEN_Crypt_KeyDes3K_fromData(GWEN_Crypt_CryptMode_Cbc, 24, p, 16);
1341
      break;
1342
    case AH_CryptMode_Rah:
1343
      sk=GWEN_Crypt_KeyAes256_fromData(GWEN_Crypt_CryptMode_Cbc, 32, p, 32);
1344
      break;
1345
    default:
1346
      return GWEN_ERROR_INTERNAL;
1347
    }
1348
    if (sk==NULL) {
1349
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not create DES key from data");
1350
      return GWEN_ERROR_BAD_DATA;
1351
    }
1352
  }
1353
  else {
1354
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Missing message key");
1355
    return GWEN_ERROR_BAD_DATA;
1356
  }
1357

    
1358
  /* get encrypted data */
1359
  p=GWEN_DB_GetBinValue(ndata, "CryptData", 0, 0, 0, &l);
1360
  if (!p || !l) {
1361
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt data");
1362
    GWEN_Crypt_Key_free(sk);
1363
    return GWEN_ERROR_BAD_DATA;
1364
  }
1365

    
1366
  /* decipher message with session key */
1367
  mbuf=GWEN_Buffer_new(0, l, 0, 1);
1368
  rv=GWEN_Crypt_Key_Decipher(sk,
1369
                             (const uint8_t *)p, l,
1370
                             (uint8_t *)GWEN_Buffer_GetPosPointer(mbuf),
1371
                             &l);
1372
  GWEN_Crypt_Key_free(sk);
1373
  if (rv<0) {
1374
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not decipher with DES session key (%d)", rv);
1375
    GWEN_Buffer_free(mbuf);
1376
    return rv;
1377
  }
1378
  GWEN_Buffer_IncrementPos(mbuf, l);
1379
  GWEN_Buffer_AdjustUsedBytes(mbuf);
1380

    
1381
  /* unpadd message */
1382
  switch (rxh_parameter->protocol) {
1383
  case AH_CryptMode_Rdh:
1384
    rv=GWEN_Padd_UnpaddWithAnsiX9_23(mbuf);
1385
    break;
1386
  case AH_CryptMode_Rah:
1387
    rv=GWEN_Padd_UnpaddWithZka(mbuf);
1388
    break;
1389
  default:
1390
    return GWEN_ERROR_INTERNAL;
1391
  }
1392
  if (rv) {
1393
    DBG_INFO(AQHBCI_LOGDOMAIN,
1394
             "Error unpadding message with ANSI X9.23 (%d)", rv);
1395
    GWEN_Buffer_free(mbuf);
1396
    return rv;
1397
  }
1398

    
1399
  /* store crypter id */
1400
  AH_Msg_SetCrypterId(hmsg, crypterId);
1401

    
1402
  /* store new buffer inside message */
1403
  GWEN_Buffer_free(hmsg->origbuffer);
1404
  hmsg->origbuffer=hmsg->buffer;
1405
  GWEN_Buffer_Rewind(mbuf);
1406
  hmsg->buffer=mbuf;
1407

    
1408
  return 0;
1409
}
1410

    
1411
static
1412
int AH_MsgRxh__Verify_Internal(GWEN_CRYPT_KEY *k,
1413
                               GWEN_CRYPT_PADDALGO *a,
1414
                               const uint8_t *pInData,
1415
                               uint32_t inLen,
1416
                               const uint8_t *pSignatureData,
1417
                               uint32_t signatureLen)
1418
{
1419

    
1420
  int rv;
1421
  GWEN_CRYPT_PADDALGOID aid;
1422

    
1423
  aid=GWEN_Crypt_PaddAlgo_GetId(a);
1424

    
1425
  if (aid==GWEN_Crypt_PaddAlgoId_Iso9796_2 ||
1426
      aid==GWEN_Crypt_PaddAlgoId_Pkcs1_2 ||
1427
      aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1428
    GWEN_BUFFER *tbuf;
1429
    uint32_t l;
1430

    
1431
    /* these algos add random numbers, we must use encrypt fn here and
1432
     * compare the decrypted and unpadded data with the source data */
1433
    tbuf=GWEN_Buffer_new(0, signatureLen+16, 0, 0);
1434
    l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
1435
    rv=GWEN_Crypt_Key_Encipher(k,
1436
                               pSignatureData, signatureLen,
1437
                               (uint8_t *)GWEN_Buffer_GetStart(tbuf),
1438
                               &l);
1439
    if (rv<0) {
1440
      DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1441
      GWEN_Buffer_free(tbuf);
1442
      return rv;
1443
    }
1444
    GWEN_Buffer_IncrementPos(tbuf, l);
1445
    GWEN_Buffer_AdjustUsedBytes(tbuf);
1446

    
1447
    if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1448
      int nbits;
1449
      uint8_t *modPtr;
1450
      /* nasty hack, do something better later */
1451
      uint8_t modBuffer[AH_MSGRXH_MAXKEYBUF];
1452
      uint32_t modLen;
1453
      GWEN_MDIGEST *md;
1454

    
1455
      modPtr=&modBuffer[0];
1456
      modLen=AH_MSGRXH_MAXKEYBUF;
1457
      /* calculate real number of bits */
1458
      rv=GWEN_Crypt_KeyRsa_GetModulus(k, modPtr, &modLen);
1459

    
1460
      nbits=modLen*8;
1461
      while (modLen && *modPtr==0) {
1462
        nbits-=8;
1463
        modLen--;
1464
        modPtr++;
1465
      }
1466
      if (modLen) {
1467
        uint8_t b=*modPtr;
1468
        int i;
1469
        uint8_t mask=0x80;
1470

    
1471
        for (i=0; i<8; i++) {
1472
          if (b & mask)
1473
            break;
1474
          nbits--;
1475
          mask>>=1;
1476
        }
1477
      }
1478

    
1479
      if (nbits==0) {
1480
        DBG_ERROR(GWEN_LOGDOMAIN, "Empty modulus");
1481
        GWEN_Buffer_free(tbuf);
1482
        return GWEN_ERROR_GENERIC;
1483
      }
1484

    
1485
      md=GWEN_MDigest_Sha256_new();
1486
      rv=GWEN_Padd_VerifyPkcs1Pss((const uint8_t *) GWEN_Buffer_GetStart(tbuf),
1487
                                  GWEN_Buffer_GetUsedBytes(tbuf),
1488
                                  nbits,
1489
                                  pInData, inLen,
1490
                                  inLen,
1491
                                  md);
1492
      GWEN_MDigest_free(md);
1493
      if (rv<0) {
1494
        DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
1495
        GWEN_Buffer_free(tbuf);
1496
        return rv;
1497
      }
1498
    }
1499
    else {
1500
      rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
1501
      if (rv<0) {
1502
        DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1503
        GWEN_Buffer_free(tbuf);
1504
        return rv;
1505
      }
1506
      l=GWEN_Buffer_GetUsedBytes(tbuf);
1507

    
1508
      if (l!=inLen) {
1509
        DBG_ERROR(GWEN_LOGDOMAIN, "Signature length doesn't match");
1510
        GWEN_Buffer_free(tbuf);
1511
        return GWEN_ERROR_VERIFY;
1512
      }
1513
      if (memcmp(pInData, GWEN_Buffer_GetStart(tbuf), l)!=0) {
1514
        DBG_ERROR(GWEN_LOGDOMAIN, "Signature doesn't match:");
1515
        GWEN_Buffer_free(tbuf);
1516
        return GWEN_ERROR_VERIFY;
1517
      }
1518
    }
1519
    GWEN_Buffer_free(tbuf);
1520
  }
1521
  else {
1522
    GWEN_BUFFER *srcBuf;
1523

    
1524
    /* copy to a buffer for padding */
1525
    srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1526
    GWEN_Buffer_AppendBytes(srcBuf, (const char *)pInData, inLen);
1527

    
1528
    /* padd according to given algo */
1529
    rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1530
    if (rv) {
1531
      DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1532
      GWEN_Buffer_free(srcBuf);
1533
      return rv;
1534
    }
1535

    
1536
    /* verify with key */
1537
    rv=GWEN_Crypt_Key_Verify(k,
1538
                             (const uint8_t *)GWEN_Buffer_GetStart(srcBuf),
1539
                             GWEN_Buffer_GetUsedBytes(srcBuf),
1540
                             pSignatureData,
1541
                             signatureLen);
1542
    GWEN_Buffer_free(srcBuf);
1543
    if (rv) {
1544
      DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1545
      return rv;
1546
    }
1547
  }
1548

    
1549

    
1550

    
1551
  return 0;
1552
}
1553

    
1554

    
1555

    
1556
int AH_Msg_VerifyRxh(AH_MSG *hmsg, GWEN_DB_NODE *gr)
1557
{
1558
  AH_HBCI *h;
1559
  GWEN_LIST *sigheads;
1560
  GWEN_LIST *sigtails;
1561
  GWEN_DB_NODE *n;
1562
  int nonSigHeads;
1563
  int nSigheads;
1564
  unsigned int dataBegin;
1565
  char *dataStart;
1566
  unsigned int dataLength;
1567
  unsigned int i;
1568
  AB_USER *u;
1569
  GWEN_CRYPT_TOKEN *ct;
1570
  const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1571
  int ksize;
1572
  int rv;
1573
  uint32_t gid;
1574
  uint32_t hashLen;
1575
  AH_HASH_ALG hashAlg;
1576
  AH_OPMODE opMode;
1577
  uint8_t rxhVersion;
1578
  RXH_PARAMETER *rxh_parameter;
1579
  GWEN_CRYPT_KEY *bankPubSignKey;
1580

    
1581
  /* get correct parameters */
1582
  u=AH_Dialog_GetDialogOwner(hmsg->dialog);
1583
  assert(u);
1584

    
1585
  rxhVersion = AH_User_GetRdhType(u);
1586
  switch (AH_User_GetCryptMode(u)) {
1587
  case AH_CryptMode_Rdh:
1588
    rxh_parameter=rdh_parameter[rxhVersion];
1589
    if (rxh_parameter == NULL) {
1590
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
1591
      return AB_ERROR_NOT_INIT;
1592
    }
1593
    break;
1594
  case AH_CryptMode_Rah:
1595
    rxh_parameter=rah_parameter[rxhVersion];
1596
    if (rxh_parameter == NULL) {
1597
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Profile RDH%d is not supported!", rxhVersion);
1598
      return AB_ERROR_NOT_INIT;
1599
    }
1600
    break;
1601
  default:
1602
    return GWEN_ERROR_INTERNAL;
1603
  }
1604
  assert(hmsg);
1605
  h=AH_Dialog_GetHbci(hmsg->dialog);
1606
  assert(h);
1607

    
1608

    
1609
  gid=0;
1610

    
1611

    
1612
  hashAlg = rxh_parameter->hashAlgS;
1613
  opMode= rxh_parameter->opmodSignS;
1614

    
1615
  /* get crypt token of signer */
1616
  rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
1617
                              AH_User_GetTokenType(u),
1618
                              AH_User_GetTokenName(u),
1619
                              &ct);
1620
  if (rv) {
1621
    DBG_INFO(AQHBCI_LOGDOMAIN,
1622
             "Could not get crypt token for user \"%s\" (%d)",
1623
             AB_User_GetUserId(u), rv);
1624
    return rv;
1625
  }
1626

    
1627
  /* open CryptToken if necessary */
1628
  if (!GWEN_Crypt_Token_IsOpen(ct)) {
1629
    GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN);
1630
    rv=GWEN_Crypt_Token_Open(ct, 0, gid);
1631
    if (rv) {
1632
      DBG_INFO(AQHBCI_LOGDOMAIN,
1633
               "Could not open crypt token for user \"%s\" (%d)",
1634
               AB_User_GetUserId(u), rv);
1635
      return rv;
1636
    }
1637
  }
1638

    
1639
  /* get context and key info */
1640
  ctx=GWEN_Crypt_Token_GetContext(ct,
1641
                                  AH_User_GetTokenContextId(u),
1642
                                  gid);
1643
  if (ctx==NULL) {
1644
    DBG_INFO(AQHBCI_LOGDOMAIN,
1645
             "Context %d not found on crypt token [%s:%s]",
1646
             AH_User_GetTokenContextId(u),
1647
             GWEN_Crypt_Token_GetTypeName(ct),
1648
             GWEN_Crypt_Token_GetTokenName(ct));
1649
    return GWEN_ERROR_NOT_FOUND;
1650
  }
1651

    
1652
  /* let's go */
1653
  sigheads=GWEN_List_new();
1654

    
1655
  /* enumerate signature heads */
1656
  nonSigHeads=0;
1657
  nSigheads=0;
1658
  n=GWEN_DB_GetFirstGroup(gr);
1659
  while (n) {
1660
    if (strcasecmp(GWEN_DB_GroupName(n), "SigHead")==0) {
1661
      /* found a signature head */
1662
      if (nonSigHeads) {
1663
        DBG_ERROR(AQHBCI_LOGDOMAIN,
1664
                  "Found some unsigned parts at the beginning");
1665
        GWEN_List_free(sigheads);
1666
        return GWEN_ERROR_BAD_DATA;
1667
      }
1668
      GWEN_List_PushBack(sigheads, n);
1669
      nSigheads++;
1670
    }
1671
    else if (strcasecmp(GWEN_DB_GroupName(n), "MsgHead")!=0) {
1672
      if (nSigheads)
1673
        break;
1674
      nonSigHeads++;
1675
    }
1676
    n=GWEN_DB_GetNextGroup(n);
1677
  } /* while */
1678

    
1679
  if (!n) {
1680
    if (nSigheads) {
1681
      DBG_ERROR(AQHBCI_LOGDOMAIN,
1682
                "Found Signature heads but no other segments");
1683
      GWEN_List_free(sigheads);
1684
      return GWEN_ERROR_BAD_DATA;
1685
    }
1686
    DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signatures");
1687
    GWEN_List_free(sigheads);
1688
    return 0;
1689
  }
1690

    
1691
  /* only now we need the verify key */
1692
  /* the public sign key is not on the RDH card, but exchanged in the
1693
   * initial key exchange and resides in the user information
1694
   */
1695
  bankPubSignKey=AH_User_GetBankPubSignKey(u);
1696
  if (bankPubSignKey==NULL) {
1697
    /* this may be the first message with the public keys from the bank server,
1698
     * if its signed, the key is transmitted in the message and my be verified with
1699
     * different methods ([HBCI] B.3.1.3, case A):
1700
     * * the zka card contains the hash in EF_NOTEPAD
1701
     * * a certificate is sent with the message to verify
1702
     * * INI letter
1703
     *
1704
     * check message for "S"-KEy, look up if there is a hash on the chip card
1705
     */
1706
    bankPubSignKey=AH_MsgRxh_VerifyInitialSignKey(ct, ctx, u, gr);
1707

    
1708
    if (bankPubSignKey==NULL) {
1709
      DBG_INFO(AQHBCI_LOGDOMAIN,
1710
               "No public bank sign key for user [%s]",
1711
               AB_User_GetUserName(u));
1712
      return GWEN_ERROR_NOT_FOUND;
1713
    }
1714
  }
1715

    
1716
  ksize=GWEN_Crypt_Key_GetKeySize(bankPubSignKey);
1717
  assert(ksize<=AH_MSGRXH_MAXKEYBUF);
1718

    
1719
  /* store begin of signed data */
1720
  dataBegin=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0);
1721
  if (!dataBegin) {
1722
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No position specifications in segment");
1723
    GWEN_List_free(sigheads);
1724
    return GWEN_ERROR_BAD_DATA;
1725
  }
1726

    
1727
  /* now get first signature tail */
1728
  while (n) {
1729
    if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")==0) {
1730
      unsigned int currpos;
1731

    
1732
      /* found a signature tail */
1733
      currpos=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0);
1734
      if (!currpos || dataBegin>currpos) {
1735
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Bad position specification in Signature tail");
1736
        GWEN_List_free(sigheads);
1737
        return GWEN_ERROR_BAD_DATA;
1738
      }
1739
      dataLength=currpos-dataBegin;
1740
      break;
1741
    }
1742
    n=GWEN_DB_GetNextGroup(n);
1743
  } /* while */
1744

    
1745
  if (!n) {
1746
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No signature tail found");
1747
    GWEN_List_free(sigheads);
1748
    return GWEN_ERROR_BAD_DATA;
1749
  }
1750

    
1751
  sigtails=GWEN_List_new();
1752
  while (n) {
1753
    if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")!=0)
1754
      break;
1755
    GWEN_List_PushBack(sigtails, n);
1756
    n=GWEN_DB_GetNextGroup(n);
1757
  } /* while */
1758

    
1759
  if (!n) {
1760
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Message tail expected");
1761
    GWEN_List_free(sigheads);
1762
    GWEN_List_free(sigtails);
1763
    return GWEN_ERROR_BAD_DATA;
1764
  }
1765

    
1766
  if (strcasecmp(GWEN_DB_GroupName(n), "MsgTail")!=0) {
1767
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (msg tail expected)");
1768
    GWEN_List_free(sigheads);
1769
    GWEN_List_free(sigtails);
1770
    return GWEN_ERROR_BAD_DATA;
1771
  }
1772

    
1773
  n=GWEN_DB_GetNextGroup(n);
1774
  if (n) {
1775
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (end expected)");
1776
    GWEN_List_free(sigheads);
1777
    GWEN_List_free(sigtails);
1778
    return GWEN_ERROR_BAD_DATA;
1779
  }
1780

    
1781
  if (GWEN_List_GetSize(sigheads)!=
1782
      GWEN_List_GetSize(sigtails)) {
1783
    DBG_ERROR(AQHBCI_LOGDOMAIN,
1784
              "Number of signature heads (%d) does not match "
1785
              "number of signature tails (%d)",
1786
              GWEN_List_GetSize(sigheads),
1787
              GWEN_List_GetSize(sigtails));
1788
    GWEN_List_free(sigheads);
1789
    GWEN_List_free(sigtails);
1790
    return GWEN_ERROR_BAD_DATA;
1791
  }
1792

    
1793
  /* ok, now verify all signatures */
1794
  dataStart=GWEN_Buffer_GetStart(hmsg->buffer)+dataBegin;
1795
  for (i=0; i< GWEN_List_GetSize(sigtails); i++) {
1796
    GWEN_DB_NODE *sighead;
1797
    GWEN_DB_NODE *sigtail;
1798
    const uint8_t *p;
1799
    uint32_t l;
1800
    int rv;
1801
    uint8_t hash[32];
1802
    const char *signerId;
1803

    
1804
    /* get signature tail */
1805
    sigtail=(GWEN_DB_NODE *)GWEN_List_GetBack(sigtails);
1806

    
1807
    /* get corresponding signature head */
1808
    sighead=(GWEN_DB_NODE *)GWEN_List_GetFront(sigheads);
1809

    
1810
    if (!sighead || !sigtail) {
1811
      DBG_ERROR(AQHBCI_LOGDOMAIN,
1812
                "No signature head/tail left (internal error)");
1813
      GWEN_List_free(sigheads);
1814
      GWEN_List_free(sigtails);
1815
      return GWEN_ERROR_INTERNAL;
1816
    }
1817

    
1818
    GWEN_List_PopBack(sigtails);
1819
    GWEN_List_PopFront(sigheads);
1820

    
1821
    signerId=GWEN_DB_GetCharValue(sighead, "key/userid", 0,
1822
                                  I18N("unknown"));
1823

    
1824
    /* some checks */
1825
    if (strcasecmp(GWEN_DB_GetCharValue(sighead, "ctrlref", 0, ""),
1826
                   GWEN_DB_GetCharValue(sigtail, "ctrlref", 0, ""))!=0) {
1827
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Non-matching signature tail");
1828
      GWEN_List_free(sigheads);
1829
      GWEN_List_free(sigtails);
1830
      return GWEN_ERROR_BAD_DATA;
1831
    }
1832

    
1833
    /* hash signature head and data */
1834
    if (1) {
1835
      GWEN_MDIGEST *md;
1836

    
1837
      /* hash sighead + data */
1838
      p=(const uint8_t *)GWEN_Buffer_GetStart(hmsg->buffer);
1839
      p+=GWEN_DB_GetIntValue(sighead,
1840
                             "segment/pos",
1841
                             0,
1842
                             0);
1843
      l=GWEN_DB_GetIntValue(sighead,
1844
                            "segment/length",
1845
                            0,
1846
                            0);
1847
      switch (hashAlg) {
1848
      case AH_HashAlg_Sha1:
1849
        md=GWEN_MDigest_Sha1_new();
1850
        break;
1851
      case AH_HashAlg_Sha256:
1852
      case AH_HashAlg_Sha256Sha256:
1853
        md=GWEN_MDigest_Sha256_new();
1854
        break;
1855
      case AH_HashAlg_Ripmed160:
1856
        md=GWEN_MDigest_Rmd160_new();
1857
        break;
1858
      default:
1859
        md=NULL;
1860
      }
1861

    
1862
      /* first round */
1863
      rv=GWEN_MDigest_Begin(md);
1864
      if (rv==0)
1865
        /* digest signature head */
1866
        rv=GWEN_MDigest_Update(md, p, l);
1867
      if (rv==0)
1868
        /* digest data */
1869
        rv=GWEN_MDigest_Update(md, (const uint8_t *)dataStart, dataLength);
1870
      if (rv==0)
1871
        rv=GWEN_MDigest_End(md);
1872
      if (rv<0) {
1873
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
1874
        GWEN_MDigest_free(md);
1875
        GWEN_List_free(sigheads);
1876
        GWEN_List_free(sigtails);
1877
        return rv;
1878
      }
1879
      memmove(hash,
1880
              GWEN_MDigest_GetDigestPtr(md),
1881
              GWEN_MDigest_GetDigestSize(md));
1882

    
1883
      /* second round */
1884
      if (hashAlg==AH_HashAlg_Sha256Sha256) {
1885
        uint8_t hash1[32];
1886
        memmove(hash1,
1887
                hash,
1888
                GWEN_MDigest_GetDigestSize(md));
1889
        rv=GWEN_MDigest_Begin(md);
1890
        if (rv==0)
1891
          /* digest signature head */
1892
          rv=GWEN_MDigest_Update(md, hash1, sizeof(hash1));
1893
        if (rv==0)
1894
          rv=GWEN_MDigest_End(md);
1895
        if (rv<0) {
1896
          DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
1897
          GWEN_MDigest_free(md);
1898
          GWEN_List_free(sigheads);
1899
          GWEN_List_free(sigtails);
1900
          return rv;
1901
        }
1902
        memmove(hash,
1903
                GWEN_MDigest_GetDigestPtr(md),
1904
                GWEN_MDigest_GetDigestSize(md));
1905
      }
1906
      hashLen=GWEN_MDigest_GetDigestSize(md);
1907
      GWEN_MDigest_free(md);
1908
    }
1909

    
1910
    /* verify signature */
1911
    p=GWEN_DB_GetBinValue(sigtail, "signature", 0, 0, 0, &l);
1912

    
1913
    if (p && l) {
1914

    
1915
      GWEN_CRYPT_PADDALGO *algo;
1916

    
1917
      switch (opMode) {
1918
      case AH_Opmode_Iso9796_1:
1919
        algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_1A4);
1920
        GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1921
        break;
1922

    
1923
      case AH_Opmode_Iso9796_2:
1924
        algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2);
1925
        GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1926
        break;
1927

    
1928
      case AH_Opmode_Rsa_Pkcs1_v1_5:
1929
        algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_2);
1930
        GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1931
        break;
1932

    
1933
      case AH_Opmode_Rsa_Pss:
1934
        algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256);
1935
        GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Key_GetKeySize(bankPubSignKey));
1936
        break;
1937
      default:
1938
        return GWEN_ERROR_INTERNAL;
1939
      }
1940

    
1941
      rv=AH_MsgRxh__Verify_Internal(bankPubSignKey, algo,
1942
                                    hash, hashLen, p, l);
1943
      GWEN_Crypt_PaddAlgo_free(algo);
1944

    
1945
      if (rv) {
1946
        if (rv==GWEN_ERROR_NO_KEY) {
1947
          DBG_ERROR(AQHBCI_LOGDOMAIN,
1948
                    "Unable to verify signature of user \"%s\" (no key)",
1949
                    signerId);
1950
          GWEN_Gui_ProgressLog(gid,
1951
                               GWEN_LoggerLevel_Error,
1952
                               I18N("Unable to verify signature (no key)"));
1953
        }
1954
        else {
1955
          GWEN_BUFFER *tbuf;
1956

    
1957
          tbuf=GWEN_Buffer_new(0, hashLen, 0, 1);
1958
          if (rv==GWEN_ERROR_VERIFY) {
1959
            DBG_ERROR(AQHBCI_LOGDOMAIN,
1960
                      "Invalid signature of user \"%s\"", signerId);
1961
            GWEN_Gui_ProgressLog(gid,
1962
                                 GWEN_LoggerLevel_Error,
1963
                                 I18N("Invalid signature!!!"));
1964
            GWEN_Buffer_AppendString(tbuf, "!");
1965
          }
1966
          else {
1967
            GWEN_Gui_ProgressLog(gid,
1968
                                 GWEN_LoggerLevel_Error,
1969
                                 I18N("Could not verify signature"));
1970
            DBG_ERROR(AQHBCI_LOGDOMAIN,
1971
                      "Could not verify data with medium of user \"%s\" (%d)",
1972
                      AB_User_GetUserId(u), rv);
1973
            GWEN_Buffer_AppendString(tbuf, "?");
1974
          }
1975

    
1976
          GWEN_Buffer_AppendString(tbuf, signerId);
1977
          AH_Msg_AddSignerId(hmsg, GWEN_Buffer_GetStart(tbuf));
1978
          GWEN_Buffer_free(tbuf);
1979
        }
1980
      }
1981
      else {
1982
        DBG_INFO(AQHBCI_LOGDOMAIN, "Message signed by \"%s\"", signerId);
1983
        AH_Msg_AddSignerId(hmsg, signerId);
1984
      }
1985
    }
1986
    else {
1987
      DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signature");
1988
      GWEN_List_free(sigheads);
1989
      GWEN_List_free(sigtails);
1990
      return GWEN_ERROR_BAD_DATA;
1991
    }
1992

    
1993
    DBG_DEBUG(AQHBCI_LOGDOMAIN, "Verification done");
1994
  } /* for */
1995

    
1996
  GWEN_List_free(sigheads);
1997
  GWEN_List_free(sigtails);
1998
  return 0;
1999
}
2000