playing with smartcard: rsa key upload?

Danny De Cock godot at ulyssis.org
Fri Nov 15 09:36:36 EST 2002


hi,

this is me again on smartcard authentication using openssh with opensc
support ];-)

I finally managed to get openssh do the job without spectacular crashes
using a combination of: openssh-3.5p1, openssl-0.9.7-stable-SNAP-20021112,
zlib-1.1.4, and the cvs-source for opensc fetched on november 12th.

the changes I had to apply to scard.h, scard-opensc.c, sshconnect2.c,
ssh-rsa.c and the Makefile (which was produced by `./configure
--with-opensc=/usr/local --with-ssl-dir=/usr/local/ssl`) are included in
the attachment. <joke> without these changes, the ssh binary dies due to a
combination of fatal misuderstandings ];->> </joke>

with these changes, a gemsafe gpk 16000 smartcard, holding a private key
and a corresponding certificate, completes the rsa digital signature
generation (using the first private key it finds) during the ssh
authentication process (e.g. with `ssh -I 0 wherever.org`).

I do not claim that the changes I applied are clean (cfr. sshconnect2.c),
but they do what I expect them to do.

in order not to interfere with the original openssh-3.5p1, all my changes
follow this structure:

#if defined(SMARTCARD) && defined(USE_OPENSC)
  my code
#else
  original code
#endif

feel free to produce comments, danny.

ps: is there a special reason why scp does not have smartcard support
similar to ssh? I am currently `copying' the way ssh.c deals with
smartcard support in general to scp.c, as for my application, I need both
programs to behave similarly...

On Mon, 4 Nov 2002, Markus Friedl wrote:

> On Sun, Nov 03, 2002 at 06:14:57PM +0100, Danny De Cock wrote:
> > the attachment contains a source file which solves the segmentation
> > faults: a few type conflicts caused fatal misunderstandings between
> > several routines of openssl and openssh.
>
> no, 'fatal misunderstandings' is wrong. OpenSSL has 2 different
> interfaces for overloading the RSA routines (engine and non-engine).
> check scard.c for a way to work around this problem (->USE_ENGINE).
>
> (btw, please send diffs instead of complete files).
>
> -m
-------------- next part --------------
===================== scard.h =====================
40,43d39
< #if defined(SMARTCARD) && defined(USE_OPENSC)
< int sc_sign(int type, u_char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa);
< #endif
< 
===================== scard-opensc.c =====================
188,210c188
< #if defined(SMARTCARD) && defined(USE_OPENSC)
< char *
< get_pin (struct sc_pkcs15_object *obj)
< {
<   char buf[80];
<   char *pincode;
<   struct sc_pkcs15_pin_info *pinfo = (struct sc_pkcs15_pin_info *) obj->data;
< 
<   sprintf (buf, "Enter PIN [%s]: ", obj->label);
<   while (1)
<     {
<       pincode = getpass (buf);
<       if (strlen (pincode) == 0)
< 	return NULL;
<       if (strlen (pincode) < pinfo->min_length ||
< 	  strlen (pincode) > pinfo->stored_length)
< 	continue;
<       return pincode;
<     }
< }
< #endif
< 
< int
---
> static int
214,274d191
< #if defined(SMARTCARD) && defined(USE_OPENSC)
<   struct sc_pkcs15_object *key_obj;
<   int r;
<   struct sc_pkcs15_id id;
<   struct sc_pkcs15_object *objs[32];
<   struct sc_pkcs15_object *key;
<   unsigned long flags = 0;
<   char *pincode;
<   struct sc_pkcs15_object *pin;
< 
<   r = sc_lock (card);
<   if (r)
<     {
<       error ("Unable to lock smartcard: %s", sc_strerror (r));
<       goto err;
<     }
<   r = sc_pkcs15_get_objects (p15card, SC_PKCS15_TYPE_PRKEY, objs, 32);
<   key = objs[0]; 
<   if (key->auth_id.len)
<     {
<       r = sc_pkcs15_find_pin_by_auth_id (p15card, &key->auth_id, &pin);
<       if (r)
< 	{
< 	  debug (stderr, "Unable to find PIN code for private key: %s\n",
< 		   sc_strerror (r));
< 	  return -1;
< 	}
<       pincode = get_pin (pin);
<       if (pincode == NULL)
< 	{
< 	  return -1;
< 	}
<       r =
< 	sc_pkcs15_verify_pin (p15card,
< 			      (struct sc_pkcs15_pin_info *) pin->data,
< 			      (const u8 *) pincode, strlen (pincode));
<       if (r)
< 	{
< 	  debug (stderr, "PIN code verification failed: %s\n",
< 		   sc_strerror (r));
< 	  return -1;
< 	}
<       free (pincode);
<       debug ("PIN code correct.\n");
<     }
< //  /* FIXME: check 'type' and modify flags accordingly */
<   flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
<   r = sc_pkcs15_compute_signature (p15card, key, flags,
< 				   m, m_len, sigret, RSA_size (rsa));
<   if (r < 0)
<     {
<       error ("sc_pkcs15_compute_signature() failed: %s", sc_strerror (r));
<       goto err;
<     }
<   sc_unlock (card);
<   *siglen = r;
<   return 1;
< err:
<   sc_close ();
<   return 0;
< #else
298d214
< #endif
===================== sshconnect2.c =====================
170,175d169
< #if defined(SMARTCARD) && defined(USE_OPENSC)
< static int
< key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
<     u_char *data, u_int datalen);
< #endif
< 
605,607d598
< #if defined(SMARTCARD) && defined(USE_OPENSC)
< 	ret = (key_sign_cb)(authctxt, k, &signature, &slen,
< #else
609d599
< #endif
===================== ssh-rsa.c =====================
40,43d39
< #if defined(SMARTCARD) && defined(USE_OPENSC)
< #include "scard.h"
< #endif
< 
74,76d69
< #if defined(SMARTCARD) && defined(USE_OPENSC)
< 	ok = sc_sign(nid, digest, dlen, sig, &len, key->rsa);
< #else
78d70
< #endif
===================== Makefile =====================
65,66c65
< #SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
< SSHOBJS= scard-opensc.o ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
---
> SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o


More information about the openssh-unix-dev mailing list