24 #define SCOREBOARD_MIN_SIZE 8
25 #define SCOREBOARD_MAX_SIZE 128
32 #define SCOREBOARD_KEY_SIZE MAX_SESSIONID_SIZE
33 #define SCOREBOARD_DATA_SIZE SSL_SECRET_SIZE
41 typedef BYTE SCOREBOARD_DATA[ SCOREBOARD_DATA_SIZE ];
47 int sessionCheckValue;
57 BUFFER( SCOREBOARD_KEY_SIZE, sessionIDlength )
\
58 BYTE sessionID[ SCOREBOARD_KEY_SIZE + 4 ];
80 #define SCOREBOARD_TIMEOUT 3600
109 static
BOOLEAN sanityCheck(
const SCOREBOARD_INFO *scoreboardInfo )
111 assert(
isReadPtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
114 if( scoreboardInfo->noEntries < SCOREBOARD_MIN_SIZE || \
115 scoreboardInfo->noEntries > SCOREBOARD_MAX_SIZE )
117 if( scoreboardInfo->lastEntry < 0 || \
118 scoreboardInfo->lastEntry > scoreboardInfo->noEntries )
120 if( scoreboardInfo->uniqueID < 0 )
129 static
void clearScoreboardEntry( SCOREBOARD_INDEX *scoreboardEntryPtr )
131 void *savedDataPtr = scoreboardEntryPtr->data;
134 sizeof( SCOREBOARD_INDEX ) ) );
135 assert(
isWritePtr( scoreboardEntryPtr->data, SCOREBOARD_DATA_SIZE ) );
137 REQUIRES_V( scoreboardEntryPtr->data != NULL );
139 zeroise( scoreboardEntryPtr->data, SCOREBOARD_DATA_SIZE );
140 memset( scoreboardEntryPtr, 0,
sizeof( SCOREBOARD_INDEX ) );
141 scoreboardEntryPtr->data = savedDataPtr;
142 scoreboardEntryPtr->dataLength = 0;
148 static
int addEntryData(
INOUT SCOREBOARD_INDEX *scoreboardEntryPtr,
152 IN_INT_Z const int altKeyCheckValue,
157 const time_t currentTime )
161 assert(
isWritePtr( scoreboardEntryPtr,
sizeof( SCOREBOARD_INDEX ) ) );
163 assert( ( altKey == NULL && altKeyLength == 0 ) || \
165 assert(
isReadPtr( value, valueLength ) );
169 REQUIRES( ( altKey == NULL && altKeyLength == 0 && \
170 altKeyCheckValue == 0 ) || \
171 ( altKey != NULL && \
173 altKeyCheckValue >= 0 ) );
174 REQUIRES( valueLength > 0 && valueLength <= SCOREBOARD_DATA_SIZE );
178 clearScoreboardEntry( scoreboardEntryPtr );
182 scoreboardEntryPtr->sessionCheckValue = keyCheckValue;
187 scoreboardEntryPtr->fqdnCheckValue = altKeyCheckValue;
189 altKey, altKeyLength );
191 status = attributeCopyParams( scoreboardEntryPtr->sessionID,
193 &scoreboardEntryPtr->sessionIDlength,
196 status = attributeCopyParams( scoreboardEntryPtr->data,
197 SCOREBOARD_DATA_SIZE,
198 &scoreboardEntryPtr->dataLength,
199 value, valueLength );
201 scoreboardEntryPtr->isServerData = ( altKey == NULL ) ?
TRUE :
FALSE;
202 scoreboardEntryPtr->timeStamp = currentTime;
224 static
int findEntry(
INOUT SCOREBOARD_INFO *scoreboardInfo,
229 const time_t currentTime,
232 SCOREBOARD_INDEX *scoreboardIndex = scoreboardInfo->index;
234 const BOOLEAN keyIsSessionID = \
237 const BOOLEAN isServerMatch = \
240 time_t oldestTime = currentTime;
241 const int checkValue = checksumData( key, keyLength );
242 int nextFreeEntry =
CRYPT_ERROR, lastUsedEntry = 0, oldestEntry = 0;
245 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
247 assert(
isWritePtr( position,
sizeof(
int ) ) );
249 scoreboardInfo->noEntries *
sizeof( SCOREBOARD_INDEX ) ) );
263 for( i = 0; i < scoreboardInfo->lastEntry && \
266 SCOREBOARD_INDEX *scoreboardEntryPtr = &scoreboardIndex[ i ];
269 if( scoreboardEntryPtr->timeStamp + SCOREBOARD_TIMEOUT < currentTime )
270 clearScoreboardEntry( scoreboardEntryPtr );
284 if( scoreboardEntryPtr->timeStamp < oldestTime )
288 oldestTime = scoreboardEntryPtr->timeStamp;
299 if( scoreboardEntryPtr->isServerData != isServerMatch )
304 if( ( keyIsSessionID && \
305 scoreboardEntryPtr->sessionCheckValue == checkValue ) || \
306 ( !keyIsSessionID && \
307 scoreboardEntryPtr->fqdnCheckValue == checkValue ) )
309 void *hashPtr = keyIsSessionID ? \
310 scoreboardEntryPtr->sessionHash : \
311 scoreboardEntryPtr->fqdnHash;
328 ENSURES( i < FAILSAFE_ITERATIONS_MAX );
332 if( lastUsedEntry + 1 < scoreboardInfo->lastEntry )
333 scoreboardInfo->lastEntry = lastUsedEntry + 1;
336 if( matchPosition >= 0 )
338 *position = matchPosition;
344 if( nextFreeEntry >= 0 )
348 *position = nextFreeEntry;
354 if( scoreboardInfo->lastEntry < scoreboardInfo->noEntries )
355 *position = scoreboardInfo->lastEntry;
359 *position = oldestEntry;
362 ENSURES( *position >= 0 && *position < scoreboardInfo->noEntries );
422 static
int addEntry(
INOUT SCOREBOARD_INFO *scoreboardInfo,
427 IN_BUFFER( valueLength )
const void *value,
431 SCOREBOARD_INDEX *scoreboardIndex = scoreboardInfo->index;
432 SCOREBOARD_INDEX *scoreboardEntryPtr = NULL;
433 const time_t currentTime =
getTime();
435 const int checkValue = checksumData( key, keyLength );
436 int altCheckValue = 0, altPosition =
DUMMY_INIT;
439 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
441 assert( ( altKey == NULL && altKeyLength == 0 ) || \
443 assert(
isReadPtr( value, valueLength ) );
444 assert(
isWritePtr( uniqueID,
sizeof(
int ) ) );
446 scoreboardInfo->noEntries *
sizeof( SCOREBOARD_INDEX ) ) );
449 REQUIRES( ( altKey == NULL && altKeyLength == 0 ) || \
450 ( altKey != NULL && \
452 REQUIRES( valueLength > 0 && valueLength <= SCOREBOARD_DATA_SIZE );
454 REQUIRES( sanityCheck( scoreboardInfo ) );
465 status = findEntry( scoreboardInfo, isClient ? \
468 key, keyLength, currentTime, &position );
471 ENSURES( position >= 0 && position < scoreboardInfo->noEntries );
474 altCheckValue = checksumData( altKey, altKeyLength );
476 altKey, altKeyLength, currentTime,
481 altPosition < scoreboardInfo->noEntries );
509 if( altKey != NULL && position != altPosition )
512 clearScoreboardEntry( &scoreboardIndex[ position ] );
518 position == altPosition ) );
519 scoreboardEntryPtr = &scoreboardIndex[
position ];
520 if( scoreboardEntryPtr->dataLength != valueLength || \
521 memcmp( scoreboardEntryPtr->data, value, valueLength ) )
525 clearScoreboardEntry( &scoreboardIndex[ position ] );
529 scoreboardEntryPtr->timeStamp = currentTime;
540 ENSURES( position != altPosition );
541 scoreboardEntryPtr = &scoreboardIndex[ altPosition ];
547 ( altStatus ==
OK_SPECIAL && position == altPosition ) )
548 scoreboardEntryPtr = &scoreboardIndex[ position ];
550 ENSURES( scoreboardEntryPtr != NULL );
553 status = addEntryData( scoreboardEntryPtr, checkValue, key, keyLength,
554 altCheckValue, altKey, altKeyLength, value,
555 valueLength, currentTime );
558 clearScoreboardEntry( scoreboardEntryPtr );
561 *uniqueID = scoreboardEntryPtr->uniqueID = scoreboardInfo->uniqueID++;
564 if( position >= scoreboardInfo->lastEntry )
565 scoreboardInfo->lastEntry = position + 1;
573 static
int lookupScoreboard(
INOUT SCOREBOARD_INFO *scoreboardInfo,
581 SCOREBOARD_INDEX *scoreboardIndex = scoreboardInfo->index;
582 SCOREBOARD_INDEX *scoreboardEntryPtr;
583 const time_t currentTime =
getTime();
586 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
589 assert(
isWritePtr( uniqueID,
sizeof(
int ) ) );
591 scoreboardInfo->noEntries *
sizeof( SCOREBOARD_INDEX ) ) );
596 REQUIRES( sanityCheck( scoreboardInfo ) );
608 status = findEntry( scoreboardInfo, keyType, key, keyLength,
609 currentTime, &position );
617 ENSURES( position >= 0 && position < scoreboardInfo->noEntries );
618 scoreboardEntryPtr = &scoreboardIndex[
position ];
622 lookupResult->key = scoreboardEntryPtr->sessionID;
623 lookupResult->keySize = scoreboardEntryPtr->sessionIDlength;
624 lookupResult->data = scoreboardEntryPtr->data;
625 lookupResult->dataSize = scoreboardEntryPtr->dataLength;
626 *uniqueID = scoreboardEntryPtr->uniqueID;
629 scoreboardEntryPtr->timeStamp = currentTime;
631 ENSURES( sanityCheck( scoreboardInfo ) );
647 void *scoreboardInfoPtr,
654 SCOREBOARD_INFO *scoreboardInfo = scoreboardInfoPtr;
657 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
671 status = lookupScoreboard( scoreboardInfo, keyType, key, keyLength,
672 lookupResult, &uniqueID );
679 void *scoreboardInfoPtr,
685 SCOREBOARD_INFO *scoreboardInfo = scoreboardInfoPtr;
688 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
690 assert(
isReadPtr( value, valueLength ) );
693 REQUIRES( valueLength > 0 && valueLength <= SCOREBOARD_DATA_SIZE );
699 status = addEntry( scoreboardInfo, key, keyLength, NULL, 0,
700 (
void * ) value, valueLength, &uniqueID );
707 void *scoreboardInfoPtr,
715 SCOREBOARD_INFO *scoreboardInfo = scoreboardInfoPtr;
718 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
720 assert(
isReadPtr( altKey, altKeyLength ) );
721 assert(
isReadPtr( value, valueLength ) );
725 REQUIRES( valueLength > 0 && valueLength <= SCOREBOARD_DATA_SIZE );
731 status = addEntry( scoreboardInfo, key, keyLength, altKey, altKeyLength,
732 (
void * ) value, valueLength, &uniqueID );
738 void deleteScoreboardEntry(
INOUT TYPECAST( SCOREBOARD_INFO * ) \
739 void *scoreboardInfoPtr,
742 SCOREBOARD_INFO *scoreboardInfo = scoreboardInfoPtr;
743 SCOREBOARD_INDEX *scoreboardIndex = scoreboardInfo->index;
744 int lastUsedEntry = -1, i,
status;
746 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
756 for( i = 0; i < scoreboardInfo->lastEntry && \
759 SCOREBOARD_INDEX *scoreboardEntryPtr = &scoreboardIndex[ i ];
767 if( scoreboardEntryPtr->uniqueID == uniqueID )
769 clearScoreboardEntry( scoreboardEntryPtr );
776 ENSURES_V( i < FAILSAFE_ITERATIONS_MAX );
780 scoreboardInfo->lastEntry = lastUsedEntry + 1;
794 static
BOOLEAN selfTest(
INOUT SCOREBOARD_INFO *scoreboardInfo )
797 int uniqueID1, uniqueID2, foundUniqueID;
800 "test value 1", 12 );
804 "test value 2", 12 );
812 if( foundUniqueID != uniqueID1 || \
813 lookupResult.
keySize != 10 || \
814 memcmp( lookupResult.key,
"test key 1", 10 ) || \
816 memcmp( lookupResult.data,
"test value 1", 12 ) )
818 deleteScoreboardEntry( scoreboardInfo, uniqueID1 );
824 deleteScoreboardEntry( scoreboardInfo, uniqueID2 );
825 if( scoreboardInfo->lastEntry != 0 || \
826 scoreboardInfo->uniqueID != 2 )
836 void *scoreboardInfoPtr,
838 const int scoreboardEntries )
840 SCOREBOARD_INFO *scoreboardInfo = scoreboardInfoPtr;
841 SCOREBOARD_INDEX *scoreboardIndex;
842 SCOREBOARD_DATA *scoreboardData;
845 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
850 REQUIRES( scoreboardEntries >= SCOREBOARD_MIN_SIZE && \
851 scoreboardEntries <= SCOREBOARD_MAX_SIZE );
858 memset( scoreboardInfo, 0,
sizeof( SCOREBOARD_INFO ) );
859 scoreboardInfo->uniqueID = 0;
860 scoreboardInfo->lastEntry = 0;
861 scoreboardInfo->noEntries = scoreboardEntries;
864 if( ( scoreboardInfo->index =
clAlloc(
"initScoreboard", \
865 scoreboardEntries *
sizeof( SCOREBOARD_INDEX ) ) ) == NULL )
867 status = krnlMemalloc( &scoreboardInfo->data, \
868 scoreboardEntries *
sizeof( SCOREBOARD_DATA ) );
871 clFree(
"initScoreboard", scoreboardInfo->index );
872 memset( scoreboardInfo, 0,
sizeof( SCOREBOARD_INFO ) );
875 scoreboardIndex = scoreboardInfo->index;
876 scoreboardData = scoreboardInfo->data;
877 memset( scoreboardIndex, 0, \
878 scoreboardEntries *
sizeof( SCOREBOARD_INDEX ) );
879 for( i = 0; i < scoreboardEntries; i++ )
881 scoreboardIndex[ i ].data = &scoreboardData[ i ];
882 scoreboardIndex[ i ].dataLength = 0;
884 memset( scoreboardInfo->data, 0, \
885 scoreboardEntries *
sizeof( SCOREBOARD_DATA ) );
888 if( !selfTest( scoreboardInfo ) )
890 status = krnlMemfree( (
void ** ) &scoreboardInfo->data );
892 clFree(
"initScoreboard", scoreboardInfo->index );
893 memset( scoreboardInfo, 0,
sizeof( SCOREBOARD_INFO ) );
904 void *scoreboardInfoPtr )
906 SCOREBOARD_INFO *scoreboardInfo = scoreboardInfoPtr;
909 assert(
isWritePtr( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) ) );
923 status = krnlMemfree( (
void ** ) &scoreboardInfo->data );
925 zeroise( scoreboardInfo->index, \
926 scoreboardInfo->noEntries *
sizeof( SCOREBOARD_INDEX ) );
927 clFree(
"endScoreboard", scoreboardInfo->index );
928 zeroise( scoreboardInfo,
sizeof( SCOREBOARD_INFO ) );