13
13
14
14
#define DISTANCE_INVALID (0xFF )
15
15
16
+ #ifdef MY_SIGNING_FEATURE
16
17
// Macros for manipulating signing requirement table
17
18
#define DO_SIGN (node ) (node == 0 ? (~doSign[0 ]&1 ) : (~doSign[node>>4 ]&(node%16 )))
18
19
#define SET_SIGN (node ) (node == 0 ? (doSign[0 ]&=~1 ) : (doSign[node>>4 ]&=~(node%16 )))
19
20
#define CLEAR_SIGN (node ) (node == 0 ? (doSign[0 ]|=1 ) : (doSign[node>>4 ]|=(node%16 )))
21
+ #endif
20
22
21
23
// Inline function and macros
22
24
static inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) {
@@ -38,10 +40,16 @@ static inline bool isValidDistance( const uint8_t distance ) {
38
40
}
39
41
40
42
41
- MySensor::MySensor (MyTransport &_radio, MySigning &_signer, MyHw &_hw)
43
+ MySensor::MySensor (MyTransport &_radio, MyHw &_hw
44
+ #ifdef MY_SIGNING_FEATURE
45
+ , MySigning &_signer
46
+ #endif
47
+ )
42
48
:
43
49
radio(_radio),
50
+ #ifdef MY_SIGNING_FEATURE
44
51
signer (_signer),
52
+ #endif
45
53
hw (_hw)
46
54
{
47
55
}
@@ -63,8 +71,10 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
63
71
hw_readConfigBlock ((void *)&nc, (void *)EEPROM_NODE_ID_ADDRESS, sizeof (NodeConfig));
64
72
// Read latest received controller configuration from EEPROM
65
73
hw_readConfigBlock ((void *)&cc, (void *)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof (ControllerConfig));
74
+ #ifdef MY_SIGNING_FEATURE
66
75
// Read out the signing requirements from EEPROM
67
76
hw_readConfigBlock ((void *)doSign, (void *)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS, sizeof (doSign));
77
+ #endif
68
78
69
79
if (isGateway) {
70
80
nc.distance = 0 ;
@@ -128,13 +138,15 @@ void MySensor::setupNode() {
128
138
129
139
// Present node and request config
130
140
if (!isGateway && nc.nodeId != AUTO) {
141
+ #ifdef MY_SIGNING_FEATURE
131
142
// Notify gateway (and possibly controller) about the signing preferences of this node
132
143
sendRoute (build (msg, nc.nodeId , GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false ).set (signer.requestSignatures ()));
133
144
134
145
// If we do require signing, wait for the gateway to tell us how it prefer us to transmit our messages
135
146
if (signer.requestSignatures ()) {
136
147
wait (2000 );
137
148
}
149
+ #endif
138
150
139
151
// Send presentation for this radio node (attach
140
152
present (NODE_SENSOR_ID, repeaterMode? S_ARDUINO_REPEATER_NODE : S_ARDUINO_NODE);
@@ -186,19 +198,47 @@ boolean MySensor::sendRoute(MyMessage &message) {
186
198
187
199
mSetVersion (message, PROTOCOL_VERSION);
188
200
201
+ #ifdef MY_SIGNING_FEATURE
189
202
// If destination is known to require signed messages and we are the sender, sign this message unless it is an ACK or a handshake message
190
203
if (DO_SIGN (message.destination ) && message.sender == nc.nodeId && !mGetAck (message) && mGetLength (msg) &&
191
204
(mGetCommand (message) != C_INTERNAL ||
192
205
(message.type != I_GET_NONCE && message.type != I_GET_NONCE_RESPONSE && message.type != I_REQUEST_SIGNING &&
193
206
message.type != I_ID_REQUEST && message.type != I_ID_RESPONSE &&
194
207
message.type != I_FIND_PARENT && message.type != I_FIND_PARENT_RESPONSE))) {
195
- if (!sign (message)) {
208
+ bool signOk = false ;
209
+ // Send nonce-request
210
+ if (!sendRoute (build (tmpMsg, nc.nodeId , message.destination , message.sensor , C_INTERNAL, I_GET_NONCE, false ).set (" " ))) {
211
+ debug (PSTR (" nonce tr err\n " ));
212
+ return false ;
213
+ }
214
+ // We have to wait for the nonce to arrive before we can sign our original message
215
+ // Other messages could come in-between. We trust process() takes care of them
216
+ unsigned long enter = hw_millis ();
217
+ msgSign = message; // Copy the message to sign since message buffer might be touched in process()
218
+ while (hw_millis () - enter < MY_VERIFICATION_TIMEOUT_MS) {
219
+ if (process ()) {
220
+ if (mGetCommand (getLastMessage ()) == C_INTERNAL && getLastMessage ().type == I_GET_NONCE_RESPONSE) {
221
+ // Proceed with signing if nonce has been received
222
+ if (signer.putNonce (getLastMessage ()) && signer.signMsg (msgSign)) {
223
+ message = msgSign; // Write the signed message back
224
+ signOk = true ;
225
+ }
226
+ break ;
227
+ }
228
+ }
229
+ }
230
+ if (hw_millis () - enter > MY_VERIFICATION_TIMEOUT_MS) {
231
+ debug (PSTR (" nonce tmo\n " ));
232
+ return false ;
233
+ }
234
+ if (!signOk) {
196
235
debug (PSTR (" sign fail\n " ));
197
236
return false ;
198
237
}
199
238
// After this point, only the 'last' member of the message structure is allowed to be altered if the message has been signed,
200
239
// or signature will become invalid and the message rejected by the receiver
201
240
} else mSetSigned (message, 0 ); // Message is not supposed to be signed, make sure it is marked unsigned
241
+ #endif
202
242
203
243
if (dest == GATEWAY_ADDRESS || !repeaterMode) {
204
244
// If destination is the gateway or if we aren't a repeater, let
@@ -313,10 +353,13 @@ boolean MySensor::process() {
313
353
if (!radio.available (&to))
314
354
return false ;
315
355
356
+ #ifdef MY_SIGNING_FEATURE
316
357
(void )signer.checkTimer (); // Manage signing timeout
317
-
358
+ #endif
359
+
318
360
uint8_t len = radio.receive ((uint8_t *)&msg);
319
361
362
+ #ifdef MY_SIGNING_FEATURE
320
363
// Before processing message, reject unsigned messages if signing is required and check signature (if it is signed and addressed to us)
321
364
// Note that we do not care at all about any signature found if we do not require signing, nor do we care about ACKs (they are never signed)
322
365
if (signer.requestSignatures () && msg.destination == nc.nodeId && mGetLength (msg) && !mGetAck (msg) &&
@@ -334,6 +377,7 @@ boolean MySensor::process() {
334
377
return false ; // This signed message has been tampered with!
335
378
}
336
379
}
380
+ #endif
337
381
338
382
// Add string termination, good if we later would want to print it.
339
383
msg.data [mGetLength (msg)] = ' \0 ' ;
@@ -392,6 +436,7 @@ boolean MySensor::process() {
392
436
}
393
437
}
394
438
return false ;
439
+ #ifdef MY_SIGNING_FEATURE
395
440
} else if (type == I_GET_NONCE) {
396
441
if (signer.getNonce (msg)) {
397
442
sendRoute (build (msg, nc.nodeId , msg.sender , NODE_SENSOR_ID, C_INTERNAL, I_GET_NONCE_RESPONSE, false ));
@@ -406,7 +451,7 @@ boolean MySensor::process() {
406
451
CLEAR_SIGN (msg.sender );
407
452
}
408
453
// Save updated table
409
- hw_writeConfigBlock ((void *)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS , (void *)doSign , sizeof (doSign));
454
+ hw_writeConfigBlock ((void *)doSign , (void *)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS , sizeof (doSign));
410
455
411
456
// Inform sender about our preference if we are a gateway, but only require signing if the sender required signing
412
457
// We do not currently want a gateway to require signing from all nodes in a network just because it wants one node
@@ -420,6 +465,7 @@ boolean MySensor::process() {
420
465
return false ; // Signing request is an internal MySensor protocol message, no need to inform caller about this
421
466
} else if (type == I_GET_NONCE_RESPONSE) {
422
467
return true ; // Just pass along nonce silently (no need to call callback for these)
468
+ #endif
423
469
} else if (sender == GATEWAY_ADDRESS) {
424
470
bool isMetric;
425
471
@@ -524,27 +570,3 @@ int8_t MySensor::sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, ui
524
570
return hw.sleep (interrupt1, mode1, interrupt2, mode2, ms) ;
525
571
}
526
572
527
- bool MySensor::sign (MyMessage &message) {
528
- if (!sendRoute (build (tmpMsg, nc.nodeId , message.destination , message.sensor , C_INTERNAL, I_GET_NONCE, false ).set (" " ))) {
529
- return false ;
530
- } else {
531
- // We have to wait for the nonce to arrive before we can sign our original message
532
- // Other messages could come in-between. We trust process() takes care of them
533
- unsigned long enter = hw_millis ();
534
- msgSign = message; // Copy the message to sign since message buffer might be touched in process()
535
- while (hw_millis () - enter < 5000 ) {
536
- if (process ()) {
537
- if (mGetCommand (getLastMessage ()) == C_INTERNAL && getLastMessage ().type == I_GET_NONCE_RESPONSE) {
538
- // Proceed with signing if nonce has been received
539
- if (signer.putNonce (getLastMessage ()) && signer.signMsg (msgSign)) {
540
- message = msgSign; // Write the signed message back
541
- return true ;
542
- }
543
- break ;
544
- }
545
- }
546
- }
547
- }
548
- return false ;
549
- }
550
-
0 commit comments