예제 #1
0
파일: rpm.c 프로젝트: wlindauer/abrt
void rpm_load_gpgkey(const char* filename)
{
#ifdef HAVE_LIBRPM
    uint8_t *pkt = NULL;
    size_t pklen;
    if (pgpReadPkts(filename, &pkt, &pklen) != PGPARMOR_PUBKEY)
    {
        free(pkt);
        error_msg("Can't load public GPG key %s", filename);
        return;
    }

    uint8_t keyID[8];
#if 0
    if (pgpPubkeyFingerprint(pkt, pklen, keyID) == 0)
#else
    if (pgpPubkeyKeyID(pkt, pklen, keyID) == 0)
#endif
    {
        char *fingerprint = pgpHexStr(keyID, sizeof(keyID));
        if (fingerprint != NULL)
            list_fingerprints = g_list_append(list_fingerprints, fingerprint);
    }
    free(pkt);
#else
    return;
#endif
}
예제 #2
0
파일: signature.c 프로젝트: ereshetova/rpm
static rpmRC
verifyMD5Digest(rpmtd sigtd, DIGEST_CTX md5ctx, char **msg)
{
    rpmRC res = RPMRC_FAIL; /* assume failure */
    uint8_t * md5sum = NULL;
    size_t md5len = 0;
    char *md5;
    const char *title = _("MD5 digest:");
    *msg = NULL;
    DIGEST_CTX ctx = rpmDigestDup(md5ctx);

    if (ctx == NULL) {
	rasprintf(msg, "%s %s\n", title, rpmSigString(res));
	goto exit;
    }

    (void) rpmDigestFinal(ctx, (void **)&md5sum, &md5len, 0);

    md5 = pgpHexStr(md5sum, md5len);
    if (md5len != sigtd->count || memcmp(md5sum, sigtd->data, md5len)) {
	char *hex = rpmtdFormat(sigtd, RPMTD_FORMAT_STRING, NULL);
	rasprintf(msg, "%s %s Expected(%s) != (%s)\n", title,
		  rpmSigString(res), hex, md5);
	free(hex);
    } else {
	res = RPMRC_OK;
	rasprintf(msg, "%s %s (%s)\n", title, rpmSigString(res), md5);
    }
    free(md5);

exit:
    md5sum = _free(md5sum);
    return res;
}
예제 #3
0
파일: rpmpgp.c 프로젝트: crossbuild/rpm
/** \ingroup rpmpgp
 * Return hex formatted representation of a multiprecision integer.
 * @param p		bytes
 * @return		hex formatted string (malloc'ed)
 */
static inline
char * pgpMpiStr(const uint8_t *p)
{
    char *str = NULL;
    char *hex = pgpHexStr(p+2, pgpMpiLen(p)-2);
    rasprintf(&str, "[%4u]: %s", pgpGrab(p, (size_t) 2), hex);
    free(hex);
    return str;
}
예제 #4
0
파일: rpmfi.c 프로젝트: cms-externals/rpm
char * rpmfiFDigestHex(rpmfi fi, pgpHashAlgo *algo)
{
    size_t diglen = 0;
    char *fdigest = NULL;
    const unsigned char *digest = rpmfiFDigest(fi, algo, &diglen);
    if (digest) {
	fdigest = pgpHexStr(digest, diglen);
    }
    return fdigest;
}
예제 #5
0
파일: rpmpgp.c 프로젝트: crossbuild/rpm
static void pgpPrtHex(const char *pre, const uint8_t *p, size_t plen)
{
    char *hex = NULL;
    if (!_print) return;
    if (pre && *pre)
	fprintf(stderr, "%s", pre);
    hex = pgpHexStr(p, plen);
    fprintf(stderr, " %s", hex);
    free(hex);
}
예제 #6
0
int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
{
    int ret;
    unsigned char *digest = NULL;
    unsigned int digestlen;

    if (ctx == NULL) return -1;

    digestlen = EVP_MD_CTX_size(ctx->md_ctx);
    digest = xcalloc(digestlen, sizeof(*digest));

    ret = EVP_DigestFinal_ex(ctx->md_ctx, digest, &digestlen);
    if (ret != 1) goto done;

    if (!asAscii) {
        /* Raw data requested */
        if (lenp) *lenp = digestlen;
        if (datap) {
            *datap = digest;
            digest = NULL;
        }
    }

    else {
        /* ASCII requested */
        if (lenp) *lenp = (2*digestlen) + 1;
        if (datap) {
            const uint8_t * s = (const uint8_t *) digest;
            *datap = pgpHexStr(s, digestlen);
        }
    }

    ret = 1;

done:
    if (digest) {
        /* Zero the digest, just in case it's sensitive */
        memset(digest, 0, digestlen);
        free(digest);
    }

    EVP_MD_CTX_free(ctx->md_ctx);
    free(ctx);

    if (ret != 1) {
        return -1;
    }

    return 0;
}
예제 #7
0
파일: formats.c 프로젝트: OlegGirko/rpm
/**
 * barebones string representation with no extra formatting
 * @param td		tag data container
 * @return		formatted string
 */
