#include "sslContext.h"
#include "cryptType.h"
#include "sslMemory.h"
#include "sslDigests.h"
#include "sslDebug.h"
#include "appleCdsa.h"
#include <Security/cssm.h>
#include <string.h>
#define DIGEST_PRINT 0
#if DIGEST_PRINT
#define dgprintf(s) printf s
#else
#define dgprintf(s)
#endif
typedef struct {
CSSM_CC_HANDLE hashHand;
} cdsaHashContext;
const UInt8 SSLMACPad1[MAX_MAC_PADDING] =
{
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36
};
const UInt8 SSLMACPad2[MAX_MAC_PADDING] =
{
0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,
0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C,0x5C
};
OSStatus
CloneHashState(
const HashReference &ref,
const SSLBuffer &state,
SSLBuffer &newState,
SSLContext *ctx)
{
OSStatus err;
if ((err = SSLAllocBuffer(newState, ref.contextSize, ctx)) != 0)
return err;
return ref.clone(state, newState);
}
OSStatus
ReadyHash(const HashReference &ref, SSLBuffer &state, SSLContext *ctx)
{
OSStatus err;
if ((err = SSLAllocBuffer(state, ref.contextSize, ctx)) != 0)
return err;
return ref.init(state, ctx);
}
OSStatus CloseHash(const HashReference &ref, SSLBuffer &state, SSLContext *ctx)
{
OSStatus serr;
if(state.data == NULL) {
return noErr;
}
serr = ref.close(state, ctx);
if(serr) {
return serr;
}
return SSLFreeBuffer(state, ctx);
}
static OSStatus HashNullInit(SSLBuffer &digestCtx, SSLContext *sslCtx);
static OSStatus HashNullUpdate(SSLBuffer &digestCtx, const SSLBuffer &data);
static OSStatus HashNullFinal(SSLBuffer &digestCtx, SSLBuffer &digest);
static OSStatus HashNullClose(SSLBuffer &digestCtx, SSLContext *sslCtx);
static OSStatus HashNullClone(const SSLBuffer &src, SSLBuffer &dst);
static OSStatus HashMD5Init(SSLBuffer &digestCtx, SSLContext *sslCtx);
static OSStatus HashSHA1Init(SSLBuffer &digestCtx, SSLContext *sslCtx);
static OSStatus cdsaHashInit(SSLBuffer &digestCtx, SSLContext *sslCtx,
CSSM_ALGORITHMS digestAlg);
static OSStatus cdsaHashUpdate(SSLBuffer &digestCtx, const SSLBuffer &data);
static OSStatus cdsaHashFinal(SSLBuffer &digestCtx, SSLBuffer &digest);
static OSStatus cdsaHashClose(SSLBuffer &digestCtx, SSLContext *sslCtx);
static OSStatus cdsaHashClone(const SSLBuffer &src, SSLBuffer &dest);
const HashReference SSLHashNull =
{
0,
0,
0,
HashNullInit,
HashNullUpdate,
HashNullFinal,
HashNullClose,
HashNullClone
};
const HashReference SSLHashMD5 =
{
sizeof(cdsaHashContext),
16,
48,
HashMD5Init,
cdsaHashUpdate,
cdsaHashFinal,
cdsaHashClose,
cdsaHashClone
};
const HashReference SSLHashSHA1 =
{
sizeof(cdsaHashContext),
20,
40,
HashSHA1Init,
cdsaHashUpdate,
cdsaHashFinal,
cdsaHashClose,
cdsaHashClone
};
static OSStatus HashNullInit(SSLBuffer &digestCtx, SSLContext *sslCtx) {
return noErr;
}
static OSStatus HashNullUpdate(SSLBuffer &digestCtx, const SSLBuffer &data) {
return noErr;
}
static OSStatus HashNullFinal(SSLBuffer &digestCtx, SSLBuffer &digest) {
return noErr;
}
static OSStatus HashNullClose(SSLBuffer &digestCtx, SSLContext *sslCtx) {
return noErr;
}
static OSStatus HashNullClone(const SSLBuffer &src, SSLBuffer &dest) {
return noErr;
}
static OSStatus HashMD5Init(SSLBuffer &digestCtx, SSLContext *sslCtx)
{
assert(digestCtx.length >= sizeof(cdsaHashContext));
return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_MD5);
}
static OSStatus HashSHA1Init(SSLBuffer &digestCtx, SSLContext *sslCtx)
{
assert(digestCtx.length >= sizeof(cdsaHashContext));
return cdsaHashInit(digestCtx, sslCtx, CSSM_ALGID_SHA1);
}
static OSStatus cdsaHashInit(SSLBuffer &digestCtx,
SSLContext *sslCtx,
CSSM_ALGORITHMS digestAlg)
{
OSStatus serr;
cdsaHashContext *cdsaCtx;
CSSM_CC_HANDLE hashHand = 0;
CSSM_RETURN crtn;
assert(digestCtx.length >= sizeof(cdsaHashContext));
serr = attachToCsp(sslCtx); if(serr) {
return serr;
}
cdsaCtx = (cdsaHashContext *)digestCtx.data;
cdsaCtx->hashHand = 0;
dgprintf(("###cdsaHashInit cdsaCtx %p\n", cdsaCtx));
crtn = CSSM_CSP_CreateDigestContext(sslCtx->cspHand,
digestAlg,
&hashHand);
if(crtn) {
sslErrorLog("CSSM_CSP_CreateDigestContext failure\n");
return errSSLCrypto;
}
crtn = CSSM_DigestDataInit(hashHand);
if(crtn) {
CSSM_DeleteContext(hashHand);
sslErrorLog("CSSM_DigestDataInit failure\n");
return errSSLCrypto;
}
cdsaCtx->hashHand = hashHand;
return noErr;
}
static OSStatus cdsaHashUpdate(SSLBuffer &digestCtx, const SSLBuffer &data)
{
cdsaHashContext *cdsaCtx;
CSSM_RETURN crtn;
CSSM_DATA cdata;
assert(digestCtx.length >= sizeof(cdsaHashContext));
cdsaCtx = (cdsaHashContext *)digestCtx.data;
SSLBUF_TO_CSSM(&data, &cdata);
crtn = CSSM_DigestDataUpdate(cdsaCtx->hashHand, &cdata, 1);
if(crtn) {
sslErrorLog("CSSM_DigestDataUpdate failure\n");
return errSSLCrypto;
}
else {
return noErr;
}
}
static OSStatus cdsaHashFinal(SSLBuffer &digestCtx, SSLBuffer &digest)
{
cdsaHashContext *cdsaCtx;
CSSM_RETURN crtn;
CSSM_DATA cdata;
OSStatus srtn = noErr;
assert(digestCtx.length >= sizeof(cdsaHashContext));
cdsaCtx = (cdsaHashContext *)digestCtx.data;
dgprintf(("###cdsaHashFinal cdsaCtx %p\n", cdsaCtx));
SSLBUF_TO_CSSM(&digest, &cdata);
crtn = CSSM_DigestDataFinal(cdsaCtx->hashHand, &cdata);
if(crtn) {
sslErrorLog("CSSM_DigestDataFinal failure\n");
srtn = errSSLCrypto;
}
else {
digest.length = cdata.Length;
}
CSSM_DeleteContext(cdsaCtx->hashHand);
cdsaCtx->hashHand = 0;
return srtn;
}
static OSStatus cdsaHashClose(SSLBuffer &digestCtx, SSLContext *sslCtx)
{
cdsaHashContext *cdsaCtx;
assert(digestCtx.length >= sizeof(cdsaHashContext));
cdsaCtx = (cdsaHashContext *)digestCtx.data;
dgprintf(("###cdsaHashClose cdsaCtx %p\n", cdsaCtx));
if(cdsaCtx->hashHand != 0) {
CSSM_DeleteContext(cdsaCtx->hashHand);
cdsaCtx->hashHand = 0;
}
return noErr;
}
static OSStatus cdsaHashClone(const SSLBuffer &src, SSLBuffer &dst)
{
cdsaHashContext *srcCtx;
cdsaHashContext *dstCtx;
CSSM_RETURN crtn;
assert(src.length >= sizeof(cdsaHashContext));
assert(dst.length >= sizeof(cdsaHashContext));
srcCtx = (cdsaHashContext *)src.data;
dstCtx = (cdsaHashContext *)dst.data;
dgprintf(("###cdsaHashClone srcCtx %p dstCtx %p\n", srcCtx, dstCtx));
crtn = CSSM_DigestDataClone(srcCtx->hashHand, &dstCtx->hashHand);
if(crtn) {
sslErrorLog("CSSM_DigestDataClone failure\n");
return errSSLCrypto;
}
else {
return noErr;
}
}