add useratomic DecryptVerify Callbacks, example

This commit is contained in:
toddouska 2013-08-21 16:55:34 -07:00
parent 442886a207
commit 54a2f8b9aa
5 changed files with 315 additions and 133 deletions

View File

@ -1261,7 +1261,8 @@ struct CYASSL_CTX {
TLSX* extensions; /* RFC 6066 TLS Extensions data */
#endif
#ifdef ATOMIC_USER
CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Callback */
CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Cb */
CallbackDecryptVerify DecryptVerifyCb; /* Atomic User Decrypt/Verify Cb */
#endif
};
@ -1403,6 +1404,7 @@ typedef struct Keys {
#endif
word32 encryptSz; /* last size of encrypted data */
word32 padSz; /* how much to advance after decrypt part */
byte encryptionOn; /* true after change cipher spec */
byte decryptedCur; /* only decrypt current record once */
} Keys;
@ -1826,7 +1828,8 @@ struct CYASSL {
#endif
CYASSL_ALERT_HISTORY alert_history;
#ifdef ATOMIC_USER
void* MacEncryptCtx; /* Atomic User Mac/Encrypt Callback Context */
void* MacEncryptCtx; /* Atomic User Mac/Encrypt Callback Context */
void* DecryptVerifyCtx; /* Atomic User Decrypt/Verify Callback Context */
#endif
};

View File

