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