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

Generated by  doxygen 1.6.2