A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Tue Oct 15 07:26:15 2019 +0000
Revision:
19:f22327e8be7b
Parent:
18:e3cf22ba2a06
Child:
21:a6d6e26dd742
Pulled AES128_CBC_SHA1 into its own routines to keep it apart from future work.

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