Mercurial > pidgin.yaz
comparison libpurple/cipher.c @ 17977:f71bd7e56389
propagate from branch 'im.pidgin.pidgin' (head b438ea0760758dc547f95d62892455f50ee4c4f1)
to branch 'im.pidgin.soc.2007.remotelogging' (head 7e683fd40634aa3eb22dcf25cbd25c8959d76662)
author | Michael Shkutkov <mshkutkov@soc.pidgin.im> |
---|---|
date | Sat, 09 Jun 2007 12:01:29 +0000 |
parents | 103a37dd9398 |
children | 9a1c7a566d7c 941965d6fd88 |
comparison
equal
deleted
inserted
replaced
16392:9da82444eee3 | 17977:f71bd7e56389 |
---|---|
337 NULL, /* encrypt */ | 337 NULL, /* encrypt */ |
338 NULL, /* decrypt */ | 338 NULL, /* decrypt */ |
339 NULL, /* set salt */ | 339 NULL, /* set salt */ |
340 NULL, /* get salt size */ | 340 NULL, /* get salt size */ |
341 NULL, /* set key */ | 341 NULL, /* set key */ |
342 NULL /* get key size */ | 342 NULL, /* get key size */ |
343 | |
344 /* padding */ | |
345 NULL, | |
346 NULL, | |
347 NULL, | |
348 NULL | |
343 }; | 349 }; |
344 | 350 |
345 /******************************************************************************* | 351 /******************************************************************************* |
346 * MD4 | 352 * MD4 |
347 ******************************************************************************/ | 353 ******************************************************************************/ |
586 NULL, /* encrypt */ | 592 NULL, /* encrypt */ |
587 NULL, /* decrypt */ | 593 NULL, /* decrypt */ |
588 NULL, /* set salt */ | 594 NULL, /* set salt */ |
589 NULL, /* get salt size */ | 595 NULL, /* get salt size */ |
590 NULL, /* set key */ | 596 NULL, /* set key */ |
591 NULL /* get key size */ | 597 NULL, /* get key size */ |
598 | |
599 /* padding */ | |
600 NULL, | |
601 NULL, | |
602 NULL, | |
603 NULL | |
592 }; | 604 }; |
593 | 605 |
594 /****************************************************************************** | 606 /****************************************************************************** |
595 * DES | 607 * DES |
596 *****************************************************************************/ | 608 *****************************************************************************/ |
1004 des_encrypt, /* encrypt */ | 1016 des_encrypt, /* encrypt */ |
1005 NULL, /* decrypt */ | 1017 NULL, /* decrypt */ |
1006 NULL, /* set salt */ | 1018 NULL, /* set salt */ |
1007 NULL, /* get salt size */ | 1019 NULL, /* get salt size */ |
1008 des_set_key, /* set key */ | 1020 des_set_key, /* set key */ |
1009 NULL /* get key size */ | 1021 NULL, /* get key size */ |
1022 | |
1023 /* padding */ | |
1024 NULL, | |
1025 NULL, | |
1026 NULL, | |
1027 NULL | |
1010 }; | 1028 }; |
1011 | 1029 |
1012 | 1030 |
1013 /******************************************************************************* | 1031 /******************************************************************************* |
1014 * SHA-1 | 1032 * SHA-1 |
1245 NULL, /* encrypt */ | 1263 NULL, /* encrypt */ |
1246 NULL, /* decrypt */ | 1264 NULL, /* decrypt */ |
1247 NULL, /* set salt */ | 1265 NULL, /* set salt */ |
1248 NULL, /* get salt size */ | 1266 NULL, /* get salt size */ |
1249 NULL, /* set key */ | 1267 NULL, /* set key */ |
1250 NULL /* get key size */ | 1268 NULL, /* get key size */ |
1269 | |
1270 /* padding */ | |
1271 NULL, | |
1272 NULL, | |
1273 NULL, | |
1274 NULL | |
1275 }; | |
1276 | |
1277 /******************************************************************************* | |
1278 * RC4 | |
1279 ******************************************************************************/ | |
1280 | |
1281 struct RC4Context { | |
1282 guchar state[256]; | |
1283 guchar x; | |
1284 guchar y; | |
1285 gint key_len; | |
1286 }; | |
1287 | |
1288 static void | |
1289 rc4_init(PurpleCipherContext *context, void *extra) { | |
1290 struct RC4Context *rc4_ctx; | |
1291 rc4_ctx = g_new0(struct RC4Context, 1); | |
1292 purple_cipher_context_set_data(context, rc4_ctx); | |
1293 purple_cipher_context_reset(context, extra); | |
1294 } | |
1295 | |
1296 | |
1297 static void | |
1298 rc4_reset(PurpleCipherContext *context, void *extra) { | |
1299 struct RC4Context *rc4_ctx; | |
1300 guint i; | |
1301 | |
1302 rc4_ctx = purple_cipher_context_get_data(context); | |
1303 | |
1304 g_return_if_fail(rc4_ctx); | |
1305 | |
1306 for(i = 0; i < 256; i++) | |
1307 rc4_ctx->state[i] = i; | |
1308 rc4_ctx->x = 0; | |
1309 rc4_ctx->y = 0; | |
1310 | |
1311 /* default is 5 bytes (40bit key) */ | |
1312 rc4_ctx->key_len = 5; | |
1313 | |
1314 } | |
1315 | |
1316 static void | |
1317 rc4_uninit(PurpleCipherContext *context) { | |
1318 struct RC4Context *rc4_ctx; | |
1319 | |
1320 rc4_ctx = purple_cipher_context_get_data(context); | |
1321 memset(rc4_ctx, 0, sizeof(rc4_ctx)); | |
1322 | |
1323 g_free(rc4_ctx); | |
1324 rc4_ctx = NULL; | |
1325 } | |
1326 | |
1327 | |
1328 | |
1329 static void | |
1330 rc4_set_key (PurpleCipherContext *context, const guchar * key) { | |
1331 struct RC4Context *ctx; | |
1332 guchar *state; | |
1333 guchar temp_swap; | |
1334 guchar x, y; | |
1335 guint i; | |
1336 | |
1337 ctx = purple_cipher_context_get_data(context); | |
1338 | |
1339 x = 0; | |
1340 y = 0; | |
1341 state = &ctx->state[0]; | |
1342 for(i = 0; i < 256; i++) | |
1343 { | |
1344 y = (key[x] + state[i] + y) % 256; | |
1345 temp_swap = state[i]; | |
1346 state[i] = state[y]; | |
1347 state[y] = temp_swap; | |
1348 x = (x + 1) % ctx->key_len; | |
1349 } | |
1350 } | |
1351 | |
1352 static void | |
1353 rc4_set_opt(PurpleCipherContext *context, const gchar *name, void *value) { | |
1354 struct RC4Context *ctx; | |
1355 | |
1356 ctx = purple_cipher_context_get_data(context); | |
1357 | |
1358 if(!strcmp(name, "key_len")) { | |
1359 ctx->key_len = GPOINTER_TO_INT(value); | |
1360 } | |
1361 } | |
1362 | |
1363 static size_t | |
1364 rc4_get_key_size (PurpleCipherContext *context) | |
1365 { | |
1366 struct RC4Context *ctx; | |
1367 | |
1368 g_return_val_if_fail(context, -1); | |
1369 | |
1370 ctx = purple_cipher_context_get_data(context); | |
1371 | |
1372 g_return_val_if_fail(ctx, -1); | |
1373 | |
1374 return ctx->key_len; | |
1375 } | |
1376 | |
1377 static void * | |
1378 rc4_get_opt(PurpleCipherContext *context, const gchar *name) { | |
1379 struct RC4Context *ctx; | |
1380 | |
1381 ctx = purple_cipher_context_get_data(context); | |
1382 | |
1383 if(!strcmp(name, "key_len")) { | |
1384 return GINT_TO_POINTER(ctx->key_len); | |
1385 } | |
1386 | |
1387 return NULL; | |
1388 } | |
1389 | |
1390 static gint | |
1391 rc4_encrypt(PurpleCipherContext *context, const guchar data[], | |
1392 size_t len, guchar output[], size_t *outlen) { | |
1393 struct RC4Context *ctx; | |
1394 guchar temp_swap; | |
1395 guchar x, y, z; | |
1396 guchar *state; | |
1397 guint i; | |
1398 | |
1399 ctx = purple_cipher_context_get_data(context); | |
1400 | |
1401 x = ctx->x; | |
1402 y = ctx->y; | |
1403 state = &ctx->state[0]; | |
1404 | |
1405 for(i = 0; i < len; i++) | |
1406 { | |
1407 x = (x + 1) % 256; | |
1408 y = (state[x] + y) % 256; | |
1409 temp_swap = state[x]; | |
1410 state[x] = state[y]; | |
1411 state[y] = temp_swap; | |
1412 z = state[x] + (state[y]) % 256; | |
1413 output[i] = data[i] ^ state[z]; | |
1414 } | |
1415 ctx->x = x; | |
1416 ctx->y = y; | |
1417 if(outlen) | |
1418 *outlen = len; | |
1419 | |
1420 return 0; | |
1421 } | |
1422 | |
1423 static PurpleCipherOps RC4Ops = { | |
1424 rc4_set_opt, /* Set Option */ | |
1425 rc4_get_opt, /* Get Option */ | |
1426 rc4_init, /* init */ | |
1427 rc4_reset, /* reset */ | |
1428 rc4_uninit, /* uninit */ | |
1429 NULL, /* set iv */ | |
1430 NULL, /* append */ | |
1431 NULL, /* digest */ | |
1432 rc4_encrypt, /* encrypt */ | |
1433 NULL, /* decrypt */ | |
1434 NULL, /* set salt */ | |
1435 NULL, /* get salt size */ | |
1436 rc4_set_key, /* set key */ | |
1437 rc4_get_key_size, /* get key size */ | |
1438 | |
1439 /* padding */ | |
1440 NULL, | |
1441 NULL, | |
1442 NULL, | |
1443 NULL | |
1251 }; | 1444 }; |
1252 | 1445 |
1253 /******************************************************************************* | 1446 /******************************************************************************* |
1254 * Structs | 1447 * Structs |
1255 ******************************************************************************/ | 1448 ******************************************************************************/ |
1256 struct _PurpleCipher { | 1449 struct _PurpleCipher { |
1257 gchar *name; | 1450 gchar *name; /**< Internal name - used for searching */ |
1258 PurpleCipherOps *ops; | 1451 PurpleCipherOps *ops; /**< Operations supported by this cipher */ |
1259 guint ref; | 1452 guint ref; /**< Reference count */ |
1260 }; | 1453 }; |
1261 | 1454 |
1262 struct _PurpleCipherContext { | 1455 struct _PurpleCipherContext { |
1263 PurpleCipher *cipher; | 1456 PurpleCipher *cipher; /**< Cipher this context is under */ |
1264 gpointer data; | 1457 gpointer data; /**< Internal cipher state data */ |
1265 }; | 1458 }; |
1266 | 1459 |
1267 /****************************************************************************** | 1460 /****************************************************************************** |
1268 * Globals | 1461 * Globals |
1269 *****************************************************************************/ | 1462 *****************************************************************************/ |
1442 | 1635 |
1443 purple_ciphers_register_cipher("md5", &MD5Ops); | 1636 purple_ciphers_register_cipher("md5", &MD5Ops); |
1444 purple_ciphers_register_cipher("sha1", &SHA1Ops); | 1637 purple_ciphers_register_cipher("sha1", &SHA1Ops); |
1445 purple_ciphers_register_cipher("md4", &MD4Ops); | 1638 purple_ciphers_register_cipher("md4", &MD4Ops); |
1446 purple_ciphers_register_cipher("des", &DESOps); | 1639 purple_ciphers_register_cipher("des", &DESOps); |
1640 purple_ciphers_register_cipher("rc4", &RC4Ops); | |
1447 } | 1641 } |
1448 | 1642 |
1449 void | 1643 void |
1450 purple_ciphers_uninit() { | 1644 purple_ciphers_uninit() { |
1451 PurpleCipher *cipher; | 1645 PurpleCipher *cipher; |
1804 g_return_val_if_fail(nonce != NULL, NULL); | 1998 g_return_val_if_fail(nonce != NULL, NULL); |
1805 | 1999 |
1806 /* Check for a supported algorithm. */ | 2000 /* Check for a supported algorithm. */ |
1807 g_return_val_if_fail(algorithm == NULL || | 2001 g_return_val_if_fail(algorithm == NULL || |
1808 *algorithm == '\0' || | 2002 *algorithm == '\0' || |
1809 strcasecmp(algorithm, "MD5") || | 2003 g_ascii_strcasecmp(algorithm, "MD5") || |
1810 strcasecmp(algorithm, "MD5-sess"), NULL); | 2004 g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL); |
1811 | 2005 |
1812 cipher = purple_ciphers_find_cipher("md5"); | 2006 cipher = purple_ciphers_find_cipher("md5"); |
1813 g_return_val_if_fail(cipher != NULL, NULL); | 2007 g_return_val_if_fail(cipher != NULL, NULL); |
1814 | 2008 |
1815 context = purple_cipher_context_new(cipher, NULL); | 2009 context = purple_cipher_context_new(cipher, NULL); |
1818 purple_cipher_context_append(context, (guchar *)":", 1); | 2012 purple_cipher_context_append(context, (guchar *)":", 1); |
1819 purple_cipher_context_append(context, (guchar *)realm, strlen(realm)); | 2013 purple_cipher_context_append(context, (guchar *)realm, strlen(realm)); |
1820 purple_cipher_context_append(context, (guchar *)":", 1); | 2014 purple_cipher_context_append(context, (guchar *)":", 1); |
1821 purple_cipher_context_append(context, (guchar *)password, strlen(password)); | 2015 purple_cipher_context_append(context, (guchar *)password, strlen(password)); |
1822 | 2016 |
1823 if (algorithm != NULL && !strcasecmp(algorithm, "MD5-sess")) | 2017 if (algorithm != NULL && !g_ascii_strcasecmp(algorithm, "MD5-sess")) |
1824 { | 2018 { |
1825 guchar digest[16]; | 2019 guchar digest[16]; |
1826 | 2020 |
1827 if (client_nonce == NULL) | 2021 if (client_nonce == NULL) |
1828 { | 2022 { |
1869 g_return_val_if_fail(session_key != NULL, NULL); | 2063 g_return_val_if_fail(session_key != NULL, NULL); |
1870 | 2064 |
1871 /* Check for a supported algorithm. */ | 2065 /* Check for a supported algorithm. */ |
1872 g_return_val_if_fail(algorithm == NULL || | 2066 g_return_val_if_fail(algorithm == NULL || |
1873 *algorithm == '\0' || | 2067 *algorithm == '\0' || |
1874 strcasecmp(algorithm, "MD5") || | 2068 g_ascii_strcasecmp(algorithm, "MD5") || |
1875 strcasecmp(algorithm, "MD5-sess"), NULL); | 2069 g_ascii_strcasecmp(algorithm, "MD5-sess"), NULL); |
1876 | 2070 |
1877 /* Check for a supported "quality of protection". */ | 2071 /* Check for a supported "quality of protection". */ |
1878 g_return_val_if_fail(qop == NULL || | 2072 g_return_val_if_fail(qop == NULL || |
1879 *qop == '\0' || | 2073 *qop == '\0' || |
1880 strcasecmp(qop, "auth") || | 2074 g_ascii_strcasecmp(qop, "auth") || |
1881 strcasecmp(qop, "auth-int"), NULL); | 2075 g_ascii_strcasecmp(qop, "auth-int"), NULL); |
1882 | 2076 |
1883 cipher = purple_ciphers_find_cipher("md5"); | 2077 cipher = purple_ciphers_find_cipher("md5"); |
1884 g_return_val_if_fail(cipher != NULL, NULL); | 2078 g_return_val_if_fail(cipher != NULL, NULL); |
1885 | 2079 |
1886 context = purple_cipher_context_new(cipher, NULL); | 2080 context = purple_cipher_context_new(cipher, NULL); |
1887 | 2081 |
1888 purple_cipher_context_append(context, (guchar *)method, strlen(method)); | 2082 purple_cipher_context_append(context, (guchar *)method, strlen(method)); |
1889 purple_cipher_context_append(context, (guchar *)":", 1); | 2083 purple_cipher_context_append(context, (guchar *)":", 1); |
1890 purple_cipher_context_append(context, (guchar *)digest_uri, strlen(digest_uri)); | 2084 purple_cipher_context_append(context, (guchar *)digest_uri, strlen(digest_uri)); |
1891 | 2085 |
1892 if (qop != NULL && !strcasecmp(qop, "auth-int")) | 2086 if (qop != NULL && !g_ascii_strcasecmp(qop, "auth-int")) |
1893 { | 2087 { |
1894 PurpleCipherContext *context2; | 2088 PurpleCipherContext *context2; |
1895 gchar entity_hash[33]; | 2089 gchar entity_hash[33]; |
1896 | 2090 |
1897 if (entity == NULL) | 2091 if (entity == NULL) |