static char * stringFormat(rpmtd td)
{
    char *val = NULL;

    switch (rpmtdClass(td)) {
	case RPM_NUMERIC_CLASS:
	    rasprintf(&val, "%" PRIu64, rpmtdGetNumber(td));
	    break;
	case RPM_STRING_CLASS:
	    val = xstrdup(rpmtdGetString(td));
	    break;
	case RPM_BINARY_CLASS:
	    val = pgpHexStr(td->data, td->count);
	    break;
	default:
	    val = xstrdup("(unknown type)");
	    break;
    }
    return val;
}
예제 #8
0
파일: formats.c 프로젝트: OlegGirko/rpm
/**
 * Display signature fingerprint and time.
 * @param td		tag data container
 * @return		formatted string
 */
static char * pgpsigFormat(rpmtd td)
{
    char * val = NULL;

    if (rpmtdType(td) != RPM_BIN_TYPE) {
	val = xstrdup(_("(not a blob)"));
    } else {
	pgpDigParams sigp = NULL;

	if (pgpPrtParams(td->data, td->count, PGPTAG_SIGNATURE, &sigp)) {
	    val = xstrdup(_("(not an OpenPGP signature)"));
	} else {
	    char dbuf[BUFSIZ];
	    char *keyid = pgpHexStr(sigp->signid, sizeof(sigp->signid));
	    unsigned int dateint = pgpGrab(sigp->time, sizeof(sigp->time));
	    time_t date = dateint;
	    struct tm * tms = localtime(&date);
	    unsigned int key_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO);
	    unsigned int hash_algo = pgpDigParamsAlgo(sigp, PGPVAL_HASHALGO);

	    if (!(tms && strftime(dbuf, sizeof(dbuf), "%c", tms) > 0)) {
		snprintf(dbuf, sizeof(dbuf),
			 _("Invalid date %u"), dateint);
		dbuf[sizeof(dbuf)-1] = '\0';
	    }

	    rasprintf(&val, "%s/%s, %s, Key ID %s",
			pgpValString(PGPVAL_PUBKEYALGO, key_algo),
			pgpValString(PGPVAL_HASHALGO, hash_algo),
			dbuf, keyid);

	    free(keyid);
	    pgpDigParamsFree(sigp);
	}
    }

    return val;
}
예제 #9
0
파일: digest.c 프로젝트: cms-externals/rpm
int
rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
{
    unsigned char * digest;
    unsigned int digestlen;

    if (ctx == NULL)
	return -1;
    digestlen = HASH_ResultLenContext(ctx->hashctx);
    digest = xmalloc(digestlen);

DPRINTF((stderr, "*** Final(%p,%p,%p,%zd) hashctx %p digest %p\n", ctx, datap, lenp, asAscii, ctx->hashctx, digest));
/* FIX: check rc */
    HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);

    /* Return final digest. */
    if (!asAscii) {
	if (lenp) *lenp = digestlen;
	if (datap) {
	    *datap = digest;
	    digest = NULL;
	}
    } else {
	if (lenp) *lenp = (2*digestlen) + 1;
	if (datap) {
	    const uint8_t * s = (const uint8_t *) digest;
	    *datap = pgpHexStr(s, digestlen);
	}
    }
    if (digest) {
	memset(digest, 0, digestlen);	/* In case it's sensitive */
	free(digest);
    }
    HASH_Destroy(ctx->hashctx);
    memset(ctx, 0, sizeof(*ctx));	/* In case it's sensitive */
    free(ctx);
    return 0;
}
예제 #10
0
파일: rpmvs.c 프로젝트: junaruga/rpm
static rpmRC rpmsinfoInit(rpmtd td, const char *origin,
		      struct rpmsinfo_s *sinfo, char **msg)
{
    rpmRC rc = RPMRC_FAIL;
    const void *data = NULL;
    const struct vfytag_s *tinfo;
    const struct vfyinfo_s *vinfo;
    rpm_count_t dlen = 0;
    int ix;

    if ((ix = sinfoLookup(td->tag)) == -1) {
	/* anything unknown just falls through for now */
	rc = RPMRC_OK;
	goto exit;
    }
    vinfo = &rpmvfyitems[ix];
    tinfo = &rpmvfytags[ix];
    assert(tinfo->tag == vinfo->tag);

    *sinfo = rpmvfyitems[ix].vi; /* struct assignment */

    if (tinfo->tagtype && tinfo->tagtype != td->type) {
	rasprintf(msg, _("%s tag %u: invalid type %u"),
			origin, td->tag, td->type);
	goto exit;
    }

