A simple library to support serving https.
Dependents: oldheating gps motorhome heating
tls/tls-request.c
- Committer:
- andrewboyson
- Date:
- 2019-07-31
- Revision:
- 2:82268409e83f
- Child:
- 4:6a1d887f1cad
File content as of revision 2:82268409e83f:
#include "tls.h" #include "tls-defs.h" #include "tls-state.h" #include "tls-session.h" #include "tls-log.h" #include "mstimer.h" #include "random.h" #include "log.h" #include "pri-key.h" static int handleClientHello(int length, char* pBuffer, struct TlsState* pState) //returns 0 on success; -1 on error { //Check things look ok char* p = pBuffer; if (length < 100) { LogF("TLS - %d byte client hello message is not at least 100 bytes long\r\n", length); return -1; } //Read in the parameters char versionH = *p++; char versionL = *p++; char* pRandom = p; p += 32; int sessionIdLength = *p++; char* pSessionId = p; //Handle the parameters pState->session = -1; if (sessionIdLength == 1) pState->session = *pSessionId; struct TlsSession* pSession = TlsSessionGetFromIndex(pState->session); if (!pSession || pSession->state != TLS_SESSION_STATE_VALID) { pSession = TlsSessionGetOldest(); pSession->state = TLS_SESSION_STATE_STARTED; } pState->session = TlsSessionGetIndex(pSession); pSession->lastUsed = MsTimerCount; for (int i = 0; i < 32; i++) pSession->clientRandom[i] = *pRandom++; for (int i = 0; i < 32; i++) pSession->serverRandom[i] = RandomGetByte(); //Log the parameters if (TlsTrace) { LogF("- client version HH:LL: %02x:%02x\r\n", versionH, versionL); Log ("- client random:\r\n"); LogBytesAsHex(pRandom, 32); Log("\r\n"); Log ("- client session id:\r\n"); LogBytesAsHex(pSessionId, sessionIdLength); Log("\r\n"); LogF("- session index: %d\r\n", pState->session); } return 0; } static int handleClientKeyExchange(int length, char* pBuffer, struct TlsState* pState) //returns 0 on success; -1 on error { struct TlsSession* pSession = TlsSessionGetFromIndex(pState->session); if (length != 130) { LogF("TLS - %d byte client key exchange message is not 130 bytes long\r\n", length); return -1; } int premasterLength = pBuffer[0] << 8 | pBuffer[1]; //Overall length 2 bytes if (premasterLength != 128) { LogF("TLS - %d byte encrypted pre master secret is not 128 bytes long\r\n", length); return -1; } char* pEncryptedPreMasterSecret = pBuffer + 2; pSession->slotPriKeyDecryption = PriKeyDecryptStart(pEncryptedPreMasterSecret); if (TlsTrace) { LogF("- encrypted pre master\r\n", premasterLength); LogBytesAsHex(pEncryptedPreMasterSecret, 128); Log("\r\n"); } return 0; } static void handleHandshake(int length, char* pBuffer, struct TlsState* pState) { char* p = pBuffer; while (p < pBuffer + length) { char handshakeType = *p++; int handshakeLength = *p++ << 16; handshakeLength |= *p++ << 8; handshakeLength |= *p++ ; //Handshake length 3 bytes if (TlsTrace) { Log ("- handshake type: "); TlsLogHandshakeType(handshakeType); Log("\r\n"); LogF("- handshake length: %d\r\n", handshakeLength); } int r = -1; switch (handshakeType) { case TLS_HANDSHAKE_ClientHello: r = handleClientHello(handshakeLength, p, pState); pState->toDo = r ? DO_SEND_ALERT_ILLEGAL_PARAMETER : DO_SEND_SERVER_HELLO; break; case TLS_HANDSHAKE_ClientKeyExchange: r = handleClientKeyExchange(handshakeLength, p, pState); pState->toDo = r ? DO_SEND_ALERT_ILLEGAL_PARAMETER : DO_WAIT_DECRYPT_MASTER_SECRET; break; default: LogF("TLS - ignoring untreated %d byte handshake type ", handshakeLength); TlsLogHandshakeType(handshakeType); Log("\r\n"); break; } p += handshakeLength; } } static void handleAlert(int length, char* pBuffer) { char level = pBuffer[0]; char description = pBuffer[1]; if (TlsTrace) { Log("- alert level: "); TlsLogAlertLevel (level); Log("\r\n"); Log("- alert description: "); TlsLogAlertDescription(description); Log("\r\n"); } } static void handleApplication(int length, char* pBuffer) { if (TlsTrace) { Log("- application data:\r\n"); LogBytesAsHex(pBuffer, length); Log("\r\n"); } } void TlsRequest(char* pTlsState, char* pWebState, int size, char* pRequestStream, uint32_t positionInRequestStream) { struct TlsState* pState = (struct TlsState*)pTlsState; if (TlsTrace) LogF("TLS <<< %d (%u)\r\n", size, positionInRequestStream); if (size == 0) return; //if (positionInRequestStream != 0) return; char contentType = pRequestStream[0]; char versionH = pRequestStream[1]; char versionL = pRequestStream[2]; int length = pRequestStream[3] << 8 | pRequestStream[4]; //Length (2 bytes) if (TlsTrace) { Log ("- content type: "); TlsLogContentType(contentType); Log("\r\n"); LogF("- legacy HH:LL: %02x:%02x\r\n", versionH, versionL); LogF("- length : %d\r\n" , length); } switch (contentType) { case TLS_CONTENT_TYPE_Handshake: { handleHandshake(length, pRequestStream + 5, pState); return; } case TLS_CONTENT_TYPE_ALERT: { handleAlert(length, pRequestStream + 5); return; } case TLS_CONTENT_TYPE_Application: { handleApplication(length, pRequestStream + 5); pState->toDo = DO_APPLICATION; return; } default: Log("TLS - untreated content type "); TlsLogContentType(contentType); Log("\r\n"); pState->toDo = DO_WAIT_CLIENT_HELLO; return; } }