From 8da33d6da86575cc1dfd109282de3c6345686327 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 30 Oct 2026 03:22:47 +0000 Subject: [PATCH] upstream: harden private key serialisation API to avoid NULL deref if it ever called with a public key. Anthropic ANT-2026-MZ3ZOEX6 OpenBSD-Commit-ID: 037e85c68ca3a63329cffcaf7eb6ad0bdf6c7a14 --- ssh-ecdsa.c | 9 ++++++--- ssh-ed25519.c | 4 +++- ssh-rsa.c | 4 +++- sshkey.c | 4 +++- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 54a626e3f..ad69039b2 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.29 2026/02/14 00:18:34 jsg Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.30 2026/10/30 03:22:47 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -147,13 +147,16 @@ ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b, enum sshkey_serialize_rep opts) { int r; + const BIGNUM *priv; + if ((priv = EC_KEY_get0_private_key( + EVP_PKEY_get0_EC_KEY(key->pkey))) == NULL) + return SSH_ERR_INVALID_ARGUMENT; if (!sshkey_is_cert(key)) { if ((r = ssh_ecdsa_serialize_public(key, b, opts)) != 0) return r; } - if ((r = sshbuf_put_bignum2(b, - EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(key->pkey)))) != 0) + if ((r = sshbuf_put_bignum2(b, priv)) != 0) return r; return 0; } diff --git a/ssh-ed25519.c b/ssh-ed25519.c index e8113e8e9..adac89900 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ed25519.c,v 1.24 2026/09/16 00:43:00 djm Exp $ */ +/* $OpenBSD: ssh-ed25519.c,v 1.25 2026/10/30 03:22:47 djm Exp $ */ /* * Copyright (c) 2013 Markus Friedl * @@ -70,6 +70,8 @@ ssh_ed25519_serialize_private(const struct sshkey *key, struct sshbuf *b, { int r; + if (key->ed25519_sk == NULL) + return SSH_ERR_INVALID_ARGUMENT; if ((r = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0 || (r = sshbuf_put_string(b, key->ed25519_sk, ED25519_SK_SZ)) != 0) return r; diff --git a/ssh-rsa.c b/ssh-rsa.c index 7165b40ae..27304a045 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.85 2026/10/30 01:45:14 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.86 2026/10/30 03:22:47 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -99,6 +99,8 @@ ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b, RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); RSA_get0_factors(rsa, &rsa_p, &rsa_q); RSA_get0_crt_params(rsa, NULL, NULL, &rsa_iqmp); + if (rsa_d == NULL) + return SSH_ERR_INVALID_ARGUMENT; if (!sshkey_is_cert(key)) { /* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */ diff --git a/sshkey.c b/sshkey.c index 8cd9e07af..6375d58bd 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.166 2026/10/30 01:34:10 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.167 2026/10/30 03:22:47 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -2560,6 +2560,8 @@ sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b) { int r; + if (key->sk_key_handle == NULL) + return SSH_ERR_INVALID_ARGUMENT; if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0 || (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||