    if (tinfo->tagcount && tinfo->tagcount != td->count) {
	rasprintf(msg, _("%s: tag %u: invalid count %u"),
			origin, td->tag, td->count);
	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: invalid data %p (%u)"),
			origin, td->tag, data, dlen);
	goto exit;
    }

    if (td->type == RPM_STRING_TYPE && td->size == 0)
	td->size = dlen + 1;

    if (tinfo->tagsize && (td->flags & RPMTD_IMMUTABLE) &&
		tinfo->tagsize != td->size) {
	rasprintf(msg, _("%s tag %u: invalid size %u"),
			origin, td->tag, td->size);
	goto exit;
    }

    if (sinfo->type == RPMSIG_SIGNATURE_TYPE) {
	if (pgpPrtParams(data, dlen, PGPTAG_SIGNATURE, &sinfo->sig)) {
	    rasprintf(msg, _("%s tag %u: invalid OpenPGP signature"),
		    origin, td->tag);
	    goto exit;
	}
	sinfo->hashalgo = pgpDigParamsAlgo(sinfo->sig, PGPVAL_HASHALGO);
	sinfo->keyid = pgpGrab(sinfo->sig->signid+4, 4);
    } else if (sinfo->type == RPMSIG_DIGEST_TYPE) {
	if (td->type == RPM_BIN_TYPE) {
	    sinfo->dig = pgpHexStr(data, dlen);
	} else {
	    if (!validHex(data, dlen)) {
		rasprintf(msg, _("%s: tag %u: invalid hex"), origin, td->tag);
		goto exit;
	    }
	    sinfo->dig = xstrdup(data);
	}
    }

    if (sinfo->hashalgo)
	sinfo->id = (td->tag << 16) | rpmtdGetIndex(td);

    rc = RPMRC_OK;

exit:
    return rc;
}
예제 #11
0
파일: rpmts.c 프로젝트: OlegGirko/rpm
/* Build pubkey header. */
static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp)
{
    Header h = headerNew();
    const char * afmt = "%{pubkeys:armor}";
    const char * group = "Public Keys";
    const char * license = "pubkey";
    const char * buildhost = "localhost";
    const char * userid;
    rpmsenseFlags pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL);
    uint32_t zero = 0;
    uint32_t keytime = 0;
    pgpDig dig = NULL;
    pgpDigParams pubp = NULL;
    char * d = NULL;
    char * enc = NULL;
    char * n = NULL;
    char * u = NULL;
    char * v = NULL;
    char * r = NULL;
    char * evr = NULL;
    int rc = -1;

    if ((enc = rpmPubkeyBase64(key)) == NULL)
	goto exit;
    if ((dig = rpmPubkeyDig(key)) == NULL)
	goto exit;
    if ((pubp = pgpDigGetParams(dig, PGPTAG_PUBLIC_KEY)) == NULL)
	goto exit;

    /* Build header elements. */
    v = pgpHexStr(pubp->signid, sizeof(pubp->signid)); 
    r = pgpHexStr(pubp->time, sizeof(pubp->time));
    userid = pubp->userid ? pubp->userid : "none";
    keytime = pgpGrab(pubp->time, sizeof(pubp->time));

    rasprintf(&n, "gpg(%s)", v+8);
    rasprintf(&u, "gpg(%s)", userid);
    rasprintf(&evr, "%d:%s-%s", pubp->version, v, r);

    headerPutString(h, RPMTAG_PUBKEYS, enc);

    if ((d = headerFormat(h, afmt, NULL)) == NULL)
	goto exit;

    headerPutString(h, RPMTAG_NAME, "gpg-pubkey");
    headerPutString(h, RPMTAG_VERSION, v+8);
    headerPutString(h, RPMTAG_RELEASE, r);
    headerPutString(h, RPMTAG_DESCRIPTION, d);
    headerPutString(h, RPMTAG_GROUP, group);
    headerPutString(h, RPMTAG_LICENSE, license);
    headerPutString(h, RPMTAG_SUMMARY, u);
    headerPutString(h, RPMTAG_PACKAGER, userid);

    headerPutUint32(h, RPMTAG_SIZE, &zero, 1);

    headerPutString(h, RPMTAG_PROVIDENAME, u);
    headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
    headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);
	
    headerPutString(h, RPMTAG_PROVIDENAME, n);
    headerPutString(h, RPMTAG_PROVIDEVERSION, evr);
    headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1);

    headerPutString(h, RPMTAG_RPMVERSION, RPMVERSION);
    headerPutString(h, RPMTAG_BUILDHOST, buildhost);
    headerPutUint32(h, RPMTAG_BUILDTIME, &keytime, 1);
    headerPutString(h, RPMTAG_SOURCERPM, "(none)");

    /* Reload the lot to immutable region and stomp sha1 digest on it */
    h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
    if (h != NULL) {
	char *sha1 = NULL;
	unsigned int blen = 0;
	const void *blob = headerExport(h, &blen);

	/* XXX FIXME: bah, this code is repeated in way too many places */
	DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
	rpmDigestUpdate(ctx, rpm_header_magic, sizeof(rpm_header_magic));
	rpmDigestUpdate(ctx, blob, blen);
	rpmDigestFinal(ctx, (void **)&sha1, NULL, 1);

	if (sha1) {
	    headerPutString(h, RPMTAG_SHA1HEADER, sha1);
	    *hdrp = headerLink(h);
	    rc = 0;
	}
	free(sha1);
    }

exit:
    headerFree(h);
    pgpFreeDig(dig);
    free(n);
    free(u);
    free(v);
    free(r);
    free(evr);
    free(enc);
    free(d);

    return rc;
}