Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
tls/tls-request.c@2:82268409e83f, 2019-07-31 (annotated)
- Committer:
- andrewboyson
- Date:
- Wed Jul 31 15:12:34 2019 +0000
- Revision:
- 2:82268409e83f
- Child:
- 4:6a1d887f1cad
A lot of tidying. Not working yet.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| andrewboyson | 2:82268409e83f | 1 | #include "tls.h" |
| andrewboyson | 2:82268409e83f | 2 | #include "tls-defs.h" |
| andrewboyson | 2:82268409e83f | 3 | #include "tls-state.h" |
| andrewboyson | 2:82268409e83f | 4 | #include "tls-session.h" |
| andrewboyson | 2:82268409e83f | 5 | #include "tls-log.h" |
| andrewboyson | 2:82268409e83f | 6 | #include "mstimer.h" |
| andrewboyson | 2:82268409e83f | 7 | #include "random.h" |
| andrewboyson | 2:82268409e83f | 8 | #include "log.h" |
| andrewboyson | 2:82268409e83f | 9 | #include "pri-key.h" |
| andrewboyson | 2:82268409e83f | 10 | |
| andrewboyson | 2:82268409e83f | 11 | static int handleClientHello(int length, char* pBuffer, struct TlsState* pState) //returns 0 on success; -1 on error |
| andrewboyson | 2:82268409e83f | 12 | { |
| andrewboyson | 2:82268409e83f | 13 | //Check things look ok |
| andrewboyson | 2:82268409e83f | 14 | char* p = pBuffer; |
| andrewboyson | 2:82268409e83f | 15 | if (length < 100) |
| andrewboyson | 2:82268409e83f | 16 | { |
| andrewboyson | 2:82268409e83f | 17 | LogF("TLS - %d byte client hello message is not at least 100 bytes long\r\n", length); |
| andrewboyson | 2:82268409e83f | 18 | return -1; |
| andrewboyson | 2:82268409e83f | 19 | } |
| andrewboyson | 2:82268409e83f | 20 | |
| andrewboyson | 2:82268409e83f | 21 | //Read in the parameters |
| andrewboyson | 2:82268409e83f | 22 | char versionH = *p++; |
| andrewboyson | 2:82268409e83f | 23 | char versionL = *p++; |
| andrewboyson | 2:82268409e83f | 24 | |
| andrewboyson | 2:82268409e83f | 25 | char* pRandom = p; |
| andrewboyson | 2:82268409e83f | 26 | p += 32; |
| andrewboyson | 2:82268409e83f | 27 | |
| andrewboyson | 2:82268409e83f | 28 | int sessionIdLength = *p++; |
| andrewboyson | 2:82268409e83f | 29 | char* pSessionId = p; |
| andrewboyson | 2:82268409e83f | 30 | |
| andrewboyson | 2:82268409e83f | 31 | //Handle the parameters |
| andrewboyson | 2:82268409e83f | 32 | pState->session = -1; |
| andrewboyson | 2:82268409e83f | 33 | if (sessionIdLength == 1) pState->session = *pSessionId; |
| andrewboyson | 2:82268409e83f | 34 | struct TlsSession* pSession = TlsSessionGetFromIndex(pState->session); |
| andrewboyson | 2:82268409e83f | 35 | if (!pSession || pSession->state != TLS_SESSION_STATE_VALID) |
| andrewboyson | 2:82268409e83f | 36 | { |
| andrewboyson | 2:82268409e83f | 37 | pSession = TlsSessionGetOldest(); |
| andrewboyson | 2:82268409e83f | 38 | pSession->state = TLS_SESSION_STATE_STARTED; |
| andrewboyson | 2:82268409e83f | 39 | } |
| andrewboyson | 2:82268409e83f | 40 | pState->session = TlsSessionGetIndex(pSession); |
| andrewboyson | 2:82268409e83f | 41 | |
| andrewboyson | 2:82268409e83f | 42 | pSession->lastUsed = MsTimerCount; |
| andrewboyson | 2:82268409e83f | 43 | for (int i = 0; i < 32; i++) pSession->clientRandom[i] = *pRandom++; |
| andrewboyson | 2:82268409e83f | 44 | for (int i = 0; i < 32; i++) pSession->serverRandom[i] = RandomGetByte(); |
| andrewboyson | 2:82268409e83f | 45 | |
| andrewboyson | 2:82268409e83f | 46 | //Log the parameters |
| andrewboyson | 2:82268409e83f | 47 | if (TlsTrace) |
| andrewboyson | 2:82268409e83f | 48 | { |
| andrewboyson | 2:82268409e83f | 49 | LogF("- client version HH:LL: %02x:%02x\r\n", versionH, versionL); |
| andrewboyson | 2:82268409e83f | 50 | Log ("- client random:\r\n"); LogBytesAsHex(pRandom, 32); Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 51 | Log ("- client session id:\r\n"); LogBytesAsHex(pSessionId, sessionIdLength); Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 52 | LogF("- session index: %d\r\n", pState->session); |
| andrewboyson | 2:82268409e83f | 53 | } |
| andrewboyson | 2:82268409e83f | 54 | return 0; |
| andrewboyson | 2:82268409e83f | 55 | } |
| andrewboyson | 2:82268409e83f | 56 | static int handleClientKeyExchange(int length, char* pBuffer, struct TlsState* pState) //returns 0 on success; -1 on error |
| andrewboyson | 2:82268409e83f | 57 | { |
| andrewboyson | 2:82268409e83f | 58 | struct TlsSession* pSession = TlsSessionGetFromIndex(pState->session); |
| andrewboyson | 2:82268409e83f | 59 | |
| andrewboyson | 2:82268409e83f | 60 | if (length != 130) |
| andrewboyson | 2:82268409e83f | 61 | { |
| andrewboyson | 2:82268409e83f | 62 | LogF("TLS - %d byte client key exchange message is not 130 bytes long\r\n", length); |
| andrewboyson | 2:82268409e83f | 63 | return -1; |
| andrewboyson | 2:82268409e83f | 64 | } |
| andrewboyson | 2:82268409e83f | 65 | int premasterLength = pBuffer[0] << 8 | pBuffer[1]; //Overall length 2 bytes |
| andrewboyson | 2:82268409e83f | 66 | if (premasterLength != 128) |
| andrewboyson | 2:82268409e83f | 67 | { |
| andrewboyson | 2:82268409e83f | 68 | LogF("TLS - %d byte encrypted pre master secret is not 128 bytes long\r\n", length); |
| andrewboyson | 2:82268409e83f | 69 | return -1; |
| andrewboyson | 2:82268409e83f | 70 | } |
| andrewboyson | 2:82268409e83f | 71 | char* pEncryptedPreMasterSecret = pBuffer + 2; |
| andrewboyson | 2:82268409e83f | 72 | pSession->slotPriKeyDecryption = PriKeyDecryptStart(pEncryptedPreMasterSecret); |
| andrewboyson | 2:82268409e83f | 73 | |
| andrewboyson | 2:82268409e83f | 74 | if (TlsTrace) |
| andrewboyson | 2:82268409e83f | 75 | { |
| andrewboyson | 2:82268409e83f | 76 | LogF("- encrypted pre master\r\n", premasterLength); |
| andrewboyson | 2:82268409e83f | 77 | LogBytesAsHex(pEncryptedPreMasterSecret, 128); |
| andrewboyson | 2:82268409e83f | 78 | Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 79 | } |
| andrewboyson | 2:82268409e83f | 80 | |
| andrewboyson | 2:82268409e83f | 81 | return 0; |
| andrewboyson | 2:82268409e83f | 82 | } |
| andrewboyson | 2:82268409e83f | 83 | static void handleHandshake(int length, char* pBuffer, struct TlsState* pState) |
| andrewboyson | 2:82268409e83f | 84 | { |
| andrewboyson | 2:82268409e83f | 85 | char* p = pBuffer; |
| andrewboyson | 2:82268409e83f | 86 | while (p < pBuffer + length) |
| andrewboyson | 2:82268409e83f | 87 | { |
| andrewboyson | 2:82268409e83f | 88 | char handshakeType = *p++; |
| andrewboyson | 2:82268409e83f | 89 | int handshakeLength = *p++ << 16; |
| andrewboyson | 2:82268409e83f | 90 | handshakeLength |= *p++ << 8; |
| andrewboyson | 2:82268409e83f | 91 | handshakeLength |= *p++ ; //Handshake length 3 bytes |
| andrewboyson | 2:82268409e83f | 92 | |
| andrewboyson | 2:82268409e83f | 93 | if (TlsTrace) |
| andrewboyson | 2:82268409e83f | 94 | { |
| andrewboyson | 2:82268409e83f | 95 | Log ("- handshake type: "); TlsLogHandshakeType(handshakeType); Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 96 | LogF("- handshake length: %d\r\n", handshakeLength); |
| andrewboyson | 2:82268409e83f | 97 | } |
| andrewboyson | 2:82268409e83f | 98 | |
| andrewboyson | 2:82268409e83f | 99 | int r = -1; |
| andrewboyson | 2:82268409e83f | 100 | switch (handshakeType) |
| andrewboyson | 2:82268409e83f | 101 | { |
| andrewboyson | 2:82268409e83f | 102 | case TLS_HANDSHAKE_ClientHello: |
| andrewboyson | 2:82268409e83f | 103 | r = handleClientHello(handshakeLength, p, pState); |
| andrewboyson | 2:82268409e83f | 104 | pState->toDo = r ? DO_SEND_ALERT_ILLEGAL_PARAMETER : DO_SEND_SERVER_HELLO; |
| andrewboyson | 2:82268409e83f | 105 | break; |
| andrewboyson | 2:82268409e83f | 106 | |
| andrewboyson | 2:82268409e83f | 107 | case TLS_HANDSHAKE_ClientKeyExchange: |
| andrewboyson | 2:82268409e83f | 108 | r = handleClientKeyExchange(handshakeLength, p, pState); |
| andrewboyson | 2:82268409e83f | 109 | pState->toDo = r ? DO_SEND_ALERT_ILLEGAL_PARAMETER : DO_WAIT_DECRYPT_MASTER_SECRET; |
| andrewboyson | 2:82268409e83f | 110 | break; |
| andrewboyson | 2:82268409e83f | 111 | |
| andrewboyson | 2:82268409e83f | 112 | default: |
| andrewboyson | 2:82268409e83f | 113 | LogF("TLS - ignoring untreated %d byte handshake type ", handshakeLength); |
| andrewboyson | 2:82268409e83f | 114 | TlsLogHandshakeType(handshakeType); |
| andrewboyson | 2:82268409e83f | 115 | Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 116 | break; |
| andrewboyson | 2:82268409e83f | 117 | } |
| andrewboyson | 2:82268409e83f | 118 | p += handshakeLength; |
| andrewboyson | 2:82268409e83f | 119 | } |
| andrewboyson | 2:82268409e83f | 120 | } |
| andrewboyson | 2:82268409e83f | 121 | static void handleAlert(int length, char* pBuffer) |
| andrewboyson | 2:82268409e83f | 122 | { |
| andrewboyson | 2:82268409e83f | 123 | char level = pBuffer[0]; |
| andrewboyson | 2:82268409e83f | 124 | char description = pBuffer[1]; |
| andrewboyson | 2:82268409e83f | 125 | if (TlsTrace) |
| andrewboyson | 2:82268409e83f | 126 | { |
| andrewboyson | 2:82268409e83f | 127 | Log("- alert level: "); TlsLogAlertLevel (level); Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 128 | Log("- alert description: "); TlsLogAlertDescription(description); Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 129 | } |
| andrewboyson | 2:82268409e83f | 130 | } |
| andrewboyson | 2:82268409e83f | 131 | static void handleApplication(int length, char* pBuffer) |
| andrewboyson | 2:82268409e83f | 132 | { |
| andrewboyson | 2:82268409e83f | 133 | if (TlsTrace) |
| andrewboyson | 2:82268409e83f | 134 | { |
| andrewboyson | 2:82268409e83f | 135 | Log("- application data:\r\n"); |
| andrewboyson | 2:82268409e83f | 136 | LogBytesAsHex(pBuffer, length); |
| andrewboyson | 2:82268409e83f | 137 | Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 138 | } |
| andrewboyson | 2:82268409e83f | 139 | } |
| andrewboyson | 2:82268409e83f | 140 | void TlsRequest(char* pTlsState, char* pWebState, int size, char* pRequestStream, uint32_t positionInRequestStream) |
| andrewboyson | 2:82268409e83f | 141 | { |
| andrewboyson | 2:82268409e83f | 142 | struct TlsState* pState = (struct TlsState*)pTlsState; |
| andrewboyson | 2:82268409e83f | 143 | |
| andrewboyson | 2:82268409e83f | 144 | if (TlsTrace) LogF("TLS <<< %d (%u)\r\n", size, positionInRequestStream); |
| andrewboyson | 2:82268409e83f | 145 | |
| andrewboyson | 2:82268409e83f | 146 | if (size == 0) return; |
| andrewboyson | 2:82268409e83f | 147 | //if (positionInRequestStream != 0) return; |
| andrewboyson | 2:82268409e83f | 148 | char contentType = pRequestStream[0]; |
| andrewboyson | 2:82268409e83f | 149 | char versionH = pRequestStream[1]; |
| andrewboyson | 2:82268409e83f | 150 | char versionL = pRequestStream[2]; |
| andrewboyson | 2:82268409e83f | 151 | int length = pRequestStream[3] << 8 | pRequestStream[4]; //Length (2 bytes) |
| andrewboyson | 2:82268409e83f | 152 | if (TlsTrace) |
| andrewboyson | 2:82268409e83f | 153 | { |
| andrewboyson | 2:82268409e83f | 154 | Log ("- content type: "); TlsLogContentType(contentType); Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 155 | LogF("- legacy HH:LL: %02x:%02x\r\n", versionH, versionL); |
| andrewboyson | 2:82268409e83f | 156 | LogF("- length : %d\r\n" , length); |
| andrewboyson | 2:82268409e83f | 157 | } |
| andrewboyson | 2:82268409e83f | 158 | switch (contentType) |
| andrewboyson | 2:82268409e83f | 159 | { |
| andrewboyson | 2:82268409e83f | 160 | case TLS_CONTENT_TYPE_Handshake: |
| andrewboyson | 2:82268409e83f | 161 | { |
| andrewboyson | 2:82268409e83f | 162 | handleHandshake(length, pRequestStream + 5, pState); |
| andrewboyson | 2:82268409e83f | 163 | return; |
| andrewboyson | 2:82268409e83f | 164 | } |
| andrewboyson | 2:82268409e83f | 165 | case TLS_CONTENT_TYPE_ALERT: |
| andrewboyson | 2:82268409e83f | 166 | { |
| andrewboyson | 2:82268409e83f | 167 | handleAlert(length, pRequestStream + 5); |
| andrewboyson | 2:82268409e83f | 168 | return; |
| andrewboyson | 2:82268409e83f | 169 | } |
| andrewboyson | 2:82268409e83f | 170 | case TLS_CONTENT_TYPE_Application: |
| andrewboyson | 2:82268409e83f | 171 | { |
| andrewboyson | 2:82268409e83f | 172 | handleApplication(length, pRequestStream + 5); |
| andrewboyson | 2:82268409e83f | 173 | pState->toDo = DO_APPLICATION; |
| andrewboyson | 2:82268409e83f | 174 | return; |
| andrewboyson | 2:82268409e83f | 175 | } |
| andrewboyson | 2:82268409e83f | 176 | |
| andrewboyson | 2:82268409e83f | 177 | default: |
| andrewboyson | 2:82268409e83f | 178 | Log("TLS - untreated content type "); TlsLogContentType(contentType); Log("\r\n"); |
| andrewboyson | 2:82268409e83f | 179 | pState->toDo = DO_WAIT_CLIENT_HELLO; |
| andrewboyson | 2:82268409e83f | 180 | return; |
| andrewboyson | 2:82268409e83f | 181 | } |
| andrewboyson | 2:82268409e83f | 182 | } |