x509 for hostkeys.

Markus Friedl markus at openbsd.org
Thu Jan 31 22:09:10 EST 2002


This (very quick) patch allows you to connect with the commercial
ssh.com windows client and use x509 certs for hostkeys.  You have
to import your CA cert (ca.crt) in the windows client and certify
your hostkey:

$ cat << 'EOF' > x509v3.cnf
CERTPATHLEN             = 1
CERTUSAGE               = digitalSignature,keyCertSign
CERTIP                  = 0.0.0.0
[x509v3_CA]
basicConstraints=critical,CA:true,pathlen:$ENV::CERTPATHLEN
keyUsage=$ENV::CERTUSAGE
[x509v3_IPAddr]
subjectAltName=IP:$ENV::CERTIP
[x509v3_DNSName]
subjectAltName=DNS:$ENV::CERTDNS
EOF
$ CERTDNS=myipaddr; export CERTDNS
$ openssl req -new -key /etc/ssh_host_rsa_key -out HOSTKEY.csr 
$ openssl x509 -req -days 365 -in HOSTKEY.csr -CA ca.crt \
	-CAkey ca.key -CAcreateserial \
	-extfile x509v3.cnf -extensions x509v3_DNSName \
	-out HOSTKEY.crt
$ umask 077
$ cat /etc/ssh_host_rsa_key HOSTKEY.crt > /etc/ssh_host_rsa_key+cert
$ echo HostKey  /etc/ssh_host_rsa_key+cert > sshd_config-test
$ sudo sshd -p 2222 -ddd -f sshd_config-test

Index: authfile.c
===================================================================
RCS file: /home/markus/cvs/ssh/authfile.c,v
retrieving revision 1.45
diff -u -r1.45 authfile.c
--- authfile.c	29 Dec 2001 21:56:01 -0000	1.45
+++ authfile.c	31 Jan 2002 10:50:53 -0000
@@ -460,6 +460,24 @@
 		error("PEM_read_PrivateKey: mismatch or "
 		    "unknown EVP_PKEY save_type %d", pk->save_type);
 	}
+	if (prv != NULL) {
+		/* try to get a certificate if we have the private key */
+		prv->x509 = PEM_read_X509(fp, NULL, NULL, (char *)passphrase);
+		if (prv->x509 != NULL) {
+			debug("PEM_read_X509");
+#ifdef DEBUG_X509
+			X509_print_fp(stdout, prv->x509);
+			{
+				EVP_PKEY *pkey = X509_get_pubkey(prv->x509);
+				if (pkey->type == EVP_PKEY_RSA) {
+					debug("PEM_read_X509 -> RSA");
+				} else if (pkey->type == EVP_PKEY_DSA) {
+					debug("PEM_read_X509 -> DSA");
+				}
+			}
+#endif
+		}
+	}
 	fclose(fp);
 	if (pk != NULL)
 		EVP_PKEY_free(pk);
Index: key.c
===================================================================
RCS file: /home/markus/cvs/ssh/key.c,v
retrieving revision 1.39
diff -u -r1.39 key.c
--- key.c	25 Jan 2002 22:07:40 -0000	1.39
+++ key.c	31 Jan 2002 10:26:53 -0000
@@ -53,10 +53,12 @@
 	RSA *rsa;
 	DSA *dsa;
 	k = xmalloc(sizeof(*k));
+	memset(k, 0, sizeof(*k));
 	k->type = type;
 	k->flags = 0;
 	k->dsa = NULL;
 	k->rsa = NULL;
+	k->x509 = NULL;
 	switch (k->type) {
 	case KEY_RSA1:
 	case KEY_RSA:
@@ -141,6 +143,10 @@
 		fatal("key_free: bad key type %d", k->type);
 		break;
 	}
+	if (k->x509 != NULL) {
+		X509_free(k->x509);
+		k->x509 = NULL;
+	}
 	xfree(k);
 }
 int
@@ -538,6 +544,8 @@
 {
 	switch (k->type) {
 	case KEY_RSA:
+		if (k->x509)
+			return "x509v3-sign-rsa";
 		return "ssh-rsa";
 		break;
 	case KEY_DSA:
@@ -641,6 +649,10 @@
 		return KEY_RSA;
 	} else if (strcmp(name, "ssh-dss") == 0) {
 		return KEY_DSA;
+	} else if (strcmp(name, "x509v3-sign-rsa") == 0) {
+		return KEY_RSA;
+	} else if (strcmp(name, "x509v3-sign-dss") == 0) {
+		return KEY_DSA;
 	}
 	debug2("key_type_from_name: unknown key type '%s'", name);
 	return KEY_UNSPEC;
@@ -739,9 +751,16 @@
 		buffer_put_bignum2(&b, key->dsa->pub_key);
 		break;
 	case KEY_RSA:
-		buffer_put_cstring(&b, key_ssh_name(key));
-		buffer_put_bignum2(&b, key->rsa->e);
-		buffer_put_bignum2(&b, key->rsa->n);
+		if (key->x509) {
+			/* XXX ssh.com does not accept a key name here */
+			len = i2d_X509(key->x509, NULL);
+			buf = buffer_append_space(&b, len);
+			i2d_X509(key->x509, &buf);
+		} else {
+			buffer_put_cstring(&b, key_ssh_name(key));
+			buffer_put_bignum2(&b, key->rsa->e);
+			buffer_put_bignum2(&b, key->rsa->n);
+		}
 		break;
 	default:
 		error("key_to_blob: unsupported key type %d", key->type);
Index: key.h
===================================================================
RCS file: /home/markus/cvs/ssh/key.h,v
retrieving revision 1.17
diff -u -r1.17 key.h
--- key.h	17 Sep 2001 19:27:15 -0000	1.17
+++ key.h	30 Jan 2002 15:23:11 -0000
@@ -28,6 +28,7 @@
 
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
+#include <openssl/x509.h>
 
 typedef struct Key Key;
 enum types {
@@ -53,6 +54,7 @@
 	int	 flags;
 	RSA	*rsa;
 	DSA	*dsa;
+	X509	*x509;
 };
 
 Key	*key_new(int);
Index: ssh-rsa.c
===================================================================
RCS file: /home/markus/cvs/ssh/ssh-rsa.c,v
retrieving revision 1.15
diff -u -r1.15 ssh-rsa.c
--- ssh-rsa.c	25 Jan 2002 21:42:11 -0000	1.15
+++ ssh-rsa.c	31 Jan 2002 09:23:53 -0000
@@ -91,7 +91,11 @@
 	}
 	/* encode signature */
 	buffer_init(&b);
+#if 0
 	buffer_put_cstring(&b, "ssh-rsa");
+#else
+	buffer_put_cstring(&b, key_ssh_name(key));
+#endif
 	buffer_put_string(&b, sig, slen);
 	len = buffer_len(&b);
 	ret = xmalloc(len);



More information about the openssh-unix-dev mailing list