diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-08-11 22:24:07 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-08-11 22:24:07 +0000 |
commit | 596fe6fcff78fc66f2ed7e8bd46475feef9c6210 (patch) | |
tree | f2d48964e5d77ada7f9f5188b5f8c35483dded66 /src/fs/fs_uri.c | |
parent | b309c5f5ae339faf3632f7ee3a86520981f6523a (diff) | |
download | gnunet-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.c | 211 |
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 | */ | ||
432 | static unsigned int | ||
433 | c2v (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 | */ | ||
458 | static int | ||
459 | enc2bin (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 | */ | ||
497 | struct 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) | |||
432 | static struct GNUNET_FS_Uri * | 518 | static struct GNUNET_FS_Uri * |
433 | uri_loc_parse (const char *s, char **emsg) | 519 | uri_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; |
513 | ERR: | 605 | ERR: |
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 | */ | ||
1260 | static unsigned int | ||
1261 | c2v (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 | */ | ||
1286 | static int | ||
1287 | enc2bin (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; |