sslHandshakeFinish.c [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;
Boolean isServerMsg;
unsigned finishedSize;
UInt8 *p;
int head;
switch(ctx->negProtocolVersion) {
case SSL_Version_3_0:
finishedSize = 36;
break;
case DTLS_Version_1_0:
case TLS_Version_1_0:
case TLS_Version_1_1:
case TLS_Version_1_2:
finishedSize = 12;
break;
default:
assert(0);
return errSSLInternal;
}
finished->protocolVersion = ctx->negProtocolVersion;
finished->contentType = SSL_RecordTypeHandshake;
head = SSLHandshakeHeaderSize(finished);
if ((err = SSLAllocBuffer(&finished->contents, finishedSize + head,
ctx)) != 0)
return err;
p = SSLEncodeHandshakeHeader(ctx, finished, SSL_HdskFinished, finishedSize);
finishedMsg.data = p;
finishedMsg.length = finishedSize;
isServerMsg = (ctx->protocolSide == kSSLServerSide) ? true : false;
err = ctx->sslTslCalls->computeFinishedMac(ctx, finishedMsg, isServerMsg);
if(err)
return err;
SSLFreeBuffer(&ctx->ownVerifyData, ctx);
return SSLCopyBuffer(&finishedMsg, &ctx->ownVerifyData);
}
OSStatus
SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
{ OSStatus err;
SSLBuffer expectedFinished;
Boolean isServerMsg;
unsigned finishedSize;
switch(ctx->negProtocolVersion) {
case SSL_Version_3_0:
finishedSize = 36;
break;
case DTLS_Version_1_0:
case TLS_Version_1_0:
case TLS_Version_1_1:
case TLS_Version_1_2:
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;
isServerMsg = (ctx->protocolSide == kSSLServerSide) ? false : true;
if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished, isServerMsg)) != 0)
goto fail;
if (memcmp(expectedFinished.data, message.data, finishedSize) != 0)
{
sslErrorLog("SSLProcessFinished: memcmp failure\n");
err = errSSLProtocol;
goto fail;
}
SSLFreeBuffer(&ctx->peerVerifyData, ctx);
err = SSLCopyBuffer(&expectedFinished, &ctx->peerVerifyData);
fail:
SSLFreeBuffer(&expectedFinished, ctx);
return err;
}
OSStatus
SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx)
{ OSStatus err;
int head;
helloDone->contentType = SSL_RecordTypeHandshake;
assert(ctx->negProtocolVersion >= SSL_Version_3_0);
helloDone->protocolVersion = ctx->negProtocolVersion;
head = SSLHandshakeHeaderSize(helloDone);
if ((err = SSLAllocBuffer(&helloDone->contents, head, ctx)) != 0)
return err;
SSLEncodeHandshakeHeader(ctx, helloDone, SSL_HdskServerHelloDone, 0);
return noErr;
}
OSStatus
SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
{ assert(ctx->protocolSide == kSSLClientSide);
if (message.length != 0) {
sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
return errSSLProtocol;
}
return noErr;
}