#ifndef _SSL_H_
#include "ssl.h"
#endif
#ifndef _SSLCTX_H_
#include "sslctx.h"
#endif
#ifndef _SSLSESS_H_
#include "sslsess.h"
#endif
#ifndef _SSLALLOC_H_
#include "sslalloc.h"
#endif
#ifndef _SSLUTIL_H_
#include "sslutil.h"
#endif
#ifndef _SSL_DEBUG_H_
#include "sslDebug.h"
#endif
#ifndef _CIPHER_SPECS_H_
#include "cipherSpecs.h"
#endif
#ifdef _APPLE_CDSA_
#ifndef _APPLE_SESSION_H_
#include "appleSession.h"
#endif
#endif
#include <string.h>
#include <stddef.h>
typedef struct
{ int sessionIDLen;
UInt8 sessionID[32];
SSLProtocolVersion protocolVersion;
UInt16 cipherSuite;
UInt8 masterSecret[48];
int certCount;
UInt8 certs[1];
} ResumableSession;
SSLErr
SSLAddSessionID(const SSLContext *ctx)
{ SSLErr err;
uint32 sessionIDLen;
SSLBuffer sessionID;
ResumableSession *session;
int certCount;
SSLCertificate *cert;
uint8 *certDest;
if (ctx->peerID.data == 0)
return SSLSessionNotFoundErr;
sessionIDLen = offsetof(ResumableSession, certs);
cert = ctx->peerCert;
certCount = 0;
while (cert)
{ ++certCount;
sessionIDLen += 4 + cert->derCert.length;
cert = cert->next;
}
if ((err = SSLAllocBuffer(&sessionID, sessionIDLen, &ctx->sysCtx)) != 0)
return err;
session = (ResumableSession*)sessionID.data;
session->sessionIDLen = ctx->sessionID.length;
memcpy(session->sessionID, ctx->sessionID.data, session->sessionIDLen);
session->protocolVersion = ctx->negProtocolVersion;
session->cipherSuite = ctx->selectedCipher;
memcpy(session->masterSecret, ctx->masterSecret, 48);
session->certCount = certCount;
certDest = session->certs;
cert = ctx->peerCert;
while (cert)
{ certDest = SSLEncodeInt(certDest, cert->derCert.length, 4);
memcpy(certDest, cert->derCert.data, cert->derCert.length);
certDest += cert->derCert.length;
cert = cert->next;
}
#ifdef _APPLE_CDSA_
err = sslAddSession(ctx->peerID, sessionID, ctx->sessionCtx.sessionRef);
#else
err = ctx->sessionCtx.addSession(ctx->peerID, sessionID, ctx->sessionCtx.sessionRef);
#endif
SSLFreeBuffer(&sessionID, &ctx->sysCtx);
return err;
}
SSLErr
SSLGetSessionID(SSLBuffer *sessionData, const SSLContext *ctx)
{ SSLErr err;
if (ctx->peerID.data == 0)
return ERR(SSLSessionNotFoundErr);
sessionData->data = 0;
#ifdef _APPLE_CDSA_
err = sslGetSession(ctx->peerID, sessionData, ctx->sessionCtx.sessionRef);
#else
ERR(err = ctx->sessionCtx.getSession(ctx->peerID, sessionData, ctx->sessionCtx.sessionRef));
#endif
if (sessionData->data == 0)
return ERR(SSLSessionNotFoundErr);
return err;
}
SSLErr
SSLDeleteSessionID(const SSLContext *ctx)
{ SSLErr err;
if (ctx->peerID.data == 0)
return SSLSessionNotFoundErr;
#ifdef _APPLE_CDSA_
err = sslDeleteSession(ctx->peerID, ctx->sessionCtx.sessionRef);
#else
err = ctx->sessionCtx.deleteSession(ctx->peerID, ctx->sessionCtx.sessionRef);
#endif
return err;
}
SSLErr
SSLRetrieveSessionIDIdentifier(
const SSLBuffer sessionData,
SSLBuffer *identifier,
const SSLContext *ctx)
{ SSLErr err;
ResumableSession *session;
session = (ResumableSession*) sessionData.data;
if ((err = SSLAllocBuffer(identifier, session->sessionIDLen, &ctx->sysCtx)) != 0)
return err;
memcpy(identifier->data, session->sessionID, session->sessionIDLen);
return SSLNoErr;
}
SSLErr
SSLRetrieveSessionIDProtocolVersion(
const SSLBuffer sessionID,
SSLProtocolVersion *version,
const SSLContext *ctx)
{ ResumableSession *session;
session = (ResumableSession*) sessionID.data;
*version = session->protocolVersion;
return SSLNoErr;
}
SSLErr
SSLInstallSessionID(const SSLBuffer sessionData, SSLContext *ctx)
{ SSLErr err;
ResumableSession *session;
uint8 *storedCertProgress;
SSLCertificate *cert, *lastCert;
#ifndef __APPLE__
SSLBuffer certAlloc;
#endif
int certCount;
uint32 certLen;
session = (ResumableSession*)sessionData.data;
CASSERT(ctx->negProtocolVersion == session->protocolVersion);
ctx->selectedCipher = session->cipherSuite;
if ((err = FindCipherSpec(ctx)) != 0) {
return err;
}
memcpy(ctx->masterSecret, session->masterSecret, 48);
lastCert = 0;
storedCertProgress = session->certs;
certCount = session->certCount;
while (certCount--)
{
#ifdef __APPLE__
cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
if(cert == NULL) {
return SSLMemoryErr;
}
#else
if ((err = SSLAllocBuffer(&certAlloc, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
return err;
cert = (SSLCertificate*)certAlloc.data;
#endif
cert->next = 0;
certLen = SSLDecodeInt(storedCertProgress, 4);
storedCertProgress += 4;
if ((err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
{
#ifdef __APPLE__
sslFree(cert);
#else
SSLFreeBuffer(&certAlloc,&ctx->sysCtx);
#endif
return err;
}
memcpy(cert->derCert.data, storedCertProgress, certLen);
storedCertProgress += certLen;
#ifndef _APPLE_CDSA_
if ((err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
{
SSLFreeBuffer(&cert->derCert,&ctx->sysCtx);
#ifdef __APPLE__
sslFree(cert);
#else
SSLFreeBuffer(&certAlloc,&ctx->sysCtx);
#endif
return err;
}
#endif
if (lastCert == 0)
ctx->peerCert = cert;
else
lastCert->next = cert;
lastCert = cert;
}
return SSLNoErr;
}