From 7da9af66027d826deb6fcc49116fe196ad54e118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 18 Mar 2013 21:34:29 +0000 Subject: [PATCH] Set a reasonable, hard limit on label length. This removes the need for a variable-length key structure (to accommodate a variable-length label) and vastly simplifies key parsing. git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@678 185d5e19-27fe-0310-9dcf-9bff6b9f3609 --- include/security/oath.h | 2 +- include/security/oath_constants.h | 5 +++++ include/security/oath_types.h | 8 ++------ lib/liboath/oath_key.c | 30 +++++++++--------------------- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/include/security/oath.h b/include/security/oath.h index 3329042..e897162 100644 --- a/include/security/oath.h +++ b/include/security/oath.h @@ -36,7 +36,7 @@ #include #include -struct oath_key *oath_key_alloc(size_t); +struct oath_key *oath_key_alloc(void); void oath_key_free(struct oath_key *); struct oath_key *oath_key_from_uri(const char *); struct oath_key *oath_key_from_file(const char *); diff --git a/include/security/oath_constants.h b/include/security/oath_constants.h index f7482d0..1838d61 100644 --- a/include/security/oath_constants.h +++ b/include/security/oath_constants.h @@ -71,4 +71,9 @@ enum oath_hash { */ #define OATH_MAX_KEYLEN 64 +/* + * Maximum label length in characters, including terminating NUL. + */ +#define OATH_MAX_LABELLEN 64 + #endif diff --git a/include/security/oath_types.h b/include/security/oath_types.h index 94f2122..cec8e38 100644 --- a/include/security/oath_types.h +++ b/include/security/oath_types.h @@ -47,15 +47,11 @@ struct oath_key { /* label */ size_t labellen; /* bytes incl. NUL */ - char *label; + char label[OATH_MAX_LABELLEN]; /* key */ size_t keylen; /* bytes */ - uint8_t *key; - - /* buffer for label + NUL + key */ - size_t datalen; /* bytes */ - uint8_t data[]; + uint8_t key[OATH_MAX_KEYLEN]; }; #endif diff --git a/lib/liboath/oath_key.c b/lib/liboath/oath_key.c index 30e78f2..98ff3dc 100644 --- a/lib/liboath/oath_key.c +++ b/lib/liboath/oath_key.c @@ -56,15 +56,14 @@ * label and key. */ struct oath_key * -oath_key_alloc(size_t extra) +oath_key_alloc(void) { struct oath_key *key; - if ((key = calloc(1, sizeof *key + extra)) == NULL) { + if ((key = calloc(1, sizeof *key)) == NULL) { openpam_log(PAM_LOG_ERROR, "malloc(): %s", strerror(errno)); return (NULL); } - key->datalen = extra; /* XXX should try to wire */ return (key); } @@ -77,7 +76,7 @@ oath_key_free(struct oath_key *key) { if (key != NULL) { - memset(key, 0, sizeof *key + key->datalen); + memset(key, 0, sizeof *key); free(key); } } @@ -94,12 +93,7 @@ oath_key_from_uri(const char *uri) uintmax_t n; char *e; - /* - * The URI string contains the label, the base32-encoded key and - * some fluff, so the combined length of the label and key can - * never exceed the length of the URI string. - */ - if ((key = oath_key_alloc(strlen(uri))) == NULL) + if ((key = oath_key_alloc()) == NULL) return (NULL); /* check method */ @@ -123,8 +117,8 @@ oath_key_from_uri(const char *uri) /* extract label */ if ((q = strchr(p, '?')) == NULL) goto invalid; - key->label = (char *)key->data; - key->labellen = (q - p) + 1; + if ((key->labellen = q - p + 1) > sizeof key->label) + goto invalid; memcpy(key->label, p, q - p); key->label[q - p] = '\0'; p = q + 1; @@ -145,12 +139,7 @@ oath_key_from_uri(const char *uri) if (key->keylen != 0) /* dupe */ goto invalid; - /* base32-encoded key - multiple of 40 bits */ - if ((r - q) % 8 != 0 || - base32_declen(r - q) > OATH_MAX_KEYLEN) - goto invalid; - key->key = key->data + key->labellen; - key->keylen = key->datalen - key->labellen; + key->keylen = sizeof key->key; if (base32_dec(q, r - q, key->key, &key->keylen) != 0) goto invalid; if (base32_enclen(key->keylen) != (size_t)(r - q)) @@ -314,16 +303,15 @@ oath_dummy_key(enum oath_mode mode, enum oath_hash hash, unsigned int digits) { struct oath_key *key; - if ((key = oath_key_alloc(DUMMY_LABELLEN + DUMMY_KEYLEN)) == NULL) + if ((key = oath_key_alloc()) == NULL) return (NULL); key->mode = mode; key->digits = digits; key->counter = 0; key->timestep = 30; key->hash = hash; - key->label = (char *)key->data; memcpy(key->label, DUMMY_LABEL, DUMMY_LABELLEN); - key->key = key->data + DUMMY_LABELLEN; + key->labellen = DUMMY_LABELLEN; key->keylen = DUMMY_KEYLEN; return (key); }