Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-11-02 Thread Justus Winter
Michael Schroeder  writes:

> On Mon, Nov 01, 2021 at 04:37:21PM +0100, Justus Winter wrote:
>> Pointing to openssl or gcrypt doesn't really fly.  gcrypt and openssl
>> (at least the interface that RPM uses) are providing mechanisms without
>> policy.
>
> Most distros have patches that make the crypto libraries read
> /proc/sys/crypto/fips_enabled and enforce restrictions in FIPS mode.

I understand that.  I also know how to programmatically put gcrypt
and openssl into FIPS mode.  Please see my test program:

https://sequoia-pgp.org/tmp/fipstest.c

My point is the following.  If RPM relies on policies enforced by the
underlying crypto libraries, such as FIPS, and there is no additional
mechanism in RPM, then RPM is unfortunately not following best practices
when it comes to sunsetting insecure hash algorithms.

Again, if there is an additional mechanism that I haven't found yet, I'm
sorry for the noise.  Then again, noone pointed me to that.

These are my findings for openSUSE 15.3:

linux@localhost:~> ./fipstest
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl allows MD5
openssl has SHA1
openssl allows SHA1
linux@localhost:~> ./fipstest turn on fips mode please
WARN: Failed to get gcrypt into fips mode
WARN: The current version of OpenSSL is not FIPS-capable.
WARN: Failed to get openssl into FIPS mode
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl has SHA1
linux@localhost:~> sudo mkdir /etc/gcrypt
linux@localhost:~> sudo touch /etc/gcrypt/fips_enabled
linux@localhost:~> ./fipstest turn on fips mode please
WARN: Failed to get gcrypt into fips mode
WARN: The current version of OpenSSL is not FIPS-capable.
WARN: Failed to get openssl into FIPS mode
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl has SHA1

So indeed, if I enable FIPS mode, openssl no longer allows MD5 or SHA1
to be used.  Unfortunately, that doesn't help RPM, because on openSUSE,
RPM links against gcrypt, which allows both MD5 and SHA1:

linux@localhost:~> ldd /bin/rpm | grep gcrypt
libgcrypt.so.20 => /usr/lib64/libgcrypt.so.20 (0x7f5f5ddcb000)

These are my findings for SLES 15sp3:

jj@localhost:~> ./fipstest
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl allows MD5
openssl has SHA1
openssl allows SHA1
jj@localhost:~> ./fipstest enable fips mode please
WARN: Failed to get gcrypt into fips mode
WARN: The current version of OpenSSL is not FIPS-capable.
WARN: Failed to get openssl into FIPS mode
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl has SHA1
jj@localhost:~> sudo mkdir /etc/gcrypt
[sudo] password for root:
jj@localhost:~> sudo touch /etc/gcrypt/fips_enabled
jj@localhost:~> ./fipstest enable fips mode please
WARN: Failed to get gcrypt into fips mode
WARN: The current version of OpenSSL is not FIPS-capable.
WARN: Failed to get openssl into FIPS mode
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl has SHA1
jj@localhost:~> ldd /bin/rpm | grep gcrypt
libgcrypt.so.20 => /usr/lib64/libgcrypt.so.20 (0x7fac0729a000)

So, same as openSUSE.

I conclude that both openSUSE's and SLES' RPM accept MD5 and SHA1
binding signatures and signatures over RPMs.

Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-11-01 Thread Justus Winter
Panu Matilainen  writes:

> On 11/1/21 14:07, Justus Winter wrote:
>> Neal Gompa  writes:
>>
>>> On Thu, Oct 28, 2021 at 11:17 AM Justus Winter  
>>> wrote:
>>>>
>>>> Panu Matilainen  writes:
>>>>
>>>>>> https://tests.sequoia-pgp.org/rpmsop.html#Detached_Sign-Verify_roundtrip_with_key__Bob___MD5
>>>>>>
>>>>>> - accepts MD5 signatures !!!
>>>>>>
>>>>>> https://tests.sequoia-pgp.org/rpmsop.html#Signature_over_the_shattered_collision
>>>>>>
>>>>>> - accepts SHA1 signatures !!!
>>>>>
>>>>> Rpm needs to be able to work with content from the nineties, when MD5
>>>>> was still the hottest thing around, ditto with SHA1.
>>>>
>>>> Contemporary versions of RPM need to work with content from the
>>>> nineties?  I find that hard to believe.
>>>>
>>>
>>> I still sometimes deal with RPMs created in the early 2000s, it's not
>>> terribly hard to believe people wind up working with older stuff. Lots
>>> of old Linux games were released as RPMs back in the 90s too.
>>
>> I see.  But, that doesn't mean that the RPMs are signed, or that the
>> signer's key is trusted by you, or that the signer's key uses a public
>> key signing algorithm and key size that is still cryptographically
>> relevant today.
>>
>> I'm of the firm belief that signatures with weak hash algorithms should
>> be considered either bad or non-existent, and explicit override by the
>> administrator should be necessary to override that.
>
> FWIW, non-existence is how rpm treats such things when encountered, such
> as in FIPS mode.
>
>>
>> In the pull request, Panu writes:
>>
>>> I'm saying that deciding what is an acceptable algorithm and what is
>>> not, is a question that does not belong to rpm at all. It's a matter
>>> of distro/system policies, including but not limited to FIPS
>>
>> I'm worried about that.  First of all, considering signatures using MD5
>> or SHA1 bad is not a policy, that is baseline footgun protection.  Any
>> distro policy should be on top of that, i.e. a refinement.
>
> I'm not arguing that MD5 or SHA1 is a secure algorithm by now, it's just
> that questions like "what is and what is not a secure algorithm" leads
> into the kind of political crap that I simply refuse to touch in rpm.
>
> This is just a side-track of the agenda at hand, now can we please just
> agree to disagree and move on.

Well, I need to get a feel of the status quo, and how receptive a
community is with respect to changes and contributions before I start
putting in considerable effort.

>> Also, I don't quite understand how this policy is enabled or enforced.
>> As far as I can see, you defer the decision on what algorithm is
>> acceptable to the cryptographic backend.
>
> Yes.
>
>> First, RPM makes no effort to put either openssl nor gcrypt into FIPS
>> mode, so it has to be a distro-wide or system wide configuration.
>
> It's not RPM's business to configure such a thing even if it could! It's
> a system policy that somebody needs to set, and rpm will happily comply.
>
>> https://www.gnupg.org/documentation/manuals/gcrypt/Enabling-FIPS-mode.html
>> https://wiki.openssl.org/index.php/FIPS_mode_set()
>>
>> System-wide FIPS mode is not enabled by default on Fedora 35 or Debian
>> Bullseye.
>
> I've only been using FIPS mode as an example of a policy that does
> enforce obsolete hashes not getting used. FIPS is a whole lot more
> though, it's not something the average user will want to have enabled.
> My point is that there are mechanisms to deal with this on central
> level, and that's where it should be handled. If MD5 is considered
> insecure then disable the damn thing in the crypto library, and rpm will
> merrily comply.

I am also using FIPS as a stand-in for any kind of policy, mostly
because it is the only one I know that enjoys widespread support in
software and I kind of know how to get the crypto libraries into that
policy.

>> Second, OpenPGP separates digest computation and signature verification
>> into two steps.  When RPM hands off the digest to the cryptographic
>> library, then the library doesn't have enough context to understand
>> which hash algorithm produced the digest (with the exception of RSA
>> signature verification, where the hash algorithm is passed along with
>> the digest).
>>
>> Therefore, whether a hash algorithm is accepted for signature
>> verification comes down to whether it is produced by

Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-11-01 Thread Justus Winter
Justus Winter  writes:

>>>>> Looking at the task for roughly an hour or so (so, take it with a grain
>>>>> of salt...), my strategy would be to decouple the current implementation
>>>>> by clearly defining the public API, then provide a drop-in replacement
>>>>> for that API that can be enabled at compile-time.
>>>>>
>>>>> Does that sound reasonable?
>>>>
>>>> Decoupling the implementation from the API would be beneficial to rpm in
>>>> any case because
>>>> a) it'd also enable implementing support for other libraries as well (eg
>>>> RNP which is much closer in language family) and as long as the internal
>>>> implementation is preserved, bootstrapping with minimal dependencies.
>>>> b) doing so tends to have a positive impact on codebase
>>>> c) having someone experienced with OpenPGP do it, the resulting API may
>>>> even make some sense...
>>>>
>>>> So while I'm not at all eager to gain a Rust dependency and there'll be
>>>> somewhat more (not less) code to maintain, but as per the plan above I
>>>> think this sounds like a net positive for us. Always assuming somebody
>>>> is willing to do the work that is.
>>> 
>>> Great.  I'll give it a try and will likely come back with questions in
>>> the process.
>>> 
>>>>> Do you have questions or remarks?  I'm happy to get the discussion
>>>>> rolling :)
>>>>
>>>> As a someone who's been living under a crate when it comes to Rust... I
>>>> can see from the Sequoia docs that FFI is used for calling from other
>>>> languages and there's a separate C library for this. How's the API
>>>> coverage (just curious) and more importantly, stability? And if this is
>>>> a shared library then the question extends to ABI stability as well.
>>> 
>>> That is a good question.  When we started with Sequoia, we imagined
>>> having a general-purpose C API.  We started to build one, driven by the
>>> needs of our companies C library.  However, it became increasingly clear
>>> that a) this is a lot of work, b) the general-purpose interface was
>>> quite brittle, and most importantly c) it resulted in a lot of code on
>>> the consumer side that would have been much more concise and robust if
>>> it would have been written in Rust using the native interface.
>>> 
>>> Hence, our new strategy is to create point solutions in Rust that expose
>>> the exact handful of functions that a project requires.  We have done
>>> that for our companies library, and it has greatly improved the quality
>>> of the code.  You can see examples of such point solutions here:
>>> 
>>> https://gitlab.com/teythoon/sequoia-nlnet-encrypt-confirmation
>>> https://gitlab.com/wiktor/anonaddy-sequoia
>>> 
>>> For RPM, this point solution would implement the public functions from
>>> rpmio/{rpmpgp,rpmkeyring,digest}*.  This API is internal to RPM, so any
>>> changes to the C side would also be made to the Rust side.  Hopefully,
>>> the interface will be small and changes seldom.
>>
>> So... what does this mean in practical terms? Somebody maintains this 
>> piece of Rust code externally somewhere? And a versioned shared library 
>> + header file is what you get when it's built? Do you have an example of 
>> such a point solution for a C/C++ project?
>
> Yes.  This is the point solution for the pEp engine, which is our

My apologies...

Yes.  This is the point solution for the pEp engine, which is our
companies high-level key management library:

https://gitea.pep.foundation/neal/pEpEngineSequoiaBackend/src/branch/main

It builds a shared library that is linked to the main library.

>> Just kinda worried about this requirement to sync with an external 
>> project in a language none of us knows anything about.

I understand.

Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-11-01 Thread Justus Winter
Panu Matilainen  writes:

> On 10/25/21 18:06, Justus Winter wrote:
>> Panu Matilainen  writes:
>>>> I have also skimmed RPM's code.  From what I can tell, the relevant code
>>>> is in rpmio/{rpmpgp,rpmkeyring,digest}*, the public API uses the "rpm"
>>>> prefix, "pgp"-prefixed functions and types are hardly used outside of
>>>> the PGP implementation.
>>>
>>> The users of those pgp* functions are not many there are a handful so it
>>> can't be all just thrown away at once. Unfortunately.
>> 
>> Sure, I didn't meant to throw them out, but just review the call sites
>> and maybe make it part of the public API.
>
> Yup, understood. *I* would like to throw them out though :)

Yeah, I can see that now :)

>>>> Looking at the task for roughly an hour or so (so, take it with a grain
>>>> of salt...), my strategy would be to decouple the current implementation
>>>> by clearly defining the public API, then provide a drop-in replacement
>>>> for that API that can be enabled at compile-time.
>>>>
>>>> Does that sound reasonable?
>>>
>>> Decoupling the implementation from the API would be beneficial to rpm in
>>> any case because
>>> a) it'd also enable implementing support for other libraries as well (eg
>>> RNP which is much closer in language family) and as long as the internal
>>> implementation is preserved, bootstrapping with minimal dependencies.
>>> b) doing so tends to have a positive impact on codebase
>>> c) having someone experienced with OpenPGP do it, the resulting API may
>>> even make some sense...
>>>
>>> So while I'm not at all eager to gain a Rust dependency and there'll be
>>> somewhat more (not less) code to maintain, but as per the plan above I
>>> think this sounds like a net positive for us. Always assuming somebody
>>> is willing to do the work that is.
>> 
>> Great.  I'll give it a try and will likely come back with questions in
>> the process.
>> 
>>>> Do you have questions or remarks?  I'm happy to get the discussion
>>>> rolling :)
>>>
>>> As a someone who's been living under a crate when it comes to Rust... I
>>> can see from the Sequoia docs that FFI is used for calling from other
>>> languages and there's a separate C library for this. How's the API
>>> coverage (just curious) and more importantly, stability? And if this is
>>> a shared library then the question extends to ABI stability as well.
>> 
>> That is a good question.  When we started with Sequoia, we imagined
>> having a general-purpose C API.  We started to build one, driven by the
>> needs of our companies C library.  However, it became increasingly clear
>> that a) this is a lot of work, b) the general-purpose interface was
>> quite brittle, and most importantly c) it resulted in a lot of code on
>> the consumer side that would have been much more concise and robust if
>> it would have been written in Rust using the native interface.
>> 
>> Hence, our new strategy is to create point solutions in Rust that expose
>> the exact handful of functions that a project requires.  We have done
>> that for our companies library, and it has greatly improved the quality
>> of the code.  You can see examples of such point solutions here:
>> 
>> https://gitlab.com/teythoon/sequoia-nlnet-encrypt-confirmation
>> https://gitlab.com/wiktor/anonaddy-sequoia
>> 
>> For RPM, this point solution would implement the public functions from
>> rpmio/{rpmpgp,rpmkeyring,digest}*.  This API is internal to RPM, so any
>> changes to the C side would also be made to the Rust side.  Hopefully,
>> the interface will be small and changes seldom.
>
> So... what does this mean in practical terms? Somebody maintains this 
> piece of Rust code externally somewhere? And a versioned shared library 
> + header file is what you get when it's built? Do you have an example of 
> such a point solution for a C/C++ project?

Yes.  This is the point solution for the pEp engine, which is our 

> Just kinda worried about this requirement to sync with an external 
> project in a language none of us knows anything about.


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-11-01 Thread Justus Winter
Justus Winter  writes:

> Even though second preimage attacks on these two hash functions are
> still very expensive, the shattered paper demonstrates that hash
> collisions are enough to re-purpose an OpenPGP signature.
>
> https://shattered.io/

Sorry, I meant the SHA-1 is a Shambles paper.

https://sha-mbles.github.io/

Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-11-01 Thread Justus Winter
Neal Gompa  writes:

> On Thu, Oct 28, 2021 at 11:17 AM Justus Winter  wrote:
>>
>> Panu Matilainen  writes:
>>
>> >> https://tests.sequoia-pgp.org/rpmsop.html#Detached_Sign-Verify_roundtrip_with_key__Bob___MD5
>> >>
>> >> - accepts MD5 signatures !!!
>> >>
>> >> https://tests.sequoia-pgp.org/rpmsop.html#Signature_over_the_shattered_collision
>> >>
>> >> - accepts SHA1 signatures !!!
>> >
>> > Rpm needs to be able to work with content from the nineties, when MD5
>> > was still the hottest thing around, ditto with SHA1.
>>
>> Contemporary versions of RPM need to work with content from the
>> nineties?  I find that hard to believe.
>>
>
> I still sometimes deal with RPMs created in the early 2000s, it's not
> terribly hard to believe people wind up working with older stuff. Lots
> of old Linux games were released as RPMs back in the 90s too.

I see.  But, that doesn't mean that the RPMs are signed, or that the
signer's key is trusted by you, or that the signer's key uses a public
key signing algorithm and key size that is still cryptographically
relevant today.

I'm of the firm belief that signatures with weak hash algorithms should
be considered either bad or non-existent, and explicit override by the
administrator should be necessary to override that.

In the pull request, Panu writes:

> I'm saying that deciding what is an acceptable algorithm and what is
> not, is a question that does not belong to rpm at all. It's a matter
> of distro/system policies, including but not limited to FIPS

I'm worried about that.  First of all, considering signatures using MD5
or SHA1 bad is not a policy, that is baseline footgun protection.  Any
distro policy should be on top of that, i.e. a refinement.

Also, I don't quite understand how this policy is enabled or enforced.
As far as I can see, you defer the decision on what algorithm is
acceptable to the cryptographic backend.

First, RPM makes no effort to put either openssl nor gcrypt into FIPS
mode, so it has to be a distro-wide or system wide configuration.

https://www.gnupg.org/documentation/manuals/gcrypt/Enabling-FIPS-mode.html
https://wiki.openssl.org/index.php/FIPS_mode_set()

System-wide FIPS mode is not enabled by default on Fedora 35 or Debian
Bullseye.

Second, OpenPGP separates digest computation and signature verification
into two steps.  When RPM hands off the digest to the cryptographic
library, then the library doesn't have enough context to understand
which hash algorithm produced the digest (with the exception of RSA
signature verification, where the hash algorithm is passed along with
the digest).

Therefore, whether a hash algorithm is accepted for signature
verification comes down to whether it is produced by the backend or
not.  I wrote a small test program to explore this.

This is the result on Fedora 35:

[liveuser@localhost-live ~]$ ./fipstest
gcrypt allows MD5
gcrypt allows SHA1
WARN: The current version of OpenSSL is not FIPS-capable.
openssl has MD5
openssl has SHA1
openssl allows SHA1
[liveuser@localhost-live ~]$ ./fipstest enable fips mode please
gcrypt allows MD5
gcrypt allows SHA1
WARN: The current version of OpenSSL is not FIPS-capable.
openssl has MD5
openssl has SHA1
openssl allows SHA1

This is the result on Debian Bullseye:

% ./fipstest
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl allows MD5
openssl has SHA1
openssl allows SHA1
% ./fipstest fips mode please
WARN: The current version of OpenSSL is not FIPS-capable.
WARN: Failed to get openssl into FIPS mode
gcrypt allows MD5
gcrypt allows SHA1
openssl has MD5
openssl allows MD5
openssl has SHA1
openssl allows SHA1

Some observations:

  - On both systems, FIPS mode has no influence on the availability of
MD5 or SHA1 in gcrypt or openssl.

  - Fedora seems to have patched openssl to unconditionally disable MD5.

  - On Fedora, RPM links against openssl, on Debian against gcrypt.

Based on these observations, I conclude that ---unless I missed a
different mechanism that enforces a different policy---

  - on Fedora, RPM accepts SHA1 signatures

  - on Debian, RPM accepts MD5 and SHA1 signatures

independent of whether FIPS mode is enabled, and that applies both for
signatures over data (i.e. RPM authentication) and binding signatures
(i.e. OpenPGP certificate canonicalization).

Even though second preimage attacks on these two hash functions are
still very expensive, the shattered paper demonstrates that hash
collisions are enough to re-purpose an OpenPGP signature.

https://shattered.io/

Please check my findings.  A black box test would also be good, but I'm
not familiar enough with RPM to produce one.


Thanks,
Justus
/* gcc -o fipstest fipstest.c `libgcrypt-config --cflags --libs` `pkg-config --cflags --libs openssl` */

#include 
#include 
#include 

