summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2020-04-08 00:10:38 +0000
committerDamien Miller <djm@cvs.openbsd.org>2020-04-08 00:10:38 +0000
commit27ed7dcde2fbbd245e69b8fec72278fa67d66add (patch)
tree8972420ddfe06f7fa7527dd9a2b4810688d76165
parent885753c5de1d1c8f641074805b8474922628c9ad (diff)
let sshkey_try_load_public() load public keys from the unencrypted
envelope of private key files if not sidecar public key file is present. ok markus@
-rw-r--r--usr.bin/ssh/authfile.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/usr.bin/ssh/authfile.c b/usr.bin/ssh/authfile.c
index c3f3ccdcbbc..c945c040298 100644
--- a/usr.bin/ssh/authfile.c
+++ b/usr.bin/ssh/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.138 2020/04/08 00:09:24 djm Exp $ */
+/* $OpenBSD: authfile.c,v 1.139 2020/04/08 00:10:37 djm Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
@@ -189,6 +189,38 @@ sshkey_load_private(const char *filename, const char *passphrase,
return r;
}
+/* Load a pubkey from the unencrypted envelope of a new-format private key */
+static int
+sshkey_load_pubkey_from_private(const char *filename, struct sshkey **pubkeyp)
+{
+ struct sshbuf *buffer = NULL;
+ struct sshkey *pubkey = NULL;
+ int r, fd;
+
+ if (pubkeyp != NULL)
+ *pubkeyp = NULL;
+
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ return SSH_ERR_SYSTEM_ERROR;
+ if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
+ (r = sshkey_parse_pubkey_from_private_fileblob_type(buffer,
+ KEY_UNSPEC, &pubkey)) != 0)
+ goto out;
+ if ((r = sshkey_set_filename(pubkey, filename)) != 0)
+ goto out;
+ /* success */
+ if (pubkeyp != NULL) {
+ *pubkeyp = pubkey;
+ pubkey = NULL;
+ }
+ r = 0;
+ out:
+ close(fd);
+ sshbuf_free(buffer);
+ sshkey_free(pubkey);
+ return r;
+}
+
static int
sshkey_try_load_public(struct sshkey **kp, const char *filename,
char **commentp)
@@ -267,6 +299,10 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
if ((r = sshkey_try_load_public(keyp, pubfile, commentp)) == 0)
goto out;
+ /* finally, try to extract public key from private key file */
+ if ((r = sshkey_load_pubkey_from_private(filename, keyp)) == 0)
+ goto out;
+
out:
free(pubfile);
return r;