示例#1
0
/*
    Update session information in the cache.
    This is called when we've determined the master secret and when we're
    closing the connection to update various values in the cache.
*/
int32 matrixUpdateSession(ssl_t *ssl)
{
    char    *id;
    uint32  i;

    if (!(ssl->flags & SSL_FLAGS_SERVER)) {
        return -1;
    }
    if ((id = ssl->sessionId) == NULL) {
        return -1;
    }
    i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];
    if (i < 0 || i >= SSL_SESSION_TABLE_SIZE) {
        return -1;
    }
/*
    If there is an error on the session, invalidate for any future use
*/
    sslLockMutex(&sessionTableLock);
    sessionTable[i].inUse = ssl->flags & SSL_FLAGS_CLOSED ? 0 : 1;
    if (ssl->flags & SSL_FLAGS_ERROR) {
        memset(sessionTable[i].masterSecret, 0x0, SSL_HS_MASTER_SIZE);
        sessionTable[i].cipher = NULL;
        sslUnlockMutex(&sessionTableLock);
        return -1;
    }
    memcpy(sessionTable[i].masterSecret, ssl->sec.masterSecret,
        SSL_HS_MASTER_SIZE);
    sessionTable[i].cipher = ssl->cipher;
    sslUnlockMutex(&sessionTableLock);
    return 0;
}
示例#2
0
int32 matrixSslGetResumptionFlag(ssl_t *ssl, char *flag)
{
    char    *id;
    uint32  i;

    if (!(ssl->flags & SSL_FLAGS_SERVER)) {
        return -1;
    }
    if ((id = ssl->sessionId) == NULL) {
        return -1;
    }
    i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];
    if (i < 0 || i >= SSL_SESSION_TABLE_SIZE) {
        return -1;
    }
    sslLockMutex(&sessionTableLock);
    sessionTable[i].inUse = ssl->flags & SSL_FLAGS_CLOSED ? 0 : 1;
    if (ssl->flags & SSL_FLAGS_ERROR) {
        sslUnlockMutex(&sessionTableLock);
        return -1;
    }
    *flag = sessionTable[i].flag;
    sslUnlockMutex(&sessionTableLock);
    return 0;
}
示例#3
0
/*
    Clear the inUse flag during re-handshakes so the entry may be found
*/
int32 matrixClearSession(ssl_t *ssl, int32 remove)
{
    char    *id;
    uint32  i;

    if (ssl->sessionIdLen <= 0) {
        return -1;
    }
    id = ssl->sessionId;

    i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];
    if (i >= SSL_SESSION_TABLE_SIZE || i < 0) {
        return -1;
    }
    sslLockMutex(&sessionTableLock);
    sessionTable[i].inUse = 0;
    sessionTable[i].flag = 0;
/*
    If this is a full removal, actually delete the entry rather than
    just setting the inUse to 0.  Also need to clear any RESUME flag
    on the ssl connection so a new session will be correctly registered.
*/
    if (remove) {
        memset(ssl->sessionId, 0x0, SSL_MAX_SESSION_ID_SIZE);
        ssl->sessionIdLen = 0;
        memset(&sessionTable[i], 0x0, sizeof(sslSessionEntry_t));
        ssl->flags &= ~SSL_FLAGS_RESUMED;
    }
    sslUnlockMutex(&sessionTableLock);
    return 0;
}
示例#4
0
void sslDestroyMutex(sslMutex_t *mutex)
{
	if (mutex == NULL) {
		return;
	}
	sslLockMutex(mutex);
	semDelete((SEM_ID) mutex);
}
示例#5
0
/*
    Look up a session ID in the cache.  If found, set the ssl masterSecret
    and cipher to the pre-negotiated values
*/
int32 matrixResumeSession(ssl_t *ssl)
{
    char    *id;
    uint32  i;

    if (!(ssl->flags & SSL_FLAGS_SERVER)) {
        return -1;
    }
    if (ssl->sessionIdLen <= 0) {
        return -1;
    }
    id = ssl->sessionId;

    i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];

    sslLockMutex(&sessionTableLock);
    if (i >= SSL_SESSION_TABLE_SIZE || i < 0 ||
            sessionTable[i].cipher == NULL) {
        sslUnlockMutex(&sessionTableLock);
        return -1;
    }
/*
    Id looks valid.  Update the access time for expiration check.
    Expiration is done on daily basis (86400 seconds)
*/
    sslInitMsecs(&sessionTable[i].accessTime);
    if (memcmp(sessionTable[i].id, id,
                min(ssl->sessionIdLen, SSL_MAX_SESSION_ID_SIZE)) != 0 ||
            sslDiffSecs(sessionTable[i].startTime,
                sessionTable[i].accessTime) > 86400 ||
            sessionTable[i].inUse ||
            sessionTable[i].majVer != ssl->majVer ||
            sessionTable[i].minVer != ssl->minVer) {
        sslUnlockMutex(&sessionTableLock);
        return -1;
    }
    memcpy(ssl->sec.masterSecret, sessionTable[i].masterSecret,
        SSL_HS_MASTER_SIZE);
    ssl->cipher = sessionTable[i].cipher;
    sessionTable[i].inUse = 1;
    sslUnlockMutex(&sessionTableLock);
    return 0;
}
示例#6
0
void matrixSslClose(void)
{
#ifdef USE_SERVER_SIDE_SSL
	int32		i;

	sslLockMutex(&sessionTableLock);
	for (i = 0; i < SSL_SESSION_TABLE_SIZE; i++) {
		if (sessionTable[i].inUse == 1) {
			matrixStrDebugMsg("Warning: closing while session still in use\n",
				NULL);
		}
	}
	memset(sessionTable, 0x0, 
		sizeof(sslSessionEntry_t) * SSL_SESSION_TABLE_SIZE);
	sslUnlockMutex(&sessionTableLock);
	sslDestroyMutex(&sessionTableLock);
#endif /* USE_SERVER_SIDE_SSL */
	matrixPkiClose();
}
示例#7
0
/*
    Register a session in the session resumption cache.  If successful (rc >=0),
    the ssl sessionId and sessionIdLength fields will be non-NULL upon
    return.
*/
int32 matrixRegisterSession(ssl_t *ssl)
{
    uint32      i, j;
    sslTime_t   t;

    if (!(ssl->flags & SSL_FLAGS_SERVER)) {
        return -1;
    }
/*
    Iterate the session table, looking for an empty entry (cipher null), and
    the oldest entry that is not in use
*/
    sslLockMutex(&sessionTableLock);
    j = SSL_SESSION_TABLE_SIZE;
    t = sessionTable[0].accessTime;
    for (i = 0; i < SSL_SESSION_TABLE_SIZE; i++) {
        if (sessionTable[i].cipher == NULL) {
            break;
        }
        if (sslCompareTime(sessionTable[i].accessTime, t) &&
                sessionTable[i].inUse == 0) {
            t = sessionTable[i].accessTime;
            j = i;
        }
    }
/*
    If there were no empty entries, get the oldest unused entry.
    If all entries are in use, return -1, meaning we can't cache the
    session at this time
*/
    if (i >= SSL_SESSION_TABLE_SIZE) {
        if (j < SSL_SESSION_TABLE_SIZE) {
            i = j;
        } else {
            sslUnlockMutex(&sessionTableLock);
            return -1;
        }
    }
/*
    Register the incoming masterSecret and cipher, which could still be null,
    depending on when we're called.
*/
    memcpy(sessionTable[i].masterSecret, ssl->sec.masterSecret,
        SSL_HS_MASTER_SIZE);
    sessionTable[i].cipher = ssl->cipher;
    sessionTable[i].inUse = 1;
    sslUnlockMutex(&sessionTableLock);
/*
    The sessionId is the current serverRandom value, with the first 4 bytes
    replaced with the current cache index value for quick lookup later.
    FUTURE SECURITY - Should generate more random bytes here for the session
    id.  We re-use the server random as the ID, which is OK, since it is
    sent plaintext on the network, but an attacker listening to a resumed
    connection will also be able to determine part of the original server
    random used to generate the master key, even if he had not seen it
    initially.
*/
    memcpy(sessionTable[i].id, ssl->sec.serverRandom,
        min(SSL_HS_RANDOM_SIZE, SSL_MAX_SESSION_ID_SIZE));
    ssl->sessionIdLen = SSL_MAX_SESSION_ID_SIZE;
    sessionTable[i].id[0] = (unsigned char)(i & 0xFF);
    sessionTable[i].id[1] = (unsigned char)((i & 0xFF00) >> 8);
    sessionTable[i].id[2] = (unsigned char)((i & 0xFF0000) >> 16);
    sessionTable[i].id[3] = (unsigned char)((i & 0xFF000000) >> 24);
    memcpy(ssl->sessionId, sessionTable[i].id, SSL_MAX_SESSION_ID_SIZE);
/*
    startTime is used to check expiry of the entry
    accessTime is used to for cache replacement logic
    The versions are stored, because a cached session must be reused
    with same SSL version.
*/
    sslInitMsecs(&sessionTable[i].startTime);
    sessionTable[i].accessTime = sessionTable[i].startTime;
    sessionTable[i].majVer = ssl->majVer;
    sessionTable[i].minVer = ssl->minVer;
    sessionTable[i].flag = 0;

    return i;
}