mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-19 09:02:22 +02:00
Move OpenPGP OID helpers to common/.
This is needed so that the agent will be able to export and import OpenPGP secret keys. Add test case. Removed unused function.
This commit is contained in:
parent
328a642aa5
commit
e0d4139e19
@ -1,3 +1,10 @@
|
|||||||
|
2011-01-31 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* openpgp-oid.c: New.
|
||||||
|
* t-openpgp-oid.c: New.
|
||||||
|
|
||||||
|
* convert.c (mpi2hex): Remove.
|
||||||
|
|
||||||
2011-01-20 Werner Koch <wk@g10code.com>
|
2011-01-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
Fix bug#1313.
|
Fix bug#1313.
|
||||||
|
@ -90,6 +90,7 @@ common_sources = \
|
|||||||
localename.c \
|
localename.c \
|
||||||
session-env.c session-env.h \
|
session-env.c session-env.h \
|
||||||
userids.c userids.h \
|
userids.c userids.h \
|
||||||
|
openpgp-oid.c \
|
||||||
helpfile.c
|
helpfile.c
|
||||||
|
|
||||||
# To make the code easier to read we have split home some code into
|
# To make the code easier to read we have split home some code into
|
||||||
@ -160,7 +161,7 @@ if HAVE_W32_SYSTEM
|
|||||||
jnlib_tests += t-w32-reg
|
jnlib_tests += t-w32-reg
|
||||||
endif
|
endif
|
||||||
module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil \
|
module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil \
|
||||||
t-session-env
|
t-session-env t-openpgp-oid
|
||||||
if !HAVE_W32CE_SYSTEM
|
if !HAVE_W32CE_SYSTEM
|
||||||
module_tests += t-exechelp
|
module_tests += t-exechelp
|
||||||
endif
|
endif
|
||||||
@ -192,6 +193,7 @@ t_sexputil_LDADD = $(t_common_ldadd)
|
|||||||
t_b64_LDADD = $(t_common_ldadd)
|
t_b64_LDADD = $(t_common_ldadd)
|
||||||
t_exechelp_LDADD = $(t_common_ldadd)
|
t_exechelp_LDADD = $(t_common_ldadd)
|
||||||
t_session_env_LDADD = $(t_common_ldadd)
|
t_session_env_LDADD = $(t_common_ldadd)
|
||||||
|
t_openpgp_oid_LDADD = $(t_common_ldadd)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,37 +245,3 @@ hex2str_alloc (const char *hexstring, size_t *r_count)
|
|||||||
BUG ();
|
BUG ();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns hex representation of the MPI;
|
|
||||||
* caller must free with xfree
|
|
||||||
* Returns NULL on error, never throws
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
mpi2hex( gcry_mpi_t m )
|
|
||||||
{
|
|
||||||
#warning we have code for this in libcrypt
|
|
||||||
size_t nbytes;
|
|
||||||
size_t nbytes2;
|
|
||||||
int rc;
|
|
||||||
byte *p;
|
|
||||||
|
|
||||||
nbytes = (mpi_get_nbits ( m )+7)/8;
|
|
||||||
if( nbytes == 0 )
|
|
||||||
return NULL;
|
|
||||||
p = xtrymalloc( nbytes*3+1 );
|
|
||||||
if( p==NULL )
|
|
||||||
return NULL;
|
|
||||||
rc = gcry_mpi_print (GCRYMPI_FMT_USG, p+2*nbytes+1, nbytes, &nbytes2, m);
|
|
||||||
if( rc ) {
|
|
||||||
xfree( p );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bin2hex( p+2*nbytes+1, nbytes2, p );
|
|
||||||
p[nbytes2*2] = '\0';
|
|
||||||
/*printf("%s:%d>>>> Created the string %s from %d bytes %02x %02x
|
|
||||||
..., MPI was %d bytes\n", __FILE__, __LINE__, p, nbytes2,
|
|
||||||
p[2*nbytes+1], p[2*nbytes+2], nbytes); */
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
227
common/openpgp-oid.c
Normal file
227
common/openpgp-oid.c
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
/* openpgp-oids.c - OID helper for OpenPGP
|
||||||
|
* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* 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
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper for openpgp_oid_from_str. */
|
||||||
|
static size_t
|
||||||
|
make_flagged_int (unsigned long value, char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
int more = 0;
|
||||||
|
int shift;
|
||||||
|
|
||||||
|
/* fixme: figure out the number of bits in an ulong and start with
|
||||||
|
that value as shift (after making it a multiple of 7) a more
|
||||||
|
straigtforward implementation is to do it in reverse order using
|
||||||
|
a temporary buffer - saves a lot of compares */
|
||||||
|
for (more=0, shift=28; shift > 0; shift -= 7)
|
||||||
|
{
|
||||||
|
if (more || value >= (1<<shift))
|
||||||
|
{
|
||||||
|
buf[buflen++] = 0x80 | (value >> shift);
|
||||||
|
value -= (value >> shift) << shift;
|
||||||
|
more = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf[buflen++] = value;
|
||||||
|
return buflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert the OID given in dotted decimal form in STRING to an DER
|
||||||
|
* encoding and store it as an opaque value at R_MPI. The format of
|
||||||
|
* the DER encoded is not a regular ASN.1 object but the modified
|
||||||
|
* format as used by OpenPGP for the ECC curve description. On error
|
||||||
|
* the function returns and error code an NULL is stored at R_BUG.
|
||||||
|
* Note that scanning STRING stops at the first white space
|
||||||
|
* character. */
|
||||||
|
gpg_error_t
|
||||||
|
openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi)
|
||||||
|
{
|
||||||
|
unsigned char *buf;
|
||||||
|
size_t buflen;
|
||||||
|
unsigned long val1, val;
|
||||||
|
const char *endp;
|
||||||
|
int arcno;
|
||||||
|
|
||||||
|
*r_mpi = NULL;
|
||||||
|
|
||||||
|
if (!string || !*string)
|
||||||
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
/* We can safely assume that the encoded OID is shorter than the string. */
|
||||||
|
buf = xtrymalloc (1 + strlen (string) + 2);
|
||||||
|
if (!buf)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
/* Save the first byte for the length. */
|
||||||
|
buflen = 1;
|
||||||
|
|
||||||
|
val1 = 0; /* Avoid compiler warning. */
|
||||||
|
arcno = 0;
|
||||||
|
do {
|
||||||
|
arcno++;
|
||||||
|
val = strtoul (string, (char**)&endp, 10);
|
||||||
|
if (!digitp (string) || !(*endp == '.' || !*endp))
|
||||||
|
{
|
||||||
|
xfree (buf);
|
||||||
|
return gpg_error (GPG_ERR_INV_OID_STRING);
|
||||||
|
}
|
||||||
|
if (*endp == '.')
|
||||||
|
string = endp+1;
|
||||||
|
|
||||||
|
if (arcno == 1)
|
||||||
|
{
|
||||||
|
if (val > 2)
|
||||||
|
break; /* Not allowed, error catched below. */
|
||||||
|
val1 = val;
|
||||||
|
}
|
||||||
|
else if (arcno == 2)
|
||||||
|
{ /* Need to combine the first two arcs in one octet. */
|
||||||
|
if (val1 < 2)
|
||||||
|
{
|
||||||
|
if (val > 39)
|
||||||
|
{
|
||||||
|
xfree (buf);
|
||||||
|
return gpg_error (GPG_ERR_INV_OID_STRING);
|
||||||
|
}
|
||||||
|
buf[buflen++] = val1*40 + val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val += 80;
|
||||||
|
buflen = make_flagged_int (val, buf, buflen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buflen = make_flagged_int (val, buf, buflen);
|
||||||
|
}
|
||||||
|
} while (*endp == '.');
|
||||||
|
|
||||||
|
if (arcno == 1 || buflen < 2 || buflen > 254 )
|
||||||
|
{ /* It is not possible to encode only the first arc. */
|
||||||
|
xfree (buf);
|
||||||
|
return gpg_error (GPG_ERR_INV_OID_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf = buflen - 1;
|
||||||
|
*r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8);
|
||||||
|
if (!*r_mpi)
|
||||||
|
{
|
||||||
|
xfree (buf);
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return a malloced string represenation of the OID in the opaque MPI
|
||||||
|
A. In case of an error NULL is returned and ERRNO is set. */
|
||||||
|
char *
|
||||||
|
openpgp_oid_to_str (gcry_mpi_t a)
|
||||||
|
{
|
||||||
|
const unsigned char *buf;
|
||||||
|
size_t length;
|
||||||
|
char *string, *p;
|
||||||
|
int n = 0;
|
||||||
|
unsigned long val, valmask;
|
||||||
|
|
||||||
|
valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
|
||||||
|
|
||||||
|
if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
|
||||||
|
{
|
||||||
|
gpg_err_set_errno (EINVAL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = gcry_mpi_get_opaque (a, &length);
|
||||||
|
length = (length+7)/8;
|
||||||
|
|
||||||
|
/* The first bytes gives the length; check consistency. */
|
||||||
|
if (!length || buf[0] != length -1)
|
||||||
|
{
|
||||||
|
gpg_err_set_errno (EINVAL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Skip length byte. */
|
||||||
|
length--;
|
||||||
|
buf++;
|
||||||
|
|
||||||
|
/* To calculate the length of the string we can safely assume an
|
||||||
|
upper limit of 3 decimal characters per byte. Two extra bytes
|
||||||
|
account for the special first octect */
|
||||||
|
string = p = xtrymalloc (length*(1+3)+2+1);
|
||||||
|
if (!string)
|
||||||
|
return NULL;
|
||||||
|
if (!buf || !length)
|
||||||
|
{
|
||||||
|
*p = 0;
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf[0] < 40)
|
||||||
|
p += sprintf (p, "0.%d", buf[n]);
|
||||||
|
else if (buf[0] < 80)
|
||||||
|
p += sprintf (p, "1.%d", buf[n]-40);
|
||||||
|
else {
|
||||||
|
val = buf[n] & 0x7f;
|
||||||
|
while ( (buf[n]&0x80) && ++n < length )
|
||||||
|
{
|
||||||
|
if ( (val & valmask) )
|
||||||
|
goto badoid; /* Overflow. */
|
||||||
|
val <<= 7;
|
||||||
|
val |= buf[n] & 0x7f;
|
||||||
|
}
|
||||||
|
val -= 80;
|
||||||
|
sprintf (p, "2.%lu", val);
|
||||||
|
p += strlen (p);
|
||||||
|
}
|
||||||
|
for (n++; n < length; n++)
|
||||||
|
{
|
||||||
|
val = buf[n] & 0x7f;
|
||||||
|
while ( (buf[n]&0x80) && ++n < length )
|
||||||
|
{
|
||||||
|
if ( (val & valmask) )
|
||||||
|
goto badoid; /* Overflow. */
|
||||||
|
val <<= 7;
|
||||||
|
val |= buf[n] & 0x7f;
|
||||||
|
}
|
||||||
|
sprintf (p, ".%lu", val);
|
||||||
|
p += strlen (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = 0;
|
||||||
|
return string;
|
||||||
|
|
||||||
|
badoid:
|
||||||
|
/* Return a special OID (gnu.gnupg.badoid) to indicate the error
|
||||||
|
case. The OID is broken and thus we return one which can't do
|
||||||
|
any harm. Formally this does not need to be a bad OID but an OID
|
||||||
|
with an arc that can't be represented in a 32 bit word is more
|
||||||
|
than likely corrupt. */
|
||||||
|
xfree (string);
|
||||||
|
return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973");
|
||||||
|
}
|
148
common/t-openpgp-oid.c
Normal file
148
common/t-openpgp-oid.c
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/* t-openpgp-oid.c - Module test for openpgp-oid.c
|
||||||
|
* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* 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
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#define pass() do { ; } while(0)
|
||||||
|
#define fail(a,e) \
|
||||||
|
do { fprintf (stderr, "%s:%d: test %d failed (%s)\n", \
|
||||||
|
__FILE__,__LINE__, (a), gpg_strerror (e)); \
|
||||||
|
exit (1); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_openpgp_oid_from_str (void)
|
||||||
|
{
|
||||||
|
static char *sample_oids[] =
|
||||||
|
{
|
||||||
|
"0.0",
|
||||||
|
"1.0",
|
||||||
|
"1.2.3",
|
||||||
|
"1.2.840.10045.3.1.7",
|
||||||
|
"1.3.132.0.34",
|
||||||
|
"1.3.132.0.35",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
gpg_error_t err;
|
||||||
|
gcry_mpi_t a;
|
||||||
|
int idx;
|
||||||
|
char *string;
|
||||||
|
unsigned char *p;
|
||||||
|
unsigned int nbits;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
err = openpgp_oid_from_str ("", &a);
|
||||||
|
if (gpg_err_code (err) != GPG_ERR_INV_VALUE)
|
||||||
|
fail (0, err);
|
||||||
|
gcry_mpi_release (a);
|
||||||
|
|
||||||
|
err = openpgp_oid_from_str (".", &a);
|
||||||
|
if (gpg_err_code (err) != GPG_ERR_INV_OID_STRING)
|
||||||
|
fail (0, err);
|
||||||
|
gcry_mpi_release (a);
|
||||||
|
|
||||||
|
err = openpgp_oid_from_str ("0", &a);
|
||||||
|
if (gpg_err_code (err) != GPG_ERR_INV_OID_STRING)
|
||||||
|
fail (0, err);
|
||||||
|
gcry_mpi_release (a);
|
||||||
|
|
||||||
|
for (idx=0; sample_oids[idx]; idx++)
|
||||||
|
{
|
||||||
|
err = openpgp_oid_from_str (sample_oids[idx], &a);
|
||||||
|
if (err)
|
||||||
|
fail (idx, err);
|
||||||
|
|
||||||
|
string = openpgp_oid_to_str (a);
|
||||||
|
if (!string)
|
||||||
|
fail (idx, gpg_error_from_syserror ());
|
||||||
|
if (strcmp (string, sample_oids[idx]))
|
||||||
|
fail (idx, 0);
|
||||||
|
xfree (string);
|
||||||
|
|
||||||
|
p = gcry_mpi_get_opaque (a, &nbits);
|
||||||
|
length = (nbits+7)/8;
|
||||||
|
if (!p || !length || p[0] != length - 1)
|
||||||
|
fail (idx, 0);
|
||||||
|
|
||||||
|
gcry_mpi_release (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_openpgp_oid_to_str (void)
|
||||||
|
{
|
||||||
|
static struct {
|
||||||
|
const char *string;
|
||||||
|
unsigned char der[10];
|
||||||
|
} samples[] = {
|
||||||
|
{ "1.2.840.10045.3.1.7",
|
||||||
|
{8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }},
|
||||||
|
|
||||||
|
{ "1.3.132.0.34",
|
||||||
|
{5, 0x2B, 0x81, 0x04, 0x00, 0x22 }},
|
||||||
|
|
||||||
|
{ "1.3.132.0.35",
|
||||||
|
{ 5, 0x2B, 0x81, 0x04, 0x00, 0x23 }},
|
||||||
|
|
||||||
|
{ NULL }};
|
||||||
|
gcry_mpi_t a;
|
||||||
|
int idx;
|
||||||
|
char *string;
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
for (idx=0; samples[idx].string; idx++)
|
||||||
|
{
|
||||||
|
p = xmalloc (samples[idx].der[0]+1);
|
||||||
|
memcpy (p, samples[idx].der, samples[idx].der[0]+1);
|
||||||
|
a = gcry_mpi_set_opaque (NULL, p, (samples[idx].der[0]+1)*8);
|
||||||
|
if (!a)
|
||||||
|
fail (idx, gpg_error_from_syserror ());
|
||||||
|
|
||||||
|
string = openpgp_oid_to_str (a);
|
||||||
|
if (!string)
|
||||||
|
fail (idx, gpg_error_from_syserror ());
|
||||||
|
if (strcmp (string, samples[idx].string))
|
||||||
|
fail (idx, 0);
|
||||||
|
xfree (string);
|
||||||
|
gcry_mpi_release (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
test_openpgp_oid_from_str ();
|
||||||
|
test_openpgp_oid_to_str ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -196,7 +196,6 @@ gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
|
|||||||
int hex2bin (const char *string, void *buffer, size_t length);
|
int hex2bin (const char *string, void *buffer, size_t length);
|
||||||
int hexcolon2bin (const char *string, void *buffer, size_t length);
|
int hexcolon2bin (const char *string, void *buffer, size_t length);
|
||||||
char *bin2hex (const void *buffer, size_t length, char *stringbuf);
|
char *bin2hex (const void *buffer, size_t length, char *stringbuf);
|
||||||
char *mpi2hex (gcry_mpi_t m);
|
|
||||||
char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
|
char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
|
||||||
const char *hex2str (const char *hexstring,
|
const char *hex2str (const char *hexstring,
|
||||||
char *buffer, size_t bufsize, size_t *buflen);
|
char *buffer, size_t bufsize, size_t *buflen);
|
||||||
@ -210,6 +209,11 @@ char *percent_unescape (const char *string, int nulrepl);
|
|||||||
size_t percent_plus_unescape_inplace (char *string, int nulrepl);
|
size_t percent_plus_unescape_inplace (char *string, int nulrepl);
|
||||||
size_t percent_unescape_inplace (char *string, int nulrepl);
|
size_t percent_unescape_inplace (char *string, int nulrepl);
|
||||||
|
|
||||||
|
/*-- openpgp-oid.c --*/
|
||||||
|
gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi);
|
||||||
|
char *openpgp_oid_to_str (gcry_mpi_t a);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-- homedir.c --*/
|
/*-- homedir.c --*/
|
||||||
const char *standard_homedir (void);
|
const char *standard_homedir (void);
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
2011-01-31 Werner Koch <wk@g10code.com>
|
2011-01-31 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* misc.c (make_flagged_int, openpgp_oid_from_str)
|
||||||
|
(openpgp_oid_to_str): Move to ../common/openpgp-oids.c.
|
||||||
|
|
||||||
* ecdh.c (pk_ecdh_encrypt_with_shared_point): Return an opaque MPI.
|
* ecdh.c (pk_ecdh_encrypt_with_shared_point): Return an opaque MPI.
|
||||||
|
|
||||||
* build-packet.c (mpi_write): Rename to gpg_mpi_write and make global.
|
* build-packet.c (mpi_write): Rename to gpg_mpi_write and make global.
|
||||||
|
@ -165,10 +165,6 @@ unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey );
|
|||||||
int mpi_print (estream_t stream, gcry_mpi_t a, int mode);
|
int mpi_print (estream_t stream, gcry_mpi_t a, int mode);
|
||||||
unsigned int ecdsa_qbits_from_Q (unsigned int qbits);
|
unsigned int ecdsa_qbits_from_Q (unsigned int qbits);
|
||||||
|
|
||||||
/* Other stuff */
|
|
||||||
gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi);
|
|
||||||
char *openpgp_oid_to_str (gcry_mpi_t a);
|
|
||||||
|
|
||||||
|
|
||||||
/*-- status.c --*/
|
/*-- status.c --*/
|
||||||
void set_status_fd ( int fd );
|
void set_status_fd ( int fd );
|
||||||
|
201
g10/misc.c
201
g10/misc.c
@ -1552,204 +1552,3 @@ ecdsa_qbits_from_Q (unsigned int qbits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper for openpgp_oid_from_str. */
|
|
||||||
static size_t
|
|
||||||
make_flagged_int (unsigned long value, char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
int more = 0;
|
|
||||||
int shift;
|
|
||||||
|
|
||||||
/* fixme: figure out the number of bits in an ulong and start with
|
|
||||||
that value as shift (after making it a multiple of 7) a more
|
|
||||||
straigtforward implementation is to do it in reverse order using
|
|
||||||
a temporary buffer - saves a lot of compares */
|
|
||||||
for (more=0, shift=28; shift > 0; shift -= 7)
|
|
||||||
{
|
|
||||||
if (more || value >= (1<<shift))
|
|
||||||
{
|
|
||||||
buf[buflen++] = 0x80 | (value >> shift);
|
|
||||||
value -= (value >> shift) << shift;
|
|
||||||
more = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf[buflen++] = value;
|
|
||||||
return buflen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Convert the OID given in dotted decimal form in STRING to an DER
|
|
||||||
* encoding and store it as an opaque value at R_MPI. The format of
|
|
||||||
* the DER encoded is not a regular ASN.1 object but the modified
|
|
||||||
* format as used by OpenPGP for the ECC curve description. On error
|
|
||||||
* the function returns and error code an NULL is stored at R_BUG.
|
|
||||||
* Note that scanning STRING stops at the first white space
|
|
||||||
* character. */
|
|
||||||
gpg_error_t
|
|
||||||
openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi)
|
|
||||||
{
|
|
||||||
unsigned char *buf;
|
|
||||||
size_t buflen;
|
|
||||||
unsigned long val1, val;
|
|
||||||
const char *endp;
|
|
||||||
int arcno;
|
|
||||||
|
|
||||||
*r_mpi = NULL;
|
|
||||||
|
|
||||||
if (!string || !*string)
|
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
|
||||||
|
|
||||||
/* We can safely assume that the encoded OID is shorter than the string. */
|
|
||||||
buf = xtrymalloc (1 + strlen (string) + 2);
|
|
||||||
if (!buf)
|
|
||||||
return gpg_error_from_syserror ();
|
|
||||||
/* Save the first byte for the length. */
|
|
||||||
buflen = 1;
|
|
||||||
|
|
||||||
val1 = 0; /* Avoid compiler warning. */
|
|
||||||
arcno = 0;
|
|
||||||
do {
|
|
||||||
arcno++;
|
|
||||||
val = strtoul (string, (char**)&endp, 10);
|
|
||||||
if (!digitp (string) || !(*endp == '.' || !*endp))
|
|
||||||
{
|
|
||||||
xfree (buf);
|
|
||||||
return gpg_error (GPG_ERR_INV_OID_STRING);
|
|
||||||
}
|
|
||||||
if (*endp == '.')
|
|
||||||
string = endp+1;
|
|
||||||
|
|
||||||
if (arcno == 1)
|
|
||||||
{
|
|
||||||
if (val > 2)
|
|
||||||
break; /* Not allowed, error catched below. */
|
|
||||||
val1 = val;
|
|
||||||
}
|
|
||||||
else if (arcno == 2)
|
|
||||||
{ /* Need to combine the first two arcs in one octet. */
|
|
||||||
if (val1 < 2)
|
|
||||||
{
|
|
||||||
if (val > 39)
|
|
||||||
{
|
|
||||||
xfree (buf);
|
|
||||||
return gpg_error (GPG_ERR_INV_OID_STRING);
|
|
||||||
}
|
|
||||||
buf[buflen++] = val1*40 + val;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val += 80;
|
|
||||||
buflen = make_flagged_int (val, buf, buflen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buflen = make_flagged_int (val, buf, buflen);
|
|
||||||
}
|
|
||||||
} while (*endp == '.');
|
|
||||||
|
|
||||||
if (arcno == 1 || buflen < 2 || buflen > 254 )
|
|
||||||
{ /* It is not possible to encode only the first arc. */
|
|
||||||
xfree (buf);
|
|
||||||
return gpg_error (GPG_ERR_INV_OID_STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf = buflen - 1;
|
|
||||||
*r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8);
|
|
||||||
if (!*r_mpi)
|
|
||||||
{
|
|
||||||
xfree (buf);
|
|
||||||
return gpg_error_from_syserror ();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return a malloced string represenation of the OID in the opaque MPI
|
|
||||||
A. In case of an error NULL is returned and ERRNO is set. */
|
|
||||||
char *
|
|
||||||
openpgp_oid_to_str (gcry_mpi_t a)
|
|
||||||
{
|
|
||||||
const unsigned char *buf;
|
|
||||||
size_t length;
|
|
||||||
char *string, *p;
|
|
||||||
int n = 0;
|
|
||||||
unsigned long val, valmask;
|
|
||||||
|
|
||||||
valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1));
|
|
||||||
|
|
||||||
if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
|
|
||||||
{
|
|
||||||
gpg_err_set_errno (EINVAL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = gcry_mpi_get_opaque (a, &length);
|
|
||||||
length = (length+7)/8;
|
|
||||||
|
|
||||||
/* The first bytes gives the length; check consistency. */
|
|
||||||
if (!length || buf[0] != length -1)
|
|
||||||
{
|
|
||||||
gpg_err_set_errno (EINVAL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* Skip length byte. */
|
|
||||||
length--;
|
|
||||||
buf++;
|
|
||||||
|
|
||||||
/* To calculate the length of the string we can safely assume an
|
|
||||||
upper limit of 3 decimal characters per byte. Two extra bytes
|
|
||||||
account for the special first octect */
|
|
||||||
string = p = xtrymalloc (length*(1+3)+2+1);
|
|
||||||
if (!string)
|
|
||||||
return NULL;
|
|
||||||
if (!buf || !length)
|
|
||||||
{
|
|
||||||
*p = 0;
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[0] < 40)
|
|
||||||
p += sprintf (p, "0.%d", buf[n]);
|
|
||||||
else if (buf[0] < 80)
|
|
||||||
p += sprintf (p, "1.%d", buf[n]-40);
|
|
||||||
else {
|
|
||||||
val = buf[n] & 0x7f;
|
|
||||||
while ( (buf[n]&0x80) && ++n < length )
|
|
||||||
{
|
|
||||||
if ( (val & valmask) )
|
|
||||||
goto badoid; /* Overflow. */
|
|
||||||
val <<= 7;
|
|
||||||
val |= buf[n] & 0x7f;
|
|
||||||
}
|
|
||||||
val -= 80;
|
|
||||||
sprintf (p, "2.%lu", val);
|
|
||||||
p += strlen (p);
|
|
||||||
}
|
|
||||||
for (n++; n < length; n++)
|
|
||||||
{
|
|
||||||
val = buf[n] & 0x7f;
|
|
||||||
while ( (buf[n]&0x80) && ++n < length )
|
|
||||||
{
|
|
||||||
if ( (val & valmask) )
|
|
||||||
goto badoid; /* Overflow. */
|
|
||||||
val <<= 7;
|
|
||||||
val |= buf[n] & 0x7f;
|
|
||||||
}
|
|
||||||
sprintf (p, ".%lu", val);
|
|
||||||
p += strlen (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
*p = 0;
|
|
||||||
return string;
|
|
||||||
|
|
||||||
badoid:
|
|
||||||
/* Return a special OID (gnu.gnupg.badoid) to indicate the error
|
|
||||||
case. The OID is broken and thus we return one which can't do
|
|
||||||
any harm. Formally this does not need to be a bad OID but an OID
|
|
||||||
with an arc that can't be represented in a 32 bit word is more
|
|
||||||
than likely corrupt. */
|
|
||||||
xfree (string);
|
|
||||||
return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ const void *find_tuple (tupledesc_t tupledesc,
|
|||||||
unsigned int tag, size_t *r_length);
|
unsigned int tag, size_t *r_length);
|
||||||
const void *next_tuple (tupledesc_t tupledesc,
|
const void *next_tuple (tupledesc_t tupledesc,
|
||||||
unsigned int *r_tag, size_t *r_length);
|
unsigned int *r_tag, size_t *r_length);
|
||||||
char *mpi2hex( gcry_mpi_t m );
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*G13_UTILS_H*/
|
#endif /*G13_UTILS_H*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user