Esempio n. 1
0
rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, char ** msg)
{
    rpmRC rc = RPMRC_FAIL;
    rpmVSFlags vsflags = rpmtsVSFlags(ts);
    rpmKeyring keyring = rpmtsGetKeyring(ts, 1);
    struct hdrblob_s blob;

    if (hdrblobInit(uh, uc, 0, 0, &blob, msg) == RPMRC_OK) {
	rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
	rc = headerSigVerify(keyring, vsflags, &blob, msg);
	rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), uc);

	if (rc == RPMRC_NOTFOUND && msg != NULL && *msg == NULL)
	    rasprintf(msg, "Header sanity check: OK");
    }

    rpmKeyringFree(keyring);

    return rc;
}
Esempio n. 2
0
static rpmRC headerVerify(rpmKeyring keyring, rpmVSFlags vsflags,
			  const void * uh, size_t uc, char ** msg)
{
    char *buf = NULL;
    int32_t * ei = (int32_t *) uh;
    int32_t il = ntohl(ei[0]);
    int32_t dl = ntohl(ei[1]);
    entryInfo pe = (entryInfo) &ei[2];
    int32_t pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(*pe)) + dl;
    unsigned char * dataStart = (unsigned char *) (pe + il);
    struct indexEntry_s entry;
    struct entryInfo_s info;
    int32_t ril = 0;
    unsigned char * regionEnd = NULL;
    rpmRC rc = RPMRC_FAIL;	/* assume failure */

    /* Is the blob the right size? */
    if (uc > 0 && pvlen != uc) {
	rasprintf(&buf, _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"),
		(int)uc, (int)il, (int)dl);
	goto exit;
    }

    memset(&entry, 0, sizeof(entry));
    memset(&info, 0, sizeof(info));

    /* Check (and convert) the 1st tag element. */
    if (headerVerifyInfo(1, dl, pe, &entry.info, 0) != -1) {
	rasprintf(&buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
		0, entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	goto exit;
    }

    /* Is there an immutable header region tag? */
    if (!(entry.info.tag == RPMTAG_HEADERIMMUTABLE
       && entry.info.type == RPM_BIN_TYPE
       && entry.info.count == REGION_TAG_COUNT))
    {
	rc = RPMRC_NOTFOUND;
	goto exit;
    }

    /* Is the trailer within the data area? */
    if (entry.info.offset + REGION_TAG_COUNT > dl) {
	rasprintf(&buf, 
		_("region offset: BAD, tag %d type %d offset %d count %d\n"),
		entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	goto exit;
    }

    /* Is there an immutable header region tag trailer? */
    regionEnd = dataStart + entry.info.offset;
    (void) memcpy(&info, regionEnd, REGION_TAG_COUNT);
    regionEnd += REGION_TAG_COUNT;

    if (headerVerifyInfo(1, dl, &info, &entry.info, 1) != -1 ||
	!(entry.info.tag == RPMTAG_HEADERIMMUTABLE
       && entry.info.type == RPM_BIN_TYPE
       && entry.info.count == REGION_TAG_COUNT))
    {
	rasprintf(&buf, 
		_("region trailer: BAD, tag %d type %d offset %d count %d\n"),
		entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	goto exit;
    }
    memset(&info, 0, sizeof(info));

    /* Is the no. of tags in the region less than the total no. of tags? */
    ril = entry.info.offset/sizeof(*pe);
    if ((entry.info.offset % sizeof(*pe)) || ril > il) {
	rasprintf(&buf, _("region size: BAD, ril(%d) > il(%d)\n"), ril, il);
	goto exit;
    }

    /* Verify header-only digest/signature if there is one we can use. */
    rc = headerSigVerify(keyring, vsflags,
			 il, dl, ril, (regionEnd - dataStart),
			 pe, dataStart, &buf);

exit:
    /* If no header-only digest/signature, then do simple sanity check. */
    if (rc == RPMRC_NOTFOUND) {
	int xx = headerVerifyInfo(ril-1, dl, pe+1, &entry.info, 0);
	if (xx != -1) {
	    rasprintf(&buf,
		_("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
		xx+1, entry.info.tag, entry.info.type,
		entry.info.offset, entry.info.count);
	    rc = RPMRC_FAIL;
	} else {
	    rasprintf(&buf, "Header sanity check: OK\n");
	    rc = RPMRC_OK;
	}
    }

    if (msg) 
	*msg = buf;
    else
	free(buf);

    return rc;
}