diff options
author | djm@openbsd.org <djm@openbsd.org> | 2020-04-08 00:08:46 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2020-04-08 10:14:21 +1000 |
commit | f290ab0833e44355fc006e4e67b92446c14673ef (patch) | |
tree | a561fa46ca1ec8e24fa809e977584800bebf5c81 /sshkey.c | |
parent | 8d514eea4ae089626a55e11c7bc1745c8d9683e4 (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.c | 66 |
1 files changed, 65 insertions, 1 deletions
@@ -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 | ||
4369 | static int | ||
4370 | sshkey_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 */ |
4371 | static int | 4421 | static 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 | ||
4783 | int | ||
4784 | sshkey_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 |