From c4b6b35bfa98e478f1d13f4ce3e664771f2604c2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sun, 30 Aug 2015 19:04:44 +0200 Subject: [PATCH] Add gpgme_pubkey_algo_string * src/gpgme.h.in (GPGME_PK_EDDSA): New. (gpgme_pubkey_algo_string): New. * src/conversion.c (_gpgme_map_pk_algo): Add new algo. * src/gpgme.c (gpgme_pubkey_algo_string): New. (gpgme_pubkey_algo_name): Reformat. Signed-off-by: Werner Koch --- NEWS | 7 ++++ doc/gpgme.texi | 21 ++++++++--- src/conversion.c | 1 + src/data-mem.c | 3 +- src/gpgme.c | 89 +++++++++++++++++++++++++++++++---------------- src/gpgme.def | 2 ++ src/gpgme.h.in | 10 ++++-- src/libgpgme.vers | 2 ++ 8 files changed, 98 insertions(+), 37 deletions(-) diff --git a/NEWS b/NEWS index 7bf140b6..85c084ff 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,13 @@ Noteworthy changes in version 1.6.1 (unreleased) [C25/A14/R_] ------------------------------------------------ + * New function to format a GnuPG style public key algorithm string. + + * Interface changes relative to the 1.6.0 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgme_pubkey_algo_string NEW. + GPGME_PK_EDDSA NEW. + Noteworthy changes in version 1.6.0 (2015-08-26) [C25/A14/R0] ------------------------------------------------ diff --git a/doc/gpgme.texi b/doc/gpgme.texi index c02a30f3..a764ce42 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -1161,6 +1161,9 @@ Algorithm as defined by FIPS 186-2 and RFC-6637. This value indicates ECDH, the Eliptic Curve Diffie-Hellmann encryption algorithm as defined by RFC-6637. +@item GPGME_PK_EDDSA +This value indicates the EdDSA algorithm. + @end table @end deftp @@ -1174,6 +1177,14 @@ If @var{algo} is not a valid public key algorithm, @code{NULL} is returned. @end deftypefun +@deftypefun {char *} gpgme_pubkey_algo_string (@w{gpgme_subkey_t @var{key}}) +The function @code{gpgme_pubkey_algo_string} is a convenience function +to build and return an algorithm string in the same way GnuPG does +(e.g. ``rsa2048'' or ``ed25519''). The caller must free the result +using @code{gpgme_free}. On error (e.g. invalid argument or memory +exhausted), the function returns NULL and sets @code{ERRNO}. +@end deftypefun + @node Hash Algorithms @section Hash Algorithms @@ -1954,9 +1965,11 @@ case, the data object @var{dh} is destroyed. @deftypefun void gpgme_free (@w{void *@var{buffer}}) The function @code{gpgme_free} releases the memory returned by -@code{gpgme_data_release_and_get_mem}. It should be used instead of -the system libraries @code{free} function in case different allocators -are used in a single program. +@code{gpgme_data_release_and_get_mem} and +@code{gpgme_pubkey_algo_string}. It should be used instead of the +system libraries @code{free} function in case different allocators are +used by a program. This is often the case if gpgme is used under +Windows as a DLL. @end deftypefun @@ -2838,7 +2851,7 @@ True if the secret key is stored on a smart card. The serial number of a smart card holding this key or @code{NULL}. @item char *curve -For ECC algoritms the name of the curve. +For ECC algorithms the name of the curve. @end table @end deftp diff --git a/src/conversion.c b/src/conversion.c index d04a6bef..0992225b 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -427,6 +427,7 @@ _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol) case 18: algo = GPGME_PK_ECDH; break; case 19: algo = GPGME_PK_ECDSA; break; case 20: break; + case 22: algo = GPGME_PK_EDDSA; break; default: algo = 0; break; /* Unknown. */ } } diff --git a/src/data-mem.c b/src/data-mem.c index e06a920c..a498b826 100644 --- a/src/data-mem.c +++ b/src/data-mem.c @@ -271,7 +271,8 @@ gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len) } -/* Release the memory returned by gpgme_data_release_and_get_mem(). */ +/* Release the memory returned by gpgme_data_release_and_get_mem() and + some other functions. */ void gpgme_free (void *buffer) { diff --git a/src/gpgme.c b/src/gpgme.c index 0cf999a7..343e7752 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -1,7 +1,7 @@ /* gpgme.c - GnuPG Made Easy. Copyright (C) 2000 Werner Koch (dd9jn) Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012, - 2014 g10 Code GmbH + 2014, 2015 g10 Code GmbH This file is part of GPGME. @@ -994,41 +994,70 @@ gpgme_sig_notation_get (gpgme_ctx_t ctx) return ctx->sig_notations; } + +/* Return a public key algorithm string made of the algorithm and size + or the curve name. May return NULL on error. Caller must free the + result using gpgme_free. */ +char * +gpgme_pubkey_algo_string (gpgme_subkey_t subkey) +{ + const char *prefix = NULL; + char *result; + + if (!subkey) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + + switch (subkey->pubkey_algo) + { + case GPGME_PK_RSA: + case GPGME_PK_RSA_E: + case GPGME_PK_RSA_S: prefix = "rsa"; break; + case GPGME_PK_ELG_E: prefix = "elg"; break; + case GPGME_PK_DSA: prefix = "dsa"; break; + case GPGME_PK_ELG: prefix = "xxx"; break; + case GPGME_PK_ECC: + case GPGME_PK_ECDH: + case GPGME_PK_ECDSA: + case GPGME_PK_EDDSA: prefix = ""; break; + } + + if (prefix && *prefix) + { + char buffer[40]; + snprintf (buffer, sizeof buffer, "%s%u", prefix, subkey->length); + result = strdup (buffer); + } + else if (prefix && subkey->curve && *subkey->curve) + result = strdup (subkey->curve); + else if (prefix) + result = strdup ("E_error"); + else + result = strdup ("unknown"); + + return result; +} + + const char * gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo) { switch (algo) { - case GPGME_PK_RSA: - return "RSA"; - - case GPGME_PK_RSA_E: - return "RSA-E"; - - case GPGME_PK_RSA_S: - return "RSA-S"; - - case GPGME_PK_ELG_E: - return "ELG-E"; - - case GPGME_PK_DSA: - return "DSA"; - - case GPGME_PK_ECC: - return "ECC"; - - case GPGME_PK_ELG: - return "ELG"; - - case GPGME_PK_ECDSA: - return "ECDSA"; - - case GPGME_PK_ECDH: - return "ECDH"; - - default: - return NULL; + case GPGME_PK_RSA: return "RSA"; + case GPGME_PK_RSA_E: return "RSA-E"; + case GPGME_PK_RSA_S: return "RSA-S"; + case GPGME_PK_ELG_E: return "ELG-E"; + case GPGME_PK_DSA: return "DSA"; + case GPGME_PK_ECC: return "ECC"; + case GPGME_PK_ELG: return "ELG"; + case GPGME_PK_ECDSA: return "ECDSA"; + case GPGME_PK_ECDH: return "ECDH"; + case GPGME_PK_EDDSA: return "EdDSA"; + default: return NULL; } } diff --git a/src/gpgme.def b/src/gpgme.def index a3f5fb4a..3b56aaad 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -223,5 +223,7 @@ EXPORTS gpgme_set_status_cb @167 gpgme_get_status_cb @168 + + gpgme_pubkey_algo_string @169 ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 6cea2c77..e7216cbe 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -261,7 +261,8 @@ typedef enum GPGME_PK_ECC = 18, GPGME_PK_ELG = 20, GPGME_PK_ECDSA = 301, - GPGME_PK_ECDH = 302 + GPGME_PK_ECDH = 302, + GPGME_PK_EDDSA = 303 } gpgme_pubkey_algo_t; @@ -1218,7 +1219,8 @@ gpgme_error_t gpgme_data_new_from_mem (gpgme_data_t *r_dh, size is returned in R_LEN. */ char *gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len); -/* Release the memory returned by gpgme_data_release_and_get_mem(). */ +/* Release the memory returned by gpgme_data_release_and_get_mem() and + some other functions. */ void gpgme_free (void *buffer); gpgme_error_t gpgme_data_new_from_cbs (gpgme_data_t *dh, @@ -2232,6 +2234,10 @@ gpgme_error_t gpgme_engine_check_version (gpgme_protocol_t proto); void gpgme_result_ref (void *result); void gpgme_result_unref (void *result); +/* Return a public key algorithm string (e.g. "rsa2048"). Caller must + free using gpgme_free. */ +char *gpgme_pubkey_algo_string (gpgme_subkey_t subkey); + /* Return a statically allocated string with the name of the public key algorithm ALGO, or NULL if that name is not known. */ const char *gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo); diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 6687571f..c677190f 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -98,6 +98,8 @@ GPGME_1.1 { gpgme_set_status_cb; gpgme_get_status_cb; + + gpgme_pubkey_algo_string; };