Blame SOURCES/Include-length-when-using-krb5_c_decrypt.patch

4bd34d
From 5dec1aeb0a6080ea661061b52248e60afc969426 Mon Sep 17 00:00:00 2001
4bd34d
From: Robbie Harwood <rharwood@redhat.com>
4bd34d
Date: Tue, 16 Apr 2019 16:08:32 -0400
4bd34d
Subject: [PATCH] Include length when using krb5_c_decrypt()
4bd34d
4bd34d
For some enctypes, krb5_c_decrypt() will add padding bytes which are
4bd34d
included in the returned length.  However, functions which use the
4bd34d
objects we're storing aren't always prepared for that: in particular,
4bd34d
gss_import_cred() will declare a token invalid if there's trailing
4bd34d
garbage.
4bd34d
4bd34d
Work around this by including 4 bytes of length on encrypted objects.
4bd34d
4bd34d
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
4bd34d
Reviewed-by: Simo Sorce <simo@redhat.com>
4bd34d
Merges: #244
4bd34d
(cherry picked from commit 87957caf541114f6f15a495dd7d30556dc5801d9)
4bd34d
---
4bd34d
 src/gp_export.c | 35 +++++++++++++++++++++++++++++++----
4bd34d
 1 file changed, 31 insertions(+), 4 deletions(-)
4bd34d
4bd34d
diff --git a/src/gp_export.c b/src/gp_export.c
4bd34d
index 7ad8037..aa0a8ec 100644
4bd34d
--- a/src/gp_export.c
4bd34d
+++ b/src/gp_export.c
4bd34d
@@ -193,6 +193,9 @@ done:
4bd34d
     return ret_maj;
4bd34d
 }
4bd34d
 
4bd34d
+/* We need to include a length in our payloads because krb5_c_decrypt() will
4bd34d
+ * pad the contents for some enctypes, and gss_import_cred() doesn't like
4bd34d
+ * having extra bytes on tokens. */
4bd34d
 static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key,
4bd34d
                              size_t len, void *buf, octet_string *out)
4bd34d
 {
4bd34d
@@ -200,9 +203,27 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key,
4bd34d
     krb5_data data_in;
4bd34d
     krb5_enc_data enc_handle;
4bd34d
     size_t cipherlen;
4bd34d
+    char *packed = NULL;
4bd34d
+    uint32_t netlen;
4bd34d
 
4bd34d
-    data_in.length = len;
4bd34d
-    data_in.data = buf;
4bd34d
+    if (len > (uint32_t)(-1)) {
4bd34d
+        /* Needs to fit in 4 bytes of payload, so... */
4bd34d
+        ret = ENOMEM;
4bd34d
+        goto done;
4bd34d
+    }
4bd34d
+
4bd34d
+    packed = malloc(len);
4bd34d
+    if (!packed) {
4bd34d
+        ret = errno;
4bd34d
+        goto done;
4bd34d
+    }
4bd34d
+
4bd34d
+    netlen = htonl(len);
4bd34d
+    memcpy(packed, (uint8_t *)&netlen, 4);
4bd34d
+    memcpy(packed + 4, buf, len);
4bd34d
+
4bd34d
+    data_in.length = len + 4;
4bd34d
+    data_in.data = packed;
4bd34d
 
4bd34d
     memset(&enc_handle, '\0', sizeof(krb5_enc_data));
4bd34d
 
4bd34d
@@ -240,16 +261,19 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key,
4bd34d
     }
4bd34d
 
4bd34d
 done:
4bd34d
+    free(packed);
4bd34d
     free(enc_handle.ciphertext.data);
4bd34d
     return ret;
4bd34d
 }
4bd34d
 
4bd34d
+/* See comment above on gp_encrypt_buffer(). */
4bd34d
 static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key,
4bd34d
-                             octet_string *in, size_t *len, void *buf)
4bd34d
+                             octet_string *in, size_t *len, char *buf)
4bd34d
 {
4bd34d
     int ret;
4bd34d
     krb5_data data_out;
4bd34d
     krb5_enc_data enc_handle;
4bd34d
+    uint32_t netlen;
4bd34d
 
4bd34d
     memset(&enc_handle, '\0', sizeof(krb5_enc_data));
4bd34d
 
4bd34d
@@ -270,7 +294,10 @@ static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key,
4bd34d
         return ret;
4bd34d
     }
4bd34d
 
4bd34d
-    *len = data_out.length;
4bd34d
+    /* And handle the padding. */
4bd34d
+    memcpy(&netlen, buf, 4);
4bd34d
+    *len = ntohl(netlen);
4bd34d
+    memmove(buf, buf + 4, *len);
4bd34d
 
4bd34d
     return 0;
4bd34d
 }