- markus@cvs.openbsd.org 2001/08/02 00:10:17
     [ssh-keygen.c]
     add -D readerid option (download, i.e. print public RSA key to stdout).
     check for card present when uploading keys.
     use strings instead of ints for smartcard reader ids, too.
diff --git a/ChangeLog b/ChangeLog
index 1f018a9..054dfe4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -102,6 +102,11 @@
      [scard.c ssh.c]
      support finish rsa keys.
      free public keys after login -> call finish -> close smartcard.
+   - markus@cvs.openbsd.org 2001/08/02 00:10:17
+     [ssh-keygen.c]
+     add -D readerid option (download, i.e. print public RSA key to stdout).
+     check for card present when uploading keys.
+     use strings instead of ints for smartcard reader ids, too.
 
 20010803
  - (djm) Fix interrupted read in entropy gatherer. Spotted by markus@ on
@@ -6212,4 +6217,4 @@
  - Wrote replacements for strlcpy and mkdtemp
  - Released 1.0pre1
 
-$Id: ChangeLog,v 1.1452 2001/08/06 21:42:00 mouring Exp $
+$Id: ChangeLog,v 1.1453 2001/08/06 21:44:05 mouring Exp $
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 5fadad7..096908f 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -12,15 +12,11 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.74 2001/08/01 23:33:09 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.75 2001/08/02 00:10:17 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 
-#ifdef SMARTCARD
-#include <sectok.h>
-#endif
-
 #include "xmalloc.h"
 #include "key.h"
 #include "rsa.h"
@@ -32,6 +28,11 @@
 #include "log.h"
 #include "readpass.h"
 
+#ifdef SMARTCARD
+#include <sectok.h>
+#include <openssl/engine.h>
+#include "scard.h"
+#endif
 
 /* Number of bits in the RSA/DSA key.  This value can be changed on the command line. */
 int bits = 1024;
@@ -410,7 +411,7 @@
 }
 
 static void
-do_upload(struct passwd *pw, int reader)
+do_upload(struct passwd *pw, const char *sc_reader_id)
 {
 	Key *prv = NULL;
 	struct stat st;
@@ -441,14 +442,19 @@
 	COPY_RSA_KEY(dmp1, 4);
 	COPY_RSA_KEY(n, 5);
 	len = BN_num_bytes(prv->rsa->n);
-	fd = sectok_open(reader, STONOWAIT, &sw);
+	fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
 	if (fd < 0) {
-                error("sectok_open failed: %s", sectok_get_sw(sw));
+		error("sectok_open failed: %s", sectok_get_sw(sw));
+		goto done;
+	}
+	if (! sectok_cardpresent(fd)) {
+		error("smartcard in reader %s not present",
+		    sc_reader_id);
 		goto done;
 	}
 	ret = sectok_reset(fd, 0, NULL, &sw);
 	if (ret <= 0) {
-                error("sectok_reset failed: %s", sectok_get_sw(sw));
+		error("sectok_reset failed: %s", sectok_get_sw(sw));
 		goto done;
 	}
 	if ((cla = cyberflex_inq_class(fd)) < 0) {
@@ -495,6 +501,20 @@
 		sectok_close(fd);
 	exit(status);
 }
+
+static void
+do_download(struct passwd *pw, const char *sc_reader_id)
+{
+	Key *pub = NULL;
+
+	pub = sc_get_key(sc_reader_id);
+	if (pub == NULL)
+		fatal("cannot read public key from smartcard");
+	key_write(pub, stdout);
+	key_free(pub);
+	fprintf(stdout, "\n");
+	exit(0);
+}
 #endif
 
 static void
@@ -784,10 +804,11 @@
 main(int ac, char **av)
 {
 	char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
+	char *reader_id = NULL;
 	Key *private, *public;
 	struct passwd *pw;
-	int opt, type, fd, reader = -1;
 	struct stat st;
+	int opt, type, fd, download = 0;
 	FILE *f;
 
 	extern int optind;
@@ -810,7 +831,7 @@
 		exit(1);
 	}
 
-	while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:u:P:N:C:")) != -1) {
+	while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:u:D:P:N:C:")) != -1) {
 		switch (opt) {
 		case 'b':
 			bits = atoi(optarg);
@@ -870,8 +891,10 @@
 		case 't':
 			key_type_name = optarg;
 			break;
+		case 'D':
+			download = 1;
 		case 'u':
-			reader = atoi(optarg); /*XXX*/
+			reader_id = optarg;
 			break;
 		case '?':
 		default:
@@ -898,12 +921,16 @@
 		do_convert_from_ssh2(pw);
 	if (print_public)
 		do_print_public(pw);
-	if (reader != -1)
+	if (reader_id != NULL) {
 #ifdef SMARTCARD
-		do_upload(pw, reader);
+		if (download)
+			do_download(pw, reader_id);
+		else
+			do_upload(pw, reader_id);
 #else
 		fatal("no support for smartcards.");
 #endif
+	}
 
 	arc4random_stir();