Dear Maintainer,

I've wrote and tested the attached patches. They seem seem to resolve this
issue. They also add infrastructure to make it easier to add support for
different signing algorithms.
diff --git a/src/util/simplelog.c b/src/util/simplelog.c
index 07191d9..5bed40d 100644
--- a/src/util/simplelog.c
+++ b/src/util/simplelog.c
@@ -228,7 +228,7 @@ static gpg_error_t
 internal_log_write (log_handle_t handle, log_level_t level,
 		    const char *fmt, va_list ap)
 {
-  gpg_error_t err;
+  gpg_error_t err = 0;
 
   assert (handle->backend != LOG_BACKEND_NONE);
 
@@ -270,7 +270,6 @@ internal_log_write (log_handle_t handle, log_level_t level,
 	}
 	  
       vsyslog (LOG_MAKEPRI (LOG_AUTH, syslog_priority), fmt, ap);
-      err = 0;
     }
   else if (handle->backend == LOG_BACKEND_STREAM
 	   || handle->backend == LOG_BACKEND_FILE)
@@ -314,7 +313,6 @@ internal_log_write (log_handle_t handle, log_level_t level,
       vfprintf (stream, fmt, ap);
       putc ('\n', stream);
 
-      err = 0;
     }
 
   return err;
diff --git a/src/pam/auth-method-localdb/Makefile.am b/src/pam/auth-method-localdb/Makefile.am
index c033f16..ac528b0 100644
--- a/src/pam/auth-method-localdb/Makefile.am
+++ b/src/pam/auth-method-localdb/Makefile.am
@@ -11,7 +11,7 @@
 # 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, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
diff --git a/src/pam/auth-method-localdb/auth-localdb.c b/src/pam/auth-method-localdb/auth-localdb.c
index d73808d..f9041f7 100644
--- a/src/pam/auth-method-localdb/auth-localdb.c
+++ b/src/pam/auth-method-localdb/auth-localdb.c
@@ -1,18 +1,18 @@
 /* auth-localdb.c - localdb authentication method for Poldi.
    Copyright (C) 2004, 2005, 2007, 2008, 2009 g10 Code GmbH
- 
+
    This file is part of Poldi.
- 
+
    Poldi 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.
- 
+
    Poldi 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/>.  */
@@ -33,15 +33,17 @@
 
 #include "scd/scd.h"
 #include "util/support.h"
+#include "util/key-types.h"
+#include "util/debugTools.h"
 #include "auth-support/ctx.h"
 #include "auth-support/wait-for-card.h"
 
 #include "usersdb.h"
 #include "key-lookup.h"
 
-
 
 #if 0
+
 /* Currently, the localdb method doesn't require a special cookie. */
 
 static gpg_error_t