@ -948,6 +948,14 @@ CYASSL_API void CyaSSL_CTX_SetMacEncryptCb(CYASSL_CTX*, CallbackMacEncrypt);
CYASSL_API void CyaSSL_SetMacEncryptCtx(CYASSL* ssl, void *ctx);
CYASSL_API void* CyaSSL_GetMacEncryptCtx(CYASSL* ssl);
typedef int (*CallbackDecryptVerify)(CYASSL* ssl,
unsigned char* decOut, const unsigned char* decIn,
unsigned int decSz, int content, int verify, unsigned int* padSz,
void* ctx);
CYASSL_API void CyaSSL_CTX_SetDecryptVerifyCb(CYASSL_CTX*,
CallbackDecryptVerify);
CYASSL_API void CyaSSL_SetDecryptVerifyCtx(CYASSL* ssl, void *ctx);
CYASSL_API void* CyaSSL_GetDecryptVerifyCtx(CYASSL* ssl);
CYASSL_API const unsigned char* CyaSSL_GetMacSecret(CYASSL*, int);
CYASSL_API const unsigned char* CyaSSL_GetClientWriteKey(CYASSL*);
@ -956,9 +964,13 @@ CYASSL_API const unsigned char* CyaSSL_GetServerWriteKey(CYASSL*);
CYASSL_API const unsigned char* CyaSSL_GetServerWriteIV(CYASSL*);
CYASSL_API int CyaSSL_GetKeySize(CYASSL*);
CYASSL_API int CyaSSL_GetSide(CYASSL*);
CYASSL_API int CyaSSL_IsTLSv1_1(CYASSL*);
CYASSL_API int CyaSSL_GetBulkCipher(CYASSL*);
CYASSL_API int CyaSSL_GetCipherBlockSize(CYASSL*);
CYASSL_API int CyaSSL_GetAeadMacSize(CYASSL*);
CYASSL_API int CyaSSL_GetHmacSize(CYASSL*);
CYASSL_API int CyaSSL_GetHmacType(CYASSL*);
CYASSL_API int CyaSSL_GetCipherType(CYASSL*);
CYASSL_API int CyaSSL_SetTlsHmacInner(CYASSL*, unsigned char*,
unsigned int, int, int);
@ -966,6 +978,9 @@ CYASSL_API int CyaSSL_SetTlsHmacInner(CYASSL*, unsigned char*,
enum {
CYASSL_SERVER_END = 0,
CYASSL_CLIENT_END = 1,
CYASSL_BLOCK_TYPE = 2,
CYASSL_STREAM_TYPE = 3,
CYASSL_AEAD_TYPE = 4,
CYASSL_TLS_HMAC_INNER_SZ = 13 /* SEQ_SZ + ENUM + VERSION_SZ + LEN_SZ */
};

View File

@ -1301,6 +1301,13 @@ typedef struct AtomicEncCtx {
} AtomicEncCtx;
/* Atomic Decrypt Context example */
typedef struct AtomicDecCtx {
int keySetup; /* have we done key setup yet */
Aes aes; /* for aes example */
} AtomicDecCtx;
static INLINE int myMacEncryptCb(CYASSL* ssl, unsigned char* macOut,
const unsigned char* macIn, unsigned int macInSz, int macContent,
int macVerify, unsigned char* encOut, const unsigned char* encIn,
@ -1360,24 +1367,126 @@ static INLINE int myMacEncryptCb(CYASSL* ssl, unsigned char* macOut,
return AesCbcEncrypt(&encCtx->aes, encOut, encIn, encSz);
}
static INLINE int myDecryptVerifyCb(CYASSL* ssl,
unsigned char* decOut, const unsigned char* decIn,
unsigned int decSz, int macContent, int macVerify,
unsigned int* padSz, void* ctx)
{
AtomicDecCtx* decCtx = (AtomicDecCtx*)ctx;
int ret = 0;
int macInSz = 0;
int ivExtra = 0;
int digestSz = CyaSSL_GetHmacSize(ssl);
unsigned int pad = 0;
unsigned int padByte = 0;
Hmac hmac;
byte myInner[CYASSL_TLS_HMAC_INNER_SZ];
byte verify[INNER_HASH_SIZE];
const char* tlsStr = "TLS";
/* example supports (d)tls aes */
if (CyaSSL_GetBulkCipher(ssl) != cyassl_aes) {
printf("myMacEncryptCb not using AES\n");
return -1;
}
if (strstr(CyaSSL_get_version(ssl), tlsStr) == NULL) {
printf("myMacEncryptCb not using (D)TLS\n");
return -1;
}
/*decrypt */
if (decCtx->keySetup == 0) {
int keyLen = CyaSSL_GetKeySize(ssl);
const byte* key;
const byte* iv;
/* decrypt is from other side (peer) */
if (CyaSSL_GetSide(ssl) == CYASSL_SERVER_END) {
key = CyaSSL_GetClientWriteKey(ssl);
iv = CyaSSL_GetClientWriteIV(ssl);
}
else {
key = CyaSSL_GetServerWriteKey(ssl);
iv = CyaSSL_GetServerWriteIV(ssl);
}
ret = AesSetKey(&decCtx->aes, key, keyLen, iv, AES_DECRYPTION);
if (ret != 0) {
printf("AesSetKey failed in myDecryptVerifyCb\n");
return ret;
}
decCtx->keySetup = 1;
}
/* decrypt */
ret = AesCbcDecrypt(&decCtx->aes, decOut, decIn, decSz);
if (CyaSSL_GetCipherType(ssl) == CYASSL_AEAD_TYPE) {
*padSz = CyaSSL_GetAeadMacSize(ssl);
return 0; /* hmac, not needed if aead mode */
}
if (CyaSSL_GetCipherType(ssl) == CYASSL_BLOCK_TYPE) {
pad = *(decOut + decSz - 1);
padByte = 1;
if (CyaSSL_IsTLSv1_1(ssl))
ivExtra = CyaSSL_GetCipherBlockSize(ssl);
}
*padSz = CyaSSL_GetHmacSize(ssl) + pad + padByte;
macInSz = decSz - ivExtra - digestSz - pad - padByte;
CyaSSL_SetTlsHmacInner(ssl, myInner, macInSz, macContent, macVerify);
HmacSetKey(&hmac, CyaSSL_GetHmacType(ssl),
CyaSSL_GetMacSecret(ssl, macVerify), digestSz);
HmacUpdate(&hmac, myInner, sizeof(myInner));
HmacUpdate(&hmac, decOut + ivExtra, macInSz);
HmacFinal(&hmac, verify);
if (memcmp(verify, decOut + decSz - digestSz - pad - padByte,
digestSz) != 0) {
printf("myDecryptVerify verify failed\n");
return -1;
}
return ret;
}
static INLINE void SetupAtomicUser(CYASSL_CTX* ctx, CYASSL* ssl)
{
AtomicEncCtx* encCtx;
AtomicDecCtx* decCtx;
encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx));
if (encCtx == NULL)
err_sys("AtomicEncCtx malloc failed");
memset(encCtx, 0, sizeof(AtomicEncCtx));
decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx));
if (decCtx == NULL) {
free(encCtx);
err_sys("AtomicDecCtx malloc failed");
}
memset(decCtx, 0, sizeof(AtomicDecCtx));
CyaSSL_CTX_SetMacEncryptCb(ctx, myMacEncryptCb);
CyaSSL_SetMacEncryptCtx(ssl, encCtx);
CyaSSL_CTX_SetDecryptVerifyCb(ctx, myDecryptVerifyCb);
CyaSSL_SetDecryptVerifyCtx(ssl, decCtx);
}
static INLINE void FreeAtomicUser(CYASSL* ssl)
{
AtomicEncCtx* encCtx = CyaSSL_GetMacEncryptCtx(ssl);
AtomicDecCtx* decCtx = CyaSSL_GetDecryptVerifyCtx(ssl);
free(decCtx);
free(encCtx);
}

View File

@ -429,7 +429,8 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
ctx->extensions = NULL;
#endif
#ifdef ATOMIC_USER
ctx->MacEncryptCb = NULL;
ctx->MacEncryptCb = NULL;
ctx->DecryptVerifyCb = NULL;
#endif
if (InitMutex(&ctx->countMutex) < 0) {
@ -1379,6 +1380,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->dtls_msg_list = NULL;
#endif
ssl->keys.encryptSz = 0;
ssl->keys.padSz = 0;
ssl->keys.encryptionOn = 0; /* initially off */
ssl->keys.decryptedCur = 0; /* initially off */
ssl->options.sessionCacheOff = ctx->sessionCacheOff;
@ -1479,7 +1481,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
InitCiphers(ssl);
InitCipherSpecs(&ssl->specs);
#ifdef ATOMIC_USER
ssl->MacEncryptCtx = NULL;
ssl->MacEncryptCtx = NULL;
ssl->DecryptVerifyCtx = NULL;
#endif
/* all done with init, now can return errors, call other stuff */
@ -3366,20 +3369,7 @@ static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx)
int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
{
int finishedSz = ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ;
int headerSz = HANDSHAKE_HEADER_SZ;
word32 macSz = finishedSz + HANDSHAKE_HEADER_SZ,
idx = *inOutIdx,
padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - finishedSz -
ssl->specs.hash_size;
const byte* mac;
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
headerSz += DTLS_HANDSHAKE_EXTRA;
macSz += DTLS_HANDSHAKE_EXTRA;
padSz -= DTLS_HANDSHAKE_EXTRA;
}
#endif
word32 idx = *inOutIdx;
#ifdef CYASSL_CALLBACKS
if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
@ -3391,32 +3381,9 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
return VERIFY_FINISHED_ERROR;
}
}
if (ssl->specs.cipher_type != aead) {
byte verifyMAC[MAX_DIGEST_SIZE];
ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
handshake, 1);
idx += finishedSz;
/* read mac and fill */
mac = input + idx;
idx += ssl->specs.hash_size;
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
padSz -= ssl->specs.block_size;
idx += padSz;
/* verify mac */
if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size) != 0) {
CYASSL_MSG("Verify finished error on mac");
return VERIFY_MAC_ERROR;
}
}
else {
idx += (finishedSz + ssl->specs.aead_mac_size);
}
idx += finishedSz;
idx += ssl->keys.padSz;
if (ssl->options.side == CYASSL_CLIENT_END) {
ssl->options.serverState = SERVER_FINISHED_COMPLETE;
if (!ssl->options.resuming) {
@ -3865,6 +3832,7 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
}
static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
word32 sz)
{
@ -4035,32 +4003,6 @@ static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz)
}
/* decrypt input message in place */
static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx)
{
int decryptResult;
int sanityResult = SanityCheckCipherText(ssl, sz);
if (sanityResult != 0)
return sanityResult;
decryptResult = Decrypt(ssl, input, input, sz);
if (decryptResult == 0)
{
ssl->keys.encryptSz = sz;
ssl->keys.decryptedCur = 1;
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
*idx += ssl->specs.block_size; /* go past TLSv1.1 IV */
if (ssl->specs.cipher_type == aead)
*idx += AEAD_EXP_IV_SZ;
}
return decryptResult;
}
#ifndef NO_OLD_TLS
static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
@ -4284,7 +4226,7 @@ static INLINE int GetRounds(int pLen, int padLen, int t)
/* timing resistant pad/verify check, return 0 on success */
static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
int pLen)
int pLen, int content)
{
byte verify[MAX_DIGEST_SIZE];
byte dummy[MAX_PAD_SIZE];
@ -4294,7 +4236,7 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
if ( (t + padLen + 1) > pLen) {
CYASSL_MSG("Plain Len not long enough for pad/mac");
PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
ssl->hmac(ssl, verify, input, pLen - t, content, 1);
ConstantCompare(verify, input + pLen - t, t);
return VERIFY_MAC_ERROR;
@ -4303,14 +4245,14 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
CYASSL_MSG("PadCheck failed");
PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
ssl->hmac(ssl, verify, input, pLen - t, application_data, 1);
ssl->hmac(ssl, verify, input, pLen - t, content, 1);
ConstantCompare(verify, input + pLen - t, t);
return VERIFY_MAC_ERROR;
}
PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, application_data, 1);
ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
@ -4326,17 +4268,13 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t,
int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
{
word32 msgSz = ssl->keys.encryptSz;
word32 pad = 0,
padByte = 0,
idx = *inOutIdx,
digestSz = ssl->specs.hash_size;
int dataSz, ret;
word32 idx = *inOutIdx;
int dataSz;
int ivExtra = 0;
byte* rawData = input + idx; /* keep current for hmac */
#ifdef HAVE_LIBZ
byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
#endif
byte verify[MAX_DIGEST_SIZE];
if (ssl->options.handShakeState != HANDSHAKE_DONE) {
CYASSL_MSG("Received App data before handshake complete");
@ -4347,35 +4285,12 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
if (ssl->specs.cipher_type == block) {
if (ssl->options.tls1_1)
ivExtra = ssl->specs.block_size;
pad = *(input + idx + msgSz - ivExtra - 1);
padByte = 1;
if (ssl->options.tls) {
ret = TimingPadVerify(ssl, input + idx, pad, digestSz,
msgSz - ivExtra);
if (ret != 0)
return ret;
}
else { /* sslv3, some implementations have bad padding */
ssl->hmac(ssl, verify, rawData, msgSz - digestSz - pad - 1,
application_data, 1);
if (ConstantCompare(verify, rawData + msgSz - digestSz - pad - 1,
digestSz) != 0)
return VERIFY_MAC_ERROR;
}
}
else if (ssl->specs.cipher_type == stream) {
ssl->hmac(ssl, verify, rawData, msgSz - digestSz, application_data, 1);
if (ConstantCompare(verify, rawData + msgSz - digestSz, digestSz) != 0){
return VERIFY_MAC_ERROR;
}
}
else if (ssl->specs.cipher_type == aead) {
ivExtra = AEAD_EXP_IV_SZ;
digestSz = ssl->specs.aead_mac_size;
}
dataSz = msgSz - ivExtra - digestSz - pad - padByte;
dataSz = msgSz - ivExtra - ssl->keys.padSz;
if (dataSz < 0) {
CYASSL_MSG("App data buffer error, malicious input?");
return BUFFER_ERROR;
@ -4397,10 +4312,7 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
ssl->buffers.clearOutputBuffer.length = dataSz;
}
idx += digestSz;
idx += pad;
if (padByte)
idx++;
idx += ssl->keys.padSz;
#ifdef HAVE_LIBZ
/* decompress could be bigger, overwrite after verify */
@ -4444,27 +4356,7 @@ static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type)
CYASSL_ERROR(*type);
if (ssl->keys.encryptionOn) {
if (ssl->specs.cipher_type != aead) {
int aSz = ALERT_SIZE;
const byte* mac;
byte verify[MAX_DIGEST_SIZE];
int padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
/* read mac and fill */
mac = input + *inOutIdx;
*inOutIdx += (ssl->specs.hash_size + padSz);
/* verify */
if (XMEMCMP(mac, verify, ssl->specs.hash_size) != 0) {
CYASSL_MSG(" alert verify mac error");
return VERIFY_MAC_ERROR;
}
}
else {
*inOutIdx += ssl->specs.aead_mac_size;
}
*inOutIdx += ssl->keys.padSz;
}
return level;
@ -4533,11 +4425,61 @@ static int GetInputData(CYASSL *ssl, word32 size)
return 0;
}
static INLINE int VerifyMac(CYASSL* ssl, const byte* input, word32 msgSz,
int content, word32* padSz)
{
int ivExtra = 0;
int ret;
word32 pad = 0;
word32 padByte = 0;
word32 digestSz = ssl->specs.hash_size;
byte verify[MAX_DIGEST_SIZE];
if (ssl->specs.cipher_type == block) {
if (ssl->options.tls1_1)
ivExtra = ssl->specs.block_size;
pad = *(input + msgSz - ivExtra - 1);
padByte = 1;
if (ssl->options.tls) {
ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
content);
if (ret != 0)
return ret;
}
else { /* sslv3, some implementations have bad padding */
ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
content, 1);
if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
digestSz) != 0)
return VERIFY_MAC_ERROR;
}
}
else if (ssl->specs.cipher_type == stream) {
ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
return VERIFY_MAC_ERROR;
}
}
if (ssl->specs.cipher_type == aead) {
*padSz = ssl->specs.aead_mac_size;
}
else {
*padSz = digestSz + pad + padByte;
}
return 0;
}
/* process input requests, return 0 is done, 1 is call again to complete, and
negative number is error */
int ProcessReply(CYASSL* ssl)
{
int ret = 0, type, readSz;
int atomicUser = 0;
word32 startIdx = 0;
#ifndef NO_CYASSL_SERVER
byte b0, b1;
@ -4546,6 +4488,11 @@ int ProcessReply(CYASSL* ssl)
int used;
#endif
#ifdef ATOMIC_USER
if (ssl->ctx->DecryptVerifyCb)
atomicUser = 1;
#endif
for (;;) {
switch ((processReply)ssl->options.processReply) {
@ -4676,14 +4623,53 @@ int ProcessReply(CYASSL* ssl)
case runProcessingOneMessage:
if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0) {
ret = DecryptMessage(ssl, ssl->buffers.inputBuffer.buffer +
ssl->buffers.inputBuffer.idx,
ssl->curSize,
&ssl->buffers.inputBuffer.idx);
ret = SanityCheckCipherText(ssl, ssl->curSize);
if (ret < 0)
return ret;
if (atomicUser) {
#ifdef ATOMIC_USER
ret = ssl->ctx->DecryptVerifyCb(ssl,
ssl->buffers.inputBuffer.buffer +
ssl->buffers.inputBuffer.idx,
ssl->buffers.inputBuffer.buffer +
ssl->buffers.inputBuffer.idx,
ssl->curSize, ssl->curRL.type, 1,
&ssl->keys.padSz, ssl->DecryptVerifyCtx);
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
/* go past TLSv1.1 IV */
if (ssl->specs.cipher_type == aead)
ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
#endif /* ATOMIC_USER */
}
else {
ret = Decrypt(ssl, ssl->buffers.inputBuffer.buffer +
ssl->buffers.inputBuffer.idx,
ssl->buffers.inputBuffer.buffer +
ssl->buffers.inputBuffer.idx,
ssl->curSize);
if (ret < 0) {
CYASSL_ERROR(ret);
return DECRYPT_ERROR;
}
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
/* go past TLSv1.1 IV */
if (ssl->specs.cipher_type == aead)
ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
ssl->buffers.inputBuffer.idx,
ssl->curSize, ssl->curRL.type,
&ssl->keys.padSz);
}
if (ret < 0) {
CYASSL_ERROR(ret);
return DECRYPT_ERROR;
}
ssl->keys.encryptSz = ssl->curSize;
ssl->keys.decryptedCur = 1;
}
CYASSL_MSG("received record layer msg");

View File

@ -830,6 +830,29 @@ void* CyaSSL_GetMacEncryptCtx(CYASSL* ssl)
}
void CyaSSL_CTX_SetDecryptVerifyCb(CYASSL_CTX* ctx, CallbackDecryptVerify cb)
{
if (ctx)
ctx->DecryptVerifyCb = cb;
}
void CyaSSL_SetDecryptVerifyCtx(CYASSL* ssl, void *ctx)
{
if (ssl)
ssl->DecryptVerifyCtx = ctx;
}
void* CyaSSL_GetDecryptVerifyCtx(CYASSL* ssl)
{
if (ssl)
return ssl->DecryptVerifyCtx;
return NULL;
}
const byte* CyaSSL_GetClientWriteKey(CYASSL* ssl)
{
if (ssl)
@ -884,6 +907,52 @@ int CyaSSL_GetBulkCipher(CYASSL* ssl)
}
int CyaSSL_GetCipherType(CYASSL* ssl)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
if (ssl->specs.cipher_type == block)
return CYASSL_BLOCK_TYPE;
if (ssl->specs.cipher_type == stream)
return CYASSL_STREAM_TYPE;
if (ssl->specs.cipher_type == aead)
return CYASSL_AEAD_TYPE;
return -1;
}
int CyaSSL_GetCipherBlockSize(CYASSL* ssl)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
return ssl->specs.block_size;
}
int CyaSSL_GetAeadMacSize(CYASSL* ssl)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
return ssl->specs.aead_mac_size;
}
int CyaSSL_IsTLSv1_1(CYASSL* ssl)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
if (ssl->options.tls1_1)
return 1;
return 0;
}
int CyaSSL_GetSide(CYASSL* ssl)
{
if (ssl)