[openssh-commits] [openssh] 02/07: upstream: check that pubkey in private key envelope matches actual

git+noreply at mindrot.org git+noreply at mindrot.org
Wed Apr 8 10:14:28 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 6aabfb6d22b36d07f584cba97f4cdc4363a829da
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Wed Apr 8 00:04:32 2020 +0000

    upstream: check that pubkey in private key envelope matches actual
    
    private key
    
    (this public key is currently unusued)
    
    ok markus@
    
    OpenBSD-Commit-ID: 634a60b5e135d75f48249ccdf042f3555112049c
---
 sshkey.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/sshkey.c b/sshkey.c
index 0fc0f97c..7ff61c85 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.103 2020/04/08 00:01:52 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.104 2020/04/08 00:04:32 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -4135,8 +4135,8 @@ private2_uudecode(struct sshbuf *blob, struct sshbuf **decodedp)
 }
 
 static int
-private2_decrypt(struct sshbuf *decoded, struct sshbuf **decryptedp,
-    const char *passphrase)
+private2_decrypt(struct sshbuf *decoded, const char *passphrase,
+    struct sshbuf **decryptedp, struct sshkey **pubkeyp)
 {
 	char *ciphername = NULL, *kdfname = NULL;
 	const struct sshcipher *cipher = NULL;
@@ -4144,13 +4144,15 @@ private2_decrypt(struct sshbuf *decoded, struct sshbuf **decryptedp,
 	size_t keylen = 0, ivlen = 0, authlen = 0, slen = 0;
 	struct sshbuf *kdf = NULL, *decrypted = NULL;
 	struct sshcipher_ctx *ciphercontext = NULL;
+	struct sshkey *pubkey = NULL;
 	u_char *key = NULL, *salt = NULL, *dp;
 	u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
 
-	if (decoded == NULL || decryptedp == NULL)
+	if (decoded == NULL || decryptedp == NULL || pubkeyp == NULL)
 		return SSH_ERR_INVALID_ARGUMENT;
 
 	*decryptedp = NULL;
+	*pubkeyp = NULL;
 
 	if ((decrypted = sshbuf_new()) == NULL) {
 		r = SSH_ERR_ALLOC_FAIL;
@@ -4171,7 +4173,7 @@ private2_decrypt(struct sshbuf *decoded, struct sshbuf **decryptedp,
 		goto out;
 	}
 
-	if ((r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */
+	if ((r = sshkey_froms(decoded, &pubkey)) != 0 ||
 	    (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
 		goto out;
 
@@ -4258,11 +4260,14 @@ private2_decrypt(struct sshbuf *decoded, struct sshbuf **decryptedp,
 	/* success */
 	*decryptedp = decrypted;
 	decrypted = NULL;
+	*pubkeyp = pubkey;
+	pubkey = NULL;
 	r = 0;
  out:
 	cipher_free(ciphercontext);
 	free(ciphername);
 	free(kdfname);
+	sshkey_free(pubkey);
 	if (salt != NULL) {
 		explicit_bzero(salt, slen);
 		free(salt);
@@ -4308,7 +4313,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
 	char *comment = NULL;
 	int r = SSH_ERR_INTERNAL_ERROR;
 	struct sshbuf *decoded = NULL, *decrypted = NULL;
-	struct sshkey *k = NULL;
+	struct sshkey *k = NULL, *pubkey = NULL;
 
 	if (keyp != NULL)
 		*keyp = NULL;
@@ -4317,7 +4322,8 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
 
 	/* Undo base64 encoding and decrypt the private section */
 	if ((r = private2_uudecode(blob, &decoded)) != 0 ||
-	    (r = private2_decrypt(decoded, &decrypted, passphrase)) != 0)
+	    (r = private2_decrypt(decoded, passphrase,
+	    &decrypted, &pubkey)) != 0)
 		goto out;
 
 	/* Load the private key and comment */
@@ -4329,7 +4335,11 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
 	if ((r = private2_check_padding(decrypted)) != 0)
 		goto out;
 
-	/* XXX decode pubkey and check against private */
+	/* Check that the public key in the envelope matches the private key */
+	if (!sshkey_equal(pubkey, k)) {
+		r = SSH_ERR_INVALID_FORMAT;
+		goto out;
+	}
 
 	/* success */
 	r = 0;
@@ -4346,6 +4356,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
 	sshbuf_free(decoded);
 	sshbuf_free(decrypted);
 	sshkey_free(k);
+	sshkey_free(pubkey);
 	return r;
 }
 

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


More information about the openssh-commits mailing list