Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add python getter for signature headers #346

Open
sdherr opened this issue Feb 1, 2023 · 13 comments
Open

Add python getter for signature headers #346

sdherr opened this issue Feb 1, 2023 · 13 comments

Comments

@sdherr
Copy link

sdherr commented Feb 1, 2023

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 sdherr changed the title Add python getter for sigpgp and siggpg Add python getter for signature headers Feb 2, 2023
@dralley
Copy link
Contributor

dralley commented Feb 13, 2023

@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.

@kontura
Copy link
Contributor

kontura commented Feb 16, 2023

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.

@dralley
Copy link
Contributor

dralley commented Feb 17, 2023

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.

@sdherr
Copy link
Author

sdherr commented Feb 17, 2023

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.

@dralley
Copy link
Contributor

dralley commented Mar 7, 2023

@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?

@sdherr
Copy link
Author

sdherr commented Mar 14, 2023

@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
Copy link
Author

sdherr commented Mar 14, 2023

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.

@dralley
Copy link
Contributor

dralley commented Mar 14, 2023

I believe SIGPGP and SIGGPG are deprecated and newer versions of RPM don't output them, if I am reading this correctly. rpm-software-management/rpm#2374 (reply in thread)

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
Copy link
Contributor

dralley commented Apr 3, 2023

@DemiMarie Do you have any insight on these questions?

@DemiMarie
Copy link

@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.

@dralley
Copy link
Contributor

dralley commented Apr 4, 2023

@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?

@DemiMarie
Copy link

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

@dralley
Copy link
Contributor

dralley commented Apr 4, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants