diff options
| author | Werner Koch <[email protected]> | 2025-11-15 16:45:12 +0000 |
|---|---|---|
| committer | Werner Koch <[email protected]> | 2025-11-15 16:45:12 +0000 |
| commit | 5d855f76c8af280f0a2b01d64283a9efa0f5d795 (patch) | |
| tree | 30f16f1053e6a37fed3aa14540c620aa502c363f | |
| parent | gpg: Refactor an import function for better readability. (diff) | |
| download | gnupg-5d855f76c8af280f0a2b01d64283a9efa0f5d795.tar.gz gnupg-5d855f76c8af280f0a2b01d64283a9efa0f5d795.zip | |
gpg: Change the mode1003 format for composite keys.
* g10/export.c (secret_key_to_mode1003): Put both parts into one
container.
* g10/parse-packet.c (parse_key): Revert to old version.
--
Let's have a proper s-expression for composite keys.
Updates-commit: e5473262e88473a101241e7b4860882ebeb1ed97
| -rw-r--r-- | doc/DETAILS | 19 | ||||
| -rw-r--r-- | g10/export.c | 12 | ||||
| -rw-r--r-- | g10/parse-packet.c | 12 |
3 files changed, 18 insertions, 25 deletions
diff --git a/doc/DETAILS b/doc/DETAILS index cd6cf7314..588cb02c7 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -1576,15 +1576,16 @@ CREATE TABLE signatures ( - The serial number. Regardless of what the length octet indicates no more than 16 octets are stored. - 3 :: The internal representation of a private key: For v4 keys we - first write 4 octets big endian length of the following - s-expression(s) with the protected or unprotected private key; - for v5 keys this is not necessarily because that length - header is always there. The actual data are N octets of - s-expression. Any protection (including the real S2K) is - part of that data. For a dual key the second s-expression is - concatenated to the first; thus two complete s-expressions - are used. Note that the public key parameters are - repeated in the s-expression. + first write 4 octets big endian length of the following + s-expression(s) with the protected or unprotected private key; for + v5 keys this is not necessarily because that length header is + always there. The actual data are N octets of s-expression. Any + protection (including the real S2K) is part of that data. For a + composite key (aka PQ/T hybrid) the two s-expressions are combined + in a new s-expression using this layout: + (composite-key(<ecckey>)(<kyberkey>)). + Note that the respective public key parameters are repeated in the + s-expressions. Note that gpg internally stores the GNU S2K Extension Number as an S2K Specifier with an offset of 1000. diff --git a/g10/export.c b/g10/export.c index 7c7869fb8..fc2625684 100644 --- a/g10/export.c +++ b/g10/export.c @@ -837,6 +837,8 @@ secret_key_to_mode1003 (gcry_sexp_t s_key, PKT_public_key *pk, int is_part2) goto leave; if (is_part2) /* Append secret s-expr to the existing one. */ { + char const prefix[] = "(13:composite-key"; + unsigned int prefixlen = strlen (prefix); const unsigned char *oldbuf; unsigned int oldbuflen; unsigned char *newbuf; @@ -845,16 +847,18 @@ secret_key_to_mode1003 (gcry_sexp_t s_key, PKT_public_key *pk, int is_part2) gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE)); oldbuf = gcry_mpi_get_opaque (pk->pkey[npkey], &oldbuflen); oldbuflen = (oldbuflen +7)/8; /* Fixup bits to bytes */ - newbuf = xtrymalloc_secure (oldbuflen + buflen); + newbuf = xtrymalloc_secure (prefixlen + oldbuflen + buflen + 1); if (!newbuf) { err = gpg_error_from_syserror (); goto leave; } - memcpy (newbuf, oldbuf, oldbuflen); - memcpy (newbuf+oldbuflen, buf, buflen); + memcpy (newbuf, prefix, prefixlen); + memcpy (newbuf+prefixlen, oldbuf, oldbuflen); + memcpy (newbuf+prefixlen+oldbuflen, buf, buflen); + newbuf[prefixlen+oldbuflen+buflen] = ')'; /* close prefix */ buf = newbuf; - buflen = oldbuflen + buflen; + buflen = prefixlen + oldbuflen + buflen + 1; } /* Note that BUF is consumed by gcry_mpi_set_opaque. */ pk->pkey[npkey] = gcry_mpi_set_opaque (NULL, buf, buflen*8); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index aac3a988c..22db04291 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -3079,22 +3079,10 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, if (mpi_print_mode) { char *tmpsxp = canon_sexp_to_string (tmpp, pktlen); - size_t len1 = gcry_sexp_canon_len (tmpp, pktlen, NULL, NULL); - const char *tp = tmpp; es_fprintf (listfp, "\tskey[%d]: %s\n", npkey, tmpsxp? trim_trailing_spaces (tmpsxp) /* */: "[invalid S-expression]"); - if (len1 && len1 < pktlen - && tp[len1] == '(' && tp[pktlen-1] == ')' ) - { - /* Second s-expression from a dual key. */ - xfree (tmpsxp); - tmpsxp = canon_sexp_to_string (tp+len1, pktlen-len1); - es_fprintf (listfp, "\t part-2: %s\n", - tmpsxp? trim_trailing_spaces (tmpsxp) - /* */: "[invalid S-expression]"); - } xfree (tmpsxp); } else |
