Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Jun 27 21:19:08 2019 +0000
Revision:
150:3366e4a0c60e
Parent:
149:39d1ba392f4b
Child:
151:bde6f7da1755
Added function to read PEM encoded private key

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 145:206bf0d073c7 1 #include <stdbool.h>
andrewboyson 145:206bf0d073c7 2
andrewboyson 147:a6093b52e654 3 #include "http.h"
andrewboyson 145:206bf0d073c7 4 #include "tcpbuf.h"
andrewboyson 145:206bf0d073c7 5 #include "action.h"
andrewboyson 147:a6093b52e654 6 #include "net.h"
andrewboyson 147:a6093b52e654 7 #include "log.h"
andrewboyson 147:a6093b52e654 8 #include "led.h"
andrewboyson 145:206bf0d073c7 9 #include "restart.h"
andrewboyson 145:206bf0d073c7 10 #include "mstimer.h"
andrewboyson 149:39d1ba392f4b 11 #include "random.h"
andrewboyson 150:3366e4a0c60e 12 #include "pri-key.h"
andrewboyson 145:206bf0d073c7 13
andrewboyson 145:206bf0d073c7 14 #define TLS_CONTENT_TYPE_ChangeCipher 20
andrewboyson 145:206bf0d073c7 15 #define TLS_CONTENT_TYPE_Alert 21
andrewboyson 145:206bf0d073c7 16 #define TLS_CONTENT_TYPE_Handshake 22
andrewboyson 145:206bf0d073c7 17 #define TLS_CONTENT_TYPE_Application 23
andrewboyson 145:206bf0d073c7 18 #define TLS_CONTENT_TYPE_Heartbeat 24
andrewboyson 145:206bf0d073c7 19
andrewboyson 145:206bf0d073c7 20 #define TLS_HANDSHAKE_HelloRequest 0
andrewboyson 145:206bf0d073c7 21 #define TLS_HANDSHAKE_ClientHello 1
andrewboyson 145:206bf0d073c7 22 #define TLS_HANDSHAKE_ServerHello 2
andrewboyson 145:206bf0d073c7 23 #define TLS_HANDSHAKE_NewSessionTicket 4
andrewboyson 145:206bf0d073c7 24 #define TLS_HANDSHAKE_EncryptedExtensions 8
andrewboyson 145:206bf0d073c7 25 #define TLS_HANDSHAKE_Certificate 11
andrewboyson 145:206bf0d073c7 26 #define TLS_HANDSHAKE_ServerKeyExchange 12
andrewboyson 145:206bf0d073c7 27 #define TLS_HANDSHAKE_CertificateRequest 13
andrewboyson 145:206bf0d073c7 28 #define TLS_HANDSHAKE_ServerHelloDone 14
andrewboyson 145:206bf0d073c7 29 #define TLS_HANDSHAKE_CertificateVerify 15
andrewboyson 145:206bf0d073c7 30 #define TLS_HANDSHAKE_ClientKeyExchange 16
andrewboyson 145:206bf0d073c7 31 #define TLS_HANDSHAKE_Finished 20
andrewboyson 145:206bf0d073c7 32
andrewboyson 148:5489d36986e5 33 #define DO_WAIT_CLIENT_HELLO 0
andrewboyson 148:5489d36986e5 34 #define DO_SEND_SERVER_HELLO 1
andrewboyson 148:5489d36986e5 35 #define DO_WAIT_CLIENT_CHANGE 2
andrewboyson 148:5489d36986e5 36 #define DO_SEND_SERVER_CHANGE 3
andrewboyson 148:5489d36986e5 37 #define DO_APPLICATION 4
andrewboyson 147:a6093b52e654 38
andrewboyson 147:a6093b52e654 39 bool TlsTrace = true;
andrewboyson 145:206bf0d073c7 40
andrewboyson 149:39d1ba392f4b 41 static const char certificate[] = {
andrewboyson 149:39d1ba392f4b 42 #include "certificate.inc"
andrewboyson 149:39d1ba392f4b 43 };
andrewboyson 149:39d1ba392f4b 44
andrewboyson 149:39d1ba392f4b 45 void TlsInit()
andrewboyson 149:39d1ba392f4b 46 {
andrewboyson 150:3366e4a0c60e 47 PriKeyInit();
andrewboyson 149:39d1ba392f4b 48 }
andrewboyson 149:39d1ba392f4b 49
andrewboyson 149:39d1ba392f4b 50
andrewboyson 147:a6093b52e654 51 struct state
andrewboyson 147:a6093b52e654 52 {
andrewboyson 147:a6093b52e654 53 int toDo;
andrewboyson 147:a6093b52e654 54 };
andrewboyson 147:a6093b52e654 55 static void logContentType(char contentType)
andrewboyson 147:a6093b52e654 56 {
andrewboyson 147:a6093b52e654 57 switch (contentType)
andrewboyson 147:a6093b52e654 58 {
andrewboyson 147:a6093b52e654 59 case TLS_CONTENT_TYPE_ChangeCipher: Log ("Change cipher"); break;
andrewboyson 147:a6093b52e654 60 case TLS_CONTENT_TYPE_Alert: Log ("Alert"); break;
andrewboyson 147:a6093b52e654 61 case TLS_CONTENT_TYPE_Handshake: Log ("Handshake"); break;
andrewboyson 147:a6093b52e654 62 case TLS_CONTENT_TYPE_Application: Log ("Application"); break;
andrewboyson 147:a6093b52e654 63 case TLS_CONTENT_TYPE_Heartbeat: Log ("Heartbeat"); break;
andrewboyson 147:a6093b52e654 64 default: LogF("%02hX", contentType); break;
andrewboyson 147:a6093b52e654 65 }
andrewboyson 147:a6093b52e654 66 }
andrewboyson 147:a6093b52e654 67 static void logHandshakeType(char handshakeType)
andrewboyson 145:206bf0d073c7 68 {
andrewboyson 145:206bf0d073c7 69 switch (handshakeType)
andrewboyson 145:206bf0d073c7 70 {
andrewboyson 145:206bf0d073c7 71 case TLS_HANDSHAKE_HelloRequest: Log ("Hello request"); break;
andrewboyson 145:206bf0d073c7 72 case TLS_HANDSHAKE_ClientHello: Log ("Client hello"); break;
andrewboyson 145:206bf0d073c7 73 case TLS_HANDSHAKE_ServerHello: Log ("Server hello"); break;
andrewboyson 145:206bf0d073c7 74 case TLS_HANDSHAKE_NewSessionTicket: Log ("New session ticket"); break;
andrewboyson 145:206bf0d073c7 75 case TLS_HANDSHAKE_EncryptedExtensions: Log ("Encrypted extensions"); break;
andrewboyson 145:206bf0d073c7 76 case TLS_HANDSHAKE_Certificate: Log ("Certificate"); break;
andrewboyson 145:206bf0d073c7 77 case TLS_HANDSHAKE_ServerKeyExchange: Log ("Server key exchange"); break;
andrewboyson 145:206bf0d073c7 78 case TLS_HANDSHAKE_CertificateRequest: Log ("Certificate request"); break;
andrewboyson 145:206bf0d073c7 79 case TLS_HANDSHAKE_ServerHelloDone: Log ("Server hello done"); break;
andrewboyson 145:206bf0d073c7 80 case TLS_HANDSHAKE_CertificateVerify: Log ("Certificate verify"); break;
andrewboyson 145:206bf0d073c7 81 case TLS_HANDSHAKE_ClientKeyExchange: Log ("Client key exchange"); break;
andrewboyson 145:206bf0d073c7 82 case TLS_HANDSHAKE_Finished: Log ("Finished"); break;
andrewboyson 145:206bf0d073c7 83 default: LogF("%02hX", handshakeType); break;
andrewboyson 145:206bf0d073c7 84 }
andrewboyson 145:206bf0d073c7 85 }
andrewboyson 147:a6093b52e654 86 void TlsRequest(char* pTlsState, char* pWebState, int size, char* pRequestStream, uint32_t positionInRequestStream)
andrewboyson 145:206bf0d073c7 87 {
andrewboyson 147:a6093b52e654 88 struct state* pState = (struct state*)pTlsState;
andrewboyson 147:a6093b52e654 89
andrewboyson 147:a6093b52e654 90 if (TlsTrace) LogF("TLS <<< %d (%u)\r\n", size, positionInRequestStream);
andrewboyson 145:206bf0d073c7 91
andrewboyson 145:206bf0d073c7 92 if (size == 0) return;
andrewboyson 145:206bf0d073c7 93 if (positionInRequestStream != 0) return;
andrewboyson 145:206bf0d073c7 94 char contentType = pRequestStream[0];
andrewboyson 149:39d1ba392f4b 95 char versionH = pRequestStream[1];
andrewboyson 149:39d1ba392f4b 96 char versionL = pRequestStream[2];
andrewboyson 149:39d1ba392f4b 97 int length = pRequestStream[3] << 8 | pRequestStream[4]; //Length (2 bytes)
andrewboyson 148:5489d36986e5 98 if (TlsTrace)
andrewboyson 148:5489d36986e5 99 {
andrewboyson 149:39d1ba392f4b 100 Log (" content type: "); logContentType(contentType); Log("\r\n");
andrewboyson 149:39d1ba392f4b 101 LogF(" legacy HH:LL: %02x:%02x\r\n", versionH, versionL);
andrewboyson 149:39d1ba392f4b 102 LogF(" length : %d\r\n" , length);
andrewboyson 148:5489d36986e5 103 }
andrewboyson 145:206bf0d073c7 104 switch (contentType)
andrewboyson 145:206bf0d073c7 105 {
andrewboyson 145:206bf0d073c7 106 case TLS_CONTENT_TYPE_Handshake:
andrewboyson 148:5489d36986e5 107 {
andrewboyson 148:5489d36986e5 108 char handshakeType = pRequestStream[5];
andrewboyson 148:5489d36986e5 109 if (TlsTrace) { Log(" handshake type: "); logHandshakeType(handshakeType); Log("\r\n"); }
andrewboyson 148:5489d36986e5 110 pState->toDo = DO_SEND_SERVER_HELLO;
andrewboyson 148:5489d36986e5 111 return;
andrewboyson 148:5489d36986e5 112 }
andrewboyson 147:a6093b52e654 113 case TLS_CONTENT_TYPE_Application:
andrewboyson 148:5489d36986e5 114 {
andrewboyson 148:5489d36986e5 115 pState->toDo = DO_APPLICATION;
andrewboyson 148:5489d36986e5 116 return;
andrewboyson 148:5489d36986e5 117 }
andrewboyson 148:5489d36986e5 118
andrewboyson 145:206bf0d073c7 119 default:
andrewboyson 147:a6093b52e654 120 Log("TLS - ignoring untreated content type\r\n");
andrewboyson 148:5489d36986e5 121 pState->toDo = DO_WAIT_CLIENT_HELLO;
andrewboyson 145:206bf0d073c7 122 return;
andrewboyson 145:206bf0d073c7 123 }
andrewboyson 145:206bf0d073c7 124 }
andrewboyson 149:39d1ba392f4b 125 char lengthH(int size) { return size >> 8;}
andrewboyson 149:39d1ba392f4b 126 char lengthL(int size) { return size & 0xFF; }
andrewboyson 149:39d1ba392f4b 127 void addSize(int size)
andrewboyson 149:39d1ba392f4b 128 {
andrewboyson 149:39d1ba392f4b 129 TcpBufAddChar(size >> 8 );
andrewboyson 149:39d1ba392f4b 130 TcpBufAddChar(size & 0xFF);
andrewboyson 149:39d1ba392f4b 131 }
andrewboyson 149:39d1ba392f4b 132
andrewboyson 147:a6093b52e654 133 static void sendServerHello()
andrewboyson 145:206bf0d073c7 134 {
andrewboyson 145:206bf0d073c7 135 Log(" sending server hello\r\n");
andrewboyson 149:39d1ba392f4b 136 TcpBufAddChar(TLS_CONTENT_TYPE_Handshake); //Content is handshakes
andrewboyson 149:39d1ba392f4b 137 TcpBufAddChar(0x03); TcpBufAddChar(0x03); //Legacy TLS version
andrewboyson 149:39d1ba392f4b 138 addSize((45 + 4) + (sizeof(certificate) + 6 + 4) + (0 + 4)); //Handshakes Length (2 bytes)
andrewboyson 148:5489d36986e5 139
andrewboyson 149:39d1ba392f4b 140 TcpBufAddChar(TLS_HANDSHAKE_ServerHello); TcpBufAddChar(0x00); //Handshake type server hello
andrewboyson 149:39d1ba392f4b 141 addSize(45); //Size of this handshake
andrewboyson 149:39d1ba392f4b 142 TcpBufAddChar(0x03); TcpBufAddChar(0x03); //TLS version 1.2
andrewboyson 149:39d1ba392f4b 143 for (int i = 0; i < 32; i++) TcpBufAddChar(RandomGetByte()); //32 bit random number
andrewboyson 149:39d1ba392f4b 144 TcpBufAddChar(0x00); //SessionId length 0
andrewboyson 149:39d1ba392f4b 145 TcpBufAddChar(0x00); TcpBufAddChar(0x2f); //Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
andrewboyson 149:39d1ba392f4b 146 TcpBufAddChar(0x00); //Compression method none
andrewboyson 149:39d1ba392f4b 147 TcpBufAddChar(0x00); TcpBufAddChar(0x05); //Extensions length (2 bytes) 5 bytes
andrewboyson 149:39d1ba392f4b 148 TcpBufAddChar(0xff); TcpBufAddChar(0x01); //Extension Renegotiation Info
andrewboyson 149:39d1ba392f4b 149 TcpBufAddChar(0x00); TcpBufAddChar(0x01); //1 bytes of "Renegotiation Info" extension data follows
andrewboyson 149:39d1ba392f4b 150 TcpBufAddChar(0x00); //length is zero, because this is a new connection
andrewboyson 149:39d1ba392f4b 151
andrewboyson 149:39d1ba392f4b 152 TcpBufAddChar(TLS_HANDSHAKE_Certificate); TcpBufAddChar(0x00); //Handshake type certificate
andrewboyson 149:39d1ba392f4b 153 addSize(sizeof(certificate) + 6); TcpBufAddChar(0x00); //Size of this handshake
andrewboyson 149:39d1ba392f4b 154 addSize(sizeof(certificate) + 3); TcpBufAddChar(0x00); //Size of all certificates
andrewboyson 149:39d1ba392f4b 155 addSize(sizeof(certificate) ); //Size of first certificate
andrewboyson 149:39d1ba392f4b 156 for (int i = 0; i < sizeof(certificate); i++) TcpBufAddChar(certificate[i]); //Certificate
andrewboyson 149:39d1ba392f4b 157
andrewboyson 149:39d1ba392f4b 158 TcpBufAddChar(TLS_HANDSHAKE_ServerHelloDone); TcpBufAddChar(0x00); //Handshake type server hello done
andrewboyson 149:39d1ba392f4b 159 addSize(0); //Size of this handshake
andrewboyson 145:206bf0d073c7 160 }
andrewboyson 147:a6093b52e654 161
andrewboyson 147:a6093b52e654 162 int TlsPoll(char* pTlsState, char* pWebState, bool clientFinished)
andrewboyson 145:206bf0d073c7 163 {
andrewboyson 147:a6093b52e654 164 struct state* pState = (struct state*)pTlsState;
andrewboyson 147:a6093b52e654 165
andrewboyson 147:a6093b52e654 166 switch (pState->toDo)
andrewboyson 147:a6093b52e654 167 {
andrewboyson 148:5489d36986e5 168 case DO_WAIT_CLIENT_HELLO:
andrewboyson 147:a6093b52e654 169 if (clientFinished) return -1; //The client hasn't made a request and never will so finish
andrewboyson 147:a6093b52e654 170 else return 0; //The client hasn't made a request yet but it could.
andrewboyson 147:a6093b52e654 171 case DO_APPLICATION: return HttpPollFunction(pWebState, clientFinished); //Return whatever HTTP would be
andrewboyson 147:a6093b52e654 172 default: return 1; //The client has made a request so do it
andrewboyson 147:a6093b52e654 173 }
andrewboyson 147:a6093b52e654 174 }
andrewboyson 147:a6093b52e654 175 bool TlsReply(char* pTlsState, char* pWebState)
andrewboyson 147:a6093b52e654 176 {
andrewboyson 147:a6093b52e654 177 struct state* pState = (struct state*)pTlsState;
andrewboyson 147:a6093b52e654 178
andrewboyson 148:5489d36986e5 179 switch(pState->toDo)
andrewboyson 148:5489d36986e5 180 {
andrewboyson 148:5489d36986e5 181 case DO_SEND_SERVER_HELLO: sendServerHello(); return true;
andrewboyson 148:5489d36986e5 182 default: return true; //Finished
andrewboyson 148:5489d36986e5 183 }
andrewboyson 147:a6093b52e654 184 }
andrewboyson 147:a6093b52e654 185 static char encrypt(char c)
andrewboyson 147:a6093b52e654 186 {
andrewboyson 147:a6093b52e654 187 return c; //Implement encryption
andrewboyson 145:206bf0d073c7 188 }
andrewboyson 145:206bf0d073c7 189 void TlsAddChar(char c)
andrewboyson 145:206bf0d073c7 190 {
andrewboyson 147:a6093b52e654 191 char e = encrypt(c);
andrewboyson 147:a6093b52e654 192 TcpBufAddChar(e);
andrewboyson 145:206bf0d073c7 193 }