Skip to content

Commit 0a59e00

Browse files
committed
Nordic BLE: Update GATT server security management
This patch refines permission applied to characteristic and descriptors; instead of a single level of permission , each characteristic receives a permission for the read operation, one for the write operation and another one for the update operation. As a consequence, updates are not sent if the link does not cover the update permission requirement. Descriptors also benefits individually from read and write permission.
1 parent 4f1e574 commit 0a59e00

File tree

3 files changed

+79
-68
lines changed

3 files changed

+79
-68
lines changed

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/custom/custom_helper.cpp

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,34 @@ typedef struct {
3030
static unsigned uuidTableEntries = 0; /* current usage of the table */
3131
converted_uuid_table_entry_t convertedUUIDTable[UUID_TABLE_MAX_ENTRIES];
3232

33+
namespace {
34+
35+
static void set_perm(ble_gap_conn_sec_mode_t& dest, GattAttribute::Security_t src) {
36+
switch (src.value()) {
37+
case GattAttribute::Security_t::NONE:
38+
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dest);
39+
break;
40+
41+
case GattAttribute::Security_t::UNAUTHENTICATED:
42+
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&dest);
43+
break;
44+
45+
case GattAttribute::Security_t::AUTHENTICATED:
46+
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&dest);
47+
break;
48+
49+
case GattAttribute::Security_t::SC_AUTHENTICATED:
50+
BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(&dest);
51+
break;
52+
53+
default:
54+
break;
55+
}
56+
}
57+
58+
}
59+
60+
3361
void custom_reset_128bits_uuid_table() {
3462
uuidTableEntries = 0;
3563
}
@@ -203,7 +231,9 @@ error_t custom_decode_uuid_base(uint8_t const *const p_uuid_base,
203231
error_t custom_add_in_characteristic(uint16_t service_handle,
204232
ble_uuid_t *p_uuid,
205233
uint8_t properties,
206-
SecurityManager::SecurityMode_t requiredSecurity,
234+
GattAttribute::Security_t read_security,
235+
GattAttribute::Security_t write_security,
236+
GattAttribute::Security_t update_security,
207237
uint8_t *p_data,
208238
uint16_t length,
209239
uint16_t max_length,
@@ -226,8 +256,8 @@ error_t custom_add_in_characteristic(uint16_t service_handle,
226256
/* Notification requires cccd */
227257
memclr_( &cccd_md, sizeof(ble_gatts_attr_md_t));
228258
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
229-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
230-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
259+
set_perm(cccd_md.read_perm, GattAttribute::Security_t::NONE);
260+
set_perm(cccd_md.write_perm, update_security);
231261
}
232262

233263
ble_gatts_char_md_t char_md = {0};
@@ -256,49 +286,8 @@ error_t custom_add_in_characteristic(uint16_t service_handle,
256286
/* Always set variable size */
257287
attr_md.vlen = has_variable_len;
258288

259-
if (char_props.read || char_props.notify || char_props.indicate) {
260-
switch (requiredSecurity) {
261-
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
262-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
263-
break;
264-
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
265-
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
266-
break;
267-
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
268-
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.read_perm);
269-
break;
270-
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
271-
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.read_perm);
272-
break;
273-
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
274-
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.read_perm);
275-
break;
276-
default:
277-
break;
278-
};
279-
}
280-
281-
if (char_props.write || char_props.write_wo_resp) {
282-
switch (requiredSecurity) {
283-
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
284-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
285-
break;
286-
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
287-
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
288-
break;
289-
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
290-
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.write_perm);
291-
break;
292-
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
293-
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.write_perm);
294-
break;
295-
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
296-
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.write_perm);
297-
break;
298-
default:
299-
break;
300-
};
301-
}
289+
set_perm(attr_md.read_perm, read_security);
290+
set_perm(attr_md.write_perm, write_security);
302291

303292
ble_gatts_attr_t attr_char_value = {0};
304293

@@ -342,7 +331,9 @@ error_t custom_add_in_descriptor(uint16_t char_handle,
342331
uint16_t length,
343332
uint16_t max_length,
344333
bool has_variable_len,
345-
uint16_t *p_desc_handle)
334+
uint16_t *p_desc_handle,
335+
GattAttribute::Security_t read_security,
336+
GattAttribute::Security_t write_security)
346337
{
347338
/* Descriptor metadata */
348339
ble_gatts_attr_md_t desc_md = {0};
@@ -352,8 +343,8 @@ error_t custom_add_in_descriptor(uint16_t char_handle,
352343
desc_md.vlen = has_variable_len;
353344

354345
/* Make it readable and writable */
355-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.read_perm);
356-
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.write_perm);
346+
set_perm(desc_md.read_perm, read_security);
347+
set_perm(desc_md.write_perm, write_security);
357348

