A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Tue Sep 24 18:11:02 2019 +0000
Revision:
10:e269fd7b9500
Child:
13:0a80b49a5e78
Got padlock and some application data through. Now need to use China remainder theorem to speed up decryption and things up and the session id to avoid having to do the decryption.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 10:e269fd7b9500 1 #include "tls-defs.h"
andrewboyson 10:e269fd7b9500 2 #include "tls-connection.h"
andrewboyson 10:e269fd7b9500 3 #include "tls-session.h"
andrewboyson 10:e269fd7b9500 4 #include "tls-log.h"
andrewboyson 10:e269fd7b9500 5 #include "tls-prf.h"
andrewboyson 10:e269fd7b9500 6 #include "ser-cer.h"
andrewboyson 10:e269fd7b9500 7 #include "pri-key.h"
andrewboyson 10:e269fd7b9500 8 #include "log.h"
andrewboyson 10:e269fd7b9500 9 #include "aes128.h"
andrewboyson 10:e269fd7b9500 10 #include "random.h"
andrewboyson 10:e269fd7b9500 11 #include "sha1.h"
andrewboyson 10:e269fd7b9500 12 #include "tls-mac.h"
andrewboyson 10:e269fd7b9500 13 #include "http.h"
andrewboyson 10:e269fd7b9500 14
andrewboyson 10:e269fd7b9500 15 void addSize(uint8_t** ppCurrent, int size)
andrewboyson 10:e269fd7b9500 16 {
andrewboyson 10:e269fd7b9500 17 uint8_t* p = *ppCurrent;
andrewboyson 10:e269fd7b9500 18 *p++ = size >> 8;
andrewboyson 10:e269fd7b9500 19 *p++ = size & 0xFF;
andrewboyson 10:e269fd7b9500 20 *ppCurrent = p;
andrewboyson 10:e269fd7b9500 21 }
andrewboyson 10:e269fd7b9500 22 void backfillSize(uint8_t* pCurrent, uint8_t* pStart)
andrewboyson 10:e269fd7b9500 23 {
andrewboyson 10:e269fd7b9500 24 int size = pCurrent - pStart - 2;
andrewboyson 10:e269fd7b9500 25 *(pStart + 0) = size >> 8;
andrewboyson 10:e269fd7b9500 26 *(pStart + 1) = size & 0xFF;
andrewboyson 10:e269fd7b9500 27 }
andrewboyson 10:e269fd7b9500 28 static void sendServerHello(struct TlsConnection* pConnection, struct TlsSession* pSession, int* pWindowSize, uint8_t* pWindow, uint32_t positionOfWindowInStream)
andrewboyson 10:e269fd7b9500 29 {
andrewboyson 10:e269fd7b9500 30 //Set up a multiple handshakes content - hello, certificate and done
andrewboyson 10:e269fd7b9500 31 LogTime(" sending server hello\r\n");
andrewboyson 10:e269fd7b9500 32 uint8_t* p = pWindow;
andrewboyson 10:e269fd7b9500 33 *p++ = TLS_CONTENT_TYPE_Handshake; //Content is handshakes
andrewboyson 10:e269fd7b9500 34 *p++ = 0x03; *p++ = 0x03; //Legacy TLS version
andrewboyson 10:e269fd7b9500 35 uint8_t* pHandshakesLength = p;
andrewboyson 10:e269fd7b9500 36 p += 2; //Handshakes Length (2 bytes)
andrewboyson 10:e269fd7b9500 37 uint8_t* handshakesPayloadStart = p; //Record the start of the handshake payload
andrewboyson 10:e269fd7b9500 38
andrewboyson 10:e269fd7b9500 39 //Server hello handshake
andrewboyson 10:e269fd7b9500 40 *p++ = TLS_HANDSHAKE_ServerHello; //Handshake type server hello
andrewboyson 10:e269fd7b9500 41 *p++ = 0x00;
andrewboyson 10:e269fd7b9500 42 uint8_t* pHandshakeHelloLength = p;
andrewboyson 10:e269fd7b9500 43 p += 2; //Size of this handshake
andrewboyson 10:e269fd7b9500 44 *p++ = 0x03; *p++ = 0x03; //TLS version 1.2
andrewboyson 10:e269fd7b9500 45 for (int i = 0; i < 32; i++)
andrewboyson 10:e269fd7b9500 46 {
andrewboyson 10:e269fd7b9500 47 uint8_t r = RandomGetByte();
andrewboyson 10:e269fd7b9500 48 pConnection->serverRandom[i] = r;
andrewboyson 10:e269fd7b9500 49 *p++ = r; //32 bit random number
andrewboyson 10:e269fd7b9500 50 }
andrewboyson 10:e269fd7b9500 51 *p++ = 0x04; //SessionId length 4
andrewboyson 10:e269fd7b9500 52 *p++ = pConnection->sessionId >> 24; //Session id
andrewboyson 10:e269fd7b9500 53 *p++ = pConnection->sessionId >> 16; //Session id
andrewboyson 10:e269fd7b9500 54 *p++ = pConnection->sessionId >> 8; //Session id
andrewboyson 10:e269fd7b9500 55 *p++ = pConnection->sessionId >> 0; //Session id
andrewboyson 10:e269fd7b9500 56 *p++ = 0x00; *p++ = 0x2f; //Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
andrewboyson 10:e269fd7b9500 57 *p++ = 0x00; //Compression method none
andrewboyson 10:e269fd7b9500 58 *p++ = 0x00; *p++ = 0x05; //Extensions length (2 bytes) 5 bytes
andrewboyson 10:e269fd7b9500 59 *p++ = 0xff; *p++ = 0x01; //Extension Renegotiation Info
andrewboyson 10:e269fd7b9500 60 *p++ = 0x00; *p++ = 0x01; //1 bytes of "Renegotiation Info" extension data follows
andrewboyson 10:e269fd7b9500 61 *p++ = 0x00; //length is zero, because this is a new connection
andrewboyson 10:e269fd7b9500 62 backfillSize(p, pHandshakeHelloLength);
andrewboyson 10:e269fd7b9500 63
andrewboyson 10:e269fd7b9500 64 //Certificate handshake
andrewboyson 10:e269fd7b9500 65 *p++ = TLS_HANDSHAKE_Certificate; *p++ = 0x00; //Handshake type certificate
andrewboyson 10:e269fd7b9500 66 addSize(&p, SerCerSize + 6); *p++ = 0x00; //Size of this handshake
andrewboyson 10:e269fd7b9500 67 addSize(&p, SerCerSize + 3); *p++ = 0x00; //Size of all certificates
andrewboyson 10:e269fd7b9500 68 addSize(&p, SerCerSize ); //Size of first certificate
andrewboyson 10:e269fd7b9500 69 for (int i = 0; i < SerCerSize; i++) *p++ = SerCerData[i]; //Certificate
andrewboyson 10:e269fd7b9500 70
andrewboyson 10:e269fd7b9500 71 //Hello done handshake
andrewboyson 10:e269fd7b9500 72 *p++ = TLS_HANDSHAKE_ServerHelloDone; *p++ = 0x00; //Handshake type server hello done
andrewboyson 10:e269fd7b9500 73 *p++ = 0; *p++ = 0; //Size of this handshake
andrewboyson 10:e269fd7b9500 74 backfillSize(p, pHandshakesLength);
andrewboyson 10:e269fd7b9500 75
andrewboyson 10:e269fd7b9500 76 //Finalise the handshake content
andrewboyson 10:e269fd7b9500 77 int handshakeLength = p - handshakesPayloadStart;
andrewboyson 10:e269fd7b9500 78 Sha256Add(&pConnection->handshakeSha, handshakesPayloadStart, handshakeLength); //Add the handshake hash
andrewboyson 10:e269fd7b9500 79 *pWindowSize = p - pWindow;
andrewboyson 10:e269fd7b9500 80 }
andrewboyson 10:e269fd7b9500 81 static void sendServerChange(struct TlsConnection* pConnection, struct TlsSession* pSession, int* pWindowSize, uint8_t* pWindow, uint32_t positionOfWindowInStream)
andrewboyson 10:e269fd7b9500 82 {
andrewboyson 10:e269fd7b9500 83 LogTime(" sending server change\r\n");
andrewboyson 10:e269fd7b9500 84 uint8_t* p = pWindow;
andrewboyson 10:e269fd7b9500 85 *p++ = TLS_CONTENT_TYPE_CHANGE_CIPHER; //Content is change cipher
andrewboyson 10:e269fd7b9500 86 *p++ = 0x03; *p++ = 0x03; //Legacy TLS version
andrewboyson 10:e269fd7b9500 87 *p++ = 0x00; *p++ = 0x01; //Change cipher Length (2 bytes)
andrewboyson 10:e269fd7b9500 88 *p++ = 0x01; //Change cipher message 1
andrewboyson 10:e269fd7b9500 89
andrewboyson 10:e269fd7b9500 90 //Record that all incoming messages are now encrypted
andrewboyson 10:e269fd7b9500 91 pConnection->serverEncrypted = true;
andrewboyson 10:e269fd7b9500 92 pConnection->serverSequence = 0;
andrewboyson 10:e269fd7b9500 93
andrewboyson 10:e269fd7b9500 94 LogTime(" sending server handshake finished\r\n");
andrewboyson 10:e269fd7b9500 95 *p++ = TLS_CONTENT_TYPE_Handshake; //Content is handshakes
andrewboyson 10:e269fd7b9500 96 *p++ = 0x03; *p++ = 0x03; //Legacy TLS version
andrewboyson 10:e269fd7b9500 97 uint8_t* pHandshakesLength = p;
andrewboyson 10:e269fd7b9500 98 p += 2; //Handshakes Length (2 bytes)
andrewboyson 10:e269fd7b9500 99
andrewboyson 10:e269fd7b9500 100 //Hash over all handshake payloads exchanged so far
andrewboyson 10:e269fd7b9500 101 uint8_t hash[32];
andrewboyson 10:e269fd7b9500 102 Sha256Finish(&pConnection->handshakeSha, hash);
andrewboyson 10:e269fd7b9500 103
andrewboyson 10:e269fd7b9500 104 //Make verify data
andrewboyson 10:e269fd7b9500 105 uint8_t verify[12];
andrewboyson 10:e269fd7b9500 106 TlsPrfServerFinished(pSession->masterSecret, hash, verify); //Hash over all handshakes
andrewboyson 10:e269fd7b9500 107
andrewboyson 10:e269fd7b9500 108 //Make the 'finished' handshake
andrewboyson 10:e269fd7b9500 109 uint8_t payload[16];
andrewboyson 10:e269fd7b9500 110 payload[0] = TLS_HANDSHAKE_Finished;
andrewboyson 10:e269fd7b9500 111 payload[1] = 0x00;
andrewboyson 10:e269fd7b9500 112 payload[2] = 0x00;
andrewboyson 10:e269fd7b9500 113 payload[3] = 0x0c; //Length 12
andrewboyson 10:e269fd7b9500 114 for (int i = 0; i < 12; i++) payload[i + 4] = verify[i];
andrewboyson 10:e269fd7b9500 115 int payloadLength = 16;
andrewboyson 10:e269fd7b9500 116
andrewboyson 10:e269fd7b9500 117 uint8_t mac[SHA1_HASH_SIZE];
andrewboyson 10:e269fd7b9500 118 TlsMacSha1(TLS_KEY_SIZE_MAC,
andrewboyson 10:e269fd7b9500 119 pConnection->serverMacKey,
andrewboyson 10:e269fd7b9500 120 pConnection->serverSequence,
andrewboyson 10:e269fd7b9500 121 TLS_CONTENT_TYPE_Handshake,
andrewboyson 10:e269fd7b9500 122 0x03,
andrewboyson 10:e269fd7b9500 123 0x03,
andrewboyson 10:e269fd7b9500 124 payloadLength,
andrewboyson 10:e269fd7b9500 125 payload,
andrewboyson 10:e269fd7b9500 126 mac);
andrewboyson 10:e269fd7b9500 127
andrewboyson 10:e269fd7b9500 128
andrewboyson 10:e269fd7b9500 129 //plaintext
andrewboyson 10:e269fd7b9500 130 uint8_t message[48];
andrewboyson 10:e269fd7b9500 131 for (int i = 0; i < 16; i++) message[i ] = payload[i]; //payload
andrewboyson 10:e269fd7b9500 132 for (int i = 0; i < 20; i++) message[i + 16] = mac[i]; //mac
andrewboyson 10:e269fd7b9500 133 for (int i = 0; i < 12; i++) message[i + 36] = 0x0b; //padding
andrewboyson 10:e269fd7b9500 134
andrewboyson 10:e269fd7b9500 135 uint8_t iv[16];
andrewboyson 10:e269fd7b9500 136 for (int i = 0; i < 16; i++) iv[i] = RandomGetByte();
andrewboyson 10:e269fd7b9500 137
andrewboyson 10:e269fd7b9500 138 //Encrypt
andrewboyson 10:e269fd7b9500 139 struct AES_ctx ctx;
andrewboyson 10:e269fd7b9500 140 AES_init_ctx_iv(&ctx, pConnection->serverWriteKey, iv);
andrewboyson 10:e269fd7b9500 141 AES_CBC_encrypt_buffer(&ctx, message, 48);
andrewboyson 10:e269fd7b9500 142
andrewboyson 10:e269fd7b9500 143 for (int i = 0; i < 16; i++) *p++ = iv[i];
andrewboyson 10:e269fd7b9500 144 for (int i = 0; i < 48; i++) *p++ = message[i];
andrewboyson 10:e269fd7b9500 145
andrewboyson 10:e269fd7b9500 146 //Finalise
andrewboyson 10:e269fd7b9500 147 backfillSize(p, pHandshakesLength);
andrewboyson 10:e269fd7b9500 148 pConnection->serverSequence++;
andrewboyson 10:e269fd7b9500 149 *pWindowSize = p - pWindow;
andrewboyson 10:e269fd7b9500 150 pConnection->serverPositionInStreamOffset = positionOfWindowInStream + *pWindowSize;
andrewboyson 10:e269fd7b9500 151 }
andrewboyson 10:e269fd7b9500 152 static void sendFatal(char description, int* pWindowSize, uint8_t* pWindow, uint32_t positionOfWindowInStream)
andrewboyson 10:e269fd7b9500 153 {
andrewboyson 10:e269fd7b9500 154 LogTime(" sending fatal alert: ");
andrewboyson 10:e269fd7b9500 155 TlsLogAlertDescription(description);
andrewboyson 10:e269fd7b9500 156 Log("\r\n");
andrewboyson 10:e269fd7b9500 157 uint8_t* p = pWindow;
andrewboyson 10:e269fd7b9500 158 *p++ = TLS_CONTENT_TYPE_ALERT; //Content is alert
andrewboyson 10:e269fd7b9500 159 *p++ = 0x03; *p++ = 0x03; //Legacy TLS version
andrewboyson 10:e269fd7b9500 160 addSize(&p, 2); //Alert Length (2 bytes)
andrewboyson 10:e269fd7b9500 161
andrewboyson 10:e269fd7b9500 162 *p++ = 2; //Fatal (level = 2)
andrewboyson 10:e269fd7b9500 163 *p++ = description; //Description
andrewboyson 10:e269fd7b9500 164
andrewboyson 10:e269fd7b9500 165 *pWindowSize = p - pWindow;
andrewboyson 10:e269fd7b9500 166 }
andrewboyson 10:e269fd7b9500 167
andrewboyson 10:e269fd7b9500 168 static bool sendContent(struct TlsConnection* pConnection, int* pWindowSize, uint8_t* pWindow, uint32_t positionOfWindowInStream)
andrewboyson 10:e269fd7b9500 169 {
andrewboyson 10:e269fd7b9500 170 /*
andrewboyson 10:e269fd7b9500 171 content:
andrewboyson 10:e269fd7b9500 172 contentType * 1
andrewboyson 10:e269fd7b9500 173 version * 2
andrewboyson 10:e269fd7b9500 174 length * 2
andrewboyson 10:e269fd7b9500 175 iv * AES_BLOCKLEN (16)
andrewboyson 10:e269fd7b9500 176 message:
andrewboyson 10:e269fd7b9500 177 payload * payloadLength
andrewboyson 10:e269fd7b9500 178 mac * SHA1_HASH_SIZE (20)
andrewboyson 10:e269fd7b9500 179 padding * 0 to AES_BLOCKLEN - 1 (0 to 15)
andrewboyson 10:e269fd7b9500 180 paddingLength * 1
andrewboyson 10:e269fd7b9500 181 */
andrewboyson 10:e269fd7b9500 182 #define CONTENT_MAX_OVERHEAD (5 + AES_BLOCKLEN + SHA1_HASH_SIZE + AES_BLOCKLEN - 1 + 1)
andrewboyson 10:e269fd7b9500 183
andrewboyson 10:e269fd7b9500 184 //Start
andrewboyson 10:e269fd7b9500 185 LogTime(" adding application content\r\n");
andrewboyson 10:e269fd7b9500 186 LogF("- available window size %d\r\n", *pWindowSize);
andrewboyson 10:e269fd7b9500 187 LogF("- position of window in stream %d\r\n", positionOfWindowInStream);
andrewboyson 10:e269fd7b9500 188 uint8_t* p = pWindow;
andrewboyson 10:e269fd7b9500 189 *p++ = TLS_CONTENT_TYPE_Application;
andrewboyson 10:e269fd7b9500 190 *p++ = 0x03; *p++ = 0x03;
andrewboyson 10:e269fd7b9500 191
andrewboyson 10:e269fd7b9500 192 //Prepare a place to backfill the size
andrewboyson 10:e269fd7b9500 193 uint8_t* pBackfillSize = p;
andrewboyson 10:e269fd7b9500 194 *p++ = 0; *p++ = 0;
andrewboyson 10:e269fd7b9500 195
andrewboyson 10:e269fd7b9500 196 //Add the IV
andrewboyson 10:e269fd7b9500 197 uint8_t* pIv = p;
andrewboyson 10:e269fd7b9500 198 for (int i = 0; i < AES_BLOCKLEN; i++) *p++ = RandomGetByte();
andrewboyson 10:e269fd7b9500 199
andrewboyson 10:e269fd7b9500 200 //Add the plain payload
andrewboyson 10:e269fd7b9500 201 uint8_t* pPayload = p;
andrewboyson 10:e269fd7b9500 202 int payloadSize = *pWindowSize - CONTENT_MAX_OVERHEAD;
andrewboyson 10:e269fd7b9500 203 LogF("- available payload size %d\r\n", payloadSize);
andrewboyson 10:e269fd7b9500 204 uint32_t positionOfPayloadInStream = positionOfWindowInStream - pConnection->serverPositionInStreamOffset;
andrewboyson 10:e269fd7b9500 205 LogF("- position of payload in stream %d\r\n", positionOfPayloadInStream);
andrewboyson 10:e269fd7b9500 206 bool finished = HttpAdd(pConnection->id, &payloadSize, (char*)pPayload, positionOfPayloadInStream); //Return whatever HTTP would be
andrewboyson 10:e269fd7b9500 207 LogF("- resulting payload size %d\r\n", payloadSize);
andrewboyson 10:e269fd7b9500 208 p += payloadSize;
andrewboyson 10:e269fd7b9500 209
andrewboyson 10:e269fd7b9500 210 //Add the MAC
andrewboyson 10:e269fd7b9500 211 TlsMacSha1(TLS_KEY_SIZE_MAC,
andrewboyson 10:e269fd7b9500 212 pConnection->serverMacKey,
andrewboyson 10:e269fd7b9500 213 pConnection->serverSequence,
andrewboyson 10:e269fd7b9500 214 TLS_CONTENT_TYPE_Application,
andrewboyson 10:e269fd7b9500 215 0x03,
andrewboyson 10:e269fd7b9500 216 0x03,
andrewboyson 10:e269fd7b9500 217 payloadSize,
andrewboyson 10:e269fd7b9500 218 pPayload,
andrewboyson 10:e269fd7b9500 219 p);
andrewboyson 10:e269fd7b9500 220 p += SHA1_HASH_SIZE;
andrewboyson 10:e269fd7b9500 221
andrewboyson 10:e269fd7b9500 222 //Add the padding
andrewboyson 10:e269fd7b9500 223 int paddingSize = AES_BLOCKLEN - 1 - (payloadSize + SHA1_HASH_SIZE + 1 - 1) % AES_BLOCKLEN;
andrewboyson 10:e269fd7b9500 224 LogF("- padding size %d\r\n", paddingSize);
andrewboyson 10:e269fd7b9500 225 for (int i = 0; i < paddingSize; i++) *p++ = paddingSize;
andrewboyson 10:e269fd7b9500 226
andrewboyson 10:e269fd7b9500 227 //Add the padding size
andrewboyson 10:e269fd7b9500 228 *p++ = paddingSize;
andrewboyson 10:e269fd7b9500 229
andrewboyson 10:e269fd7b9500 230 //Backfill the size
andrewboyson 10:e269fd7b9500 231 backfillSize(p, pBackfillSize);
andrewboyson 10:e269fd7b9500 232
andrewboyson 10:e269fd7b9500 233 //Calculate the resulting window size
andrewboyson 10:e269fd7b9500 234 *pWindowSize = p - pWindow;
andrewboyson 10:e269fd7b9500 235 LogF("- resulting window size %d\r\n", *pWindowSize);
andrewboyson 10:e269fd7b9500 236
andrewboyson 10:e269fd7b9500 237 //Log the plain content
andrewboyson 10:e269fd7b9500 238 Log("- plain content\r\n"); LogBytesAsHex(pWindow, *pWindowSize); Log("\r\n");
andrewboyson 10:e269fd7b9500 239
andrewboyson 10:e269fd7b9500 240 //Encrypt payload + mac + padding
andrewboyson 10:e269fd7b9500 241 struct AES_ctx ctx;
andrewboyson 10:e269fd7b9500 242 AES_init_ctx_iv(&ctx, pConnection->serverWriteKey, pIv);
andrewboyson 10:e269fd7b9500 243 AES_CBC_encrypt_buffer(&ctx, pPayload, p - pPayload);
andrewboyson 10:e269fd7b9500 244
andrewboyson 10:e269fd7b9500 245 //Finalise
andrewboyson 10:e269fd7b9500 246 pConnection->serverSequence++;
andrewboyson 10:e269fd7b9500 247 pConnection->serverPositionInStreamOffset += *pWindowSize - payloadSize;
andrewboyson 10:e269fd7b9500 248
andrewboyson 10:e269fd7b9500 249 return finished;
andrewboyson 10:e269fd7b9500 250 }
andrewboyson 10:e269fd7b9500 251 bool TlsResponse(int connectionId, bool clientFinished, int* pWindowSize, uint8_t* pWindow, uint32_t positionOfWindowInStream)
andrewboyson 10:e269fd7b9500 252 {
andrewboyson 10:e269fd7b9500 253 struct TlsConnection* pConnection = TlsConnectionOrNull(connectionId);
andrewboyson 10:e269fd7b9500 254 if (!pConnection)
andrewboyson 10:e269fd7b9500 255 {
andrewboyson 10:e269fd7b9500 256 *pWindowSize = 0;
andrewboyson 10:e269fd7b9500 257 return false;
andrewboyson 10:e269fd7b9500 258 }
andrewboyson 10:e269fd7b9500 259
andrewboyson 10:e269fd7b9500 260 if (!pConnection->sessionId)
andrewboyson 10:e269fd7b9500 261 {
andrewboyson 10:e269fd7b9500 262 *pWindowSize = 0;
andrewboyson 10:e269fd7b9500 263 return false;
andrewboyson 10:e269fd7b9500 264 }
andrewboyson 10:e269fd7b9500 265
andrewboyson 10:e269fd7b9500 266 struct TlsSession* pSession = TlsSessionOrNull(pConnection->sessionId);
andrewboyson 10:e269fd7b9500 267 if (!pSession)
andrewboyson 10:e269fd7b9500 268 {
andrewboyson 10:e269fd7b9500 269 LogTimeF("TlsPoll - invalid session %u\r\n", pConnection->sessionId);
andrewboyson 10:e269fd7b9500 270 *pWindowSize = 0;
andrewboyson 10:e269fd7b9500 271 return false;
andrewboyson 10:e269fd7b9500 272 }
andrewboyson 10:e269fd7b9500 273
andrewboyson 10:e269fd7b9500 274 switch (pConnection->toDo)
andrewboyson 10:e269fd7b9500 275 {
andrewboyson 10:e269fd7b9500 276 case DO_WAIT_CLIENT_HELLO:
andrewboyson 10:e269fd7b9500 277 case DO_WAIT_CLIENT_CHANGE:
andrewboyson 10:e269fd7b9500 278 case DO_WAIT_DECRYPT_MASTER_SECRET:
andrewboyson 10:e269fd7b9500 279 *pWindowSize = 0;
andrewboyson 10:e269fd7b9500 280 if (clientFinished) return true; //The client hasn't made a request and never will so finish
andrewboyson 10:e269fd7b9500 281 else return false; //The client hasn't made a request yet but it could.
andrewboyson 10:e269fd7b9500 282
andrewboyson 10:e269fd7b9500 283 case DO_SEND_SERVER_HELLO:
andrewboyson 10:e269fd7b9500 284 sendServerHello(pConnection, pSession, pWindowSize, pWindow, positionOfWindowInStream);
andrewboyson 10:e269fd7b9500 285 pConnection->toDo = DO_WAIT_CLIENT_CHANGE;
andrewboyson 10:e269fd7b9500 286 return false; //Not finished
andrewboyson 10:e269fd7b9500 287
andrewboyson 10:e269fd7b9500 288 case DO_SEND_SERVER_CHANGE:
andrewboyson 10:e269fd7b9500 289 sendServerChange(pConnection, pSession, pWindowSize, pWindow, positionOfWindowInStream);
andrewboyson 10:e269fd7b9500 290 pConnection->toDo = DO_APPLICATION;
andrewboyson 10:e269fd7b9500 291 return false;
andrewboyson 10:e269fd7b9500 292
andrewboyson 10:e269fd7b9500 293 case DO_APPLICATION:
andrewboyson 10:e269fd7b9500 294 {
andrewboyson 10:e269fd7b9500 295 int status = HttpPoll(connectionId, clientFinished);
andrewboyson 10:e269fd7b9500 296 bool finished;
andrewboyson 10:e269fd7b9500 297 switch (status)
andrewboyson 10:e269fd7b9500 298 {
andrewboyson 10:e269fd7b9500 299 case HTTP_WAIT: finished = false; *pWindowSize = 0; break;
andrewboyson 10:e269fd7b9500 300 case HTTP_FINISHED: finished = true; *pWindowSize = 0; break;
andrewboyson 10:e269fd7b9500 301 case HTTP_HAVE_SOMETHING_TO_SEND: finished = sendContent(pConnection, pWindowSize, pWindow, positionOfWindowInStream); break;
andrewboyson 10:e269fd7b9500 302 }
andrewboyson 10:e269fd7b9500 303 if (finished) pConnection->toDo = DO_WAIT_CLIENT_HELLO;
andrewboyson 10:e269fd7b9500 304 return finished;
andrewboyson 10:e269fd7b9500 305 }
andrewboyson 10:e269fd7b9500 306 case DO_SEND_ALERT_ILLEGAL_PARAMETER:
andrewboyson 10:e269fd7b9500 307 sendFatal(TLS_ALERT_ILLEGAL_PARAMETER, pWindowSize, pWindow, positionOfWindowInStream);
andrewboyson 10:e269fd7b9500 308 pConnection->toDo = DO_WAIT_CLIENT_HELLO;
andrewboyson 10:e269fd7b9500 309 return true; //Finished
andrewboyson 10:e269fd7b9500 310
andrewboyson 10:e269fd7b9500 311 case DO_SEND_ALERT_INTERNAL_ERROR:
andrewboyson 10:e269fd7b9500 312 sendFatal(TLS_ALERT_INTERNAL_ERROR, pWindowSize, pWindow, positionOfWindowInStream);
andrewboyson 10:e269fd7b9500 313 pConnection->toDo = DO_WAIT_CLIENT_HELLO;
andrewboyson 10:e269fd7b9500 314 return true; //Finished
andrewboyson 10:e269fd7b9500 315
andrewboyson 10:e269fd7b9500 316 default:
andrewboyson 10:e269fd7b9500 317 LogTimeF("TlsPoll - unspecified TLS state %d\r\n", pConnection->toDo);
andrewboyson 10:e269fd7b9500 318 sendFatal(TLS_ALERT_INTERNAL_ERROR, pWindowSize, pWindow, positionOfWindowInStream); //Internal error
andrewboyson 10:e269fd7b9500 319 pConnection->toDo = DO_WAIT_CLIENT_HELLO;
andrewboyson 10:e269fd7b9500 320 return true; //Finished
andrewboyson 10:e269fd7b9500 321 }
andrewboyson 10:e269fd7b9500 322 }