A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Apr 01 12:48:52 2020 +0000
Revision:
24:cb43290fc439
Parent:
22:af0b5ceb556e
Added check so that if the client closes the TCP connection before the TLS connection is established then respond that we have finished and the TCP connection is to be closed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 2:82268409e83f 1 #include "tls.h"
andrewboyson 2:82268409e83f 2 #include "tls-defs.h"
andrewboyson 5:ee5489ee1117 3 #include "tls-connection.h"
andrewboyson 2:82268409e83f 4 #include "tls-session.h"
andrewboyson 2:82268409e83f 5 #include "tls-log.h"
andrewboyson 8:5e66a6b4b38c 6 #include "tls-prf.h"
andrewboyson 2:82268409e83f 7 #include "mstimer.h"
andrewboyson 2:82268409e83f 8 #include "log.h"
andrewboyson 2:82268409e83f 9 #include "pri-key.h"
andrewboyson 18:e3cf22ba2a06 10 #include "tls-aes128cbc-sha.h"
andrewboyson 9:f354b4859b0b 11 #include "tls-mac.h"
andrewboyson 8:5e66a6b4b38c 12 #include "led.h"
andrewboyson 9:f354b4859b0b 13 #include "http.h"
andrewboyson 2:82268409e83f 14
andrewboyson 14:03a0b8fd6ddc 15 static void handleClientHello(int length, uint8_t* pBuffer, struct TlsConnection* pConnection)
andrewboyson 5:ee5489ee1117 16 {
andrewboyson 2:82268409e83f 17 //Check things look ok
andrewboyson 4:6a1d887f1cad 18 uint8_t* p = pBuffer;
andrewboyson 2:82268409e83f 19 if (length < 100)
andrewboyson 2:82268409e83f 20 {
andrewboyson 2:82268409e83f 21 LogF("TLS - %d byte client hello message is not at least 100 bytes long\r\n", length);
andrewboyson 14:03a0b8fd6ddc 22 pConnection->toDo = DO_SEND_ALERT_ILLEGAL_PARAMETER;
andrewboyson 14:03a0b8fd6ddc 23 return;
andrewboyson 2:82268409e83f 24 }
andrewboyson 4:6a1d887f1cad 25
andrewboyson 14:03a0b8fd6ddc 26 //get the version
andrewboyson 4:6a1d887f1cad 27 uint8_t versionH = *p++;
andrewboyson 4:6a1d887f1cad 28 uint8_t versionL = *p++;
andrewboyson 2:82268409e83f 29
andrewboyson 14:03a0b8fd6ddc 30 //Get the client random
andrewboyson 6:819c17738dc2 31 for (int i = 0; i < 32; i++) pConnection->clientRandom[i] = *p++;
andrewboyson 2:82268409e83f 32
andrewboyson 14:03a0b8fd6ddc 33 //Get the session id
andrewboyson 2:82268409e83f 34 int sessionIdLength = *p++;
andrewboyson 4:6a1d887f1cad 35 uint8_t* pSessionId = p;
andrewboyson 2:82268409e83f 36
andrewboyson 10:e269fd7b9500 37 if (sessionIdLength == 4)
andrewboyson 2:82268409e83f 38 {
andrewboyson 10:e269fd7b9500 39 pConnection->sessionId = *p++;
andrewboyson 10:e269fd7b9500 40 pConnection->sessionId <<= 8;
andrewboyson 10:e269fd7b9500 41 pConnection->sessionId |= *p++;
andrewboyson 10:e269fd7b9500 42 pConnection->sessionId <<= 8;
andrewboyson 10:e269fd7b9500 43 pConnection->sessionId |= *p++;
andrewboyson 10:e269fd7b9500 44 pConnection->sessionId <<= 8;
andrewboyson 10:e269fd7b9500 45 pConnection->sessionId |= *p++;
andrewboyson 2:82268409e83f 46 }
andrewboyson 10:e269fd7b9500 47 else
andrewboyson 10:e269fd7b9500 48 {
andrewboyson 10:e269fd7b9500 49 pConnection->sessionId = 0;
andrewboyson 10:e269fd7b9500 50 p += sessionIdLength;
andrewboyson 10:e269fd7b9500 51 }
andrewboyson 14:03a0b8fd6ddc 52
andrewboyson 14:03a0b8fd6ddc 53 //Work out from the session id if this connection can be resumed from an existing session
andrewboyson 14:03a0b8fd6ddc 54 struct TlsSession* pSession = TlsSessionOrNull(pConnection->sessionId);
andrewboyson 14:03a0b8fd6ddc 55 pConnection->resume = pSession && pSession->valid;
andrewboyson 14:03a0b8fd6ddc 56
andrewboyson 14:03a0b8fd6ddc 57 //If it cannot be resumed then create a new one
andrewboyson 14:03a0b8fd6ddc 58 if (!pConnection->resume)
andrewboyson 10:e269fd7b9500 59 {
andrewboyson 10:e269fd7b9500 60 pSession = TlsSessionNew();
andrewboyson 10:e269fd7b9500 61 pConnection->sessionId = pSession->id;
andrewboyson 10:e269fd7b9500 62 }
andrewboyson 2:82268409e83f 63
andrewboyson 2:82268409e83f 64 pSession->lastUsed = MsTimerCount;
andrewboyson 2:82268409e83f 65
andrewboyson 2:82268409e83f 66 //Log the parameters
andrewboyson 2:82268409e83f 67 if (TlsTrace)
andrewboyson 2:82268409e83f 68 {
andrewboyson 2:82268409e83f 69 LogF("- client version HH:LL: %02x:%02x\r\n", versionH, versionL);
andrewboyson 17:93feb2a51d58 70 Log ("- client random:\r\n"); LogBytesAsHex(pConnection->clientRandom, TLS_LENGTH_RANDOM); Log("\r\n");
andrewboyson 2:82268409e83f 71 Log ("- client session id:\r\n"); LogBytesAsHex(pSessionId, sessionIdLength); Log("\r\n");
andrewboyson 10:e269fd7b9500 72 LogF("- session index: %u\r\n", pConnection->sessionId);
andrewboyson 14:03a0b8fd6ddc 73 if (pConnection->resume) Log ("- existing session so resume\r\n");
andrewboyson 14:03a0b8fd6ddc 74 else Log ("- new session\r\n");
andrewboyson 2:82268409e83f 75 }
andrewboyson 14:03a0b8fd6ddc 76
andrewboyson 14:03a0b8fd6ddc 77 if (pConnection->resume) pConnection->toDo = DO_SEND_SERVER_HELLO_RESUME;
andrewboyson 14:03a0b8fd6ddc 78 else pConnection->toDo = DO_SEND_SERVER_HELLO_NEW;
andrewboyson 14:03a0b8fd6ddc 79
andrewboyson 14:03a0b8fd6ddc 80 return;
andrewboyson 2:82268409e83f 81 }
andrewboyson 14:03a0b8fd6ddc 82 static void handleClientKeyExchange(int length, uint8_t* pBuffer, struct TlsConnection* pConnection) //returns 0 on success; -1 on error
andrewboyson 2:82268409e83f 83 {
andrewboyson 10:e269fd7b9500 84 struct TlsSession* pSession = TlsSessionOrNull(pConnection->sessionId);
andrewboyson 5:ee5489ee1117 85 if (!pSession)
andrewboyson 5:ee5489ee1117 86 {
andrewboyson 10:e269fd7b9500 87 LogTimeF("handleClientKeyExchange - invalid session %u\r\n", pConnection->sessionId);
andrewboyson 14:03a0b8fd6ddc 88 pConnection->toDo = DO_SEND_ALERT_ILLEGAL_PARAMETER;
andrewboyson 14:03a0b8fd6ddc 89 return;
andrewboyson 5:ee5489ee1117 90 }
andrewboyson 2:82268409e83f 91
andrewboyson 2:82268409e83f 92 if (length != 130)
andrewboyson 2:82268409e83f 93 {
andrewboyson 2:82268409e83f 94 LogF("TLS - %d byte client key exchange message is not 130 bytes long\r\n", length);
andrewboyson 14:03a0b8fd6ddc 95 pConnection->toDo = DO_SEND_ALERT_ILLEGAL_PARAMETER;
andrewboyson 14:03a0b8fd6ddc 96 return;
andrewboyson 2:82268409e83f 97 }
andrewboyson 2:82268409e83f 98 int premasterLength = pBuffer[0] << 8 | pBuffer[1]; //Overall length 2 bytes
andrewboyson 2:82268409e83f 99 if (premasterLength != 128)
andrewboyson 2:82268409e83f 100 {
andrewboyson 2:82268409e83f 101 LogF("TLS - %d byte encrypted pre master secret is not 128 bytes long\r\n", length);
andrewboyson 14:03a0b8fd6ddc 102 pConnection->toDo = DO_SEND_ALERT_ILLEGAL_PARAMETER;
andrewboyson 14:03a0b8fd6ddc 103 return;
andrewboyson 2:82268409e83f 104 }
andrewboyson 4:6a1d887f1cad 105 uint8_t* pEncryptedPreMasterSecret = pBuffer + 2;
andrewboyson 14:03a0b8fd6ddc 106 pConnection->slotPriKeyDecryption = PriKeyDecryptStart(pEncryptedPreMasterSecret);
andrewboyson 2:82268409e83f 107
andrewboyson 2:82268409e83f 108 if (TlsTrace)
andrewboyson 2:82268409e83f 109 {
andrewboyson 2:82268409e83f 110 LogF("- encrypted pre master\r\n", premasterLength);
andrewboyson 2:82268409e83f 111 LogBytesAsHex(pEncryptedPreMasterSecret, 128);
andrewboyson 2:82268409e83f 112 Log("\r\n");
andrewboyson 2:82268409e83f 113 }
andrewboyson 2:82268409e83f 114
andrewboyson 14:03a0b8fd6ddc 115 pConnection->toDo = DO_WAIT_DECRYPT_MASTER_SECRET;
andrewboyson 14:03a0b8fd6ddc 116 return;
andrewboyson 2:82268409e83f 117 }
andrewboyson 14:03a0b8fd6ddc 118 static void handleClientFinished(int length, uint8_t* pBuffer, struct TlsConnection* pConnection) //returns 0 on success; -1 on error
andrewboyson 8:5e66a6b4b38c 119 {
andrewboyson 10:e269fd7b9500 120 struct TlsSession* pSession = TlsSessionOrNull(pConnection->sessionId);
andrewboyson 8:5e66a6b4b38c 121 if (!pSession)
andrewboyson 8:5e66a6b4b38c 122 {
andrewboyson 10:e269fd7b9500 123 LogTimeF("handleClientKeyExchange - invalid session %u\r\n", pConnection->sessionId);
andrewboyson 14:03a0b8fd6ddc 124 pConnection->toDo = DO_SEND_ALERT_ILLEGAL_PARAMETER;
andrewboyson 14:03a0b8fd6ddc 125 return;
andrewboyson 8:5e66a6b4b38c 126 }
andrewboyson 8:5e66a6b4b38c 127
andrewboyson 8:5e66a6b4b38c 128 //Calculate the verify message
andrewboyson 17:93feb2a51d58 129 uint8_t verify[TLS_LENGTH_VERIFY];
andrewboyson 8:5e66a6b4b38c 130 TlsPrfClientFinished(pSession->masterSecret, pConnection->clientHandshakeHash, verify);
andrewboyson 21:a6d6e26dd742 131 if (TlsTrace) { Log("- verify handshake\r\n"); LogBytesAsHex(verify, TLS_LENGTH_VERIFY); Log("\r\n"); }
andrewboyson 8:5e66a6b4b38c 132
andrewboyson 14:03a0b8fd6ddc 133 if (pConnection->resume) pConnection->toDo = DO_APPLICATION;
andrewboyson 14:03a0b8fd6ddc 134 else pConnection->toDo = DO_SEND_SERVER_CHANGE;
andrewboyson 14:03a0b8fd6ddc 135
andrewboyson 14:03a0b8fd6ddc 136 return;
andrewboyson 8:5e66a6b4b38c 137 }
andrewboyson 6:819c17738dc2 138 static void changeCipher(int length, uint8_t* pBuffer, struct TlsConnection* pConnection)
andrewboyson 6:819c17738dc2 139 {
andrewboyson 6:819c17738dc2 140 uint8_t message = pBuffer[0];
andrewboyson 21:a6d6e26dd742 141 if (TlsTrace) LogF("- message: %d\r\n", message);
andrewboyson 8:5e66a6b4b38c 142
andrewboyson 8:5e66a6b4b38c 143 //Take snapshot of the handshake hash up to this point
andrewboyson 8:5e66a6b4b38c 144 struct Sha256State handshakeSha;
andrewboyson 8:5e66a6b4b38c 145 Sha256Copy (&handshakeSha, &pConnection->handshakeSha);
andrewboyson 8:5e66a6b4b38c 146 Sha256Finish(&handshakeSha, pConnection->clientHandshakeHash);
andrewboyson 8:5e66a6b4b38c 147
andrewboyson 8:5e66a6b4b38c 148 //Record that all incoming messages are now encrypted
andrewboyson 6:819c17738dc2 149 pConnection->clientEncrypted = true;
andrewboyson 8:5e66a6b4b38c 150 pConnection->clientSequence = 0;
andrewboyson 6:819c17738dc2 151 }
andrewboyson 4:6a1d887f1cad 152 static void handleAlert(int length, uint8_t* pBuffer)
andrewboyson 2:82268409e83f 153 {
andrewboyson 4:6a1d887f1cad 154 uint8_t level = pBuffer[0];
andrewboyson 4:6a1d887f1cad 155 uint8_t description = pBuffer[1];
andrewboyson 2:82268409e83f 156 if (TlsTrace)
andrewboyson 2:82268409e83f 157 {
andrewboyson 2:82268409e83f 158 Log("- alert level: "); TlsLogAlertLevel (level); Log("\r\n");
andrewboyson 2:82268409e83f 159 Log("- alert description: "); TlsLogAlertDescription(description); Log("\r\n");
andrewboyson 2:82268409e83f 160 }
andrewboyson 2:82268409e83f 161 }
andrewboyson 9:f354b4859b0b 162 static void handleApplication(int length, uint8_t* pBuffer, struct TlsConnection* pConnection)
andrewboyson 2:82268409e83f 163 {
andrewboyson 2:82268409e83f 164 if (TlsTrace)
andrewboyson 2:82268409e83f 165 {
andrewboyson 2:82268409e83f 166 Log("- application data:\r\n");
andrewboyson 2:82268409e83f 167 LogBytesAsHex(pBuffer, length);
andrewboyson 2:82268409e83f 168 Log("\r\n");
andrewboyson 9:f354b4859b0b 169 }
andrewboyson 10:e269fd7b9500 170 HttpRequest(pConnection->id, length, (char*)pBuffer, 0);
andrewboyson 2:82268409e83f 171 }
andrewboyson 5:ee5489ee1117 172
andrewboyson 5:ee5489ee1117 173 static void handleHandshake(int length, uint8_t* pBuffer, struct TlsConnection* pConnection)
andrewboyson 2:82268409e83f 174 {
andrewboyson 8:5e66a6b4b38c 175 Sha256Add(&pConnection->handshakeSha, pBuffer, length);
andrewboyson 7:94ef5824c3c0 176
andrewboyson 5:ee5489ee1117 177 uint8_t* p = pBuffer;
andrewboyson 5:ee5489ee1117 178 while (p < pBuffer + length)
andrewboyson 5:ee5489ee1117 179 {
andrewboyson 5:ee5489ee1117 180 uint8_t handshakeType = *p++;
andrewboyson 5:ee5489ee1117 181 int handshakeLength = *p++ << 16;
andrewboyson 5:ee5489ee1117 182 handshakeLength |= *p++ << 8;
andrewboyson 5:ee5489ee1117 183 handshakeLength |= *p++ ; //Handshake length 3 bytes
andrewboyson 5:ee5489ee1117 184
andrewboyson 5:ee5489ee1117 185 if (TlsTrace)
andrewboyson 5:ee5489ee1117 186 {
andrewboyson 5:ee5489ee1117 187 Log ("- handshake type: "); TlsLogHandshakeType(handshakeType); Log("\r\n");
andrewboyson 5:ee5489ee1117 188 LogF("- handshake length: %d\r\n", handshakeLength);
andrewboyson 5:ee5489ee1117 189 }
andrewboyson 5:ee5489ee1117 190
andrewboyson 5:ee5489ee1117 191 switch (handshakeType)
andrewboyson 5:ee5489ee1117 192 {
andrewboyson 13:0a80b49a5e78 193 case TLS_HANDSHAKE_CLIENT_HELLO:
andrewboyson 14:03a0b8fd6ddc 194 handleClientHello(handshakeLength, p, pConnection);
andrewboyson 5:ee5489ee1117 195 break;
andrewboyson 5:ee5489ee1117 196
andrewboyson 13:0a80b49a5e78 197 case TLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
andrewboyson 14:03a0b8fd6ddc 198 handleClientKeyExchange(handshakeLength, p, pConnection);
andrewboyson 5:ee5489ee1117 199 break;
andrewboyson 5:ee5489ee1117 200
andrewboyson 13:0a80b49a5e78 201 case TLS_HANDSHAKE_FINISHED:
andrewboyson 14:03a0b8fd6ddc 202 handleClientFinished(handshakeLength, p, pConnection);
andrewboyson 8:5e66a6b4b38c 203 break;
andrewboyson 8:5e66a6b4b38c 204
andrewboyson 5:ee5489ee1117 205 default:
andrewboyson 5:ee5489ee1117 206 LogF("TLS - ignoring handshake type ");
andrewboyson 5:ee5489ee1117 207 TlsLogHandshakeType(handshakeType);
andrewboyson 5:ee5489ee1117 208 LogF(" and skipping %d bytes\r\n", handshakeLength);
andrewboyson 5:ee5489ee1117 209 break;
andrewboyson 5:ee5489ee1117 210 }
andrewboyson 5:ee5489ee1117 211 p += handshakeLength;
andrewboyson 5:ee5489ee1117 212 }
andrewboyson 5:ee5489ee1117 213 }
andrewboyson 8:5e66a6b4b38c 214 static int handleContent(struct TlsConnection* pConnection, uint8_t* pBuffer, int available)
andrewboyson 8:5e66a6b4b38c 215 {
andrewboyson 5:ee5489ee1117 216 uint8_t contentType = *pBuffer++;
andrewboyson 5:ee5489ee1117 217 uint8_t versionH = *pBuffer++;
andrewboyson 5:ee5489ee1117 218 uint8_t versionL = *pBuffer++;
andrewboyson 5:ee5489ee1117 219 int length = *pBuffer++ << 8;
andrewboyson 5:ee5489ee1117 220 length |= *pBuffer++;
andrewboyson 5:ee5489ee1117 221 int overallLen = length + 5;
andrewboyson 5:ee5489ee1117 222
andrewboyson 2:82268409e83f 223 if (TlsTrace)
andrewboyson 2:82268409e83f 224 {
andrewboyson 2:82268409e83f 225 Log ("- content type: "); TlsLogContentType(contentType); Log("\r\n");
andrewboyson 2:82268409e83f 226 LogF("- legacy HH:LL: %02x:%02x\r\n", versionH, versionL);
andrewboyson 2:82268409e83f 227 LogF("- length : %d\r\n" , length);
andrewboyson 2:82268409e83f 228 }
andrewboyson 8:5e66a6b4b38c 229
andrewboyson 8:5e66a6b4b38c 230 if (contentType < 20 || contentType > 24) return overallLen;
andrewboyson 8:5e66a6b4b38c 231 if (versionH != 3 ) return overallLen;
andrewboyson 8:5e66a6b4b38c 232 if (overallLen > available ) return overallLen;
andrewboyson 13:0a80b49a5e78 233
andrewboyson 8:5e66a6b4b38c 234 if (pConnection->clientEncrypted)
andrewboyson 8:5e66a6b4b38c 235 {
andrewboyson 8:5e66a6b4b38c 236 //Decrypt the message
andrewboyson 18:e3cf22ba2a06 237 TlsAes128CbcSha1Decrypt(&length, &pBuffer, pConnection, contentType);
andrewboyson 8:5e66a6b4b38c 238 }
andrewboyson 8:5e66a6b4b38c 239
andrewboyson 2:82268409e83f 240 switch (contentType)
andrewboyson 2:82268409e83f 241 {
andrewboyson 13:0a80b49a5e78 242 case TLS_CONTENT_TYPE_HANDSHAKE:
andrewboyson 8:5e66a6b4b38c 243 handleHandshake(length, pBuffer, pConnection);
andrewboyson 6:819c17738dc2 244 break;
andrewboyson 6:819c17738dc2 245
andrewboyson 6:819c17738dc2 246 case TLS_CONTENT_TYPE_CHANGE_CIPHER:
andrewboyson 6:819c17738dc2 247 changeCipher(length, pBuffer, pConnection);
andrewboyson 5:ee5489ee1117 248 break;
andrewboyson 5:ee5489ee1117 249
andrewboyson 5:ee5489ee1117 250 case TLS_CONTENT_TYPE_ALERT:
andrewboyson 5:ee5489ee1117 251 handleAlert(length, pBuffer);
andrewboyson 5:ee5489ee1117 252 break;
andrewboyson 5:ee5489ee1117 253
andrewboyson 13:0a80b49a5e78 254 case TLS_CONTENT_TYPE_APPLICATION:
andrewboyson 9:f354b4859b0b 255 handleApplication(length, pBuffer, pConnection);
andrewboyson 5:ee5489ee1117 256 pConnection->toDo = DO_APPLICATION;
andrewboyson 5:ee5489ee1117 257 break;
andrewboyson 5:ee5489ee1117 258
andrewboyson 5:ee5489ee1117 259 default:
andrewboyson 5:ee5489ee1117 260 Log("TLS - ignoring content type ");
andrewboyson 5:ee5489ee1117 261 TlsLogContentType(contentType);
andrewboyson 5:ee5489ee1117 262 LogF(" and skipping %d bytes\r\n", overallLen);
andrewboyson 5:ee5489ee1117 263 pConnection->toDo = DO_WAIT_CLIENT_HELLO;
andrewboyson 5:ee5489ee1117 264 break;
andrewboyson 5:ee5489ee1117 265 }
andrewboyson 5:ee5489ee1117 266 return overallLen;
andrewboyson 5:ee5489ee1117 267 }
andrewboyson 5:ee5489ee1117 268 void TlsRequest(int connectionId, int size, uint8_t* pRequestStream, uint32_t positionInRequestStream)
andrewboyson 6:819c17738dc2 269 {
andrewboyson 5:ee5489ee1117 270 //Log what we are doing
andrewboyson 6:819c17738dc2 271 if (TlsTrace) LogF("TLS %d <<< %d (%u)\r\n", connectionId, size, positionInRequestStream);
andrewboyson 5:ee5489ee1117 272
andrewboyson 5:ee5489ee1117 273 //Get new or existing connection information
andrewboyson 5:ee5489ee1117 274 struct TlsConnection* pConnection;
andrewboyson 5:ee5489ee1117 275 if (!positionInRequestStream)
andrewboyson 5:ee5489ee1117 276 {
andrewboyson 8:5e66a6b4b38c 277 //If this is the start of the request then open a new connection (this starts handshakeSha)
andrewboyson 5:ee5489ee1117 278 pConnection = TlsConnectionNew(connectionId);
andrewboyson 5:ee5489ee1117 279 }
andrewboyson 5:ee5489ee1117 280 else
andrewboyson 5:ee5489ee1117 281 {
andrewboyson 5:ee5489ee1117 282 //If this is in the middle of a request then open an existing connection
andrewboyson 5:ee5489ee1117 283 pConnection = TlsConnectionOrNull(connectionId);
andrewboyson 5:ee5489ee1117 284 if (!pConnection)
andrewboyson 2:82268409e83f 285 {
andrewboyson 5:ee5489ee1117 286 LogTimeF("TlsRequest - no connection corresponds to id %d\r\n", connectionId);
andrewboyson 2:82268409e83f 287 return;
andrewboyson 2:82268409e83f 288 }
andrewboyson 5:ee5489ee1117 289 }
andrewboyson 2:82268409e83f 290
andrewboyson 5:ee5489ee1117 291 //Handle each item of coalesced content
andrewboyson 5:ee5489ee1117 292 uint8_t* pNext = pRequestStream;
andrewboyson 8:5e66a6b4b38c 293 uint8_t* pDeferred = pConnection->deferredContent;
andrewboyson 8:5e66a6b4b38c 294 while (pNext < pRequestStream + size)
andrewboyson 8:5e66a6b4b38c 295 {
andrewboyson 8:5e66a6b4b38c 296 if (pConnection->clientEncrypted && pConnection->toDo == DO_WAIT_DECRYPT_MASTER_SECRET)
andrewboyson 8:5e66a6b4b38c 297 {
andrewboyson 8:5e66a6b4b38c 298 if (pDeferred >= pConnection->deferredContent + TLS_DEFERRED_CONTENT_SIZE) break;
andrewboyson 8:5e66a6b4b38c 299 *pDeferred++ = *pNext++; //Defer handling the remaining content until have master secret
andrewboyson 8:5e66a6b4b38c 300 }
andrewboyson 8:5e66a6b4b38c 301 else
andrewboyson 8:5e66a6b4b38c 302 {
andrewboyson 8:5e66a6b4b38c 303 pNext += handleContent(pConnection, pNext, size + pRequestStream - pNext);
andrewboyson 8:5e66a6b4b38c 304 }
andrewboyson 8:5e66a6b4b38c 305 }
andrewboyson 8:5e66a6b4b38c 306 }
andrewboyson 21:a6d6e26dd742 307 void TlsRequestMain()
andrewboyson 8:5e66a6b4b38c 308 {
andrewboyson 21:a6d6e26dd742 309 struct TlsConnection* pConnection = TlsConnectionGetNext();
andrewboyson 8:5e66a6b4b38c 310
andrewboyson 8:5e66a6b4b38c 311 if (pConnection->toDo != DO_WAIT_DECRYPT_MASTER_SECRET) return;
andrewboyson 8:5e66a6b4b38c 312
andrewboyson 10:e269fd7b9500 313 struct TlsSession* pSession = TlsSessionOrNull(pConnection->sessionId);
andrewboyson 8:5e66a6b4b38c 314 if (!pSession)
andrewboyson 8:5e66a6b4b38c 315 {
andrewboyson 10:e269fd7b9500 316 LogTimeF("TlsRequestAsync - invalid session %u\r\n", pConnection->sessionId);
andrewboyson 8:5e66a6b4b38c 317 return;
andrewboyson 8:5e66a6b4b38c 318 }
andrewboyson 8:5e66a6b4b38c 319
andrewboyson 10:e269fd7b9500 320 if (pSession->valid) return;
andrewboyson 8:5e66a6b4b38c 321
andrewboyson 14:03a0b8fd6ddc 322 if (!PriKeyDecryptFinished(pConnection->slotPriKeyDecryption)) return;
andrewboyson 8:5e66a6b4b38c 323
andrewboyson 17:93feb2a51d58 324 uint8_t preMasterSecret[TLS_LENGTH_PRE_MASTER_SECRET];
andrewboyson 17:93feb2a51d58 325 PriKeyDecryptResultTail(pConnection->slotPriKeyDecryption, TLS_LENGTH_PRE_MASTER_SECRET, preMasterSecret);
andrewboyson 21:a6d6e26dd742 326 if (TlsTrace)
andrewboyson 21:a6d6e26dd742 327 {
andrewboyson 21:a6d6e26dd742 328 LogTime("Pre master secret\r\n");
andrewboyson 21:a6d6e26dd742 329 LogBytesAsHex(preMasterSecret, TLS_LENGTH_PRE_MASTER_SECRET);
andrewboyson 21:a6d6e26dd742 330 Log("\r\n");
andrewboyson 21:a6d6e26dd742 331 }
andrewboyson 14:03a0b8fd6ddc 332 PriKeyDecryptClear(pConnection->slotPriKeyDecryption);
andrewboyson 8:5e66a6b4b38c 333
andrewboyson 8:5e66a6b4b38c 334 TlsPrfMasterSecret(preMasterSecret, pConnection->clientRandom, pConnection->serverRandom, pSession->masterSecret);
andrewboyson 8:5e66a6b4b38c 335
andrewboyson 19:f22327e8be7b 336 TlsPrfKeysAes128Sha1(pSession->masterSecret, pConnection->clientRandom, pConnection->serverRandom, pConnection->clientMacKey,
andrewboyson 19:f22327e8be7b 337 pConnection->serverMacKey,
andrewboyson 19:f22327e8be7b 338 pConnection->clientWriteKey,
andrewboyson 19:f22327e8be7b 339 pConnection->serverWriteKey);
andrewboyson 14:03a0b8fd6ddc 340
andrewboyson 10:e269fd7b9500 341 pSession->valid = true;
andrewboyson 8:5e66a6b4b38c 342
andrewboyson 21:a6d6e26dd742 343 if (TlsTrace)
andrewboyson 21:a6d6e26dd742 344 {
andrewboyson 21:a6d6e26dd742 345 LogTime("Sending deferred encrypted bytes\r\n");
andrewboyson 21:a6d6e26dd742 346 LogBytesAsHex(pConnection->deferredContent, TLS_DEFERRED_CONTENT_SIZE);
andrewboyson 21:a6d6e26dd742 347 Log("\r\n");
andrewboyson 21:a6d6e26dd742 348 }
andrewboyson 8:5e66a6b4b38c 349
andrewboyson 8:5e66a6b4b38c 350 handleContent(pConnection, pConnection->deferredContent, TLS_DEFERRED_CONTENT_SIZE);
andrewboyson 2:82268409e83f 351 }