From 71ad7c65189b9f8ff6226de297732257ba91040b Mon Sep 17 00:00:00 2001 From: djm Date: Wed, 11 Oct 2023 22:41:05 +0000 Subject: [PATCH] add support for reading ED25519 private keys in PEM PKCS8 format; ok markus@ tb@ --- usr.bin/ssh/sshkey.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/usr.bin/ssh/sshkey.c b/usr.bin/ssh/sshkey.c index c3c3c513502..f41018c1872 100644 --- a/usr.bin/ssh/sshkey.c +++ b/usr.bin/ssh/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.138 2023/08/21 04:36:46 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.139 2023/10/11 22:41:05 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -3367,6 +3367,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, struct sshkey *prv = NULL; BIO *bio = NULL; int r; + size_t len; if (keyp != NULL) *keyp = NULL; @@ -3442,6 +3443,39 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, #ifdef DEBUG_PK if (prv != NULL && prv->ecdsa != NULL) sshkey_dump_ec_key(prv->ecdsa); +#endif + } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_ED25519 && + (type == KEY_UNSPEC || type == KEY_ED25519)) { + if ((prv = sshkey_new(KEY_UNSPEC)) == NULL || + (prv->ed25519_sk = calloc(1, ED25519_SK_SZ)) == NULL || + (prv->ed25519_pk = calloc(1, ED25519_PK_SZ)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + prv->type = KEY_ED25519; + len = ED25519_PK_SZ; + if (!EVP_PKEY_get_raw_public_key(pk, prv->ed25519_pk, &len)) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if (len != ED25519_PK_SZ) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + len = ED25519_SK_SZ - ED25519_PK_SZ; + if (!EVP_PKEY_get_raw_private_key(pk, prv->ed25519_sk, &len)) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if (len != ED25519_SK_SZ - ED25519_PK_SZ) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + /* Append the public key to our private key */ + memcpy(prv->ed25519_sk + (ED25519_SK_SZ - ED25519_PK_SZ), + prv->ed25519_pk, ED25519_PK_SZ); +#ifdef DEBUG_PK + sshbuf_dump_data(prv->ed25519_sk, ED25519_SK_SZ, stderr); #endif } else { r = SSH_ERR_INVALID_FORMAT; @@ -3472,7 +3506,6 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, *commentp = NULL; switch (type) { - case KEY_ED25519: case KEY_XMSS: /* No fallback for new-format-only keys */ return sshkey_parse_private2(blob, type, passphrase, -- 2.20.1