How to send a close_notify at the end of an SSL connection

One of the more confusing parts of writing code to correctly work an SSL connection is the final act – the closure.

Here’s how to do it in Windows’ SChannel:

    // phCtx is the pointer to the context handle you’ve already been using for SSL.
static DWORD dwshut=SCHANNEL_SHUTDOWN; SecBuffer sbshut={sizeof(dwshut), SECBUFFER_TOKEN, &dwshut}; SecBufferDesc sdshut={SECBUFFER_VERSION,1,&sbshut}; DWORD sec_ret; sec_ret=s_pSecFuns->ApplyControlToken(phCtx,&sdshut); ASSERT(secret==SEC_E_OK); // You’ll want to do better handling than just “assert”. DWORD dwSSPIFlags=ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT | ASC_REQ_CONFIDENTIALITY | ASC_REQ_EXTENDED_ERROR | ASC_REQ_ALLOCATE_MEMORY | ASC_REQ_STREAM;
DWORD dwOutFlags=0; sbshut.BufferType=SECBUFFER_TOKEN; sbshut.cbBuffer=0; sbshut.pvBuffer=0; sdshut.cBuffers=1; sdshut.pBuffers=&sbshut; sec_ret=s_pSecFuns->AcceptSecurityContext(&tls_credhandle,phCtx, 0,dwSSPIFlags,SECURITY_NATIVE_DREP,0,&sdshut,&dwOutFlags,NULL);

At this point, you’ll need to send the contents of sbshut.pvBuffer (length is in sbshut.cbBuffer) in the stream (after anything else encrypted you’ve queued up), because it contains the close_notify message. You’ll likely have to read – and decrypt – more response back from your peer, checking for it to either close the stream, or send a matching close_notify.

[The documentation for DecryptMessage online at Microsoft's MSDN now correctly describes how to recognise and react to a peer's close_notify alert.]

After verifying that you’re receiving a close_notify from the other end, you’ll be in a loop with AcceptSecurityContext, responding to the peer, and sending what AcceptSecurityContext tells you to, until ASC (as we insiders call it) returns SEC_I_CONTEXT_EXPIRED or SEC_E_OK.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>