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