A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Oct 23 08:44:50 2019 +0000
Revision:
22:af0b5ceb556e
Parent:
21:a6d6e26dd742
Removed error if passing a 0 id to TlsSessionGetFromIdOrNull; now it just returns NULL without complaining.

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 }