cryptmgrkeys.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 
00011 #ifdef HAVE_CONFIG_H
00012 # include <config.h>
00013 #endif
00014 
00015 
00016 #include "cryptmgrkeys_p.h"
00017 #include "i18n_l.h"
00018 #include <gwenhywfar/misc.h>
00019 #include <gwenhywfar/debug.h>
00020 #include <gwenhywfar/mdigest.h>
00021 #include <gwenhywfar/padd.h>
00022 #include <gwenhywfar/crypthead.h>
00023 #include <gwenhywfar/text.h>
00024 
00025 
00026 
00027 GWEN_INHERIT(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS);
00028 
00029 
00030 
00031 GWEN_CRYPTMGR *GWEN_CryptMgrKeys_new(const char *localName,
00032                                      GWEN_CRYPT_KEY *localKey,
00033                                      const char *peerName,
00034                                      GWEN_CRYPT_KEY *peerKey,
00035                                      int ownKeys) {
00036   GWEN_CRYPTMGR *cm;
00037   GWEN_CRYPTMGR_KEYS *xcm;
00038 
00039   cm=GWEN_CryptMgr_new();
00040   GWEN_NEW_OBJECT(GWEN_CRYPTMGR_KEYS, xcm);
00041   GWEN_INHERIT_SETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm, xcm,
00042                        GWEN_CryptMgrKeys_FreeData);
00043 
00044   if (localKey) {
00045     xcm->localKey=localKey;
00046     GWEN_CryptMgr_SetLocalKeyNumber(cm, GWEN_Crypt_Key_GetKeyNumber(localKey));
00047     GWEN_CryptMgr_SetLocalKeyVersion(cm, GWEN_Crypt_Key_GetKeyVersion(localKey));
00048   }
00049   else
00050     xcm->ownLocalKey=0;
00051 
00052   if (peerKey) {
00053     xcm->peerKey=peerKey;
00054     GWEN_CryptMgr_SetPeerKeyNumber(cm, GWEN_Crypt_Key_GetKeyNumber(peerKey));
00055     GWEN_CryptMgr_SetPeerKeyVersion(cm, GWEN_Crypt_Key_GetKeyVersion(peerKey));
00056     xcm->ownPeerKey=ownKeys;
00057   }
00058   else
00059     xcm->ownPeerKey=0;
00060 
00061   if (localName)
00062     GWEN_CryptMgr_SetLocalKeyName(cm, localName);
00063 
00064   if (peerName)
00065     GWEN_CryptMgr_SetPeerKeyName(cm, peerName);
00066 
00067   GWEN_CryptMgr_SetSignDataFn(cm, GWEN_CryptMgrKeys_SignData);
00068   GWEN_CryptMgr_SetVerifyDataFn(cm, GWEN_CryptMgrKeys_VerifyData);
00069   GWEN_CryptMgr_SetEncryptKeyFn(cm, GWEN_CryptMgrKeys_EncryptKey);
00070   GWEN_CryptMgr_SetDecryptKeyFn(cm, GWEN_CryptMgrKeys_DecryptKey);
00071 
00072   return cm;
00073 }
00074 
00075 
00076 
00077 GWENHYWFAR_CB
00078 void GWEN_CryptMgrKeys_FreeData(GWEN_UNUSED void *bp, void *p) {
00079   GWEN_CRYPTMGR_KEYS *xcm;
00080 
00081   xcm=(GWEN_CRYPTMGR_KEYS*) p;
00082 
00083   if (xcm->ownLocalKey)
00084     GWEN_Crypt_Key_free(xcm->localKey);
00085   if (xcm->ownPeerKey)
00086     GWEN_Crypt_Key_free(xcm->peerKey);
00087 }
00088 
00089 
00090 
00091 void GWEN_CryptMgrKeys_SetPeerKey(GWEN_CRYPTMGR *cm,
00092                                   GWEN_CRYPT_KEY *peerKey,
00093                                   int ownKey) {
00094   GWEN_CRYPTMGR_KEYS *xcm;
00095 
00096   assert(cm);
00097   xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
00098   assert(xcm);
00099 
00100   if (xcm->ownPeerKey)
00101     GWEN_Crypt_Key_free(xcm->peerKey);
00102   xcm->peerKey=peerKey;
00103   xcm->ownPeerKey=ownKey;
00104 }
00105 
00106 
00107 
00108 GWENHYWFAR_CB
00109 int GWEN_CryptMgrKeys_SignData(GWEN_CRYPTMGR *cm,
00110                                const uint8_t *pData, uint32_t lData,
00111                                GWEN_BUFFER *dbuf) {
00112   GWEN_CRYPTMGR_KEYS *xcm;
00113   GWEN_MDIGEST *md;
00114   int rv;
00115   GWEN_BUFFER *tbuf;
00116   int ksize;
00117   uint32_t signatureLen;
00118 
00119   assert(cm);
00120   xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
00121   assert(xcm);
00122 
00123   if (xcm->localKey==NULL) {
00124     DBG_ERROR(GWEN_LOGDOMAIN, "No local key");
00125     return GWEN_ERROR_GENERIC;
00126   }
00127 
00128   ksize=GWEN_Crypt_Key_GetKeySize(xcm->localKey);
00129 
00130   /* hash pData */
00131   md=GWEN_MDigest_Rmd160_new();
00132   rv=GWEN_MDigest_Begin(md);
00133   if (rv<0) {
00134     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00135     GWEN_MDigest_free(md);
00136     return rv;
00137   }
00138   rv=GWEN_MDigest_Update(md, pData, lData);
00139   if (rv<0) {
00140     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00141     GWEN_MDigest_free(md);
00142     return rv;
00143   }
00144   rv=GWEN_MDigest_End(md);
00145   if (rv<0) {
00146     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00147     GWEN_MDigest_free(md);
00148     return rv;
00149   }
00150 
00151   /* padd */
00152   tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
00153   GWEN_Buffer_AppendBytes(tbuf,
00154                           (const char*)GWEN_MDigest_GetDigestPtr(md),
00155                           GWEN_MDigest_GetDigestSize(md));
00156   GWEN_MDigest_free(md);
00157   GWEN_Padd_PaddWithIso9796_2(tbuf, ksize);
00158 
00159   /* sign */
00160   GWEN_Buffer_AllocRoom(dbuf, ksize);
00161   signatureLen=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf);
00162   rv=GWEN_Crypt_Key_Sign(xcm->localKey,
00163                          (uint8_t*)GWEN_Buffer_GetStart(tbuf),
00164                          GWEN_Buffer_GetUsedBytes(tbuf),
00165                          (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf),
00166                          &signatureLen);
00167   GWEN_Buffer_free(tbuf);
00168   if (rv<0) {
00169     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00170     return rv;
00171   }
00172 
00173   GWEN_Buffer_IncrementPos(dbuf, signatureLen);
00174   GWEN_Buffer_AdjustUsedBytes(dbuf);
00175 
00176   return 0;
00177 }
00178 
00179 
00180 
00181 GWENHYWFAR_CB
00182 int GWEN_CryptMgrKeys_VerifyData(GWEN_CRYPTMGR *cm,
00183                                  const uint8_t *pData, uint32_t lData,
00184                                  const uint8_t *pSignature, uint32_t lSignature) {
00185   GWEN_CRYPTMGR_KEYS *xcm;
00186   GWEN_MDIGEST *md;
00187   int rv;
00188   GWEN_BUFFER *tbuf;
00189   int ksize;
00190   uint32_t l;
00191 
00192   assert(cm);
00193   xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
00194   assert(xcm);
00195 
00196   if (xcm->peerKey==NULL) {
00197     DBG_ERROR(GWEN_LOGDOMAIN, "No peer key");
00198     return GWEN_ERROR_GENERIC;
00199   }
00200 
00201   ksize=GWEN_Crypt_Key_GetKeySize(xcm->peerKey);
00202 
00203   /* the padding algo uses random numbers, so we must use the encrypt function and
00204    * compare the decoded and unpadded signature with the hash of the source data
00205    */
00206   tbuf=GWEN_Buffer_new(0, ksize+16, 0, 1);
00207   l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
00208   rv=GWEN_Crypt_Key_Encipher(xcm->peerKey,
00209                              pSignature, lSignature,
00210                              (uint8_t*)GWEN_Buffer_GetPosPointer(tbuf),
00211                              &l);
00212   if (rv<0) {
00213     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00214     GWEN_Buffer_free(tbuf);
00215     return rv;
00216   }
00217   GWEN_Buffer_IncrementPos(tbuf, l);
00218   GWEN_Buffer_AdjustUsedBytes(tbuf);
00219 
00220   /* unpadd */
00221   rv=GWEN_Padd_UnpaddWithIso9796_2(tbuf);
00222   if (rv<0) {
00223     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00224     GWEN_Buffer_free(tbuf);
00225     return rv;
00226   }
00227   /* tbuf now contains the hash */
00228 
00229   /* hash source data */
00230   md=GWEN_MDigest_Rmd160_new();
00231   rv=GWEN_MDigest_Begin(md);
00232   if (rv<0) {
00233     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00234     GWEN_MDigest_free(md);
00235     GWEN_Buffer_free(tbuf);
00236     return rv;
00237   }
00238   rv=GWEN_MDigest_Update(md, pData, lData);
00239   if (rv<0) {
00240     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00241     GWEN_MDigest_free(md);
00242     GWEN_Buffer_free(tbuf);
00243     return rv;
00244   }
00245   rv=GWEN_MDigest_End(md);
00246   if (rv<0) {
00247     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00248     GWEN_MDigest_free(md);
00249     GWEN_Buffer_free(tbuf);
00250     return rv;
00251   }
00252 
00253   if (GWEN_MDigest_GetDigestSize(md)!=GWEN_Buffer_GetUsedBytes(tbuf)) {
00254     DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature");
00255     GWEN_MDigest_free(md);
00256     GWEN_Buffer_free(tbuf);
00257     return GWEN_ERROR_VERIFY;
00258   }
00259 
00260   if (memcmp(GWEN_MDigest_GetDigestPtr(md),
00261              GWEN_Buffer_GetStart(tbuf),
00262              GWEN_MDigest_GetDigestSize(md))!=0) {
00263     DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature");
00264     GWEN_MDigest_free(md);
00265     GWEN_Buffer_free(tbuf);
00266     return GWEN_ERROR_VERIFY;
00267   }
00268 
00269   GWEN_MDigest_free(md);
00270   GWEN_Buffer_free(tbuf);
00271 
00272   return 0;
00273 }
00274 
00275 
00276 
00277 GWENHYWFAR_CB
00278 int GWEN_CryptMgrKeys_EncryptKey(GWEN_CRYPTMGR *cm,
00279                                  const uint8_t *pData, uint32_t lData,
00280                                  GWEN_BUFFER *dbuf) {
00281   GWEN_CRYPTMGR_KEYS *xcm;
00282   int rv;
00283   GWEN_BUFFER *tbuf;
00284   int ksize;
00285   uint32_t l;
00286 
00287   assert(cm);
00288   xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
00289   assert(xcm);
00290 
00291   if (xcm->peerKey==NULL) {
00292     DBG_ERROR(GWEN_LOGDOMAIN, "No peer key");
00293     return GWEN_ERROR_GENERIC;
00294   }
00295 
00296   ksize=GWEN_Crypt_Key_GetKeySize(xcm->peerKey);
00297 
00298   /* padd key data */
00299   tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
00300   GWEN_Buffer_AppendBytes(tbuf, (const char*) pData, lData);
00301   rv=GWEN_Padd_PaddWithIso9796_2(tbuf, ksize);
00302   if (rv<0) {
00303     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00304     GWEN_Buffer_free(tbuf);
00305     return rv;
00306   }
00307 
00308   GWEN_Buffer_AllocRoom(dbuf, ksize);
00309   l=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf);
00310   rv=GWEN_Crypt_Key_Encipher(xcm->peerKey,
00311                              (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
00312                              GWEN_Buffer_GetUsedBytes(tbuf),
00313                              (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf),
00314                              &l);
00315   GWEN_Buffer_free(tbuf);
00316   if (rv<0) {
00317     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00318     return rv;
00319   }
00320 
00321   GWEN_Buffer_IncrementPos(dbuf, l);
00322   GWEN_Buffer_AdjustUsedBytes(dbuf);
00323 
00324   return 0;
00325 }
00326 
00327 
00328 
00329 GWENHYWFAR_CB
00330 int GWEN_CryptMgrKeys_DecryptKey(GWEN_CRYPTMGR *cm,
00331                                  const uint8_t *pData, uint32_t lData,
00332                                  GWEN_BUFFER *dbuf) {
00333   GWEN_CRYPTMGR_KEYS *xcm;
00334   int rv;
00335   GWEN_BUFFER *tbuf;
00336   int ksize;
00337   uint32_t l;
00338 
00339   assert(cm);
00340   xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
00341   assert(xcm);
00342 
00343   if (xcm->localKey==NULL) {
00344     DBG_ERROR(GWEN_LOGDOMAIN, "No local key");
00345     return GWEN_ERROR_GENERIC;
00346   }
00347 
00348   ksize=GWEN_Crypt_Key_GetKeySize(xcm->localKey);
00349 
00350   tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
00351   l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
00352   rv=GWEN_Crypt_Key_Decipher(xcm->localKey,
00353                              pData, lData,
00354                              (uint8_t*)GWEN_Buffer_GetPosPointer(tbuf),
00355                              &l);
00356   if (rv<0) {
00357     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00358     GWEN_Buffer_free(tbuf);
00359     return rv;
00360   }
00361   GWEN_Buffer_IncrementPos(tbuf, l);
00362   GWEN_Buffer_AdjustUsedBytes(tbuf);
00363 
00364   /* unpadd data */
00365   rv=GWEN_Padd_UnpaddWithIso9796_2(tbuf);
00366   if (rv<0) {
00367     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00368     GWEN_Buffer_free(tbuf);
00369     return rv;
00370   }
00371 
00372   GWEN_Buffer_AppendBuffer(dbuf, tbuf);
00373   GWEN_Buffer_free(tbuf);
00374 
00375   return 0;
00376 }
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 

Generated on Thu Aug 20 13:54:37 2009 for gwenhywfar by  doxygen 1.5.9