aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2020-07-11 21:57:30 -0400
committerGreg Hudson <ghudson@mit.edu>2020-07-22 15:16:27 -0400
commit3f204ddd567715ef360b4bb0b32961b6a9877f9d (patch)
treeb67204c8a29122bd2a73cc5f6e3e95df158b61ad
parent99f7ad2831a01f264c07eed42a0a3a9336b86184 (diff)
downloadkrb5-3f204ddd567715ef360b4bb0b32961b6a9877f9d.zip
krb5-3f204ddd567715ef360b4bb0b32961b6a9877f9d.tar.gz
krb5-3f204ddd567715ef360b4bb0b32961b6a9877f9d.tar.bz2
Allow gss_unwrap_iov() of unpadded RC4 tokens
Windows Remote Management, when used with an RC4 session key, appears to generate GSS wrap tokens with no padding instead of the expected one byte (RFC 4757 section 7.3). These tokens cannot be decoded with gss_unwrap() or a STREAM buffer (even with Microsoft SSPI), but SSPI allows them to be decoded using explicit IOVs with either a zero-length padding buffer or no padding buffer. Allow these cases to work in kg_fixup_padding_iov(). (It is already possible to make this work with HEADER | DATA | DATA, but only by accident--kg_fixup_padding_iov() doesn't find a data buffer because kg_locate_iov() only looks for singleton buffers, so it exits early.) ticket: 8926 (new) tags: pullup target_version: 1.18-next
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index c9aaafd..84f1949 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -649,16 +649,13 @@ kg_fixup_padding_iov(OM_uint32 *minor_status, gss_iov_buffer_desc *iov,
data = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_DATA);
padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
- if (data == NULL) {
+ /* Do nothing if padding is absent or empty, to allow unwrapping of WinRM
+ * unpadded RC4 tokens using an explicit IOV array. */
+ if (data == NULL || padding == NULL || padding->buffer.length == 0) {
*minor_status = 0;
return GSS_S_COMPLETE;
}
- if (padding == NULL || padding->buffer.length == 0) {
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
-
p = (unsigned char *)padding->buffer.value;
padlength = p[padding->buffer.length - 1];