summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-04-08 00:08:46 +0000
committerDamien Miller <djm@mindrot.org>2020-04-08 10:14:21 +1000
commitf290ab0833e44355fc006e4e67b92446c14673ef (patch)
treea561fa46ca1ec8e24fa809e977584800bebf5c81 /sshkey.c
parent8d514eea4ae089626a55e11c7bc1745c8d9683e4 (diff)
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
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/sshkey.c b/sshkey.c
index e87572c17..d6cc6365f 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.106 2020/04/08 00:07:19 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.107 2020/04/08 00:08:46 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -4366,6 +4366,56 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
4366 return r; 4366 return r;
4367} 4367}
4368 4368
4369static int
4370sshkey_parse_private2_pubkey(struct sshbuf *blob, int type,
4371 struct sshkey **keyp)
4372{
4373 int r = SSH_ERR_INTERNAL_ERROR;
4374 struct sshbuf *decoded = NULL;
4375 struct sshkey *pubkey = NULL;
4376 u_int nkeys = 0;
4377
4378 if (keyp != NULL)
4379 *keyp = NULL;
4380
4381 if ((r = private2_uudecode(blob, &decoded)) != 0)
4382 goto out;
4383 /* parse public key from unencrypted envelope */
4384 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
4385 (r = sshbuf_skip_string(decoded)) != 0 || /* cipher */
4386 (r = sshbuf_skip_string(decoded)) != 0 || /* KDF alg */
4387 (r = sshbuf_skip_string(decoded)) != 0 || /* KDF hint */
4388 (r = sshbuf_get_u32(decoded, &nkeys)) != 0)
4389 goto out;
4390
4391 if (nkeys != 1) {
4392 /* XXX only one key supported at present */
4393 r = SSH_ERR_INVALID_FORMAT;
4394 goto out;
4395 }
4396
4397 /* Parse the public key */
4398 if ((r = sshkey_froms(decoded, &pubkey)) != 0)
4399 goto out;
4400
4401 if (type != KEY_UNSPEC &&
4402 sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
4403 r = SSH_ERR_KEY_TYPE_MISMATCH;
4404 goto out;
4405 }
4406
4407 /* success */
4408 r = 0;
4409 if (keyp != NULL) {
4410 *keyp = pubkey;
4411 pubkey = NULL;
4412 }
4413 out:
4414 sshbuf_free(decoded);
4415 sshkey_free(pubkey);
4416 return r;
4417}
4418
4369#ifdef WITH_OPENSSL 4419#ifdef WITH_OPENSSL
4370/* convert SSH v2 key to PEM or PKCS#8 format */ 4420/* convert SSH v2 key to PEM or PKCS#8 format */
4371static int 4421static int
@@ -4730,6 +4780,20 @@ sshkey_sig_details_free(struct sshkey_sig_details *details)
4730 freezero(details, sizeof(*details)); 4780 freezero(details, sizeof(*details));
4731} 4781}
4732 4782
4783int
4784sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type,
4785 struct sshkey **pubkeyp)
4786{
4787 int r = SSH_ERR_INTERNAL_ERROR;
4788
4789 if (pubkeyp != NULL)
4790 *pubkeyp = NULL;
4791 /* only new-format private keys bundle a public key inside */
4792 if ((r = sshkey_parse_private2_pubkey(blob, type, pubkeyp)) != 0)
4793 return r;
4794 return 0;
4795}
4796
4733#ifdef WITH_XMSS 4797#ifdef WITH_XMSS
4734/* 4798/*
4735 * serialize the key with the current state and forward the state 4799 * serialize the key with the current state and forward the state