2007-04-03 18:57:37 +02:00
|
|
|
/* sexputil.c - Utility functions for S-expressions.
|
2009-03-06 18:31:27 +01:00
|
|
|
* Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
|
2013-05-21 15:00:00 +02:00
|
|
|
* Copyright (C) 2013 Werner Koch
|
2005-04-13 11:39:38 +02:00
|
|
|
*
|
|
|
|
* This file is part of GnuPG.
|
|
|
|
*
|
Change license for some files in common to LGPLv3+/GPLv2+.
Having the LGPL on the common GnuPG code helps to share code
between GnuPG and related projects (like GPGME and Libassuan). This
is good for interoperability and to reduces bugs.
* common/asshelp.c, common/asshelp.h, common/asshelp2.c, common/b64dec.c
* common/b64enc.c, common/convert.c, common/dns-cert.c
* common/dns-cert.h common/exechelp-posix.c, common/exechelp-w32.c
* common/exechelp-w32ce.c, common/exechelp.h, common/get-passphrase.c
* common/get-passphrase.h, common/gettime.c, common/gpgrlhelp.c
* common/helpfile.c, common/homedir.c, common/http.c, common/http.h
* common/i18n.c, common/init.c, common/init.h, common/iobuf.c
* common/iobuf.h, common/localename.c, common/membuf.c, common/membuf.h
* common/miscellaneous.c, common/openpgp-oid.c, common/openpgpdefs.h
* common/percent.c, common/pka.c, common/pka.h, common/session-env.c
* common/session-env.h, common/sexp-parse.h, common/sexputil.c
* common/signal.c, common/srv.c, common/srv.h, common/ssh-utils.c
* common/ssh-utils.h, common/sysutils.c, common/sysutils.h
* common/tlv.c, common/tlv.h, common/ttyio.c, common/ttyio.h
* common/userids.c, common/userids.h, common/xasprintf.c: Change
license to LGPLv3+/GPLv2+/
2012-04-20 15:43:06 +02:00
|
|
|
* This file is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of either
|
2005-04-13 11:39:38 +02:00
|
|
|
*
|
Change license for some files in common to LGPLv3+/GPLv2+.
Having the LGPL on the common GnuPG code helps to share code
between GnuPG and related projects (like GPGME and Libassuan). This
is good for interoperability and to reduces bugs.
* common/asshelp.c, common/asshelp.h, common/asshelp2.c, common/b64dec.c
* common/b64enc.c, common/convert.c, common/dns-cert.c
* common/dns-cert.h common/exechelp-posix.c, common/exechelp-w32.c
* common/exechelp-w32ce.c, common/exechelp.h, common/get-passphrase.c
* common/get-passphrase.h, common/gettime.c, common/gpgrlhelp.c
* common/helpfile.c, common/homedir.c, common/http.c, common/http.h
* common/i18n.c, common/init.c, common/init.h, common/iobuf.c
* common/iobuf.h, common/localename.c, common/membuf.c, common/membuf.h
* common/miscellaneous.c, common/openpgp-oid.c, common/openpgpdefs.h
* common/percent.c, common/pka.c, common/pka.h, common/session-env.c
* common/session-env.h, common/sexp-parse.h, common/sexputil.c
* common/signal.c, common/srv.c, common/srv.h, common/ssh-utils.c
* common/ssh-utils.h, common/sysutils.c, common/sysutils.h
* common/tlv.c, common/tlv.h, common/ttyio.c, common/ttyio.h
* common/userids.c, common/userids.h, common/xasprintf.c: Change
license to LGPLv3+/GPLv2+/
2012-04-20 15:43:06 +02:00
|
|
|
* - the GNU Lesser General Public License as published by the Free
|
|
|
|
* Software Foundation; either version 3 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* or
|
|
|
|
*
|
|
|
|
* - the GNU General Public License as published by the Free
|
|
|
|
* Software Foundation; either version 2 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* or both in parallel, as here.
|
|
|
|
*
|
|
|
|
* This file is distributed in the hope that it will be useful,
|
2005-04-13 11:39:38 +02:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2007-07-04 21:49:40 +02:00
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
2005-04-13 11:39:38 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* This file implements a few utility functions useful when working
|
|
|
|
with canonical encrypted S-expresions (i.e. not the S-exprssion
|
|
|
|
objects from libgcrypt). */
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#ifdef HAVE_LOCALE_H
|
|
|
|
#include <locale.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "util.h"
|
2009-05-07 17:01:47 +02:00
|
|
|
#include "tlv.h"
|
2007-05-15 18:10:48 +02:00
|
|
|
#include "sexp-parse.h"
|
2016-08-08 11:46:44 +02:00
|
|
|
#include "openpgpdefs.h" /* for pubkey_algo_t */
|
2005-04-13 11:39:38 +02:00
|
|
|
|
2009-03-06 18:31:27 +01:00
|
|
|
|
2013-05-21 15:00:00 +02:00
|
|
|
/* Return a malloced string with the S-expression CANON in advanced
|
|
|
|
format. Returns NULL on error. */
|
|
|
|
static char *
|
|
|
|
sexp_to_string (gcry_sexp_t sexp)
|
|
|
|
{
|
|
|
|
size_t n;
|
|
|
|
char *result;
|
|
|
|
|
|
|
|
if (!sexp)
|
|
|
|
return NULL;
|
|
|
|
n = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
|
|
|
|
if (!n)
|
|
|
|
return NULL;
|
|
|
|
result = xtrymalloc (n);
|
|
|
|
if (!result)
|
|
|
|
return NULL;
|
|
|
|
n = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, n);
|
|
|
|
if (!n)
|
|
|
|
BUG ();
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Return a malloced string with the S-expression CANON in advanced
|
|
|
|
format. Returns NULL on error. */
|
|
|
|
char *
|
|
|
|
canon_sexp_to_string (const unsigned char *canon, size_t canonlen)
|
|
|
|
{
|
|
|
|
size_t n;
|
|
|
|
gcry_sexp_t sexp;
|
|
|
|
char *result;
|
|
|
|
|
|
|
|
n = gcry_sexp_canon_len (canon, canonlen, NULL, NULL);
|
|
|
|
if (!n)
|
|
|
|
return NULL;
|
|
|
|
if (gcry_sexp_sscan (&sexp, NULL, canon, n))
|
|
|
|
return NULL;
|
|
|
|
result = sexp_to_string (sexp);
|
|
|
|
gcry_sexp_release (sexp);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Print the canonical encoded S-expression in SEXP in advanced
|
|
|
|
format. SEXPLEN may be passed as 0 is SEXP is known to be valid.
|
|
|
|
With TEXT of NULL print just the raw S-expression, with TEXT just
|
|
|
|
an empty string, print a trailing linefeed, otherwise print an
|
|
|
|
entire debug line. */
|
|
|
|
void
|
|
|
|
log_printcanon (const char *text, const unsigned char *sexp, size_t sexplen)
|
|
|
|
{
|
|
|
|
if (text && *text)
|
|
|
|
log_debug ("%s ", text);
|
|
|
|
if (sexp)
|
|
|
|
{
|
|
|
|
char *buf = canon_sexp_to_string (sexp, sexplen);
|
|
|
|
log_printf ("%s", buf? buf : "[invalid S-expression]");
|
|
|
|
xfree (buf);
|
|
|
|
}
|
|
|
|
if (text)
|
|
|
|
log_printf ("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Print the gcryp S-expression in SEXP in advanced format. With TEXT
|
|
|
|
of NULL print just the raw S-expression, with TEXT just an empty
|
|
|
|
string, print a trailing linefeed, otherwise print an entire debug
|
|
|
|
line. */
|
|
|
|
void
|
|
|
|
log_printsexp (const char *text, gcry_sexp_t sexp)
|
|
|
|
{
|
|
|
|
if (text && *text)
|
|
|
|
log_debug ("%s ", text);
|
|
|
|
if (sexp)
|
|
|
|
{
|
|
|
|
char *buf = sexp_to_string (sexp);
|
|
|
|
log_printf ("%s", buf? buf : "[invalid S-expression]");
|
|
|
|
xfree (buf);
|
|
|
|
}
|
|
|
|
if (text)
|
|
|
|
log_printf ("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-17 17:44:44 +02:00
|
|
|
/* Helper function to create a canonical encoded S-expression from a
|
2009-03-06 18:31:27 +01:00
|
|
|
Libgcrypt S-expression object. The function returns 0 on success
|
|
|
|
and the malloced canonical S-expression is stored at R_BUFFER and
|
|
|
|
the allocated length at R_BUFLEN. On error an error code is
|
|
|
|
returned and (NULL, 0) stored at R_BUFFER and R_BUFLEN. If the
|
|
|
|
allocated buffer length is not required, NULL by be used for
|
|
|
|
R_BUFLEN. */
|
|
|
|
gpg_error_t
|
|
|
|
make_canon_sexp (gcry_sexp_t sexp, unsigned char **r_buffer, size_t *r_buflen)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
unsigned char *buf;
|
|
|
|
|
|
|
|
*r_buffer = NULL;
|
|
|
|
if (r_buflen)
|
|
|
|
*r_buflen = 0;;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2009-03-06 18:31:27 +01:00
|
|
|
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
|
|
|
|
if (!len)
|
|
|
|
return gpg_error (GPG_ERR_BUG);
|
|
|
|
buf = xtrymalloc (len);
|
|
|
|
if (!buf)
|
|
|
|
return gpg_error_from_syserror ();
|
|
|
|
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len);
|
|
|
|
if (!len)
|
|
|
|
return gpg_error (GPG_ERR_BUG);
|
|
|
|
|
|
|
|
*r_buffer = buf;
|
|
|
|
if (r_buflen)
|
|
|
|
*r_buflen = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-17 17:44:44 +02:00
|
|
|
/* Same as make_canon_sexp but pad the buffer to multiple of 64
|
2010-06-21 12:01:24 +02:00
|
|
|
bits. If SECURE is set, secure memory will be allocated. */
|
2010-06-17 17:44:44 +02:00
|
|
|
gpg_error_t
|
2010-06-21 12:01:24 +02:00
|
|
|
make_canon_sexp_pad (gcry_sexp_t sexp, int secure,
|
2010-06-17 17:44:44 +02:00
|
|
|
unsigned char **r_buffer, size_t *r_buflen)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
unsigned char *buf;
|
|
|
|
|
|
|
|
*r_buffer = NULL;
|
|
|
|
if (r_buflen)
|
|
|
|
*r_buflen = 0;;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2010-06-17 17:44:44 +02:00
|
|
|
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
|
|
|
|
if (!len)
|
|
|
|
return gpg_error (GPG_ERR_BUG);
|
|
|
|
len += (8 - len % 8) % 8;
|
2010-06-21 12:01:24 +02:00
|
|
|
buf = secure? xtrycalloc_secure (1, len) : xtrycalloc (1, len);
|
2010-06-17 17:44:44 +02:00
|
|
|
if (!buf)
|
|
|
|
return gpg_error_from_syserror ();
|
|
|
|
if (!gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len))
|
|
|
|
return gpg_error (GPG_ERR_BUG);
|
|
|
|
|
|
|
|
*r_buffer = buf;
|
|
|
|
if (r_buflen)
|
|
|
|
*r_buflen = len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-04-13 11:39:38 +02:00
|
|
|
/* Return the so called "keygrip" which is the SHA-1 hash of the
|
|
|
|
public key parameters expressed in a way depended on the algorithm.
|
|
|
|
|
|
|
|
KEY is expected to be an canonical encoded S-expression with a
|
|
|
|
public or private key. KEYLEN is the length of that buffer.
|
|
|
|
|
2007-12-13 16:45:40 +01:00
|
|
|
GRIP must be at least 20 bytes long. On success 0 is returned, on
|
|
|
|
error an error code. */
|
2005-04-13 11:39:38 +02:00
|
|
|
gpg_error_t
|
|
|
|
keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
|
|
|
|
unsigned char *grip)
|
|
|
|
{
|
|
|
|
gpg_error_t err;
|
|
|
|
gcry_sexp_t sexp;
|
|
|
|
|
|
|
|
if (!grip)
|
|
|
|
return gpg_error (GPG_ERR_INV_VALUE);
|
2005-06-16 10:12:03 +02:00
|
|
|
err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen);
|
2005-04-13 11:39:38 +02:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (!gcry_pk_get_keygrip (sexp, grip))
|
|
|
|
err = gpg_error (GPG_ERR_INTERNAL);
|
|
|
|
gcry_sexp_release (sexp);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2005-04-18 12:44:46 +02:00
|
|
|
|
|
|
|
/* Compare two simple S-expressions like "(3:foo)". Returns 0 if they
|
2010-06-08 18:59:19 +02:00
|
|
|
are identical or !0 if they are not. Note that this function can't
|
2005-04-18 12:44:46 +02:00
|
|
|
be used for sorting. */
|
|
|
|
int
|
2005-06-16 10:12:03 +02:00
|
|
|
cmp_simple_canon_sexp (const unsigned char *a_orig,
|
|
|
|
const unsigned char *b_orig)
|
2005-04-18 12:44:46 +02:00
|
|
|
{
|
2005-06-16 10:12:03 +02:00
|
|
|
const char *a = (const char *)a_orig;
|
|
|
|
const char *b = (const char *)b_orig;
|
2005-04-18 12:44:46 +02:00
|
|
|
unsigned long n1, n2;
|
|
|
|
char *endp;
|
|
|
|
|
|
|
|
if (!a && !b)
|
|
|
|
return 0; /* Both are NULL, they are identical. */
|
|
|
|
if (!a || !b)
|
|
|
|
return 1; /* One is NULL, they are not identical. */
|
|
|
|
if (*a != '(' || *b != '(')
|
|
|
|
log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
|
|
|
|
|
|
|
|
a++;
|
|
|
|
n1 = strtoul (a, &endp, 10);
|
|
|
|
a = endp;
|
|
|
|
b++;
|
|
|
|
n2 = strtoul (b, &endp, 10);
|
|
|
|
b = endp;
|
|
|
|
|
|
|
|
if (*a != ':' || *b != ':' )
|
|
|
|
log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
|
|
|
|
if (n1 != n2)
|
|
|
|
return 1; /* Not the same. */
|
|
|
|
|
|
|
|
for (a++, b++; n1; n1--, a++, b++)
|
|
|
|
if (*a != *b)
|
|
|
|
return 1; /* Not the same. */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-23 13:36:59 +02:00
|
|
|
/* Create a simple S-expression from the hex string at LINE. Returns
|
2005-04-18 12:44:46 +02:00
|
|
|
a newly allocated buffer with that canonical encoded S-expression
|
|
|
|
or NULL in case of an error. On return the number of characters
|
|
|
|
scanned in LINE will be stored at NSCANNED. This fucntions stops
|
|
|
|
converting at the first character not representing a hexdigit. Odd
|
|
|
|
numbers of hex digits are allowed; a leading zero is then
|
|
|
|
assumed. If no characters have been found, NULL is returned.*/
|
|
|
|
unsigned char *
|
|
|
|
make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
|
|
|
|
{
|
|
|
|
size_t n, len;
|
|
|
|
const char *s;
|
|
|
|
unsigned char *buf;
|
|
|
|
unsigned char *p;
|
2007-05-15 18:10:48 +02:00
|
|
|
char numbuf[50], *numbufp;
|
|
|
|
size_t numbuflen;
|
2005-04-18 12:44:46 +02:00
|
|
|
|
|
|
|
for (n=0, s=line; hexdigitp (s); s++, n++)
|
|
|
|
;
|
|
|
|
if (nscanned)
|
|
|
|
*nscanned = n;
|
|
|
|
if (!n)
|
|
|
|
return NULL;
|
2011-02-04 12:57:53 +01:00
|
|
|
len = ((n+1) & ~0x01)/2;
|
2007-05-15 18:10:48 +02:00
|
|
|
numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
|
|
|
|
buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
|
2005-04-18 12:44:46 +02:00
|
|
|
if (!buf)
|
|
|
|
return NULL;
|
2007-05-15 18:10:48 +02:00
|
|
|
buf[0] = '(';
|
|
|
|
p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
|
2005-04-18 12:44:46 +02:00
|
|
|
s = line;
|
|
|
|
if ((n&1))
|
|
|
|
{
|
|
|
|
*p++ = xtoi_1 (s);
|
|
|
|
s++;
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
for (; n > 1; n -=2, s += 2)
|
|
|
|
*p++ = xtoi_2 (s);
|
|
|
|
*p++ = ')';
|
|
|
|
*p = 0; /* (Not really neaded.) */
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
2007-12-13 16:45:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* Return the hash algorithm from a KSBA sig-val. SIGVAL is a
|
|
|
|
canonical encoded S-expression. Return 0 if the hash algorithm is
|
|
|
|
not encoded in SIG-VAL or it is not supported by libgcrypt. */
|
|
|
|
int
|
|
|
|
hash_algo_from_sigval (const unsigned char *sigval)
|
|
|
|
{
|
|
|
|
const unsigned char *s = sigval;
|
|
|
|
size_t n;
|
|
|
|
int depth;
|
|
|
|
char buffer[50];
|
|
|
|
|
|
|
|
if (!s || *s != '(')
|
|
|
|
return 0; /* Invalid S-expression. */
|
|
|
|
s++;
|
|
|
|
n = snext (&s);
|
|
|
|
if (!n)
|
|
|
|
return 0; /* Invalid S-expression. */
|
|
|
|
if (!smatch (&s, n, "sig-val"))
|
|
|
|
return 0; /* Not a sig-val. */
|
|
|
|
if (*s != '(')
|
|
|
|
return 0; /* Invalid S-expression. */
|
|
|
|
s++;
|
|
|
|
/* Skip over the algo+parameter list. */
|
|
|
|
depth = 1;
|
|
|
|
if (sskip (&s, &depth) || depth)
|
|
|
|
return 0; /* Invalid S-expression. */
|
|
|
|
if (*s != '(')
|
2015-11-16 12:41:46 +01:00
|
|
|
return 0; /* No further list. */
|
2007-12-13 16:45:40 +01:00
|
|
|
/* Check whether this is (hash ALGO). */
|
|
|
|
s++;
|
|
|
|
n = snext (&s);
|
|
|
|
if (!n)
|
|
|
|
return 0; /* Invalid S-expression. */
|
|
|
|
if (!smatch (&s, n, "hash"))
|
|
|
|
return 0; /* Not a "hash" keyword. */
|
|
|
|
n = snext (&s);
|
|
|
|
if (!n || n+1 >= sizeof (buffer))
|
|
|
|
return 0; /* Algorithm string is missing or too long. */
|
|
|
|
memcpy (buffer, s, n);
|
|
|
|
buffer[n] = 0;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2007-12-13 16:45:40 +01:00
|
|
|
return gcry_md_map_name (buffer);
|
|
|
|
}
|
|
|
|
|
2009-05-07 17:01:47 +02:00
|
|
|
|
|
|
|
/* Create a public key S-expression for an RSA public key from the
|
|
|
|
modulus M with length MLEN and the public exponent E with length
|
|
|
|
ELEN. Returns a newly allocated buffer of NULL in case of a memory
|
|
|
|
allocation problem. If R_LEN is not NULL, the length of the
|
|
|
|
canonical S-expression is stored there. */
|
|
|
|
unsigned char *
|
|
|
|
make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen,
|
|
|
|
const void *e_arg, size_t elen,
|
|
|
|
size_t *r_len)
|
|
|
|
{
|
|
|
|
const unsigned char *m = m_arg;
|
|
|
|
const unsigned char *e = e_arg;
|
|
|
|
int m_extra = 0;
|
|
|
|
int e_extra = 0;
|
|
|
|
char mlen_str[35];
|
|
|
|
char elen_str[35];
|
|
|
|
unsigned char *keybuf, *p;
|
2014-09-18 15:49:44 +02:00
|
|
|
const char part1[] = "(10:public-key(3:rsa(1:n";
|
|
|
|
const char part2[] = ")(1:e";
|
|
|
|
const char part3[] = ")))";
|
2009-05-07 17:01:47 +02:00
|
|
|
|
|
|
|
/* Remove leading zeroes. */
|
|
|
|
for (; mlen && !*m; mlen--, m++)
|
|
|
|
;
|
|
|
|
for (; elen && !*e; elen--, e++)
|
|
|
|
;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2009-05-07 17:01:47 +02:00
|
|
|
/* Insert a leading zero if the number would be zero or interpreted
|
|
|
|
as negative. */
|
|
|
|
if (!mlen || (m[0] & 0x80))
|
|
|
|
m_extra = 1;
|
|
|
|
if (!elen || (e[0] & 0x80))
|
|
|
|
e_extra = 1;
|
|
|
|
|
|
|
|
/* Build the S-expression. */
|
|
|
|
snprintf (mlen_str, sizeof mlen_str, "%u:", (unsigned int)mlen+m_extra);
|
|
|
|
snprintf (elen_str, sizeof elen_str, "%u:", (unsigned int)elen+e_extra);
|
|
|
|
|
|
|
|
keybuf = xtrymalloc (strlen (part1) + strlen (mlen_str) + mlen + m_extra
|
|
|
|
+ strlen (part2) + strlen (elen_str) + elen + e_extra
|
|
|
|
+ strlen (part3) + 1);
|
|
|
|
if (!keybuf)
|
|
|
|
return NULL;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2009-05-07 17:01:47 +02:00
|
|
|
p = stpcpy (keybuf, part1);
|
|
|
|
p = stpcpy (p, mlen_str);
|
|
|
|
if (m_extra)
|
|
|
|
*p++ = 0;
|
|
|
|
memcpy (p, m, mlen);
|
|
|
|
p += mlen;
|
|
|
|
p = stpcpy (p, part2);
|
|
|
|
p = stpcpy (p, elen_str);
|
|
|
|
if (e_extra)
|
|
|
|
*p++ = 0;
|
|
|
|
memcpy (p, e, elen);
|
|
|
|
p += elen;
|
|
|
|
p = stpcpy (p, part3);
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2009-05-07 17:01:47 +02:00
|
|
|
if (r_len)
|
|
|
|
*r_len = p - keybuf;
|
|
|
|
|
|
|
|
return keybuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-20 15:47:12 +02:00
|
|
|
/* Return the parameters of a public RSA key expressed as an
|
2009-07-01 20:30:33 +02:00
|
|
|
canonical encoded S-expression. */
|
2009-05-07 17:01:47 +02:00
|
|
|
gpg_error_t
|
|
|
|
get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
|
|
|
|
unsigned char const **r_n, size_t *r_nlen,
|
|
|
|
unsigned char const **r_e, size_t *r_elen)
|
|
|
|
{
|
|
|
|
gpg_error_t err;
|
|
|
|
const unsigned char *buf, *tok;
|
|
|
|
size_t buflen, toklen;
|
|
|
|
int depth, last_depth1, last_depth2;
|
|
|
|
const unsigned char *rsa_n = NULL;
|
|
|
|
const unsigned char *rsa_e = NULL;
|
|
|
|
size_t rsa_n_len, rsa_e_len;
|
|
|
|
|
|
|
|
*r_n = NULL;
|
|
|
|
*r_nlen = 0;
|
|
|
|
*r_e = NULL;
|
|
|
|
*r_elen = 0;
|
|
|
|
|
|
|
|
buf = keydata;
|
|
|
|
buflen = keydatalen;
|
|
|
|
depth = 0;
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
|
|
|
|
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen))
|
|
|
|
return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
|
|
|
|
|
|
|
|
last_depth1 = depth;
|
|
|
|
while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
|
|
|
|
&& depth && depth >= last_depth1)
|
|
|
|
{
|
|
|
|
if (tok)
|
|
|
|
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if (tok && toklen == 1)
|
|
|
|
{
|
|
|
|
const unsigned char **mpi;
|
|
|
|
size_t *mpi_len;
|
|
|
|
|
|
|
|
switch (*tok)
|
|
|
|
{
|
2011-02-04 12:57:53 +01:00
|
|
|
case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break;
|
|
|
|
case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break;
|
2009-05-07 17:01:47 +02:00
|
|
|
default: mpi = NULL; mpi_len = NULL; break;
|
|
|
|
}
|
|
|
|
if (mpi && *mpi)
|
|
|
|
return gpg_error (GPG_ERR_DUP_VALUE);
|
|
|
|
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if (tok && mpi)
|
|
|
|
{
|
|
|
|
/* Strip off leading zero bytes and save. */
|
|
|
|
for (;toklen && !*tok; toklen--, tok++)
|
|
|
|
;
|
|
|
|
*mpi = tok;
|
|
|
|
*mpi_len = toklen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Skip to the end of the list. */
|
|
|
|
last_depth2 = depth;
|
|
|
|
while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
|
|
|
|
&& depth && depth >= last_depth2)
|
|
|
|
;
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2009-06-24 16:03:09 +02:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
2009-05-07 17:01:47 +02:00
|
|
|
if (!rsa_n || !rsa_n_len || !rsa_e || !rsa_e_len)
|
|
|
|
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
|
|
|
|
|
|
|
*r_n = rsa_n;
|
|
|
|
*r_nlen = rsa_n_len;
|
|
|
|
*r_e = rsa_e;
|
|
|
|
*r_elen = rsa_e_len;
|
|
|
|
return 0;
|
|
|
|
}
|
2009-07-01 20:30:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Return the algo of a public RSA expressed as an canonical encoded
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
S-expression. The return value is a statically allocated
|
|
|
|
string. On error that string is set to NULL. */
|
2009-07-01 20:30:33 +02:00
|
|
|
gpg_error_t
|
|
|
|
get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
const char **r_algo)
|
2009-07-01 20:30:33 +02:00
|
|
|
{
|
|
|
|
gpg_error_t err;
|
|
|
|
const unsigned char *buf, *tok;
|
|
|
|
size_t buflen, toklen;
|
|
|
|
int depth;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
*r_algo = NULL;
|
2009-07-01 20:30:33 +02:00
|
|
|
|
|
|
|
buf = keydata;
|
|
|
|
buflen = keydatalen;
|
|
|
|
depth = 0;
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
|
|
|
|
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
|
|
|
|
return err;
|
|
|
|
if (!tok)
|
|
|
|
return gpg_error (GPG_ERR_BAD_PUBKEY);
|
|
|
|
|
|
|
|
if (toklen == 3 && !memcmp ("rsa", tok, toklen))
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
*r_algo = "rsa";
|
2009-07-01 20:30:33 +02:00
|
|
|
else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
*r_algo = "dsa";
|
2009-07-01 20:30:33 +02:00
|
|
|
else if (toklen == 3 && !memcmp ("elg", tok, toklen))
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
*r_algo = "elg";
|
2009-07-01 20:30:33 +02:00
|
|
|
else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
*r_algo = "ecdsa";
|
|
|
|
else if (toklen == 5 && !memcmp ("eddsa", tok, toklen))
|
|
|
|
*r_algo = "eddsa";
|
2009-07-01 20:30:33 +02:00
|
|
|
else
|
gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.
* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.
* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.
* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip): Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--
This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones. This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.
This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA. As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF. Note that EdDSA (Ed25519)
does not yet work and that more changes are required.
The ECC support is still broken right now. Needs to be fixed.
Signed-off-by: Werner Koch <wk@gnupg.org>
2014-01-30 18:48:37 +01:00
|
|
|
return gpg_error (GPG_ERR_PUBKEY_ALGO);
|
2009-07-01 20:30:33 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2016-08-08 11:46:44 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Return the algo of a public KEY of SEXP. */
|
|
|
|
int
|
|
|
|
get_pk_algo_from_key (gcry_sexp_t key)
|
|
|
|
{
|
|
|
|
gcry_sexp_t list;
|
|
|
|
const char *s;
|
|
|
|
size_t n;
|
|
|
|
char algoname[6];
|
|
|
|
int algo = 0;
|
|
|
|
|
|
|
|
list = gcry_sexp_nth (key, 1);
|
|
|
|
if (!list)
|
|
|
|
goto out;
|
|
|
|
s = gcry_sexp_nth_data (list, 0, &n);
|
|
|
|
if (!s)
|
|
|
|
goto out;
|
|
|
|
if (n >= sizeof (algoname))
|
|
|
|
goto out;
|
|
|
|
memcpy (algoname, s, n);
|
|
|
|
algoname[n] = 0;
|
|
|
|
|
|
|
|
algo = gcry_pk_map_name (algoname);
|
|
|
|
if (algo == GCRY_PK_ECC)
|
|
|
|
{
|
|
|
|
gcry_sexp_t l1 = gcry_sexp_find_token (list, "flags", 0);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = l1 ? gcry_sexp_length (l1)-1 : 0; i > 0; i--)
|
|
|
|
{
|
|
|
|
s = gcry_sexp_nth_data (l1, i, &n);
|
|
|
|
if (!s)
|
|
|
|
continue; /* Not a data element. */
|
|
|
|
|
|
|
|
if (n == 5 && !memcmp (s, "eddsa", 5))
|
|
|
|
{
|
|
|
|
algo = GCRY_PK_EDDSA;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gcry_sexp_release (l1);
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
gcry_sexp_release (list);
|
|
|
|
|
|
|
|
return algo;
|
|
|
|
}
|