int main(int argv, char **argc) {

Re: [Rpm-maint] [rpm-software-management/rpm] Justus/openpgp fixes (PR #1813)

2021-10-27 Thread Justus Winter
@teythoon commented on this pull request.



> @@ -503,6 +500,9 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, 
> pgpSigType sigtype,
case PGPSUBTYPE_REVOKE_REASON:
case PGPSUBTYPE_FEATURES:
case PGPSUBTYPE_EMBEDDED_SIG:
+   pgpPrtHex("", p+1, plen-1);
+   break;
+   case PGPSUBTYPE_NOTATION:

The difference is that you made an conscious decision to ignore a subpacket 
like the features subpacket, whereas you did not make a conscious decision to 
ignore the notation with the name "something-import...@example.org".

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/rpm-software-management/rpm/pull/1813#discussion_r737562867___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] [rpm-software-management/rpm] Justus/openpgp fixes (PR #1813)

2021-10-27 Thread Justus Winter
@teythoon pushed 1 commit.

1780fbe2286b309f8bdc24728731f2e28603  Fix handling of signature notations


-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/rpm-software-management/rpm/pull/1813/files/d70ee8e68871281664d8b0edfbdc511ad6947fcf..1780fbe2286b309f8bdc24728731f2e28603
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


[Rpm-maint] [rpm-software-management/rpm] Justus/openpgp fixes (PR #1813)

2021-10-27 Thread Justus Winter

You can view, comment on, or merge this pull request online at:

  https://github.com/rpm-software-management/rpm/pull/1813

-- Commit Summary --

  * https://github.com/rpm-software-management/rpm/pull/1813/commits/5d7965a23779321ba2e8820e1859507f03e0e152;>Fix
 signature subpacket type handling
  * https://github.com/rpm-software-management/rpm/pull/1813/commits/7c261daabb14299c53e5f6ad966ece6d9e398f4a;>Fix
 handling of critical signature subpackets
  * https://github.com/rpm-software-management/rpm/pull/1813/commits/0d83d29ba824e4f2d8ef7f3073327d5f2253f7c0;>Fix
 hashlen overflow
  * https://github.com/rpm-software-management/rpm/pull/1813/commits/73a3eddbb22f559f6e1ecd85331b6f28e9045ef2;>Fix
 typo
  * https://github.com/rpm-software-management/rpm/pull/1813/commits/d70ee8e68871281664d8b0edfbdc511ad6947fcf;>Fix
 Ed25519 signature verification using libgcrypt

-- File Changes --

M rpmio/digest.h (2)
M rpmio/digest_libgcrypt.c (2)
M rpmio/rpmkeyring.h (2)
M rpmio/rpmpgp.c (11)

-- Patch Links --

https://github.com/rpm-software-management/rpm/pull/1813.patch
https://github.com/rpm-software-management/rpm/pull/1813.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/rpm-software-management/rpm/pull/1813
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-10-27 Thread Justus Winter
Justus Winter  writes:

> Panu Matilainen  writes:
>
>> Decoupling the implementation from the API would be beneficial to rpm in 
>> any case because
>> a) it'd also enable implementing support for other libraries as well (eg 
>> RNP which is much closer in language family) and as long as the internal 
>> implementation is preserved, bootstrapping with minimal dependencies.
>> b) doing so tends to have a positive impact on codebase
>> c) having someone experienced with OpenPGP do it, the resulting API may 
>> even make some sense...
>>
>> So while I'm not at all eager to gain a Rust dependency and there'll be 
>> somewhat more (not less) code to maintain, but as per the plan above I 
>> think this sounds like a net positive for us. Always assuming somebody 
>> is willing to do the work that is.
>
> Great.  I'll give it a try and will likely come back with questions in
> the process.

To get familiar with the code and interface, I wrote a SOP
implementation on top of RPM's OpenPGP implementation.

https://www.ietf.org/archive/id/draft-dkg-openpgp-stateless-cli-03.html

It only verifies signatures, of course.  Nevertheless, I was then able
to plug it into our interoperability test suite, and it turned up
interesting results.  See below.

In the process, I had to fix a few issues in the implementation to get
it to a point where it was able to verify a signature made by Sequoia
PGP using a key created by Sequoia.

https://github.com/rpm-software-management/rpm/pull/1813

It seems to me that it is not only a point solution to verify
signatures, but it has been written around the material that GnuPG
creates rather than being a first-principles implementation.  That is
unfortunate for a number of reasons.  First, it leads to a rather
brittle implementation.  Second, it prevents users of RPM from
transitioning to a different PGP implementation.  Finally, it even
prevents GnuPG from ever evolving.

Regarding the interface, I was surprised how low-level it was.  Not only
is that hard to use, but it also leaks implementation and OpenPGP
details to the call sites.  Ideally, there should be one function that
given a set of certificates, a signature, and the data should return
whether the data could be authenticated.  Plus a couple of functions for
diagnostics and miscellaneous stuff.

If I were to add a second backend, I'd first rework the interface to be
considerably more high-level.


Here are the interoperability test suite results.  Note that many tests
simply fail for rpmsop because it doesn't do encryption:

https://tests.sequoia-pgp.org/rpmsop.html

These are my notes interpreting the results.  !!! marks security
problems:

