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 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 #define DISABLE_DEBUGLOG
15 
16 
17 #include "cryptmgr_p.h"
18 #include "i18n_l.h"
19 #include <gwenhywfar/misc.h>
20 #include <gwenhywfar/debug.h>
21 #include <gwenhywfar/gwentime.h>
22 
23 #include <gwenhywfar/crypthead.h>
24 #include <gwenhywfar/sighead.h>
25 #include <gwenhywfar/sigtail.h>
26 #include <gwenhywfar/tag16.h>
27 #include <gwenhywfar/cryptkeysym.h>
28 #include <gwenhywfar/padd.h>
29 
30 
31 
32 
GWEN_INHERIT_FUNCTIONS(GWEN_CRYPTMGR)33 GWEN_INHERIT_FUNCTIONS(GWEN_CRYPTMGR)
34 
35 
36 
37 GWEN_CRYPTMGR *GWEN_CryptMgr_new(void)
38 {
39   GWEN_CRYPTMGR *cm;
40 
41   GWEN_NEW_OBJECT(GWEN_CRYPTMGR, cm);
42   GWEN_INHERIT_INIT(GWEN_CRYPTMGR, cm);
43 
44   return cm;
45 }
46 
47 
48 
GWEN_CryptMgr_free(GWEN_CRYPTMGR * cm)49 void GWEN_CryptMgr_free(GWEN_CRYPTMGR *cm)
50 {
51   if (cm) {
52     GWEN_INHERIT_FINI(GWEN_CRYPTMGR, cm);
53     free(cm->localKeyName);
54     free(cm->peerKeyName);
55 
56     GWEN_FREE_OBJECT(cm);
57   }
58 }
59 
60 
61 
GWEN_CryptMgr_GetLocalKeyName(const GWEN_CRYPTMGR * cm)62 const char *GWEN_CryptMgr_GetLocalKeyName(const GWEN_CRYPTMGR *cm)
63 {
64   assert(cm);
65   return cm->localKeyName;
66 }
67 
68 
69 
GWEN_CryptMgr_SetLocalKeyName(GWEN_CRYPTMGR * cm,const char * s)70 void GWEN_CryptMgr_SetLocalKeyName(GWEN_CRYPTMGR *cm, const char *s)
71 {
72   assert(cm);
73   free(cm->localKeyName);
74   if (s)
75     cm->localKeyName=strdup(s);
76   else
77     cm->localKeyName=NULL;
78 }
79 
80 
81 
GWEN_CryptMgr_GetLocalKeyNumber(const GWEN_CRYPTMGR * cm)82 int GWEN_CryptMgr_GetLocalKeyNumber(const GWEN_CRYPTMGR *cm)
83 {
84   assert(cm);
85   return cm->localKeyNumber;
86 }
87 
88 
89 
GWEN_CryptMgr_SetLocalKeyNumber(GWEN_CRYPTMGR * cm,int i)90 void GWEN_CryptMgr_SetLocalKeyNumber(GWEN_CRYPTMGR *cm, int i)
91 {
92   assert(cm);
93   cm->localKeyNumber=i;
94 }
95 
96 
97 
GWEN_CryptMgr_GetLocalKeyVersion(const GWEN_CRYPTMGR * cm)98 int GWEN_CryptMgr_GetLocalKeyVersion(const GWEN_CRYPTMGR *cm)
99 {
100   assert(cm);
101   return cm->localKeyVersion;
102 }
103 
104 
105 
GWEN_CryptMgr_SetLocalKeyVersion(GWEN_CRYPTMGR * cm,int i)106 void GWEN_CryptMgr_SetLocalKeyVersion(GWEN_CRYPTMGR *cm, int i)
107 {
108   assert(cm);
109   cm->localKeyVersion=i;
110 }
111 
112 
113 
GWEN_CryptMgr_GetPeerKeyName(const GWEN_CRYPTMGR * cm)114 const char *GWEN_CryptMgr_GetPeerKeyName(const GWEN_CRYPTMGR *cm)
115 {
116   assert(cm);
117   return cm->peerKeyName;
118 }
119 
120 
121 
GWEN_CryptMgr_SetPeerKeyName(GWEN_CRYPTMGR * cm,const char * s)122 void GWEN_CryptMgr_SetPeerKeyName(GWEN_CRYPTMGR *cm, const char *s)
123 {
124   assert(cm);
125   free(cm->peerKeyName);
126   if (s)
127     cm->peerKeyName=strdup(s);
128   else
129     cm->peerKeyName=NULL;
130 }
131 
132 
133 
GWEN_CryptMgr_GetPeerKeyNumber(const GWEN_CRYPTMGR * cm)134 int GWEN_CryptMgr_GetPeerKeyNumber(const GWEN_CRYPTMGR *cm)
135 {
136   assert(cm);
137   return cm->peerKeyNumber;
138 }
139 
140 
141 
GWEN_CryptMgr_SetPeerKeyNumber(GWEN_CRYPTMGR * cm,int i)142 void GWEN_CryptMgr_SetPeerKeyNumber(GWEN_CRYPTMGR *cm, int i)
143 {
144   assert(cm);
145   cm->peerKeyNumber=i;
146 }
147 
148 
149 
GWEN_CryptMgr_GetPeerKeyVersion(const GWEN_CRYPTMGR * cm)150 int GWEN_CryptMgr_GetPeerKeyVersion(const GWEN_CRYPTMGR *cm)
151 {
152   assert(cm);
153   return cm->peerKeyVersion;
154 }
155 
156 
157 
GWEN_CryptMgr_SetPeerKeyVersion(GWEN_CRYPTMGR * cm,int i)158 void GWEN_CryptMgr_SetPeerKeyVersion(GWEN_CRYPTMGR *cm, int i)
159 {
160   assert(cm);
161   cm->peerKeyVersion=i;
162 }
163 
164 
165 
GWEN_CryptMgr_GetCryptProfile(const GWEN_CRYPTMGR * cm)166 int GWEN_CryptMgr_GetCryptProfile(const GWEN_CRYPTMGR *cm)
167 {
168   assert(cm);
169   return cm->cryptProfile;
170 }
171 
172 
173 
GWEN_CryptMgr_SetCryptProfile(GWEN_CRYPTMGR * cm,int i)174 void GWEN_CryptMgr_SetCryptProfile(GWEN_CRYPTMGR *cm, int i)
175 {
176   assert(cm);
177   cm->cryptProfile=i;
178 }
179 
180 
181 
GWEN_CryptMgr_GetSignatureProfile(const GWEN_CRYPTMGR * cm)182 int GWEN_CryptMgr_GetSignatureProfile(const GWEN_CRYPTMGR *cm)
183 {
184   assert(cm);
185   return cm->signatureProfile;
186 }
187 
188 
189 
GWEN_CryptMgr_SetSignatureProfile(GWEN_CRYPTMGR * cm,int i)190 void GWEN_CryptMgr_SetSignatureProfile(GWEN_CRYPTMGR *cm, int i)
191 {
192   assert(cm);
193   cm->signatureProfile=i;
194 }
195 
196 
197 
198 
199 
GWEN_CryptMgr_SignData(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)200 int GWEN_CryptMgr_SignData(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
201 {
202   assert(cm);
203   if (cm->signDataFn)
204     return cm->signDataFn(cm, pData, lData, dbuf);
205   else
206     return GWEN_ERROR_NOT_IMPLEMENTED;
207 }
208 
209 
210 
GWEN_CryptMgr_EncryptKey(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)211 int GWEN_CryptMgr_EncryptKey(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
212 {
213   assert(cm);
214   if (cm->encryptKeyFn)
215     return cm->encryptKeyFn(cm, pData, lData, dbuf);
216   else
217     return GWEN_ERROR_NOT_IMPLEMENTED;
218 }
219 
220 
221 
GWEN_CryptMgr_VerifyData(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,const uint8_t * pSignature,uint32_t lSignature)222 int GWEN_CryptMgr_VerifyData(GWEN_CRYPTMGR *cm,
223                              const uint8_t *pData, uint32_t lData,
224                              const uint8_t *pSignature, uint32_t lSignature)
225 {
226   assert(cm);
227   if (cm->verifyDataFn)
228     return cm->verifyDataFn(cm, pData, lData, pSignature, lSignature);
229   else
230     return GWEN_ERROR_NOT_IMPLEMENTED;
231 }
232 
233 
234 
GWEN_CryptMgr_DecryptKey(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)235 int GWEN_CryptMgr_DecryptKey(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
236 {
237   assert(cm);
238   if (cm->decryptKeyFn)
239     return cm->decryptKeyFn(cm, pData, lData, dbuf);
240   else
241     return GWEN_ERROR_NOT_IMPLEMENTED;
242 }
243 
244 
245 
GWEN_CryptMgr_SetSignDataFn(GWEN_CRYPTMGR * cm,GWEN_CRYPTMGR_SIGNDATA_FN f)246 GWEN_CRYPTMGR_SIGNDATA_FN GWEN_CryptMgr_SetSignDataFn(GWEN_CRYPTMGR *cm,
247                                                       GWEN_CRYPTMGR_SIGNDATA_FN f)
248 {
249   GWEN_CRYPTMGR_SIGNDATA_FN of;
250 
251   assert(cm);
252   of=cm->signDataFn;
253   cm->signDataFn=f;
254   return of;
255 }
256 
257 
258 
GWEN_CryptMgr_SetVerifyDataFn(GWEN_CRYPTMGR * cm,GWEN_CRYPTMGR_VERIFYDATA_FN f)259 GWEN_CRYPTMGR_VERIFYDATA_FN GWEN_CryptMgr_SetVerifyDataFn(GWEN_CRYPTMGR *cm,
260                                                           GWEN_CRYPTMGR_VERIFYDATA_FN f)
261 {
262   GWEN_CRYPTMGR_VERIFYDATA_FN of;
263 
264   assert(cm);
265   of=cm->verifyDataFn;
266   cm->verifyDataFn=f;
267   return of;
268 }
269 
270 
271 
GWEN_CryptMgr_SetEncryptKeyFn(GWEN_CRYPTMGR * cm,GWEN_CRYPTMGR_ENCRYPTKEY_FN f)272 GWEN_CRYPTMGR_ENCRYPTKEY_FN GWEN_CryptMgr_SetEncryptKeyFn(GWEN_CRYPTMGR *cm,
273                                                           GWEN_CRYPTMGR_ENCRYPTKEY_FN f)
274 {
275   GWEN_CRYPTMGR_ENCRYPTKEY_FN of;
276 
277   assert(cm);
278   of=cm->encryptKeyFn;
279   cm->encryptKeyFn=f;
280   return of;
281 }
282 
283 
284 
GWEN_CryptMgr_SetDecryptKeyFn(GWEN_CRYPTMGR * cm,GWEN_CRYPTMGR_DECRYPTKEY_FN f)285 GWEN_CRYPTMGR_DECRYPTKEY_FN GWEN_CryptMgr_SetDecryptKeyFn(GWEN_CRYPTMGR *cm,
286                                                           GWEN_CRYPTMGR_DECRYPTKEY_FN f)
287 {
288   GWEN_CRYPTMGR_DECRYPTKEY_FN of;
289 
290   assert(cm);
291   of=cm->decryptKeyFn;
292   cm->decryptKeyFn=f;
293   return of;
294 }
295 
296 
297 
GWEN_CryptMgr_Sign(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)298 int GWEN_CryptMgr_Sign(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
299 {
300   GWEN_SIGHEAD *sh;
301   GWEN_SIGTAIL *st;
302   GWEN_TIME *ti;
303   uint32_t pos;
304   uint32_t shPos;
305   uint8_t *p;
306   uint32_t l;
307   int rv;
308   GWEN_BUFFER *sigbuf;
309 
310   assert(cm);
311   GWEN_Buffer_AppendByte(dbuf, GWEN_CRYPTMGR_TLV_SIGNEDOBJECT);
312   pos=GWEN_Buffer_GetPos(dbuf);
313   GWEN_Buffer_AppendByte(dbuf, 0);
314   GWEN_Buffer_AppendByte(dbuf, 0);
315 
316   /* prepare signature head */
317   sh=GWEN_SigHead_new();
318   GWEN_SigHead_SetKeyName(sh, cm->localKeyName);
319   GWEN_SigHead_SetKeyNumber(sh, cm->localKeyNumber);
320   GWEN_SigHead_SetKeyVersion(sh, cm->localKeyVersion);
321   ti=GWEN_CurrentTime();
322   GWEN_SigHead_SetDateTime(sh, ti);
323   GWEN_Time_free(ti);
324   GWEN_SigHead_SetSignatureProfile(sh, cm->signatureProfile);
325   GWEN_SigHead_SetSignatureNumber(sh, 1);
326 
327   /* write signature head to buffer */
328   shPos=GWEN_Buffer_GetPos(dbuf);
329   rv=GWEN_SigHead_toBuffer(sh, dbuf, GWEN_CRYPTMGR_TLV_SIGHEAD);
330   GWEN_SigHead_free(sh);
331   if (rv<0) {
332     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
333     return rv;
334   }
335 
336   /* write data to buffer */
337   if (pData && lData)
338     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPTMGR_TLV_SIGDATA,
339                                 (const char *)pData,
340                                 lData,
341                                 dbuf);
342 
343   /* sign data: signature head TLV + data TLV */
344   sigbuf=GWEN_Buffer_new(0, 300, 0, 1);
345   p=((uint8_t *)GWEN_Buffer_GetStart(dbuf))+shPos;
346   l=GWEN_Buffer_GetPos(dbuf)-shPos;
347   rv=GWEN_CryptMgr_SignData(cm, p, l, sigbuf);
348   if (rv<0) {
349     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
350     GWEN_Buffer_free(sigbuf);
351     return rv;
352   }
353 
354   /* create signature tail */
355   st=GWEN_SigTail_new();
356   GWEN_SigTail_SetSignature(st,
357                             (const uint8_t *)GWEN_Buffer_GetStart(sigbuf),
358                             GWEN_Buffer_GetUsedBytes(sigbuf));
359   GWEN_Buffer_free(sigbuf);
360   GWEN_SigTail_SetSignatureNumber(st, 1);
361 
362   /* write signature tail */
363   rv=GWEN_SigTail_toBuffer(st, dbuf, GWEN_CRYPTMGR_TLV_SIGTAIL);
364   GWEN_SigTail_free(st);
365   if (rv<0) {
366     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
367     return rv;
368   }
369 
370   /* write complete size */
371   l=GWEN_Buffer_GetPos(dbuf)-pos-2;
372   p=(uint8_t *)GWEN_Buffer_GetStart(dbuf)+pos;
373   *(p++)=l & 0xff;
374   *p=(l>>8) & 0xff;
375 
376   return 0;
377 }
378 
379 
380 
GWEN_CryptMgr_Encrypt(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)381 int GWEN_CryptMgr_Encrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
382 {
383   GWEN_CRYPTHEAD *ch;
384   uint32_t pos;
385   uint8_t *p;
386   uint32_t l;
387   int rv;
388   GWEN_BUFFER *cryptbuf;
389   GWEN_BUFFER *tbuf;
390   GWEN_CRYPT_KEY *mkey;
391 
392   assert(cm);
393 
394   /* generate a message key */
395   mkey=GWEN_Crypt_KeyBlowFish_Generate(GWEN_Crypt_CryptMode_Cbc, 256/8, 2);
396   if (mkey==NULL) {
397     DBG_ERROR(GWEN_LOGDOMAIN, "Unable to generate BLOWFISH key");
398     return GWEN_ERROR_GENERIC;
399   }
400 
401   GWEN_Buffer_AppendByte(dbuf, GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT);
402   pos=GWEN_Buffer_GetPos(dbuf);
403   GWEN_Buffer_AppendByte(dbuf, 0);
404   GWEN_Buffer_AppendByte(dbuf, 0);
405 
406   /* prepare signature head */
407   ch=GWEN_CryptHead_new();
408   GWEN_CryptHead_SetKeyName(ch, cm->peerKeyName);
409   GWEN_CryptHead_SetKeyNumber(ch, cm->peerKeyNumber);
410   GWEN_CryptHead_SetKeyVersion(ch, cm->peerKeyVersion);
411   GWEN_CryptHead_SetCryptProfile(ch, cm->signatureProfile);
412 
413   /* encrypt key */
414   cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1);
415   rv=GWEN_CryptMgr_EncryptKey(cm,
416                               GWEN_Crypt_KeyBlowFish_GetKeyDataPtr(mkey),
417                               GWEN_Crypt_KeyBlowFish_GetKeyDataLen(mkey),
418                               cryptbuf);
419   if (rv<0) {
420     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
421     GWEN_Buffer_free(cryptbuf);
422     GWEN_CryptHead_free(ch);
423     GWEN_Crypt_Key_free(mkey);
424     return rv;
425   }
426   GWEN_CryptHead_SetKey(ch,
427                         (const uint8_t *)GWEN_Buffer_GetStart(cryptbuf),
428                         GWEN_Buffer_GetUsedBytes(cryptbuf));
429   GWEN_Buffer_free(cryptbuf);
430 
431   /* write crypt head to buffer */
432   rv=GWEN_CryptHead_toBuffer(ch, dbuf, GWEN_CRYPTMGR_TLV_CRYPTHEAD);
433   GWEN_CryptHead_free(ch);
434   if (rv<0) {
435     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
436     GWEN_Crypt_Key_free(mkey);
437     return rv;
438   }
439 
440   /* padd plain text data */
441   tbuf=GWEN_Buffer_new(0, lData+256, 0, 1);
442   GWEN_Buffer_AppendBytes(tbuf, (const char *)pData, lData);
443   GWEN_Padd_PaddWithAnsiX9_23(tbuf);
444 
445   /* encrypt with message key */
446   cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1);
447   l=GWEN_Buffer_GetMaxUnsegmentedWrite(cryptbuf);
448   rv=GWEN_Crypt_Key_Encipher(mkey,
449                              (const uint8_t *)GWEN_Buffer_GetStart(tbuf),
450                              GWEN_Buffer_GetUsedBytes(tbuf),
451                              (uint8_t *)GWEN_Buffer_GetStart(cryptbuf),
452                              &l);
453   GWEN_Buffer_free(tbuf);
454   if (rv<0) {
455     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
456     GWEN_Buffer_free(cryptbuf);
457     GWEN_Crypt_Key_free(mkey);
458     return rv;
459   }
460   GWEN_Buffer_IncrementPos(cryptbuf, l);
461   GWEN_Buffer_AdjustUsedBytes(cryptbuf);
462 
463   /* write encrypted data */
464   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPTMGR_TLV_CRYPTDATA,
465                               GWEN_Buffer_GetStart(cryptbuf),
466                               GWEN_Buffer_GetUsedBytes(cryptbuf),
467                               dbuf);
468   GWEN_Buffer_free(cryptbuf);
469   GWEN_Crypt_Key_free(mkey);
470 
471   /* write complete size */
472   l=GWEN_Buffer_GetPos(dbuf)-pos-2;
473   p=(uint8_t *)GWEN_Buffer_GetStart(dbuf)+pos;
474   *(p++)=l & 0xff;
475   *p=(l>>8) & 0xff;
476 
477   return 0;
478 }
479 
480 
481 
GWEN_CryptMgr_Verify(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)482 int GWEN_CryptMgr_Verify(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
483 {
484   GWEN_TAG16 *tag;
485   const uint8_t *p;
486   uint32_t l;
487   GWEN_SIGHEAD *sh=NULL;
488   GWEN_SIGTAIL *st=NULL;
489   const uint8_t *pSignedData=NULL;
490   uint32_t lSignedData=0;
491   int rv;
492 
493   assert(cm);
494   if (lData<3) {
495     DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
496     return GWEN_ERROR_BAD_DATA;
497   }
498 
499   tag=GWEN_Tag16_fromBuffer2(pData, lData, 0);
500   if (tag==NULL) {
501     DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV");
502     return GWEN_ERROR_BAD_DATA;
503   }
504 
505   if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_SIGNEDOBJECT) {
506     DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain asigned object");
507     GWEN_Tag16_free(tag);
508     return GWEN_ERROR_BAD_DATA;
509   }
510 
511   p=GWEN_Tag16_GetTagData(tag);
512   l=GWEN_Tag16_GetTagLength(tag);
513 
514   /* read sighead */
515   if (l) {
516     GWEN_TAG16 *subtag;
517 
518     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
519     if (subtag) {
520       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGHEAD) {
521         sh=GWEN_SigHead_fromBuffer(GWEN_Tag16_GetTagData(subtag),
522                                    GWEN_Tag16_GetTagLength(subtag));
523         if (sh) {
524           pSignedData=p;
525           lSignedData=GWEN_Tag16_GetTagSize(subtag);
526         }
527       }
528       p+=GWEN_Tag16_GetTagSize(subtag);
529       l-=GWEN_Tag16_GetTagSize(subtag);
530       GWEN_Tag16_free(subtag);
531     }
532   }
533 
534   /* read and store signed data */
535   if (l) {
536     GWEN_TAG16 *subtag;
537 
538     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
539     if (subtag) {
540       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGDATA) {
541         GWEN_Buffer_AppendBytes(dbuf,
542                                 GWEN_Tag16_GetTagData(subtag),
543                                 GWEN_Tag16_GetTagLength(subtag));
544         if ((pSignedData+lSignedData)==p) {
545           lSignedData+=GWEN_Tag16_GetTagSize(subtag);
546         }
547         else {
548           DBG_ERROR(GWEN_LOGDOMAIN, "data TLV must follow sighead TLV");
549           GWEN_Tag16_free(subtag);
550           GWEN_SigHead_free(sh);
551           GWEN_Tag16_free(tag);
552           return GWEN_ERROR_BAD_DATA;
553         }
554       }
555       p+=GWEN_Tag16_GetTagSize(subtag);
556       l-=GWEN_Tag16_GetTagSize(subtag);
557       GWEN_Tag16_free(subtag);
558     }
559   }
560 
561   /* read sigtail (contains the signature) */
562   if (l) {
563     GWEN_TAG16 *subtag;
564 
565     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
566     if (subtag) {
567       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGTAIL) {
568         st=GWEN_SigTail_fromBuffer(GWEN_Tag16_GetTagData(subtag),
569                                    GWEN_Tag16_GetTagLength(subtag));
570       }
571       p+=GWEN_Tag16_GetTagSize(subtag);
572       l-=GWEN_Tag16_GetTagSize(subtag);
573       GWEN_Tag16_free(subtag);
574     }
575   }
576 
577   /* check for all needed components */
578   if (!(sh && st && pSignedData && lSignedData)) {
579     DBG_ERROR(GWEN_LOGDOMAIN, "Signed object is not complete");
580     GWEN_SigTail_free(st);
581     GWEN_SigHead_free(sh);
582     GWEN_Tag16_free(tag);
583     return GWEN_ERROR_BAD_DATA;
584   }
585 
586   if (GWEN_SigHead_GetSignatureNumber(sh)!=GWEN_SigTail_GetSignatureNumber(st)) {
587     DBG_ERROR(GWEN_LOGDOMAIN, "Sighead doesn't match sigtail");
588     GWEN_SigTail_free(st);
589     GWEN_SigHead_free(sh);
590     GWEN_Tag16_free(tag);
591     return GWEN_ERROR_BAD_DATA;
592   }
593 
594   /* store or check peer key info */
595   if (cm->peerKeyName==NULL) {
596     /* store peer info */
597     GWEN_CryptMgr_SetPeerKeyName(cm, GWEN_SigHead_GetKeyName(sh));
598     GWEN_CryptMgr_SetPeerKeyNumber(cm, GWEN_SigHead_GetKeyNumber(sh));
599     GWEN_CryptMgr_SetPeerKeyVersion(cm, GWEN_SigHead_GetKeyVersion(sh));
600   }
601   else {
602     const char *s;
603 
604     /* compare peer info with expected info */
605     s=GWEN_SigHead_GetKeyName(sh);
606     if (!(cm->peerKeyName && s && (strcasecmp(cm->peerKeyName, s)==0) &&
607           (cm->peerKeyNumber==GWEN_SigHead_GetKeyNumber(sh)) &&
608           (cm->peerKeyVersion==GWEN_SigHead_GetKeyVersion(sh)))) {
609       DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected peer key information in signature");
610       GWEN_SigTail_free(st);
611       GWEN_SigHead_free(sh);
612       GWEN_Tag16_free(tag);
613 
614       return GWEN_ERROR_BAD_DATA;
615     }
616   }
617 
618   /* verify signature */
619   rv=GWEN_CryptMgr_VerifyData(cm,
620                               pSignedData, lSignedData,
621                               GWEN_SigTail_GetSignaturePtr(st),
622                               GWEN_SigTail_GetSignatureLen(st));
623   GWEN_SigTail_free(st);
624   GWEN_SigHead_free(sh);
625   GWEN_Tag16_free(tag);
626 
627   if (rv<0) {
628     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
629     return rv;
630   }
631 
632   return 0;
633 }
634 
635 
636 
GWEN_CryptMgr_Decrypt(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)637 int GWEN_CryptMgr_Decrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
638 {
639   GWEN_TAG16 *tag;
640   const uint8_t *p;
641   uint32_t l;
642   GWEN_CRYPTHEAD *ch=NULL;
643   const uint8_t *pEncryptedData=NULL;
644   uint32_t lEncryptedData=0;
645   int rv;
646   GWEN_BUFFER *tbuf;
647   GWEN_CRYPT_KEY *mkey;
648 
649   assert(cm);
650   if (lData<3) {
651     DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
652     return GWEN_ERROR_BAD_DATA;
653   }
654 
655   tag=GWEN_Tag16_fromBuffer2(pData, lData, 0);
656   if (tag==NULL) {
657     DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV");
658     return GWEN_ERROR_BAD_DATA;
659   }
660 
661   if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT) {
662     DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain an encrypted object");
663     GWEN_Tag16_free(tag);
664     return GWEN_ERROR_BAD_DATA;
665   }
666 
667   p=GWEN_Tag16_GetTagData(tag);
668   l=GWEN_Tag16_GetTagLength(tag);
669 
670   /* read crypthead */
671   if (l) {
672     GWEN_TAG16 *subtag;
673 
674     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
675     if (subtag) {
676       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTHEAD) {
677         ch=GWEN_CryptHead_fromBuffer(GWEN_Tag16_GetTagData(subtag),
678                                      GWEN_Tag16_GetTagLength(subtag));
679       }
680       p+=GWEN_Tag16_GetTagSize(subtag);
681       l-=GWEN_Tag16_GetTagSize(subtag);
682       GWEN_Tag16_free(subtag);
683     }
684   }
685 
686   /* read encrypted data */
687   if (l) {
688     GWEN_TAG16 *subtag;
689 
690     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
691     if (subtag) {
692       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTDATA) {
693         pEncryptedData=GWEN_Tag16_GetTagData(subtag);
694         lEncryptedData=GWEN_Tag16_GetTagLength(subtag);
695       }
696       p+=GWEN_Tag16_GetTagSize(subtag);
697       l-=GWEN_Tag16_GetTagSize(subtag);
698       GWEN_Tag16_free(subtag);
699     }
700   }
701 
702   /* check for all needed components */
703   if (!(ch && pEncryptedData && lEncryptedData)) {
704     DBG_ERROR(GWEN_LOGDOMAIN, "Encrypted object is not complete");
705     GWEN_CryptHead_free(ch);
706     GWEN_Tag16_free(tag);
707     return GWEN_ERROR_BAD_DATA;
708   }
709 
710   /* store or check peer key info */
711   if (cm->localKeyName) {
712     const char *s;
713 
714     /* compare peer info with expected info */
715     s=GWEN_CryptHead_GetKeyName(ch);
716     if (!(cm->localKeyName && s && (strcasecmp(cm->localKeyName, s)==0) &&
717           (cm->localKeyNumber==GWEN_CryptHead_GetKeyNumber(ch)) &&
718           (cm->localKeyVersion==GWEN_CryptHead_GetKeyVersion(ch)))) {
719       DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected local key information in signature");
720       GWEN_CryptHead_free(ch);
721       GWEN_Tag16_free(tag);
722 
723       return GWEN_ERROR_BAD_DATA;
724     }
725   }
726 
727   /* decrypt message key */
728   tbuf=GWEN_Buffer_new(0, GWEN_CryptHead_GetKeyLen(ch), 0, 1);
729   rv=GWEN_CryptMgr_DecryptKey(cm,
730                               GWEN_CryptHead_GetKeyPtr(ch),
731                               GWEN_CryptHead_GetKeyLen(ch),
732                               tbuf);
733   GWEN_CryptHead_free(ch);
734   if (rv<0) {
735     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
736     GWEN_Buffer_free(tbuf);
737     GWEN_Tag16_free(tag);
738     return rv;
739   }
740 
741   /* create message key */
742   mkey=GWEN_Crypt_KeyBlowFish_fromData(GWEN_Crypt_CryptMode_Cbc,
743                                        256/8,
744                                        (const uint8_t *) GWEN_Buffer_GetStart(tbuf),
745                                        GWEN_Buffer_GetUsedBytes(tbuf));
746   GWEN_Buffer_free(tbuf);
747   if (mkey==NULL) {
748     DBG_ERROR(GWEN_LOGDOMAIN, "Unable to create BLOWFISH key from received data");
749     GWEN_Tag16_free(tag);
750     return GWEN_ERROR_BAD_DATA;
751   }
752 
753 
754   /* decrypt data with message key */
755   tbuf=GWEN_Buffer_new(0, lEncryptedData+256, 0, 1);
756   l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
757   rv=GWEN_Crypt_Key_Decipher(mkey,
758                              pEncryptedData, lEncryptedData,
759                              (uint8_t *)GWEN_Buffer_GetStart(tbuf),
760                              &l);
761   if (rv<0) {
762     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
763     GWEN_Buffer_free(tbuf);
764     GWEN_Crypt_Key_free(mkey);
765     GWEN_Tag16_free(tag);
766     return rv;
767   }
768   GWEN_Buffer_IncrementPos(tbuf, l);
769   GWEN_Buffer_AdjustUsedBytes(tbuf);
770 
771   /* unpadd data */
772   rv=GWEN_Padd_UnpaddWithAnsiX9_23(tbuf);
773   if (rv<0) {
774     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
775     GWEN_Buffer_free(tbuf);
776     GWEN_Crypt_Key_free(mkey);
777     GWEN_Tag16_free(tag);
778     return rv;
779   }
780 
781   /* store data */
782   GWEN_Buffer_AppendBuffer(dbuf, tbuf);
783 
784   GWEN_Buffer_free(tbuf);
785   GWEN_Crypt_Key_free(mkey);
786   GWEN_Tag16_free(tag);
787 
788   return 0;
789 }
790 
791 
792 
GWEN_CryptMgr_Encode(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)793 int GWEN_CryptMgr_Encode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
794 {
795   GWEN_BUFFER *tbuf;
796   int rv;
797 
798   tbuf=GWEN_Buffer_new(0, lData, 0, 1);
799 
800   /* create signed object */
801   DBG_INFO(GWEN_LOGDOMAIN, "Signing data");
802   rv=GWEN_CryptMgr_Sign(cm, pData, lData, tbuf);
803   if (rv<0) {
804     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
805     GWEN_Buffer_free(tbuf);
806     return rv;
807   }
808 
809   /* create encrypted object (containing a signed object in this case) */
810   DBG_INFO(GWEN_LOGDOMAIN, "Encrypting data");
811   rv=GWEN_CryptMgr_Encrypt(cm,
812                            (const uint8_t *)GWEN_Buffer_GetStart(tbuf),
813                            GWEN_Buffer_GetUsedBytes(tbuf),
814                            dbuf);
815   GWEN_Buffer_free(tbuf);
816   if (rv<0) {
817     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
818     return rv;
819   }
820 
821   return 0;
822 }
823 
824 
825 
GWEN_CryptMgr_Decode(GWEN_CRYPTMGR * cm,const uint8_t * pData,uint32_t lData,GWEN_BUFFER * dbuf)826 int GWEN_CryptMgr_Decode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
827 {
828   GWEN_BUFFER *tbuf;
829   int rv;
830 
831   tbuf=GWEN_Buffer_new(0, lData, 0, 1);
832 
833   /* decrypt encrypted object */
834   DBG_INFO(GWEN_LOGDOMAIN, "Decrypting data");
835   rv=GWEN_CryptMgr_Decrypt(cm, pData, lData, tbuf);
836   if (rv<0) {
837     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
838     GWEN_Buffer_free(tbuf);
839     return rv;
840   }
841 
842   /* verify signature, copy signed data to dbuf in the process */
843   DBG_INFO(GWEN_LOGDOMAIN, "Verifying data");
844   rv=GWEN_CryptMgr_Verify(cm,
845                           (const uint8_t *)GWEN_Buffer_GetStart(tbuf),
846                           GWEN_Buffer_GetUsedBytes(tbuf),
847                           dbuf);
848   GWEN_Buffer_free(tbuf);
849   if (rv<0) {
850     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
851     return rv;
852   }
853 
854   return 0;
855 }
856 
857 
858 
859 
860 
861