mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 20:33:31 +01:00
parent
74c2bff781
commit
c024ff8671
@ -672,79 +672,6 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
|
||||
return seconds_valid;
|
||||
}
|
||||
|
||||
/** Parse a service descriptor at <b>str</b> (<b>len</b> bytes). On
|
||||
* success, return a newly alloced service_descriptor_t. On failure,
|
||||
* return NULL.
|
||||
*/
|
||||
rend_service_descriptor_t *
|
||||
rend_parse_service_descriptor(const char *str, size_t len)
|
||||
{
|
||||
rend_service_descriptor_t *result = NULL;
|
||||
int i, n_intro_points;
|
||||
size_t keylen, asn1len;
|
||||
const char *end, *cp, *eos;
|
||||
rend_intro_point_t *intro;
|
||||
|
||||
result = tor_malloc_zero(sizeof(rend_service_descriptor_t));
|
||||
cp = str;
|
||||
end = str+len;
|
||||
if (end-cp<2) goto truncated;
|
||||
result->version = 0;
|
||||
if (end-cp < 2) goto truncated;
|
||||
asn1len = ntohs(get_uint16(cp));
|
||||
cp += 2;
|
||||
if ((size_t)(end-cp) < asn1len) goto truncated;
|
||||
result->pk = crypto_pk_asn1_decode(cp, asn1len);
|
||||
if (!result->pk) goto truncated;
|
||||
cp += asn1len;
|
||||
if (end-cp < 4) goto truncated;
|
||||
result->timestamp = (time_t) ntohl(get_uint32(cp));
|
||||
cp += 4;
|
||||
result->protocols = 1<<2; /* always use intro format 2 */
|
||||
if (end-cp < 2) goto truncated;
|
||||
n_intro_points = ntohs(get_uint16(cp));
|
||||
cp += 2;
|
||||
|
||||
result->intro_nodes = smartlist_new();
|
||||
for (i=0;i<n_intro_points;++i) {
|
||||
if (end-cp < 2) goto truncated;
|
||||
eos = (const char *)memchr(cp,'\0',end-cp);
|
||||
if (!eos) goto truncated;
|
||||
/* Write nickname to extend info, but postpone the lookup whether
|
||||
* we know that router. It's not part of the parsing process. */
|
||||
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
strlcpy(intro->extend_info->nickname, cp,
|
||||
sizeof(intro->extend_info->nickname));
|
||||
smartlist_add(result->intro_nodes, intro);
|
||||
cp = eos+1;
|
||||
}
|
||||
keylen = crypto_pk_keysize(result->pk);
|
||||
tor_assert(end-cp >= 0);
|
||||
if ((size_t)(end-cp) < keylen) goto truncated;
|
||||
if ((size_t)(end-cp) > keylen) {
|
||||
log_warn(LD_PROTOCOL,
|
||||
"Signature is %d bytes too long on service descriptor.",
|
||||
(int)((size_t)(end-cp) - keylen));
|
||||
goto error;
|
||||
}
|
||||
note_crypto_pk_op(REND_CLIENT);
|
||||
if (crypto_pk_public_checksig_digest(result->pk,
|
||||
(char*)str,cp-str, /* data */
|
||||
(char*)cp,end-cp /* signature*/
|
||||
)<0) {
|
||||
log_warn(LD_PROTOCOL, "Bad signature on service descriptor.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return result;
|
||||
truncated:
|
||||
log_warn(LD_PROTOCOL, "Truncated service descriptor.");
|
||||
error:
|
||||
rend_service_descriptor_free(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Sets <b>out</b> to the first 10 bytes of the digest of <b>pk</b>,
|
||||
* base32 encoded. NUL-terminates out. (We use this string to
|
||||
* identify services in directory requests and .onion URLs.)
|
||||
|
@ -26,8 +26,6 @@ void rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint,
|
||||
const uint8_t *payload);
|
||||
|
||||
void rend_service_descriptor_free(rend_service_descriptor_t *desc);
|
||||
rend_service_descriptor_t *rend_parse_service_descriptor(const char *str,
|
||||
size_t len);
|
||||
int rend_get_service_id(crypto_pk_t *pk, char *out);
|
||||
void rend_encoded_v2_service_descriptor_free(
|
||||
rend_encoded_v2_service_descriptor_t *desc);
|
||||
|
Loading…
Reference in New Issue
Block a user