00001
00002
00003
00004
00005
00006
00007
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
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
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
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
00207
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
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
00231
00232
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
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
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