summaryrefslogtreecommitdiff
path: root/src/sexp.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2007-04-18 12:59:00 +0000
committerWerner Koch <wk@gnupg.org>2007-04-18 12:59:00 +0000
commitf4598e52aeb88c1c7511d6ec106c285c096c8ed2 (patch)
tree7abc3a8711facf8fac5375206c4b30f0ee35ee61 /src/sexp.c
parent591697fc7621e8aa16abb3f60dc297ea9af1048f (diff)
downloadlibgcrypt-f4598e52aeb88c1c7511d6ec106c285c096c8ed2.tar.gz
Enhanced support for ECDSA.
Along with the latest libksba it is now possible for gpgsm to import an ECC certificate.
Diffstat (limited to 'src/sexp.c')
-rw-r--r--src/sexp.c183
1 files changed, 95 insertions, 88 deletions
diff --git a/src/sexp.c b/src/sexp.c
index dab2b548..e88d12c1 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -1,6 +1,6 @@
/* sexp.c - S-Expression handling
* Copyright (C) 1999, 2000, 2001, 2002, 2003,
- * 2004, 2006 Free Software Foundation, Inc.
+ * 2004, 2006, 2007 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -582,116 +582,123 @@ gcry_sexp_car( const gcry_sexp_t list )
return gcry_sexp_nth ( list, 0 );
}
-/****************
- * Get data from the car. The returned value is valid as long as the list
- * is not modified.
- */
-const char *
-gcry_sexp_nth_data( const gcry_sexp_t list, int number, size_t *datalen )
+
+/* Helper to get data from the car. The returned value is valid as
+ long as the list is not modified. */
+static const char *
+sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
{
- const byte *p;
- DATALEN n;
- int level = 0;
+ const byte *p;
+ DATALEN n;
+ int level = 0;
+
+ *datalen = 0;
+ if ( !list )
+ return NULL;
- *datalen = 0;
- if ( !list ) {
- return NULL;
- }
- p = list->d;
- if ( *p == ST_OPEN )
- p++; /* yep, a list */
- else if (number )
- return NULL; /* not a list but an n > 0 element requested */
+ p = list->d;
+ if ( *p == ST_OPEN )
+ p++; /* Yep, a list. */
+ else if (number)
+ return NULL; /* Not a list but N > 0 requested. */
- /* skip n elements */
- while ( number > 0 ) {
- if ( *p == ST_DATA ) {
- memcpy ( &n, ++p, sizeof n );
- p += sizeof n + n;
- p--;
- if ( !level )
- number--;
+ /* Skip over N elements. */
+ while ( number > 0 )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
}
- else if ( *p == ST_OPEN ) {
- level++;
+ else if ( *p == ST_OPEN )
+ {
+ level++;
}
- else if ( *p == ST_CLOSE ) {
- level--;
- if ( !level )
- number--;
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ if ( !level )
+ number--;
}
- else if ( *p == ST_STOP ) {
- return NULL;
+ else if ( *p == ST_STOP )
+ {
+ return NULL;
}
- p++;
+ p++;
}
-
- if ( *p == ST_DATA ) {
- memcpy ( &n, ++p, sizeof n );
- *datalen = n;
- return (const char*)p + sizeof n;
+ /* If this is data, return it. */
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ *datalen = n;
+ return (const char*)p + sizeof n;
}
+
+ return NULL;
+}
+
+/* Get data from the car. The returned value is valid as long as the
+ list is not modified. */
+const char *
+gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
+{
+ return sexp_nth_data (list, number, datalen);
+}
+
+
+/* Get a string from the car. The returned value is a malloced string
+ and needs to be freed by the caller. */
+char *
+_gcry_sexp_nth_string (const gcry_sexp_t list, int number)
+{
+ const char *s;
+ size_t n;
+ char *buf;
+
+ s = sexp_nth_data (list, number, &n);
+ if (!s || n < 1 || (n+1) < 1)
+ return NULL;
+ buf = gcry_malloc (n+1);
+ if (!buf)
return NULL;
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ return buf;
}
-/****************
+/* Public version of _gcry_sexp_nth_string. */
+char *
+gcry_sexp_nth_string (const gcry_sexp_t list, int number)
+{
+ return _gcry_sexp_nth_string (list, number);
+}
+
+/*
* Get a MPI from the car
*/
gcry_mpi_t
gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
{
- const byte *p;
- DATALEN n;
- int level = 0;
-
- if ( !list )
- return NULL;
- if ( !mpifmt )
- mpifmt = GCRYMPI_FMT_STD;
+ const char *s;
+ size_t n;
+ gcry_mpi_t a;
- p = list->d;
- if ( *p == ST_OPEN )
- p++; /* yep, a list */
- else if (number )
- return NULL; /* not a list but an n > 0 element requested */
+ if ( !mpifmt )
+ mpifmt = GCRYMPI_FMT_STD;
- /* skip n elements */
- while ( number > 0 ) {
- if ( *p == ST_DATA ) {
- memcpy ( &n, ++p, sizeof n );
- p += sizeof n + n;
- p--;
- if ( !level )
- number--;
- }
- else if ( *p == ST_OPEN ) {
- level++;
- }
- else if ( *p == ST_CLOSE ) {
- level--;
- if ( !level )
- number--;
- }
- else if ( *p == ST_STOP ) {
- return NULL;
- }
- p++;
- }
-
- if ( *p == ST_DATA ) {
- gcry_mpi_t a;
- size_t nbytes;
-
- memcpy ( &n, ++p, sizeof n );
- p += sizeof n;
- nbytes = n;
- if( !gcry_mpi_scan( &a, mpifmt, p, n, &nbytes ) )
- return a;
- }
+ s = sexp_nth_data (list, number, &n);
+ if (!s)
+ return NULL;
+ if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
return NULL;
+
+ return a;
}