https://tests.sequoia-pgp.org/rpmsop.html#Detached_signature_with_Subpackets

- issuer fingerprint handling would be nice
- signatures with multiple issuers not well supported
- invalid signatures with missing or unhashed creation time are considered valid
- signatures with future creation time are considered valid

https://tests.sequoia-pgp.org/rpmsop.html#Detached_signatures__Linebreak_normalization

- text mode line ending normalization is broken (or not implemented)

https://tests.sequoia-pgp.org/rpmsop.html#Detached_signatures_with_unknown_packets

- unknown signature versions should be ignored

https://tests.sequoia-pgp.org/rpmsop.html#Detached_Sign-Verify_roundtrip_with_key__Bob___MD5

- accepts MD5 signatures !!!

https://tests.sequoia-pgp.org/rpmsop.html#Signature_over_the_shattered_collision

- accepts SHA1 signatures !!!

https://tests.sequoia-pgp.org/rpmsop.html#Primary_key_binding_signatures

- accepts signing-capable subkeys without primary key binding signature !!!

https://tests.sequoia-pgp.org/rpmsop.html#Key_Flags_Composition

- accepts signatures made by encryption subkeys !!!

https://tests.sequoia-pgp.org/rpmsop.html#Temporary_validity

- pays no attention to timestamps and relations between cert and signature !!!

https://tests.sequoia-pgp.org/rpmsop.html#Marker_Packet

- marker packets must be ignored

https://tests.sequoia-pgp.org/rpmsop.html#Mangled_ASCII_Armored_Signatures

- ASCII armor parser is very brittle


The tests don't reflect that, but I saw that ECDSA is not supported.
AIUI that means that in FIPS mode, only RSA signatures can be used.


I also looked at the fix for CVE-2021-3521.  It adds code that does what
I'd call partial certificate canonicalization.  There are some crucial
steps missing, like reasoning about key metadata (at least keyflags) and
checking primary key binding signatures.  Also, the code rejects some
conforming certificates, like certs with an encryption-capable, non-RSA
subkey followed by an signing-capable subkey.

I'm also worried that the test vectors added in that commit are somewhat
misleading, at least the names don't match exactly what is in them:

CVE-2021-3521-badbind.asc: Sounds like it has a bad binding signature,
but infact 

Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-10-26 Thread Justus Winter
Michael Schroeder  writes:

> On Mon, Oct 25, 2021 at 05:32:38PM +0200, Justus Winter wrote:
>> Michael Schroeder  writes:
>> 
>> > On 10/21/21 18:12, Justus Winter wrote:
>> >> First, I think replacing RPM's point solution with a general purpose
>> >> implementation will improve correctness.  Robust signature verification
>> >> requires canonicalization of the issuing certificate, which is tricky
>> >> [0], [1], [2].
>> >
>> > Wait, those links don't say why canonicalization is required. What's
>> > the attack vector? Do you have other pointers?
>> 
>> Canonicalization is required before a certificate can be safely used for
>> any operation.  OpenPGP certificates are compound structures made out of
>> packets bound together by signatures.  Canonicalization requires several
>> steps, among them re-ordering out-of-place packets, deduplicating
>> packets, checking signatures (and embedded signatures for signing
>> subkeys), reasoning about signature and key lifetimes, and revocations.
>
> Yes, except that rpm needs just a very limited subset of this. No
> chain of trust, no revokations, and so on. It basically needs what
> 'gpgv' is providing: it must check a signature against a set of
> trusted public keys.

gpgv absolutely does certificate canonicalization.  And it does a lot of
the things that I have mentioned.

I think what you are saying is that RPM expects certificates to be
canonicalized before they are fed to RPM.  But, that is exactly what led
to CVE-2021-3521.

https://access.redhat.com/security/cve/cve-2021-3521

>> That unfortunately is true.  Or rather, it was.  OpenPGP's development
>> picked up speed, we recently formed a design team that is creating a
>> proposal for the next RFC, and have produced a new draft just last week:
>> 
>> https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh/
>> 
>> Relevant changes for RPM include: New key packet types, new hash
>> algorithms, EdDSA over Ed448, new fingerprint format, maybe new
>> signature packet types.
>
> Yeah, that's the old rfc Werner has been working on the last 6 years.
> I hopt it finally gets out of the "draft" status. (Actually, it's more
> imporatant to us what features gpg already provides. So we already
> implemented ed25519 even if it is still only in a ietf draft.)

No, that is not the old RFC that Werner has been working on.  The
document that Werner worked on is

https://datatracker.ietf.org/doc/draft-ietf-openpgp-rfc4880bis/

It is true that a lot of changes that were in RFC4880bis were cleaned
up, improved, and merged into the openpgp-crypto-refresh.  But, in
contrast to RFC4880bis, the openpgp-crypto-refresh has been written by
the working group's design team and represents a broad consensus among
active OpenPGP implementations.

