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

Clarify requirement 19: ASCII vs. Binary signature #797

Open
tschmidtb51 opened this issue Oct 17, 2024 · 8 comments · May be fixed by #839
Open

Clarify requirement 19: ASCII vs. Binary signature #797

tschmidtb51 opened this issue Oct 17, 2024 · 8 comments · May be fixed by #839
Assignees
Labels
csaf 2.1 csaf 2.1 work editor-revision already worked on in the editor revision editorial mostly nits and consistency

Comments

@tschmidtb51
Copy link
Contributor

We should clarify whether we expect signatures to be in ASCII or binary format or both should be accepted. Therefore, we need to figure out whether it make a difference for implementers.

@tschmidtb51 tschmidtb51 added the investigation needed anything that needs some investigation label Oct 17, 2024
@bernhardreiter
Copy link
Contributor

The question should be evaluated for public key files as well. Relevant languages to check would include Java, Rust and Go (according to @tschmidtb51).

@bernhardreiter
Copy link
Contributor

bernhardreiter commented Oct 28, 2024

Summary

The expected advantages and drawbacks are small, of allowing both armored and binary file format variants of public keys and detached signatures for the upcoming CSAF 2.1 format.

Examined implementations can deal with variants without hassle.

@bernhardreiter has a tendency to go with ASCII armored files only. This is based on the general rules of thumb to be consistent and reduce variants as a precaution against complexity.

Details

In general: Any additional variant will make a standard a little bit harder to understand, write and read. And several little variants will easily multiply the difficulty. So personally I'd rather allow one variant, less unless it is really having a significant advantage. So the burden of proof would be on the proposed enhancement from my perspective.

little advantages for variants

There are two possible advantages for allowing both file formats for signatures and public keys:

  • An implementation would not need to transform (or recreate) the files if it got them already in one of two formats.
  • The binary files could save a bit of space as they are more compact.

CSAF 2.0 documents are in JSON, which is quite verbose. Compared to those documents, the size increase by using ASCII armored signatures and public key file is just a little. So if one format is to be selected, ASCII armored seems to be the better fit with in the CSAF 2.0 family of files.

little drawbacks for variants

For implementations that find and read CSAF documents, the potential drawback is that they may need to transform the files before processing. This is not the case for a number of tested programming languages and OpenPGP v4 crypto libraries.

The main drawback is that analysing a CSAF (trusted) provider's files in the subcase that the signatures do not validate as they should is getting slightly more complicated. One example: binary pubkeys and detached signatures are less easily identified as such, the posix file will say data on a detached signature, but work on a binary pubkey.

Examining software implementation difficulties

In order to find out how implementations behave this little investigation's focus is on the parsing side of the files. Reading happens more often than writing (and I lack data about what files are already existing on the potential CSAF Trusted Provider sides).

The next steps are to check which preferred methods for reading pubkeys and checking signatures are for the different languages.

selection criteria for modules

  • GnuPG probably is the reference implementation of OpenPGP RFC 4880. (Note I am part of the GnuPG-Team).
  • For other languages low level libraries with OpenPGP RFC 4880 (aka OpenPGP v4) are preferred and those that are mostly implemented in the language itself. Those modules seem to be the best example of implementation difficulties as there will always be a possibility to write a function to deal with both armor and binary data on a higher level, but most implementors will start with a low level library that has little dependencies, if they can.

GnuPG

And elder version of gpg (GnuPG v2.2.40) does not make a difference when checking a detached signature as ascii or binary format. Importing behaves the same.

(Using GnuPG via the library GPGME is a common method to interact with GnuPG, which is a widespread OpenPGP implementation. It is used by many other programming languages. Expectation: variants are easy to implement)

Java

Bouncycastle accepts both variants with automatic detection, so they are easy to implement.

Details

A brief search in the documentation and example code did not find a direct hint.
Thus an implementation example could give more insights:

Testing official example code:

All four variants work with the example verifier:

alias DetachedSignatureProcessor='java -cp /usr/share/maven-repo/org/bouncycastle/bcpg/debian/bcpg-debian.jar org.bouncycastle.openpgp.examples.DetachedSignatureProcessor'

DetachedSignatureProcessor -v hello.txt hello.txt.sig bernhard_pubkey.gpg
   signature verified.
