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