1 /***************************************************************************
2 begin : Sun Oct 27 2019
3 copyright : (C) 2019 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * This file is part of the project "AqBanking". *
8 * Please see toplevel file COPYING of that project for license details. *
9 ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15 #include "session/hbci/s_verify_hbci.h"
16 #include "session/s_decode.h"
17 #include "session/cryptparams.h"
18 #include "parser/parser.h"
19
20 #include <gwenhywfar/misc.h>
21 #include <gwenhywfar/debug.h>
22 #include <gwenhywfar/text.h>
23 #include <gwenhywfar/mdigest.h>
24 #include <gwenhywfar/paddalgo.h>
25
26 #include <time.h>
27
28
29
30 /* ------------------------------------------------------------------------------------------------
31 * forward declarations
32 * ------------------------------------------------------------------------------------------------
33 */
34
35
36
37 /* ------------------------------------------------------------------------------------------------
38 * implementations
39 * ------------------------------------------------------------------------------------------------
40 */
41
42
43
AQFINTS_Session_VerifySegmentHbci(AQFINTS_SESSION * sess,AQFINTS_MESSAGE * message,const AQFINTS_KEYDESCR * keyDescr,AQFINTS_SEGMENT * segSigHead,AQFINTS_SEGMENT * segSigTail,AQFINTS_SEGMENT * segFirstSigned,AQFINTS_SEGMENT * segLastSigned)44 int AQFINTS_Session_VerifySegmentHbci(AQFINTS_SESSION *sess,
45 AQFINTS_MESSAGE *message,
46 const AQFINTS_KEYDESCR *keyDescr,
47 AQFINTS_SEGMENT *segSigHead,
48 AQFINTS_SEGMENT *segSigTail,
49 AQFINTS_SEGMENT *segFirstSigned,
50 AQFINTS_SEGMENT *segLastSigned)
51 {
52 int rv;
53 GWEN_DB_NODE *dbSigHead;
54 GWEN_DB_NODE *dbSigTail;
55 const uint8_t *ptr;
56 unsigned int len=0;
57 int sigCounter;
58 const char *securityProfileName;
59 int securityProfileVersion;
60 const AQFINTS_CRYPTPARAMS *cryptParams;
61 GWEN_BUFFER *bufHashData;
62
63 securityProfileName=AQFINTS_KeyDescr_GetSecurityProfileName(keyDescr);
64 securityProfileVersion=AQFINTS_KeyDescr_GetSecurityProfileVersion(keyDescr);
65
66 /* hack for hibiscus */
67 if (securityProfileVersion==0) {
68 if (securityProfileName && strcasecmp(securityProfileName, "RDH")==0)
69 securityProfileVersion=10;
70 }
71
72 cryptParams=AQFINTS_CryptParams_GetParamsForSecurityProfile(securityProfileName, securityProfileVersion);
73 if (cryptParams==NULL) {
74 DBG_ERROR(AQFINTS_LOGDOMAIN, "No crypt params for [%s:%d]", securityProfileName?securityProfileName:"<empty>",
75 securityProfileVersion);
76 return GWEN_ERROR_INVALID;
77 }
78
79 dbSigTail=AQFINTS_Segment_GetDbData(segSigTail);
80 assert(dbSigTail);
81 ptr=(const uint8_t *) GWEN_DB_GetBinValue(dbSigTail, "signature", 0, 0, 0, &len);
82 if (ptr==NULL || len<1) {
83 DBG_ERROR(AQFINTS_LOGDOMAIN, "No signature in segment");
84 return GWEN_ERROR_BAD_DATA;
85 }
86
87 dbSigHead=AQFINTS_Segment_GetDbData(segSigHead);
88 assert(dbSigHead);
89 sigCounter=GWEN_DB_GetIntValue(dbSigHead, "signseq", 0, 0);
90
91 bufHashData=GWEN_Buffer_new(0, 256, 0, 1);
92 rv=AQFINTS_Session_SampleDataToHash(segSigHead, segFirstSigned, segLastSigned, bufHashData);
93 if (rv<0) {
94 DBG_INFO(AQFINTS_LOGDOMAIN, "here (%d)", rv);
95 GWEN_Buffer_free(bufHashData);
96 return rv;
97 }
98
99 rv=AQFINTS_Session_Verify(sess, keyDescr, cryptParams,
100 (const uint8_t *) GWEN_Buffer_GetStart(bufHashData), GWEN_Buffer_GetUsedBytes(bufHashData),
101 ptr, len, sigCounter);
102 if (rv<0) {
103 if (rv==GWEN_ERROR_TRY_AGAIN) {
104 DBG_INFO(AQFINTS_LOGDOMAIN, "Not yet ready to verify signature, retry later");
105 GWEN_Buffer_free(bufHashData);
106 }
107 else {
108 DBG_INFO(AQFINTS_LOGDOMAIN, "here (%d)", rv);
109 }
110 return rv;
111 }
112
113 return 0;
114 }
115
116
117
118
119