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