-
Notifications
You must be signed in to change notification settings - Fork 16
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
Feature to sign existing rpm file #46
Conversation
There are a few hoops to jump through, but I will help you to get this done! First, you need to sign the ECA:
I don't think the "signed off" header is required anymore, we will find that out afterwards :) |
I signed the ECA. What do you mean about the "signed off" header ? |
Here is quick summary on this: https://docs.pi-hole.net/guides/github/how-to-signoff/ … but, we don't need it anymore. The ECA check passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good in general, there are a few things I would kindly ask you to iron out.
There are a few other items that I would like to see changed, but that is me :) And I am not sure you want to be bothered with that. It's about the API and how to use this. I would try to aim for some changes that prefer static methods (when an instance is not required) and which use streaming of data (vs reading in the full RPM into memory).
I am happy to work with you on this, if you are interested. But it is ok for me, if you don't have the time. I might follow up on this later on.
I leave this up to you, but don't feel pressured in any way! Really!
rpm/src/main/java/org/eclipse/packager/rpm/signature/RpmFileSignatureProcessor.java
Show resolved
Hide resolved
rpm/src/main/java/org/eclipse/packager/rpm/signature/RpmFileSignatureProcessor.java
Show resolved
Hide resolved
rpm/src/test/java/org/eclipse/packager/rpm/signature/RpmFileSignatureProcessorTest.java
Outdated
Show resolved
Hide resolved
rpm/src/test/java/org/eclipse/packager/rpm/signature/RpmFileSignatureProcessorTest.java
Outdated
Show resolved
Hide resolved
ArmoredInputStream armoredInputStream = new ArmoredInputStream(publicKeyStream); | ||
PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(armoredInputStream); | ||
PGPPublicKey publicKey = publicKeyRing.getPublicKey(); | ||
// TODO Signature Check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's ok if the test isn't there yet. But I think in this case, it should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is to keep the test file logic. Read rpm -> sign it -> write signed rpm -> read it -> verify signature -> remove it. If I remove this test, write the rpm after sign it became useless.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or complete the test before accepting the PR...
I agree for static method. But I hesitate to do a class with an InputStream instance of the file, or static method which can be good too. |
rpm/src/test/java/org/eclipse/packager/rpm/signature/RpmFileSignatureProcessorTest.java
Outdated
Show resolved
Hide resolved
rpm/src/main/java/org/eclipse/packager/rpm/signature/RpmFileSignatureProcessor.java
Outdated
Show resolved
Hide resolved
I would like to do use streaming of data like you describe but I don't know how to do it. That was what I want to do at the first time but I didn't find a way to stream the files many times and split it (or maybe I have to pass a File object directly to the method?). |
rpm/src/main/java/org/eclipse/packager/rpm/signature/RpmFileSignatureProcessor.java
Outdated
Show resolved
Hide resolved
Yea, I am not sure either, but let's give it a try and try to iterate a bit on it:
For the other part, it indeed looks like one needs to iterate over the data twice: 1) for generating the digests, 2) for writing the content (after calculating the digest). I guess there are two alternatives to that:
However, I think that's not worth the effort, unless someone asks for it. But I think there should be a note on the API which tells people that the RPM content will be read into memory, for bigger RPMs that might have an impact. |
I think the memory usage will show itself for RPMs which are significantly above the size of the Java heap that the test application normally has. Say a 1 GiB RPM should show a difference. Unfortunately the changes brought in a few regressions. Using packager/rpm/src/main/java/org/eclipse/packager/rpm/build/RpmWriter.java Lines 265 to 301 in d002b44
I am not sure this complexity is worth the effort. I guess this depends on how many RPMs you plan to sign, and if I/O performance might be an issue. So maybe it is easier to just use something like
|
We don't have many rpm to sign but it can be more than 1.5GB so I prefer to optimize the memory usage. |
I added a method to check if it read/write the good number of bytes. I hope it is enough, actually the test pass and I have the same result than before. |
Yes, that is something that is not really reproducible. It can happen, it can happen only on some platforms. We had an issue like that way back, which only manifested itself on Windows. Still, ignoring the result is a violation of the API, nothing to blame windows for (in this case 😁). Unfortunately, just failing isn't the right approach IMHO. That is ok if the return code is Here is what Guava does for example: https://github.com/google/guava/blob/8506c5312bc78552c21612a614aeeb11c3d24f8b/guava/src/com/google/common/io/ByteStreams.java#L139-L150 However, I don't see much value in replicating that. Maybe it is easier to not use
That should to the same, but not require you to manually count bytes, or use some of the other "safe" read functions. It requires Java 11, but I think we already require that. And if not, I don't see a reason why we can't change to Java 11. For the missing, second, unit test: I think an easy solution to this could be to just assume that the |
I checked InputStream.#readNBytes(byte[],int,int) and InputStream#readAllBytes() but it put all bytes into memory... I made a rework using commons-compress methods, I think it is enough for memory optimization. |
Bonus points for keeping Java 8 compatibility :D … should anyone need that :) I think all that remains is to implement the second unit test, IIRC you had a command to verify this, using |
RpmInputStream rpmSigned = new RpmInputStream(new FileInputStream(signedRpm)); | ||
rpmSigned.available(); | ||
rpmSigned.close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ctron I know this is an old PR, but I see this isn't really handled properly. I will make a PR.
Link to rpm-builder#75
This allows to sign an existing rpm file by using RpmFileSignatureProcessor.
Example :
A complete example is available in units tests -> RpmFileSignatureProcessorTest
The solution has been verified on linux with "rpm --checksig" command.
A next step could be to verify the signature (test initialized) but I prefers to develop it in another feature.