/* New SSL protocol context This structure is associated with a single SSL connection. Each socket using SSL should be associated with a new SSL context. certBuf and privKey ARE NOT duplicated within the server context, in order to minimize memory usage with multiple simultaneous requests. They must not be deleted by caller until all server contexts using them are deleted. */ int32 matrixSslNewSession(ssl_t **ssl, sslKeys_t *keys, sslSessionId_t *session, int32 flags) { psPool_t *pool = NULL; ssl_t *lssl; /* First API level chance to make sure a user is not attempting to use client or server support that was not built into this library compile */ #ifndef USE_SERVER_SIDE_SSL if (flags & SSL_FLAGS_SERVER) { matrixStrDebugMsg("MatrixSSL lib not compiled with server support\n", NULL); return -1; } #endif #ifndef USE_CLIENT_SIDE_SSL if (!(flags & SSL_FLAGS_SERVER)) { matrixStrDebugMsg("MatrixSSL lib not compiled with client support\n", NULL); return -1; } #endif if (flags & SSL_FLAGS_CLIENT_AUTH) { matrixStrDebugMsg("MatrixSSL lib not compiled with client " \ "authentication support\n", NULL); return -1; } if (flags & SSL_FLAGS_SERVER) { if (keys == NULL) { matrixStrDebugMsg("NULL keys in matrixSslNewSession\n", NULL); return -1; } if (session != NULL) { matrixStrDebugMsg("Server session must be NULL\n", NULL); return -1; } } *ssl = lssl = psMalloc(pool, sizeof(ssl_t)); if (lssl == NULL) { return SSL_MEM_ERROR; } memset(lssl, 0x0, sizeof(ssl_t)); lssl->pool = pool; lssl->cipher = sslGetCipherSpec(SSL_NULL_WITH_NULL_NULL); sslActivateReadCipher(lssl); sslActivateWriteCipher(lssl); sslActivatePublicCipher(lssl); lssl->recordHeadLen = SSL3_HEADER_LEN; lssl->hshakeHeadLen = SSL3_HANDSHAKE_HEADER_LEN; if (flags & SSL_FLAGS_SERVER) { lssl->flags |= SSL_FLAGS_SERVER; /* Client auth can only be requested by server, not set by client */ if (flags & SSL_FLAGS_CLIENT_AUTH) { lssl->flags |= SSL_FLAGS_CLIENT_AUTH; } lssl->hsState = SSL_HS_CLIENT_HELLO; } else { /* Client is first to set protocol version information based on compile and/or the 'flags' parameter so header information in the handshake messages will be correctly set. */ lssl->majVer = SSL3_MAJ_VER; lssl->minVer = SSL3_MIN_VER; lssl->hsState = SSL_HS_SERVER_HELLO; if (session != NULL && session->cipherId != SSL_NULL_WITH_NULL_NULL) { lssl->cipher = sslGetCipherSpec(session->cipherId); if (lssl->cipher == NULL) { matrixStrDebugMsg("Invalid session id to matrixSslNewSession\n", NULL); } else { memcpy(lssl->sec.masterSecret, session->masterSecret, SSL_HS_MASTER_SIZE); lssl->sessionIdLen = SSL_MAX_SESSION_ID_SIZE; memcpy(lssl->sessionId, session->id, SSL_MAX_SESSION_ID_SIZE); } } } lssl->err = SSL_ALERT_NONE; lssl->keys = keys; return 0; }
/* New SSL protocol context This structure is associated with a single SSL connection. Each socket using SSL should be associated with a new SSL context. certBuf and privKey ARE NOT duplicated within the server context, in order to minimize memory usage with multiple simultaneous requests. They must not be deleted by caller until all server contexts using them are deleted. */ int32 matrixSslNewSession(ssl_t **ssl, sslKeys_t *keys, sslSessionId_t *session, int32 flags) { psPool_t *pool = NULL; ssl_t *lssl; /* First API level chance to make sure a user is not attempting to use client or server support that was not built into this library compile */ #ifndef USE_SERVER_SIDE_SSL if (flags & SSL_FLAGS_SERVER) { psTraceInfo("SSL_FLAGS_SERVER passed to matrixSslNewSession but MatrixSSL lib was not compiled with server support\n"); return PS_ARG_FAIL; } #endif #ifndef USE_CLIENT_SIDE_SSL if (!(flags & SSL_FLAGS_SERVER)) { psTraceInfo("SSL_FLAGS_SERVER was not passed to matrixSslNewSession but MatrixSSL was not compiled with client support\n"); return PS_ARG_FAIL; } #endif if (flags & SSL_FLAGS_CLIENT_AUTH) { psTraceInfo("SSL_FLAGS_CLIENT_AUTH passed to matrixSslNewSession but MatrixSSL was not compiled with USE_CLIENT_AUTH enabled\n"); return PS_ARG_FAIL; } if (flags & SSL_FLAGS_SERVER) { if (keys == NULL) { psTraceInfo("NULL keys parameter passed to matrixSslNewSession\n"); return PS_ARG_FAIL; } if (session != NULL) { psTraceInfo("Ignoring session parameter to matrixSslNewSession\n"); } } *ssl = lssl = psMalloc(pool, sizeof(ssl_t)); if (lssl == NULL) { psTraceInfo("Out of memory for ssl_t in matrixSslNewSession\n"); return PS_MEM_FAIL; } memset(lssl, 0x0, sizeof(ssl_t)); /* Data buffers */ lssl->outsize = SSL_DEFAULT_OUT_BUF_SIZE; lssl->outbuf = psMalloc(MATRIX_NO_POOL, lssl->outsize); if (lssl->outbuf == NULL) { psTraceInfo("Out of memory for outbuf in matrixSslNewSession\n"); psFree(lssl); return PS_MEM_FAIL; } lssl->insize = SSL_DEFAULT_IN_BUF_SIZE; lssl->inbuf = psMalloc(MATRIX_NO_POOL, lssl->insize); if (lssl->inbuf == NULL) { psTraceInfo("Out of memory for inbuf in matrixSslNewSession\n"); psFree(lssl->outbuf); psFree(lssl); return PS_MEM_FAIL; } lssl->sPool = pool; lssl->keys = keys; lssl->cipher = sslGetCipherSpec(lssl, SSL_NULL_WITH_NULL_NULL); sslActivateReadCipher(lssl); sslActivateWriteCipher(lssl); lssl->recordHeadLen = SSL3_HEADER_LEN; lssl->hshakeHeadLen = SSL3_HANDSHAKE_HEADER_LEN; if (flags & SSL_FLAGS_SERVER) { lssl->flags |= SSL_FLAGS_SERVER; /* Client auth can only be requested by server, not set by client */ if (flags & SSL_FLAGS_CLIENT_AUTH) { lssl->flags |= SSL_FLAGS_CLIENT_AUTH; } lssl->hsState = SSL_HS_CLIENT_HELLO; } else { /* Client is first to set protocol version information based on compile and/or the 'flags' parameter so header information in the handshake messages will be correctly set. */ #ifdef USE_TLS #ifndef DISABLE_TLS_1_0 lssl->majVer = TLS_MAJ_VER; lssl->minVer = TLS_MIN_VER; #endif #if defined(USE_TLS_1_1) && !defined(DISABLE_TLS_1_1) lssl->majVer = TLS_MAJ_VER; lssl->minVer = TLS_1_1_MIN_VER; lssl->flags |= SSL_FLAGS_TLS_1_1; #endif /* USE_TLS_1_1 */ if (lssl->majVer == 0) { /* USE_TLS enabled but all DISABLE_TLS versions are enabled so use SSLv3. Compile time tests would catch if no versions are enabled at all */ lssl->majVer = SSL3_MAJ_VER; lssl->minVer = SSL3_MIN_VER; } else { lssl->flags |= SSL_FLAGS_TLS; } #else /* USE_TLS */ lssl->majVer = SSL3_MAJ_VER; lssl->minVer = SSL3_MIN_VER; #endif /* USE_TLS */ lssl->hsState = SSL_HS_SERVER_HELLO; if (session != NULL && session->cipherId != SSL_NULL_WITH_NULL_NULL) { lssl->cipher = sslGetCipherSpec(lssl, session->cipherId); if (lssl->cipher == NULL) { psTraceInfo("Invalid session id to matrixSslNewSession\n"); } else { memcpy(lssl->sec.masterSecret, session->masterSecret, SSL_HS_MASTER_SIZE); lssl->sessionIdLen = SSL_MAX_SESSION_ID_SIZE; memcpy(lssl->sessionId, session->id, SSL_MAX_SESSION_ID_SIZE); } } lssl->sid = session; } lssl->err = SSL_ALERT_NONE; return PS_SUCCESS; }