Skip to content

Commit 6378a2d

Browse files
committed
#217 in progress encryption support, as yet untested
1 parent 43d51a4 commit 6378a2d

File tree

2 files changed

+159
-78
lines changed

2 files changed

+159
-78
lines changed

src/remote/BaseBufferedRemoteTransport.cpp

Lines changed: 106 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,84 +5,125 @@
55

66
#include "BaseBufferedRemoteTransport.h"
77

8-
using namespace tcremote;
8+
namespace tcremote {
99

10-
BaseBufferedRemoteTransport::BaseBufferedRemoteTransport(BufferingMode bufferMode, uint8_t readBufferSize, uint8_t writeBufferSize)
11-
: TagValueTransport(TVAL_BUFFERED), writeBufferSize(writeBufferSize), writeBufferPos(0),
12-
readBufferSize(readBufferSize), readBufferPos(0), readBufferAvail(0), mode(bufferMode), ticksSinceWrite(0) {
13-
readBuffer = new uint8_t[readBufferSize];
14-
writeBuffer = new uint8_t[writeBufferSize];
15-
}
16-
17-
BaseBufferedRemoteTransport::~BaseBufferedRemoteTransport() {
18-
delete[] readBuffer;
19-
delete[] writeBuffer;
20-
}
10+
BaseBufferedRemoteTransport::BaseBufferedRemoteTransport(BufferingMode bufferMode, uint8_t readBufferSize,
11+
uint8_t writeBufferSize, EncryptionHandler* encHandler)
12+
: TagValueTransport(TVAL_BUFFERED), writeBufferSize(writeBufferSize),
13+
readBufferSize(readBufferSize), writeBufferPos(0), readBufferPos(0), encryptionBufferPos(0), readBufferAvail(0),
14+
encryptionHandler(encHandler), mode(bufferMode),
15+
ticksSinceWrite(0) {
16+
if(mode != BUFFER_ONE_MESSAGE && encHandler != nullptr) {
17+
serlogF(SER_ERROR, "EncHandler requires mode=BUFFER_ONE_MESSAGE");
18+
encHandler = nullptr; // turn off encryption, will not work in any other mode
19+
}
20+
readBuffer = new uint8_t[readBufferSize];
21+
writeBuffer = new uint8_t[writeBufferSize];
22+
encryptionBuffer = new uint8_t[readBufferSize];
23+
}
2124

22-
void BaseBufferedRemoteTransport::endMsg() {
23-
TagValueTransport::endMsg();
24-
if(mode == BUFFER_ONE_MESSAGE) flush();
25-
}
25+
BaseBufferedRemoteTransport::~BaseBufferedRemoteTransport() {
26+
delete[] readBuffer;
27+
delete[] writeBuffer;
28+
}
2629

27-
uint8_t BaseBufferedRemoteTransport::readByte() {
28-
if(!readAvailable()) return -1;
29-
auto ch = readBuffer[readBufferPos];
30-
readBufferPos += 1;
31-
// only uncomment the below for worst case debugging.
32-
//serlogF2(SER_DEBUG, "readByte ", ch);
33-
return ch;
34-
}
30+
void BaseBufferedRemoteTransport::endMsg() {
31+
TagValueTransport::endMsg();
32+
if (mode == BUFFER_ONE_MESSAGE) flushInternal();
33+
}
3534

36-
bool BaseBufferedRemoteTransport::readAvailable() {
37-
if(readBufferAvail && readBufferPos < readBufferAvail) {
38-
return true;
35+
uint8_t BaseBufferedRemoteTransport::readByte() {
36+
if (!readAvailable()) return -1;
37+
auto ch = readBuffer[readBufferPos];
38+
readBufferPos += 1;
39+
// only uncomment the below for worst case debugging.
40+
//serlogF2(SER_DEBUG, "readByte ", ch);
41+
return ch;
3942
}
4043

41-
readBufferAvail = (int8_t)fillReadBuffer(readBuffer, readBufferSize);
42-
readBufferPos = 0;
43-
return readBufferPos < readBufferAvail;
44-
}
44+
bool BaseBufferedRemoteTransport::readAvailable() {
45+
if (readBufferAvail && readBufferPos < readBufferAvail) {
46+
return true;
47+
}
4548

46-
int BaseBufferedRemoteTransport::writeChar(char data) {
47-
if(writeBufferPos >= writeBufferSize) {
48-
// we've exceeded the buffer size so we must flush, and then ensure
49-
// that flush actually did something and there is now capacity.
50-
flush();
51-
if(writeBufferPos >= writeBufferSize) return 0;// we did not write so return an error condition.
49+
if(encryptionHandler != nullptr && encryptionBuffer != nullptr) {
50+
readBufferAvail = readBufferPos = 0;
51+
if(encryptionBufferPos < 2) {
52+
encryptionBufferPos = (uint16_t) fillReadBuffer(encryptionBuffer, readBufferSize);
53+
}
54+
if(encryptionBufferPos >= 2) {
55+
int encryptionSize = (encryptionBuffer[0] << 8) + encryptionBuffer[1];
56+
if(encryptionBufferPos >= encryptionSize) {
57+
int len = encryptionHandler->decryptData(&encryptionBuffer[2], encryptionBufferPos - 2, readBuffer, readBufferSize);
58+
readBufferAvail = len;
59+
readBufferPos = 0;
60+
encryptionBufferPos = 0;
61+
return len > 0;
62+
}
63+
}
64+
} else {
65+
readBufferAvail = (uint16_t) fillReadBuffer(readBuffer, readBufferSize);
66+
readBufferPos = 0;
67+
}
68+
return readBufferPos < readBufferAvail;
5269
}
53-
writeBuffer[writeBufferPos++] = data;
54-
ticksSinceWrite = 0;
55-
return 1;
56-
}
5770

58-
int BaseBufferedRemoteTransport::writeStr(const char *data) {
59-
// only uncomment below for worst case debugging..
60-
// serlogF2(SER_NETWORK_DEBUG, "writing ", data);
71+
int BaseBufferedRemoteTransport::writeChar(char data) {
72+
if (writeBufferPos >= writeBufferSize) {
73+
// we've exceeded the buffer size so we must flush, and then ensure
74+
// that flush actually did something and there is now capacity.
75+
flushInternal();
76+
if (writeBufferPos >= writeBufferSize) return 0;// we did not write so return an error condition.
77+
}
78+
writeBuffer[writeBufferPos++] = data;
79+
ticksSinceWrite = 0;
80+
return 1;
81+
}
82+
83+
int BaseBufferedRemoteTransport::writeStr(const char *data) {
84+
// only uncomment below for worst case debugging..
85+
// serlogF2(SER_NETWORK_DEBUG, "writing ", data);
6186

62-
size_t len = strlen(data);
63-
for(size_t i = 0; i < len; ++i) {
64-
if(writeChar(data[i]) == 0) {
65-
return 0;
87+
size_t len = strlen(data);
88+
for (size_t i = 0; i < len; ++i) {
89+
if (writeChar(data[i]) == 0) {
90+
return 0;
91+
}
6692
}
93+
return (int) len;
6794
}
68-
return (int)len;
69-
}
7095

71-
void BaseBufferedRemoteTransport::flushIfRequired() {
72-
if(!connected() || writeBufferPos == 0 || mode == BUFFER_ONE_MESSAGE) return;
96+
void BaseBufferedRemoteTransport::flushIfRequired() {
97+
if (!connected() || writeBufferPos == 0 || mode == BUFFER_ONE_MESSAGE) return;
7398

74-
if(ticksSinceWrite < TICKS_TO_FLUSH_WRITE) ++ticksSinceWrite;
75-
if(ticksSinceWrite == TICKS_TO_FLUSH_WRITE) {
76-
ticksSinceWrite = 0xff;
77-
flush();
99+
if (ticksSinceWrite < TICKS_TO_FLUSH_WRITE) ++ticksSinceWrite;
100+
if (ticksSinceWrite == TICKS_TO_FLUSH_WRITE) {
101+
ticksSinceWrite = 0xff;
102+
flush();
103+
}
78104
}
79-
}
80105

81-
void BaseBufferedRemoteTransport::close() {
82-
flush();
83-
writeBufferPos = 0;
84-
readBufferPos = 0;
85-
readBufferAvail = 0;
86-
currentField.msgType = UNKNOWN_MSG_TYPE;
87-
currentField.fieldType = FVAL_PROCESSING_AWAITINGMSG;
88-
}
106+
void BaseBufferedRemoteTransport::close() {
107+
writeBufferPos = 0;
108+
readBufferPos = 0;
109+
readBufferAvail = 0;
110+
currentField.msgType = UNKNOWN_MSG_TYPE;
111+
currentField.fieldType = FVAL_PROCESSING_AWAITINGMSG;
112+
}
113+
114+
void BaseBufferedRemoteTransport::flushInternal() {
115+
if(encryptionHandler != nullptr && encryptionBuffer != nullptr) {
116+
int written = encryptionHandler->encryptData(writeBuffer, writeBufferPos, encryptionBuffer, writeBufferSize);
117+
if(written == 0) {
118+
serlogF(SER_ERROR, "Net encrypt fail");
119+
close();
120+
} else {
121+
memcpy(writeBuffer, encryptionBuffer, written);
122+
writeBufferPos = written;
123+
flush();
124+
}
125+
} else {
126+
flush();
127+
}
128+
}
129+
}

src/remote/BaseBufferedRemoteTransport.h

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,36 @@
1616

1717
namespace tcremote {
1818

19-
enum BufferingMode : uint8_t { BUFFER_ONE_MESSAGE, BUFFER_MESSAGES_TILL_FULL };
19+
enum BufferingMode : uint8_t {
20+
BUFFER_ONE_MESSAGE, BUFFER_MESSAGES_TILL_FULL
21+
};
22+
23+
/**
24+
* An implementation of this class can both encrypt and decrypt data on behalf of a BaseBufferedTagValTransport
25+
* instance.
26+
*/
27+
class EncryptionHandler {
28+
public:
29+
/**
30+
* Encrypt plain text data into encrypted format into the buffer
31+
* @param plainText the plain bytes to encrypt
32+
* @param bytesIn the number of bytes to encrypt
33+
* @param buffer the output encrypted message
34+
* @param buffLen the buffer maximum length
35+
* @return the number of bytes encrypted or 0 if it fails.
36+
*/
37+
virtual int encryptData(const uint8_t *plainText, int bytesIn, const uint8_t *buffer, size_t buffLen) = 0;
38+
/**
39+
* Decrypt data from the wire into plain text and store the output into the buffer
40+
* @param encoded the encoded data to decrypt
41+
* @param bytesIn the number of encoded bytes to decrypt
42+
* @param buffer the buffer to output plaintext to
43+
* @param buffLen the size of the buffer
44+
* @return the number of bytes returned, or 0 if it fails.
45+
*/
46+
virtual int decryptData(const uint8_t *encoded, int bytesIn, const uint8_t *buffer, size_t buffLen) = 0;
47+
};
48+
2049

2150
/**
2251
* Many transports need buffering of messages, for example the regular Ethernet2 library will send
@@ -26,31 +55,42 @@ namespace tcremote {
2655
*/
2756
class BaseBufferedRemoteTransport : public TagValueTransport {
2857
protected:
29-
const int writeBufferSize;
30-
uint8_t* readBuffer;
31-
uint8_t* writeBuffer;
32-
uint8_t writeBufferPos;
33-
const uint8_t readBufferSize;
34-
uint8_t readBufferPos;
35-
uint8_t readBufferAvail;
58+
const uint16_t writeBufferSize;
59+
const uint16_t readBufferSize;
60+
uint8_t *readBuffer;
61+
uint8_t *writeBuffer;
62+
uint8_t *encryptionBuffer;
63+
uint16_t writeBufferPos;
64+
uint16_t readBufferPos;
65+
uint16_t encryptionBufferPos;
66+
uint16_t readBufferAvail;
67+
EncryptionHandler* encryptionHandler;
3668
BufferingMode mode;
3769
uint8_t ticksSinceWrite;
3870
public:
39-
BaseBufferedRemoteTransport(BufferingMode bufferMode, uint8_t readBufferSize, uint8_t writeBufferSize);
71+
BaseBufferedRemoteTransport(BufferingMode bufferMode, uint8_t readBufferSize, uint8_t writeBufferSize,
72+
EncryptionHandler* encHandler = nullptr);
73+
4074
~BaseBufferedRemoteTransport() override;
4175

4276
void endMsg() override;
4377

44-
int writeChar(char data) override ;
45-
int writeStr(const char* data) override;
78+
int writeChar(char data) override;
79+
80+
int writeStr(const char *data) override;
81+
4682
uint8_t readByte() override;
83+
4784
bool readAvailable() override;
85+
4886
void close() override;
87+
4988
void flushIfRequired();
5089

51-
virtual int fillReadBuffer(uint8_t* dataBuffer, int maxSize)=0;
52-
};
90+
void flushInternal();
5391

92+
virtual int fillReadBuffer(uint8_t *dataBuffer, int maxSize) = 0;
93+
};
5494
}
5595

5696
#endif //TCMENU_BASEBUFFEREDREMOTETRANSPORT_H

0 commit comments

Comments
 (0)