- djm@cvs.openbsd.org 2010/08/04 05:42:47
     [auth.c auth2-hostbased.c authfile.c authfile.h ssh-keysign.8]
     [ssh-keysign.c ssh.c]
     enable certificates for hostbased authentication, from Iain Morgan;
     "looks ok" markus@
diff --git a/authfile.c b/authfile.c
index 224c6aa..6bf41db 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.80 2010/03/04 10:36:03 djm Exp $ */
+/* $OpenBSD: authfile.c,v 1.81 2010/08/04 05:42:47 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -693,6 +693,64 @@
 	return NULL;
 }
 
+/* Load the certificate associated with the named private key */
+Key *
+key_load_cert(const char *filename)
+{
+	Key *pub;
+	char file[MAXPATHLEN];
+
+	pub = key_new(KEY_UNSPEC);
+	if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
+	    (strlcat(file, "-cert.pub", sizeof file) < sizeof(file)) &&
+	    (key_try_load_public(pub, file, NULL) == 1))
+		return pub;
+	key_free(pub);
+	return NULL;
+}
+
+/* Load private key and certificate */
+Key *
+key_load_private_cert(int type, const char *filename, const char *passphrase,
+    int *perm_ok)
+{
+	Key *key, *pub;
+
+	switch (type) {
+	case KEY_RSA:
+	case KEY_DSA:
+		break;
+	default:
+		error("%s: unsupported key type", __func__);
+		return NULL;
+	}
+
+	if ((key = key_load_private_type(type, filename, 
+	    passphrase, NULL, perm_ok)) == NULL)
+		return NULL;
+
+	if ((pub = key_load_cert(filename)) == NULL) {
+		key_free(key);
+		return NULL;
+	}
+
+	/* Make sure the private key matches the certificate */
+	if (key_equal_public(key, pub) == 0) {
+		error("%s: certificate does not match private key %s",
+		    __func__, filename);
+	} else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) {
+		error("%s: key_to_certified failed", __func__);
+	} else {
+		key_cert_copy(pub, key);
+		key_free(pub);
+		return key;
+	}
+
+	key_free(key);
+	key_free(pub);
+	return NULL;
+}
+
 /*
  * Returns 1 if the specified "key" is listed in the file "filename",
  * 0 if the key is not listed or -1 on error.