gwenhywfar 4.0.3

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