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)