gwenhywfar  4.8.0beta
cryptmgrkeys.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Mon Dec 01 2008
3  copyright : (C) 2008 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * Please see toplevel file COPYING for license details *
8  ***************************************************************************/
9 
10 
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14 
15 #define DISABLE_DEBUGLOG
16 
17 
18 #include "cryptmgrkeys_p.h"
19 #include "i18n_l.h"
20 #include <gwenhywfar/misc.h>
21 #include <gwenhywfar/debug.h>
22 #include <gwenhywfar/mdigest.h>
23 #include <gwenhywfar/padd.h>
24 #include <gwenhywfar/crypthead.h>
25 #include <gwenhywfar/text.h>
26 
27 
28 
29 GWEN_INHERIT(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS);
30 
31 
32 
33 GWEN_CRYPTMGR *GWEN_CryptMgrKeys_new(const char *localName,
34  GWEN_CRYPT_KEY *localKey,
35  const char *peerName,
36  GWEN_CRYPT_KEY *peerKey,
37  int ownKeys) {
38  GWEN_CRYPTMGR *cm;
39  GWEN_CRYPTMGR_KEYS *xcm;
40 
41  cm=GWEN_CryptMgr_new();
42  GWEN_NEW_OBJECT(GWEN_CRYPTMGR_KEYS, xcm);
43  GWEN_INHERIT_SETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm, xcm,
45 
46  if (localKey) {
47  xcm->localKey=localKey;
50  xcm->ownLocalKey=ownKeys;
51  }
52  else
53  xcm->ownLocalKey=0;
54 
55  if (peerKey) {
56  xcm->peerKey=peerKey;
59  xcm->ownPeerKey=ownKeys;
60  }
61  else
62  xcm->ownPeerKey=0;
63 
64  if (localName)
65  GWEN_CryptMgr_SetLocalKeyName(cm, localName);
66 
67  if (peerName)
68  GWEN_CryptMgr_SetPeerKeyName(cm, peerName);
69 
74 
75  return cm;
76 }
77 
78 
79 
81 void GWEN_CryptMgrKeys_FreeData(GWEN_UNUSED void *bp, void *p) {
82  GWEN_CRYPTMGR_KEYS *xcm;
83 
84  xcm=(GWEN_CRYPTMGR_KEYS*) p;
85 
86  if (xcm->ownLocalKey)
87  GWEN_Crypt_Key_free(xcm->localKey);
88  if (xcm->ownPeerKey)
89  GWEN_Crypt_Key_free(xcm->peerKey);
90 }
91 
92 
93 
95  GWEN_CRYPT_KEY *peerKey,
96  int ownKey) {
97  GWEN_CRYPTMGR_KEYS *xcm;
98 
99  assert(cm);
100  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
101  assert(xcm);
102 
103  if (xcm->ownPeerKey)
104  GWEN_Crypt_Key_free(xcm->peerKey);
105  xcm->peerKey=peerKey;
106  xcm->ownPeerKey=ownKey;
107 }
108 
109 
110 
113  const uint8_t *pData, uint32_t lData,
114  GWEN_BUFFER *dbuf) {
115  GWEN_CRYPTMGR_KEYS *xcm;
116  GWEN_MDIGEST *md;
117  int rv;
118  GWEN_BUFFER *tbuf;
119  int ksize;
120  uint32_t signatureLen;
121 
122  assert(cm);
123  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
124  assert(xcm);
125 
126  if (xcm->localKey==NULL) {
127  DBG_ERROR(GWEN_LOGDOMAIN, "No local key");
128  return GWEN_ERROR_GENERIC;
129  }
130 
131  ksize=GWEN_Crypt_Key_GetKeySize(xcm->localKey);
132 
133  /* hash pData */
135  rv=GWEN_MDigest_Begin(md);
136  if (rv<0) {
137  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
138  GWEN_MDigest_free(md);
139  return rv;
140  }
141  rv=GWEN_MDigest_Update(md, pData, lData);
142  if (rv<0) {
143  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
144  GWEN_MDigest_free(md);
145  return rv;
146  }
147  rv=GWEN_MDigest_End(md);
148  if (rv<0) {
149  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
150  GWEN_MDigest_free(md);
151  return rv;
152  }
153 
154  /* padd */
155  tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
157  (const char*)GWEN_MDigest_GetDigestPtr(md),
159  GWEN_MDigest_free(md);
160  GWEN_Padd_PaddWithIso9796_2(tbuf, ksize);
161 
162  /* sign */
163  GWEN_Buffer_AllocRoom(dbuf, ksize);
164  signatureLen=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf);
165  rv=GWEN_Crypt_Key_Sign(xcm->localKey,
166  (uint8_t*)GWEN_Buffer_GetStart(tbuf),
168  (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf),
169  &signatureLen);
170  GWEN_Buffer_free(tbuf);
171  if (rv<0) {
172  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
173  return rv;
174  }
175 
176  GWEN_Buffer_IncrementPos(dbuf, signatureLen);
178 
179  return 0;
180 }
181 
182 
183 
186  const uint8_t *pData, uint32_t lData,
187  const uint8_t *pSignature, uint32_t lSignature) {
188  GWEN_CRYPTMGR_KEYS *xcm;
189  GWEN_MDIGEST *md;
190  int rv;
191  GWEN_BUFFER *tbuf;
192  int ksize;
193  uint32_t l;
194 
195  assert(cm);
196  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
197  assert(xcm);
198 
199  if (xcm->peerKey==NULL) {
200  DBG_ERROR(GWEN_LOGDOMAIN, "No peer key");
201  return GWEN_ERROR_GENERIC;
202  }
203 
204  ksize=GWEN_Crypt_Key_GetKeySize(xcm->peerKey);
205 
206  /* the padding algo uses random numbers, so we must use the encrypt function and
207  * compare the decoded and unpadded signature with the hash of the source data
208  */
209  tbuf=GWEN_Buffer_new(0, ksize+16, 0, 1);
211  rv=GWEN_Crypt_Key_Encipher(xcm->peerKey,
212  pSignature, lSignature,
213  (uint8_t*)GWEN_Buffer_GetPosPointer(tbuf),
214  &l);
215  if (rv<0) {
216  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
217  GWEN_Buffer_free(tbuf);
218  return rv;
219  }
220  GWEN_Buffer_IncrementPos(tbuf, l);
222 
223  /* unpadd */
225  if (rv<0) {
226  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
227  GWEN_Buffer_free(tbuf);
228  return rv;
229  }
230  /* tbuf now contains the hash */
231 
232  /* hash source data */
234  rv=GWEN_MDigest_Begin(md);
235  if (rv<0) {
236  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
237  GWEN_MDigest_free(md);
238  GWEN_Buffer_free(tbuf);
239  return rv;
240  }
241  rv=GWEN_MDigest_Update(md, pData, lData);
242  if (rv<0) {
243  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
244  GWEN_MDigest_free(md);
245  GWEN_Buffer_free(tbuf);
246  return rv;
247  }
248  rv=GWEN_MDigest_End(md);
249  if (rv<0) {
250  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
251  GWEN_MDigest_free(md);
252  GWEN_Buffer_free(tbuf);
253  return rv;
254  }
255 
257  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature");
258  GWEN_MDigest_free(md);
259  GWEN_Buffer_free(tbuf);
260  return GWEN_ERROR_VERIFY;
261  }
262 
263  if (memcmp(GWEN_MDigest_GetDigestPtr(md),
264  GWEN_Buffer_GetStart(tbuf),
265  GWEN_MDigest_GetDigestSize(md))!=0) {
266  DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature");
267  GWEN_MDigest_free(md);
268  GWEN_Buffer_free(tbuf);
269  return GWEN_ERROR_VERIFY;
270  }
271 
272  GWEN_MDigest_free(md);
273  GWEN_Buffer_free(tbuf);
274 
275  return 0;
276 }
277 
278 
279 
282  const uint8_t *pData, uint32_t lData,
283  GWEN_BUFFER *dbuf) {
284  GWEN_CRYPTMGR_KEYS *xcm;
285  int rv;
286  GWEN_BUFFER *tbuf;
287  int ksize;
288  uint32_t l;
289 
290  assert(cm);
291  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
292  assert(xcm);
293 
294  if (xcm->peerKey==NULL) {
295  DBG_ERROR(GWEN_LOGDOMAIN, "No peer key");
296  return GWEN_ERROR_GENERIC;
297  }
298 
299  ksize=GWEN_Crypt_Key_GetKeySize(xcm->peerKey);
300 
301  /* padd key data */
302  tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
303  GWEN_Buffer_AppendBytes(tbuf, (const char*) pData, lData);
304  rv=GWEN_Padd_PaddWithIso9796_2(tbuf, ksize);
305  if (rv<0) {
306  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
307  GWEN_Buffer_free(tbuf);
308  return rv;
309  }
310 
311  GWEN_Buffer_AllocRoom(dbuf, ksize);
313  rv=GWEN_Crypt_Key_Encipher(xcm->peerKey,
314  (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
316  (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf),
317  &l);
318  GWEN_Buffer_free(tbuf);
319  if (rv<0) {
320  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
321  return rv;
322  }
323 
324  GWEN_Buffer_IncrementPos(dbuf, l);
326 
327  return 0;
328 }
329 
330 
331 
334  const uint8_t *pData, uint32_t lData,
335  GWEN_BUFFER *dbuf) {
336  GWEN_CRYPTMGR_KEYS *xcm;
337  int rv;
338  GWEN_BUFFER *tbuf;
339  int ksize;
340  uint32_t l;
341 
342  assert(cm);
343  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
344  assert(xcm);
345 
346  if (xcm->localKey==NULL) {
347  DBG_ERROR(GWEN_LOGDOMAIN, "No local key");
348  return GWEN_ERROR_GENERIC;
349  }
350 
351  ksize=GWEN_Crypt_Key_GetKeySize(xcm->localKey);
352 
353  tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
355  rv=GWEN_Crypt_Key_Decipher(xcm->localKey,
356  pData, lData,
357  (uint8_t*)GWEN_Buffer_GetPosPointer(tbuf),
358  &l);
359  if (rv<0) {
360  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
361  GWEN_Buffer_free(tbuf);
362  return rv;
363  }
364  GWEN_Buffer_IncrementPos(tbuf, l);
366 
367  /* unpadd data */
369  if (rv<0) {
370  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
371  GWEN_Buffer_free(tbuf);
372  return rv;
373  }
374 
375  GWEN_Buffer_AppendBuffer(dbuf, tbuf);
376  GWEN_Buffer_free(tbuf);
377 
378  return 0;
379 }
380 
381 
382 
383 
384 
385 
386 
387 
388 
389 
390 
391 
392