aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_uri.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-11 22:24:07 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-11 22:24:07 +0000
commit596fe6fcff78fc66f2ed7e8bd46475feef9c6210 (patch)
treef2d48964e5d77ada7f9f5188b5f8c35483dded66 /src/fs/fs_uri.c
parentb309c5f5ae339faf3632f7ee3a86520981f6523a (diff)
downloadgnunet-596fe6fcff78fc66f2ed7e8bd46475feef9c6210.tar.gz
gnunet-596fe6fcff78fc66f2ed7e8bd46475feef9c6210.zip
more work on FS URIs
Diffstat (limited to 'src/fs/fs_uri.c')
-rw-r--r--src/fs/fs_uri.c211
1 files changed, 119 insertions, 92 deletions
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index 10ffe1350..cf0e8a067 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -80,6 +80,7 @@
80 */ 80 */
81#include "platform.h" 81#include "platform.h"
82#include "gnunet_fs_service.h" 82#include "gnunet_fs_service.h"
83#include "gnunet_signatures.h"
83#include "fs.h" 84#include "fs.h"
84 85
85 86
@@ -422,6 +423,91 @@ uri_chk_parse (const char *s, char **emsg)
422 423
423 424
424/** 425/**
426 * Convert a character back to the binary value
427 * that it represents (given base64-encoding).
428 *
429 * @param a character to convert
430 * @return offset in the "tbl" array
431 */
432static unsigned int
433c2v (unsigned char a)
434{
435 if ((a >= '0') && (a <= '9'))
436 return a - '0';
437 if ((a >= 'A') && (a <= 'Z'))
438 return (a - 'A' + 10);
439 if ((a >= 'a') && (a <= 'z'))
440 return (a - 'a' + 36);
441 if (a == '_')
442 return 62;
443 if (a == '=')
444 return 63;
445 return -1;
446}
447
448
449/**
450 * Convert string back to binary data.
451 *
452 * @param input '\0'-terminated string
453 * @param data where to write binary data
454 * @param size how much data should be converted
455 * @return number of characters processed from input,
456 * -1 on error
457 */
458static int
459enc2bin (const char *input, void *data, size_t size)
460{
461 size_t len;
462 size_t pos;
463 unsigned int bits;
464 unsigned int hbits;
465
466 len = size * 8 / 6;
467 if (((size * 8) % 6) != 0)
468 len++;
469 if (strlen (input) < len)
470 return -1; /* error! */
471 bits = 0;
472 hbits = 0;
473 len = 0;
474 pos = 0;
475 for (pos = 0; pos < size; pos++)
476 {
477 while (hbits < 8)
478 {
479 bits |= (c2v (input[len++]) << hbits);
480 hbits += 6;
481 }
482 (((unsigned char *) data)[pos]) = (unsigned char) bits;
483 bits >>= 8;
484 hbits -= 8;
485 }
486 return len;
487}
488
489
490/**
491 * Structure that defines how the
492 * contents of a location URI must be
493 * assembled in memory to create or
494 * verify the signature of a location
495 * URI.
496 */
497struct LocUriAssembly
498{
499 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
500
501 struct GNUNET_TIME_AbsoluteNBO exptime;
502
503 struct FileIdentifier fi;
504
505 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded peer;
506
507};
508
509
510/**
425 * Parse a LOC URI. 511 * Parse a LOC URI.
426 * Also verifies validity of the location URI. 512 * Also verifies validity of the location URI.
427 * 513 *
@@ -432,12 +518,15 @@ uri_chk_parse (const char *s, char **emsg)
432static struct GNUNET_FS_Uri * 518static struct GNUNET_FS_Uri *
433uri_loc_parse (const char *s, char **emsg) 519uri_loc_parse (const char *s, char **emsg)
434{ 520{
435 struct GNUNET_FS_Uri *ret; 521 struct GNUNET_FS_Uri *uri;
436 char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)]; 522 char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
437 char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)]; 523 char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
438 unsigned int pos; 524 unsigned int pos;
439 unsigned int npos; 525 unsigned int npos;
440 unsigned long long exptime; 526 unsigned long long exptime;
527 struct GNUNET_TIME_Absolute et;
528 struct GNUNET_CRYPTO_RsaSignature sig;
529 struct LocUriAssembly ass;
441 int ret; 530 int ret;
442 size_t slen; 531 size_t slen;
443 char *addr; 532 char *addr;
@@ -462,14 +551,14 @@ uri_loc_parse (const char *s, char **emsg)
462 h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)-1] = '\0'; 551 h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)-1] = '\0';
463 552
464 if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, 553 if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1,
465 &fi.chk.key)) || 554 &ass.fi.chk.key)) ||
466 (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, 555 (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2,
467 &fi.chk.query)) 556 &ass.fi.chk.query)) ||
468 (1 != SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2], 557 (1 != SSCANF (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
469 "%llu", 558 "%llu",
470 &fi.file_length)) ) 559 &ass.fi.file_length)) )
471 return NULL; 560 return NULL;
472 fi.file_length = GNUNET_htonll (fi.file_length); 561 ass.fi.file_length = GNUNET_htonll (ass.fi.file_length);
473 562
474 npos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2; 563 npos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) * 2;
475 while ((s[npos] != '\0') && (s[npos] != '.')) 564 while ((s[npos] != '\0') && (s[npos] != '.'))
@@ -477,39 +566,42 @@ uri_loc_parse (const char *s, char **emsg)
477 if (s[npos] == '\0') 566 if (s[npos] == '\0')
478 goto ERR; 567 goto ERR;
479 ret = enc2bin (&s[npos], 568 ret = enc2bin (&s[npos],
480 &loc->peer, 569 &ass.peer,
481 sizeof (GNUNET_RSA_PublicKey)); 570 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
482 if (ret == -1) 571 if (ret == -1)
483 goto ERR; 572 goto ERR;
484 npos += ret; 573 npos += ret;
485 if (dup[npos++] != '.') 574 if (s[npos++] != '.')
486 goto ERR; 575 goto ERR;
487 ret = enc2bin (&s[npos], 576 ret = enc2bin (&s[npos],
488 &loc->contentSignature, 577 &sig,
489 sizeof (struct GNUNET_CRYPTO_RsaSignature)); 578 sizeof (struct GNUNET_CRYPTO_RsaSignature));
490 if (ret == -1) 579 if (ret == -1)
491 goto ERR; 580 goto ERR;
492 npos += ret; 581 npos += ret;
493 if (dup[npos++] != '.') 582 if (s[npos++] != '.')
494 goto ERR; 583 goto ERR;
495 if (1 != SSCANF (&dup[npos], "%llu", &exptime)) 584 if (1 != SSCANF (&s[npos], "%llu", &exptime))
496 goto ERR; 585 goto ERR;
497 // FIXME: do something to exptime... 586 ass.purpose.size = htonl(sizeof(struct LocUriAssembly));
498 /* Finally: verify sigs! */ 587 ass.purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_NAMESPACE_PLACEMENT);
499 if (GNUNET_OK != GNUNET_RSA_verify (&loc->fi, 588 et.value = exptime;
500 sizeof (struct FileIdentifier) + 589 ass.exptime = GNUNET_TIME_absolute_hton (et);
501 sizeof (GNUNET_PeerIdentity) + 590 if (GNUNET_OK !=
502 sizeof (GNUNET_Int32Time), 591 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_NAMESPACE_PLACEMENT,
503 &loc->contentSignature, 592 &ass.purpose,
504 &loc->peer)) 593 &sig,
594 &ass.peer))
505 goto ERR; 595 goto ERR;
506 596
507 ret = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri)); 597 uri = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri));
508 ret->type = loc; 598 uri->type = loc;
509 ret->data.loc.chk = fi; 599 uri->data.loc.fi = ass.fi;
510 ret->data.loc.xx = yy; 600 uri->data.loc.peer = ass.peer;
601 uri->data.loc.expirationTime = et;
602 uri->data.loc.contentSignature = sig;
511 603
512 return ret; 604 return uri;
513ERR: 605ERR:
514 GNUNET_free_non_null (addr); 606 GNUNET_free_non_null (addr);
515 return NULL; 607 return NULL;
@@ -1251,71 +1343,6 @@ bin2enc (const void *data, size_t size)
1251 1343
1252 1344
1253/** 1345/**
1254 * Convert a character back to the binary value
1255 * that it represents (given base64-encoding).
1256 *
1257 * @param a character to convert
1258 * @return offset in the "tbl" array
1259 */
1260static unsigned int
1261c2v (unsigned char a)
1262{
1263 if ((a >= '0') && (a <= '9'))
1264 return a - '0';
1265 if ((a >= 'A') && (a <= 'Z'))
1266 return (a - 'A' + 10);
1267 if ((a >= 'a') && (a <= 'z'))
1268 return (a - 'a' + 36);
1269 if (a == '_')
1270 return 62;
1271 if (a == '=')
1272 return 63;
1273 return -1;
1274}
1275
1276
1277/**
1278 * Convert string back to binary data.
1279 *
1280 * @param input '\0'-terminated string
1281 * @param data where to write binary data
1282 * @param size how much data should be converted
1283 * @return number of characters processed from input,
1284 * -1 on error
1285 */
1286static int
1287enc2bin (const char *input, void *data, size_t size)
1288{
1289 size_t len;
1290 size_t pos;
1291 unsigned int bits;
1292 unsigned int hbits;
1293
1294 len = size * 8 / 6;
1295 if (((size * 8) % 6) != 0)
1296 len++;
1297 if (strlen (input) < len)
1298 return -1; /* error! */
1299 bits = 0;
1300 hbits = 0;
1301 len = 0;
1302 pos = 0;
1303 for (pos = 0; pos < size; pos++)
1304 {
1305 while (hbits < 8)
1306 {
1307 bits |= (c2v (input[len++]) << hbits);
1308 hbits += 6;
1309 }
1310 (((unsigned char *) data)[pos]) = (unsigned char) bits;
1311 bits >>= 8;
1312 hbits -= 8;
1313 }
1314 return len;
1315}
1316
1317
1318/**
1319 * Convert a LOC URI to a string. 1346 * Convert a LOC URI to a string.
1320 * 1347 *
1321 * @param uri loc uri to convert 1348 * @param uri loc uri to convert
@@ -1337,15 +1364,15 @@ uri_loc_to_string (const struct GNUNET_FS_Uri *uri)
1337 peerSig = bin2enc (&uri->data.loc.contentSignature, 1364 peerSig = bin2enc (&uri->data.loc.contentSignature,
1338 sizeof (struct GNUNET_CRYPTO_RsaSignature)); 1365 sizeof (struct GNUNET_CRYPTO_RsaSignature));
1339 GNUNET_asprintf (&ret, 1366 GNUNET_asprintf (&ret,
1340 "%s%s%s.%s.%llu.%s.%s.%u", // FIXME: expirationTime 64-bit??? 1367 "%s%s%s.%s.%llu.%s.%s.%llu",
1341 GNUNET_FS_URI_PREFIX, 1368 GNUNET_FS_URI_PREFIX,
1342 GNUNET_FS_URI_LOC_INFIX, 1369 GNUNET_FS_URI_LOC_INFIX,
1343 (const char *) &keyhash, 1370 (const char *) &keyhash,
1344 (const char *) &queryhash, 1371 (const char *) &queryhash,
1345 GNUNET_ntohll (uri->data.loc.fi.file_length), 1372 (unsigned long long) GNUNET_ntohll (uri->data.loc.fi.file_length),
1346 peerId, 1373 peerId,
1347 peerSig, 1374 peerSig,
1348 uri->data.loc.expirationTime); 1375 (unsigned long long) uri->data.loc.expirationTime.value);
1349 GNUNET_free (peerSig); 1376 GNUNET_free (peerSig);
1350 GNUNET_free (peerId); 1377 GNUNET_free (peerId);
1351 return ret; 1378 return ret;