(Disclaimer: I'm part of the design team.)

Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-10-25 Thread Justus Winter
Michael Schroeder  writes:

> On 10/21/21 18:12, Justus Winter wrote:
>> First, I think replacing RPM's point solution with a general purpose
>> implementation will improve correctness.  Robust signature verification
>> requires canonicalization of the issuing certificate, which is tricky
>> [0], [1], [2].
>
> Wait, those links don't say why canonicalization is required. What's
> the attack vector? Do you have other pointers?

Canonicalization is required before a certificate can be safely used for
any operation.  OpenPGP certificates are compound structures made out of
packets bound together by signatures.  Canonicalization requires several
steps, among them re-ordering out-of-place packets, deduplicating
packets, checking signatures (and embedded signatures for signing
subkeys), reasoning about signature and key lifetimes, and revocations.

>> Further, RPM shouldn't be burdened with maintaining
>> their own point solution, which will require constant maintenance to
>> keep up with evolving standards and algorithms.
>
> I somewhat agree except that PGP moves really really slowly. It takes
> ages till some new algorithm goes in. See EdDSA as an example.

That unfortunately is true.  Or rather, it was.  OpenPGP's development
picked up speed, we recently formed a design team that is creating a
proposal for the next RFC, and have produced a new draft just last week:

https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh/

Relevant changes for RPM include: New key packet types, new hash
algorithms, EdDSA over Ed448, new fingerprint format, maybe new
signature packet types.

I expect the working group to produce a new revision of OpenPGP later
this year or early next year.

>> Second, Rust has been criticized for being not too portable [3].  While
>> there is some truth to that, at least today, there is ongoing work to
>> add a GCC backend to the Rust compiler [4], and to write a Rust frontend
>> for GCC [5].
>
> But doesn't that mean that we need to wait till this work is done?

Well, we can carefully structure the work so that RPM can keep the
current implementation while adding support for a Sequoia-based one.  So
RPM can keep using its current implementation in environments where Rust
is too much of a burden as a build dependency.  At the same time, adding
a proper abstraction layer will likely benefit the code base, and we can
improve the current implementation by comparing what it computes with
what Sequoia computes.

Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-10-25 Thread Justus Winter
Panu Matilainen  writes:

> The missing big item on this laundry-list is bootstrapping. Rpm is 
> needed very early on when bootstrapping a distro and people do not want 
> to deal with something like Rust in there. Gcc learning Rust would/will 
> change that somewhat of course, but gcc is not the only compiler used to 
> build rpm.

Indeed.  The question here for me is whether RPM needs signature
verification in the bootstrap setting at all.  Because I could imagine
bootstrapping as a two-step process, where first all the source RPMs are
verified by the host system's RPM, and the "bootstrap RPM" just skips
over the verification process.  But, I don't know how bootstrapping is
done in the RPM world.

>> I have also skimmed RPM's code.  From what I can tell, the relevant code
>> is in rpmio/{rpmpgp,rpmkeyring,digest}*, the public API uses the "rpm"
>> prefix, "pgp"-prefixed functions and types are hardly used outside of
>> the PGP implementation.
>
> The users of those pgp* functions are not many there are a handful so it 
> can't be all just thrown away at once. Unfortunately.

Sure, I didn't meant to throw them out, but just review the call sites
and maybe make it part of the public API.

>> Looking at the task for roughly an hour or so (so, take it with a grain
>> of salt...), my strategy would be to decouple the current implementation
>> by clearly defining the public API, then provide a drop-in replacement
>> for that API that can be enabled at compile-time.
>> 
>> Does that sound reasonable? 
>
> Decoupling the implementation from the API would be beneficial to rpm in 
> any case because
> a) it'd also enable implementing support for other libraries as well (eg 
> RNP which is much closer in language family) and as long as the internal 
> implementation is preserved, bootstrapping with minimal dependencies.
> b) doing so tends to have a positive impact on codebase
> c) having someone experienced with OpenPGP do it, the resulting API may 
> even make some sense...
>
> So while I'm not at all eager to gain a Rust dependency and there'll be 
> somewhat more (not less) code to maintain, but as per the plan above I 
> think this sounds like a net positive for us. Always assuming somebody 
> is willing to do the work that is.

Great.  I'll give it a try and will likely come back with questions in
the process.

>> Do you have questions or remarks?  I'm happy to get the discussion
>> rolling :)
>
> As a someone who's been living under a crate when it comes to Rust... I 
> can see from the Sequoia docs that FFI is used for calling from other 
> languages and there's a separate C library for this. How's the API 
> coverage (just curious) and more importantly, stability? And if this is 
> a shared library then the question extends to ABI stability as well.

That is a good question.  When we started with Sequoia, we imagined
having a general-purpose C API.  We started to build one, driven by the
needs of our companies C library.  However, it became increasingly clear
that a) this is a lot of work, b) the general-purpose interface was
quite brittle, and most importantly c) it resulted in a lot of code on
the consumer side that would have been much more concise and robust if
it would have been written in Rust using the native interface.

Hence, our new strategy is to create point solutions in Rust that expose
the exact handful of functions that a project requires.  We have done
that for our companies library, and it has greatly improved the quality
of the code.  You can see examples of such point solutions here:

