- Merge big update to OpenSSH-2.0 from OpenBSD CVS
   [README.openssh2]
   - interop w/ F-secure windows client
   - sync documentation
   - ssh_host_dsa_key not ssh_dsa_key
   [auth-rsa.c]
   - missing fclose
   [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c]
   [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c]
   [sshd.c uuencode.c uuencode.h authfile.h]
   - add DSA pubkey auth and other SSH2 fixes.  use ssh-keygen -[xX]
     for trading keys with the real and the original SSH, directly from the
     people who invented the SSH protocol.
   [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h]
   [sshconnect1.c sshconnect2.c]
   - split auth/sshconnect in one file per protocol version
   [sshconnect2.c]
   - remove debug
   [uuencode.c]
   - add trailing =
   [version.h]
   - OpenSSH-2.0
   [ssh-keygen.1 ssh-keygen.c]
   - add -R flag: exit code indicates if RSA is alive
   [sshd.c]
   - remove unused
     silent if -Q is specified
   [ssh.h]
   - host key becomes /etc/ssh_host_dsa_key
   [readconf.c servconf.c ]
   - ssh/sshd default to proto 1 and 2
   [uuencode.c]
   - remove debug
   [auth2.c ssh-keygen.c sshconnect2.c sshd.c]
   - xfree DSA blobs
   [auth2.c serverloop.c session.c]
   - cleanup logging for sshd/2, respect PasswordAuth no
   [sshconnect2.c]
   - less debug, respect .ssh/config
   [README.openssh2 channels.c channels.h]
   - clientloop.c session.c ssh.c
   - support for x11-fwding, client+server
diff --git a/dsa.c b/dsa.c
index 1594c14..a4f6d3e 100644
--- a/dsa.c
+++ b/dsa.c
@@ -28,7 +28,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: dsa.c,v 1.4 2000/04/14 10:30:31 markus Exp $");
+RCSID("$Id: dsa.c,v 1.5 2000/04/26 20:56:29 markus Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -47,13 +47,14 @@
 #include <openssl/hmac.h>
 #include "kex.h"
 #include "key.h"
+#include "uuencode.h"
 
 #define INTBLOB_LEN	20
 #define SIGBLOB_LEN	(2*INTBLOB_LEN)
 
 Key *
-dsa_serverkey_from_blob(
-    char *serverhostkey, int serverhostkeylen)
+dsa_key_from_blob(
+    char *blob, int blen)
 {
 	Buffer b;
 	char *ktype;
@@ -61,14 +62,17 @@
 	DSA *dsa;
 	Key *key;
 
+#ifdef DEBUG_DSS
+	dump_base64(blob, blen);
+#endif
 	/* fetch & parse DSA/DSS pubkey */
 	key = key_new(KEY_DSA);
 	dsa = key->dsa;
 	buffer_init(&b);
-	buffer_append(&b, serverhostkey, serverhostkeylen);
+	buffer_append(&b, blob, blen);
 	ktype = buffer_get_string(&b, NULL);
 	if (strcmp(KEX_DSS, ktype) != 0) {
-		error("dsa_serverkey_from_blob: cannot handle type  %s", ktype);
+		error("dsa_key_from_blob: cannot handle type  %s", ktype);
 		key_free(key);
 		return NULL;
 	}
@@ -78,7 +82,7 @@
 	buffer_get_bignum2(&b, dsa->pub_key);
 	rlen = buffer_len(&b);
 	if(rlen != 0)
-		error("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen);
+		error("dsa_key_from_blob: remaining bytes in key blob %d", rlen);
 	buffer_free(&b);
 
 	debug("keytype %s", ktype);
@@ -87,37 +91,8 @@
 #endif
 	return key;
 }
-DSA *
-dsa_load_private(char *filename)
-{
-	DSA *dsa;
-	BIO *in;
-
-	in = BIO_new(BIO_s_file());
-	if (in == NULL)
-		fatal("BIO_new failed");
-	if (BIO_read_filename(in, filename) <= 0)
-		fatal("BIO_read failed %s: %s", filename, strerror(errno));
-	fprintf(stderr, "read DSA private key\n");
-	dsa = PEM_read_bio_DSAPrivateKey(in,NULL,NULL,NULL);
-	if (dsa == NULL)
-		fatal("PEM_read_bio_DSAPrivateKey failed %s", filename);
-	BIO_free(in);
-	return dsa;
-}
-Key *
-dsa_get_serverkey(char *filename)
-{
-	Key *k = key_new(KEY_EMPTY);
-	k->type = KEY_DSA;
-	k->dsa = dsa_load_private(filename);
-#ifdef DEBUG_DSS
-	DSA_print_fp(stderr, dsa, 8);
-#endif
-	return k;
-}
 int
-dsa_make_serverkey_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
+dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
 {
 	Buffer b;
 	int len;
@@ -146,7 +121,7 @@
 dsa_sign(
     Key *key,
     unsigned char **sigp, int *lenp,
-    unsigned char *hash, int hlen)
+    unsigned char *data, int datalen)
 {
 	unsigned char *digest;
 	unsigned char *ret;
@@ -165,10 +140,13 @@
 	}
 	digest = xmalloc(evp_md->md_size);
 	EVP_DigestInit(&md, evp_md);
-	EVP_DigestUpdate(&md, hash, hlen);
+	EVP_DigestUpdate(&md, data, datalen);
 	EVP_DigestFinal(&md, digest, NULL);
 
 	sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
+	if (sig == NULL) {
+		fatal("dsa_sign: cannot sign");
+	}
 
 	rlen = BN_num_bytes(sig->r);
 	slen = BN_num_bytes(sig->s);
@@ -212,7 +190,7 @@
 dsa_verify(
     Key *key,
     unsigned char *signature, int signaturelen,
-    unsigned char *hash, int hlen)
+    unsigned char *data, int datalen)
 {
 	Buffer b;
 	unsigned char *digest;
@@ -269,10 +247,10 @@
 		xfree(sigblob);
 	}
 	
-	/* sha1 the signed data (== session_id == hash) */
+	/* sha1 the data */
 	digest = xmalloc(evp_md->md_size);
 	EVP_DigestInit(&md, evp_md);
-	EVP_DigestUpdate(&md, hash, hlen);
+	EVP_DigestUpdate(&md, data, datalen);
 	EVP_DigestFinal(&md, digest, NULL);
 
 	ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
@@ -296,3 +274,21 @@
 	debug("dsa_verify: signature %s", txt);
 	return ret;
 }
+
+Key *
+dsa_generate_key(unsigned int bits)
+{
+	DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
+	Key *k;
+	if (dsa == NULL) {
+		fatal("DSA_generate_parameters failed");
+	}
+	if (!DSA_generate_key(dsa)) {
+		fatal("DSA_generate_keys failed");
+	}
+
+	k = key_new(KEY_EMPTY);
+	k->type = KEY_DSA;
+	k->dsa = dsa;
+	return k;
+}