A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Sep 11 07:24:21 2019 +0000
Revision:
9:f354b4859b0b
Parent:
8:5e66a6b4b38c
Child:
10:e269fd7b9500
Got application data to be returned but not encrypted yet

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