Skip to content

Commit 217be6c

Browse files
github-actions[bot]filipnavaracarlossanlop
authored
Fix implementation of NegotiateAuthentication.Wrap for Kerberos on Windows (#91311)
Co-authored-by: Filip Navara <[email protected]> Co-authored-by: Carlos Sánchez López <[email protected]>
1 parent 2be287e commit 217be6c

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Windows.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -421,28 +421,32 @@ public override unsafe NegotiateAuthenticationStatusCode Wrap(ReadOnlySpan<byte>
421421
Debug.Assert(success);
422422

423423
// alloc new output buffer if not supplied or too small
424-
int resultSize = input.Length + sizes.cbMaxSignature;
424+
int resultSize = input.Length + sizes.cbSecurityTrailer + sizes.cbBlockSize;
425425
Span<byte> outputBuffer = outputWriter.GetSpan(resultSize);
426426

427427
// make a copy of user data for in-place encryption
428-
input.CopyTo(outputBuffer.Slice(sizes.cbMaxSignature, input.Length));
428+
input.CopyTo(outputBuffer.Slice(sizes.cbSecurityTrailer, input.Length));
429429

430430
isEncrypted = requestEncryption;
431431

432432
fixed (byte* outputPtr = outputBuffer)
433433
{
434434
// Prepare buffers TOKEN(signature), DATA and Padding.
435-
Interop.SspiCli.SecBuffer* unmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[2];
435+
Interop.SspiCli.SecBuffer* unmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[3];
436436
Interop.SspiCli.SecBuffer* tokenBuffer = &unmanagedBuffer[0];
437437
Interop.SspiCli.SecBuffer* dataBuffer = &unmanagedBuffer[1];
438+
Interop.SspiCli.SecBuffer* paddingBuffer = &unmanagedBuffer[2];
438439
tokenBuffer->BufferType = SecurityBufferType.SECBUFFER_TOKEN;
439440
tokenBuffer->pvBuffer = (IntPtr)(outputPtr);
440-
tokenBuffer->cbBuffer = sizes.cbMaxSignature;
441+
tokenBuffer->cbBuffer = sizes.cbSecurityTrailer;
441442
dataBuffer->BufferType = SecurityBufferType.SECBUFFER_DATA;
442-
dataBuffer->pvBuffer = (IntPtr)(outputPtr + sizes.cbMaxSignature);
443+
dataBuffer->pvBuffer = (IntPtr)(outputPtr + sizes.cbSecurityTrailer);
443444
dataBuffer->cbBuffer = input.Length;
445+
paddingBuffer->BufferType = SecurityBufferType.SECBUFFER_PADDING;
446+
paddingBuffer->pvBuffer = (IntPtr)(outputPtr + sizes.cbSecurityTrailer + input.Length);
447+
paddingBuffer->cbBuffer = sizes.cbBlockSize;
444448

445-
Interop.SspiCli.SecBufferDesc sdcInOut = new Interop.SspiCli.SecBufferDesc(2)
449+
Interop.SspiCli.SecBufferDesc sdcInOut = new Interop.SspiCli.SecBufferDesc(3)
446450
{
447451
pBuffers = unmanagedBuffer
448452
};
@@ -460,7 +464,20 @@ public override unsafe NegotiateAuthenticationStatusCode Wrap(ReadOnlySpan<byte>
460464
};
461465
}
462466

463-
outputWriter.Advance(tokenBuffer->cbBuffer + dataBuffer->cbBuffer);
467+
// Compact the result
468+
if (tokenBuffer->cbBuffer != sizes.cbSecurityTrailer)
469+
{
470+
outputBuffer.Slice(sizes.cbSecurityTrailer, dataBuffer->cbBuffer).CopyTo(
471+
outputBuffer.Slice(tokenBuffer->cbBuffer, dataBuffer->cbBuffer));
472+
}
473+
if (tokenBuffer->cbBuffer != sizes.cbSecurityTrailer ||
474+
paddingBuffer->cbBuffer != sizes.cbBlockSize)
475+
{
476+
outputBuffer.Slice(sizes.cbSecurityTrailer + input.Length, paddingBuffer->cbBuffer).CopyTo(
477+
outputBuffer.Slice(tokenBuffer->cbBuffer + dataBuffer->cbBuffer, paddingBuffer->cbBuffer));
478+
}
479+
480+
outputWriter.Advance(tokenBuffer->cbBuffer + dataBuffer->cbBuffer + paddingBuffer->cbBuffer);
464481
return NegotiateAuthenticationStatusCode.Completed;
465482
}
466483
}

0 commit comments

Comments
 (0)