Skip to content

Commit 87957ca

Browse files
Include length when using krb5_c_decrypt()
For some enctypes, krb5_c_decrypt() will add padding bytes which are included in the returned length. However, functions which use the objects we're storing aren't always prepared for that: in particular, gss_import_cred() will declare a token invalid if there's trailing garbage. Work around this by including 4 bytes of length on encrypted objects. Signed-off-by: Robbie Harwood <[email protected]> Reviewed-by: Simo Sorce <[email protected]> Merges: #244
1 parent 84cf88f commit 87957ca

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/gp_export.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,16 +193,37 @@ uint32_t gp_init_creds_handle(uint32_t *min, const char *svc_name,
193193
return ret_maj;
194194
}
195195

196+
/* We need to include a length in our payloads because krb5_c_decrypt() will
197+
* pad the contents for some enctypes, and gss_import_cred() doesn't like
198+
* having extra bytes on tokens. */
196199
static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key,
197200
size_t len, void *buf, octet_string *out)
198201
{
199202
int ret;
200203
krb5_data data_in;
201204
krb5_enc_data enc_handle;
202205
size_t cipherlen;
206+
char *packed = NULL;
207+
uint32_t netlen;
203208

204-
data_in.length = len;
205-
data_in.data = buf;
209+
if (len > (uint32_t)(-1)) {
210+
/* Needs to fit in 4 bytes of payload, so... */
211+
ret = ENOMEM;
212+
goto done;
213+
}
214+
215+
packed = malloc(len);
216+
if (!packed) {
217+
ret = errno;
218+
goto done;
219+
}
220+
221+
netlen = htonl(len);
222+
memcpy(packed, (uint8_t *)&netlen, 4);
223+
memcpy(packed + 4, buf, len);
224+
225+
data_in.length = len + 4;
226+
data_in.data = packed;
206227

207228
memset(&enc_handle, '\0', sizeof(krb5_enc_data));
208229

@@ -240,16 +261,19 @@ static int gp_encrypt_buffer(krb5_context context, krb5_keyblock *key,
240261
}
241262

242263
done:
264+
free(packed);
243265
free(enc_handle.ciphertext.data);
244266
return ret;
245267
}
246268

269+
/* See comment above on gp_encrypt_buffer(). */
247270
static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key,
248-
octet_string *in, size_t *len, void *buf)
271+
octet_string *in, size_t *len, char *buf)
249272
{
250273
int ret;
251274
krb5_data data_out;
252275
krb5_enc_data enc_handle;
276+
uint32_t netlen;
253277

254278
memset(&enc_handle, '\0', sizeof(krb5_enc_data));
255279

@@ -270,7 +294,10 @@ static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key,
270294
return ret;
271295
}
272296

273-
*len = data_out.length;
297+
/* And handle the padding. */
298+
memcpy(&netlen, buf, 4);
299+
*len = ntohl(netlen);
300+
memmove(buf, buf + 4, *len);
274301

275302
return 0;
276303
}

0 commit comments

Comments
 (0)