mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
common: New function get_keyalgo_string.
* common/openpgp-oid.c (struct keyalgo_string_s): New. (keyalgo_strings): New. (keyalgo_strings_size, keyalgo_strings_used): New. (get_keyalgo_string): New. -- This function is intended as a more general version of gpg's pubkey_string function. It has the advantage to avoid mallocs and uses static table of algorithm strings instead. There should be only a few dozen of such strings (if at all) and thus all those allocations we do internally in gpg's pubkey_string and the static buffers all over the place are not too nice. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
49c891a9bf
commit
3a1fa13eed
4 changed files with 198 additions and 3 deletions
|
@ -71,6 +71,21 @@ static const char oid_ed25519[] =
|
|||
static const char oid_cv25519[] =
|
||||
{ 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 };
|
||||
|
||||
/* A table to store keyalgo strings like "rsa2048 or "ed25519" so that
|
||||
* we do not need to allocate them. This is currently a simple array
|
||||
* but may eventually be changed to a fast data structure. Noet that
|
||||
* unknown algorithms are stored with (NBITS,CURVE) set to (0,NULL). */
|
||||
struct keyalgo_string_s
|
||||
{
|
||||
enum gcry_pk_algos algo; /* Mandatory. */
|
||||
unsigned int nbits; /* Size for classical algos. */
|
||||
char *curve; /* Curvename (OID) or NULL. */
|
||||
char *name; /* Allocated name. */
|
||||
};
|
||||
static struct keyalgo_string_s *keyalgo_strings; /* The table. */
|
||||
static size_t keyalgo_strings_size; /* Allocated size. */
|
||||
static size_t keyalgo_strings_used; /* Used size. */
|
||||
|
||||
|
||||
/* Helper for openpgp_oid_from_str. */
|
||||
static size_t
|
||||
|
@ -492,3 +507,109 @@ map_openpgp_pk_to_gcry (pubkey_algo_t algo)
|
|||
default: return algo < 110 ? algo : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return a string describing the public key algorithm and the
|
||||
* keysize. For elliptic curves the function prints the name of the
|
||||
* curve because the keysize is a property of the curve. ALGO is the
|
||||
* Gcrypt algorithmj number, curve is either NULL or give the PID of
|
||||
* the curve, NBITS is either 0 or the size of the algorithms for RSA
|
||||
* etc. The returned string is taken from permanent table. Examples
|
||||
* for the output are:
|
||||
*
|
||||
* "rsa3072" - RSA with 3072 bit
|
||||
* "elg1024" - Elgamal with 1024 bit
|
||||
* "ed25519" - ECC using the curve Ed25519.
|
||||
* "E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4".
|
||||
* "E_1.3.6.1.4.1.11591.2.12242973" - ECC with a bogus OID.
|
||||
* "unknown_N" - Unknown OpenPGP algorithm N.
|
||||
* If N is > 110 this is a gcrypt algo.
|
||||
*/
|
||||
const char *
|
||||
get_keyalgo_string (enum gcry_pk_algos algo,
|
||||
unsigned int nbits, const char *curve)
|
||||
{
|
||||
const char *prefix = NULL;
|
||||
int i;
|
||||
char *name, *curvebuf;
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_PK_RSA: prefix = "rsa"; break;
|
||||
case GCRY_PK_ELG: prefix = "elg"; break;
|
||||
case GCRY_PK_DSA: prefix = "dsa"; break;
|
||||
case GCRY_PK_ECDH:
|
||||
case GCRY_PK_ECDSA:
|
||||
case GCRY_PK_EDDSA: prefix = ""; break;
|
||||
}
|
||||
|
||||
if (prefix && *prefix && nbits)
|
||||
{
|
||||
for (i=0; i < keyalgo_strings_used; i++)
|
||||
{
|
||||
if (keyalgo_strings[i].algo == algo
|
||||
&& keyalgo_strings[i].nbits
|
||||
&& keyalgo_strings[i].nbits == nbits)
|
||||
return keyalgo_strings[i].name;
|
||||
}
|
||||
/* Not yet in the table - add it. */
|
||||
name = xasprintf ("%s%u", prefix, nbits);
|
||||
nbits = nbits? nbits : 1; /* No nbits - oops - use 1 instead. */
|
||||
curvebuf = NULL;
|
||||
}
|
||||
else if (prefix && !*prefix)
|
||||
{
|
||||
const char *curvename;
|
||||
|
||||
for (i=0; i < keyalgo_strings_used; i++)
|
||||
{
|
||||
if (keyalgo_strings[i].algo == algo
|
||||
&& keyalgo_strings[i].curve
|
||||
&& !strcmp (keyalgo_strings[i].curve, curve))
|
||||
return keyalgo_strings[i].name;
|
||||
}
|
||||
|
||||
/* Not yet in the table - add it. */
|
||||
curvename = openpgp_oid_to_curve (curve, 0);
|
||||
if (curvename)
|
||||
name = xasprintf ("%s", curvename);
|
||||
else if (curve)
|
||||
name = xasprintf ("E_%s", curve);
|
||||
else
|
||||
name = xasprintf ("E_error");
|
||||
nbits = 0;
|
||||
curvebuf = xstrdup (curve);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < keyalgo_strings_used; i++)
|
||||
{
|
||||
if (keyalgo_strings[i].algo == algo
|
||||
&& !keyalgo_strings[i].nbits
|
||||
&& !keyalgo_strings[i].curve)
|
||||
return keyalgo_strings[i].name;
|
||||
}
|
||||
/* Not yet in the table - add it. */
|
||||
name = xasprintf ("unknown_%u", (unsigned int)algo);
|
||||
nbits = 0;
|
||||
curvebuf = NULL;
|
||||
}
|
||||
|
||||
/* Store a new entry. This is a loop because of a possible nPth
|
||||
* thread switch during xrealloc. */
|
||||
while (keyalgo_strings_used >= keyalgo_strings_size)
|
||||
{
|
||||
keyalgo_strings_size += 10;
|
||||
if (keyalgo_strings_size > 1024*1024)
|
||||
log_fatal ("%s: table getting too large - possible DoS\n", __func__);
|
||||
keyalgo_strings = xrealloc (keyalgo_strings, (keyalgo_strings_size
|
||||
* sizeof *keyalgo_strings));
|
||||
}
|
||||
keyalgo_strings[keyalgo_strings_used].algo = algo;
|
||||
keyalgo_strings[keyalgo_strings_used].nbits = nbits;
|
||||
keyalgo_strings[keyalgo_strings_used].curve = curvebuf;
|
||||
keyalgo_strings[keyalgo_strings_used].name = name;
|
||||
keyalgo_strings_used++;
|
||||
|
||||
return name; /* Note that this is in the table. */
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue