turn CA signer list into CA signer hash table, defaults CA_TABLE_SIZE to 11

pull/1/head
toddouska 2013-04-25 15:36:33 -07:00
parent 9dbf6a5e10
commit 05dd84598b
4 changed files with 67 additions and 33 deletions

View File

@ -2801,6 +2801,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
} }
/* Create and init an new signer */
Signer* MakeSigner(void* heap) Signer* MakeSigner(void* heap)
{ {
Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap, Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
@ -2816,21 +2817,34 @@ Signer* MakeSigner(void* heap)
} }
void FreeSigners(Signer* signer, void* heap) /* Free an individual signer */
void FreeSigner(Signer* signer, void* heap)
{ {
while (signer) { XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
Signer* next = signer->next; XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
signer = next;
}
(void)heap; (void)heap;
} }
/* Free the whole singer table with number of rows */
void FreeSignerTable(Signer** table, int rows, void* heap)
{
int i;
for (i = 0; i < rows; i++) {
Signer* signer = table[i];
while (signer) {
Signer* next = signer->next;
FreeSigner(signer, heap);
signer = next;
}
table[i] = NULL;
}
}
#if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) #if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN)
static int SetMyVersion(word32 version, byte* output, int header) static int SetMyVersion(word32 version, byte* output, int header)

View File

@ -315,7 +315,8 @@ CYASSL_LOCAL word32 EncodeSignature(byte* out, const byte* digest, word32 digSz,
int hashOID); int hashOID);
CYASSL_LOCAL Signer* MakeSigner(void*); CYASSL_LOCAL Signer* MakeSigner(void*);
CYASSL_LOCAL void FreeSigners(Signer*, void*); CYASSL_LOCAL void FreeSigner(Signer*, void*);
CYASSL_LOCAL void FreeSignerTable(Signer**, int, void*);
CYASSL_LOCAL int ToTraditional(byte* buffer, word32 length); CYASSL_LOCAL int ToTraditional(byte* buffer, word32 length);

View File

@ -1056,9 +1056,13 @@ struct CYASSL_CRL {
#endif #endif
#ifndef CA_TABLE_SIZE
#define CA_TABLE_SIZE 11
#endif
/* CyaSSL Certificate Manager */ /* CyaSSL Certificate Manager */
struct CYASSL_CERT_MANAGER { struct CYASSL_CERT_MANAGER {
Signer* caList; /* the CA signer list */ Signer* caTable[CA_TABLE_SIZE]; /* the CA signer table */
CyaSSL_Mutex caLock; /* CA list lock */ CyaSSL_Mutex caLock; /* CA list lock */
CallbackCACache caCacheCallback; /* CA cache addition callback */ CallbackCACache caCacheCallback; /* CA cache addition callback */
void* heap; /* heap helper */ void* heap; /* heap helper */

View File

@ -664,7 +664,10 @@ CYASSL_CERT_MANAGER* CyaSSL_CertManagerNew(void)
cm = (CYASSL_CERT_MANAGER*) XMALLOC(sizeof(CYASSL_CERT_MANAGER), 0, cm = (CYASSL_CERT_MANAGER*) XMALLOC(sizeof(CYASSL_CERT_MANAGER), 0,
DYNAMIC_TYPE_CERT_MANAGER); DYNAMIC_TYPE_CERT_MANAGER);
if (cm) { if (cm) {
cm->caList = NULL; int i;
for (i = 0; i < CA_TABLE_SIZE; i++)
cm->caTable[i] = NULL;
cm->heap = NULL; cm->heap = NULL;
cm->caCacheCallback = NULL; cm->caCacheCallback = NULL;
cm->crl = NULL; cm->crl = NULL;
@ -692,7 +695,7 @@ void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm)
if (cm->crl) if (cm->crl)
FreeCRL(cm->crl, 1); FreeCRL(cm->crl, 1);
#endif #endif
FreeSigners(cm->caList, NULL); FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
FreeMutex(&cm->caLock); FreeMutex(&cm->caLock);
XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER); XFREE(cm, NULL, DYNAMIC_TYPE_CERT_MANAGER);
} }
@ -703,8 +706,6 @@ void CyaSSL_CertManagerFree(CYASSL_CERT_MANAGER* cm)
/* Unload the CA signer list */ /* Unload the CA signer list */
int CyaSSL_CertManagerUnloadCAs(CYASSL_CERT_MANAGER* cm) int CyaSSL_CertManagerUnloadCAs(CYASSL_CERT_MANAGER* cm)
{ {
Signer* signers;
CYASSL_ENTER("CyaSSL_CertManagerUnloadCAs"); CYASSL_ENTER("CyaSSL_CertManagerUnloadCAs");
if (cm == NULL) if (cm == NULL)
@ -713,12 +714,10 @@ int CyaSSL_CertManagerUnloadCAs(CYASSL_CERT_MANAGER* cm)
if (LockMutex(&cm->caLock) != 0) if (LockMutex(&cm->caLock) != 0)
return BAD_MUTEX_ERROR; return BAD_MUTEX_ERROR;
signers = cm->caList; FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
cm->caList = NULL;
UnLockMutex(&cm->caLock); UnLockMutex(&cm->caLock);
FreeSigners(signers, NULL);
return SSL_SUCCESS; return SSL_SUCCESS;
} }
@ -846,19 +845,40 @@ int CyaSSL_SetVersion(CYASSL* ssl, int version)
return SSL_SUCCESS; return SSL_SUCCESS;
} }
#endif #endif /* !leanpsk */
#if !defined(NO_CERTS) || !defined(NO_SESSION_CACHE)
/* Make a work from the front of random hash */
static INLINE word32 MakeWordFromHash(const byte* hashID)
{
return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] << 8) |
hashID[3];
}
#endif /* !NO_CERTS || !NO_SESSION_CACHE */
#ifndef NO_CERTS #ifndef NO_CERTS
/* hash is the SHA digest of name, just use first 32 bits as hash */
static INLINE word32 HashSigner(const byte* hash)
{
return MakeWordFromHash(hash) % CA_TABLE_SIZE;
}
/* does CA already exist on signer list */ /* does CA already exist on signer list */
int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash) int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
{ {
Signer* signers; Signer* signers;
int ret = 0; int ret = 0;
word32 row = HashSigner(hash);
if (LockMutex(&cm->caLock) != 0) if (LockMutex(&cm->caLock) != 0)
return ret; return ret;
signers = cm->caList; signers = cm->caTable[row];
while (signers) { while (signers) {
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) { if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
ret = 1; ret = 1;
@ -878,15 +898,15 @@ Signer* GetCA(void* vp, byte* hash)
CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp; CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
Signer* ret = NULL; Signer* ret = NULL;
Signer* signers; Signer* signers;
word32 row = HashSigner(hash);
if (cm == NULL) if (cm == NULL)
return NULL; return NULL;
if (LockMutex(&cm->caLock) != 0) if (LockMutex(&cm->caLock) != 0)
return ret; return ret;
signers = cm->caList; signers = cm->caTable[row];
while (signers) { while (signers) {
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) { if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
ret = signers; ret = signers;
@ -908,6 +928,7 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
int ret; int ret;
DecodedCert cert; DecodedCert cert;
Signer* signer = 0; Signer* signer = 0;
word32 row;
CYASSL_MSG("Adding a CA"); CYASSL_MSG("Adding a CA");
InitDecodedCert(&cert, der.buffer, der.length, cm->heap); InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
@ -938,9 +959,11 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
cert.publicKey = 0; /* don't free here */ cert.publicKey = 0; /* don't free here */
cert.subjectCN = 0; cert.subjectCN = 0;
row = HashSigner(signer->hash);
if (LockMutex(&cm->caLock) == 0) { if (LockMutex(&cm->caLock) == 0) {
signer->next = cm->caList; signer->next = cm->caTable[row];
cm->caList = signer; /* takes ownership */ cm->caTable[row] = signer; /* takes ownership */
UnLockMutex(&cm->caLock); UnLockMutex(&cm->caLock);
if (cm->caCacheCallback) if (cm->caCacheCallback)
cm->caCacheCallback(der.buffer, (int)der.length, type); cm->caCacheCallback(der.buffer, (int)der.length, type);
@ -948,7 +971,7 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
else { else {
CYASSL_MSG(" CA Mutex Lock failed"); CYASSL_MSG(" CA Mutex Lock failed");
ret = BAD_MUTEX_ERROR; ret = BAD_MUTEX_ERROR;
FreeSigners(signer, cm->heap); FreeSigner(signer, cm->heap);
} }
} }
} }
@ -3330,14 +3353,6 @@ int CyaSSL_Cleanup(void)
#ifndef NO_SESSION_CACHE #ifndef NO_SESSION_CACHE
/* Make a work from the front of random hash */
static INLINE word32 MakeWordFromHash(const byte* hashID)
{
return (hashID[0] << 24) | (hashID[1] << 16) | (hashID[2] << 8) |
hashID[3];
}
#ifndef NO_MD5 #ifndef NO_MD5
/* some session IDs aren't random afterall, let's make them random */ /* some session IDs aren't random afterall, let's make them random */