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

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