sslHandshakeFinish.cpp [plain text]
#include "sslContext.h"
#include "sslHandshake.h"
#include "sslMemory.h"
#include "sslDebug.h"
#include "sslUtils.h"
#include "sslDigests.h"
#include <string.h>
#include <assert.h>
OSStatus
SSLEncodeFinishedMessage(SSLRecord &finished, SSLContext *ctx)
{ OSStatus err;
SSLBuffer finishedMsg, shaMsgState, md5MsgState;
Boolean isServerMsg;
unsigned finishedSize;
shaMsgState.data = 0;
md5MsgState.data = 0;
switch(ctx->negProtocolVersion) {
case SSL_Version_3_0:
finished.protocolVersion = SSL_Version_3_0;
finishedSize = 36;
break;
case TLS_Version_1_0:
finished.protocolVersion = TLS_Version_1_0;
finishedSize = 12;
break;
default:
assert(0);
return errSSLInternal;
}
finished.contentType = SSL_RecordTypeHandshake;
if ((err = SSLAllocBuffer(finished.contents, finishedSize + 4,
ctx)) != 0)
return err;
finished.contents.data[0] = SSL_HdskFinished;
SSLEncodeInt(finished.contents.data + 1, finishedSize, 3);
finishedMsg.data = finished.contents.data + 4;
finishedMsg.length = finishedSize;
if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
goto fail;
if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
goto fail;
isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? true : false;
if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, finishedMsg,
shaMsgState, md5MsgState, isServerMsg)) != 0)
goto fail;
fail:
SSLFreeBuffer(shaMsgState, ctx);
SSLFreeBuffer(md5MsgState, ctx);
return err;
}
OSStatus
SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
{ OSStatus err;
SSLBuffer expectedFinished, shaMsgState, md5MsgState;
Boolean isServerMsg;
unsigned finishedSize;
switch(ctx->negProtocolVersion) {
case SSL_Version_3_0:
finishedSize = 36;
break;
case TLS_Version_1_0:
finishedSize = 12;
break;
default:
assert(0);
return errSSLInternal;
}
if (message.length != finishedSize) {
sslErrorLog("SSLProcessFinished: msg len error 1\n");
return errSSLProtocol;
}
expectedFinished.data = 0;
if ((err = SSLAllocBuffer(expectedFinished, finishedSize, ctx)) != 0)
return err;
shaMsgState.data = 0;
if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
goto fail;
md5MsgState.data = 0;
if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
goto fail;
isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? false : true;
if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished,
shaMsgState, md5MsgState, isServerMsg)) != 0)
goto fail;
if (memcmp(expectedFinished.data, message.data, finishedSize) != 0)
{
sslErrorLog("SSLProcessFinished: memcmp failure\n");
err = errSSLProtocol;
goto fail;
}
fail:
SSLFreeBuffer(expectedFinished, ctx);
SSLFreeBuffer(shaMsgState, ctx);
SSLFreeBuffer(md5MsgState, ctx);
return err;
}
OSStatus
SSLEncodeServerHelloDone(SSLRecord &helloDone, SSLContext *ctx)
{ OSStatus err;
helloDone.contentType = SSL_RecordTypeHandshake;
assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
(ctx->negProtocolVersion == TLS_Version_1_0));
helloDone.protocolVersion = ctx->negProtocolVersion;
if ((err = SSLAllocBuffer(helloDone.contents, 4, ctx)) != 0)
return err;
helloDone.contents.data[0] = SSL_HdskServerHelloDone;
SSLEncodeInt(helloDone.contents.data+1, 0, 3);
return noErr;
}
OSStatus
SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
{ assert(ctx->protocolSide == SSL_ClientSide);
if (message.length != 0) {
sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
return errSSLProtocol;
}
return noErr;
}