A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Oct 10 15:29:05 2019 +0000
Revision:
18:e3cf22ba2a06
Parent:
17:93feb2a51d58
Child:
19:f22327e8be7b
Gave the cipher part AES_128_CBC_SHA its own module.

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