コード例 #1
0
ファイル: rpmkeyring.c プロジェクト: akozumpl/rpm
rpmPubkey rpmPubkeyNew(const uint8_t *pkt, size_t pktlen)
{
    rpmPubkey key = NULL;
    pgpDigParams pgpkey = NULL;
    pgpKeyID_t keyid;
    
    if (pkt == NULL || pktlen == 0)
	goto exit;

    if (pgpPubkeyFingerprint(pkt, pktlen, keyid))
	goto exit;

    if (pgpPrtParams(pkt, pktlen, PGPTAG_PUBLIC_KEY, &pgpkey))
	goto exit;

    key = xcalloc(1, sizeof(*key));
    key->pkt = xmalloc(pktlen);
    key->pktlen = pktlen;
    key->pgpkey = pgpkey;
    key->nrefs = 0;
    memcpy(key->pkt, pkt, pktlen);
    memcpy(key->keyid, keyid, sizeof(keyid));

exit:
    return rpmPubkeyLink(key);
}
コード例 #2
0
ファイル: rpmgensig.c プロジェクト: jwakely/rpm
/**
 * Retrieve signature from header tag
 * @param sigh		signature header
 * @param sigtag	signature tag
 * @return		parsed pgp dig or NULL
 */
static pgpDigParams getSig(Header sigh, rpmTagVal sigtag)
{
    struct rpmtd_s pkt;
    pgpDigParams sig = NULL;

    if (headerGet(sigh, sigtag, &pkt, HEADERGET_DEFAULT) && pkt.data != NULL) {
	pgpPrtParams(pkt.data, pkt.count, PGPTAG_SIGNATURE, &sig);
	rpmtdFreeData(&pkt);
    }
    return sig;
}
コード例 #3
0
ファイル: rpmgensig.c プロジェクト: maxamillion/rpm
static int haveSignature(rpmtd sigtd, Header h)
{
    pgpDigParams sig1 = NULL;
    pgpDigParams sig2 = NULL;
    struct rpmtd_s oldtd;
    int rc = 0; /* assume no */

    if (!headerGet(h, rpmtdTag(sigtd), &oldtd, HEADERGET_DEFAULT))
	return rc;

    pgpPrtParams(sigtd->data, sigtd->count, PGPTAG_SIGNATURE, &sig1);
    while (rpmtdNext(&oldtd) >= 0 && rc == 0) {
	pgpPrtParams(oldtd.data, oldtd.count, PGPTAG_SIGNATURE, &sig2);
	if (pgpDigParamsCmp(sig1, sig2) == 0)
	    rc = 1;
	pgpDigParamsFree(sig2);
    }
    pgpDigParamsFree(sig1);
    rpmtdFreeData(&oldtd);

    return rc;
}
コード例 #4
0
ファイル: rpmgensig.c プロジェクト: jwakely/rpm
/*
 * Validate generated signature and insert to header if it looks sane.
 * NSS doesn't support everything GPG does. Basic tests to see if the 
 * generated signature is something we can use.
 * Return 0 on success, 1 on failure.
 */
static int putSignature(Header sigh, int ishdr, uint8_t *pkt, size_t pktlen)
{
    pgpDigParams sigp = NULL;
    rpmTagVal sigtag;
    struct rpmtd_s sigtd;
    int rc = 1; /* assume failure */
    unsigned int hash_algo;
    unsigned int pubkey_algo;

    if (pgpPrtParams(pkt, pktlen, PGPTAG_SIGNATURE, &sigp)) {
	rpmlog(RPMLOG_ERR, _("Unsupported PGP signature\n"));
	goto exit;
    }

    hash_algo = pgpDigParamsAlgo(sigp, PGPVAL_HASHALGO);
    if (rpmDigestLength(hash_algo) == 0) {
	rpmlog(RPMLOG_ERR, _("Unsupported PGP hash algorithm %u\n"), hash_algo);
	goto exit;
    }

    pubkey_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO);
    switch (pubkey_algo) {
    case PGPPUBKEYALGO_DSA:
	sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG;
	break;
    case PGPPUBKEYALGO_RSA:
	sigtag = ishdr ? RPMSIGTAG_RSA : RPMSIGTAG_PGP;
	break;
    default:
	rpmlog(RPMLOG_ERR, _("Unsupported PGP pubkey algorithm %u\n"),
		pubkey_algo);
	goto exit;
	break;
    }

    /* Looks sane, insert into header */
    rpmtdReset(&sigtd);
    sigtd.count = pktlen;
    sigtd.data = pkt;
    sigtd.type = RPM_BIN_TYPE;
    sigtd.tag = sigtag;

    /* Argh, reversed return codes */
    rc = (headerPut(sigh, &sigtd, HEADERPUT_DEFAULT) == 0);

exit:
    pgpDigParamsFree(sigp);
    return rc;
}
コード例 #5
0
ファイル: package.c プロジェクト: akozumpl/rpm
int parsePGPSig(rpmtd sigtd, const char *type, const char *fn,
		 pgpDigParams *sig)
{
    int rc = pgpPrtParams(sigtd->data, sigtd->count, PGPTAG_SIGNATURE, sig);

    if (rc != 0) {
	if (type && fn) {
	    rpmlog(RPMLOG_ERR,
		   _("skipping %s %s with unverifiable signature\n"), type, fn);
	} else if (type) {
	    rpmlog(RPMLOG_ERR,
		   _("skipping %s with unverifiable signature\n"), type);
	}
    }
    return rc;
}
コード例 #6
0
ファイル: rpmgensig.c プロジェクト: maxamillion/rpm
/*
 * Validate generated signature and insert to header if it looks sane.
 * NSS doesn't support everything GPG does. Basic tests to see if the 
 * generated signature is something we can use.
 * Return generated signature tag data on success, NULL on failure.
 */
static rpmtd makeSigTag(Header sigh, int ishdr, uint8_t *pkt, size_t pktlen)
{
    pgpDigParams sigp = NULL;
    rpmTagVal sigtag;
    rpmtd sigtd = NULL;
    unsigned int hash_algo;
    unsigned int pubkey_algo;

    if (pgpPrtParams(pkt, pktlen, PGPTAG_SIGNATURE, &sigp)) {
	rpmlog(RPMLOG_ERR, _("Unsupported PGP signature\n"));
	goto exit;
    }

    hash_algo = pgpDigParamsAlgo(sigp, PGPVAL_HASHALGO);
    if (rpmDigestLength(hash_algo) == 0) {
	rpmlog(RPMLOG_ERR, _("Unsupported PGP hash algorithm %u\n"), hash_algo);
	goto exit;
    }

    pubkey_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO);
    switch (pubkey_algo) {
    case PGPPUBKEYALGO_DSA:
	sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG;
	break;
    case PGPPUBKEYALGO_RSA:
	sigtag = ishdr ? RPMSIGTAG_RSA : RPMSIGTAG_PGP;
	break;
    default:
	rpmlog(RPMLOG_ERR, _("Unsupported PGP pubkey algorithm %u\n"),
		pubkey_algo);
	goto exit;
	break;
    }

    /* Looks sane, create the tag data */
    sigtd = rpmtdNew();
    sigtd->count = pktlen;
    sigtd->data = memcpy(xmalloc(pktlen), pkt, pktlen);;
    sigtd->type = RPM_BIN_TYPE;
    sigtd->tag = sigtag;
    sigtd->flags |= RPMTD_ALLOCED;

exit:
    pgpDigParamsFree(sigp);
    return sigtd;
}
コード例 #7
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;
}
コード例 #8
0
ファイル: signature.c プロジェクト: ignatenkobrain/rpm
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;
    int hexstring = 0;

    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;
	hexstring = 1;
	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 (tagtype && tagtype != td->type) {
	rasprintf(msg, _("%s tag %u: BAD, invalid type %u"),
			origin, td->tag, td->type);
	goto exit;
    }

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

    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 (hexstring) {
	for (const char * b = td->data; *b != '\0'; b++) {
	    if (strchr("0123456789abcdefABCDEF", *b) == NULL) {
		rasprintf(msg, _("%s: tag %u: BAD, not hex"), origin, td->tag);
		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;
}
コード例 #9
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;
}