Andrew Boyson / crypto

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Oct 16 17:14:03 2019 +0000
Revision:
21:a6d6e26dd742
Parent:
19:f22327e8be7b
Child:
22:af0b5ceb556e
Removed debug messages

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 21:a6d6e26dd742 132 if (TlsTrace) { Log("- verify handshake\r\n"); LogBytesAsHex(verify, TLS_LENGTH_VERIFY); Log("\r\n"); }
andrewboyson 8:5e66a6b4b38c 133
andrewboyson 14:03a0b8fd6ddc 134 if (pConnection->resume) pConnection->toDo = DO_APPLICATION;
andrewboyson 14:03a0b8fd6ddc 135 else pConnection->toDo = DO_SEND_SERVER_CHANGE;
andrewboyson 14:03a0b8fd6ddc 136
andrewboyson 14:03a0b8fd6ddc 137 return;
andrewboyson 8:5e66a6b4b38c 138 }
andrewboyson 6:819c17738dc2 139 static void changeCipher(int length, uint8_t* pBuffer, struct TlsConnection* pConnection)
andrewboyson 6:819c17738dc2 140 {
andrewboyson 6:819c17738dc2 141 uint8_t message = pBuffer[0];
andrewboyson 21:a6d6e26dd742 142 if (TlsTrace) LogF("- message: %d\r\n", message);
andrewboyson 8:5e66a6b4b38c 143
andrewboyson 8:5e66a6b4b38c 144 //Take snapshot of the handshake hash up to this point
andrewboyson 8:5e66a6b4b38c 145 struct Sha256State handshakeSha;
andrewboyson 8:5e66a6b4b38c 146 Sha256Copy (&handshakeSha, &pConnection->handshakeSha);
andrewboyson 8:5e66a6b4b38c 147 Sha256Finish(&handshakeSha, pConnection->clientHandshakeHash);
andrewboyson 8:5e66a6b4b38c 148
andrewboyson 8:5e66a6b4b38c 149 //Record that all incoming messages are now encrypted
andrewboyson 6:819c17738dc2 150 pConnection->clientEncrypted = true;
andrewboyson 8:5e66a6b4b38c 151 pConnection->clientSequence = 0;
andrewboyson 6:819c17738dc2 152 }
andrewboyson 4:6a1d887f1cad 153 static void handleAlert(int length, uint8_t* pBuffer)
andrewboyson 2:82268409e83f 154 {
andrewboyson 4:6a1d887f1cad 155 uint8_t level = pBuffer[0];
andrewboyson 4:6a1d887f1cad 156 uint8_t description = pBuffer[1];
andrewboyson 2:82268409e83f 157 if (TlsTrace)
andrewboyson 2:82268409e83f 158 {
andrewboyson 2:82268409e83f 159 Log("- alert level: "); TlsLogAlertLevel (level); Log("\r\n");
andrewboyson 2:82268409e83f 160 Log("- alert description: "); TlsLogAlertDescription(description); Log("\r\n");
andrewboyson 2:82268409e83f 161 }
andrewboyson 2:82268409e83f 162 }
andrewboyson 9:f354b4859b0b 163 static void handleApplication(int length, uint8_t* pBuffer, struct TlsConnection* pConnection)
andrewboyson 2:82268409e83f 164 {
andrewboyson 2:82268409e83f 165 if (TlsTrace)
andrewboyson 2:82268409e83f 166 {
andrewboyson 2:82268409e83f 167 Log("- application data:\r\n");
andrewboyson 2:82268409e83f 168 LogBytesAsHex(pBuffer, length);
andrewboyson 2:82268409e83f 169 Log("\r\n");
andrewboyson 9:f354b4859b0b 170 }
andrewboyson 10:e269fd7b9500 171 HttpRequest(pConnection->id, length, (char*)pBuffer, 0);
andrewboyson 2:82268409e83f 172 }
andrewboyson 5:ee5489ee1117 173
andrewboyson 5:ee5489ee1117 174 static void handleHandshake(int length, uint8_t* pBuffer, struct TlsConnection* pConnection)
andrewboyson 2:82268409e83f 175 {
andrewboyson 8:5e66a6b4b38c 176 Sha256Add(&pConnection->handshakeSha, pBuffer, length);
andrewboyson 7:94ef5824c3c0 177
andrewboyson 5:ee5489ee1117 178 uint8_t* p = pBuffer;
andrewboyson 5:ee5489ee1117 179 while (p < pBuffer + length)
andrewboyson 5:ee5489ee1117 180 {
andrewboyson 5:ee5489ee1117 181 uint8_t handshakeType = *p++;
andrewboyson 5:ee5489ee1117 182 int handshakeLength = *p++ << 16;
andrewboyson 5:ee5489ee1117 183 handshakeLength |= *p++ << 8;
andrewboyson 5:ee5489ee1117 184 handshakeLength |= *p++ ; //Handshake length 3 bytes
andrewboyson 5:ee5489ee1117 185
andrewboyson 5:ee5489ee1117 186 if (TlsTrace)
andrewboyson 5:ee5489ee1117 187 {
andrewboyson 5:ee5489ee1117 188 Log ("- handshake type: "); TlsLogHandshakeType(handshakeType); Log("\r\n");
andrewboyson 5:ee5489ee1117 189 LogF("- handshake length: %d\r\n", handshakeLength);
andrewboyson 5:ee5489ee1117 190 }
andrewboyson 5:ee5489ee1117 191
andrewboyson 5:ee5489ee1117 192 switch (handshakeType)
andrewboyson 5:ee5489ee1117 193 {
andrewboyson 13:0a80b49a5e78 194 case TLS_HANDSHAKE_CLIENT_HELLO:
andrewboyson 14:03a0b8fd6ddc 195 handleClientHello(handshakeLength, p, pConnection);
andrewboyson 5:ee5489ee1117 196 break;
andrewboyson 5:ee5489ee1117 197
andrewboyson 13:0a80b49a5e78 198 case TLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
andrewboyson 14:03a0b8fd6ddc 199 handleClientKeyExchange(handshakeLength, p, pConnection);
andrewboyson 5:ee5489ee1117 200 break;
andrewboyson 5:ee5489ee1117 201
andrewboyson 13:0a80b49a5e78 202 case TLS_HANDSHAKE_FINISHED:
andrewboyson 14:03a0b8fd6ddc 203 handleClientFinished(handshakeLength, p, pConnection);
andrewboyson 8:5e66a6b4b38c 204 break;
andrewboyson 8:5e66a6b4b38c 205
andrewboyson 5:ee5489ee1117 206 default:
andrewboyson 5:ee5489ee1117 207 LogF("TLS - ignoring handshake type ");
andrewboyson 5:ee5489ee1117 208 TlsLogHandshakeType(handshakeType);
andrewboyson 5:ee5489ee1117 209 LogF(" and skipping %d bytes\r\n", handshakeLength);
andrewboyson 5:ee5489ee1117 210 break;
andrewboyson 5:ee5489ee1117 211 }
andrewboyson 5:ee5489ee1117 212 p += handshakeLength;
andrewboyson 5:ee5489ee1117 213 }
andrewboyson 5:ee5489ee1117 214 }
andrewboyson 8:5e66a6b4b38c 215 static int handleContent(struct TlsConnection* pConnection, uint8_t* pBuffer, int available)
andrewboyson 8:5e66a6b4b38c 216 {
andrewboyson 5:ee5489ee1117 217 uint8_t contentType = *pBuffer++;
andrewboyson 5:ee5489ee1117 218 uint8_t versionH = *pBuffer++;
andrewboyson 5:ee5489ee1117 219 uint8_t versionL = *pBuffer++;
andrewboyson 5:ee5489ee1117 220 int length = *pBuffer++ << 8;
andrewboyson 5:ee5489ee1117 221 length |= *pBuffer++;
andrewboyson 5:ee5489ee1117 222 int overallLen = length + 5;
andrewboyson 5:ee5489ee1117 223
andrewboyson 2:82268409e83f 224 if (TlsTrace)
andrewboyson 2:82268409e83f 225 {
andrewboyson 2:82268409e83f 226 Log ("- content type: "); TlsLogContentType(contentType); Log("\r\n");
andrewboyson 2:82268409e83f 227 LogF("- legacy HH:LL: %02x:%02x\r\n", versionH, versionL);
andrewboyson 2:82268409e83f 228 LogF("- length : %d\r\n" , length);
andrewboyson 2:82268409e83f 229 }
andrewboyson 8:5e66a6b4b38c 230
andrewboyson 8:5e66a6b4b38c 231 if (contentType < 20 || contentType > 24) return overallLen;
andrewboyson 8:5e66a6b4b38c 232 if (versionH != 3 ) return overallLen;
andrewboyson 8:5e66a6b4b38c 233 if (overallLen > available ) return overallLen;
andrewboyson 13:0a80b49a5e78 234
andrewboyson 8:5e66a6b4b38c 235 if (pConnection->clientEncrypted)
andrewboyson 8:5e66a6b4b38c 236 {
andrewboyson 8:5e66a6b4b38c 237 //Decrypt the message
andrewboyson 18:e3cf22ba2a06 238 TlsAes128CbcSha1Decrypt(&length, &pBuffer, pConnection, contentType);
andrewboyson 8:5e66a6b4b38c 239 }
andrewboyson 8:5e66a6b4b38c 240
andrewboyson 2:82268409e83f 241 switch (contentType)
andrewboyson 2:82268409e83f 242 {
andrewboyson 13:0a80b49a5e78 243 case TLS_CONTENT_TYPE_HANDSHAKE:
andrewboyson 8:5e66a6b4b38c 244 handleHandshake(length, pBuffer, pConnection);
andrewboyson 6:819c17738dc2 245 break;
andrewboyson 6:819c17738dc2 246
andrewboyson 6:819c17738dc2 247 case TLS_CONTENT_TYPE_CHANGE_CIPHER:
andrewboyson 6:819c17738dc2 248 changeCipher(length, pBuffer, pConnection);
andrewboyson 5:ee5489ee1117 249 break;
andrewboyson 5:ee5489ee1117 250
andrewboyson 5:ee5489ee1117 251 case TLS_CONTENT_TYPE_ALERT:
andrewboyson 5:ee5489ee1117 252 handleAlert(length, pBuffer);
andrewboyson 5:ee5489ee1117 253 break;
andrewboyson 5:ee5489ee1117 254
andrewboyson 13:0a80b49a5e78 255 case TLS_CONTENT_TYPE_APPLICATION:
andrewboyson 9:f354b4859b0b 256 handleApplication(length, pBuffer, pConnection);
andrewboyson 5:ee5489ee1117 257 pConnection->toDo = DO_APPLICATION;
andrewboyson 5:ee5489ee1117 258 break;
andrewboyson 5:ee5489ee1117 259
andrewboyson 5:ee5489ee1117 260 default:
andrewboyson 5:ee5489ee1117 261 Log("TLS - ignoring content type ");
andrewboyson 5:ee5489ee1117 262 TlsLogContentType(contentType);
andrewboyson 5:ee5489ee1117 263 LogF(" and skipping %d bytes\r\n", overallLen);
andrewboyson 5:ee5489ee1117 264 pConnection->toDo = DO_WAIT_CLIENT_HELLO;
andrewboyson 5:ee5489ee1117 265 break;
andrewboyson 5:ee5489ee1117 266 }
andrewboyson 5:ee5489ee1117 267 return overallLen;
andrewboyson 5:ee5489ee1117 268 }
andrewboyson 5:ee5489ee1117 269 void TlsRequest(int connectionId, int size, uint8_t* pRequestStream, uint32_t positionInRequestStream)
andrewboyson 6:819c17738dc2 270 {
andrewboyson 5:ee5489ee1117 271 //Log what we are doing
andrewboyson 6:819c17738dc2 272 if (TlsTrace) LogF("TLS %d <<< %d (%u)\r\n", connectionId, size, positionInRequestStream);
andrewboyson 5:ee5489ee1117 273
andrewboyson 5:ee5489ee1117 274 //Get new or existing connection information
andrewboyson 5:ee5489ee1117 275 struct TlsConnection* pConnection;
andrewboyson 5:ee5489ee1117 276 if (!positionInRequestStream)
andrewboyson 5:ee5489ee1117 277 {
andrewboyson 8:5e66a6b4b38c 278 //If this is the start of the request then open a new connection (this starts handshakeSha)
andrewboyson 5:ee5489ee1117 279 pConnection = TlsConnectionNew(connectionId);
andrewboyson 5:ee5489ee1117 280 }
andrewboyson 5:ee5489ee1117 281 else
andrewboyson 5:ee5489ee1117 282 {
andrewboyson 5:ee5489ee1117 283 //If this is in the middle of a request then open an existing connection
andrewboyson 5:ee5489ee1117 284 pConnection = TlsConnectionOrNull(connectionId);
andrewboyson 5:ee5489ee1117 285 if (!pConnection)
andrewboyson 2:82268409e83f 286 {
andrewboyson 5:ee5489ee1117 287 LogTimeF("TlsRequest - no connection corresponds to id %d\r\n", connectionId);
andrewboyson 2:82268409e83f 288 return;
andrewboyson 2:82268409e83f 289 }
andrewboyson 5:ee5489ee1117 290 }
andrewboyson 2:82268409e83f 291
andrewboyson 5:ee5489ee1117 292 //Handle each item of coalesced content
andrewboyson 5:ee5489ee1117 293 uint8_t* pNext = pRequestStream;
andrewboyson 8:5e66a6b4b38c 294 uint8_t* pDeferred = pConnection->deferredContent;
andrewboyson 8:5e66a6b4b38c 295 while (pNext < pRequestStream + size)
andrewboyson 8:5e66a6b4b38c 296 {
andrewboyson 8:5e66a6b4b38c 297 if (pConnection->clientEncrypted && pConnection->toDo == DO_WAIT_DECRYPT_MASTER_SECRET)
andrewboyson 8:5e66a6b4b38c 298 {
andrewboyson 8:5e66a6b4b38c 299 if (pDeferred >= pConnection->deferredContent + TLS_DEFERRED_CONTENT_SIZE) break;
andrewboyson 8:5e66a6b4b38c 300 *pDeferred++ = *pNext++; //Defer handling the remaining content until have master secret
andrewboyson 8:5e66a6b4b38c 301 }
andrewboyson 8:5e66a6b4b38c 302 else
andrewboyson 8:5e66a6b4b38c 303 {
andrewboyson 8:5e66a6b4b38c 304 pNext += handleContent(pConnection, pNext, size + pRequestStream - pNext);
andrewboyson 8:5e66a6b4b38c 305 }
andrewboyson 8:5e66a6b4b38c 306 }
andrewboyson 8:5e66a6b4b38c 307 }
andrewboyson 21:a6d6e26dd742 308 void TlsRequestMain()
andrewboyson 8:5e66a6b4b38c 309 {
andrewboyson 21:a6d6e26dd742 310 struct TlsConnection* pConnection = TlsConnectionGetNext();
andrewboyson 8:5e66a6b4b38c 311
andrewboyson 8:5e66a6b4b38c 312 if (pConnection->toDo != DO_WAIT_DECRYPT_MASTER_SECRET) return;
andrewboyson 8:5e66a6b4b38c 313
andrewboyson 10:e269fd7b9500 314 struct TlsSession* pSession = TlsSessionOrNull(pConnection->sessionId);
andrewboyson 8:5e66a6b4b38c 315 if (!pSession)
andrewboyson 8:5e66a6b4b38c 316 {
andrewboyson 10:e269fd7b9500 317 LogTimeF("TlsRequestAsync - invalid session %u\r\n", pConnection->sessionId);
andrewboyson 8:5e66a6b4b38c 318 return;
andrewboyson 8:5e66a6b4b38c 319 }
andrewboyson 8:5e66a6b4b38c 320
andrewboyson 10:e269fd7b9500 321 if (pSession->valid) return;
andrewboyson 8:5e66a6b4b38c 322
andrewboyson 14:03a0b8fd6ddc 323 if (!PriKeyDecryptFinished(pConnection->slotPriKeyDecryption)) return;
andrewboyson 8:5e66a6b4b38c 324
andrewboyson 17:93feb2a51d58 325 uint8_t preMasterSecret[TLS_LENGTH_PRE_MASTER_SECRET];
andrewboyson 17:93feb2a51d58 326 PriKeyDecryptResultTail(pConnection->slotPriKeyDecryption, TLS_LENGTH_PRE_MASTER_SECRET, preMasterSecret);
andrewboyson 21:a6d6e26dd742 327 if (TlsTrace)
andrewboyson 21:a6d6e26dd742 328 {
andrewboyson 21:a6d6e26dd742 329 LogTime("Pre master secret\r\n");
andrewboyson 21:a6d6e26dd742 330 LogBytesAsHex(preMasterSecret, TLS_LENGTH_PRE_MASTER_SECRET);
andrewboyson 21:a6d6e26dd742 331 Log("\r\n");
andrewboyson 21:a6d6e26dd742 332 }
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 21:a6d6e26dd742 344 if (TlsTrace)
andrewboyson 21:a6d6e26dd742 345 {
andrewboyson 21:a6d6e26dd742 346 LogTime("Sending deferred encrypted bytes\r\n");
andrewboyson 21:a6d6e26dd742 347 LogBytesAsHex(pConnection->deferredContent, TLS_DEFERRED_CONTENT_SIZE);
andrewboyson 21:a6d6e26dd742 348 Log("\r\n");
andrewboyson 21:a6d6e26dd742 349 }
andrewboyson 8:5e66a6b4b38c 350
andrewboyson 8:5e66a6b4b38c 351 handleContent(pConnection, pConnection->deferredContent, TLS_DEFERRED_CONTENT_SIZE);
andrewboyson 2:82268409e83f 352 }