-
Notifications
You must be signed in to change notification settings - Fork 5
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
Create encrypting/signing integration test for example/key_from_raw_data.cpp #58
Comments
Here is a proposal for using blinded
What follows frames a smoke test that includes three subkeys, For readers following this thread desiring to better understand, examine https://wiki.debian.org/Subkeys and https://davesteele.github.io/gpg/2014/09/20/anatomy-of-a-gpg-key/. |
The proposed test below has four signature packets.
Test vector keys:
Convention for naming important variables inside the sally_0E68D9A4-test.cpp.
|
Starting to code from the spec above. |
If you are interested, we already have a set of integration tests here (without test vectors though): https://github.com/summitto/pgp-key-generation/blob/master/tests/integration_test.py |
The following GNUv3 code builds off key_from_raw_data.cpp to perform a smoke test of the depth and breadth of pgp-packet-library for generating realistic set of nine PGP packets that aggregate into a PGP certificate with a master key and three associated subkeys. This integration smoke test will exercise four different signatures. The supplied code compiles fine and executes as expected. However, if lines 204 through 225 are uncommented for Packet#6, the code will not compile. This is a breadth issue. Also having depth issues commented out sections of Packet #3, examine lines commented out from 166 through 181.
|
The % cat sally_0E68D9A4-allkeys.asc.master
% cat sally_0E68D9A4-allkeys.asc.master | sed 's/-----BEGIN PGP PRIVATE KEY BLOCK-----//' | sed 's/-----END PGP PRIVATE KEY BLOCK-----//' | sed '/^$/d' | sed '/^=.*$/d' | tr -d '\n' | bx base64-decode | bx base16-encode
% cat 247356FEC6DF10DBB962C8D96AF0BBCC0E68D9A4.rev.master
% echo iHgEIBYKACAWIQQkc1b+xt8Q27liyNlq8LvMDmjZpAUCXg6vuwIdAAAKCRBq8LvMDmjZpDVqAP9QSQnSHzJXt+ub4WYW2kkxQ61uOCrUAT88YF5PxOiqeAEA0woZJlwWtaOCSVZ/Sf3pJCQGAXmxL+f1xum54TWvDgo= | bx base64-decode | bx base16-encode
|
The parsing script is an ugly duckling not meant for distribution but here are its results for the nine packet certificate. % ./parse.csh sally_0E68D9A4-allkeys.asc.master
|
Worth noting the signature types for the smoke test above are of types described at https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-09#section-5.2.1:
It is worth noting that from an analysis of the g10/keygen.c: write_keybinding() function reveals that an authentication subkey really requires two signatures to be made.
The make_backsig then performs a make_keysig_packet(...) call requiring a 0x19 signature. The way signatures are created for 0x13, 0x18, 0x19, and 0x20 are different according to https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-09#section-5.2.4. How those signatures are created in the RFC appear to lack sufficient detail. From https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-09#appendix-A.2, the second packet
|
Added a post at https://www.reddit.com/r/pgp/comments/hb6jxp/analysis_of_a_raw_pgp_signature_packet_0x13/ for how to compute the R&S signature components for packet #3 above. I'm confident the ./sign program used works properly because it produced identical test vector results to https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-09#appendix-A.2. % echo 4f70656e504750040016080006050255f95f9504ff0000000c | bx sha256
% ./sign -k 1a8b1ff05ded48e18bf50166c664ab023ea70003d78d9e41f5758a91d850f8d2 -m f6220a3f757814f4c2176ffbb68b00249cd4ccdc059c4b34ad871f30b1740280
|
https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=g10/sign.c;h=6e9f68ec041b8adf3c197a70aa4bf93cad57b5e3;hb=refs/heads/STABLE-BRANCH-2-2#l1569 is relevant to https://www.rfc-editor.org/rfc/rfc2440.html#section-5.2.4 "Computing Signatures" After examining https://docs.sequoia-pgp.org/src/sequoia_openpgp/serialize.rs.htm, the following concerning certificate building also looks promising:
The main issue is the references above is they were not designed for creating deterministic/recoverable PGP certificates, neither public nor private. |
Another established ed25519 0x13 -> Positive certification test is located at https://github.com/romanz/trezor-agent/blob/master/libagent/gpg/tests/77E9D99CBB9B4C961370BAF9AD4DD89F17138874.gpg. The following code is relevant: |
Thanks for the research @skaht, are you happy with the preliminary results? May I ask where the |
Both parse.csh and sign.cpp are exploratory code I wrote to provide feedback when trying to understand RFC 4880 and using gpg as the reference PGP implementation. https://dump.sequoia-pgp.org/ will be more useful than parse.csh. The sign.cpp code uses uses libsodium's crypto_sign_detached() function. Was really hoping to utilize the pgp-packet-library package to deterministically create PGP certificates, but this package does not yet have enough implemented depth and breadth as the use-case driven code up top demonstrates. I'm on a tight schedule and will continue to press forward to develop a less functional (easier to audit) but immediately practicable PGP certificate synthesis package to mitigate schedule risks. |
Any estimates as too when subkey signature support for packets no. 5, no. 7, no. 9 mentioned as inline code comments in line 83 through 97? |
Hi @skaht, unfortunately we can't give any estimates at the moment. We'll notify you when we continue with the topic! |
Figured how to use gpg libraries to compute keygrips directly from both ed25519 and cv25519 public key s expressions. Moving on to computing deterministic certificates using gpg libraries. |
GPGME is nothing more than a native "C/C++/Python" wrapper around gpg. This became obvious when I dug down through the GPGME Library source code used to synthesize keys corresponding to my top-level ikc.c source code I wrote that linked to the GPGME Library.
|
Okay guys there is now working C++ code (not pgp-packet-library) to synthesize deterministic OpenPGP master, sign, encr, auth keys and associated certs/keyblocks. The major issue I have is there no dependable means I've identified to determine the two byte field delimiters separating secret keys and signature values from other fields. Other than that, I'm 97% of the way there... Not apparent how sections of https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10#section-5.2.4 and https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10#section-5.5.3 are useful concerning determining the delimiter rules. Delimiters tend to be 0x0100, 0x00ff, 0x00fe, 0x00fc, 0x00fb. Just need to understand the method to the madness... If delimiters are replaced with those created by gpg, the same certificates can be synthesized. If the delimiters are not replaced, it appears gpg can still import the externally generated certs and functions. |
C++ constructor overloading can be applied for synthesizing Primary and Secondary secret keys and different signature types such 0x13 (primary cert), 0x18 (subkey certs), 0x19 (sign subkey backsignature), 0x20 (primary revocation cert), contextually sensitive keychain 0x28 (subkey revocation certs). GPG has no batch capability for generating subkey revocation certs in advance, requires being in the interactive mode. |
It is interesting to contrast the output results of June 12th, 2020 results above to: % cat sally_0E68D9A4_ikop.asc | gpg --list-packets --verbose
The net result is not all fields are shown with the gpg command, for example:
|
Not clear if gnupg-2.2.*/doc/DETAILS is useful for resolving the the details for |
Turned out that the 2-byte signature headers are nothing more than libgcrypt artifacts that store the bits required to contain the R and S signatures. This detail was not documented in RFC 4880bis10. |
No description provided.
The text was updated successfully, but these errors were encountered: