forked from wolfSSL/wolfssl
add cert cache persistence
This commit is contained in:
14
configure.ac
14
configure.ac
@ -263,6 +263,19 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Persistent cert cache
|
||||||
|
AC_ARG_ENABLE([savecert],
|
||||||
|
[ --enable-savecert Enable persistent cert cache (default: disabled)],
|
||||||
|
[ ENABLED_SAVECERT=$enableval ],
|
||||||
|
[ ENABLED_SAVECERT=no ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "$ENABLED_SAVECERT" = "yes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DPERSIST_CERT_CACHE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# SNIFFER
|
# SNIFFER
|
||||||
AC_ARG_ENABLE([sniffer],
|
AC_ARG_ENABLE([sniffer],
|
||||||
[AS_HELP_STRING([--enable-sniffer],[ Enable CyaSSL sniffer support (default: disabled) ])],[
|
[AS_HELP_STRING([--enable-sniffer],[ Enable CyaSSL sniffer support (default: disabled) ])],[
|
||||||
@ -1393,6 +1406,7 @@ echo " * OCSP: $ENABLED_OCSP"
|
|||||||
echo " * CRL: $ENABLED_CRL"
|
echo " * CRL: $ENABLED_CRL"
|
||||||
echo " * CRL-MONITOR: $ENABLED_CRL_MONITOR"
|
echo " * CRL-MONITOR: $ENABLED_CRL_MONITOR"
|
||||||
echo " * Persistent session cache: $ENABLED_SAVESESSION"
|
echo " * Persistent session cache: $ENABLED_SAVESESSION"
|
||||||
|
echo " * Persistent cert cache: $ENABLED_SAVECERT"
|
||||||
echo " * NTRU: $ENABLED_NTRU"
|
echo " * NTRU: $ENABLED_NTRU"
|
||||||
echo " * valgrind unit tests: $ENABLED_VALGRIND"
|
echo " * valgrind unit tests: $ENABLED_VALGRIND"
|
||||||
echo " * LIBZ: $ENABLED_LIBZ"
|
echo " * LIBZ: $ENABLED_LIBZ"
|
||||||
|
@ -2844,9 +2844,12 @@ Signer* MakeSigner(void* heap)
|
|||||||
Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
|
Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
|
||||||
DYNAMIC_TYPE_SIGNER);
|
DYNAMIC_TYPE_SIGNER);
|
||||||
if (signer) {
|
if (signer) {
|
||||||
signer->name = 0;
|
signer->pubKeySize = 0;
|
||||||
signer->publicKey = 0;
|
signer->keyOID = 0;
|
||||||
signer->next = 0;
|
signer->publicKey = NULL;
|
||||||
|
signer->nameLen = 0;
|
||||||
|
signer->name = NULL;
|
||||||
|
signer->next = NULL;
|
||||||
}
|
}
|
||||||
(void)heap;
|
(void)heap;
|
||||||
|
|
||||||
|
@ -280,16 +280,18 @@ struct DecodedCert {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SHA_DIGEST_SIZE
|
#ifdef SHA_DIGEST_SIZE
|
||||||
#define SIGNER_DIGEST_SIZE SHA_DIGEST_SIZE
|
#define SIGNER_DIGEST_SIZE SHA_DIGEST_SIZE
|
||||||
#else
|
#else
|
||||||
#define SIGNER_DIGEST_SIZE 20
|
#define SIGNER_DIGEST_SIZE 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* CA Signers */
|
/* CA Signers */
|
||||||
|
/* if change layout change PERSIST_CERT_CACHE functions too */
|
||||||
struct Signer {
|
struct Signer {
|
||||||
byte* publicKey;
|
|
||||||
word32 pubKeySize;
|
word32 pubKeySize;
|
||||||
word32 keyOID; /* key type */
|
word32 keyOID; /* key type */
|
||||||
|
byte* publicKey;
|
||||||
|
int nameLen;
|
||||||
char* name; /* common name */
|
char* name; /* common name */
|
||||||
byte subjectNameHash[SIGNER_DIGEST_SIZE];
|
byte subjectNameHash[SIGNER_DIGEST_SIZE];
|
||||||
/* sha hash of names in certificate */
|
/* sha hash of names in certificate */
|
||||||
|
@ -112,7 +112,7 @@ enum CyaSSL_ErrorCodes {
|
|||||||
GEN_COOKIE_E = -277, /* Generate Cookie Error */
|
GEN_COOKIE_E = -277, /* Generate Cookie Error */
|
||||||
NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
|
NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
|
||||||
FWRITE_ERROR = -279, /* fwrite problem */
|
FWRITE_ERROR = -279, /* fwrite problem */
|
||||||
CACHE_MATCH_ERROR = -280, /* session cache hdr match err */
|
CACHE_MATCH_ERROR = -280, /* cache hdr match err */
|
||||||
/* add strings to SetErrorString !!!!! */
|
/* add strings to SetErrorString !!!!! */
|
||||||
|
|
||||||
/* begin negotiation parameter errors */
|
/* begin negotiation parameter errors */
|
||||||
|
@ -1073,6 +1073,11 @@ struct CYASSL_CERT_MANAGER {
|
|||||||
CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */
|
CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CYASSL_LOCAL int CM_SaveCertCache(CYASSL_CERT_MANAGER*, const char*);
|
||||||
|
CYASSL_LOCAL int CM_RestoreCertCache(CYASSL_CERT_MANAGER*, const char*);
|
||||||
|
CYASSL_LOCAL int CM_MemSaveCertCache(CYASSL_CERT_MANAGER*, void*, int, int*);
|
||||||
|
CYASSL_LOCAL int CM_MemRestoreCertCache(CYASSL_CERT_MANAGER*, const void*, int);
|
||||||
|
CYASSL_LOCAL int CM_GetCertCacheMemSize(CYASSL_CERT_MANAGER*);
|
||||||
|
|
||||||
/* CyaSSL Sock Addr */
|
/* CyaSSL Sock Addr */
|
||||||
struct CYASSL_SOCKADDR {
|
struct CYASSL_SOCKADDR {
|
||||||
|
13
cyassl/ssl.h
13
cyassl/ssl.h
@ -233,12 +233,21 @@ CYASSL_API int CyaSSL_pending(CYASSL*);
|
|||||||
CYASSL_API void CyaSSL_load_error_strings(void);
|
CYASSL_API void CyaSSL_load_error_strings(void);
|
||||||
CYASSL_API int CyaSSL_library_init(void);
|
CYASSL_API int CyaSSL_library_init(void);
|
||||||
CYASSL_API long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX*, long);
|
CYASSL_API long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX*, long);
|
||||||
CYASSL_API int CyaSSL_save_session_cache(const char *fname);
|
|
||||||
CYASSL_API int CyaSSL_restore_session_cache(const char *fname);
|
/* session cache persistence */
|
||||||
|
CYASSL_API int CyaSSL_save_session_cache(const char*);
|
||||||
|
CYASSL_API int CyaSSL_restore_session_cache(const char*);
|
||||||
CYASSL_API int CyaSSL_memsave_session_cache(void*, int);
|
CYASSL_API int CyaSSL_memsave_session_cache(void*, int);
|
||||||
CYASSL_API int CyaSSL_memrestore_session_cache(const void*, int);
|
CYASSL_API int CyaSSL_memrestore_session_cache(const void*, int);
|
||||||
CYASSL_API int CyaSSL_get_session_cache_memsize(void);
|
CYASSL_API int CyaSSL_get_session_cache_memsize(void);
|
||||||
|
|
||||||
|
/* certificate cache persistence, uses ctx since certs are per ctx */
|
||||||
|
CYASSL_API int CyaSSL_CTX_save_cert_cache(CYASSL_CTX*, const char*);
|
||||||
|
CYASSL_API int CyaSSL_CTX_restore_cert_cache(CYASSL_CTX*, const char*);
|
||||||
|
CYASSL_API int CyaSSL_CTX_memsave_cert_cache(CYASSL_CTX*, void*, int, int*);
|
||||||
|
CYASSL_API int CyaSSL_CTX_memrestore_cert_cache(CYASSL_CTX*, const void*, int);
|
||||||
|
CYASSL_API int CyaSSL_CTX_get_cert_cache_memsize(CYASSL_CTX*);
|
||||||
|
|
||||||
/* only supports full name from cipher_name[] delimited by : */
|
/* only supports full name from cipher_name[] delimited by : */
|
||||||
CYASSL_API int CyaSSL_CTX_set_cipher_list(CYASSL_CTX*, const char*);
|
CYASSL_API int CyaSSL_CTX_set_cipher_list(CYASSL_CTX*, const char*);
|
||||||
CYASSL_API int CyaSSL_set_cipher_list(CYASSL*, const char*);
|
CYASSL_API int CyaSSL_set_cipher_list(CYASSL*, const char*);
|
||||||
|
@ -5790,7 +5790,7 @@ void SetErrorString(int error, char* str)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CACHE_MATCH_ERROR:
|
case CACHE_MATCH_ERROR:
|
||||||
XSTRNCPY(str, "Session Cache restore header match Error", max);
|
XSTRNCPY(str, "Cache restore header match Error", max);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
|
536
src/ssl.c
536
src/ssl.c
@ -1002,7 +1002,8 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
|
|||||||
signer->keyOID = cert.keyOID;
|
signer->keyOID = cert.keyOID;
|
||||||
signer->publicKey = cert.publicKey;
|
signer->publicKey = cert.publicKey;
|
||||||
signer->pubKeySize = cert.pubKeySize;
|
signer->pubKeySize = cert.pubKeySize;
|
||||||
signer->name = cert.subjectCN;
|
signer->nameLen = cert.subjectCNLen;
|
||||||
|
signer->name = cert.subjectCN;
|
||||||
#ifndef NO_SKID
|
#ifndef NO_SKID
|
||||||
XMEMCPY(signer->subjectKeyIdHash,
|
XMEMCPY(signer->subjectKeyIdHash,
|
||||||
cert.extSubjKeyId, SHA_DIGEST_SIZE);
|
cert.extSubjKeyId, SHA_DIGEST_SIZE);
|
||||||
@ -2617,6 +2618,72 @@ void CyaSSL_CTX_SetCACb(CYASSL_CTX* ctx, CallbackCACache cb)
|
|||||||
ctx->cm->caCacheCallback = cb;
|
ctx->cm->caCacheCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(PERSIST_CERT_CACHE)
|
||||||
|
|
||||||
|
#if !defined(NO_FILESYSTEM)
|
||||||
|
|
||||||
|
/* Persist cert cache to file */
|
||||||
|
int CyaSSL_CTX_save_cert_cache(CYASSL_CTX* ctx, const char* fname)
|
||||||
|
{
|
||||||
|
CYASSL_ENTER("CyaSSL_CTX_save_cert_cache");
|
||||||
|
|
||||||
|
if (ctx == NULL || fname == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return CM_SaveCertCache(ctx->cm, fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Persist cert cache from file */
|
||||||
|
int CyaSSL_CTX_restore_cert_cache(CYASSL_CTX* ctx, const char* fname)
|
||||||
|
{
|
||||||
|
CYASSL_ENTER("CyaSSL_CTX_restore_cert_cache");
|
||||||
|
|
||||||
|
if (ctx == NULL || fname == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return CM_RestoreCertCache(ctx->cm, fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NO_FILESYSTEM */
|
||||||
|
|
||||||
|
/* Persist cert cache to memory */
|
||||||
|
int CyaSSL_CTX_memsave_cert_cache(CYASSL_CTX* ctx, void* mem, int sz, int* used)
|
||||||
|
{
|
||||||
|
CYASSL_ENTER("CyaSSL_CTX_memsave_cert_cache");
|
||||||
|
|
||||||
|
if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Resotre cert cache from memory */
|
||||||
|
int CyaSSL_CTX_memrestore_cert_cache(CYASSL_CTX* ctx, const void* mem, int sz)
|
||||||
|
{
|
||||||
|
CYASSL_ENTER("CyaSSL_CTX_memrestore_cert_cache");
|
||||||
|
|
||||||
|
if (ctx == NULL || mem == NULL || sz <= 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return CM_MemRestoreCertCache(ctx->cm, mem, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get how big the the cert cache save buffer needs to be */
|
||||||
|
int CyaSSL_CTX_get_cert_cache_memsize(CYASSL_CTX* ctx)
|
||||||
|
{
|
||||||
|
CYASSL_ENTER("CyaSSL_CTX_get_cert_cache_memsize");
|
||||||
|
|
||||||
|
if (ctx == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return CM_GetCertCacheMemSize(ctx->cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* PERSISTE_CERT_CACHE */
|
||||||
#endif /* !NO_CERTS */
|
#endif /* !NO_CERTS */
|
||||||
|
|
||||||
|
|
||||||
@ -2981,6 +3048,473 @@ long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX* ctx, long mode)
|
|||||||
#endif /* NO_SESSION_CACHE */
|
#endif /* NO_SESSION_CACHE */
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(NO_CERTS)
|
||||||
|
#if defined(PERSIST_CERT_CACHE)
|
||||||
|
|
||||||
|
|
||||||
|
#define CYASSL_CACHE_CERT_VERSION 1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int version; /* cache cert layout version id */
|
||||||
|
int rows; /* hash table rows, CA_TABLE_SIZE */
|
||||||
|
int columns[CA_TABLE_SIZE]; /* columns per row on list */
|
||||||
|
int signerSz; /* sizeof Signer object */
|
||||||
|
} CertCacheHeader;
|
||||||
|
|
||||||
|
/* current cert persistance laytout is:
|
||||||
|
|
||||||
|
1) CertCacheHeader
|
||||||
|
2) caTable
|
||||||
|
|
||||||
|
update CYASSL_CERT_CACHE_VERSION if change layout for the following
|
||||||
|
PERSIST_CERT_CACHE functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Return memory needed to persist this signer, have lock */
|
||||||
|
static INLINE int GetSignerMemory(Signer* signer)
|
||||||
|
{
|
||||||
|
int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
|
||||||
|
+ sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
|
||||||
|
|
||||||
|
#if !defined(NO_SKID)
|
||||||
|
sz += sizeof(signer->subjectKeyIdHash);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* add dynamic bytes needed */
|
||||||
|
sz += signer->pubKeySize;
|
||||||
|
sz += signer->nameLen;
|
||||||
|
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return memory needed to persist this row, have lock */
|
||||||
|
static INLINE int GetCertCacheRowMemory(Signer* row)
|
||||||
|
{
|
||||||
|
int sz = 0;
|
||||||
|
|
||||||
|
while (row) {
|
||||||
|
sz += GetSignerMemory(row);
|
||||||
|
row = row->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get the size of persist cert cache, have lock */
|
||||||
|
static INLINE int GetCertCacheMemSize(CYASSL_CERT_MANAGER* cm)
|
||||||
|
{
|
||||||
|
int sz;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sz = sizeof(CertCacheHeader);
|
||||||
|
|
||||||
|
for (i = 0; i < CA_TABLE_SIZE; i++)
|
||||||
|
sz += GetCertCacheRowMemory(cm->caTable[i]);
|
||||||
|
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Store cert cache header columns with number of itms per list, have lock */
|
||||||
|
static INLINE void SetCertHeaderColumns(CYASSL_CERT_MANAGER* cm, int* columns)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Signer* row;
|
||||||
|
|
||||||
|
for (i = 0; i < CA_TABLE_SIZE; i++) {
|
||||||
|
int count = 0;
|
||||||
|
row = cm->caTable[i];
|
||||||
|
|
||||||
|
while (row) {
|
||||||
|
++count;
|
||||||
|
row = row->next;
|
||||||
|
}
|
||||||
|
columns[i] = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Resotre whole cert row from memory, have lock, return bytes consumed,
|
||||||
|
< 0 on eror, have lock */
|
||||||
|
static INLINE int RestoreCertRow(CYASSL_CERT_MANAGER* cm, byte* current,
|
||||||
|
int row, int listSz, const byte* end)
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if (listSz < 0) {
|
||||||
|
CYASSL_MSG("Row header corrupted, negative value");
|
||||||
|
return PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (listSz) {
|
||||||
|
Signer* signer;
|
||||||
|
byte* start = current + idx; /* for end checks on this signer */
|
||||||
|
int minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
|
||||||
|
sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
|
||||||
|
#ifndef NO_SKID
|
||||||
|
minSz += sizeof(signer->subjectKeyIdHash);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (start + minSz > end) {
|
||||||
|
CYASSL_MSG("Would overread restore buffer");
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
signer = MakeSigner(cm->heap);
|
||||||
|
if (signer == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
/* pubKeySize */
|
||||||
|
XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
|
||||||
|
idx += sizeof(signer->pubKeySize);
|
||||||
|
|
||||||
|
/* keyOID */
|
||||||
|
XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
|
||||||
|
idx += sizeof(signer->keyOID);
|
||||||
|
|
||||||
|
/* pulicKey */
|
||||||
|
if (start + minSz + signer->pubKeySize > end) {
|
||||||
|
CYASSL_MSG("Would overread restore buffer");
|
||||||
|
FreeSigner(signer, cm->heap);
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
signer->publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
|
||||||
|
DYNAMIC_TYPE_KEY);
|
||||||
|
if (signer->publicKey == NULL) {
|
||||||
|
FreeSigner(signer, cm->heap);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(signer->publicKey, current + idx, signer->pubKeySize);
|
||||||
|
idx += signer->pubKeySize;
|
||||||
|
|
||||||
|
/* nameLen */
|
||||||
|
XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
|
||||||
|
idx += sizeof(signer->nameLen);
|
||||||
|
|
||||||
|
/* name */
|
||||||
|
if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
|
||||||
|
CYASSL_MSG("Would overread restore buffer");
|
||||||
|
FreeSigner(signer, cm->heap);
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
|
||||||
|
DYNAMIC_TYPE_SUBJECT_CN);
|
||||||
|
if (signer->name == NULL) {
|
||||||
|
FreeSigner(signer, cm->heap);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(signer->name, current + idx, signer->nameLen);
|
||||||
|
idx += signer->nameLen;
|
||||||
|
|
||||||
|
/* subjectNameHash */
|
||||||
|
XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
|
||||||
|
idx += SIGNER_DIGEST_SIZE;
|
||||||
|
|
||||||
|
#ifndef NO_SKID
|
||||||
|
/* subjectKeyIdHash */
|
||||||
|
XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
|
||||||
|
idx += SIGNER_DIGEST_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
signer->next = cm->caTable[row];
|
||||||
|
cm->caTable[row] = signer;
|
||||||
|
|
||||||
|
--listSz;
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Sotre whole cert row into memory, have lock, return bytes added */
|
||||||
|
static INLINE int StoreCertRow(CYASSL_CERT_MANAGER* cm, byte* current, int row)
|
||||||
|
{
|
||||||
|
int added = 0;
|
||||||
|
Signer* list = cm->caTable[row];
|
||||||
|
|
||||||
|
while (list) {
|
||||||
|
XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
|
||||||
|
added += sizeof(list->pubKeySize);
|
||||||
|
|
||||||
|
XMEMCPY(current + added, &list->keyOID, sizeof(list->keyOID));
|
||||||
|
added += sizeof(list->keyOID);
|
||||||
|
|
||||||
|
XMEMCPY(current + added, list->publicKey, list->pubKeySize);
|
||||||
|
added += list->pubKeySize;
|
||||||
|
|
||||||
|
XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
|
||||||
|
added += sizeof(list->nameLen);
|
||||||
|
|
||||||
|
XMEMCPY(current + added, list->name, list->nameLen);
|
||||||
|
added += list->nameLen;
|
||||||
|
|
||||||
|
XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
|
||||||
|
added += SIGNER_DIGEST_SIZE;
|
||||||
|
|
||||||
|
#ifndef NO_SKID
|
||||||
|
XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
|
||||||
|
added += SIGNER_DIGEST_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Persist cert cache to memory, have lock */
|
||||||
|
static INLINE int DoMemSaveCertCache(CYASSL_CERT_MANAGER* cm, void* mem, int sz)
|
||||||
|
{
|
||||||
|
int realSz;
|
||||||
|
int ret = SSL_SUCCESS;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
CYASSL_ENTER("DoMemSaveCertCache");
|
||||||
|
|
||||||
|
realSz = GetCertCacheMemSize(cm);
|
||||||
|
if (realSz > sz) {
|
||||||
|
CYASSL_MSG("Mem output buffer too small");
|
||||||
|
ret = BUFFER_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
byte* current;
|
||||||
|
CertCacheHeader hdr;
|
||||||
|
|
||||||
|
hdr.version = CYASSL_CACHE_CERT_VERSION;
|
||||||
|
hdr.rows = CA_TABLE_SIZE;
|
||||||
|
SetCertHeaderColumns(cm, hdr.columns);
|
||||||
|
hdr.signerSz = (int)sizeof(Signer);
|
||||||
|
|
||||||
|
XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
|
||||||
|
current = (byte*)mem + sizeof(CertCacheHeader);
|
||||||
|
|
||||||
|
for (i = 0; i < CA_TABLE_SIZE; ++i)
|
||||||
|
current += StoreCertRow(cm, current, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(NO_FILESYSTEM)
|
||||||
|
|
||||||
|
/* Persist cert cache to file */
|
||||||
|
int CM_SaveCertCache(CYASSL_CERT_MANAGER* cm, const char* fname)
|
||||||
|
{
|
||||||
|
XFILE file;
|
||||||
|
int rc = SSL_SUCCESS;
|
||||||
|
int memSz;
|
||||||
|
byte* mem;
|
||||||
|
|
||||||
|
CYASSL_ENTER("CM_SaveCertCache");
|
||||||
|
|
||||||
|
file = XFOPEN(fname, "w+b");
|
||||||
|
if (file == XBADFILE) {
|
||||||
|
CYASSL_MSG("Coun't open cert cache save file");
|
||||||
|
return SSL_BAD_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LockMutex(&cm->caLock) != 0) {
|
||||||
|
CYASSL_MSG("LockMutex on caLock failed");
|
||||||
|
XFCLOSE(file);
|
||||||
|
return BAD_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
memSz = GetCertCacheMemSize(cm);
|
||||||
|
mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (mem == NULL) {
|
||||||
|
CYASSL_MSG("Alloc for tmp buffer failed");
|
||||||
|
rc = MEMORY_E;
|
||||||
|
} else {
|
||||||
|
rc = DoMemSaveCertCache(cm, mem, memSz);
|
||||||
|
if (rc == SSL_SUCCESS) {
|
||||||
|
int ret = (int)XFWRITE(mem, memSz, 1, file);
|
||||||
|
if (ret != 1) {
|
||||||
|
CYASSL_MSG("Cert cahce file write failed");
|
||||||
|
rc = FWRITE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnLockMutex(&cm->caLock);
|
||||||
|
XFCLOSE(file);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Resotre cert cache from file */
|
||||||
|
int CM_RestoreCertCache(CYASSL_CERT_MANAGER* cm, const char* fname)
|
||||||
|
{
|
||||||
|
XFILE file;
|
||||||
|
int rc = SSL_SUCCESS;
|
||||||
|
int ret;
|
||||||
|
int memSz;
|
||||||
|
byte* mem;
|
||||||
|
|
||||||
|
CYASSL_ENTER("CM_RestoreCertCache");
|
||||||
|
|
||||||
|
file = XFOPEN(fname, "rb");
|
||||||
|
if (file == XBADFILE) {
|
||||||
|
CYASSL_MSG("Coun't open cert cache save file");
|
||||||
|
return SSL_BAD_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFSEEK(file, 0, XSEEK_END);
|
||||||
|
memSz = (int)XFTELL(file);
|
||||||
|
XREWIND(file);
|
||||||
|
|
||||||
|
if (memSz <= 0) {
|
||||||
|
CYASSL_MSG("Bad file size");
|
||||||
|
XFCLOSE(file);
|
||||||
|
return SSL_BAD_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (mem == NULL) {
|
||||||
|
CYASSL_MSG("Alloc for tmp buffer failed");
|
||||||
|
XFCLOSE(file);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (int)XFREAD(mem, memSz, 1, file);
|
||||||
|
if (ret != 1) {
|
||||||
|
CYASSL_MSG("Cert file read error");
|
||||||
|
rc = FREAD_ERROR;
|
||||||
|
} else {
|
||||||
|
rc = CM_MemRestoreCertCache(cm, mem, memSz);
|
||||||
|
if (rc != SSL_SUCCESS) {
|
||||||
|
CYASSL_MSG("Mem restore cert cache failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFCLOSE(file);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NO_FILESYSTEM */
|
||||||
|
|
||||||
|
|
||||||
|
/* Persist cert cache to memory */
|
||||||
|
int CM_MemSaveCertCache(CYASSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
|
||||||
|
{
|
||||||
|
int realSz;
|
||||||
|
int ret = SSL_SUCCESS;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
CYASSL_ENTER("CM_MemSaveCertCache");
|
||||||
|
|
||||||
|
if (LockMutex(&cm->caLock) != 0) {
|
||||||
|
CYASSL_MSG("LockMutex on caLock failed");
|
||||||
|
return BAD_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
realSz = GetCertCacheMemSize(cm);
|
||||||
|
if (realSz > sz) {
|
||||||
|
CYASSL_MSG("Mem output buffer too small");
|
||||||
|
ret = BUFFER_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
byte* current;
|
||||||
|
CertCacheHeader hdr;
|
||||||
|
|
||||||
|
hdr.version = CYASSL_CACHE_CERT_VERSION;
|
||||||
|
hdr.rows = CA_TABLE_SIZE;
|
||||||
|
SetCertHeaderColumns(cm, hdr.columns);
|
||||||
|
hdr.signerSz = (int)sizeof(Signer);
|
||||||
|
|
||||||
|
XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
|
||||||
|
current = (byte*)mem + sizeof(CertCacheHeader);
|
||||||
|
|
||||||
|
for (i = 0; i < CA_TABLE_SIZE; ++i)
|
||||||
|
current += StoreCertRow(cm, current, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnLockMutex(&cm->caLock);
|
||||||
|
*used = realSz;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Resotre cert cache from memory */
|
||||||
|
int CM_MemRestoreCertCache(CYASSL_CERT_MANAGER* cm, const void* mem, int sz)
|
||||||
|
{
|
||||||
|
int ret = SSL_SUCCESS;
|
||||||
|
int i;
|
||||||
|
CertCacheHeader* hdr = (CertCacheHeader*)mem;
|
||||||
|
byte* current = (byte*)mem + sizeof(CertCacheHeader);
|
||||||
|
byte* end = (byte*)mem + sz; /* don't go over */
|
||||||
|
|
||||||
|
CYASSL_ENTER("CM_MemRestoreCertCache");
|
||||||
|
|
||||||
|
if (current > end) {
|
||||||
|
CYASSL_MSG("Cert Cahce Memory buffer too small");
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr->version != CYASSL_CACHE_CERT_VERSION ||
|
||||||
|
hdr->rows != CA_TABLE_SIZE ||
|
||||||
|
hdr->signerSz != (int)sizeof(Signer)) {
|
||||||
|
|
||||||
|
CYASSL_MSG("Cert Cache Memory header mismatch");
|
||||||
|
return CACHE_MATCH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LockMutex(&cm->caLock) != 0) {
|
||||||
|
CYASSL_MSG("LockMutex on caLock failed");
|
||||||
|
return BAD_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
|
||||||
|
|
||||||
|
for (i = 0; i < CA_TABLE_SIZE; ++i) {
|
||||||
|
int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
|
||||||
|
if (added < 0) {
|
||||||
|
CYASSL_MSG("RestoreCertRow error");
|
||||||
|
ret = added;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current += added;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnLockMutex(&cm->caLock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get how big the the cert cache save buffer needs to be */
|
||||||
|
int CM_GetCertCacheMemSize(CYASSL_CERT_MANAGER* cm)
|
||||||
|
{
|
||||||
|
int sz;
|
||||||
|
|
||||||
|
CYASSL_ENTER("CM_GetCertCacheMemSize");
|
||||||
|
|
||||||
|
if (LockMutex(&cm->caLock) != 0) {
|
||||||
|
CYASSL_MSG("LockMutex on caLock failed");
|
||||||
|
return BAD_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sz = GetCertCacheMemSize(cm);
|
||||||
|
|
||||||
|
UnLockMutex(&cm->caLock);
|
||||||
|
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* PERSIST_CERT_CACHE */
|
||||||
|
#endif /* NO_CERTS */
|
||||||
|
|
||||||
|
|
||||||
int CyaSSL_CTX_set_cipher_list(CYASSL_CTX* ctx, const char* list)
|
int CyaSSL_CTX_set_cipher_list(CYASSL_CTX* ctx, const char* list)
|
||||||
{
|
{
|
||||||
CYASSL_ENTER("CyaSSL_CTX_set_cipher_list");
|
CYASSL_ENTER("CyaSSL_CTX_set_cipher_list");
|
||||||
|
Reference in New Issue
Block a user