[openssh-commits] [openssh] 01/02: upstream: add support for reading ED25519 private keys in PEM PKCS8

git+noreply at mindrot.org git+noreply at mindrot.org
Thu Oct 12 10:00:22 AEDT 2023


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 76e91e7238cdc5662bc818e2a48d466283840d23
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Wed Oct 11 22:41:05 2023 +0000

    upstream: add support for reading ED25519 private keys in PEM PKCS8
    
    format; ok markus@ tb@
    
    OpenBSD-Commit-ID: 01b85c91757e6b057e9b23b8a23f96415c3c7174
---
 configure.ac | 24 ++++++++++++++++++++++++
 sshkey.c     | 39 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index d8816e3f..0f457f3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3140,6 +3140,30 @@ if test "x$openssl" = "xyes" ; then
 			ecdsa-sha2-nistp521 \
 			ecdsa-sha2-nistp521-cert-v01 at openssh.com"
 	fi
+
+	# Check libcrypto ED25519 support
+	AC_CHECK_FUNCS([EVP_PKEY_get_raw_public_key])
+	AC_CHECK_FUNCS([EVP_PKEY_get_raw_private_key])
+	AC_MSG_CHECKING([whether OpenSSL has ED25519 support])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		unsigned char buf[64];
+		memset(buf, 0, sizeof(buf));
+		exit(EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519,
+		    buf, sizeof(buf)) == NULL);
+		]])],
+		[
+			AC_MSG_RESULT([no])
+		],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([OPENSSL_HAS_ED25519], [1],
+			    [libcrypto has ed25519 support])
+		]
+	)
 fi
 
 # PKCS11/U2F depend on OpenSSL and dlopen().
diff --git a/sshkey.c b/sshkey.c
index 2d3906ad..33f5e734 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,

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list