Re: Schannel and Session Renegotiation
From: Vishal Mishra [MS] (vishalmi_at_online.microsoft.com)
Date: 09/04/03
- Next message: Joe Richards [MVP]: "Re: unlock Win2000 server"
- Previous message: Maur: "Make Money Now **This Really Works -just read- **"
- In reply to: Mark M.: "Re: Schannel and Session Renegotiation"
- Next in thread: Mark M.: "Re: Schannel and Session Renegotiation"
- Reply: Mark M.: "Re: Schannel and Session Renegotiation"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Date: Wed, 3 Sep 2003 15:18:42 -0700
Thanx for the in-depth analysis!
As you rightly observed, Schannel does not support the server sending app
data after sending a hello_request. It must receive a client_hello and
renegotiate a new handshake or else it will error out.
The RFC provides different ways for the server to react after sending a
hello_request, Schannel simply decided to support the below.
>From Section 7.4.1.1 Hello Request:
"If the server sends a hello request but does not receive a client hello in
response, it may close the connection with a fatal alert."
We are discussing the option of providing support for the client blowing off
the hello_request but I can't say if it be done.
I understand the requirements of long-lived sessions and thats where client
initiated renegotiation support came into the picture and was supported. I
don't see how the above support will effect that?
As for session renegotiation; Windows Server 2003, W2K SP5 and XP SP2
provide renegotiation support from both server and client side....:)
-- Vishal Mishra [MSFT] This posting is provided "AS IS" with no warranties and confers no rights. Use of any included samples is subject to the terms specified at http://www.microsoft.com/info/copyright.htm" ------------------------------------------------------------------------- "Mark M." <mark_NOSPAM_mullane@hotmail.com> wrote in message news:bj4lfo$hhv$1@kermit.esat.net... > Vishal - > > Thanks for your time & thoughts. Let me ask for clarification: > > > I looked deep into this and I am of the opinion now that after the server > > sends out a hello_request there is no way it SHOULD be sending any app > data. > > The implementation does not support it. > > Which of the following do you mean? > > 1. The server CANNOT send any app data after sending the HELLO_REQUEST as > the implementation(SChannel) does not support receipt of app data at any > stage once ISC has been called for the first time in a handshake loop. In > this case the server must be designed to "behave properly" with an Schannel > client. This is what I think you mean (& what I observe!) > > 2. The server SHOULD not send any app data as SSL does not support this. > This I do not believe to be true. An SSL implementation COULD and SHOULD > support the receipt of app data at certain stages of the renegotiation > handshake (both client AND server). Referring to you earlier comments below > : > > > > > This seems like an application dependent issue. If your server does > not > > > > require client_hello after requesting for it then it should start > sending > > > > the data out and the client should handle that like other app data. > The > > > > client did not send a client_hello so its not in the ISC/ASC handshake > dance > > > > but is in the loop where it accepts and decrypts data with the > existing > > > > session keys. > > The problem is that in the generic case the server does not KNOW apriori > whether or not the client > will support renegotiation! The spec says its optional for the client. So > the server continues sending > app data as you say. Then the client decides to renegotiate.This scheme > currently breaks with an SChannel client for reason 1 above! > So it seems I must force the server to wait until after the handshake is > complete before sending any more app > data. This present more problems: How do I find out if it completed ? (A > problem [not yours!] for some OPENSSL-based servers...!) How long do I give > the client to start & complete the renegotiation? I cannot assume/expect > it'll start immediatlely....etc.etc...) So you see - by not supporting > receipt of encrypted app data after handshake requests the option of the > client ignoring the request is effectively removed. I hope this will be > addressed in future versions of SChannel. > > This is not an easy issue & I appreciate you taking the time to think about > it. I think the SSL spec is sufficiently > loose on session renegotiation to allow for SSL implementors to be sloppy > with it. However, given the ever-increasing use of SSL beyond it original > design goals (in particular VPN - type apps, which could have very > long-lived sessions) its time the implementors took note. OpenSSL & SChannel > are probably the 2 most popular SSL implementations out there. OpenSSL has > (recently!) addressed session renegotiation. Perhaps its time MS did the > same with SChannel? > > Thanks again Vishal. > > Regards............... > > Mark. > > > > > > > > > "Vishal Mishra [MS]" <vishalmi@online.microsoft.com> wrote in message > news:O4GDoOYcDHA.3248@tk2msftngp13.phx.gbl... > > I looked deep into this and I am of the opinion now that after the server > > sends out a hello_request there is no way it SHOULD be sending any app > data. > > The implementation does not support it. > > > > -- > > Vishal Mishra [MSFT] > > This posting is provided "AS IS" with no warranties and confers no rights. > > Use of any included samples is subject to the terms specified at > > http://www.microsoft.com/info/copyright.htm" > > ------------------------------------------------------------------------- > > > > "Mark M." <mark_NOSPAM_mullane@hotmail.com> wrote in message > > news:bivhjp$n6q$1@kermit.esat.net... > > > Thanks Vishal for your detailed answer, which does help clear up some > > > issues, but unfortunately is not the answer I've been looking for..... > > > > > > I am interested in a situation where a "generic" SSL server wants to > > > re-negotiate the sesion keys...(definitely recomended for long-lived > > > sessions) ... but is happy to continue if the client decides its OK not > > to - > > > the client dictates policy in this regard. > > > So I guess as far as the server is concerned its scenario 3 that you > > > outlined below... > > > > > > The problem is that in this case the server should continue happily > > sending > > > app data UNTIL it gets a CLIENT_HELLO... (that seems reasonable > behaviour > > to > > > me, [e.g. in a proxy?] in the case where renegotiation is not > mandatory - > > it > > > is certainly allowed by the spec)....... > > > > > > --- SNIP --- > > > > > BUT: PROBLEM: When a client is in a "handshake loop" in it is > > entirely > > > > > possible to read() application layer records (not "handshake" > > records) > > > > > "from-the-wire" - sent by the server before IT received the initial > > > CLIENT_HELLO. > > > > > > > > [vishal mishra] The server does not (should not?, app dependent I > > beleive) > > > > send app data after requesting a renegotiation. It waits for the > client > > to > > > > send a client_hello and then depending on application, it can either > > close > > > > the connection with a fatal error or continue servicing client > requests. > > > TCP > > > > guarantees that client gets all app data before the hello_request. > > > > This seems like an application dependent issue. If your server does > not > > > > require client_hello after requesting for it then it should start > > sending > > > > the data out and the client should handle that like other app data. > The > > > > client did not send a client_hello so its not in the ISC/ASC handshake > > > dance > > > > but is in the loop where it accepts and decrypts data with the > existing > > > > session keys. > > > > > > > > > > --- END SNIP --- > > > > > > > > > From this answer it seems that SChannel will barf if it gets app data > > while > > > in the ASC/ISC handshake "dance". [ ISC = InitializeSecurityContext, ASC > = > > > AcceptSecurityContext] > > > > > > Q: IS THIS THE CASE?? > > > > > > I fear it is - and this is probably (?) related to why Client-side > > initiated > > > renegotiation is not supported. > > > > > > The core problem is that SChannel provides no way to distinguish app > data > > > from handshake data. Sure - DecryptMessage() "knows" about HELLO_REQUEST > > but > > > it seems that ISC cannot handle Encrypted Application data, and thats > what > > > is needed.......let me elborate.. > > > > > > It appears that SChannel only allows ISC calls with a NULL Security > > Context > > > (new session) or with an existing Security Context after receiving a > > > HELLO_REQUEST. After the first ISC call passing in empty buffers to > > generate > > > the CLIENT_HELLO, no application data is allowed until the handshake is > > > complete & ISC returns SEC_E_OK. This explains why Client-side initiated > > > renegotiations are not supported. In this case the server has no way of > > > knowing it should stop sending app data, hence ISC is potentially in > > > trouble.... > > > > > > For what its worth, a possible solution could be for ISC to return > > decrypted > > > app data with a specific rv (SEC_E_APP_DATA?) if it is received from the > > > server & passed into ISC during the initial stages of the handshake > loop > > > (before the app gets the SERVER_HELLO.) > > > Note that ISC must decrypt the encrypted handshake messages during a > > > renegotiation anyway... > > > it should be easy to recognise, decrypt & return app data. > > > Of course once the SERVER_HELLO IS received, app data is not allowed & > an > > > error should be returned if it is. > > > > > > What do you think MS....? > > > > > > As it stands, the server _cannot_ send app data after sending the > > > HELLO_REQUEST - it must continue to deal with incoming data on the old > > > session keys, but either die or forget about the renegotiaion request of > > it > > > does not get a CLIENT_HELLO within some app-dependent time (or received > > > number of data records...) > > > I must say the spec (see below) is loose on this point. > > > > > > --- SNIP --- > > > > RFC TLS1.0: http://www.ietf.org/rfc/rfc2246.txt > > > > 7.4.1.1. Hello request > > > > When this message will be sent: > > > > The hello request message may be sent by the server at any > time. > > > > Meaning of this message: > > > > Hello request is a simple notification that the client should > > > > begin the negotiation process anew by sending a client hello > > > > message when convenient. This message will be ignored by the > > > > client if the client is currently negotiating a session. This > > > > message may be ignored by the client if it does not wish to > > > > renegotiate a session, or the client may, if it wishes, respond > > > > with a no_renegotiation alert. Since handshake messages are > > > > intended to have transmission precedence over application data, > > > > it is expected that the negotiation will begin before no more > > > > than a few records are received from the client. If the server > > > > sends a hello request but does not receive a client hello in > > > > response, it may close the connection with a fatal alert. > > > > > > > > After sending a hello request, servers should not repeat the > request > > > > until the subsequent handshake negotiation is complete. > > > > > > --- END SNIP --- > > > > > > So can you confirm that ISC will not accept Encrypted App data before > the > > > ISC handshake loop returns SEC_E_OK ? > > > > > > Thanks again...... > > > > > > Regards...............Mark > > > > > > > > > > > > > > > > > > > > > "Vishal Mishra [MS]" <vishalmi@online.microsoft.com> wrote in message > > > news:OOWPoIabDHA.3080@TK2MSFTNGP11.phx.gbl... > > > > Server (non-anonymous) can ask for renegotiation in 3 cases: > > > > > > > > 1- Upfront the server can ask a client to authenticate and send the > > client > > > > certificate. This is during the initial handshake and the server sends > a > > > > "certificate_request" message (pass the flag bewlo to ASC and Schannel > > > does > > > > this) > > > > Server initiated renegotiation requires: > > > > dwSSPIFlags |= ASC_REQ_MUTUAL_AUTH; > > > > > > > > 2- After the initial handshake, the client requests an access > protected > > > > resource, then the server can initiate a renegotiation to ask for > client > > > > authentication. This is the case where the server sends the > > hello_request. > > > I > > > > have pasted the relevant portion from the RFC and how Schannel > generates > > > > this message via the code below. When the client reveices a > > hello_request > > > it > > > > then kicks off a new handshake by sending a client_hello. > > > > > > > > RFC TLS1.0: http://www.ietf.org/rfc/rfc2246.txt > > > > 7.4.1.1. Hello request > > > > When this message will be sent: > > > > The hello request message may be sent by the server at any > time. > > > > Meaning of this message: > > > > Hello request is a simple notification that the client should > > > > begin the negotiation process anew by sending a client hello > > > > message when convenient. This message will be ignored by the > > > > client if the client is currently negotiating a session. This > > > > message may be ignored by the client if it does not wish to > > > > renegotiate a session, or the client may, if it wishes, respond > > > > with a no_renegotiation alert. Since handshake messages are > > > > intended to have transmission precedence over application data, > > > > it is expected that the negotiation will begin before no more > > > > than a few records are received from the client. If the server > > > > sends a hello request but does not receive a client hello in > > > > response, it may close the connection with a fatal alert. > > > > > > > > After sending a hello request, servers should not repeat the > request > > > > until the subsequent handshake negotiation is complete. > > > > > > > > Structure of this message: > > > > struct { } HelloRequest; > > > > > > > > Note: This message should never be included in the message hashes > which > > > > are maintained throughout the handshake and used in the > finished > > > > messages and the certificate verify message. > > > > > > > > HOW Schannel generates hello_request: > > > > // > > > > // Build encrypted hello_request message. > > > > // > > > > > > > > dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT | > > > > ASC_REQ_REPLAY_DETECT | > > > > ASC_REQ_CONFIDENTIALITY | > > > > ASC_REQ_EXTENDED_ERROR | > > > > ASC_REQ_ALLOCATE_MEMORY | > > > > ASC_REQ_STREAM; > > > > > > > > InBuffers[0].BufferType = SECBUFFER_EMPTY; > > > > InBuffers[0].pvBuffer = NULL; > > > > InBuffers[0].cbBuffer = 0; > > > > > > > > InBuffer.ulVersion = SECBUFFER_VERSION; > > > > InBuffer.cBuffers = 1; > > > > InBuffer.pBuffers = InBuffers; > > > > > > > > OutBuffers[0].BufferType = SECBUFFER_TOKEN; > > > > OutBuffers[0].pvBuffer = NULL; > > > > OutBuffers[0].cbBuffer = 0; > > > > > > > > OutBuffer.ulVersion = SECBUFFER_VERSION; > > > > OutBuffer.cBuffers = 1; > > > > OutBuffer.pBuffers = OutBuffers; > > > > > > > > Status = g_SecurityFunc.AcceptSecurityContext > > > > ( > > > > hCred, > > > > hContext, > > > > &InBuffer, > > > > dwSSPIFlags, > > > > SECURITY_NATIVE_DREP, > > > > NULL, > > > > &OutBuffer, > > > > &dwSSPIOutFlags, > > > > NULL); > > > > > > > > 3- To refresh keys. > > > > This is application dependent. The RFC states above that the server > may > > > > close the connection if it does not receive a client_hello, this is > the > > > case > > > > where the server may not close the connection as its only wanting to > > > refresh > > > > keys and the client doesn't want to. The implementation is the same > way > > as > > > > above for case2. > > > > > > > > Also, some comments inline..... > > > > > > > > Hope this helps. If I have missed something then please ask again as > > this > > > > mail was a bit comprehensive to catch all queries..:) > > > > > > > > -- > > > > Vishal Mishra [MSFT] > > > > This posting is provided "AS IS" with no warranties and confers no > > rights. > > > > Use of any included samples is subject to the terms specified at > > > > http://www.microsoft.com/info/copyright.htm" > > > > > > > ------------------------------------------------------------------------- > > > > > > > > > > > > "Mark M." <mark_NOSPAM_mullane@hotmail.com> wrote in message > > > > news:bilj7p$5f2$1@kermit.esat.net... > > > > > Hi Folks - (in particular Vishal Mishra & John Banes from MS...) > > > > > > > > > > A question regarding SSL session key renegotiation in SChannel. > > > > > > > > > > (FYI - Vishal has previously pointed out that in fact CLIENT-side > > > > initiated > > > > > Session Renegotiation is NOT supported by SChannel on W2K(before > SP5) > > or > > > > WXP > > > > > (before SP2). The first time thats been mentioned anywhere by MS > > AFAIK) > > > > > > > > > > Anyway - here goes for SERVER-side initiated Renegotation (the usual > > > > > scenario...) > > > > > > > > > > Question: How are Encrypted Application Layer Records from the > server > > > > > handled by an Schannel client > > > > > during a Session renegotiation? > > > > > > > > > > Detail: > > > > > 1. A server requests a renegotiation by sending a HELLO_REQUEST, > that > > > the > > > > > clients DecrpytMessage() recognises by returning SEC_I_RENEGOTIATE. > > > > > > > > > > 2. The client can then kick off a new handshake loop at its leisure > > (the > > > > > server MAY enforce the renegotiation, or it may not). The client > could > > > in > > > > > fact ignore the request...lets say it'd like to comply..... > > > > > > > > [vishal mishra] The server SHOULD close the connection if the client > > does > > > > not send a client_hello as the resource requested requires > > authentication. > > > > The case where it may continue is when it wants to refresh keys and > the > > > > client disagrees. This is application dependent. > > > > > > > > > 3. The client makes repeated calls to InitializeSecurityContext() > > during > > > > the > > > > > handshake loop, the first one passing in empty buffers & building a > > > > > CLIENT_HELLO, which it sends back to the server begin the > > renegotiation > > > > > proper. > > > > > > > > > 4. The client read() 's data returned by the server & passes it into > > > > > InitializeSecurityContext() until complete.... > > > > > > > > > > > > > > BUT: PROBLEM: When a client is in a "handshake loop" in it is > > entirely > > > > > possible to read() application layer records (not "handshake" > > records) > > > > "from-the-wire" - > > > > > sent by the server before IT received the > > > > > initial CLIENT_HELLO. > > > > > > > > [vishal mishra] The server does not (should not?, app dependent I > > beleive) > > > > send app data after requesting a renegotiation. It waits for the > client > > to > > > > send a client_hello and then depending on application, it can either > > close > > > > the connection with a fatal error or continue servicing client > requests. > > > TCP > > > > guarantees that client gets all app data before the hello_request. > > > > This seems like an application dependent issue. If your server does > not > > > > require client_hello after requesting for it then it should start > > sending > > > > the data out and the client should handle that like other app data. > The > > > > client did not send a client_hello so its not in the ISC/ASC handshake > > > dance > > > > but is in the loop where it accepts and decrypts data with the > existing > > > > session keys. > > > > > > > > > If the SDK samples are followed, these records will all be handled > by > > > > > InitializeSecurityContext(). > > > > > This works fine if the records are indeed all handshake records, but > > > > > what is InitializeSecurityContext()'s behaviour if passed in data > that > > > > > contains an application layer record encrypted > > > > > with the "old" session keys? > > > > > > > > > > There is no reason for the server NOT to continue sending encrypted > > data > > > > > having requested a renegotiation, as it is allowed for the client to > > > > ignore > > > > > the renegotiate request! > > > > > > > > > Of course once the server receives the CLIENT_HELLO - it should stop > > > > sending > > > > > further encrypted data. > > > > > > > > > > One _could_ have a look at the records as they come in (during the > > > > handshake > > > > > loop) & explicitly check for handshake type messages > > > > > [first byte in the record - 0x17 for application layer data, 0x16 > for > > > > > Handshake messages] > > > > > Then pass any App records to DecryptMessage, until we get a > Handshake > > > > > message, at which point we continue > > > > > with our InitializeSecurityContext loop as normal. > > > > > [ Even then - whats to stop the Handshake message being another > > > > > HELLO_REQUEST, which is properly handled by DecryptMessage ???? ] > > > > > > > > > > But isn't the API supposed to take care of that kind of stuff.....? > > > > > > > > > Any further insight would be much appreciated. .......(a bit long I > > > know - > > > > > but then again what do you expect with such an unwieldy API.....) > > > > > > > > > > Thanks a lot folks > > > > > > > > > > Regards......................Mark. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
- Next message: Joe Richards [MVP]: "Re: unlock Win2000 server"
- Previous message: Maur: "Make Money Now **This Really Works -just read- **"
- In reply to: Mark M.: "Re: Schannel and Session Renegotiation"
- Next in thread: Mark M.: "Re: Schannel and Session Renegotiation"
- Reply: Mark M.: "Re: Schannel and Session Renegotiation"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|