diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/openpgp-misc.c | 44 | ||||
-rw-r--r-- | common/openpgpdefs.h | 1 |
2 files changed, 45 insertions, 0 deletions
diff --git a/common/openpgp-misc.c b/common/openpgp-misc.c index 178a4938e..4d057e5ed 100644 --- a/common/openpgp-misc.c +++ b/common/openpgp-misc.c @@ -50,3 +50,47 @@ openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve, else return gcry_mpi_set_opaque_copy (NULL, buf+1, 448); } + + +/* + * Fix up public key for OpenPGP adding the prefix. + */ +gpg_error_t +openpgp_fixup_pubkey_448 (int algo, gcry_mpi_t *p_pubkey) +{ + gcry_mpi_t pubkey_mpi; + gcry_mpi_t a; + unsigned char *p; + const unsigned char *p_key; + unsigned int nbits; + unsigned int len; + + pubkey_mpi = *p_pubkey; + *p_pubkey = NULL; + p_key = gcry_mpi_get_opaque (pubkey_mpi, &nbits); + len = (nbits+7)/8; + if ((algo == PUBKEY_ALGO_ECDH && len != 56) + || (algo == PUBKEY_ALGO_EDDSA && len != 57) + || (algo != PUBKEY_ALGO_ECDH && algo != PUBKEY_ALGO_EDDSA)) + { + gcry_mpi_release (pubkey_mpi); + return gpg_error (GPG_ERR_BAD_PUBKEY); + } + + p = xtrymalloc (1 + len); + if (!p) + { + gcry_mpi_release (pubkey_mpi); + return gpg_error_from_syserror (); + } + + p[0] = 0x40; + memcpy (p+1, p_key, len); + + a = gcry_mpi_set_opaque (NULL, p, 0); + gcry_mpi_set_flag (a, GCRYMPI_FLAG_USER2); + *p_pubkey = a; + gcry_mpi_release (pubkey_mpi); + + return 0; +} diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 2ed4a6cd0..01a0e0edf 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -242,5 +242,6 @@ enum gcry_pk_algos map_openpgp_pk_to_gcry (pubkey_algo_t algo); /*-- openpgp-misc.c --*/ gcry_mpi_t openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve, gcry_mpi_t key); +gpg_error_t openpgp_fixup_pubkey_448 (int algo, gcry_mpi_t *p_pubkey); #endif /*GNUPG_COMMON_OPENPGPDEFS_H*/ |