Skip to content

Commit 0675a89

Browse files
author
Mika Leppänen
committed
Added dynamic setting to enable certificate validation
Added dynamic setting to border router interface to set validation of Wi-SUN specific fields on Wi-SUN certificates.
1 parent ff531d3 commit 0675a89

File tree

7 files changed

+152
-36
lines changed

7 files changed

+152
-36
lines changed

nanostack/ws_bbr_api.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,26 @@ int ws_bbr_node_access_revoke_start(int8_t interface_id);
140140
*/
141141
int ws_bbr_eapol_node_limit_set(int8_t interface_id, uint16_t limit);
142142

143+
/**
144+
* Extended certificate validation
145+
*/
146+
#define BBR_CRT_EXT_VALID_NONE 0x00 /**< Do not make extended validations */
147+
#define BBR_CRT_EXT_VALID_WISUN 0x01 /**< Validate Wi-SUN specific fields */
148+
149+
/**
150+
* Sets extended certificate validation setting
151+
*
152+
* Sets extended certificate validation setting on border router. Function can be used
153+
* to set which fields on client certificate are validated.
154+
*
155+
* \param interface_id Network interface ID
156+
* \param validation Extended Certificate validation setting
157+
* BBR_CRT_EXT_VALID_NONE Do not make extended validations
158+
* BBR_CRT_EXT_VALID_WISUN Validate Wi-SUN specific fields
159+
*
160+
* \return 0 Validation setting was set
161+
* \return <0 Setting set failed
162+
*/
163+
int ws_bbr_ext_certificate_validation_set(int8_t interface_id, uint8_t validation);
164+
143165
#endif /* WS_BBR_API_H_ */

source/6LoWPAN/ws/ws_bbr_api.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,18 @@ int ws_bbr_eapol_node_limit_set(int8_t interface_id, uint16_t limit)
636636
return -1;
637637
#endif
638638
}
639+
640+
int ws_bbr_ext_certificate_validation_set(int8_t interface_id, uint8_t validation)
641+
{
642+
(void) interface_id;
643+
#ifdef HAVE_WS_BORDER_ROUTER
644+
bool enabled = false;
645+
if (validation & BBR_CRT_EXT_VALID_WISUN) {
646+
enabled = true;
647+
}
648+
return ws_pae_controller_ext_certificate_validation_set(interface_id, enabled);
649+
#else
650+
(void) validation;
651+
return -1;
652+
#endif
653+
}

source/6LoWPAN/ws/ws_pae_controller.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ typedef struct {
100100
typedef struct {
101101
uint16_t node_limit; /**< Max number of stored supplicants */
102102
bool node_limit_set : 1; /**< Node limit set */
103+
bool ext_cert_valid_enabled : 1; /**< Extended certificate validation enabled */
103104
} pae_controller_config_t;
104105

105106
static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr);
@@ -126,7 +127,8 @@ static NS_LIST_DEFINE(pae_controller_list, pae_controller_t, link);
126127

127128
pae_controller_config_t pae_controller_config = {
128129
.node_limit = 0,
129-
.node_limit_set = false
130+
.node_limit_set = false,
131+
.ext_cert_valid_enabled = false
130132
};
131133

132134
#if !defined(HAVE_PAE_SUPP) && !defined(HAVE_PAE_AUTH)
@@ -592,6 +594,7 @@ static void ws_pae_controller_data_init(pae_controller_t *controller)
592594
sec_prot_keys_gtks_init(&controller->gtks);
593595
sec_prot_keys_gtks_init(&controller->next_gtks);
594596
sec_prot_certs_init(&controller->certs);
597+
sec_prot_certs_ext_certificate_validation_set(&controller->certs, pae_controller_config.ext_cert_valid_enabled);
595598
ws_pae_timers_settings_init(&controller->timer_settings);
596599
}
597600

@@ -1100,6 +1103,26 @@ int8_t ws_pae_controller_node_limit_set(int8_t interface_id, uint16_t limit)
11001103
#endif
11011104
}
11021105

