aboutsummaryrefslogtreecommitdiffstats
path: root/g10/build-packet.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2022-12-02 09:03:36 +0000
committerWerner Koch <[email protected]>2022-12-02 09:09:58 +0000
commit1a85ee9a431bd2243e0ad79ce5eefa78e274a491 (patch)
tree9b2e33d41d5c373110efd33e00aafba723ca2308 /g10/build-packet.c
parentgpg: Remove a mostly duplicated function. (diff)
downloadgnupg-1a85ee9a431bd2243e0ad79ce5eefa78e274a491.tar.gz
gnupg-1a85ee9a431bd2243e0ad79ce5eefa78e274a491.zip
gpg: New export option "mode1003".
* agent/command.c (cmd_export_key): Add option --mode1003. (command_has_option): Ditto. * g10/build-packet.c (do_key): Implement mode 1003. * g10/parse-packet.c (parse_key): Ditto. * g10/options.h (EXPORT_MODE1003): New.o * g10/call-agent.c (agent_export_key): Add arg mode1003. * g10/export.c (parse_export_options): Add "mode1003" (secret_key_to_mode1003): New. (receive_seckey_from_agent): Add arg mode1003. (do_export_one_keyblock): Pass option down. -- This option allows to export a secret key in GnuPG's native format. Thus no re-encryption is required and further the public key parameters are also authenticated if a protection passphrase has been used. Note that --import is not yet able to handle this new mode. Although old version of GnuPG will bail out with "invalid packet" if a mode1003 exported secret key is seen.
Diffstat (limited to 'g10/build-packet.c')
-rw-r--r--g10/build-packet.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/g10/build-packet.c b/g10/build-packet.c
index cc953557d..f33d156b3 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -674,7 +674,8 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
count += 8; /* Salt. */
if (ski->s2k.mode == 3)
count++; /* S2K.COUNT */
- if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
+ if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002
+ && ski->s2k.mode != 1003)
count += ski->ivlen;
iobuf_put (a, count);
@@ -704,8 +705,9 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
if (ski->s2k.mode == 3)
iobuf_put (a, ski->s2k.count);
- /* For our special modes 1001, 1002 we do not need an IV. */
- if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
+ /* For our special modes 1001..1003 we do not need an IV. */
+ if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002
+ && ski->s2k.mode != 1003)
iobuf_write (a, ski->iv, ski->ivlen);
}
@@ -733,6 +735,22 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
/* The serial number gets stored in the IV field. */
iobuf_write (a, ski->iv, ski->ivlen);
}
+ else if (ski->s2k.mode == 1003)
+ {
+ /* GnuPG extension - Store raw s-expression. */
+ byte *p;
+ unsigned int ndatabits;
+
+ log_assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE));
+
+ p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits);
+ /* For v5 keys we first write the number of octets of the
+ * following key material. */
+ if (is_v5)
+ write_32 (a, p? (ndatabits+7)/8 : 0);
+ if (p)
+ iobuf_write (a, p, (ndatabits+7)/8 );
+ }
else if (ski->is_protected)
{
/* The secret key is protected - write it out as it is. */