Commit aa4802204b for openssl.org

commit aa4802204b7f9ef1af23a046886b9124061c14a6
Author: Viktor Dukhovni <openssl-users@dukhovni.org>
Date:   Tue Jan 13 19:34:54 2026 +1100

    Enable signing of empty files with pkeyutl

    The allocated buffer for the file contents is then zero bytes long,
    which `app_malloc()` used to refuse.

    Reviewed-by: Matt Caswell <matt@openssl.org>
    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    MergeDate: Tue Jan 20 18:17:12 2026
    (Merged from https://github.com/openssl/openssl/pull/29613)

diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
index 59b061b7d9..bbeed96856 100644
--- a/apps/pkeyutl.c
+++ b/apps/pkeyutl.c
@@ -837,7 +837,8 @@ static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx,
                 "Error: unable to determine file size for oneshot operation\n");
             goto end;
         }
-        mbuf = app_malloc(filesize, "oneshot sign/verify buffer");
+        if (filesize > 0)
+            mbuf = app_malloc(filesize, "oneshot sign/verify buffer");
         switch (pkey_op) {
         case EVP_PKEY_OP_VERIFY:
             buf_len = BIO_read(in, mbuf, filesize);
diff --git a/apps/s_client.c b/apps/s_client.c
index d061143326..7fd6fa229b 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -346,15 +346,22 @@ static ossl_ssize_t hexdecode(const char **inptr, void *result)
 {
     unsigned char **out = (unsigned char **)result;
     const char *in = *inptr;
-    unsigned char *ret = app_malloc(strlen(in) / 2, "hexdecode");
-    unsigned char *cp = ret;
+    size_t retlen = strlen(in) / 2;
+    unsigned char *ret = NULL, *cp;
     uint8_t byte;
     int nibble = 0;

-    if (ret == NULL)
+    if (retlen > 0) {
+        if ((ret = app_malloc(retlen, "hexdecode")) == NULL)
+            return -1;
+    } else if (*in == '\0') {
+        *out = NULL;
+        return 0;
+    } else {
         return -1;
+    }

-    for (byte = 0; *in; ++in) {
+    for (cp = ret, byte = 0; *in; ++in) {
         int x;

         if (isspace(_UC(*in)))
@@ -425,9 +432,7 @@ static int tlsa_import_rr(SSL *con, const char *rrdata)
         { &selector, "selector", checked_uint8 },
         { &mtype, "mtype", checked_uint8 },
         { &data, "data", hexdecode },
-        {
-            NULL,
-        }
+        { NULL, NULL, NULL },
     };
     struct tlsa_field *f;
     int ret;
diff --git a/apps/s_server.c b/apps/s_server.c
index 2846ade6b5..79a3014542 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -3435,7 +3435,7 @@ static void print_connection_info(SSL *con)
     if ((SSL_get_options(con) & SSL_OP_NO_RENEGOTIATION))
         BIO_printf(bio_s_out, "Renegotiation is DISABLED\n");

-    if (keymatexportlabel != NULL) {
+    if (keymatexportlabel != NULL && keymatexportlen > 0) {
         BIO_printf(bio_s_out, "Keying material exporter:\n");
         BIO_printf(bio_s_out, "    Label: '%s'\n", keymatexportlabel);
         BIO_printf(bio_s_out, "    Length: %i bytes\n", keymatexportlen);
@@ -4134,7 +4134,7 @@ static int add_session(SSL *ssl, SSL_SESSION *session)

     SSL_SESSION_get_id(session, &sess->idlen);
     sess->derlen = i2d_SSL_SESSION(session, NULL);
-    if (sess->derlen < 0) {
+    if (sess->derlen <= 0) {
         BIO_printf(bio_err, "Error encoding session\n");
         OPENSSL_free(sess);
         return 0;