1106+
int8_t ws_pae_controller_ext_certificate_validation_set(int8_t interface_id, bool enabled)
1107+
{
1108+
#ifdef HAVE_PAE_AUTH
1109+
pae_controller_config.ext_cert_valid_enabled = enabled;
1110+
1111+
pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id);
1112+
if (!controller) {
1113+
return -1;
1114+
}
1115+
1116+
sec_prot_certs_ext_certificate_validation_set(&controller->certs, enabled);
1117+
1118+
return 0;
1119+
#else
1120+
(void) interface_id;
1121+
(void) enabled;
1122+
return -1;
1123+
#endif
1124+
}
1125+
11031126
void ws_pae_controller_forced_gc(bool full_gc)
11041127
{
11051128
/* Purge only when on critical limit since node limit should handle limiting

source/6LoWPAN/ws/ws_pae_controller.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,18 @@ int8_t ws_pae_controller_node_access_revoke_start(int8_t interface_id);
367367
*/
368368
int8_t ws_pae_controller_node_limit_set(int8_t interface_id, uint16_t limit);
369369

370+
/**
371+
* ws_pae_controller_ext_certificate_validation_set enable or disable extended certificate validation
372+
*
373+
* \param interface_ptr interface
374+
* \param enabled true to enable extended validation, false to disable
375+
*
376+
* \return < 0 failure
377+
* \return >= 0 success
378+
*
379+
*/
380+
int8_t ws_pae_controller_ext_certificate_validation_set(int8_t interface_id, bool enabled);
381+
370382
/**
371383
* ws_pae_controller_active_key_update update active key (test interface)
372384
*

source/Security/protocols/sec_prot_certs.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ int8_t sec_prot_certs_init(sec_prot_certs_t *certs)
4141
sec_prot_certs_chain_entry_init(&certs->own_cert_chain);
4242
ns_list_init(&certs->trusted_cert_chain_list);
4343
ns_list_init(&certs->cert_revocat_lists);
44+
certs->ext_cert_valid_enabled = false;
4445

4546
return 0;
4647
}
@@ -56,6 +57,22 @@ void sec_prot_certs_delete(sec_prot_certs_t *certs)
5657
sec_prot_certs_revocat_lists_delete(&certs->cert_revocat_lists);
5758
}
5859

60+
int8_t sec_prot_certs_ext_certificate_validation_set(sec_prot_certs_t *certs, bool enabled)
61+
{
62+
if (!certs) {
63+
return -1;
64+
}
65+
66+
certs->ext_cert_valid_enabled = enabled;
67+
68+
return 0;
69+
}
70+
71+
bool sec_prot_certs_ext_certificate_validation_get(const sec_prot_certs_t *certs)
72+
{
73+
return certs->ext_cert_valid_enabled;
74+
}
75+
5976
cert_chain_entry_t *sec_prot_certs_chain_entry_create(void)
6077
{
6178
cert_chain_entry_t *entry = ns_dyn_mem_alloc(sizeof(cert_chain_entry_t));

source/Security/protocols/sec_prot_certs.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ typedef struct {
5858
cert_chain_entry_t own_cert_chain; /**< Own certificate chain */
5959
cert_chain_list_t trusted_cert_chain_list; /**< Trusted certificate chain lists */
6060
cert_revocat_lists_t cert_revocat_lists; /**< Certificate Revocation Lists */
61+
bool ext_cert_valid_enabled : 1; /**< Extended certificate validation enabled */
6162
} sec_prot_certs_t;
6263

6364
/**
@@ -78,6 +79,28 @@ int8_t sec_prot_certs_init(sec_prot_certs_t *certs);
7879
*/
7980
void sec_prot_certs_delete(sec_prot_certs_t *certs);
8081

