X-Git-Url: http://the.earth.li/gitweb/?a=blobdiff_plain;f=decodekey.c;h=522ad901383dd6a217b0ef5ed2320a93e3d51f8b;hb=338e91f33174edebe42d77843c0eea34f53bc53c;hp=705b827d43ef7a7e69197a9a4dd9af537e81d542;hpb=23f086c85c5d2db35e9ce76cf0bbf72200b4dc42;p=onak.git diff --git a/decodekey.c b/decodekey.c index 705b827..522ad90 100644 --- a/decodekey.c +++ b/decodekey.c @@ -34,6 +34,8 @@ /* * parse_subpackets - Parse the subpackets of a Type 4 signature. * @data: The subpacket data. + * @len: The amount of data available to read. + * @parselen: The amount of data that was actually parsed. * @keyid: A pointer to where we should return the keyid. * @creationtime: A pointer to where we should return the creation time. * @@ -42,7 +44,8 @@ * processed. If the value of any piece of data is not desired a NULL * can be passed instead of a pointer to a storage area for that value. */ -int parse_subpackets(unsigned char *data, uint64_t *keyid, time_t *creation) +onak_status_t parse_subpackets(unsigned char *data, size_t len, + size_t *parselen, uint64_t *keyid, time_t *creation) { int offset = 0; int length = 0; @@ -50,8 +53,20 @@ int parse_subpackets(unsigned char *data, uint64_t *keyid, time_t *creation) log_assert(data != NULL); + /* Make sure we actually have the 2 byte length field */ + if (len < 2) { + return ONAK_E_INVALID_PKT; + } + length = (data[0] << 8) + data[1] + 2; + /* If the length is off the end of the data available, it's bogus */ + if (len < length) { + return ONAK_E_INVALID_PKT; + } + + *parselen = length; + offset = 2; while (offset < length) { packetlen = data[offset++]; @@ -109,15 +124,28 @@ int parse_subpackets(unsigned char *data, uint64_t *keyid, time_t *creation) case OPENPGP_SIGSUB_EXPORTABLE: case OPENPGP_SIGSUB_TRUSTSIG: case OPENPGP_SIGSUB_REGEX: + case OPENPGP_SIGSUB_REVOCABLE: + case OPENPGP_SIGSUB_CAPABILITIES: case OPENPGP_SIGSUB_KEYEXPIRY: + case OPENPGP_SIGSUB_ARR: case OPENPGP_SIGSUB_PREFSYM: + case OPENPGP_SIGSUB_REVOCATION_KEY: + case OPENPGP_SIGSUB_ISSUER_UID: + case OPENPGP_SIGSUB_URL: + case OPENPGP_SIGSUB_ISSUER_FINGER: case OPENPGP_SIGSUB_NOTATION: case OPENPGP_SIGSUB_PREFHASH: case OPENPGP_SIGSUB_PREFCOMPRESS: case OPENPGP_SIGSUB_KEYSERVER: + case OPENPGP_SIGSUB_PREFKEYSERVER: case OPENPGP_SIGSUB_PRIMARYUID: case OPENPGP_SIGSUB_POLICYURI: case OPENPGP_SIGSUB_KEYFLAGS: + case OPENPGP_SIGSUB_SIGNER_UID: + case OPENPGP_SIGSUB_REVOKE_REASON: + case OPENPGP_SIGSUB_FEATURES: + case OPENPGP_SIGSUB_SIGNATURE_TARGET: + case OPENPGP_SIGSUB_EMBEDDED_SIG: /* * Various subpacket types we know about, but don't * currently handle. Some are candidates for being @@ -139,7 +167,7 @@ int parse_subpackets(unsigned char *data, uint64_t *keyid, time_t *creation) offset += packetlen; } - return length; + return ONAK_E_OK; } /** @@ -174,10 +202,12 @@ struct ll *keysigs(struct ll *curll, * key or pulls the data directly from v2/3. NULL can be passed for any * values which aren't cared about. */ -void sig_info(struct openpgp_packet *packet, uint64_t *keyid, time_t *creation) +onak_status_t sig_info(struct openpgp_packet *packet, uint64_t *keyid, + time_t *creation) { - int length = 0; - + size_t length = 0; + onak_status_t res; + if (packet != NULL) { switch (packet->data[0]) { case 2: @@ -210,20 +240,25 @@ void sig_info(struct openpgp_packet *packet, uint64_t *keyid, time_t *creation) } break; case 4: - length = parse_subpackets(&packet->data[4], - keyid, creation); - parse_subpackets(&packet->data[length + 4], - keyid, creation); - /* - * Don't bother to look at the unsigned packets. - */ + res = parse_subpackets(&packet->data[4], + packet->length - 4, + &length, keyid, creation); + if (res != ONAK_E_OK) { + return res; + } + res = parse_subpackets(&packet->data[length + 4], + packet->length - (4 + length), + &length, keyid, creation); + if (res != ONAK_E_OK) { + return res; + } break; default: break; } } - return; + return ONAK_E_OK; } /**