[PATCH 4/8] g10: add new cleartext_secret_key_to_openpgp() function
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Sat May 21 01:41:07 CEST 2016
* g10/export.c (cleartext_secret_key_to_openpgp): new function,
filling in the secret key parameters of a PKT_public_key object from
a corresponding cleartext S-expression.
---
g10/export.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 144 insertions(+)
diff --git a/g10/export.c b/g10/export.c
index d931507..ffa7240 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -476,6 +476,150 @@ canon_pk_algo (enum gcry_pk_algos algo)
}
}
+/* take a cleartext dump of a secret key in PK and change the
+ parameter array in PK to include the secret parameters. */
+static gpg_error_t
+cleartext_secret_key_to_openpgp (gcry_sexp_t s_key, PKT_public_key *pk)
+{
+ gpg_error_t err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ gcry_sexp_t top_list;
+ gcry_sexp_t key = NULL;
+ char *key_type = NULL;
+ enum gcry_pk_algos pk_algo;
+ struct seckey_info *ski;
+ int idx, sec_start;
+ gcry_mpi_t pub_params[10] = { NULL };
+
+ /* we look for a private-key, then the first element in it tells us
+ the type */
+ top_list = gcry_sexp_find_token (s_key, "private-key", 0);
+ if (!top_list)
+ goto bad_seckey;
+ if (gcry_sexp_length(top_list) != 2)
+ goto bad_seckey;
+ key = gcry_sexp_nth (top_list, 1);
+ if (!key)
+ goto bad_seckey;
+ key_type = gcry_sexp_nth_string(key, 0);
+ pk_algo = gcry_pk_map_name (key_type);
+
+ log_assert(pk->seckey_info == NULL);
+
+ pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
+ if (!ski)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ switch (canon_pk_algo (pk_algo))
+ {
+ case GCRY_PK_RSA:
+ if (!is_RSA (pk->pubkey_algo))
+ goto bad_pubkey_algo;
+ err = gcry_sexp_extract_param (key, NULL, "ne",
+ &pub_params[0],
+ &pub_params[1],
+ NULL);
+ for (idx=0; idx < 2 && !err; idx++)
+ if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+ if (!err)
+ err = gcry_sexp_extract_param (key, NULL, "dpqu",
+ &pk->pkey[2],
+ &pk->pkey[3],
+ &pk->pkey[4],
+ &pk->pkey[5],
+ NULL);
+ if (!err)
+ for (idx = 2; idx < 6; idx++)
+ ski->csum += checksum_mpi (pk->pkey[idx]);
+ break;
+
+ case GCRY_PK_DSA:
+ if (!is_DSA (pk->pubkey_algo))
+ goto bad_pubkey_algo;
+ err = gcry_sexp_extract_param (key, NULL, "pqgy",
+ &pub_params[0],
+ &pub_params[1],
+ &pub_params[2],
+ &pub_params[3],
+ NULL);
+ for (idx=0; idx < 4 && !err; idx++)
+ if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+ if (!err)
+ err = gcry_sexp_extract_param (key, NULL, "x",
+ &pk->pkey[4],
+ NULL);
+ if (!err)
+ ski->csum += checksum_mpi (pk->pkey[4]);
+ break;
+
+ case GCRY_PK_ELG:
+ if (!is_ELGAMAL (pk->pubkey_algo))
+ goto bad_pubkey_algo;
+ err = gcry_sexp_extract_param (key, NULL, "pgy",
+ &pub_params[0],
+ &pub_params[1],
+ &pub_params[2],
+ NULL);
+ for (idx=0; idx < 3 && !err; idx++)
+ if (gcry_mpi_cmp(pk->pkey[idx], pub_params[idx]))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+ if (!err)
+ err = gcry_sexp_extract_param (key, NULL, "x",
+ &pk->pkey[3],
+ NULL);
+ if (!err)
+ ski->csum += checksum_mpi (pk->pkey[3]);
+ break;
+
+ case GCRY_PK_ECC:
+ err = match_curve_skey_pk (key, pk);
+ if (err)
+ goto leave;
+ if (!err)
+ err = gcry_sexp_extract_param (key, NULL, "q",
+ &pub_params[0],
+ NULL);
+ if (!err && (gcry_mpi_cmp(pk->pkey[1], pub_params[0])))
+ err = gpg_error (GPG_ERR_BAD_PUBKEY);
+
+ sec_start = 2;
+ if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+ sec_start += 1;
+ if (!err)
+ err = gcry_sexp_extract_param (key, NULL, "d",
+ &pk->pkey[sec_start],
+ NULL);
+
+ if (!err)
+ ski->csum += checksum_mpi (pk->pkey[sec_start]);
+ break;
+
+ default:
+ pk->seckey_info = NULL;
+ free (ski);
+ err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ }
+ leave:
+ gcry_sexp_release (top_list);
+ gcry_sexp_release (key);
+ gcry_free (key_type);
+
+ for (idx=0; idx < DIM(pub_params); idx++)
+ gcry_mpi_release (pub_params[idx]);
+ return err;
+
+ bad_pubkey_algo:
+ err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+ goto leave;
+
+ bad_seckey:
+ err = gpg_error (GPG_ERR_BAD_SECKEY);
+ goto leave;
+}
/* Use the key transfer format given in S_PGP to create the secinfo
structure in PK and change the parameter array in PK to include the
--
2.8.1
More information about the Gnupg-devel
mailing list