[openssh-commits] [openssh] 05/07: upstream: add sshkey_parse_pubkey_from_private_fileblob_type()

git+noreply at mindrot.org git+noreply at mindrot.org
Wed Apr 8 10:14:31 AEST 2020


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit f290ab0833e44355fc006e4e67b92446c14673ef
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Wed Apr 8 00:08:46 2020 +0000

    upstream: add sshkey_parse_pubkey_from_private_fileblob_type()
    
    Extracts a public key from the unencrypted envelope of a new-style
    OpenSSH private key.
    
    ok markus@
    
    OpenBSD-Commit-ID: 44d7ab446e5e8c686aee96d5897b26b3939939aa
---
 sshkey.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 sshkey.h |  4 +++-
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/sshkey.c b/sshkey.c
index e87572c1..d6cc6365 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.106 2020/04/08 00:07:19 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.107 2020/04/08 00:08:46 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -4366,6 +4366,56 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
 	return r;
 }
 
+static int
+sshkey_parse_private2_pubkey(struct sshbuf *blob, int type,
+    struct sshkey **keyp)
+{
+	int r = SSH_ERR_INTERNAL_ERROR;
+	struct sshbuf *decoded = NULL;
+	struct sshkey *pubkey = NULL;
+	u_int nkeys = 0;
+
+	if (keyp != NULL)
+		*keyp = NULL;
+
+	if ((r = private2_uudecode(blob, &decoded)) != 0)
+		goto out;
+	/* parse public key from unencrypted envelope */
+	if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
+	    (r = sshbuf_skip_string(decoded)) != 0 || /* cipher */
+	    (r = sshbuf_skip_string(decoded)) != 0 || /* KDF alg */
+	    (r = sshbuf_skip_string(decoded)) != 0 || /* KDF hint */
+	    (r = sshbuf_get_u32(decoded, &nkeys)) != 0)
+		goto out;
+
+	if (nkeys != 1) {
+		/* XXX only one key supported at present */
+		r = SSH_ERR_INVALID_FORMAT;
+		goto out;
+	}
+
+	/* Parse the public key */
+	if ((r = sshkey_froms(decoded, &pubkey)) != 0)
+		goto out;
+
+	if (type != KEY_UNSPEC &&
+	    sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
+		r = SSH_ERR_KEY_TYPE_MISMATCH;
+		goto out;
+	}
+
+	/* success */
+	r = 0;
+	if (keyp != NULL) {
+		*keyp = pubkey;
+		pubkey = NULL;
+	}
+ out:
+	sshbuf_free(decoded);
+	sshkey_free(pubkey);
+	return r;
+}
+
 #ifdef WITH_OPENSSL
 /* convert SSH v2 key to PEM or PKCS#8 format */
 static int
@@ -4730,6 +4780,20 @@ sshkey_sig_details_free(struct sshkey_sig_details *details)
 	freezero(details, sizeof(*details));
 }
 
+int
+sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type,
+    struct sshkey **pubkeyp)
+{
+	int r = SSH_ERR_INTERNAL_ERROR;
+
+	if (pubkeyp != NULL)
+		*pubkeyp = NULL;
+	/* only new-format private keys bundle a public key inside */
+	if ((r = sshkey_parse_private2_pubkey(blob, type, pubkeyp)) != 0)
+		return r;
+	return 0;
+}
+
 #ifdef WITH_XMSS
 /*
  * serialize the key with the current state and forward the state
diff --git a/sshkey.h b/sshkey.h
index 71a3fddc..9c1d4f63 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.44 2019/12/30 09:23:28 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.45 2020/04/08 00:08:46 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -259,6 +259,8 @@ int	sshkey_parse_private_fileblob(struct sshbuf *buffer,
     const char *passphrase, struct sshkey **keyp, char **commentp);
 int	sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
     const char *passphrase, struct sshkey **keyp, char **commentp);
+int	sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,
+    int type, struct sshkey **pubkeyp);
 
 /* XXX should be internal, but used by ssh-keygen */
 int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list