Discussion:
Help please: SChannel, Security Contexts, and DecryptMessage
(too old to reply)
Jon G
2004-02-02 15:56:11 UTC
Permalink
I am writing a client application using CryptoAPI/SChannel to connect to the server over TLS/SSL. After the handshake completes, a few Receive/Decrypt and Encrypt/Send cycles go by without incident. On the third or fourth Receive/Decrypt, I get a return code of SEC_E_MESSAGE_ALTERED from DecryptMessage.

Then I noticed the following in the Platform SDK documentation:
'When using the Schannel SSP in "streaming" mode, that is, when the ISC_REQ_STREAM or ASC_REQ_STREAM flag was specified during the handshake, EncryptMessage or DecryptMessage cannot be called at the same time from multiple threads unless each thread has its own SSPI context because each encryption or decryption operation changes the internal state of the encryption key. If the encryption key states are not synchronized on the client and server, the decryption operation fails.'

My application does use separate send and receive threads in "streaming" mode, so I decided to give each thread it's own SSPI context using ExportSecurityContext and ImportSecurityContext to "copy" the single CtxtHandle that I was using before. (I'm not sure the CtxtHandle is even what the documentation is referring to by "SSPI context.") I ended up getting the same error at the same time. So I have a few questions...

1) Is this the proper way of giving each thread its own SSPI context the way I described above? If not, what is?
2) Why am I getting the SEC_E_MESSAGE_ALTERED error?
3) Do the above questions have anything to do with one another?

Any help is appreciated.
John Banes [MS]
2004-02-09 06:42:09 UTC
Permalink
You can encrypt and decrypt at the same time, because SSL has two keys--one
for encrypting and one for decrypting. The comment in the documentation is
trying to say that you can't encrypt using two threads at the same time
using the same context, and you can't decrypt using two threads at the same
time using the same context.

The usual reason that SEC_E_MESSAGE_ALTERED is returned is when the passed
in packet fails its MAC check after being decrypted. This happens when the
packet has been modified since it was encrypted. This can also happen when
the application is attempting to decrypt a packet using the wrong context
handle, or if packets are decrypted out of order.

Figuring out bugs in this area is often difficult, especially if the error
only happens rarely. I would suggest turning on page heap to spot memory
overruns. You can also dump out the buffers following the EncryptMemory
call, and compare these with the buffer passed to DecryptMemory to make sure
no bits have been modified. If you don't have access to both sides of the
connection then using a network sniffer can be substituted for one side or
the other.

Hope this helps!

Regards,
John Banes
[Microsoft Security Developer]

This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.
Post by Jon G
I am writing a client application using CryptoAPI/SChannel to connect to
the server over TLS/SSL. After the handshake completes, a few
Receive/Decrypt and Encrypt/Send cycles go by without incident. On the third
or fourth Receive/Decrypt, I get a return code of SEC_E_MESSAGE_ALTERED from
DecryptMessage.
Post by Jon G
'When using the Schannel SSP in "streaming" mode, that is, when the
ISC_REQ_STREAM or ASC_REQ_STREAM flag was specified during the handshake,
EncryptMessage or DecryptMessage cannot be called at the same time from
multiple threads unless each thread has its own SSPI context because each
encryption or decryption operation changes the internal state of the
encryption key. If the encryption key states are not synchronized on the
client and server, the decryption operation fails.'
Post by Jon G
My application does use separate send and receive threads in "streaming"
mode, so I decided to give each thread it's own SSPI context using
ExportSecurityContext and ImportSecurityContext to "copy" the single
CtxtHandle that I was using before. (I'm not sure the CtxtHandle is even
what the documentation is referring to by "SSPI context.") I ended up
getting the same error at the same time. So I have a few questions...
Post by Jon G
1) Is this the proper way of giving each thread its own SSPI context the
way I described above? If not, what is?
Post by Jon G
2) Why am I getting the SEC_E_MESSAGE_ALTERED error?
3) Do the above questions have anything to do with one another?
Any help is appreciated.
Al S.
2004-04-15 22:31:06 UTC
Permalink
This post might be inappropriate. Click to display it.
Vishal Mishra [MSFT]
2004-04-17 02:27:06 UTC
Permalink
So
- With NT4 Server and W2K or XP as client you are receiving 0x8009030f
(SEC_E_MESSAGE_ALTERED). Which function is returning this? ASC on the server
or ISC on the client? And is this during a normal handshake (no
renegotiation etc)?

As for the flags, please try
ASC_REQ_SEQUENCE_DETECT |
ASC_REQ_REPLAY_DETECT |
ASC_REQ_CONFIDENTIALITY |
ASC_REQ_EXTENDED_ERROR |
ASC_REQ_ALLOCATE_MEMORY | // depends if you are allocating
memory or asking Schannel to do it

ASC_REQ_STREAM
// the normal buffer layout described corresponds to this and not
ASC_REQ_CONNECTION.
--
------------------------------------------
Regards,
Vishal Mishra [MSFT]
This posting is provided "AS IS" with no warranties, and confers no rights.
I'm having problems similar to Jon G.
I have a client server application that works well between 2K and XP
systems but fails quickly between NT4 server and XP or 2K. I'm using
Accept/InitializeSecurityContext xxx_REQ_CONNECTION and xxx_REQ_IDENTIFY.
Data flows well in the clear but when I receive the message
0x8009030f: The message or signature supplied for verification has been altered
after a couple of exchanges with NT4. I can exchange jigabytes of
encrypted data between the 2K/XP systems.
As you suggested, I've printed out byte counts and checksums after
encrypting on the sender side and before decrypting on the receiver side
and things match up.
Is there something I'm missing?
Loading...