DetachedSignatureProcessor -v hello.txt hello.txt.asc bernhard_pubkey.gpg
   signature verified.
DetachedSignatureProcessor -v hello.txt hello.txt.sig bernhard_gpgkey.asc
   signature verified.
DetachedSignatureProcessor -v hello.txt hello.txt.asc bernhard_gpgkey.asc
   signature verified.

The code has a variant for "compressed" OpenPGP objects, but not for armored or binary ones.

Rust

A brief search in the documentation and example code did not find a direct hint.

The rpgp implementation accepts both variants with automatic detection, so they are easy to implement.

See code example below (by @bernhard-herzog).

Go

https://github.com/ProtonMail/gopenpgp is a common choice if an OpenPGP/LibrePGP library in Go is wanted.
It is a fork from the Go standard library module, which is deprecated now.

Also used by https://github.com/csaf-poc/csaf_distribution.

Ease of implementation

Doing a documentation level research:
https://pkg.go.dev/github.com/ProtonMail/gopenpgp/v3@v3.0.0-beta.2-proton/crypto#PGPVerify

especially VerifyDetached() offers the option to set encoding to Auto which detects unarmored or armored detached signaturs.

https://pkg.go.dev/github.com/ProtonMail/gopenpgp/v3@v3.0.0-beta.2-proton/crypto#NewKey
also accepts both types.

So if the general functions are used to begin with, there is no extra
code when reading pubkeys or signatures in both formats
(expected for go).

@sthagen
Copy link
Contributor

sthagen commented Oct 29, 2024

"requirement 19" is a to me unclear reference. Can we rename the ticket or name the CSAF v2.0 or v2.1 specific target? Thanks.

@tschmidtb51
Copy link
Contributor Author

tschmidtb51 commented Oct 29, 2024

"requirement 19" is a to me unclear reference. Can we rename the ticket or name the CSAF v2.0 or v2.1 specific target? Thanks.

It is kind of independent of the version - the requirement is still the same. But I guess, we will focus first on CSAF 2.1

@tschmidtb51 tschmidtb51 added the csaf 2.1 csaf 2.1 work label Oct 29, 2024
@sthagen
Copy link
Contributor

sthagen commented Oct 30, 2024

I think I was not clear, sorry. My question is, what the relevance of "requirement 19" is, where I can find that ... or if this is some "catalog of requirements" not related to our specification but to some contract or suggested tool. Thanks.

@tschmidtb51
Copy link
Contributor Author

tschmidtb51 commented Oct 30, 2024

I think I was not clear, sorry. My question is, what the relevance of "requirement 19" is, where I can find that ... or if this is some "catalog of requirements" not related to our specification but to some contract or suggested tool. Thanks.

I'm sorry - my bad: The issue refers to the requirement 19 from section 7.1.19.

@bernhard-herzog
Copy link

The rust library rpgp supports both binary and ASCII armored keys and detached signatures. Reading a key
from a file, with the library automatically detecting whether it's ascii armored or not (assumes there's only one key in the file):

let key_file = fs::File::open(pub_key_filename).unwrap();
let (mut iter_key, _) = SignedPublicKey::from_reader_many(key_file).unwrap();
let public_key = iter_key.next().unwrap().unwrap();

For signatures the same can be done with the StandaloneSignature type.

@tschmidtb51 tschmidtb51 removed the investigation needed anything that needs some investigation label Nov 18, 2024
@tschmidtb51
Copy link
Contributor Author

For reasons above (no big advantage, less variants, stick with the existing CSAF 2.0 interpretation), I suggest to clearly state the use of ASCII armored files.

tschmidtb51 added a commit to tschmidtb51/csaf that referenced this issue Nov 18, 2024
- resolves oasis-tcs#797
- add explicit statements about OpenPGP signatures and key files being ASCII armored
@tschmidtb51 tschmidtb51 added editor-revision already worked on in the editor revision editorial mostly nits and consistency labels Nov 18, 2024
tschmidtb51 added a commit to tschmidtb51/csaf that referenced this issue Dec 2, 2024
- resolves oasis-tcs#797
- add explicit statements about OpenPGP signatures and key files being ASCII armored
@tschmidtb51 tschmidtb51 linked a pull request Dec 2, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
csaf 2.1 csaf 2.1 work editor-revision already worked on in the editor revision editorial mostly nits and consistency
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants