- markus@cvs.openbsd.org 2001/03/26 23:23:24
     [rsa.c rsa.h ssh-agent.c ssh-keygen.c]
     try to read private f-secure ssh v2 rsa keys.
diff --git a/ChangeLog b/ChangeLog
index 41ea13f..bf670de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,9 @@
    - markus@cvs.openbsd.org 2001/03/26 23:12:42
      [authfile.c]
      KNF
+   - markus@cvs.openbsd.org 2001/03/26 23:23:24
+     [rsa.c rsa.h ssh-agent.c ssh-keygen.c]
+     try to read private f-secure ssh v2 rsa keys.
 
 20010328
  - (djm) Reorder tests and library inclusion for Krb4/AFS to try to 
@@ -4744,4 +4747,4 @@
  - Wrote replacements for strlcpy and mkdtemp
  - Released 1.0pre1
 
-$Id: ChangeLog,v 1.1027 2001/03/29 00:28:37 mouring Exp $
+$Id: ChangeLog,v 1.1028 2001/03/29 00:29:54 mouring Exp $
diff --git a/rsa.c b/rsa.c
index 6265531..f69f996 100644
--- a/rsa.c
+++ b/rsa.c
@@ -60,7 +60,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: rsa.c,v 1.21 2001/02/04 15:32:24 stevesk Exp $");
+RCSID("$OpenBSD: rsa.c,v 1.22 2001/03/26 23:23:23 markus Exp $");
 
 #include "rsa.h"
 #include "log.h"
@@ -119,3 +119,23 @@
 	xfree(inbuf);
 	return len;
 }
+
+void
+generate_additional_parameters(RSA *rsa)
+{
+	BIGNUM *aux;
+	BN_CTX *ctx;
+	/* Generate additional parameters */
+	aux = BN_new();
+	ctx = BN_CTX_new();
+
+	BN_sub(aux, rsa->q, BN_value_one());
+	BN_mod(rsa->dmq1, rsa->d, aux, ctx);
+
+	BN_sub(aux, rsa->p, BN_value_one());
+	BN_mod(rsa->dmp1, rsa->d, aux, ctx);
+
+	BN_clear_free(aux);
+	BN_CTX_free(ctx);
+}
+
diff --git a/rsa.h b/rsa.h
index 713d312..d3d2c99 100644
--- a/rsa.h
+++ b/rsa.h
@@ -11,7 +11,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: rsa.h,v 1.10 2001/01/29 19:47:30 markus Exp $"); */
+/* RCSID("$OpenBSD: rsa.h,v 1.11 2001/03/26 23:23:24 markus Exp $"); */
 
 #ifndef RSA_H
 #define RSA_H
@@ -22,4 +22,6 @@
 void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
 int rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
 
+void generate_additional_parameters __P((RSA *rsa));
+
 #endif				/* RSA_H */
diff --git a/ssh-agent.c b/ssh-agent.c
index 8c4b539..6a0c0d0 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ssh-agent.c,v 1.52 2001/03/06 00:33:04 deraadt Exp $	*/
+/*	$OpenBSD: ssh-agent.c,v 1.53 2001/03/26 23:23:24 markus Exp $	*/
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.52 2001/03/06 00:33:04 deraadt Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.53 2001/03/26 23:23:24 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
@@ -361,25 +361,6 @@
 }
 
 void
-generate_additional_parameters(RSA *rsa)
-{
-	BIGNUM *aux;
-	BN_CTX *ctx;
-	/* Generate additional parameters */
-	aux = BN_new();
-	ctx = BN_CTX_new();
-
-	BN_sub(aux, rsa->q, BN_value_one());
-	BN_mod(rsa->dmq1, rsa->d, aux, ctx);
-
-	BN_sub(aux, rsa->p, BN_value_one());
-	BN_mod(rsa->dmp1, rsa->d, aux, ctx);
-
-	BN_clear_free(aux);
-	BN_CTX_free(ctx);
-}
-
-void
 process_add_identity(SocketEntry *e, int version)
 {
 	Key *k = NULL;
@@ -738,6 +719,8 @@
 	extern int optind;
 	fd_set *readsetp = NULL, *writesetp = NULL;
 
+	SSLeay_add_all_algorithms();
+
 	__progname = get_progname(av[0]);
 	init_rng();
 	seed_rng();
diff --git a/ssh-keygen.c b/ssh-keygen.c
index b3074e8..496393f 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -12,13 +12,14 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.52 2001/03/26 08:07:09 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.53 2001/03/26 23:23:24 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 
 #include "xmalloc.h"
 #include "key.h"
+#include "rsa.h"
 #include "authfile.h"
 #include "uuencode.h"
 #include "buffer.h"
@@ -169,8 +170,10 @@
 {
 	int bits = buffer_get_int(b);
 	int bytes = (bits + 7) / 8;
+
 	if (buffer_len(b) < bytes)
-		fatal("buffer_get_bignum_bits: input buffer too small");
+		fatal("buffer_get_bignum_bits: input buffer too small: "
+		    "need %d have %d", bytes, buffer_len(b));
 	BN_bin2bn((u_char *)buffer_ptr(b), bytes, value);
 	buffer_consume(b, bytes);
 }
@@ -179,9 +182,8 @@
 do_convert_private_ssh2_from_blob(char *blob, int blen)
 {
 	Buffer b;
-	DSA *dsa;
 	Key *key = NULL;
-	int ignore, magic, rlen;
+	int ignore, magic, rlen, ktype;
 	char *type, *cipher;
 
 	buffer_init(&b);
@@ -199,33 +201,64 @@
 	ignore = buffer_get_int(&b);
 	ignore = buffer_get_int(&b);
 	ignore = buffer_get_int(&b);
-	xfree(type);
 
 	if (strcmp(cipher, "none") != 0) {
 		error("unsupported cipher %s", cipher);
 		xfree(cipher);
 		buffer_free(&b);
+		xfree(type);
 		return NULL;
 	}
 	xfree(cipher);
 
-	key = key_new(KEY_DSA);
-	dsa = key->dsa;
-	dsa->priv_key = BN_new();
-	if (dsa->priv_key == NULL) {
-		error("alloc priv_key failed");
-		key_free(key);
+	if (strstr(type, "dsa")) {
+		ktype = KEY_DSA;
+	} else if (strstr(type, "rsa")) {
+		ktype = KEY_RSA;
+	} else {
+		xfree(type);
 		return NULL;
 	}
-	buffer_get_bignum_bits(&b, dsa->p);
-	buffer_get_bignum_bits(&b, dsa->g);
-	buffer_get_bignum_bits(&b, dsa->q);
-	buffer_get_bignum_bits(&b, dsa->pub_key);
-	buffer_get_bignum_bits(&b, dsa->priv_key);
+	key = key_new_private(ktype);
+	xfree(type);
+
+	switch (key->type) {
+	case KEY_DSA:
+		buffer_get_bignum_bits(&b, key->dsa->p);
+		buffer_get_bignum_bits(&b, key->dsa->g);
+		buffer_get_bignum_bits(&b, key->dsa->q);
+		buffer_get_bignum_bits(&b, key->dsa->pub_key);
+		buffer_get_bignum_bits(&b, key->dsa->priv_key);
+		break;
+	case KEY_RSA:
+		if (!BN_set_word(key->rsa->e, (u_long) buffer_get_char(&b))) {
+			buffer_free(&b);
+			key_free(key);
+			return NULL;
+		}
+		buffer_get_bignum_bits(&b, key->rsa->d);
+		buffer_get_bignum_bits(&b, key->rsa->n);
+		buffer_get_bignum_bits(&b, key->rsa->iqmp);
+		buffer_get_bignum_bits(&b, key->rsa->q);
+		buffer_get_bignum_bits(&b, key->rsa->p);
+		generate_additional_parameters(key->rsa);
+		break;
+	}
 	rlen = buffer_len(&b);
 	if(rlen != 0)
-		error("do_convert_private_ssh2_from_blob: remaining bytes in key blob %d", rlen);
+		error("do_convert_private_ssh2_from_blob: "
+		    "remaining bytes in key blob %d", rlen);
 	buffer_free(&b);
+#ifdef DEBUG_PK
+	{
+		u_int slen;
+		u_char *sig, data[10] = "abcde12345";
+
+		key_sign(key, &sig, &slen, data, sizeof data);
+		key_verify(key, sig, slen, data, sizeof data);
+		free(sig);
+	}
+#endif
 	return key;
 }
 
@@ -288,7 +321,9 @@
 		exit(1);
 	}
 	ok = private ?
-	    PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :
+	    (k->type == KEY_DSA ?
+		 PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :
+		 PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) :
 	    key_write(k, stdout);
 	if (!ok) {
 		fprintf(stderr, "key write failed");