diff options
-rw-r--r-- | sshkey.c | 66 | ||||
-rw-r--r-- | sshkey.h | 4 |
2 files changed, 68 insertions, 2 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 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.h,v 1.44 2019/12/30 09:23:28 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.h,v 1.45 2020/04/08 00:08:46 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -259,6 +259,8 @@ int sshkey_parse_private_fileblob(struct sshbuf *buffer, | |||
259 | const char *passphrase, struct sshkey **keyp, char **commentp); | 259 | const char *passphrase, struct sshkey **keyp, char **commentp); |
260 | int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, | 260 | int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, |
261 | const char *passphrase, struct sshkey **keyp, char **commentp); | 261 | const char *passphrase, struct sshkey **keyp, char **commentp); |
262 | int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, | ||
263 | int type, struct sshkey **pubkeyp); | ||
262 | 264 | ||
263 | /* XXX should be internal, but used by ssh-keygen */ | 265 | /* XXX should be internal, but used by ssh-keygen */ |
264 | int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); | 266 | int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); |