https://gitlab.com/teythoon/sequoia-nlnet-encrypt-confirmation
https://gitlab.com/wiktor/anonaddy-sequoia

For RPM, this point solution would implement the public functions from
rpmio/{rpmpgp,rpmkeyring,digest}*.  This API is internal to RPM, so any
changes to the C side would also be made to the Rust side.  Hopefully,
the interface will be small and changes seldom.

Sequoia's API is fixed during the 1.x release cycle.  We released 1.0 in
December 2020 after spending a year writing documentation for the
interface and honing it.  We're happy to report that no major issues
have popped up so far.  We're collecting interface warts in our bug
tracker, but even if we eventually go to 2.0 to be able to fix the
issues (thus breaking the API), I think most of the downstream code will
continue to work as-is, at worst requiring small fixes.

2.0 API bugs: https://gitlab.com/sequoia-pgp/sequoia/-/milestones/3

Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


Re: [Rpm-maint] Porting RPM to Sequoia PGP

2021-10-25 Thread Justus Winter
Neal Gompa  writes:

> What about DNF? The DNF package manager also uses gpgme right now, and
> one of the larger problems we have right now is that we have no
> unified keyring between DNF and RPM, because RPM doesn't have an API
> to manipulate it. If we were to adopt Sequoia as an optional
> alternative, then ideally DNF should *also* get the ability to use it,
> mostly because I'm fairly certain that the keyring storage across PGP
> implementations are incompatible. Alternatively, adding APIs to RPM so
> that DNF can consume them through the RPM interface would work too
> (and I'd probably prefer that, honestly).

Interesting.  I hadn't considered DNF.  Re-using the same OpenPGP
implementation seems reasonable, what kind of interface would be
required?

(Having said that, a keyring is a concatenation of OpenPGP certificates,
and I don't expect problems with the storage aspect.  However, different
implementations may canonicalize the certificates differently, and/or
perform signature verification slightly differently.)

> I'm personally not a fan of the anti-ergonomic stance of Rust and
> several members of the Rust core community seriously aggravate me
> given their dislike/hatred of Linux distro folks, but I can't deny
> that we're in a wave of "oxidize all the things" right now, and
> Sequoia is one of the best PGP implementations out there.

Yeah, I can relate to that.  But, I think that this will get better over
time.

Thanks,
Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint


[Rpm-maint] Porting RPM to Sequoia PGP

2021-10-21 Thread Justus Winter
Hello,

I'd like to propose to replace RPM's built-in PGP support with Sequoia.
Sequoia is an OpenPGP implementation written in Rust.  We have released
Sequoia 1.5 earlier this week, which is the first version released under
the LGPL2+.

Our low-level crate, sequoia-openpgp, features an unopinionated
interface that offers mechanisms without imposing policy upon the
downstream user.  Despite its low-level nature, our experience is that
integration code is typically smaller than code interfacing with
e.g. GPGME, which is supposed to be a high-level interface.

I have dug around in the bug tracker, and I think I have identified some
areas of concern with respect to RPM's OpenPGP support: Correctness,
portability, and license compatibility.

First, I think replacing RPM's point solution with a general purpose
implementation will improve correctness.  Robust signature verification
requires canonicalization of the issuing certificate, which is tricky
[0], [1], [2].  Further, RPM shouldn't be burdened with maintaining
their own point solution, which will require constant maintenance to
keep up with evolving standards and algorithms.

0: https://access.redhat.com/security/cve/cve-2021-3521
1: https://github.com/rpm-software-management/rpm/issues/1598
2: https://github.com/rpm-software-management/rpm/issues/1306

Second, Rust has been criticized for being not too portable [3].  While
there is some truth to that, at least today, there is ongoing work to
add a GCC backend to the Rust compiler [4], and to write a Rust frontend
for GCC [5].  The former work will likely address the issue short-term
to mid-term, while the latter will imho be a mid-term to long-term
solution.  In any case, the situation is only going to improve over
time.

3: 
https://github.com/rpm-software-management/rpm/issues/1306#issuecomment-751311089
4: https://github.com/rust-lang/rustc_codegen_gcc
5: https://github.com/Rust-GCC/gccrs

For RPM, I'd suggest to keep the current implementation as a fallback
for platforms that cannot or prefer not to use a Rust-based PGP
implementation.

Finally, regarding the license incompatibility [6], we're happy to
report that we have switched to the LGPL2+ fixing this issue.

6: 
https://github.com/rpm-software-management/rpm/issues/1306#issuecomment-751381721

I have also skimmed RPM's code.  From what I can tell, the relevant code
is in rpmio/{rpmpgp,rpmkeyring,digest}*, the public API uses the "rpm"
prefix, "pgp"-prefixed functions and types are hardly used outside of
the PGP implementation.

Looking at the task for roughly an hour or so (so, take it with a grain
of salt...), my strategy would be to decouple the current implementation
by clearly defining the public API, then provide a drop-in replacement
for that API that can be enabled at compile-time.

Does that sound reasonable?  Do you have questions or remarks?  I'm
happy to get the discussion rolling :)

Justus


signature.asc
Description: PGP signature
___
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint