mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Merge branch 'ticket28839_v2_squashed'
This commit is contained in:
commit
bb091da1e7
3
changes/ticket28839
Normal file
3
changes/ticket28839
Normal file
@ -0,0 +1,3 @@
|
||||
o Minor features (performance):
|
||||
- Speed up microdesriptor parsing by about 30%, to help
|
||||
improve startup time. Closes ticket 28839.
|
@ -177,8 +177,8 @@ microdescs_parse_from_string(const char *s, const char *eos,
|
||||
"Relay's onion key had invalid exponent.");
|
||||
goto next;
|
||||
}
|
||||
router_set_rsa_onion_pkey(tok->key, &md->onion_pkey,
|
||||
&md->onion_pkey_len);
|
||||
md->onion_pkey = tor_memdup(tok->object_body, tok->object_size);
|
||||
md->onion_pkey_len = tok->object_size;
|
||||
crypto_pk_free(tok->key);
|
||||
|
||||
if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) {
|
||||
|
@ -266,7 +266,7 @@ get_next_token(memarea_t *area,
|
||||
* attack, a bug, or some other nonsense. */
|
||||
#define MAX_LINE_LENGTH (128*1024)
|
||||
|
||||
const char *next, *eol, *obstart;
|
||||
const char *next, *eol;
|
||||
size_t obname_len;
|
||||
int i;
|
||||
directory_token_t *tok;
|
||||
@ -352,7 +352,6 @@ get_next_token(memarea_t *area,
|
||||
if (!eol || eol-*s<11 || strcmpstart(*s, "-----BEGIN ")) /* No object. */
|
||||
goto check_object;
|
||||
|
||||
obstart = *s; /* Set obstart to start of object spec */
|
||||
if (eol - *s <= 16 || memchr(*s+11,'\0',eol-*s-16) || /* no short lines, */
|
||||
strcmp_len(eol-5, "-----", 5) || /* nuls or invalid endings */
|
||||
(eol-*s) > MAX_UNPARSED_OBJECT_SIZE) { /* name too long */
|
||||
@ -383,22 +382,26 @@ get_next_token(memarea_t *area,
|
||||
if (next - *s > MAX_UNPARSED_OBJECT_SIZE)
|
||||
RET_ERR("Couldn't parse object: missing footer or object much too big.");
|
||||
|
||||
if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) { /* If it's a public key */
|
||||
tok->key = crypto_pk_new();
|
||||
if (crypto_pk_read_public_key_from_string(tok->key, obstart, eol-obstart))
|
||||
RET_ERR("Couldn't parse public key.");
|
||||
} else if (!strcmp(tok->object_type, "RSA PRIVATE KEY")) { /* private key */
|
||||
tok->key = crypto_pk_new();
|
||||
if (crypto_pk_read_private_key_from_string(tok->key, obstart, eol-obstart))
|
||||
RET_ERR("Couldn't parse private key.");
|
||||
} else { /* If it's something else, try to base64-decode it */
|
||||
{
|
||||
int r;
|
||||
tok->object_body = ALLOC(next-*s); /* really, this is too much RAM. */
|
||||
r = base64_decode(tok->object_body, next-*s, *s, next-*s);
|
||||
size_t maxsize = base64_decode_maxsize(next-*s);
|
||||
tok->object_body = ALLOC(maxsize);
|
||||
r = base64_decode(tok->object_body, maxsize, *s, next-*s);
|
||||
if (r<0)
|
||||
RET_ERR("Malformed object: bad base64-encoded data");
|
||||
tok->object_size = r;
|
||||
}
|
||||
|
||||
if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) { /* If it's a public key */
|
||||
tok->key = crypto_pk_asn1_decode(tok->object_body, tok->object_size);
|
||||
if (! tok->key)
|
||||
RET_ERR("Couldn't parse public key.");
|
||||
} else if (!strcmp(tok->object_type, "RSA PRIVATE KEY")) { /* private key */
|
||||
tok->key = crypto_pk_asn1_decode_private(tok->object_body,
|
||||
tok->object_size);
|
||||
if (! tok->key)
|
||||
RET_ERR("Couldn't parse private key.");
|
||||
}
|
||||
*s = eol;
|
||||
|
||||
check_object:
|
||||
|
@ -588,8 +588,8 @@ router_parse_entry_from_string(const char *s, const char *end,
|
||||
"Relay's onion key had invalid exponent.");
|
||||
goto err;
|
||||
}
|
||||
router_set_rsa_onion_pkey(tok->key, &router->onion_pkey,
|
||||
&router->onion_pkey_len);
|
||||
router->onion_pkey = tor_memdup(tok->object_body, tok->object_size);
|
||||
router->onion_pkey_len = tok->object_size;
|
||||
crypto_pk_free(tok->key);
|
||||
|
||||
if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) {
|
||||
|
@ -179,6 +179,18 @@ base64_encode_size(size_t srclen, int flags)
|
||||
return enclen;
|
||||
}
|
||||
|
||||
/** Return an upper bound on the number of bytes that might be needed to hold
|
||||
* the data from decoding the base64 string <b>srclen</b>. This is only an
|
||||
* upper bound, since some part of the base64 string might be padding or
|
||||
* space. */
|
||||
size_t
|
||||
base64_decode_maxsize(size_t srclen)
|
||||
{
|
||||
tor_assert(srclen < INT_MAX / 3);
|
||||
|
||||
return CEIL_DIV(srclen * 3, 4);
|
||||
}
|
||||
|
||||
/** Internal table mapping 6 bit values to the Base64 alphabet. */
|
||||
static const char base64_encode_table[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
|
@ -42,6 +42,7 @@ const char *hex_str(const char *from, size_t fromlen);
|
||||
|
||||
#define BASE64_ENCODE_MULTILINE 1
|
||||
size_t base64_encode_size(size_t srclen, int flags);
|
||||
size_t base64_decode_maxsize(size_t srclen);
|
||||
int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen,
|
||||
int flags);
|
||||
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen);
|
||||
|
@ -39,6 +39,9 @@
|
||||
#include "lib/crypt_ops/digestset.h"
|
||||
#include "lib/crypt_ops/crypto_init.h"
|
||||
|
||||
#include "feature/dirparse/microdesc_parse.h"
|
||||
#include "feature/nodelist/microdesc.h"
|
||||
|
||||
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
|
||||
static uint64_t nanostart;
|
||||
static inline uint64_t
|
||||
@ -639,6 +642,41 @@ bench_ecdh_p224(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
bench_md_parse(void)
|
||||
{
|
||||
uint64_t start, end;
|
||||
const int N = 100000;
|
||||
// selected arbitrarily
|
||||
const char md_text[] =
|
||||
"@last-listed 2018-12-14 18:14:14\n"
|
||||
"onion-key\n"
|
||||
"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIGJAoGBAMHkZeXNDX/49JqM2BVLmh1Fnb5iMVnatvZZTLJyedqDLkbXZ1WKP5oh\n"
|
||||
"7ec14dj/k3ntpwHD4s2o3Lb6nfagWbug4+F/rNJ7JuFru/PSyOvDyHGNAuegOXph\n"
|
||||
"3gTGjdDpv/yPoiadGebbVe8E7n6hO+XxM2W/4dqheKimF0/s9B7HAgMBAAE=\n"
|
||||
"-----END RSA PUBLIC KEY-----\n"
|
||||
"ntor-onion-key QgF/EjqlNG1wRHLIop/nCekEH+ETGZSgYOhu26eiTF4=\n"
|
||||
"family $00E9A86E7733240E60D8435A7BBD634A23894098 "
|
||||
"$329BD7545DEEEBBDC8C4285F243916F248972102 "
|
||||
"$69E06EBB2573A4F89330BDF8BC869794A3E10E4D "
|
||||
"$DCA2A3FAE50B3729DAA15BC95FB21AF03389818B\n"
|
||||
"p accept 53,80,443,5222-5223,25565\n"
|
||||
"id ed25519 BzffzY99z6Q8KltcFlUTLWjNTBU7yKK+uQhyi1Ivb3A\n";
|
||||
|
||||
reset_perftime();
|
||||
start = perftime();
|
||||
for (int i = 0; i < N; ++i) {
|
||||
smartlist_t *s = microdescs_parse_from_string(md_text, NULL, 1,
|
||||
SAVED_IN_CACHE, NULL);
|
||||
SMARTLIST_FOREACH(s, microdesc_t *, md, microdesc_free(md));
|
||||
smartlist_free(s);
|
||||
}
|
||||
|
||||
end = perftime();
|
||||
printf("Microdesc parse: %f nsec\n", NANOCOUNT(start, end, N));
|
||||
}
|
||||
|
||||
typedef void (*bench_fn)(void);
|
||||
|
||||
typedef struct benchmark_t {
|
||||
@ -666,6 +704,8 @@ static struct benchmark_t benchmarks[] = {
|
||||
ENT(ecdh_p256),
|
||||
ENT(ecdh_p224),
|
||||
#endif
|
||||
|
||||
ENT(md_parse),
|
||||
{NULL,NULL,0}
|
||||
};
|
||||
|
||||
|
@ -300,8 +300,8 @@ test_parsecommon_get_next_token_parse_keys(void *arg)
|
||||
tt_int_op(token->tp, OP_EQ, R_IPO_ONION_KEY);
|
||||
tt_int_op(token->n_args, OP_EQ, 0);
|
||||
tt_str_op(token->object_type, OP_EQ, "RSA PUBLIC KEY");
|
||||
tt_int_op(token->object_size, OP_EQ, 0);
|
||||
tt_assert(!token->object_body);
|
||||
tt_int_op(token->object_size, OP_EQ, 140);
|
||||
tt_assert(token->object_body);
|
||||
tt_assert(token->key);
|
||||
tt_assert(!token->error);
|
||||
|
||||
@ -335,8 +335,8 @@ test_parsecommon_get_next_token_parse_keys(void *arg)
|
||||
tt_int_op(token2->tp, OP_EQ, C_CLIENT_KEY);
|
||||
tt_int_op(token2->n_args, OP_EQ, 0);
|
||||
tt_str_op(token2->object_type, OP_EQ, "RSA PRIVATE KEY");
|
||||
tt_int_op(token2->object_size, OP_EQ, 0);
|
||||
tt_assert(!token2->object_body);
|
||||
tt_int_op(token2->object_size, OP_EQ, 608);
|
||||
tt_assert(token2->object_body);
|
||||
tt_assert(token2->key);
|
||||
tt_assert(!token->error);
|
||||
|
||||
|
@ -392,10 +392,13 @@ test_util_format_encoded_size(void *arg)
|
||||
|
||||
base64_encode(outbuf, sizeof(outbuf), (char *)inbuf, i, 0);
|
||||
tt_int_op(strlen(outbuf), OP_EQ, base64_encode_size(i, 0));
|
||||
tt_int_op(i, OP_LE, base64_decode_maxsize(strlen(outbuf)));
|
||||
|
||||
base64_encode(outbuf, sizeof(outbuf), (char *)inbuf, i,
|
||||
BASE64_ENCODE_MULTILINE);
|
||||
tt_int_op(strlen(outbuf), OP_EQ,
|
||||
base64_encode_size(i, BASE64_ENCODE_MULTILINE));
|
||||
tt_int_op(i, OP_LE, base64_decode_maxsize(strlen(outbuf)));
|
||||
}
|
||||
|
||||
done:
|
||||
@ -417,4 +420,3 @@ struct testcase_t util_format_tests[] = {
|
||||
{ "encoded_size", test_util_format_encoded_size, 0, NULL, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user