82+
/**
83+
* sec_prot_certs_ext_certificate_validation_set enable or disable extended certificate validation
84+
*
85+
* \param certs certificate information
86+
* \param enabled true to enable extended validation, false to disable
87+
*
88+
* \return < 0 failure
89+
* \return >= 0 success
90+
*
91+
*/
92+
int8_t sec_prot_certs_ext_certificate_validation_set(sec_prot_certs_t *certs, bool enabled);
93+
94+
/**
95+
* sec_prot_certs_ext_certificate_validation_get get extended certificate validation setting
96+
*
97+
* \param certs certificate information
98+
*
99+
* \return true/false enabled or not
100+
*
101+
*/
102+
bool sec_prot_certs_ext_certificate_validation_get(const sec_prot_certs_t *certs);
103+
81104
/**
82105
* sec_prot_certs_chain_entry_create allocate memory for certificate chain entry
83106
*

source/Security/protocols/tls_sec_prot/tls_sec_prot_lib.c

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@
5959
#define TLS_HANDSHAKE_TIMEOUT_MAX 201000
6060

6161
//#define TLS_SEC_PROT_LIB_TLS_DEBUG // Enable mbed TLS debug traces
62-
#define TLS_SEC_PROT_LIB_CERT_VALID_SKIP // Skip certificate validation
6362

64-
typedef int tls_sec_prot_lib_crt_verify_cb(mbedtls_x509_crt *crt, uint32_t *flags);
63+
typedef int tls_sec_prot_lib_crt_verify_cb(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags);
6564

6665
struct tls_security_s {
6766
mbedtls_ssl_config conf; /**< mbed TLS SSL configuration */
@@ -75,6 +74,7 @@ struct tls_security_s {
7574
mbedtls_x509_crt owncert; /**< Own certificate(s) */
7675
mbedtls_pk_context pkey; /**< Private key for own certificate */
7776
void *handle; /**< Handle provided in callbacks (defined by library user) */
77+
bool ext_cert_valid : 1; /**< Extended certificate validation enabled */
7878
tls_sec_prot_lib_crt_verify_cb *crt_verify; /**< Verify function for top certificate */
7979
tls_sec_prot_lib_send *send; /**< Send callback */
8080
tls_sec_prot_lib_receive *receive; /**< Receive callback */
@@ -98,10 +98,10 @@ static int tls_sec_prot_lib_x509_crt_verify(void *ctx, mbedtls_x509_crt *crt, in
9898
static int8_t tls_sec_prot_lib_subject_alternative_name_validate(mbedtls_x509_crt *crt);
9999
static int8_t tls_sec_prot_lib_extended_key_usage_validate(mbedtls_x509_crt *crt);
100100
#ifdef HAVE_PAE_AUTH
101-
static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(mbedtls_x509_crt *crt, uint32_t *flags);
101+
static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags);
102102
#endif
103103
#ifdef HAVE_PAE_SUPP
104-
static int tls_sec_prot_lib_x509_crt_server_verify(mbedtls_x509_crt *crt, uint32_t *flags);
104+
static int tls_sec_prot_lib_x509_crt_server_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags);
105105
#endif
106106
#ifdef TLS_SEC_PROT_LIB_TLS_DEBUG
107107
static void tls_sec_prot_lib_debug(void *ctx, int level, const char *file, int line, const char *string);
@@ -115,6 +115,17 @@ static void *tls_sec_prot_lib_mem_calloc(size_t count, size_t size);
115115
static void tls_sec_prot_lib_mem_free(void *ptr);
116116
#endif
117117

118+
#if defined(HAVE_PAE_AUTH) && defined(HAVE_PAE_SUPP)
119+
#define is_server_is_set (is_server == true)
120+
#define is_server_is_not_set (is_server == false)
121+
#elif defined(HAVE_PAE_AUTH)
122+
#define is_server_is_set true
123+
#define is_server_is_not_set false
124+
#elif defined(HAVE_PAE_SUPP)
125+
#define is_server_is_set false
126+
#define is_server_is_not_set true
127+
#endif
128+
118129
int8_t tls_sec_prot_lib_init(tls_security_t *sec)
119130
{
120131
const char *pers = "ws_tls";
@@ -123,7 +134,6 @@ int8_t tls_sec_prot_lib_init(tls_security_t *sec)
123134
mbedtls_platform_set_calloc_free(tls_sec_prot_lib_mem_calloc, tls_sec_prot_lib_mem_free);
124135
#endif
125136

126-
127137
mbedtls_ssl_init(&sec->ssl);
128138
mbedtls_ssl_config_init(&sec->conf);
129139
mbedtls_ctr_drbg_init(&sec->ctr_drbg);
@@ -282,22 +292,18 @@ static int tls_sec_prot_lib_configure_certificates(tls_security_t *sec, const se
282292
// Certificate verify required on both client and server
283293
mbedtls_ssl_conf_authmode(&sec->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
284294

295+
// Get extended certificate validation setting
296+
sec->ext_cert_valid = sec_prot_certs_ext_certificate_validation_get(certs);
297+
285298
return 0;
286299
}
287300

288-
#if defined(HAVE_PAE_AUTH) && defined(HAVE_PAE_SUPP)
289-
#define is_server_is_set (is_server == true)
290-
#define is_server_is_not_set (is_server == false)
291-
#elif defined(HAVE_PAE_AUTH)
292-
#define is_server_is_set true
293-
#define is_server_is_not_set false
294-
#elif defined(HAVE_PAE_SUPP)
295-
#define is_server_is_set false
296-
#define is_server_is_not_set true
297-
#endif
298-
299301
int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_prot_certs_t *certs)
300302
{
303+
#if !defined(HAVE_PAE_SUPP) || !defined(HAVE_PAE_AUTH)
304+
(void) is_server;
305+
#endif
306+
301307
if (!sec) {
302308
return -1;
303309
}
@@ -313,6 +319,7 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
313319
}
314320
#endif
315321

322+
316323
if ((mbedtls_ssl_config_defaults(&sec->conf,
317324
is_server_is_set ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
318325
MBEDTLS_SSL_TRANSPORT_STREAM, 0)) != 0) {
@@ -470,23 +477,20 @@ static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char
470477

471478
static int tls_sec_prot_lib_x509_crt_verify(void *ctx, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags)
472479
{
473-
/* MD/PK forced also by configuration flags and dynamic settings but still verified
474-
here to prevent invalid configurations/certificates */
480+
tls_security_t *sec = (tls_security_t *) ctx;
481+
482+
/* MD/PK forced by configuration flags and dynamic settings but traced also here
483+
to prevent invalid configurations/certificates */
475484
if (crt->sig_md != MBEDTLS_MD_SHA256) {
476485
tr_error("Invalid signature md algorithm");
477-
*flags |= MBEDTLS_X509_BADCRL_BAD_MD;
478-
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
479486
}
480487
if (crt->sig_pk != MBEDTLS_PK_ECDSA) {
481488
tr_error("Invalid signature pk algorithm");
482-
*flags |= MBEDTLS_X509_BADCRL_BAD_PK;
483-
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
484489
}
485490

486491
// Verify top certificate of the chain
487492
if (certificate_depth == 0) {
488-
tls_security_t *sec = (tls_security_t *)ctx;
489-
return sec->crt_verify(crt, flags);
493+
return sec->crt_verify(sec, crt, flags);
490494
}
491495

492496
// No further checks for intermediate and root certificates at the moment
@@ -528,29 +532,30 @@ static int8_t tls_sec_prot_lib_extended_key_usage_validate(mbedtls_x509_crt *crt
528532
{
529533
// Extended key usage must be present
530534
if (mbedtls_x509_crt_check_extended_key_usage(crt, MBEDTLS_OID_WISUN_FAN, sizeof(MBEDTLS_OID_WISUN_FAN) - 1) != 0) {
535+
tr_error("invalid extended key usage");
531536
return -1; // FAIL
532537
}
533538
return 0;
534539
}
535540

536541
#ifdef HAVE_PAE_AUTH
537-
static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(mbedtls_x509_crt *crt, uint32_t *flags)
542+
static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags)
538543
{
539544
// For both IDevID and LDevId both subject alternative name or extended key usage must be valid
540545
if (tls_sec_prot_lib_subject_alternative_name_validate(crt) < 0 ||
541546
tls_sec_prot_lib_extended_key_usage_validate(crt) < 0) {
542547
tr_error("invalid cert");
543-
#ifndef TLS_SEC_PROT_LIB_CERT_VALID_SKIP
544-
*flags |= MBEDTLS_X509_BADCERT_OTHER;
545-
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
546-
#endif
548+
if (sec->ext_cert_valid) {
549+
*flags |= MBEDTLS_X509_BADCERT_OTHER;
550+
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
551+
}
547552
}
548553
return 0;
549554
}
550555
#endif
551556

552557
#ifdef HAVE_PAE_SUPP
553-
static int tls_sec_prot_lib_x509_crt_server_verify(mbedtls_x509_crt *crt, uint32_t *flags)
558+
static int tls_sec_prot_lib_x509_crt_server_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags)
554559
{
555560
int8_t sane_res = tls_sec_prot_lib_subject_alternative_name_validate(crt);
556561
int8_t ext_key_res = tls_sec_prot_lib_extended_key_usage_validate(crt);
@@ -560,10 +565,10 @@ static int tls_sec_prot_lib_x509_crt_server_verify(mbedtls_x509_crt *crt, uint32
560565
// Then both subject alternative name and extended key usage must be valid
561566
if (sane_res < 0 || ext_key_res < 0) {
562567
tr_error("invalid cert");
563-
#ifndef TLS_SEC_PROT_LIB_CERT_VALID_SKIP
564-
*flags |= MBEDTLS_X509_BADCERT_OTHER;
565-
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
566-
#endif
568+
if (sec->ext_cert_valid) {
569+
*flags |= MBEDTLS_X509_BADCERT_OTHER;
570+
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
571+
}
567572
}
568573
}
569574

@@ -656,4 +661,3 @@ uint16_t tls_sec_prot_lib_size(void)
656661
}
657662
#endif /* WS_MBEDTLS_SECURITY_ENABLED */
658663
#endif /* HAVE_WS */
659-

0 commit comments

Comments
 (0)