358349
ble_gatts_attr_t attr_desc = {0};
359350

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/btle/custom/custom_helper.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid);
4545
error_t custom_add_in_characteristic(uint16_t service_handle,
4646
ble_uuid_t *p_uuid,
4747
uint8_t properties,
48-
SecurityManager::SecurityMode_t requiredSecurity,
48+
GattAttribute::Security_t read_security,
49+
GattAttribute::Security_t write_security,
50+
GattAttribute::Security_t update_security,
4951
uint8_t *p_data,
5052
uint16_t length,
5153
uint16_t max_length,
@@ -64,7 +66,9 @@ error_t custom_add_in_descriptor(uint16_t char_handle,
6466
uint16_t length,
6567
uint16_t max_length,
6668
bool has_variable_len,
67-
uint16_t *p_desc_handle);
69+
uint16_t *p_desc_handle,
70+
GattAttribute::Security_t read_security,
71+
GattAttribute::Security_t write_security);
6872

6973
#ifdef __cplusplus
7074
}

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xGattServer.cpp

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "btle/custom/custom_helper.h"
2626

2727
#include "nRF5xn.h"
28+
#include "nrf_ble_gap.h"
2829

2930
namespace {
3031

@@ -164,21 +165,25 @@ ble_error_t nRF5xGattServer::addService(GattService &service)
164165
}
165166

166167
ASSERT_TRUE ( ERROR_NONE ==
167-
custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID,
168-
&nordicUUID,
169-
p_char->getProperties(),
170-
p_char->getRequiredSecurity(),
171-
p_char->getValueAttribute().getValuePtr(),
172-
p_char->getValueAttribute().getLength(),
173-
p_char->getValueAttribute().getMaxLength(),
174-
p_char->getValueAttribute().hasVariableLength(),
175-
userDescriptionDescriptorValuePtr,
176-
userDescriptionDescriptorValueLen,
177-
presentationFormatDescriptorValuePtr,
178-
presentationFormatDescriptorValueLen,
179-
p_char->isReadAuthorizationEnabled(),
180-
p_char->isWriteAuthorizationEnabled(),
181-
&nrfCharacteristicHandles[characteristicCount]),
168+
custom_add_in_characteristic(
169+
BLE_GATT_HANDLE_INVALID,
170+
&nordicUUID,
171+
p_char->getProperties(),
172+
p_char->getReadSecurityRequirement(),
173+
p_char->getWriteSecurityRequirement(),
174+
p_char->getUpdateSecurityRequirement(),
175+
p_char->getValueAttribute().getValuePtr(),
176+
p_char->getValueAttribute().getLength(),
177+
p_char->getValueAttribute().getMaxLength(),
178+
p_char->getValueAttribute().hasVariableLength(),
179+
userDescriptionDescriptorValuePtr,
180+
userDescriptionDescriptorValueLen,
181+
presentationFormatDescriptorValuePtr,
182+
presentationFormatDescriptorValueLen,
183+
p_char->isReadAuthorizationEnabled(),
184+
p_char->isWriteAuthorizationEnabled(),
185+
&nrfCharacteristicHandles[characteristicCount]
186+
),
182187
BLE_ERROR_PARAM_OUT_OF_RANGE );
183188

184189
/* Update the characteristic handle */
@@ -218,7 +223,9 @@ ble_error_t nRF5xGattServer::addService(GattService &service)
218223
p_desc->getLength(),
219224
p_desc->getMaxLength(),
220225
p_desc->hasVariableLength(),
221-
&nrfDescriptorHandles[descriptorCount]),
226+
&nrfDescriptorHandles[descriptorCount],
227+
p_desc->getReadSecurityRequirement(),
228+
p_desc->getWriteSecurityRequirement()),
222229
BLE_ERROR_PARAM_OUT_OF_RANGE);
223230

224231
p_descriptors[descriptorCount] = p_desc;
@@ -345,7 +352,16 @@ ble_error_t nRF5xGattServer::write(Gap::Handle_t connectionHandle, GattAttribute
345352
}
346353
}
347354

348-
if (updatesEnabled) {
355+
bool updates_permitted = false;
356+
ble_gap_conn_sec_t connection_security;
357+
uint32_t err = sd_ble_gap_conn_sec_get(connectionHandle, &connection_security);
358+
if (!err &&
359+
(connection_security.sec_mode.sm == 1) &&
360+
(connection_security.sec_mode.lv >= p_characteristics[characteristicIndex]->getUpdateSecurityRequirement().value())) {
361+
updates_permitted = true;
362+
}
363+
364+
if (updatesEnabled && updates_permitted) {
349365
error_t error = (error_t) sd_ble_gatts_hvx(connectionHandle, &hvx_params);
350366
if (error != ERROR_NONE) {
351367
switch (error) {

0 commit comments

Comments
 (0)