CAMLprim value stub_new_session_id(value unit) { CAMLparam1 (unit); sslSessionId_t *s; if(matrixSslNewSessionId(&s) < 0) { caml_failwith("Failed to allocate memory for session"); } CAMLreturn(alloc_sslSessionId_t(s)); }
/* Main routine. Initialize SSL keys and structures, and make two SSL connections, the first with a blank session Id, and the second with a session ID populated during the first connection to do a much faster session resumption connection the second time. */ int32 main(int32 argc, char **argv) { int32 rc, CAstreamLen; sslKeys_t *keys; sslSessionId_t *sid; char *CAstream; #ifdef USE_CRL int32 numLoaded; #endif #ifdef WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); #endif if ((rc = matrixSslOpen()) < 0) { _psTrace("MatrixSSL library init failure. Exiting\n"); return rc; } if (matrixSslNewKeys(&keys) < 0) { _psTrace("MatrixSSL library key init failure. Exiting\n"); return -1; } #ifdef USE_HEADER_KEYS /* In-memory based keys Build the CA list first for potential client auth usage */ CAstreamLen = 0; CAstreamLen += sizeof(RSACAS); if (CAstreamLen > 0) { CAstream = psMalloc(NULL, CAstreamLen); } else { CAstream = NULL; } CAstreamLen = 0; memcpy(CAstream, RSACAS, sizeof(RSACAS)); CAstreamLen += sizeof(RSACAS); #ifdef ID_RSA if ((rc = matrixSslLoadRsaKeysMem(keys, RSA2048, sizeof(RSA2048), RSA2048KEY, sizeof(RSA2048KEY), (unsigned char*)CAstream, CAstreamLen)) < 0) { _psTrace("No certificate material loaded. Exiting\n"); if (CAstream) psFree(CAstream); matrixSslDeleteKeys(keys); matrixSslClose(); return rc; } #endif if (CAstream) psFree(CAstream); #else /* File based keys */ CAstreamLen = 0; CAstreamLen += (int32)strlen(rsaCAFile) + 1; if (CAstreamLen > 0) { CAstream = psMalloc(NULL, CAstreamLen); memset(CAstream, 0x0, CAstreamLen); } else { CAstream = NULL; } CAstreamLen = 0; memcpy(CAstream, rsaCAFile, strlen(rsaCAFile)); CAstreamLen += strlen(rsaCAFile); /* Load Identiy */ #ifdef EXAMPLE_RSA_KEYS if ((rc = matrixSslLoadRsaKeys(keys, rsaCertFile, rsaPrivkeyFile, NULL, (char*)CAstream)) < 0) { _psTrace("No certificate material loaded. Exiting\n"); if (CAstream) psFree(CAstream); matrixSslDeleteKeys(keys); matrixSslClose(); return rc; } #endif if (CAstream) psFree(CAstream); #endif /* USE_HEADER_KEYS */ #ifdef USE_CRL if (matrixSslGetCRL(keys, crlCb, &numLoaded) < 0) { _psTrace("WARNING: A CRL failed to load\n"); } _psTraceInt("CRLs loaded: %d\n", numLoaded); #endif matrixSslNewSessionId(&sid); _psTrace("=== INITIAL CLIENT SESSION ===\n"); httpsClientConnection(keys, sid); _psTrace("\n=== CLIENT SESSION WITH CACHED SESSION ID ===\n"); httpsClientConnection(keys, sid); matrixSslDeleteSessionId(sid); matrixSslDeleteKeys(keys); matrixSslClose(); #ifdef WIN32 _psTrace("Press any key to close"); getchar(); #endif return 0; }
int main(int argc, char **argv) { int32 id; sslConn_t *svrConn, *clnConn; #ifdef ENABLE_PERF_TIMING int32 perfIter; uint32 clnTime, svrTime; #endif /* ENABLE_PERF_TIMING */ if (matrixSslOpen() < 0) { fprintf(stderr, "matrixSslOpen failed, exiting..."); } svrConn = psMalloc(MATRIX_NO_POOL, sizeof(sslConn_t)); clnConn = psMalloc(MATRIX_NO_POOL, sizeof(sslConn_t)); memset(svrConn, 0, sizeof(sslConn_t)); memset(clnConn, 0, sizeof(sslConn_t)); for (id = 0; ciphers[id].cipherId > 0; id++) { matrixSslNewSessionId(&clientSessionId); _psTraceStr("Testing %s suite\n", ciphers[id].name); /* Standard Handshake */ _psTrace(" Standard handshake test\n"); #ifdef ENABLE_PERF_TIMING /* Each matrixSsl call in the handshake is wrapped by a timer. Data exchange is NOT included in the timer */ clnTime = svrTime = 0; _psTraceInt(" %d connections\n", (int32)CONN_ITER); for (perfIter = 0; perfIter < CONN_ITER; perfIter++) { #endif /* ENABLE_PERF_TIMING */ if (initializeHandshake(clnConn, svrConn, ciphers[id], clientSessionId) < 0) { _psTrace(" FAILED: initializing Standard handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Standard handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Standard handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange srv application data\n"); } else { testTrace("\n"); } } #ifdef ENABLE_PERF_TIMING svrTime += svrConn->runningTime; clnTime += clnConn->runningTime; /* Have to reset conn for full handshake... except last time through */ if (perfIter + 1 != CONN_ITER) { matrixSslDeleteSession(clnConn->ssl); matrixSslDeleteSession(svrConn->ssl); matrixSslClearSessionId(clientSessionId); } } /* iteration loop close */ _psTraceInt(" CLIENT: %d " TIME_UNITS, (int32)clnTime/CONN_ITER); _psTraceInt(" SERVER: %d " TIME_UNITS, (int32)svrTime/CONN_ITER); _psTrace("\n"); #endif /* ENABLE_PERF_TIMING */ #ifdef SSL_REHANDSHAKES_ENABLED /* Re-Handshake (full handshake over existing connection) */ testTrace(" Re-handshake test (client-initiated)\n"); if (initializeReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #else _psTrace(" Re-handshake tests are disabled (ENABLE_SECURE_REHANDSHAKES)\n"); #endif /* Resumed handshake (fast handshake over new connection) */ testTrace(" Resumed handshake test (new connection)\n"); if (initializeResumedHandshake(clnConn, svrConn, ciphers[id]) < 0) { _psTrace(" FAILED: initializing Resumed handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Resumed handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Resumed handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #ifdef SSL_REHANDSHAKES_ENABLED /* Re-handshake initiated by server (full handshake over existing conn) */ testTrace(" Re-handshake test (server initiated)\n"); if (initializeServerInitiatedReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Re-handshake\n"); goto LBL_FREE; } if (performHandshake(svrConn, clnConn) < 0) { _psTrace(" FAILED: Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Testing 5 more re-handshake paths. Add some credits */ matrixSslAddRehandshakeCredits(svrConn->ssl, 5); /* Resumed re-handshake (fast handshake over existing connection) */ testTrace(" Resumed Re-handshake test (client initiated)\n"); if (initializeResumedReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Resumed Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Resumed Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Resumed Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Resumed re-handshake initiated by server (fast handshake over conn) */ testTrace(" Resumed Re-handshake test (server initiated)\n"); if (initializeServerInitiatedResumedReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing Resumed Re-handshake\n"); goto LBL_FREE; } if (performHandshake(svrConn, clnConn) < 0) { _psTrace(" FAILED: Resumed Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Resumed Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Re-handshaking with "upgraded" parameters */ testTrace(" Change cert callback Re-handshake test\n"); if (initializeUpgradeCertCbackReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: init upgrade certCback Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Upgrade cert callback Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Upgrade cert callback Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Upgraded keys */ testTrace(" Change keys Re-handshake test\n"); if (initializeUpgradeKeysReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: init upgrade keys Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Upgrade keys Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Upgrade keys Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } /* Change cipher spec test. Changing to a hardcoded RSA suite so this will not work on suites that don't have RSA material loaded */ if (ciphers[id].rsa == 1 && ciphers[id].ecdh == 0) { testTrace(" Change cipher suite Re-handshake test\n"); if (initializeChangeCipherReHandshake(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: init change cipher Re-handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Change cipher suite Re-handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Change cipher suite Re-handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } } #endif /* !SSL_REHANDSHAKES_ENABLED */ #ifdef USE_CLIENT_AUTH /* Client Authentication handshakes */ if (ciphers[id].psk == 0) { _psTrace(" Standard Client Authentication test\n"); #ifdef ENABLE_PERF_TIMING clnTime = svrTime = 0; _psTraceInt(" %d connections\n", (int32)CONN_ITER); for (perfIter = 0; perfIter < CONN_ITER; perfIter++) { #endif /* ENABLE_PERF_TIMING */ matrixSslClearSessionId(clientSessionId); if (initializeClientAuthHandshake(clnConn, svrConn, ciphers[id].cipherId, clientSessionId) < 0) { _psTrace(" FAILED: initializing Standard Client Auth handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Standard Client Auth handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Standard Client Auth handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #ifdef ENABLE_PERF_TIMING svrTime += svrConn->runningTime; clnTime += clnConn->runningTime; } /* iteration loop */ _psTraceInt(" CLIENT: %d " TIME_UNITS, (int32)clnTime/CONN_ITER); _psTraceInt(" SERVER: %d " TIME_UNITS, (int32)svrTime/CONN_ITER); _psTrace("\n==========\n"); #endif /* ENABLE_PERF_TIMING */ testTrace(" Resumed client authentication test\n"); if (initializeResumedHandshake(clnConn, svrConn, ciphers[id]) < 0) { _psTrace(" FAILED: initializing resumed Client Auth handshake\n"); goto LBL_FREE; } if (performHandshake(clnConn, svrConn) < 0) { _psTrace(" FAILED: Resumed Client Auth handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Resumed Client Auth handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #ifdef SSL_REHANDSHAKES_ENABLED testTrace(" Rehandshake adding client authentication test\n"); if (initializeReHandshakeClientAuth(clnConn, svrConn, ciphers[id].cipherId) < 0) { _psTrace(" FAILED: initializing reshandshke Client Auth handshake\n"); goto LBL_FREE; } /* Must be server initiatated if client auth is being turned on */ if (performHandshake(svrConn, clnConn) < 0) { _psTrace(" FAILED: Rehandshake Client Auth handshake\n"); goto LBL_FREE; } else { testTrace(" PASSED: Rehandshake Client Auth handshake"); if (exchangeAppData(clnConn, svrConn) < 0 || exchangeAppData(svrConn, clnConn) < 0) { _psTrace(" but FAILED to exchange application data\n"); } else { testTrace("\n"); } } #endif /* SSL_REHANDSHAKES_ENABLED */ } #endif /* USE_CLIENT_AUTH */ LBL_FREE: freeSessionAndConnection(svrConn); freeSessionAndConnection(clnConn); } psFree(svrConn); psFree(clnConn); matrixSslDeleteSessionId(clientSessionId); matrixSslClose(); #ifdef WIN32 _psTrace("Press any key to close"); getchar(); #endif return PS_SUCCESS; }