@@ -79,6 +81,7 @@ auth_method_localdb_auth_do (poldi_ctx_t ctx,
   size_t challenge_n;
   size_t response_n;
   gcry_sexp_t key;
+  key_types key_type;
   gpg_error_t err;
   char *card_username;
   const char *username;
@@ -143,8 +146,24 @@ auth_method_localdb_auth_do (poldi_ctx_t ctx,
   if (err)
     goto out;
 
+  /* Retrieve key type */
+  err = get_key_type(&key_type, key);
+  if(err) {
+    //unsupported crypto
+    log_msg_error (ctx->loghandle,
+       "Unsupported Key Type\n");
+
+       goto out;
+     }
+  /*Print out key type if debug is enabled */
+  if (ctx->debug) {
+    log_msg_debug (ctx->loghandle,
+       "Key Type "
+       "`%s'", key_type_to_str(key_type));
+  }
+
   /* Generate challenge.  */
-  err = challenge_generate (&challenge, &challenge_n);
+  err = challenge_generate (&challenge, &challenge_n, key_type);
   if (err)
     {
       log_msg_error (ctx->loghandle,
@@ -154,7 +173,7 @@ auth_method_localdb_auth_do (poldi_ctx_t ctx,
     }
 
   /* Let card sign the challenge.  */
-  err = scd_pksign (ctx->scd, "OPENPGP.3",
+  err = scd_pksign (ctx->scd, "OPENPGP.3", key_type,
 		    challenge, challenge_n,
 		    &response, &response_n);
   if (err)
@@ -165,8 +184,47 @@ auth_method_localdb_auth_do (poldi_ctx_t ctx,
       goto out;
     }
 
+  /*DEBUG LOG S Expressions */
+  if (ctx->debug) {
+    char outBuff[4096];
+    gcry_sexp_t sexp_signature = NULL;
+
+    switch (key_type)
+    {
+      case kType_rsa:
+      err = gcry_sexp_build (&sexp_signature, NULL, "(sig-val(rsa(s%b)))",
+           response_n,response);
+        break;
+
+      case kType_ecc_Ed25519:
+      err = gcry_sexp_build (&sexp_signature, NULL, "(sig-val(eddsa(r%b)(s%b)))",
+                             (int)response_n/2, response,
+                             (int)response_n/2, response + response_n/2);
+        break;
+
+      default:
+        err = GPG_ERR_CONFIGURATION;
+    }//switch
+    //log public key
+    //log_msg_debug(ctx->loghandle, "%s","Public_KEY");
+    outBuff[0] = 0;
+    sprintSEXP_Ed25519(key, outBuff, 4096);
+    log_msg_debug(ctx->loghandle, "Public_KEY: %s",outBuff);
+    outBuff[0] = 0;
+
+    //log Signature
+    //log_msg_debug(ctx->loghandle, "%s","Signature");
+    sprintSEXP_Ed25519(sexp_signature, outBuff, 4096);
+    log_msg_debug(ctx->loghandle, "Signature: %s",outBuff);
+    outBuff[0] = 0;
+
+    //free resources
+    gcry_sexp_release(sexp_signature);
+
+  }//if debug
+
   /* Verify response.  */
-  err = challenge_verify (key, challenge, challenge_n, response, response_n);
+  err = challenge_verify (key, key_type, challenge, challenge_n, response, response_n);
   if (err)
     {
       log_msg_error (ctx->loghandle, "failed to verify challenge");
diff --git a/src/pam/auth-method-localdb/key-lookup.c b/src/pam/auth-method-localdb/key-lookup.c
index 20fce4a..708148a 100644
--- a/src/pam/auth-method-localdb/key-lookup.c
+++ b/src/pam/auth-method-localdb/key-lookup.c
@@ -1,22 +1,22 @@
 /* key-lookup.c - Lookup keys for localdb authentication
    Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
- 
+
    This file is part of Poldi.
- 
+
    Poldi 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.
- 
+
    Poldi 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 <poldi.h>
 
 #include <unistd.h>
@@ -28,11 +28,11 @@
 
 #include "util/support.h"
 #include "util/filenames.h"
+#include "util/key-types.h"
 #include "key-lookup.h"
 #include "defs-localdb.h"
 
 
-
 /* This functions construct a new C-string containing the absolute
    path for the file, which is to expected to contain the public key
    for the card identified by SERIALNO.  Returns proper error
@@ -97,4 +97,6 @@ key_lookup_by_serialno (poldi_ctx_t ctx, const char *serialno, gcry_sexp_t *key)
   return err;
 }
 
+
+
 
diff --git a/src/pam/auth-method-localdb/key-lookup.h b/src/pam/auth-method-localdb/key-lookup.h
index a36615d..bae3834 100644
--- a/src/pam/auth-method-localdb/key-lookup.h
+++ b/src/pam/auth-method-localdb/key-lookup.h
@@ -1,18 +1,18 @@
 /* key-lookup.c - Lookup keys for localdb authentication
    Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
- 
+
    This file is part of Poldi.
- 
+
    Poldi 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.
- 
+
    Poldi 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/>.  */
diff --git a/src/pam/auth-method-x509/auth-x509.c b/src/pam/auth-method-x509/auth-x509.c
index fafdc9e..ea8c756 100644
--- a/src/pam/auth-method-x509/auth-x509.c
+++ b/src/pam/auth-method-x509/auth-x509.c
@@ -38,7 +38,7 @@
 #include "util/defs.h"
 #include "util/simplelog.h"
 #include "util/simpleparse.h"
-
+#include "util/key-types.h"
 
 
 struct x509_ctx_s
@@ -198,6 +198,7 @@ verify_challenge_sig (poldi_ctx_t ctx, ksba_cert_t cert,
 {
   gcry_sexp_t pubkey;
   gpg_error_t err;
+  key_types key_type = kType_rsa;
 
   pubkey = NULL;
 
@@ -205,7 +206,7 @@ verify_challenge_sig (poldi_ctx_t ctx, ksba_cert_t cert,
   if (err)
     goto out;
 
-  err = challenge_verify (pubkey, challenge, challenge_n,
+  err = challenge_verify (pubkey, key_type, challenge, challenge_n,
 			  response, response_n);
 
  out:
@@ -472,6 +473,7 @@ auth_method_x509_auth_do (poldi_ctx_t ctx, x509_ctx_t cookie,
   char *card_username;
   ksba_cert_t cert;
   dirmngr_ctx_t dirmngr;
+  key_types key_type;
 
   dirmngr = NULL;
   challenge = NULL;
@@ -544,8 +546,8 @@ auth_method_x509_auth_do (poldi_ctx_t ctx, x509_ctx_t cookie,
     }
 
   /*** Generate challenge. ***/
-
-  err = challenge_generate (&challenge, &challenge_n);
+  key_type = kType_rsa;
+  err = challenge_generate (&challenge, &challenge_n, key_type);
   if (err)
     {
       log_msg_error (ctx->loghandle, "failed to generate challenge: %s",
@@ -554,7 +556,7 @@ auth_method_x509_auth_do (poldi_ctx_t ctx, x509_ctx_t cookie,
     }
 
   /*** Let card sign the challenge. ***/
-  err = scd_pksign (ctx->scd, "OPENPGP.3",
+  err = scd_pksign (ctx->scd, "OPENPGP.3", key_type, 
 		    challenge, challenge_n,
 		    &response, &response_n);
   if (err)
diff --git a/src/scd/scd.c b/src/scd/scd.c
index 5d1b835..7a6c62d 100644
--- a/src/scd/scd.c
+++ b/src/scd/scd.c
@@ -1,19 +1,19 @@
 /* scd.c - Interface to Scdaemon
    Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
-   Copyright (C) 2007, 2008, 2009 g10code GmbH. 
+   Copyright (C) 2007, 2008, 2009 g10code GmbH.
 
    This file is part of Poldi.
- 
+
    Poldi 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.
- 
+
    Poldi 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/>.  */
@@ -75,7 +75,7 @@ struct learn_parm_s
   void *sinfo_cb_arg;
 };
 
-struct inq_needpin_s 
+struct inq_needpin_s
 {
   scd_context_t ctx;
   int (*getpin_cb)(void *, const char *, char*, size_t);
@@ -375,7 +375,7 @@ unescape_status_string (const char *s)
   while (*s)
     {
       if (*s == '%' && s[1] && s[2])
-        { 
+        {
           s++;
           *d = xtoi_2 (s);
           if (!*d)
@@ -391,7 +391,7 @@ unescape_status_string (const char *s)
       else
         *d++ = *s++;
     }
-  *d = 0; 
+  *d = 0;
   return buffer;
 }
 
@@ -490,7 +490,7 @@ learn_status_cb (void *opaque, const char *line)
       else if (no == 3)
         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
     }
-  
+
   return 0;
 }
 
@@ -605,7 +605,7 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
     put_membuf (data, buffer, length);
   return 0;
 }
-  
+
 /* Handle the NEEDPIN inquiry. */
 static int
 inq_needpin (void *opaque, const char *line)
@@ -628,7 +628,7 @@ inq_needpin (void *opaque, const char *line)
       line += 7;
       while (*line == ' ')
         line++;
-      
+
       pinlen = 90;
       pin = xtrymalloc_secure (pinlen);
       if (!pin)
@@ -654,7 +654,7 @@ inq_needpin (void *opaque, const char *line)
       line += 17;
       while (*line == ' ')
         line++;
-      
+
       rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
     }
   else if (!strncmp (line, "DISMISSPINPADPROMPT", 19)
@@ -688,11 +688,12 @@ inq_needpin (void *opaque, const char *line)
    the PIN, GETPIN_CB_ARG is passed as opaque argument to
    GETPIN_CB. INDATA/INDATALEN is the input for the signature
    function.  The signature created is written into newly allocated
-   memory in *R_BUF, *R_BUFLEN will hold the length of the
+   memory in *R_BUF, *S_BUF, *R_BUFLEN, S_BUFLEN will hold the length of the
    signature. */
 gpg_error_t
 scd_pksign (scd_context_t ctx,
 	    const char *keyid,
+      key_types key_type,
 	    const unsigned char *indata, size_t indatalen,
 	    unsigned char **r_buf, size_t *r_buflen)
 {
@@ -703,6 +704,7 @@ scd_pksign (scd_context_t ctx,
   size_t len;
   unsigned char *sigbuf;
   size_t sigbuflen;
+  const char * hashAlgo;
 
   *r_buf = NULL;
   *r_buflen = 0;
@@ -735,9 +737,25 @@ scd_pksign (scd_context_t ctx,
   inqparm.getpin_cb = ctx->pincb;
   inqparm.getpin_cb_arg = ctx->pincb_cookie;
 
-  /* Go, sign it. */
 
-  snprintf (line, DIM(line)-1, "PKSIGN %s", keyid);
+  //set hash type based on
+  switch (key_type)
+  {
+    case kType_rsa:
+      hashAlgo = "--hash=sha256";
+      break;
+
+    case kType_ecc_Ed25519:
+      hashAlgo = "";//default is sha512, setting that here causes scd to generate an invalid SIG
+      break;
+
+    default:
+      rc = -1;
+      goto out;
+  }//switch
+
+  /* Go, sign it. */
+  snprintf (line, DIM(line)-1, "PKSIGN %s %s",hashAlgo, keyid);
   line[DIM(line)-1] = 0;
   rc = assuan_transact (ctx->assuan_ctx, line,
                         membuf_data_cb, &data,
@@ -760,7 +778,7 @@ scd_pksign (scd_context_t ctx,
     }
 
   memcpy (p, sigbuf, sigbuflen);
-  
+
  out:
 
   xfree (get_membuf (&data, &len));
@@ -816,7 +834,7 @@ scd_readkey (scd_context_t ctx,
  out:
 
   xfree (buffer);
-    
+
   return rc;
 }
 
diff --git a/src/scd/scd.h b/src/scd/scd.h
index 8910497..f85c751 100644
--- a/src/scd/scd.h
+++ b/src/scd/scd.h
@@ -1,18 +1,18 @@
 /* scd.h - Interface to Scdaemon
-   Copyright (C) 2007, 2008, 2009 g10code GmbH. 
+   Copyright (C) 2007, 2008, 2009 g10code GmbH.
 
    This file is part of Poldi.
- 
+
    Poldi 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.
- 
+
    Poldi 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/>.  */
@@ -23,6 +23,7 @@
 #include <poldi.h>
 
 #include "util/simplelog.h"
+#include "util/key-types.h"
 
 struct scd_context;
 
@@ -81,6 +82,7 @@ void scd_release_cardinfo (struct scd_cardinfo cardinfo);
    *R_BUF, *R_BUFLEN will hold the length of the signature. */
 gpg_error_t scd_pksign (scd_context_t ctx,
 			const char *keyid,
+      key_types key_type,
 			const unsigned char *indata, size_t indatalen,
 			unsigned char **r_buf, size_t *r_buflen);
 
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 72cf95e..6f2e93d 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -11,7 +11,7 @@
 # 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, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -31,7 +31,9 @@ poldi_util_SOURCES = \
 	convert.c \
 	simplelog.c simplelog.h \
 	simpleparse.c simpleparse.h \
-	filenames.c filenames.h
+	filenames.c filenames.h \
+	key-types.c key-types.h \
+	debugTools.c debugTools.h
 
 poldi_util_CFLAGS = \
 	-Wall \
diff --git a/src/util/debugTools.c b/src/util/debugTools.c
new file mode 100644
index 0000000..6269909
--- /dev/null
+++ b/src/util/debugTools.c
@@ -0,0 +1,95 @@
+#include "debugTools.h"
+#include <string.h>
+
+void sprintSEXP_Ed25519(gcry_sexp_t in, char *rt, size_t strSize)
+{
+  size_t rsaBuff_n;
+  char *rsaBuff;
+  char btmpStr[10];
+  char tmpStr[10];
+
+  //allocate buffer memory
+  rsaBuff_n = gcry_sexp_sprint(in, GCRYSEXP_FMT_CANON, NULL, 0);
+  rsaBuff = calloc(1, rsaBuff_n);
+  if(!rsaBuff){printf("Error Allocating Dynamic Memory\n");}
+  //printf("Buffer Size: %zu\n", rsaBuff_n);
+  gcry_sexp_sprint(in, GCRYSEXP_FMT_CANON, rsaBuff, rsaBuff_n);
+
+  int k = 0;
+  char strByteSize[10];
+  int byteSize = 0;
+  int val;
+
+  for(int i=0; i != rsaBuff_n; i++) {
+    if(rsaBuff[i] == '1')
+      {
+	k = i + 1;
+	strByteSize[0] = 0;
+	byteSize = 0;
+
+	if(k <= rsaBuff_n)
+	  {
+	  if(rsaBuff[k] == ':')
+	  {
+	    //read 1
+	    addCToStr(rsaBuff[i], rt, strSize);
+	    i++;
+
+	    //read :
+	    addCToStr(rsaBuff[i], rt, strSize);
+	    i++;
+
+	    //read control char
+	    addCToStr(rsaBuff[i], rt, strSize);
+	    i++;
+
+	    //read in byte size :
+	    while(rsaBuff[i] != ':')
+	    {
+	      addCToStr(rsaBuff[i], strByteSize, 10);
+	      addCToStr(rsaBuff[i], rt, strSize);
+	      i++;
+	    }//while
+
+	    byteSize = atoi(strByteSize);
+
+	    //read in second :
+	    addCToStr(rsaBuff[i], rt, strSize);
+	    i++;
+
+	    //iterate through each byte
+	    for(int j=0; j != byteSize; j++) {
+
+	      val = (unsigned char)rsaBuff[i];
+	      sprintf(tmpStr,"%X",val);
+
+	      //need traling zero
+	      if(strlen(tmpStr) < 2) {
+		strcpy(btmpStr, tmpStr);
+
+		tmpStr[0]='0';
+		tmpStr[1]=0;
+		strcat(tmpStr,btmpStr);
+	      }
+	      strcat(rt, tmpStr);
+	      i++;
+	       }//for
+       }//if
+     }//if
+   }//if key type
+
+    addCToStr(rsaBuff[i], rt, strSize);
+  }//for
+}//sprintSEXP_Ed25519
+
+
+
+void addCToStr(char c, char *in, size_t maxStrLn)
+{
+  int endOfStr = strlen(in);
+  if(endOfStr+1 >= maxStrLn){return;}
+
+  in[endOfStr] = c;
+  endOfStr++;
+  in[endOfStr] = 0;
+}
diff --git a/src/util/debugTools.h b/src/util/debugTools.h
new file mode 100644
index 0000000..dd0d171
--- /dev/null
+++ b/src/util/debugTools.h
@@ -0,0 +1,8 @@
+#include <gcrypt.h>
+#ifndef DEBUGTOOLS_H
+#define DEBUGTOOLS_H
+
+void sprintSEXP_Ed25519(gcry_sexp_t in, char *rt, size_t strSize);
+void addCToStr(char c, char *in, size_t maxStrLn);
+
+#endif
diff --git a/src/util/key-types.c b/src/util/key-types.c
new file mode 100644
index 0000000..31ad47b
--- /dev/null
+++ b/src/util/key-types.c
@@ -0,0 +1,69 @@
+#include "key-types.h"
+
+/* Lookup key type ex, rsa, ecc, returns 1 on error and 0 otherwise
+   Currenly Only Supporting rsa and ed25519*/
+int get_key_type(key_types *key_type, gcry_sexp_t key) {
+  int err = 0;
+  size_t strCnt = 0;
+  size_t maxBuffSize = 4098;
+  char strbuff[maxBuffSize];
+  char *token;
+
+  if(key == NULL) {
+    return 1;
+  }//if
+
+  strCnt = gcry_sexp_sprint(key, GCRYSEXP_FMT_DEFAULT, strbuff, maxBuffSize);
+  if(strCnt == 0) {
+    return 1;
+  }//if
+
+
+  //parse key type from S Expression
+  token = strtok(strbuff, "\n");
+  token = strtok(NULL, ":");
+  token = strtok(NULL, "\n");
+
+  //if rsa key
+  err = strcmp(token, "rsa");
+  if(err == 0)
+  {
+    *key_type = kType_rsa;
+    return 0;
+  }//if
+
+  //if ecc key
+  err = strcmp(token, "ecc");
+  if(err == 0)
+  {
+    //get flag type
+    token = strtok(NULL, "\n");
+    token = strtok(NULL, ":");
+    token = strtok(NULL, ":");
+    token = strtok(NULL, ")");
+
+    err = strcmp(token, "eddsa");
+    if(err == 0)
+    {
+      *key_type = kType_ecc_Ed25519;
+      return 0;
+    }//if
+
+  }//if
+
+
+  return 1;
+}//key_type
+
+/* Returns the String Value of the key type
+   Returns Empty String on error*/
+const char* key_type_to_str(key_types key_type)
+{
+  switch (key_type)
+  {
+    case kType_rsa: return "rsa";
+    case kType_ecc_Ed25519: return "Ed25519";
+  }
+
+  return "";
+}
diff --git a/src/util/key-types.h b/src/util/key-types.h
new file mode 100644
index 0000000..8b30e5e
--- /dev/null
+++ b/src/util/key-types.h
@@ -0,0 +1,15 @@
+
+#include <gcrypt.h>
+
+#ifndef KEY_TYPES_H
+#define KEY_TYPES_H
+
+typedef enum{kType_rsa, kType_ecc_Ed25519} key_types;
+
+/* Get Key Type*/
+int get_key_type(key_types *key_type, gcry_sexp_t key);
+
+/* returns key type string value*/
+const char* key_type_to_str(key_types key_type);
+
+#endif
diff --git a/src/util/support.c b/src/util/support.c
index 8e576c6..3e7c358 100644
--- a/src/util/support.c
+++ b/src/util/support.c
@@ -1,18 +1,18 @@
 /* support.c - PAM authentication via OpenPGP smartcards.
    Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
- 
+
    This file is part of Poldi.
-  
+
    Poldi 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 2 of the License, or
    (at your option) any later version.
-  
+
    Poldi 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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -38,7 +38,7 @@
 #include "support.h"
 #include "defs.h"
 
-#define CHALLENGE_MD_ALGORITHM GCRY_MD_SHA1
+
 
 
 
@@ -50,11 +50,23 @@
    it's length in bytes is to be stored in *CHALLENGE_N.  Returns
    proper error code.  */
 gpg_error_t
-challenge_generate (unsigned char **challenge, size_t *challenge_n)
+challenge_generate (unsigned char **challenge, size_t *challenge_n, key_types key_type)
 {
   gpg_error_t err = GPG_ERR_NO_ERROR;
   unsigned char *challenge_new = NULL;
-  size_t challenge_new_n = gcry_md_get_algo_dlen (CHALLENGE_MD_ALGORITHM);
+  size_t challenge_new_n = 0; //gcry_md_get_algo_dlen (CHALLENGE_MD_ALGORITHM);
+
+  //determine challange size based on hashing algorithm
+  switch (key_type)
+  {
+    case kType_rsa:
+      challenge_new_n = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
+      break;
+
+    case kType_ecc_Ed25519:
+      challenge_new_n = gcry_md_get_algo_dlen (GCRY_MD_SHA512);
+      break;
+  }//switch
 
   challenge_new = xtrymalloc (challenge_new_n);
   if (! challenge_new)
@@ -79,31 +91,58 @@ challenge_release (unsigned char *challenge)
 }
 
 static gpg_error_t
-challenge_verify_sexp (gcry_sexp_t sexp_key,
+challenge_verify_sexp (gcry_sexp_t sexp_key, key_types key_type,
 		       unsigned char *challenge, size_t challenge_n,
 		       unsigned char *response, size_t response_n)
 {
   gpg_error_t err = GPG_ERR_NO_ERROR;
   gcry_sexp_t sexp_signature = NULL;
   gcry_sexp_t sexp_data = NULL;
-  gcry_mpi_t mpi_signature = NULL;
 
-  /* Convert buffers into MPIs.  */
-  if (! err)
+  /* Create according S-Expressions.  */
+  if (! err) {
+    //set data hash type based on key type
+    switch (key_type)
     {
-      if (gcry_mpi_scan (&mpi_signature, GCRYMPI_FMT_USG, response, response_n,
-			 NULL))
-	err = gpg_error (GPG_ERR_BAD_MPI);
-    }
+      case kType_rsa:
+        err = gcry_sexp_build (&sexp_data, NULL,
+             "(data (flags pkcs1) (hash sha256 %b))",
+             challenge_n, challenge);
+        break;
+
+      case kType_ecc_Ed25519:
+        err = gcry_sexp_build (&sexp_data, NULL,
+             "(data(flags eddsa)(hash-algo sha512)(value %b))",
+             challenge_n, challenge);
+        break;
+
+      default:
+        err = GPG_ERR_CONFIGURATION;
+    }//switch
+
+
+       }
+
+  if (! err) {
+      //set sig value based on key type key type
+      switch (key_type)
+      {
+        case kType_rsa:
+        err = gcry_sexp_build (&sexp_signature, NULL, "(sig-val(rsa(s%b)))",
+             response_n,response);
+          break;
+
+        case kType_ecc_Ed25519:
+        err = gcry_sexp_build (&sexp_signature, NULL, "(sig-val(eddsa(r%b)(s%b)))",
+                               response_n/2, response,
+                               response_n/2, response + response_n/2);
+          break;
+
+        default:
+          err = GPG_ERR_CONFIGURATION;
+      }//switch
 
-  /* Create according S-Expressions.  */
-  if (! err)
-    err = gcry_sexp_build (&sexp_data, NULL,
-			   "(data (flags pkcs1) (hash sha1 %b))",
-			   challenge_n, challenge);
-  if (! err)
-    err = gcry_sexp_build (&sexp_signature, NULL, "(sig-val (rsa (s %m)))",
-			   mpi_signature);
+    }
 
   /* Verify.  */
   if (! err)
@@ -113,8 +152,6 @@ challenge_verify_sexp (gcry_sexp_t sexp_key,
     gcry_sexp_release (sexp_data);
   if (sexp_signature)
     gcry_sexp_release (sexp_signature);
-  if (mpi_signature)
-    gcry_mpi_release (mpi_signature);
 
   return err;
 }
@@ -125,13 +162,13 @@ challenge_verify_sexp (gcry_sexp_t sexp_key,
    the secret key belonging to the public key given as PUBLIC_KEY.
    Returns proper error code.  */
 gpg_error_t
-challenge_verify (gcry_sexp_t public_key,
+challenge_verify (gcry_sexp_t public_key, key_types key_type,
 		  unsigned char *challenge, size_t challenge_n,
 		  unsigned char *response, size_t response_n)
 {
   gpg_error_t err;
 
-  err = challenge_verify_sexp (public_key,
+  err = challenge_verify_sexp (public_key, key_type,
 			       challenge, challenge_n, response, response_n);
 
   return err;
@@ -186,7 +223,7 @@ sexp_to_string (gcry_sexp_t sexp, char **sexp_string)
 
   *sexp_string = buffer;
   err = 0;
-  
+
  out:
 
   if (err)
@@ -372,7 +409,7 @@ int
 my_strlen (const char *s)
 {
   int ret = 0;
-  
+
   while (*s)
     {
       if (ret == INT_MAX)
diff --git a/src/util/support.h b/src/util/support.h
index e25cf01..c64f751 100644
--- a/src/util/support.h
+++ b/src/util/support.h
@@ -1,18 +1,18 @@
 /* support.h - PAM authentication via OpenPGP smartcards.
    Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
- 
+
    This file is part of Poldi.
-  
+
    Poldi 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 2 of the License, or
    (at your option) any later version.
-  
+
    Poldi 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 Lesser General Public
    License along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -23,12 +23,12 @@
 
 #include <gcrypt.h>
 #include <dirent.h>
-
+#include "key-types.h"
 /* This function generates a challenge; the challenge will be stored
    in newly allocated memory, which is to be stored in *CHALLENGE;
    it's length in bytes is to be stored in *CHALLENGE_N.  Returns
    proper error code.  */
-gpg_error_t challenge_generate (unsigned char **challenge, size_t *challenge_n);
+gpg_error_t challenge_generate (unsigned char **challenge, size_t *challenge_n, key_types key_type);
 
 /* Releases the challenge contained in CHALLENGE generated by
    challenge_generate().  */
@@ -39,7 +39,7 @@ void challenge_release (unsigned char *challenge);
    challenge given in CHALLENGE of size CHALLENGE_N (in bytes) with
    the secret key belonging to the public key given as PUBLIC_KEY.
    Returns proper error code.  */
-gpg_error_t challenge_verify (gcry_sexp_t public_key,
+gpg_error_t challenge_verify (gcry_sexp_t public_key, key_types key_type,
 			      unsigned char *challenge, size_t challenge_n,
 			      unsigned char *response, size_t response_n);
 

Reply via email to