summaryrefslogtreecommitdiffstats
path: root/sshkey.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2023-10-12 00:41:05 +0200
committerDamien Miller <djm@mindrot.org>2023-10-12 00:59:44 +0200
commit76e91e7238cdc5662bc818e2a48d466283840d23 (patch)
treebfa428fc915ee1286c8bd12217bbd815ad157b87 /sshkey.c
parentupstream: mention "none" is a valid argument to IdentityFile; bz3080 (diff)
downloadopenssh-76e91e7238cdc5662bc818e2a48d466283840d23.tar.xz
openssh-76e91e7238cdc5662bc818e2a48d466283840d23.zip
upstream: add support for reading ED25519 private keys in PEM PKCS8
format; ok markus@ tb@ OpenBSD-Commit-ID: 01b85c91757e6b057e9b23b8a23f96415c3c7174
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/sshkey.c b/sshkey.c
index 2d3906ad8..33f5e734f 100644
--- a/sshkey.c
+++ b/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.
@@ -3422,6 +3422,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;
@@ -3500,6 +3501,41 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
sshkey_dump_ec_key(prv->ecdsa);
# endif
#endif /* OPENSSL_HAS_ECC */
+#ifdef OPENSSL_HAS_ED25519
+ } 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
+#endif /* OPENSSL_HAS_ED25519 */
} else {
r = SSH_ERR_INVALID_FORMAT;
goto out;
@@ -3529,7 +3565,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,