Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

EncryptMessage returns SEC_E_INVALID_TOKEN

121 views
Skip to first unread message

Bruce Drake

unread,
Nov 30, 2009, 10:21:09 PM11/30/09
to
Hi

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;

vletoux

unread,
Dec 5, 2009, 6:30:28 AM12/5/09
to
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

Bruce Drake

unread,
Dec 9, 2009, 12:01:23 AM12/9/09
to
I thought the buffer sizes were given to you, i.e. the extra size is the
cbHeader and the cbTrailer;

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
>

Bruce Drake

unread,
Dec 15, 2009, 11:12:57 PM12/15/09
to
Just in case this is found in the future;

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

0 new messages