gwenhywfar 4.0.3
|
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