Start consolidating our tribal knowledge on signature tag data

- New internal API to "parse" signature tags, performing various
  sanity checks, classifying the type (digest, actual signature etc)
  and gathering other relevant info.
- Unused as of this commit...
This commit is contained in:
Panu Matilainen 2014-10-24 10:25:48 +03:00
parent cff6a5d991
commit ff8547a0cf
2 changed files with 102 additions and 0 deletions

View File

@ -19,6 +19,91 @@
#include "debug.h"
rpmRC rpmSigInfoParse(rpmtd td, const char *origin,
struct sigtInfo_s *sinfo, pgpDigParams *sigp, char **msg)
{
rpmRC rc = RPMRC_FAIL;
rpm_tagtype_t tagtype = 0;
rpm_count_t tagsize = 0;
pgpDigParams sig = NULL;
memset(sinfo, 0, sizeof(*sinfo));
switch (td->tag) {
case RPMSIGTAG_GPG:
case RPMSIGTAG_PGP5: /* XXX legacy */
case RPMSIGTAG_PGP:
sinfo->payload = 1;
/* fallthrough */
case RPMSIGTAG_RSA:
case RPMSIGTAG_DSA:
tagtype = RPM_BIN_TYPE;
sinfo->type = RPMSIG_SIGNATURE_TYPE;
break;
case RPMSIGTAG_SHA1:
tagsize = 41; /* includes trailing \0 */
tagtype = RPM_STRING_TYPE;
sinfo->hashalgo = PGPHASHALGO_SHA1;
sinfo->type = RPMSIG_DIGEST_TYPE;
break;
case RPMSIGTAG_MD5:
tagtype = RPM_BIN_TYPE;
tagsize = 16;
sinfo->hashalgo = PGPHASHALGO_MD5;
sinfo->type = RPMSIG_DIGEST_TYPE;
sinfo->payload = 1;
break;
case RPMSIGTAG_SIZE:
case RPMSIGTAG_PAYLOADSIZE:
tagsize = 4;
tagtype = RPM_INT32_TYPE;
sinfo->type = RPMSIG_OTHER_TYPE;
break;
case RPMSIGTAG_LONGSIZE:
case RPMSIGTAG_LONGARCHIVESIZE:
tagsize = 8;
tagtype = RPM_INT64_TYPE;
sinfo->type = RPMSIG_OTHER_TYPE;
break;
case RPMSIGTAG_RESERVEDSPACE:
tagtype = RPM_BIN_TYPE;
sinfo->type = RPMSIG_OTHER_TYPE;
break;
default:
/* anything unknown just falls through for now */
break;
}
if (tagsize && (td->flags & RPMTD_IMMUTABLE) && tagsize != td->size) {
rasprintf(msg, _("%s tag %u: BAD, invalid size %u"),
origin, td->tag, td->size);
goto exit;
}
if (tagtype && tagtype != td->type) {
rasprintf(msg, _("%s tag %u: BAD, invalid type %u"),
origin, td->tag, td->type);
goto exit;
}
if (sinfo->type == RPMSIG_SIGNATURE_TYPE) {
if (pgpPrtParams(td->data, td->count, PGPTAG_SIGNATURE, &sig)) {
rasprintf(msg, _("%s tag %u: BAD, invalid OpenPGP signature"),
origin, td->tag);
goto exit;
}
sinfo->hashalgo = pgpDigParamsAlgo(sig, PGPVAL_HASHALGO);
}
rc = RPMRC_OK;
if (sigp)
*sigp = sig;
else
pgpDigParamsFree(sig);
exit:
return rc;
}
/**
* Print package size.
* @todo rpmio: use fdSize rather than fstat(2) to get file size.

View File

@ -15,6 +15,19 @@ typedef enum sigType_e {
RPMSIGTYPE_HEADERSIG= 5 /*!< Header style signature */
} sigType;
enum {
RPMSIG_UNKNOWN_TYPE = 0,
RPMSIG_DIGEST_TYPE = 1,
RPMSIG_SIGNATURE_TYPE = 2,
RPMSIG_OTHER_TYPE = 3,
};
struct sigtInfo_s {
int hashalgo;
int payload;
int type;
};
#ifdef __cplusplus
extern "C" {
#endif
@ -69,6 +82,10 @@ RPM_GNUC_INTERNAL
int parsePGPSig(rpmtd sigtd, const char *type,
pgpDigParams *sig, char **msg);
RPM_GNUC_INTERNAL
rpmRC rpmSigInfoParse(rpmtd td, const char *origin,
struct sigtInfo_s *sigt, pgpDigParams *sigp, char **msg);
#ifdef __cplusplus
}
#endif