mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Use a single path for all PEM-like objects in get_next_token()
Previously, we would decode the PEM wrapper for keys twice: once in get_next_token, and once later in PEM decode. Now we just do all of the wrapper and base64 stuff in get_next_token, and store the base64-decoded part in the token object for keys and non-keys alike. This change should speed up parsing slightly by letting us skip a bunch of stuff in crypto_pk_read_*from_string(), including the tag detection parts of pem_decode(), and an extra key allocation and deallocation pair. Retaining the base64-decoded part in the token object will allow us to speed up our microdesc parsing, since it is the asn1 portion that we actually want to retain.
This commit is contained in:
@@ -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,15 +382,7 @@ 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;
|
||||
size_t maxsize = base64_decode_maxsize(next-*s);
|
||||
tok->object_body = ALLOC(maxsize);
|
||||
@@ -400,6 +391,17 @@ get_next_token(memarea_t *area,
|
||||
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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user