When using the EncryptMessage (SChannel) from the win32 API with a valid
context after negotiation (I am supplying the four buffers in the
correct order) I get the SEC_E_INVALID_TOKEN response which according to
the documentation is No SECBUFFER_DATA type buffer was found.
I am using WIndows 7 Professional and Delphi 2010.
I have verified that the SECBUFFER_DATA is going in and it has the
correct data in it. Is there something further back in the "chain" that
could be wrong that I could check?
Why is no SECBUFFER_TOKEN required in the EncryptMessage?
I am using SP_PROT_TLS1_CLIENT and SP_PROT_TLS1_SERVER etc. Are there
restrictions on the crypto or I am getting a bogus error message, any
tips would be greatly appreciated.
Thanks, Bruce
The code is the following;
procedure TSecureChannel.Encrypt(InData: PAnsiChar; InDataLength: Cardinal);
var
IoBuffer: PAnsiChar;
IoBufferLength: DWORD;
SecBufDesc: TSecBufferDesc;
SecBufs: packed array [0 .. 3] of TSecBuffer;
SecStatus: TSecurityStatus;
begin
IoBufferLength := FSecPkgSizes.cbHeader + InDataLength +
FSecPkgSizes.cbTrailer;
IoBuffer := AllocMem(IoBufferLength);
Move(InData[0], IoBuffer[FSecPkgSizes.cbHeader], InDataLength);
SecBufs[0].BufferType := SECBUFFER_STREAM_HEADER;
SecBufs[0].cbBuffer := FSecPkgSizes.cbHeader;
SecBufs[0].pvBuffer := IoBuffer;
SecBufs[1].BufferType := SECBUFFER_DATA;
SecBufs[1].cbBuffer := InDataLength;
SecBufs[1].pvBuffer := IoBuffer + FSecPkgSizes.cbHeader;
SecBufs[2].BufferType := SECBUFFER_STREAM_TRAILER;
SecBufs[2].cbBuffer := FSecPkgSizes.cbTrailer;
SecBufs[2].pvBuffer := IoBuffer + FSecPkgSizes.cbHeader + InDataLength;
SecBufs[3].BufferType := SECBUFFER_EMPTY;
SecBufs[3].cbBuffer := 0;
SecBufs[3].pvBuffer := nil;
SecBufDesc.ulVersion := SECBUFFER_VERSION;
SecBufDesc.cBuffers := 4;
SecBufDesc.pBuffers := @SecBufs[0];
SecStatus := EncryptMessage(FContext, 0, @SecBufDesc, 0);
if SecStatus <> SEC_E_OK then
begin
OnErrorEvent('::Encrypt; EncryptMessage Error
'SecStatusToMsg(SecStatus), SecStatus);
end;
end;
I think the returned data is larger than the decrypted data.
Personnaly, I'm using 8kB buffer ...
Regards,
Vincent
totalBufferLength = secPkgSizes.cbHeader + inDataLength +
secPkgSizes.cbTrailer;
So I am not sure what you mean by 8k buffer? What happens when you get a
message that is exactly 8k? I tried a 16k buffer and I have verified
also that the EncryptMessage is getting the data via injecting
STRACE.DLL into the running executable and I get this;
12/07/2009 23:10:30:635 - SecBuffer #0 BufferType:0x00000007 cbBuffer:5
12/07/2009 23:10:30:636 - SecBuffer #1 BufferType:0x00000001 cbBuffer:13
12/07/2009 23:10:30:636 - SECBUFFER_DATA - 13 byte(s) / EncryptMessage -
INPUT
=====================================================
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 0123456789abcdef
0000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 21 00 hello world!.
=====================================================
12/07/2009 23:10:30:636 - SecBuffer #2 BufferType:0x00000006 cbBuffer:36
12/07/2009 23:10:30:636 - SecBuffer #3 BufferType:0x00000000 cbBuffer:0
12/07/2009 23:10:30:636 -
*** WARNING : EncryptMessage failed (80090308) ***
Bruce
vletoux wrote:
> Assert that you have enough spaces in your buffer.
>
> I think the returned data is larger than the decrypted data.
>
> Personnaly, I'm using 8kB buffer ...
>
> Regards,
> Vincent
>
When you set up your context on both client and server using;
InitializeSecurityContext // Schannel Client
AcceptSecurityContext // Schannel Server
pay very special care to the flags you pass in for the type of context
you want as that determines the types of SecBuffer(s) that you need for
both EncryptMessage and DecryptMessage. For instance I am currently using;
FClientContextFlags :=
ISC_REQ_CONFIDENTIALITY or
ISC_REQ_STREAM or
ISC_REQ_ALLOCATE_MEMORY;
FServerContextFlags :=
ASC_REQ_CONFIDENTIALITY or
ASC_REQ_STREAM or
ASC_REQ_ALLOCATE_MEMORY;
which means that for EncryptMessage you need four SecBuffers of;
SECBUFFER_STREAM_HEADER
SECBUFFER_DATA
SECBUFFER_STREAM_TRAILER
SECBUFFER_EMPTY
and for DecryptMessage you also need four SecBuffers of;
SECBUFFER_DATA
SECBUFFER_EMPTY
SECBUFFER_EMPTY
SECBUFFER_EMPTY
My problem was that I had *_REQ_STREAM and *_REQ_CONNECTION which on
closer reading of the documentation are essentially incompatible. This
is on top of making sure you have a valid certificate/trusted etc.
I hope this helps someone.
Bruce