A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Sep 26 07:19:09 2019 +0000
Revision:
12:2c342345b3db
Parent:
10:e269fd7b9500
Child:
13:0a80b49a5e78
Chinese remainder theorem implemented giving a useful reduction from 20s to 5s to decrypt RSA.

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