gwenhywfar 4.0.3

cryptmgr.c

Go to the documentation of this file.
00001 /***************************************************************************
00002     begin       : Mon Dec 01 2008
00003     copyright   : (C) 2008 by Martin Preuss
00004     email       : martin@libchipcard.de
00005 
00006  ***************************************************************************
00007  *          Please see toplevel file COPYING for license details           *
00008  ***************************************************************************/
00009 
00010 #ifdef HAVE_CONFIG_H
00011 # include <config.h>
00012 #endif
00013 
00014 #define DISABLE_DEBUGLOG
00015 
00016 
00017 #include "cryptmgr_p.h"
00018 #include "i18n_l.h"
00019 #include <gwenhywfar/misc.h>
00020 #include <gwenhywfar/debug.h>
00021 #include <gwenhywfar/gwentime.h>
00022 
00023 #include <gwenhywfar/crypthead.h>
00024 #include <gwenhywfar/sighead.h>
00025 #include <gwenhywfar/sigtail.h>
00026 #include <gwenhywfar/tag16.h>
00027 #include <gwenhywfar/cryptkeysym.h>
00028 #include <gwenhywfar/padd.h>
00029 
00030 
00031 
00032 
00033 GWEN_INHERIT_FUNCTIONS(GWEN_CRYPTMGR)
00034 
00035 
00036 
00037 GWEN_CRYPTMGR *GWEN_CryptMgr_new() {
00038   GWEN_CRYPTMGR *cm;
00039 
00040   GWEN_NEW_OBJECT(GWEN_CRYPTMGR, cm);
00041   GWEN_INHERIT_INIT(GWEN_CRYPTMGR, cm);
00042 
00043   return cm;
00044 }
00045 
00046 
00047 
00048 void GWEN_CryptMgr_free(GWEN_CRYPTMGR *cm) {
00049   if (cm) {
00050     GWEN_INHERIT_FINI(GWEN_CRYPTMGR, cm);
00051     free(cm->localKeyName);
00052     free(cm->peerKeyName);
00053 
00054     GWEN_FREE_OBJECT(cm);
00055   }
00056 }
00057 
00058 
00059 
00060 const char *GWEN_CryptMgr_GetLocalKeyName(const GWEN_CRYPTMGR *cm) {
00061   assert(cm);
00062   return cm->localKeyName;
00063 }
00064 
00065 
00066 
00067 void GWEN_CryptMgr_SetLocalKeyName(GWEN_CRYPTMGR *cm, const char *s) {
00068   assert(cm);
00069   free(cm->localKeyName);
00070   if (s) cm->localKeyName=strdup(s);
00071   else cm->localKeyName=NULL;
00072 }
00073 
00074 
00075 
00076 int GWEN_CryptMgr_GetLocalKeyNumber(const GWEN_CRYPTMGR *cm) {
00077   assert(cm);
00078   return cm->localKeyNumber;
00079 }
00080 
00081 
00082 
00083 void GWEN_CryptMgr_SetLocalKeyNumber(GWEN_CRYPTMGR *cm, int i) {
00084   assert(cm);
00085   cm->localKeyNumber=i;
00086 }
00087 
00088 
00089 
00090 int GWEN_CryptMgr_GetLocalKeyVersion(const GWEN_CRYPTMGR *cm) {
00091   assert(cm);
00092   return cm->localKeyVersion;
00093 }
00094 
00095 
00096 
00097 void GWEN_CryptMgr_SetLocalKeyVersion(GWEN_CRYPTMGR *cm, int i) {
00098   assert(cm);
00099   cm->localKeyVersion=i;
00100 }
00101 
00102 
00103 
00104 const char *GWEN_CryptMgr_GetPeerKeyName(const GWEN_CRYPTMGR *cm) {
00105   assert(cm);
00106   return cm->peerKeyName;
00107 }
00108 
00109 
00110 
00111 void GWEN_CryptMgr_SetPeerKeyName(GWEN_CRYPTMGR *cm, const char *s) {
00112   assert(cm);
00113   free(cm->peerKeyName);
00114   if (s) cm->peerKeyName=strdup(s);
00115   else cm->peerKeyName=NULL;
00116 }
00117 
00118 
00119 
00120 int GWEN_CryptMgr_GetPeerKeyNumber(const GWEN_CRYPTMGR *cm) {
00121   assert(cm);
00122   return cm->peerKeyNumber;
00123 }
00124 
00125 
00126 
00127 void GWEN_CryptMgr_SetPeerKeyNumber(GWEN_CRYPTMGR *cm, int i) {
00128   assert(cm);
00129   cm->peerKeyNumber=i;
00130 }
00131 
00132 
00133 
00134 int GWEN_CryptMgr_GetPeerKeyVersion(const GWEN_CRYPTMGR *cm) {
00135   assert(cm);
00136   return cm->peerKeyVersion;
00137 }
00138 
00139 
00140 
00141 void GWEN_CryptMgr_SetPeerKeyVersion(GWEN_CRYPTMGR *cm, int i) {
00142   assert(cm);
00143   cm->peerKeyVersion=i;
00144 }
00145 
00146 
00147 
00148 int GWEN_CryptMgr_GetCryptProfile(const GWEN_CRYPTMGR *cm) {
00149   assert(cm);
00150   return cm->cryptProfile;
00151 }
00152 
00153 
00154 
00155 void GWEN_CryptMgr_SetCryptProfile(GWEN_CRYPTMGR *cm, int i) {
00156   assert(cm);
00157   cm->cryptProfile=i;
00158 }
00159 
00160 
00161 
00162 int GWEN_CryptMgr_GetSignatureProfile(const GWEN_CRYPTMGR *cm) {
00163   assert(cm);
00164   return cm->signatureProfile;
00165 }
00166 
00167 
00168 
00169 void GWEN_CryptMgr_SetSignatureProfile(GWEN_CRYPTMGR *cm, int i) {
00170   assert(cm);
00171   cm->signatureProfile=i;
00172 }
00173 
00174 
00175 
00176 
00177 
00178 int GWEN_CryptMgr_SignData(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00179   assert(cm);
00180   if (cm->signDataFn)
00181     return cm->signDataFn(cm, pData, lData, dbuf);
00182   else
00183     return GWEN_ERROR_NOT_IMPLEMENTED;
00184 }
00185 
00186 
00187 
00188 int GWEN_CryptMgr_EncryptKey(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00189   assert(cm);
00190   if (cm->encryptKeyFn)
00191     return cm->encryptKeyFn(cm, pData, lData, dbuf);
00192   else
00193     return GWEN_ERROR_NOT_IMPLEMENTED;
00194 }
00195 
00196 
00197 
00198 int GWEN_CryptMgr_VerifyData(GWEN_CRYPTMGR *cm,
00199                              const uint8_t *pData, uint32_t lData,
00200                              const uint8_t *pSignature, uint32_t lSignature) {
00201   assert(cm);
00202   if (cm->verifyDataFn)
00203     return cm->verifyDataFn(cm, pData, lData, pSignature, lSignature);
00204   else
00205     return GWEN_ERROR_NOT_IMPLEMENTED;
00206 }
00207 
00208 
00209 
00210 int GWEN_CryptMgr_DecryptKey(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00211   assert(cm);
00212   if (cm->decryptKeyFn)
00213     return cm->decryptKeyFn(cm, pData, lData, dbuf);
00214   else
00215     return GWEN_ERROR_NOT_IMPLEMENTED;
00216 }
00217 
00218 
00219 
00220 GWEN_CRYPTMGR_SIGNDATA_FN GWEN_CryptMgr_SetSignDataFn(GWEN_CRYPTMGR *cm,
00221                                                       GWEN_CRYPTMGR_SIGNDATA_FN f) {
00222   GWEN_CRYPTMGR_SIGNDATA_FN of;
00223 
00224   assert(cm);
00225   of=cm->signDataFn;
00226   cm->signDataFn=f;
00227   return of;
00228 }
00229 
00230 
00231 
00232 GWEN_CRYPTMGR_VERIFYDATA_FN GWEN_CryptMgr_SetVerifyDataFn(GWEN_CRYPTMGR *cm,
00233                                                           GWEN_CRYPTMGR_VERIFYDATA_FN f) {
00234   GWEN_CRYPTMGR_VERIFYDATA_FN of;
00235 
00236   assert(cm);
00237   of=cm->verifyDataFn;
00238   cm->verifyDataFn=f;
00239   return of;
00240 }
00241 
00242 
00243 
00244 GWEN_CRYPTMGR_ENCRYPTKEY_FN GWEN_CryptMgr_SetEncryptKeyFn(GWEN_CRYPTMGR *cm,
00245                                                           GWEN_CRYPTMGR_ENCRYPTKEY_FN f) {
00246   GWEN_CRYPTMGR_ENCRYPTKEY_FN of;
00247 
00248   assert(cm);
00249   of=cm->encryptKeyFn;
00250   cm->encryptKeyFn=f;
00251   return of;
00252 }
00253 
00254 
00255 
00256 GWEN_CRYPTMGR_DECRYPTKEY_FN GWEN_CryptMgr_SetDecryptKeyFn(GWEN_CRYPTMGR *cm,
00257                                                           GWEN_CRYPTMGR_DECRYPTKEY_FN f) {
00258   GWEN_CRYPTMGR_DECRYPTKEY_FN of;
00259 
00260   assert(cm);
00261   of=cm->decryptKeyFn;
00262   cm->decryptKeyFn=f;
00263   return of;
00264 }
00265 
00266 
00267 
00268 int GWEN_CryptMgr_Sign(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00269   GWEN_SIGHEAD *sh;
00270   GWEN_SIGTAIL *st;
00271   GWEN_TIME *ti;
00272   uint32_t pos;
00273   uint32_t shPos;
00274   uint8_t *p;
00275   uint32_t l;
00276   int rv;
00277   GWEN_BUFFER *sigbuf;
00278 
00279   assert(cm);
00280   GWEN_Buffer_AppendByte(dbuf, GWEN_CRYPTMGR_TLV_SIGNEDOBJECT);
00281   pos=GWEN_Buffer_GetPos(dbuf);
00282   GWEN_Buffer_AppendByte(dbuf, 0);
00283   GWEN_Buffer_AppendByte(dbuf, 0);
00284 
00285   /* prepare signature head */
00286   sh=GWEN_SigHead_new();
00287   GWEN_SigHead_SetKeyName(sh, cm->localKeyName);
00288   GWEN_SigHead_SetKeyNumber(sh, cm->localKeyNumber);
00289   GWEN_SigHead_SetKeyVersion(sh, cm->localKeyVersion);
00290   ti=GWEN_CurrentTime();
00291   GWEN_SigHead_SetDateTime(sh, ti);
00292   GWEN_Time_free(ti);
00293   GWEN_SigHead_SetSignatureProfile(sh, cm->signatureProfile);
00294   GWEN_SigHead_SetSignatureNumber(sh, 1);
00295 
00296   /* write signature head to buffer */
00297   shPos=GWEN_Buffer_GetPos(dbuf);
00298   rv=GWEN_SigHead_toBuffer(sh, dbuf, GWEN_CRYPTMGR_TLV_SIGHEAD);
00299   GWEN_SigHead_free(sh);
00300   if (rv<0) {
00301     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00302     return rv;
00303   }
00304 
00305   /* write data to buffer */
00306   if (pData && lData)
00307     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPTMGR_TLV_SIGDATA,
00308                                 (const char*)pData,
00309                                 lData,
00310                                 dbuf);
00311 
00312   /* sign data: signature head TLV + data TLV */
00313   sigbuf=GWEN_Buffer_new(0, 300, 0, 1);
00314   p=((uint8_t*)GWEN_Buffer_GetStart(dbuf))+shPos;
00315   l=GWEN_Buffer_GetPos(dbuf)-shPos;
00316   rv=GWEN_CryptMgr_SignData(cm, p, l, sigbuf);
00317   if (rv<0) {
00318     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00319     GWEN_Buffer_free(sigbuf);
00320     return rv;
00321   }
00322 
00323   /* create signature tail */
00324   st=GWEN_SigTail_new();
00325   GWEN_SigTail_SetSignature(st,
00326                             (const uint8_t*)GWEN_Buffer_GetStart(sigbuf),
00327                             GWEN_Buffer_GetUsedBytes(sigbuf));
00328   GWEN_Buffer_free(sigbuf);
00329   GWEN_SigTail_SetSignatureNumber(st, 1);
00330 
00331   /* write signature tail */
00332   rv=GWEN_SigTail_toBuffer(st, dbuf, GWEN_CRYPTMGR_TLV_SIGTAIL);
00333   GWEN_SigTail_free(st);
00334   if (rv<0) {
00335     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00336     return rv;
00337   }
00338 
00339   /* write complete size */
00340   l=GWEN_Buffer_GetPos(dbuf)-pos-2;
00341   p=(uint8_t*)GWEN_Buffer_GetStart(dbuf)+pos;
00342   *(p++)=l & 0xff;
00343   *p=(l>>8) & 0xff;
00344 
00345   return 0;
00346 }
00347 
00348 
00349 
00350 int GWEN_CryptMgr_Encrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00351   GWEN_CRYPTHEAD *ch;
00352   uint32_t pos;
00353   uint8_t *p;
00354   uint32_t l;
00355   int rv;
00356   GWEN_BUFFER *cryptbuf;
00357   GWEN_BUFFER *tbuf;
00358   GWEN_CRYPT_KEY *mkey;
00359 
00360   assert(cm);
00361 
00362   /* generate a message key */
00363   mkey=GWEN_Crypt_KeyBlowFish_Generate(GWEN_Crypt_CryptMode_Cbc, 256/8, 2);
00364   if (mkey==NULL) {
00365     DBG_ERROR(GWEN_LOGDOMAIN, "Unable to generate BLOWFISH key");
00366     return GWEN_ERROR_GENERIC;
00367   }
00368 
00369   GWEN_Buffer_AppendByte(dbuf, GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT);
00370   pos=GWEN_Buffer_GetPos(dbuf);
00371   GWEN_Buffer_AppendByte(dbuf, 0);
00372   GWEN_Buffer_AppendByte(dbuf, 0);
00373 
00374   /* prepare signature head */
00375   ch=GWEN_CryptHead_new();
00376   GWEN_CryptHead_SetKeyName(ch, cm->peerKeyName);
00377   GWEN_CryptHead_SetKeyNumber(ch, cm->peerKeyNumber);
00378   GWEN_CryptHead_SetKeyVersion(ch, cm->peerKeyVersion);
00379   GWEN_CryptHead_SetCryptProfile(ch, cm->signatureProfile);
00380 
00381   /* encrypt key */
00382   cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1);
00383   rv=GWEN_CryptMgr_EncryptKey(cm,
00384                               GWEN_Crypt_KeyBlowFish_GetKeyDataPtr(mkey),
00385                               GWEN_Crypt_KeyBlowFish_GetKeyDataLen(mkey),
00386                               cryptbuf);
00387   if (rv<0) {
00388     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00389     GWEN_Buffer_free(cryptbuf);
00390     GWEN_CryptHead_free(ch);
00391     GWEN_Crypt_Key_free(mkey);
00392     return rv;
00393   }
00394   GWEN_CryptHead_SetKey(ch,
00395                         (const uint8_t*)GWEN_Buffer_GetStart(cryptbuf),
00396                         GWEN_Buffer_GetUsedBytes(cryptbuf));
00397   GWEN_Buffer_free(cryptbuf);
00398 
00399   /* write crypt head to buffer */
00400   rv=GWEN_CryptHead_toBuffer(ch, dbuf, GWEN_CRYPTMGR_TLV_CRYPTHEAD);
00401   GWEN_CryptHead_free(ch);
00402   if (rv<0) {
00403     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00404     GWEN_Crypt_Key_free(mkey);
00405     return rv;
00406   }
00407 
00408   /* padd plain text data */
00409   tbuf=GWEN_Buffer_new(0, lData+256, 0, 1);
00410   GWEN_Buffer_AppendBytes(tbuf, (const char*)pData, lData);
00411   GWEN_Padd_PaddWithAnsiX9_23(tbuf);
00412 
00413   /* encrypt with message key */
00414   cryptbuf=GWEN_Buffer_new(0, lData+256, 0, 1);
00415   l=GWEN_Buffer_GetMaxUnsegmentedWrite(cryptbuf);
00416   rv=GWEN_Crypt_Key_Encipher(mkey,
00417                              (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
00418                              GWEN_Buffer_GetUsedBytes(tbuf),
00419                              (uint8_t*)GWEN_Buffer_GetStart(cryptbuf),
00420                              &l);
00421   GWEN_Buffer_free(tbuf);
00422   if (rv<0) {
00423     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00424     GWEN_Buffer_free(cryptbuf);
00425     GWEN_Crypt_Key_free(mkey);
00426     return rv;
00427   }
00428   GWEN_Buffer_IncrementPos(cryptbuf, l);
00429   GWEN_Buffer_AdjustUsedBytes(cryptbuf);
00430 
00431   /* write encrypted data */
00432   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPTMGR_TLV_CRYPTDATA,
00433                               GWEN_Buffer_GetStart(cryptbuf),
00434                               GWEN_Buffer_GetUsedBytes(cryptbuf),
00435                               dbuf);
00436   GWEN_Buffer_free(cryptbuf);
00437   GWEN_Crypt_Key_free(mkey);
00438 
00439   /* write complete size */
00440   l=GWEN_Buffer_GetPos(dbuf)-pos-2;
00441   p=(uint8_t*)GWEN_Buffer_GetStart(dbuf)+pos;
00442   *(p++)=l & 0xff;
00443   *p=(l>>8) & 0xff;
00444 
00445   return 0;
00446 }
00447 
00448 
00449 
00450 int GWEN_CryptMgr_Verify(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00451   GWEN_TAG16 *tag;
00452   const uint8_t *p;
00453   uint32_t l;
00454   GWEN_SIGHEAD *sh=NULL;
00455   GWEN_SIGTAIL *st=NULL;
00456   const uint8_t *pSignedData=NULL;
00457   uint32_t lSignedData=0;
00458   int rv;
00459 
00460   assert(cm);
00461   if (lData<3) {
00462     DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
00463     return GWEN_ERROR_BAD_DATA;
00464   }
00465 
00466   tag=GWEN_Tag16_fromBuffer2(pData, lData, 0);
00467   if (tag==NULL) {
00468     DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV");
00469     return GWEN_ERROR_BAD_DATA;
00470   }
00471 
00472   if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_SIGNEDOBJECT) {
00473     DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain asigned object");
00474     GWEN_Tag16_free(tag);
00475     return GWEN_ERROR_BAD_DATA;
00476   }
00477 
00478   p=GWEN_Tag16_GetTagData(tag);
00479   l=GWEN_Tag16_GetTagLength(tag);
00480 
00481   /* read sighead */
00482   if (l) {
00483     GWEN_TAG16 *subtag;
00484 
00485     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
00486     if (subtag) {
00487       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGHEAD) {
00488         sh=GWEN_SigHead_fromBuffer(GWEN_Tag16_GetTagData(subtag),
00489                                    GWEN_Tag16_GetTagLength(subtag));
00490         if (sh) {
00491           pSignedData=p;
00492           lSignedData=GWEN_Tag16_GetTagSize(subtag);
00493         }
00494       }
00495       p+=GWEN_Tag16_GetTagSize(subtag);
00496       l-=GWEN_Tag16_GetTagSize(subtag);
00497       GWEN_Tag16_free(subtag);
00498     }
00499   }
00500 
00501   /* read and store signed data */
00502   if (l) {
00503     GWEN_TAG16 *subtag;
00504 
00505     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
00506     if (subtag) {
00507       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGDATA) {
00508         GWEN_Buffer_AppendBytes(dbuf,
00509                                 GWEN_Tag16_GetTagData(subtag),
00510                                 GWEN_Tag16_GetTagLength(subtag));
00511         if ((pSignedData+lSignedData)==p) {
00512           lSignedData+=GWEN_Tag16_GetTagSize(subtag);
00513         }
00514         else {
00515           DBG_ERROR(GWEN_LOGDOMAIN, "data TLV must follow sighead TLV");
00516           GWEN_Tag16_free(subtag);
00517           GWEN_SigHead_free(sh);
00518           GWEN_Tag16_free(tag);
00519           return GWEN_ERROR_BAD_DATA;
00520         }
00521       }
00522       p+=GWEN_Tag16_GetTagSize(subtag);
00523       l-=GWEN_Tag16_GetTagSize(subtag);
00524       GWEN_Tag16_free(subtag);
00525     }
00526   }
00527 
00528   /* read sigtail (contains the signature) */
00529   if (l) {
00530     GWEN_TAG16 *subtag;
00531 
00532     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
00533     if (subtag) {
00534       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_SIGTAIL) {
00535         st=GWEN_SigTail_fromBuffer(GWEN_Tag16_GetTagData(subtag),
00536                                    GWEN_Tag16_GetTagLength(subtag));
00537       }
00538       p+=GWEN_Tag16_GetTagSize(subtag);
00539       l-=GWEN_Tag16_GetTagSize(subtag);
00540       GWEN_Tag16_free(subtag);
00541     }
00542   }
00543 
00544   /* check for all needed components */
00545   if (!(sh && st && pSignedData && lSignedData)) {
00546     DBG_ERROR(GWEN_LOGDOMAIN, "Signed object is not complete");
00547     GWEN_SigTail_free(st);
00548     GWEN_SigHead_free(sh);
00549     GWEN_Tag16_free(tag);
00550     return GWEN_ERROR_BAD_DATA;
00551   }
00552 
00553   if (GWEN_SigHead_GetSignatureNumber(sh)!=GWEN_SigTail_GetSignatureNumber(st)) {
00554     DBG_ERROR(GWEN_LOGDOMAIN, "Sighead doesn't match sigtail");
00555     GWEN_SigTail_free(st);
00556     GWEN_SigHead_free(sh);
00557     GWEN_Tag16_free(tag);
00558     return GWEN_ERROR_BAD_DATA;
00559   }
00560 
00561   /* store or check peer key info */
00562   if (cm->peerKeyName==NULL) {
00563     /* store peer info */
00564     GWEN_CryptMgr_SetPeerKeyName(cm, GWEN_SigHead_GetKeyName(sh));
00565     GWEN_CryptMgr_SetPeerKeyNumber(cm, GWEN_SigHead_GetKeyNumber(sh));
00566     GWEN_CryptMgr_SetPeerKeyVersion(cm, GWEN_SigHead_GetKeyVersion(sh));
00567   }
00568   else {
00569     const char *s;
00570 
00571     /* compare peer info with expected info */
00572     s=GWEN_SigHead_GetKeyName(sh);
00573     if (!(cm->peerKeyName && s && (strcasecmp(cm->peerKeyName, s)==0) &&
00574           (cm->peerKeyNumber==GWEN_SigHead_GetKeyNumber(sh)) &&
00575           (cm->peerKeyVersion==GWEN_SigHead_GetKeyVersion(sh)))) {
00576       DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected peer key information in signature");
00577       GWEN_SigTail_free(st);
00578       GWEN_SigHead_free(sh);
00579       GWEN_Tag16_free(tag);
00580 
00581       return GWEN_ERROR_BAD_DATA;
00582     }
00583   }
00584 
00585   /* verify signature */
00586   rv=GWEN_CryptMgr_VerifyData(cm,
00587                               pSignedData, lSignedData,
00588                               GWEN_SigTail_GetSignaturePtr(st),
00589                               GWEN_SigTail_GetSignatureLen(st));
00590   GWEN_SigTail_free(st);
00591   GWEN_SigHead_free(sh);
00592   GWEN_Tag16_free(tag);
00593 
00594   if (rv<0) {
00595     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00596     return rv;
00597   }
00598 
00599   return 0;
00600 }
00601 
00602 
00603 
00604 int GWEN_CryptMgr_Decrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00605   GWEN_TAG16 *tag;
00606   const uint8_t *p;
00607   uint32_t l;
00608   GWEN_CRYPTHEAD *ch=NULL;
00609   const uint8_t *pEncryptedData=NULL;
00610   uint32_t lEncryptedData=0;
00611   int rv;
00612   GWEN_BUFFER *tbuf;
00613   GWEN_CRYPT_KEY *mkey;
00614 
00615   assert(cm);
00616   if (lData<3) {
00617     DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
00618     return GWEN_ERROR_BAD_DATA;
00619   }
00620 
00621   tag=GWEN_Tag16_fromBuffer2(pData, lData, 0);
00622   if (tag==NULL) {
00623     DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV");
00624     return GWEN_ERROR_BAD_DATA;
00625   }
00626 
00627   if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT) {
00628     DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain an encrypted object");
00629     GWEN_Tag16_free(tag);
00630     return GWEN_ERROR_BAD_DATA;
00631   }
00632 
00633   p=GWEN_Tag16_GetTagData(tag);
00634   l=GWEN_Tag16_GetTagLength(tag);
00635 
00636   /* read crypthead */
00637   if (l) {
00638     GWEN_TAG16 *subtag;
00639 
00640     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
00641     if (subtag) {
00642       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTHEAD) {
00643         ch=GWEN_CryptHead_fromBuffer(GWEN_Tag16_GetTagData(subtag),
00644                                      GWEN_Tag16_GetTagLength(subtag));
00645       }
00646       p+=GWEN_Tag16_GetTagSize(subtag);
00647       l-=GWEN_Tag16_GetTagSize(subtag);
00648       GWEN_Tag16_free(subtag);
00649     }
00650   }
00651 
00652   /* read encrypted data */
00653   if (l) {
00654     GWEN_TAG16 *subtag;
00655 
00656     subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
00657     if (subtag) {
00658       if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTDATA) {
00659         pEncryptedData=GWEN_Tag16_GetTagData(subtag);
00660         lEncryptedData=GWEN_Tag16_GetTagLength(subtag);
00661       }
00662       p+=GWEN_Tag16_GetTagSize(subtag);
00663       l-=GWEN_Tag16_GetTagSize(subtag);
00664       GWEN_Tag16_free(subtag);
00665     }
00666   }
00667 
00668   /* check for all needed components */
00669   if (!(ch && pEncryptedData && lEncryptedData)) {
00670     DBG_ERROR(GWEN_LOGDOMAIN, "Encrypted object is not complete");
00671     GWEN_CryptHead_free(ch);
00672     GWEN_Tag16_free(tag);
00673     return GWEN_ERROR_BAD_DATA;
00674   }
00675 
00676   /* store or check peer key info */
00677   if (cm->localKeyName) {
00678     const char *s;
00679 
00680     /* compare peer info with expected info */
00681     s=GWEN_CryptHead_GetKeyName(ch);
00682     if (!(cm->localKeyName && s && (strcasecmp(cm->localKeyName, s)==0) &&
00683           (cm->localKeyNumber==GWEN_CryptHead_GetKeyNumber(ch)) &&
00684           (cm->localKeyVersion==GWEN_CryptHead_GetKeyVersion(ch)))) {
00685       DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected local key information in signature");
00686       GWEN_CryptHead_free(ch);
00687       GWEN_Tag16_free(tag);
00688 
00689       return GWEN_ERROR_BAD_DATA;
00690     }
00691   }
00692 
00693   /* decrypt message key */
00694   tbuf=GWEN_Buffer_new(0, GWEN_CryptHead_GetKeyLen(ch), 0, 1);
00695   rv=GWEN_CryptMgr_DecryptKey(cm,
00696                               GWEN_CryptHead_GetKeyPtr(ch),
00697                               GWEN_CryptHead_GetKeyLen(ch),
00698                               tbuf);
00699   GWEN_CryptHead_free(ch);
00700   if (rv<0) {
00701     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00702     GWEN_Buffer_free(tbuf);
00703     GWEN_Tag16_free(tag);
00704     return rv;
00705   }
00706 
00707   /* create message key */
00708   mkey=GWEN_Crypt_KeyBlowFish_fromData(GWEN_Crypt_CryptMode_Cbc,
00709                                        256/8,
00710                                        (const uint8_t*) GWEN_Buffer_GetStart(tbuf),
00711                                        GWEN_Buffer_GetUsedBytes(tbuf));
00712   GWEN_Buffer_free(tbuf);
00713   if (mkey==NULL) {
00714     DBG_ERROR(GWEN_LOGDOMAIN, "Unable to create BLOWFISH key from received data");
00715     GWEN_Tag16_free(tag);
00716     return GWEN_ERROR_BAD_DATA;
00717   }
00718 
00719 
00720   /* decrypt data with message key */
00721   tbuf=GWEN_Buffer_new(0, lEncryptedData+256, 0, 1);
00722   l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
00723   rv=GWEN_Crypt_Key_Decipher(mkey,
00724                              pEncryptedData, lEncryptedData,
00725                              (uint8_t*)GWEN_Buffer_GetStart(tbuf),
00726                              &l);
00727   if (rv<0) {
00728     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00729     GWEN_Buffer_free(tbuf);
00730     GWEN_Crypt_Key_free(mkey);
00731     GWEN_Tag16_free(tag);
00732     return rv;
00733   }
00734   GWEN_Buffer_IncrementPos(tbuf, l);
00735   GWEN_Buffer_AdjustUsedBytes(tbuf);
00736 
00737   /* unpadd data */
00738   rv=GWEN_Padd_UnpaddWithAnsiX9_23(tbuf);
00739   if (rv<0) {
00740     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00741     GWEN_Buffer_free(tbuf);
00742     GWEN_Crypt_Key_free(mkey);
00743     GWEN_Tag16_free(tag);
00744     return rv;
00745   }
00746 
00747   /* store data */
00748   GWEN_Buffer_AppendBuffer(dbuf, tbuf);
00749 
00750   GWEN_Buffer_free(tbuf);
00751   GWEN_Crypt_Key_free(mkey);
00752   GWEN_Tag16_free(tag);
00753 
00754   return 0;
00755 }
00756 
00757 
00758 
00759 int GWEN_CryptMgr_Encode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00760   GWEN_BUFFER *tbuf;
00761   int rv;
00762 
00763   tbuf=GWEN_Buffer_new(0, lData, 0, 1);
00764 
00765   /* create signed object */
00766   DBG_INFO(GWEN_LOGDOMAIN, "Signing data");
00767   rv=GWEN_CryptMgr_Sign(cm, pData, lData, tbuf);
00768   if (rv<0) {
00769     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00770     GWEN_Buffer_free(tbuf);
00771     return rv;
00772   }
00773 
00774   /* create encrypted object (containing a signed object in this case) */
00775   DBG_INFO(GWEN_LOGDOMAIN, "Encrypting data");
00776   rv=GWEN_CryptMgr_Encrypt(cm,
00777                            (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
00778                            GWEN_Buffer_GetUsedBytes(tbuf),
00779                            dbuf);
00780   GWEN_Buffer_free(tbuf);
00781   if (rv<0) {
00782     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00783     return rv;
00784   }
00785 
00786   return 0;
00787 }
00788 
00789 
00790 
00791 int GWEN_CryptMgr_Decode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
00792   GWEN_BUFFER *tbuf;
00793   int rv;
00794 
00795   tbuf=GWEN_Buffer_new(0, lData, 0, 1);
00796 
00797   /* decrypt encrypted object */
00798   DBG_INFO(GWEN_LOGDOMAIN, "Decrypting data");
00799   rv=GWEN_CryptMgr_Decrypt(cm, pData, lData, tbuf);
00800   if (rv<0) {
00801     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00802     GWEN_Buffer_free(tbuf);
00803     return rv;
00804   }
00805 
00806   /* verify signature, copy signed data to dbuf in the process */
00807   DBG_INFO(GWEN_LOGDOMAIN, "Verifying data");
00808   rv=GWEN_CryptMgr_Verify(cm,
00809                           (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
00810                           GWEN_Buffer_GetUsedBytes(tbuf),
00811                           dbuf);
00812   GWEN_Buffer_free(tbuf);
00813   if (rv<0) {
00814     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00815     return rv;
00816   }
00817 
00818   return 0;
00819 }
00820 
00821 
00822 
00823 
00824