[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Use a single path for all PEM-like objects in get_next_token()
commit 0556942284d7dcdf0a5e7a31e94b925378a338a8
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Fri Dec 14 13:17:17 2018 -0500
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.
---
src/feature/dirparse/parsecommon.c | 24 +++++++++++++-----------
src/test/test_parsecommon.c | 8 ++++----
2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/src/feature/dirparse/parsecommon.c b/src/feature/dirparse/parsecommon.c
index 91b775533..2e7cea816 100644
--- a/src/feature/dirparse/parsecommon.c
+++ b/src/feature/dirparse/parsecommon.c
@@ -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:
diff --git a/src/test/test_parsecommon.c b/src/test/test_parsecommon.c
index 6da125dd0..8e74fcdb4 100644
--- a/src/test/test_parsecommon.c
+++ b/src/test/test_parsecommon.c
@@ -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);
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits