createrepo_c icon indicating copy to clipboard operation
createrepo_c copied to clipboard

Add python getter for signature headers

Open sdherr opened this issue 2 years ago • 13 comments

The C code already knows how to load sigpgp and siggpg on a Package from the rpm header, but the python bindings don't define getters for those attributes. Can you add one? Nothing fancy, the binary signature is all I want.

I'm not an expert on rpm headers, but it appears that there are also potentially other header fields that could be used for this purpose, like maybe dsaheader and rsaheader? I see them in the definition of the "--info" query format on rpm at least. If they are necessary can you please parse them out of the header too and add python bindings?

sdherr avatar Feb 01 '23 22:02 sdherr

@kontura This would be useful for Pulp - it's possible that the functionality is already available in librpm via python bindings, but the documentation pages for those appear to be broken currently (see: "Programming RPM with Python" on this page http://rpm.org/documentation.html)

If it is, and it's widely available (e.g. EL8), and you don't see any value in proxying the functionality, then I suppose we can close.

dralley avatar Feb 13 '23 18:02 dralley

It is definitely available, I found some description of the API here: https://github.com/rpm-software-management/rpm/blob/master/python/header-py.c

For example this should work:

import os, rpm

ts = rpm.TransactionSet()
fdno = os.open('/home/amatej/htop-3.2.2-1.fc39.x86_64.rpm', os.O_RDONLY)
hdr = ts.hdrFromFdno(fdno)
os.close(fdno)

print(hdr[rpm.RPMTAG_SIGPGP])
print(hdr[rpm.RPMTAG_SIGGPG])

However if it will be more convenient for you I think we can add the python getters.

I'm not an expert on rpm headers, but it appears that there are also potentially other header fields that could be used for this purpose, like maybe dsaheader and rsaheader? I see them in the definition of the "--info" query format on rpm at least. If they are necessary can you please parse them out of the header too and add python bindings?

There is a bunch of header fields related to just signatures: https://github.com/rpm-software-management/rpm/blob/master/docs/manual/tags.md#signatures-and-digests I am not sure which do you require or for what purpose but I don't think we want to add all of them to createrepo_c api.

kontura avatar Feb 16 '23 07:02 kontura

Question: Is there any signatures or other relevant tags (current or future) that you might be interested in @sdherr, that aren't available in the version of RPM currently present on EL8?

The tags are just constants so I'm sure they could be read anyway even if the constant doesn't have a definition in an older version of librpm (that is, the tag could be hardcoded ourselves for better compatibility). But nonetheless.

dralley avatar Feb 17 '23 05:02 dralley

I don't feel qualified to answer that question. Look, what I actually, truly, deep in my heart-of-hearts want, is a single method that I can call that will return THE SIGNATURE of the RPM (with python bindings). Current and future-proof. So that I can pass it off to pgp and read it.

I came up with that list of four headers by looking at what rpm -qi does by looking at the definition of the "alias --info" in /usr/lib/rpm/rpmpopt-*, which seems to me to say that it looks at (in turn) each of DSAHEADER, RSAHEADER, SIGGPG, and SIGPGP, and passing the first one found through a pgpsig filter.

Now, I cannot stress enough how little I know about the internal implementation details of RPM headers. Why are there four instead of one? Beats me. Is there a 5th or 6th coming in the future? Don't know. What I actually care about, is "What is this RPM's signature?" You guys are the RPM experts, you tell me what is necessary.

sdherr avatar Feb 17 '23 06:02 sdherr

@kontura Is it generally true that all of the packages in a distro, be it Fedora X or RHEL Y, are signed with one key and have one specific signature type? I know that during beta cycles at least this is occasionally not true, but I am otherwise not certain.

And how varied are signature types across, say, EL7, EL8 and EL9?

dralley avatar Mar 07 '23 22:03 dralley

@kontura You are assuming that the rpm python module is installed, which is not a given. Yes that works, if python3-rpm is installed. The point of making this available in the createrepo python bindings is to avoid that extra dependency in environments where it is not already given and where requiring a new OS package on a diverse installation base is hard, as is the case for pulp_rpm.

I do not care about all the possible signature fields, just those four. Or I think it would even be acceptable to only have to two that createrepo already knows about and just needs python bindings for.

sdherr avatar Mar 14 '23 21:03 sdherr

The doc you linked was very helpful in that regard. It explained that DSAHEADER and RSAHEADER are signatures of the header packets, not of the body of the rpm. So for my purposes I think that's entirely optional / duplicated with SIGGPG and SIGPGP.

sdherr avatar Mar 14 '23 21:03 sdherr

I believe SIGPGP and SIGGPG are deprecated and newer versions of RPM don't output them, if I am reading this correctly. https://github.com/rpm-software-management/rpm/discussions/2374#discussioncomment-5224278

The header contains metadata on the payload including a checksum of the payload, so you only need to sign the header to effectively sign the whole package, so long as the checksum of the payload is being verified too by the client (and it is). I believe DSA support is also being phased out too (same link), so that leaves RSA.

Are there anything others to be aware of? Is RSAHEADER the most preferred? Is it fairly reliable (e.g. do all packages back to, say, EL7 have them)?

dralley avatar Mar 14 '23 21:03 dralley

@DemiMarie Do you have any insight on these questions?

dralley avatar Apr 03 '23 14:04 dralley

@DemiMarie Do you have any insight on these questions?

SIGPGP and SIGGPG are deprecated. The DSA signature field is used for EdDSA signatures and those are not deprecated, so you need to check both.

DemiMarie avatar Apr 03 '23 18:04 DemiMarie

@DemiMarie Is it guaranteed that a RPM has one and only one signature? e.g. is it possible for an RPM to simultaneously be signed by an RSA key and an EdDSA key and have both signatures present in the header simultaneously?

dralley avatar Apr 04 '23 02:04 dralley

@dralley the current implementation will not produce such packages, but I am not sure if it will accept them.

DemiMarie avatar Apr 04 '23 04:04 DemiMarie

I'm happy to assume it doesn't happen, then.

dralley avatar Apr 04 '23 21:04 dralley