#include "sslContext.h"
#include "sslHandshake.h"
#include "sslMemory.h"
#include "sslAlertMessage.h"
#include "sslDebug.h"
#include "sslCipherSpecs.h"
#include <assert.h>
#include <string.h>
OSStatus
SSLEncodeChangeCipherSpec(SSLRecord *rec, SSLContext *ctx)
{ OSStatus err;
assert(ctx->writePending_ready);
sslLogNegotiateDebug("===Sending changeCipherSpec msg");
rec->contentType = SSL_RecordTypeChangeCipher;
assert(ctx->negProtocolVersion >= SSL_Version_3_0);
rec->protocolVersion = ctx->negProtocolVersion;
rec->contents.length = 1;
if ((err = SSLAllocBuffer(&rec->contents, 1)))
return err;
rec->contents.data[0] = 1;
ctx->messageQueueContainsChangeCipherSpec=true;
return errSecSuccess;
}
OSStatus
SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx)
{ OSStatus err;
if (rec.contents.length != 1 || rec.contents.data[0] != 1)
{
if(ctx->isDTLS)
return errSSLWouldBlock;
SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
sslErrorLog("***bad changeCipherSpec msg: length %d data 0x%x\n",
(unsigned)rec.contents.length, (unsigned)rec.contents.data[0]);
return errSSLProtocol;
}
if((ctx->protocolSide == kSSLClientSide) &&
(ctx->sessionTicket.length != 0) &&
((ctx->state == SSL_HdskStateKeyExchange) || (ctx->state == SSL_HdskStateCert)) &&
(ctx->masterSecretCallback != NULL)) {
size_t secretLen = SSL_MASTER_SECRET_SIZE;
sslEapDebug("Client side resuming based on masterSecretCallback");
ctx->masterSecretCallback(ctx, ctx->masterSecretArg,
ctx->masterSecret, &secretLen);
ctx->sessionMatch = 1;
if ((err = FindCipherSpec(ctx)) != 0) {
return err;
}
if((err = SSLInitPendingCiphers(ctx)) != 0) {
SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
return err;
}
SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
}
if (!ctx->readPending_ready || ctx->state != SSL_HdskStateChangeCipherSpec)
{
if(ctx->isDTLS)
return errSSLWouldBlock;
SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
sslErrorLog("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
(unsigned)ctx->readPending_ready, (unsigned)ctx->state);
return errSSLProtocol;
}
sslLogNegotiateDebug("===Processing changeCipherSpec msg");
if ((err = ctx->recFuncs->advanceReadCipher(ctx->recCtx)) != 0)
{ SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
return err;
}
ctx->readCipher_ready = 0;
SSLChangeHdskState(ctx, SSL_HdskStateFinished);
return errSecSuccess;
}