let sshkey_try_load_public() load public keys from the unencrypted
authordjm <djm@openbsd.org>
Wed, 8 Apr 2020 00:10:37 +0000 (00:10 +0000)
committerdjm <djm@openbsd.org>
Wed, 8 Apr 2020 00:10:37 +0000 (00:10 +0000)
envelope of private key files if not sidecar public key file is
present.

ok markus@

usr.bin/ssh/authfile.c

index c3f3ccd..c945c04 100644 (file)
@@ -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;