diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2017-04-12 10:58:52 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2017-04-12 11:06:11 +0300 |
commit | 65bdcd8bbf4f1eaa540132cc9c2e6665ca119e72 (patch) | |
tree | b35cac8d4dc733a92a26a8d0b25ec2fa54cce3e5 | |
parent | 43c053b753e278a465cf7b5a155d332e0eb240d4 (diff) | |
download | rpm-65bdcd8bbf4f1eaa540132cc9c2e6665ca119e72.tar.gz |
Dont assume signature data is always at td->data
Grab data + its length to helper variables by whatever appropriate
means early on and use those to access the data. In particular, this
supposedly adds support for string arrays as signature data.
While at it, add a test for NULL or too short data.
-rw-r--r-- | lib/signature.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/lib/signature.c b/lib/signature.c index 2d5f0d725..d7acb5a4e 100644 --- a/lib/signature.c +++ b/lib/signature.c @@ -29,6 +29,8 @@ rpmRC rpmsinfoInit(rpmtd td, const char *origin, rpm_count_t tagsize = 0; rpm_count_t tagcount = 0; int hexstring = 0; + const void *data = NULL; + rpm_count_t dlen = 0; memset(sinfo, 0, sizeof(*sinfo)); switch (td->tag) { @@ -116,8 +118,28 @@ rpmRC rpmsinfoInit(rpmtd td, const char *origin, goto exit; } + switch (td->type) { + case RPM_STRING_TYPE: + case RPM_STRING_ARRAY_TYPE: + data = rpmtdGetString(td); + if (data) + dlen = strlen(data); + break; + case RPM_BIN_TYPE: + data = td->data; + dlen = td->count; + break; + } + + /* MD5 has data length of 16, everything else is (much) larger */ + if (sinfo->hashalgo && (data == NULL || dlen < 16)) { + rasprintf(msg, _("%s tag %u: BAD, invalid data %p (%u)"), + origin, td->tag, data, dlen); + goto exit; + } + if (td->type == RPM_STRING_TYPE && td->size == 0) - td->size = strlen(td->data) + 1; + td->size = dlen + 1; if (tagsize && (td->flags & RPMTD_IMMUTABLE) && tagsize != td->size) { rasprintf(msg, _("%s tag %u: BAD, invalid size %u"), @@ -126,7 +148,7 @@ rpmRC rpmsinfoInit(rpmtd td, const char *origin, } if (hexstring) { - for (const char * b = td->data; *b != '\0'; b++) { + for (const char * b = data; *b != '\0'; b++) { if (strchr("0123456789abcdefABCDEF", *b) == NULL) { rasprintf(msg, _("%s: tag %u: BAD, not hex"), origin, td->tag); goto exit; @@ -135,7 +157,7 @@ rpmRC rpmsinfoInit(rpmtd td, const char *origin, } if (sinfo->type == RPMSIG_SIGNATURE_TYPE) { - if (pgpPrtParams(td->data, td->count, PGPTAG_SIGNATURE, &sinfo->sig)) { + if (pgpPrtParams(data, dlen, PGPTAG_SIGNATURE, &sinfo->sig)) { rasprintf(msg, _("%s tag %u: BAD, invalid OpenPGP signature"), origin, td->tag); goto exit; @@ -144,9 +166,9 @@ rpmRC rpmsinfoInit(rpmtd td, const char *origin, sinfo->keyid = pgpGrab(sinfo->sig->signid+4, 4); } else if (sinfo->type == RPMSIG_DIGEST_TYPE) { if (td->type == RPM_BIN_TYPE) - sinfo->dig = pgpHexStr(td->data, td->count); + sinfo->dig = pgpHexStr(data, dlen); else - sinfo->dig = xstrdup(rpmtdGetString(td)); + sinfo->dig = xstrdup(data); } sinfo->tag = td->tag; |