#include "sslContext.h"
#include "sslUtils.h"
#include "sslMemory.h"
#include "sslDebug.h"
#include <Security/devrandom.h>
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include <sys/time.h>
UInt32
SSLDecodeInt(const unsigned char *p, int length)
{ UInt32 val = 0;
while (length--)
val = (val << 8) | *p++;
return val;
}
unsigned char *
SSLEncodeInt(unsigned char *p, UInt32 value, int length)
{ unsigned char *retVal = p + length;
assert(length > 0 && length <= 4);
while (length--)
{ p[length] = (UInt8)value;
value >>= 8;
}
return retVal;
}
UInt8*
SSLEncodeUInt64(UInt8 *p, sslUint64 value)
{ p = SSLEncodeInt(p, value.high, 4);
return SSLEncodeInt(p, value.low, 4);
}
void
IncrementUInt64(sslUint64 *v)
{ if (++v->low == 0)
++v->high;
}
UInt32
SSLGetCertificateChainLength(const SSLCertificate *c)
{
UInt32 rtn = 0;
while (c)
{
rtn++;
c = c->next;
}
return rtn;
}
Boolean sslIsSessionActive(const SSLContext *ctx)
{
assert(ctx != NULL);
switch(ctx->state) {
case SSL_HdskStateUninit:
case SSL_HdskStateServerUninit:
case SSL_HdskStateClientUninit:
case SSL_HdskStateGracefulClose:
case SSL_HdskStateErrorClose:
return false;
default:
return true;
}
}
OSStatus sslDeleteCertificateChain(
SSLCertificate *certs,
SSLContext *ctx)
{
SSLCertificate *cert;
SSLCertificate *nextCert;
assert(ctx != NULL);
cert=certs;
while(cert != NULL) {
nextCert = cert->next;
SSLFreeBuffer(cert->derCert, ctx);
sslFree(cert);
cert = nextCert;
}
return noErr;
}
#if SSL_DEBUG
const char *protocolVersStr(SSLProtocolVersion prot)
{
switch(prot) {
case SSL_Version_Undetermined: return "SSL_Version_Undetermined";
case SSL_Version_2_0: return "SSL_Version_2_0";
case SSL_Version_3_0: return "SSL_Version_3_0";
case TLS_Version_1_0: return "TLS_Version_1_0";
default: sslErrorLog("protocolVersStr: bad prot\n"); return "BAD PROTOCOL";
}
return NULL;
}
#endif
OSStatus sslIoRead(
SSLBuffer buf,
size_t *actualLength,
SSLContext *ctx)
{
UInt32 dataLength = buf.length;
OSStatus ortn;
*actualLength = 0;
ortn = (ctx->ioCtx.read)(ctx->ioCtx.ioRef,
buf.data,
&dataLength);
*actualLength = dataLength;
return ortn;
}
OSStatus sslIoWrite(
SSLBuffer buf,
size_t *actualLength,
SSLContext *ctx)
{
UInt32 dataLength = buf.length;
OSStatus ortn;
*actualLength = 0;
ortn = (ctx->ioCtx.write)(ctx->ioCtx.ioRef,
buf.data,
&dataLength);
*actualLength = dataLength;
return ortn;
}
OSStatus sslTime(UInt32 *tim)
{
time_t t;
time(&t);
*tim = (UInt32)t;
return noErr;
}
OSStatus sslRand(SSLContext *ctx, SSLBuffer *buf)
{
OSStatus serr = noErr;
assert(ctx != NULL);
assert(buf != NULL);
assert(buf->data != NULL);
if(buf->length == 0) {
sslErrorLog("sslRand: zero buf->length\n");
return noErr;
}
try {
Security::DevRandomGenerator devRand(false);
devRand.random(buf->data, buf->length);
}
catch(...) {
serr = errSSLCrypto;
}
return serr;
}
OSStatus sslVerifyProtVersion(
SSLContext *ctx,
SSLProtocolVersion peerVersion, SSLProtocolVersion *negVersion) {
OSStatus ortn = noErr;
switch(peerVersion) {
case SSL_Version_2_0:
if(ctx->versionSsl2Enable) {
*negVersion = SSL_Version_2_0;
}
else {
ortn = errSSLNegotiation;
}
break;
case SSL_Version_3_0:
if(ctx->versionSsl3Enable) {
*negVersion = SSL_Version_3_0;
}
else if(ctx->protocolSide == SSL_ClientSide) {
ortn = errSSLNegotiation;
}
else if(ctx->versionSsl2Enable) {
*negVersion = SSL_Version_2_0;
}
else {
ortn = errSSLNegotiation;
}
break;
case TLS_Version_1_0:
if(ctx->versionTls1Enable) {
*negVersion = TLS_Version_1_0;
}
else if(ctx->protocolSide == SSL_ClientSide) {
ortn = errSSLNegotiation;
}
else if(ctx->versionSsl3Enable) {
*negVersion = SSL_Version_3_0;
}
else if(ctx->versionSsl2Enable) {
*negVersion = SSL_Version_2_0;
}
else {
sslErrorLog("sslVerifyProtVersion: no protocols supported\n");
ortn = errSSLNegotiation;
}
break;
default:
ortn = errSSLNegotiation;
break;
}
return ortn;
}
OSStatus sslGetMaxProtVersion(
SSLContext *ctx,
SSLProtocolVersion *version) {
OSStatus ortn = noErr;
if(ctx->versionTls1Enable) {
*version = TLS_Version_1_0;
}
else if(ctx->versionSsl3Enable) {
*version = SSL_Version_3_0;
}
else if(ctx->versionSsl2Enable) {
*version = SSL_Version_2_0;
}
else {
ortn = paramErr;
}
return ortn;
}