1 From 3a354d276c3375fd0ef20f5ced8f6c4d8c39c419 Mon Sep 17 00:00:00 2001
2 From: Oleksii Udod <o.udod@samsung.com>
3 Date: Wed, 12 Aug 2015 17:20:21 +0300
4 Subject: [PATCH 1/1] add support of X.509 into tinyDTLS external library
6 Change-Id: I560506e0c0828674969829c9e900ae08bacaeef1
7 Signed-off-by: Oleksii Udod <o.udod@samsung.com>
9 extlibs/tinydtls/SConscript | 5 +-
10 extlibs/tinydtls/configure.in | 6 +
11 extlibs/tinydtls/crypto.c | 2 +-
12 extlibs/tinydtls/crypto.h | 4 +-
13 extlibs/tinydtls/dtls.c | 257 ++++++++++++++++++++-----
14 extlibs/tinydtls/dtls.h | 108 ++++++++++-
15 extlibs/tinydtls/dtls_config.h | 51 +++++
16 extlibs/tinydtls/dtls_config.h.in | 3 +
17 extlibs/tinydtls/global.h | 7 +-
18 extlibs/tinydtls/netq.h | 2 +-
19 extlibs/tinydtls/tests/Makefile.in | 4 +-
20 extlibs/tinydtls/tests/dtls-client.c | 336 ++++++++++++++++++++++++++++++--
21 extlibs/tinydtls/tests/dtls-server.c | 358 +++++++++++++++++++++++++++++++++--
22 extlibs/tinydtls/tinydtls.h | 3 +
23 extlibs/tinydtls/tinydtls.h.in | 3 +
24 15 files changed, 1065 insertions(+), 84 deletions(-)
26 diff --git a/extlibs/tinydtls/SConscript b/extlibs/tinydtls/SConscript
27 index 4c6b4e1..7ca5ae2 100644
28 --- a/extlibs/tinydtls/SConscript
29 +++ b/extlibs/tinydtls/SConscript
30 @@ -31,7 +31,6 @@ if(target_os) == 'arduino':
31 env.Replace(CFLAGS = env.get('CXXFLAGS'))
35 tinydtls_src_path = root_dir
37 env.AppendUnique(CPPPATH = [root_dir])
38 @@ -62,7 +61,7 @@ tinydtls_src = [
39 env.AppendUnique(TINYDTLS_SRC = tinydtls_src)
41 if not env.get('RELEASE'):
42 - if(target_os) not in ['arduino']:
43 + if(target_os) not in ['android', 'arduino']:
44 env.AppendUnique(TINYDTLS_SRC = ['debug.c'])
46 env.AppendUnique(CPPDEFINES = ['NDEBUG'])
47 @@ -71,6 +70,7 @@ else:
49 env.AppendUnique(CPPDEFINES = ['DTLSV12', 'WITH_SHA256', 'DTLS_CHECK_CONTENTTYPE'])
52 libtinydtls = env.StaticLibrary('libtinydtls', env.get('TINYDTLS_SRC'), OBJPREFIX='libtinydtls_')
54 ######################################################################
55 @@ -94,6 +94,7 @@ if not env.get('RELEASE'):
56 samples_env.PrependUnique(LIBS = ['tinydtls'])
58 Alias("samples", [dtlsserver, dtlsclient])
60 samples_env.AppendTarget('samples')
62 env.InstallTarget(libtinydtls, 'libtinydtls');
63 diff --git a/extlibs/tinydtls/configure.in b/extlibs/tinydtls/configure.in
64 index 70b9a54..c3ebbf3 100644
65 --- a/extlibs/tinydtls/configure.in
66 +++ b/extlibs/tinydtls/configure.in
67 @@ -69,6 +69,12 @@ AC_ARG_WITH(psk,
68 [AC_DEFINE(DTLS_PSK, 1, [Define to 1 if building with PSK support])
72 + [AS_HELP_STRING([--with-x509],[use dtls as transport protocol])],
73 + [AC_DEFINE(DTLS_X509, 1, [Define to 1 if building with X.509 support])
77 CPPFLAGS="${CPPFLAGS} -DDTLSv12 -DWITH_SHA256"
78 OPT_OBJS="${OPT_OBJS} sha2/sha2.o"
80 diff --git a/extlibs/tinydtls/crypto.c b/extlibs/tinydtls/crypto.c
81 index deaf581..7433432 100644
82 --- a/extlibs/tinydtls/crypto.c
83 +++ b/extlibs/tinydtls/crypto.c
84 @@ -493,7 +493,7 @@ dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
89 +#if defined(DTLS_ECC) || defined(DTLS_X509)
91 int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
93 diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h
94 index f4cfc66..cade1b2 100644
95 --- a/extlibs/tinydtls/crypto.h
96 +++ b/extlibs/tinydtls/crypto.h
97 @@ -131,14 +131,14 @@ typedef struct {
98 dtls_cipher_t cipher; /**< cipher type */
99 unsigned int do_client_auth:1;
101 -#ifdef DTLS_ECC && DTLS_PSK
102 +#if defined(DTLS_ECC) && defined(DTLS_PSK)
104 dtls_handshake_parameters_ecc_t ecc;
105 dtls_handshake_parameters_psk_t psk;
107 #else /* DTLS_ECC && DTLS_PSK */
110 +#if defined(DTLS_ECC) || defined(DTLS_X509)
111 dtls_handshake_parameters_ecc_t ecc;
112 #endif /* DTLS_ECC */
114 diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c
115 index 6104a08..f1e2486 100644
116 --- a/extlibs/tinydtls/dtls.c
117 +++ b/extlibs/tinydtls/dtls.c
118 @@ -479,7 +479,7 @@ static uint8 compression_methods[] = {
119 /** returns true if the cipher matches TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */
120 static inline int is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(dtls_cipher_t cipher)
123 +#if defined(DTLS_ECC) || defined(DTLS_X509)
124 return cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
127 @@ -532,13 +532,24 @@ static inline int is_psk_supported(dtls_context_t *ctx)
128 static inline int is_ecdsa_supported(dtls_context_t *ctx, int is_client)
131 - return ctx && ctx->h && ((!is_client && ctx->h->get_ecdsa_key) ||
132 + return ctx && ctx->h && ((!is_client && ctx->h->get_ecdsa_key) ||
133 (is_client && ctx->h->verify_ecdsa_key));
136 #endif /* DTLS_ECC */
139 +/** returns true if the application is configured for x509 */
140 +static inline int is_x509_supported(dtls_context_t *ctx, int is_client)
143 + return ctx && ctx->h && ((!is_client && ctx->h->get_x509_cert) ||
144 + (is_client && ctx->h->verify_x509_cert));
147 +#endif /* DTLS_X509 */
150 /** Returns true if the application is configured for ecdhe_ecdsa with
151 * client authentication */
152 static inline int is_ecdsa_client_auth_supported(dtls_context_t *ctx)
153 @@ -550,6 +561,17 @@ static inline int is_ecdsa_client_auth_supported(dtls_context_t *ctx)
154 #endif /* DTLS_ECC */
157 +/** Returns true if the application is configured for x509 with
158 + * client authentication */
159 +static inline int is_x509_client_auth_supported(dtls_context_t *ctx)
162 + return ctx && ctx->h && ctx->h->get_x509_cert && ctx->h->verify_x509_cert;
165 +#endif /* DTLS_X509 */
168 /** returns true if ecdh_anon_with_aes_128_cbc_sha is supported */
169 static inline int is_ecdh_anon_supported(dtls_context_t *ctx)
171 @@ -586,16 +608,19 @@ known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) {
177 psk = is_psk_supported(ctx);
178 ecdsa = is_ecdsa_supported(ctx, is_client);
179 ecdh_anon = is_ecdh_anon_supported(ctx);
180 ecdhe_psk = is_ecdhe_psk_supported(ctx);
181 + x509 = is_x509_supported(ctx, is_client);
183 return (psk && is_tls_psk_with_aes_128_ccm_8(code)) ||
184 (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)) ||
185 (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code)) ||
186 - (ecdhe_psk && is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(code));
187 + (ecdhe_psk && is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(code)) ||
188 + (x509 && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code));
192 @@ -744,7 +769,7 @@ calculate_key_block(dtls_context_t *ctx,
195 #endif /* DTLS_PSK */
197 +#if defined(DTLS_ECC) || defined(DTLS_X509)
198 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
199 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
200 pre_master_len = dtls_ecdh_pre_master_secret(handshake->keyx.ecc.own_eph_priv,
201 @@ -870,8 +895,13 @@ static int verify_ext_cert_type(uint8 *data, size_t data_length) {
202 cert_type = dtls_uint8_to_int(data);
203 data += sizeof(uint8);
206 if (cert_type == TLS_CERT_TYPE_RAW_PUBLIC_KEY)
210 + if (cert_type == TLS_CERT_TYPE_X509)
215 dtls_warn("no supported certificate type found\n");
216 @@ -962,7 +992,12 @@ dtls_check_tls_extension(dtls_peer_t *peer,
217 if (verify_ext_cert_type(data, j))
221 if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
223 + if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
224 + (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
229 @@ -972,7 +1007,12 @@ dtls_check_tls_extension(dtls_peer_t *peer,
230 if (verify_ext_cert_type(data, j))
234 if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
236 + if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
237 + (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
242 @@ -1138,7 +1178,7 @@ check_client_keyexchange(dtls_context_t *ctx,
243 dtls_handshake_parameters_t *handshake,
244 uint8 *data, size_t length) {
247 +#if defined(DTLS_ECC) || defined(DTLS_X509)
248 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) ||
249 is_tls_ecdh_anon_with_aes_128_cbc_sha_256(handshake->cipher) ) {
251 @@ -1529,7 +1569,6 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
252 memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(sendbuf)->content_type, 3); /* type and version */
253 dtls_int_to_uint16(A_DATA + 11, res - 8); /* length */
256 res = dtls_encrypt(start + 8, res - 8, start + 8, nonce,
257 dtls_kb_local_write_key(security, peer->role),
258 dtls_kb_key_size(security, peer->role),
259 @@ -1841,7 +1880,7 @@ dtls_verify_peer(dtls_context_t *ctx,
264 +#if defined(DTLS_ECC) || defined(DTLS_X509)
266 dtls_check_ecdsa_signature_elem(uint8 *data, size_t data_length,
267 unsigned char **result_r,
268 @@ -2025,8 +2064,13 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
269 /* length of this extension type */
270 dtls_int_to_uint16(p, 1);
273 + if (CALL(ctx, is_x509_active) == 0)
274 + dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
276 +#endif /* DTLS_X509 */
277 + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
279 - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
282 /* client certificate type extension */
283 @@ -2037,7 +2081,13 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
284 dtls_int_to_uint16(p, 1);
287 - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
289 + if (CALL(ctx, is_x509_active) == 0)
290 + dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
292 +#endif /* DTLS_X509 */
293 + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
297 /* ec_point_formats */
298 @@ -2072,7 +2122,7 @@ dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer,
299 uint8 buf[DTLS_CE_LENGTH];
305 * Start message construction at beginning of buffer. */
307 @@ -2097,7 +2147,46 @@ dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer,
308 return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE,
311 +#endif /* DTLS_ECC */
315 +dtls_send_certificate_x509(dtls_context_t *ctx, dtls_peer_t *peer)
317 + uint8 buf[DTLS_MAX_CERT_SIZE];
320 + unsigned char *cert;
323 + dtls_info("\n dtls_send_certificate_ecdsa\n");
324 + ret = CALL(ctx, get_x509_cert, &peer->session,
325 + (const unsigned char **)&cert, &cert_size);
328 + dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
334 + * Start message construction at beginning of buffer. */
337 + dtls_int_to_uint24(p, cert_size); /* certificates length */
338 + p += sizeof(uint24);
340 + memcpy(p, cert, cert_size);
343 + assert(p - buf <= sizeof(buf));
345 + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE,
348 +#endif /* DTLS_X509 */
350 +#if defined(DTLS_X509) || defined(DTLS_ECC)
352 dtls_add_ecdsa_signature_elem(uint8 *p, uint32_t *point_r, uint32_t *point_s)
354 @@ -2204,7 +2293,6 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
355 dtls_ecdsa_generate_key(config->keyx.ecc.own_eph_priv,
356 ephemeral_pub_x, ephemeral_pub_y,
360 /* sign the ephemeral and its paramaters */
361 dtls_ecdsa_create_sig(key->priv_key, DTLS_EC_KEY_SIZE,
362 @@ -2221,7 +2309,7 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
363 return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE,
366 -#endif /* DTLS_ECC */
367 +#endif /* defined(DTLS_X509) || defined(DTLS_ECC) */
369 #if defined(DTLS_PSK) && defined(DTLS_ECC)
370 static int dtls_send_server_key_exchange_ecdhe_psk(dtls_context_t *ctx, dtls_peer_t *peer,
371 @@ -2327,7 +2415,7 @@ dtls_send_server_key_exchange_psk(dtls_context_t *ctx, dtls_peer_t *peer,
373 #endif /* DTLS_PSK */
376 +#if defined(DTLS_ECC) || defined(DTLS_X509)
378 dtls_send_server_certificate_request(dtls_context_t *ctx, dtls_peer_t *peer)
380 @@ -2401,7 +2489,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
381 ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
382 ecdhe_psk = is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
385 +#if defined(DTLS_ECC) || defined(DTLS_X509)
387 res = dtls_send_server_key_exchange_ecdh(ctx, peer, NULL);
389 @@ -2413,13 +2501,24 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
391 const dtls_ecc_key_t *ecdsa_key;
393 - res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
395 + if (CALL(ctx, is_x509_active) == 0)
396 + res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
398 +#endif /* DTLS_X509 */
399 + res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
402 - dtls_crit("no ecdsa certificate to send in certificate\n");
403 + dtls_debug("no ecdsa key to send\n");
407 - res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
409 + if (CALL(ctx, is_x509_active) == 0)
410 + res = dtls_send_certificate_x509(ctx, peer);
412 +#endif /* DTLS_X509 */
413 + res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
416 dtls_debug("dtls_server_hello: cannot prepare Certificate record\n");
417 @@ -2434,9 +2533,8 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
420 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) &&
421 - is_ecdsa_client_auth_supported(ctx)) {
422 + (is_ecdsa_client_auth_supported(ctx) || (is_x509_client_auth_supported(ctx)))) {
423 res = dtls_send_server_certificate_request(ctx, peer);
426 dtls_debug("dtls_server_hello(with ECDSA): cannot prepare certificate Request record\n");
428 @@ -2554,7 +2652,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
431 #endif /* DTLS_PSK */
433 +#if defined(DTLS_ECC) || defined(DTLS_X509)
434 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
435 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
436 uint8 *ephemeral_pub_x;
437 @@ -2644,7 +2742,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
442 +#if defined(DTLS_ECC) || defined(DTLS_X509)
444 dtls_send_certificate_verify_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
445 const dtls_ecc_key_t *key)
446 @@ -2723,6 +2821,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
451 dtls_handshake_parameters_t *handshake = peer->handshake_params;
454 @@ -2733,6 +2832,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
456 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
457 ecdsa = is_ecdsa_supported(ctx, 1);
458 + x509 = is_x509_supported(ctx, 1);
460 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
461 ecdh_anon = is_ecdh_anon_supported(ctx);
462 @@ -2745,11 +2845,12 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
463 ecdsa = is_ecdsa_supported(ctx, 1);
464 ecdh_anon = is_ecdh_anon_supported(ctx);
465 ecdhe_psk = is_ecdhe_psk_supported(ctx);
466 + x509 = is_x509_supported(ctx, 1);
470 - cipher_size = 2 + (ecdsa ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
471 - extension_size = (ecdsa) ? (2 + 6 + 6 + 8 + 6) : 0;
472 + cipher_size = 2 + ((ecdsa || x509) ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
473 + extension_size = (ecdsa || x509) ? (2 + 6 + 6 + 8 + 6) : 0;
475 if (cipher_size == 0) {
476 dtls_crit("no cipher callbacks implemented\n");
477 @@ -2799,7 +2900,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
478 dtls_int_to_uint16(p, TLS_PSK_WITH_AES_128_CCM_8);
482 + if (ecdsa || x509) {
483 dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
486 @@ -2821,7 +2922,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
491 + if (ecdsa || x509) {
492 /* client certificate type extension */
493 dtls_int_to_uint16(p, TLS_EXT_CLIENT_CERTIFICATE_TYPE);
495 @@ -2834,7 +2935,13 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
496 dtls_int_to_uint8(p, 1);
499 - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
501 + if (CALL(ctx, is_x509_active) == 0)
502 + dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
504 +#endif /* DTLS_X509 */
505 + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
509 /* client certificate type extension */
510 @@ -2849,7 +2956,13 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
511 dtls_int_to_uint8(p, 1);
514 - dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
516 + if (CALL(ctx, is_x509_active) == 0)
517 + dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
519 +#endif /* DTLS_X509 */
520 + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
524 /* elliptic_curves */
525 @@ -2985,8 +3098,9 @@ check_server_hello_verify_request(dtls_context_t *ctx,
531 -check_server_certificate(dtls_context_t *ctx,
532 +check_peer_certificate(dtls_context_t *ctx,
534 uint8 *data, size_t data_length)
536 @@ -3036,7 +3150,41 @@ check_server_certificate(dtls_context_t *ctx,
540 +#endif /* DTLS_ECC */
544 +check_peer_certificate_x509(dtls_context_t *ctx,
546 + uint8 *data, size_t data_length)
549 + dtls_handshake_parameters_t *config = peer->handshake_params;
552 + dtls_info("\n check_peer_certificate_x509\n");
553 + update_hs_hash(peer, data, data_length);
555 + assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher));
557 + data += DTLS_HS_LENGTH;
559 + cert_length = dtls_uint24_to_int(data);
560 + data += sizeof(uint24);
562 + ret = CALL(ctx, verify_x509_cert, &peer->session, data, cert_length,
563 + config->keyx.ecc.other_pub_x, sizeof(config->keyx.ecc.other_pub_x),
564 + config->keyx.ecc.other_pub_y, sizeof(config->keyx.ecc.other_pub_y));
566 + dtls_warn("The certificate was not accepted\n");
572 +#endif /* DTLS_X509 */
574 +#if defined(DTLS_X509) || defined(DTLS_ECC)
576 check_server_key_exchange_ecdsa(dtls_context_t *ctx,
578 @@ -3385,13 +3533,17 @@ check_certificate_request(dtls_context_t *ctx,
582 -check_server_hellodone(dtls_context_t *ctx,
583 +check_server_hellodone(dtls_context_t *ctx,
585 uint8 *data, size_t data_length)
590 const dtls_ecc_key_t *ecdsa_key;
592 + unsigned char *cert;
594 +#endif /* DTLS_X509 */
595 #endif /* DTLS_ECC */
597 dtls_handshake_parameters_t *handshake = peer->handshake_params;
598 @@ -3400,16 +3552,25 @@ check_server_hellodone(dtls_context_t *ctx,
600 update_hs_hash(peer, data, data_length);
603 +#if defined(DTLS_ECC) || defined(DTLS_X509)
604 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
606 - res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
608 + if (CALL(ctx, is_x509_active) == 0)
609 + res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
611 +#endif /* DTLS_X509 */
612 + res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
614 - dtls_crit("no ecdsa certificate to send in certificate\n");
615 + dtls_crit("no ecdsa key to use\n");
619 - res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
621 + if (CALL(ctx, is_x509_active) == 0)
622 + res = dtls_send_certificate_x509(ctx, peer);
624 +#endif /* DTLS_X509 */
625 + res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
628 dtls_debug("dtls_server_hello: cannot prepare Certificate record\n");
629 @@ -3428,7 +3589,6 @@ check_server_hellodone(dtls_context_t *ctx,
632 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
634 res = dtls_send_certificate_verify_ecdh(ctx, peer, ecdsa_key);
637 @@ -3655,16 +3815,21 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
642 +#if defined(DTLS_ECC) || defined(DTLS_X509)
643 case DTLS_HT_CERTIFICATE:
645 if ((role == DTLS_CLIENT && state != DTLS_STATE_WAIT_SERVERCERTIFICATE) ||
646 (role == DTLS_SERVER && state != DTLS_STATE_WAIT_CLIENTCERTIFICATE)) {
647 return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
649 - err = check_server_certificate(ctx, peer, data, data_length);
651 + if (CALL(ctx, is_x509_active) == 0)
652 + err = check_peer_certificate_x509(ctx, peer, data, data_length);
654 +#endif /* DTLS_X509 */
655 + err = check_peer_certificate(ctx, peer, data, data_length);
657 - dtls_warn("error in check_server_certificate err: %i\n", err);
658 + dtls_warn("error in check_peer_certificate err: %i\n", err);
661 if (role == DTLS_CLIENT) {
662 @@ -3679,7 +3844,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
664 case DTLS_HT_SERVER_KEY_EXCHANGE:
667 +#if defined(DTLS_ECC) || defined(DTLS_X509)
668 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) {
669 if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
670 return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
671 @@ -3811,13 +3976,13 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
672 update_hs_hash(peer, data, data_length);
674 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) &&
675 - is_ecdsa_client_auth_supported(ctx))
676 + (is_ecdsa_client_auth_supported(ctx) || (is_x509_client_auth_supported(ctx))))
677 peer->state = DTLS_STATE_WAIT_CERTIFICATEVERIFY; //ecdsa
679 peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; //psk || ecdh_anon
683 +#if defined(DTLS_ECC) || defined(DTLS_X509)
684 case DTLS_HT_CERTIFICATE_VERIFY:
686 if (state != DTLS_STATE_WAIT_CERTIFICATEVERIFY) {
687 @@ -3934,7 +4099,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
690 if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) &&
691 - is_ecdsa_client_auth_supported(ctx))
692 + (is_ecdsa_client_auth_supported(ctx) || (is_x509_client_auth_supported(ctx))))
693 peer->state = DTLS_STATE_WAIT_CLIENTCERTIFICATE; //ecdhe
695 peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; //psk, ecdh_anon
696 @@ -4261,7 +4426,7 @@ dtls_handle_message(dtls_context_t *ctx,
697 data = msg + DTLS_RH_LENGTH;
698 data_length = rlen - DTLS_RH_LENGTH;
699 state = DTLS_STATE_WAIT_CLIENTHELLO;
700 - role = DTLS_SERVER;
701 + role = DTLS_SERVER;
703 int err = dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR);
704 dtls_info("decrypt_verify() failed\n");
705 @@ -4506,7 +4671,7 @@ dtls_connect_peer(dtls_context_t *ctx, dtls_peer_t *peer) {
706 res = dtls_send_client_hello(ctx, peer, NULL, 0);
708 dtls_warn("cannot send ClientHello\n");
711 peer->state = DTLS_STATE_CLIENTHELLO;
714 diff --git a/extlibs/tinydtls/dtls.h b/extlibs/tinydtls/dtls.h
715 index 7d2bc19..c5a86df 100644
716 --- a/extlibs/tinydtls/dtls.h
717 +++ b/extlibs/tinydtls/dtls.h
719 #define DTLS_VERSION 0xfefd /* DTLS v1.2 */
723 +#define DTLS_MAX_CERT_SIZE 1400
726 typedef enum dtls_credentials_type_t {
727 DTLS_PSK_HINT, DTLS_PSK_IDENTITY, DTLS_PSK_KEY
728 } dtls_credentials_type_t;
729 @@ -181,10 +185,11 @@ typedef struct {
731 * @return @c 0 if result is set, or less than zero on error.
733 - int (*get_ecdsa_key)(struct dtls_context_t *ctx,
734 + int (*get_ecdsa_key)(struct dtls_context_t *ctx,
735 const session_t *session,
736 const dtls_ecc_key_t **result);
740 * Called during handshake to check the peer's pubic key in this
741 * session. If the public key matches the session and should be
742 @@ -211,12 +216,111 @@ typedef struct {
743 * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_UNKNOWN);
744 * return dtls_alert_fatal_create(DTLS_ALERT_UNKNOWN_CA);
746 - int (*verify_ecdsa_key)(struct dtls_context_t *ctx,
747 + int (*verify_ecdsa_key)(struct dtls_context_t *ctx,
748 const session_t *session,
749 const unsigned char *other_pub_x,
750 const unsigned char *other_pub_y,
752 #endif /* DTLS_ECC */
755 + * Called during handshake to get the server's or client's ecdsa
756 + * key used to authenticate this server or client in this
757 + * session. If found, the key must be stored in @p result and
758 + * the return value must be @c 0. If not found, @p result is
759 + * undefined and the return value must be less than zero.
761 + * If ECDSA should not be supported, set this pointer to NULL.
763 + * Implement this if you want to provide your own certificate to
764 + * the other peer. This is mandatory for a server providing X.509
765 + * support and optional for a client. A client doing DTLS client
766 + * authentication has to implementing this callback.
768 + * @param ctx The current dtls context.
769 + * @param session The session where the key will be used.
770 + * @param result Must be set to the key object to used for the given
772 + * @return @c 0 if result is set, or less than zero on error.
774 + int (*get_x509_key)(struct dtls_context_t *ctx,
775 + const session_t *session,
776 + const dtls_ecc_key_t **result);
778 + * Called during handshake to get the server's or client's
779 + * certificate used to authenticate this server or client in this
780 + * session. If found, the certificate must be stored in @p cert and
781 + * the return value must be @c 0. If not found, @p cert is
782 + * undefined and the return value must be less than zero.
784 + * If X.509 should not be supported, set this pointer to NULL.
786 + * Implement this if you want to provide your own certificate to
787 + * the other peer. This is mandatory for a server providing X.509
788 + * support and optional for a client. A client doing DTLS client
789 + * authentication has to implementing this callback.
791 + * @param ctx The current dtls context.
792 + * @param session The session where the certificate will be used.
793 + * @param cert Must be set to the certificate object to used for
794 + * the given session.
795 + * @param cert_size Size of certificate in bytes.
796 + * @return @c 0 if result is set, or less than zero on error.
798 + int (*get_x509_cert)(struct dtls_context_t *ctx,
799 + const session_t *session,
800 + const unsigned char **cert,
801 + size_t *cert_size);
804 + * Called during handshake to check the peer's certificate in this
805 + * session. If the certificate matches the session and is valid the
806 + * return value must be @c 0. If not valid, the return value must be
809 + * If X.509 should not be supported, set this pointer to NULL.
811 + * Implement this if you want to verify the other peers certificate.
812 + * This is mandatory for a DTLS client doing based X.509
813 + * authentication. A server implementing this will request the
814 + * client to do DTLS client authentication.
816 + * @param ctx The current dtls context.
817 + * @param session The session where the key will be used.
818 + * @param cert Peer's certificate to check.
819 + * @param cert_size Size of certificate in bytes.
820 + * @param x Allocated memory to store peer's public key part x.
821 + * @param x_size Size of allocated memory to store peer's public key part x.
822 + * @param y Allocated memory to store peer's public key part y.
823 + * @param y_size Size of allocated memory to store peer's public key part y.
824 + * @return @c 0 if public key matches, or less than zero on error.
826 + * return dtls_alert_fatal_create(DTLS_ALERT_BAD_CERTIFICATE);
827 + * return dtls_alert_fatal_create(DTLS_ALERT_UNSUPPORTED_CERTIFICATE);
828 + * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_REVOKED);
829 + * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_EXPIRED);
830 + * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_UNKNOWN);
831 + * return dtls_alert_fatal_create(DTLS_ALERT_UNKNOWN_CA);
833 + int (*verify_x509_cert)(struct dtls_context_t *ctx,
834 + const session_t *session,
835 + const unsigned char *cert,
843 + * Called during handshake to check if certificate format should be X.509
845 + * If X.509 should not be supported, set this pointer to NULL.
847 + * @param ctx The current dtls context.
848 + * @return @c 0 if certificate format should be X.509, or less than zero on error.
850 + int (*is_x509_active)(struct dtls_context_t *ctx);
851 +#endif /* DTLS_X509 */
854 /** Holds global information of the DTLS engine. */
855 diff --git a/extlibs/tinydtls/dtls_config.h b/extlibs/tinydtls/dtls_config.h
856 index 39df8c9..c6c4e39 100644
857 --- a/extlibs/tinydtls/dtls_config.h
858 +++ b/extlibs/tinydtls/dtls_config.h
863 +/* Define if building universal (internal helper macro) */
864 +/* #undef AC_APPLE_UNIVERSAL_BUILD */
866 +/* Define to 1 if building with X.509 support */
869 +/* Define to 1 if you have the <arpa/inet.h> header file. */
870 +#define HAVE_ARPA_INET_H 1
872 /* Define to 1 if you have the <assert.h> header file. */
873 #define HAVE_ASSERT_H 1
875 +/* Define to 1 if you have the <fcntl.h> header file. */
876 +#define HAVE_FCNTL_H 1
878 +/* Define to 1 if you have the `fls' function. */
879 +/* #undef HAVE_FLS */
881 +/* Define to 1 if you have the <inttypes.h> header file. */
882 +#define HAVE_INTTYPES_H 1
884 /* Define to 1 if your system has a GNU libc compatible `malloc' function, and
886 #define HAVE_MALLOC 1
888 /* Define to 1 if you have the `memset' function. */
889 #define HAVE_MEMSET 1
891 +/* Define to 1 if you have the <netdb.h> header file. */
892 +#define HAVE_NETDB_H 1
894 +/* Define to 1 if you have the <netinet/in.h> header file. */
895 +#define HAVE_NETINET_IN_H 1
897 +/* Define to 1 if you have the `select' function. */
898 +#define HAVE_SELECT 1
900 +/* Define to 1 if struct sockaddr_in6 has a member sin6_len. */
901 +/* #undef HAVE_SOCKADDR_IN6_SIN6_LEN */
903 +/* Define to 1 if you have the `socket' function. */
904 +#define HAVE_SOCKET 1
906 /* Define to 1 if you have the <stddef.h> header file. */
907 #define HAVE_STDDEF_H 1
910 /* Define to 1 if you have the `strnlen' function. */
911 #define HAVE_STRNLEN 1
913 +/* Define to 1 if you have the <sys/param.h> header file. */
914 +#define HAVE_SYS_PARAM_H 1
916 +/* Define to 1 if you have the <sys/socket.h> header file. */
917 +#define HAVE_SYS_SOCKET_H 1
919 +/* Define to 1 if you have the <sys/stat.h> header file. */
920 +#define HAVE_SYS_STAT_H 1
922 +/* Define to 1 if you have the <sys/time.h> header file. */
923 +#define HAVE_SYS_TIME_H 1
925 +/* Define to 1 if you have the <sys/types.h> header file. */
926 +#define HAVE_SYS_TYPES_H 1
928 /* Define to 1 if you have the <time.h> header file. */
929 #define HAVE_TIME_H 1
931 +/* Define to 1 if you have the <unistd.h> header file. */
932 +#define HAVE_UNISTD_H 1
934 /* Define to 1 if you have the `vprintf' function. */
935 #define HAVE_VPRINTF 1
937 diff --git a/extlibs/tinydtls/dtls_config.h.in b/extlibs/tinydtls/dtls_config.h.in
938 index a29077c..adc8dc5 100644
939 --- a/extlibs/tinydtls/dtls_config.h.in
940 +++ b/extlibs/tinydtls/dtls_config.h.in
942 /* Define if building universal (internal helper macro) */
943 #undef AC_APPLE_UNIVERSAL_BUILD
945 +/* Define to 1 if building with X.509 support */
948 /* Define to 1 if you have the <arpa/inet.h> header file. */
949 #undef HAVE_ARPA_INET_H
951 diff --git a/extlibs/tinydtls/global.h b/extlibs/tinydtls/global.h
952 index 8b3c518..048bacd 100644
953 --- a/extlibs/tinydtls/global.h
954 +++ b/extlibs/tinydtls/global.h
955 @@ -55,7 +55,7 @@ typedef unsigned char uint48[6];
956 When Peers are sending bigger messages this causes problems. Californium
957 with ECDSA needs at least 220 */
960 +#if defined(DTLS_ECC) || defined(DTLS_X509)
961 #define DTLS_MAX_BUF 200
963 #define DTLS_MAX_BUF 100
964 @@ -96,7 +96,10 @@ typedef enum {
965 #define TLS_EXT_SERVER_CERTIFICATE_TYPE 20 /* see RFC 7250 */
966 #define TLS_EXT_ENCRYPT_THEN_MAC 22 /* see RFC 7366 */
968 -#define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */
969 +/* see http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-3 */
970 +#define TLS_CERT_TYPE_X509 0 /* see RFC 6091 */
971 +#define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */
974 #define TLS_EXT_ELLIPTIC_CURVES_SECP256R1 23 /* see RFC 4492 */
976 diff --git a/extlibs/tinydtls/netq.h b/extlibs/tinydtls/netq.h
977 index a771b23..fea7511 100644
978 --- a/extlibs/tinydtls/netq.h
979 +++ b/extlibs/tinydtls/netq.h
985 +#if defined(DTLS_ECC) || defined(DTLS_X509)
986 #define NETQ_MAXCNT 5 /**< maximum number of elements in netq structure */
987 #elif defined(DTLS_PSK)
988 #define NETQ_MAXCNT 3 /**< maximum number of elements in netq structure */
989 diff --git a/extlibs/tinydtls/tests/Makefile.in b/extlibs/tinydtls/tests/Makefile.in
990 index 3a50695..a2d8ca4 100644
991 --- a/extlibs/tinydtls/tests/Makefile.in
992 +++ b/extlibs/tinydtls/tests/Makefile.in
993 @@ -41,9 +41,9 @@ SOURCES:= dtls-server.c ccm-test.c prf-test.c \
994 OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
995 PROGRAMS:= $(patsubst %.c, %, $(SOURCES))
997 -CFLAGS:=-Wall @CFLAGS@
998 +CFLAGS:=-Wall @CFLAGS@
999 CPPFLAGS:=-I$(top_srcdir) @CPPFLAGS@
1000 -LDFLAGS:=-L$(top_builddir)
1001 +LDFLAGS:=-L$(top_builddir)
1002 LDLIBS:=-ltinydtls @LIBS@
1003 DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@
1004 FILES:=Makefile.in $(SOURCES) ccm-testdata.c #cbc_aes128-testdata.c
1005 diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c
1006 index dfd34c8..2c4eff9 100644
1007 --- a/extlibs/tinydtls/tests/dtls-client.c
1008 +++ b/extlibs/tinydtls/tests/dtls-client.c
1013 -#include "global.h"
1016 +#include "global.h"
1021 + * @struct byte_array
1023 + * General purpose byte array structure.
1025 + * Contains pointer to array of bytes and it's length.
1030 + uint8_t *data; /**< Pointer to the byte array */
1031 + size_t len; /**< Data size */
1035 +/**@def BYTE_ARRAY_INITIALIZER
1037 + * Initializes of existing byte array pointer to \a NULL.
1039 +#undef BYTE_ARRAY_INITIALIZER
1040 +#define BYTE_ARRAY_INITIALIZER {NULL, 0}
1042 +#define DTLS_PRIVATE_KEY_SIZE (32)
1043 +#define DTLS_PUBLIC_KEY_SIZE (64)
1045 #define DEFAULT_PORT 20220
1048 #define PSK_SERVER_IDENTITY "Server_identity"
1049 #define PSK_DEFAULT_KEY "secretPSK"
1050 #define PSK_OPTIONS "i:s:k:"
1051 +#define X509_OPTIONS "x:r:u:"
1054 #define UNUSED_PARAM __attribute__((unused))
1055 @@ -46,7 +72,105 @@ static dtls_str output_file = { 0, NULL }; /* output file name */
1056 static dtls_context_t *dtls_context = NULL;
1057 static dtls_context_t *orig_dtls_context = NULL;
1060 +#define CLIENT_CRT_LEN 293
1061 +static const unsigned char g_client_certificate[CLIENT_CRT_LEN] = {
1063 + 0x30, 0x82, 0x01, 0x1e, 0x30, 0x81, 0xc4, 0xa0,
1064 + 0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x38,
1065 + 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
1066 + 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x17,
1067 + 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
1068 + 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
1069 + 0x20, 0x49, 0x53, 0x53, 0x55, 0x45, 0x52, 0x30,
1070 + 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, 0x30,
1071 + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
1072 + 0x17, 0x0d, 0x34, 0x39, 0x30, 0x31, 0x30, 0x31,
1073 + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
1074 + 0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
1075 + 0x04, 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
1076 + 0x6c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54,
1077 + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
1078 + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
1079 + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
1080 + 0x42, 0x00, 0x04, 0xe3, 0xd1, 0x67, 0x1e, 0xdc,
1081 + 0x46, 0xf4, 0x19, 0x50, 0x15, 0x2e, 0x3a, 0x2f,
1082 + 0xd8, 0x68, 0x6b, 0x37, 0x32, 0x84, 0x9e, 0x83,
1083 + 0x81, 0xbf, 0x25, 0x5d, 0xbb, 0x18, 0x07, 0x3c,
1084 + 0xbd, 0xf3, 0xab, 0xd3, 0xbf, 0x53, 0x59, 0xc9,
1085 + 0x1e, 0xce, 0x5b, 0x39, 0x6a, 0xe5, 0x60, 0xf3,
1086 + 0x70, 0xdb, 0x66, 0xb6, 0x80, 0xcb, 0x65, 0x0b,
1087 + 0x35, 0x2a, 0x62, 0x44, 0x89, 0x63, 0x64, 0x6f,
1088 + 0x6f, 0xbd, 0xf0, 0x30, 0x0c, 0x06, 0x08, 0x2a,
1089 + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05,
1090 + 0x00, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20,
1091 + 0x60, 0xdc, 0x45, 0x77, 0x7d, 0xcb, 0xc3, 0xb4,
1092 + 0xba, 0x60, 0x5a, 0x2e, 0xe5, 0x4e, 0x19, 0x8b,
1093 + 0x48, 0x8a, 0x87, 0xd4, 0x66, 0xb4, 0x1a, 0x86,
1094 + 0x23, 0x67, 0xb8, 0xb6, 0x50, 0xfe, 0x4d, 0xde,
1095 + 0x02, 0x20, 0x60, 0x68, 0x46, 0xff, 0x74, 0x11,
1096 + 0xfb, 0x36, 0x13, 0xf4, 0xa7, 0x3d, 0xb7, 0x35,
1097 + 0x79, 0x23, 0x29, 0x14, 0x6a, 0x28, 0x09, 0xff,
1098 + 0x8c, 0x19, 0x26, 0xe3, 0x41, 0xc8, 0xe4, 0x13,
1100 +//default client's key pair
1101 +static const unsigned char x509_priv_key[] = {
1102 + 0xf9, 0x42, 0xb4, 0x16, 0x89, 0x10, 0xf4, 0x07,
1103 + 0x99, 0xb2, 0xe2, 0x9a, 0xed, 0xd4, 0x39, 0xb8,
1104 + 0xca, 0xd4, 0x9d, 0x76, 0x11, 0x43, 0x3a, 0xac,
1105 + 0x14, 0xba, 0x17, 0x9d, 0x3e, 0xbb, 0xbf, 0xbc};
1107 +static const unsigned char x509_pub_key_x[] = {
1108 + 0xe3, 0xd1, 0x67, 0x1e, 0xdc, 0x46, 0xf4, 0x19,
1109 + 0x50, 0x15, 0x2e, 0x3a, 0x2f, 0xd8, 0x68, 0x6b,
1110 + 0x37, 0x32, 0x84, 0x9e, 0x83, 0x81, 0xbf, 0x25,
1111 + 0x5d, 0xbb, 0x18, 0x07, 0x3c, 0xbd, 0xf3, 0xab};
1113 +static const unsigned char x509_pub_key_y[] = {
1114 + 0xd3, 0xbf, 0x53, 0x59, 0xc9, 0x1e, 0xce, 0x5b,
1115 + 0x39, 0x6a, 0xe5, 0x60, 0xf3, 0x70, 0xdb, 0x66,
1116 + 0xb6, 0x80, 0xcb, 0x65, 0x0b, 0x35, 0x2a, 0x62,
1117 + 0x44, 0x89, 0x63, 0x64, 0x6f, 0x6f, 0xbd, 0xf0};
1119 +//default CA pub key
1120 +static const unsigned char x509_ca_pub_x[] = {
1121 + 0x57, 0x94, 0x7f, 0x98, 0x7a, 0x02, 0x67, 0x09,
1122 + 0x25, 0xc1, 0xcb, 0x5a, 0xf5, 0x46, 0xfb, 0xad,
1123 + 0xf7, 0x68, 0x94, 0x8c, 0xa7, 0xe3, 0xf0, 0x5b,
1124 + 0xc3, 0x6b, 0x5c, 0x9b, 0xd3, 0x7d, 0x74, 0x12
1127 +static const unsigned char x509_ca_pub_y[] = {
1128 + 0xce, 0x68, 0xbc, 0x55, 0xf5, 0xf8, 0x1b, 0x3d,
1129 + 0xef, 0xed, 0x1f, 0x2b, 0xd2, 0x69, 0x5d, 0xcf,
1130 + 0x79, 0x16, 0xa6, 0xbd, 0x97, 0x96, 0x27, 0x60,
1131 + 0x5d, 0xd1, 0xb7, 0x93, 0xa2, 0x4a, 0x62, 0x4d
1134 +//default server's key pair
1135 +static const unsigned char serv_pub_key_x[] = {
1136 + 0x07, 0x88, 0x10, 0xdc, 0x62, 0xd7, 0xe6, 0x9b,
1137 + 0x7c, 0xad, 0x6e, 0x78, 0xb0, 0x5f, 0x9a, 0x00,
1138 + 0x11, 0x74, 0x2c, 0x8b, 0xaf, 0x09, 0x65, 0x7c,
1139 + 0x86, 0x8e, 0x55, 0xcb, 0x39, 0x55, 0x72, 0xc6};
1141 +static const unsigned char serv_pub_key_y[] = {
1142 + 0x65, 0x71, 0xcd, 0x03, 0xdc, 0x2a, 0x4f, 0x46,
1143 + 0x5b, 0x14, 0xc8, 0x27, 0x74, 0xab, 0xf4, 0x1f,
1144 + 0xc1, 0x35, 0x0d, 0x42, 0xbc, 0xc2, 0x9f, 0xb5,
1145 + 0xc1, 0x79, 0xb6, 0x8b, 0xca, 0xdb, 0xff, 0x82};
1148 +static unsigned char x509_client_cert[DTLS_MAX_CERT_SIZE];
1149 +static size_t x509_client_cert_len = 0;
1150 +static unsigned char x509_client_priv[DTLS_PRIVATE_KEY_SIZE+1];
1151 +static size_t x509_client_priv_is_set = 0;
1152 +static unsigned char x509_ca_pub[DTLS_PUBLIC_KEY_SIZE+1];
1153 +static size_t x509_ca_pub_is_set = 0;
1155 +static int x509_info_from_file = 0;
1156 +#endif /*DTLS_X509*/
1158 static const unsigned char ecdsa_priv_key[] = {
1159 0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14,
1160 0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14,
1161 @@ -65,7 +189,8 @@ static const unsigned char ecdsa_pub_key_y[] = {
1162 0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B,
1163 0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29};
1166 +#endif /*DTLS_ECC*/
1167 +#if defined(DTLS_PSK) || defined(DTLS_X509)
1169 read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) {
1171 @@ -87,11 +212,11 @@ read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) {
1172 result += bytes_read;
1173 max_buf_len -= bytes_read;
1180 +#endif /*DTLS_PSK||DTLS_X509*/
1182 /* The PSK information for DTLS */
1183 #define PSK_ID_MAXLEN 256
1184 #define PSK_MAXLEN 256
1185 @@ -149,13 +274,14 @@ static int
1186 get_ecdsa_key(struct dtls_context_t *ctx,
1187 const session_t *session,
1188 const dtls_ecc_key_t **result) {
1191 static const dtls_ecc_key_t ecdsa_key = {
1192 .curve = DTLS_ECDH_CURVE_SECP256R1,
1193 .priv_key = ecdsa_priv_key,
1194 .pub_key_x = ecdsa_pub_key_x,
1195 .pub_key_y = ecdsa_pub_key_y
1198 *result = &ecdsa_key;
1201 @@ -166,10 +292,115 @@ verify_ecdsa_key(struct dtls_context_t *ctx,
1202 const unsigned char *other_pub_x,
1203 const unsigned char *other_pub_y,
1207 + (void)other_pub_x;
1208 + (void)other_pub_y;
1213 #endif /* DTLS_ECC */
1217 +get_x509_key(struct dtls_context_t *ctx,
1218 + const session_t *session,
1219 + const dtls_ecc_key_t **result) {
1222 + static dtls_ecc_key_t ecdsa_key = {
1223 + .curve = DTLS_ECDH_CURVE_SECP256R1,
1224 + .priv_key = x509_priv_key,
1225 + .pub_key_x = x509_pub_key_x,
1226 + .pub_key_y = x509_pub_key_y
1228 + if (x509_info_from_file)
1229 + ecdsa_key.priv_key = x509_client_priv;
1230 + *result = &ecdsa_key;
1235 +get_x509_cert(struct dtls_context_t *ctx,
1236 + const session_t *session,
1237 + const unsigned char **cert,
1238 + size_t *cert_size)
1242 + if (x509_info_from_file)
1244 + *cert = x509_client_cert;
1245 + *cert_size = x509_client_cert_len;
1249 + *cert = g_client_certificate;
1250 + *cert_size = CLIENT_CRT_LEN;
1256 +int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
1258 + (void)cert_der_code;
1259 + (void)ca_public_key;
1263 +static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
1264 + const unsigned char *cert, size_t cert_size,
1271 + const unsigned char *ca_pub_x;
1272 + const unsigned char *ca_pub_y;
1273 + byte_array cert_der_code = BYTE_ARRAY_INITIALIZER;
1274 + byte_array ca_public_key = BYTE_ARRAY_INITIALIZER;
1275 + unsigned char ca_pub_key[DTLS_PUBLIC_KEY_SIZE];
1279 + if (x509_info_from_file)
1281 + ca_pub_x = x509_ca_pub;
1282 + ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
1286 + ca_pub_x = x509_ca_pub_x;
1287 + ca_pub_y = x509_ca_pub_y;
1290 + cert_der_code.data = (uint8_t *)cert;
1291 + cert_der_code.len = cert_size;
1293 + ca_public_key.len = DTLS_PUBLIC_KEY_SIZE;
1294 + ca_public_key.data = ca_pub_key;
1295 + memcpy(ca_public_key.data, ca_pub_x, DTLS_PUBLIC_KEY_SIZE/2);
1296 + memcpy(ca_public_key.data + DTLS_PUBLIC_KEY_SIZE/2, ca_pub_y, DTLS_PUBLIC_KEY_SIZE/2);
1298 + memcpy(x, serv_pub_key_x, x_size);
1299 + memcpy(y, serv_pub_key_y, y_size);
1301 + ret = (int) check_certificate(cert_der_code, ca_public_key);
1306 +static int is_x509_active(struct dtls_context_t *ctx)
1312 +#endif /* DTLS_X509 */
1315 try_send(struct dtls_context_t *ctx, session_t *dst) {
1317 @@ -190,6 +421,8 @@ static int
1318 read_from_peer(struct dtls_context_t *ctx,
1319 session_t *session, uint8 *data, size_t len) {
1323 for (i = 0; i < len; i++)
1324 printf("%c", data[i]);
1326 @@ -295,16 +528,24 @@ usage( const char *program, const char *version) {
1328 fprintf(stderr, "%s v%s -- DTLS client implementation\n"
1329 "(c) 2011-2014 Olaf Bergmann <bergmann@tzi.org>\n\n"
1332 - "usage: %s [-i file] [-s file] [-k file] [-o file] [-p port] [-v num] [-c num] addr [port]\n"
1333 -#else /* DTLS_PSK */
1334 - "usage: %s [-o file] [-p port] [-v num] [-c num] addr [port]\n"
1335 + " [-i file] [-s file] [-k file]"
1336 #endif /* DTLS_PSK */
1338 + " [-x file] [-r file] [-u file]"
1339 +#endif /* DTLS_X509 */
1340 + " [-o file] [-p port] [-v num] [-c num] addr [port]\n"
1342 "\t-i file\t\tread PSK Client identity from file\n"
1343 "\t-s file\t\tread PSK Server identity from file\n"
1344 "\t-k file\t\tread pre-shared key from file\n"
1345 #endif /* DTLS_PSK */
1347 + "\t-x file\tread Client certificate from file\n"
1348 + "\t-r file\tread Client private key from file\n"
1349 + "\t-u file\tread CA public key from file\n"
1350 +#endif /* DTLS_X509 */
1351 "\t-o file\t\toutput received data to this file (use '-' for STDOUT)\n"
1352 "\t-p port\t\tlisten on specified port (default is %d)\n"
1353 "\t-v num\t\tverbosity level (default: 3)\n"
1354 @@ -325,8 +566,15 @@ static dtls_handler_t cb = {
1355 #endif /* DTLS_PSK */
1357 .get_ecdsa_key = get_ecdsa_key,
1358 - .verify_ecdsa_key = verify_ecdsa_key
1359 + .verify_ecdsa_key = verify_ecdsa_key,
1360 #endif /* DTLS_ECC */
1362 + .get_x509_key = get_x509_key,
1363 + .verify_x509_cert = verify_x509_cert,
1364 + .get_x509_cert = get_x509_cert,
1365 + .is_x509_active = is_x509_active,
1366 +#endif /* DTLS_X509 */
1370 #define DTLS_CLIENT_CMD_CLOSE "client:close"
1371 @@ -365,7 +613,7 @@ main(int argc, char **argv) {
1372 memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length);
1373 #endif /* DTLS_PSK */
1375 - while ((opt = getopt(argc, argv, "p:o:v:c:" PSK_OPTIONS)) != -1) {
1376 + while ((opt = getopt(argc, argv, "p:o:v:c:" PSK_OPTIONS X509_OPTIONS)) != -1) {
1380 @@ -396,6 +644,47 @@ main(int argc, char **argv) {
1383 #endif /* DTLS_PSK */
1387 + ssize_t result = read_from_file(optarg, x509_client_cert, DTLS_MAX_CERT_SIZE);
1390 + dtls_warn("Cannot read Client certificate. Using default\n");
1394 + x509_client_cert_len = result;
1400 + ssize_t result = read_from_file(optarg, x509_client_priv, DTLS_PRIVATE_KEY_SIZE+1);
1403 + dtls_warn("Cannot read Client private key. Using default\n");
1407 + x509_client_priv_is_set = result;
1413 + ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
1416 + dtls_warn("Cannot read CA public key. Using default\n");
1420 + x509_ca_pub_is_set = result;
1424 +#endif /* DTLS_X509 */
1426 strncpy(port_str, optarg, NI_MAXSERV-1);
1427 port_str[NI_MAXSERV - 1] = '\0';
1428 @@ -403,7 +692,7 @@ main(int argc, char **argv) {
1430 output_file.length = strlen(optarg);
1431 output_file.s = (unsigned char *)malloc(output_file.length + 1);
1434 if (!output_file.s) {
1435 dtls_crit("cannot set output file: insufficient memory\n");
1437 @@ -444,12 +733,29 @@ main(int argc, char **argv) {
1440 dtls_set_log_level(log_level);
1443 if (argc <= optind) {
1444 usage(argv[0], dtls_package_version());
1450 + if (x509_client_cert_len && x509_client_priv_is_set && x509_ca_pub_is_set)
1452 + x509_info_from_file = 1;
1454 + else if(!(x509_client_cert_len || x509_client_priv_is_set || x509_ca_pub_is_set))
1456 + x509_info_from_file = 0;
1460 + fprintf(stderr,"please set -x, -r, -u options simultaneously");
1461 + usage(argv[0], dtls_package_version());
1464 +#endif /* DTLS_X509 */
1466 memset(&dst, 0, sizeof(session_t));
1467 /* resolve destination address where server should be sent */
1468 res = resolve_address(argv[optind++], &dst.addr.sa);
1469 diff --git a/extlibs/tinydtls/tests/dtls-server.c b/extlibs/tinydtls/tests/dtls-server.c
1470 index 5893084..a3ede4d 100644
1471 --- a/extlibs/tinydtls/tests/dtls-server.c
1472 +++ b/extlibs/tinydtls/tests/dtls-server.c
1473 @@ -14,12 +14,138 @@
1477 -#include "tinydtls.h"
1480 +#include "tinydtls.h"
1485 +#define DTLS_PRIVATE_KEY_SIZE (32)
1486 +#define DTLS_PUBLIC_KEY_SIZE (64)
1489 #define DEFAULT_PORT 20220
1492 + * @struct byte_array
1494 + * General purpose byte array structure.
1496 + * Contains pointer to array of bytes and it's length.
1501 + uint8_t *data; /**< Pointer to the byte array */
1502 + size_t len; /**< Data size */
1506 +/**@def BYTE_ARRAY_INITIALIZER
1508 + * Initializes of existing byte array pointer to \a NULL.
1510 +#undef BYTE_ARRAY_INITIALIZER
1511 +#define BYTE_ARRAY_INITIALIZER {NULL, 0}
1514 +#define X509_OPTIONS "x:r:u:"
1515 +#define SERVER_CRT_LEN 295
1516 +static const unsigned char g_server_certificate[SERVER_CRT_LEN] = {
1518 + 0x30, 0x82, 0x01, 0x20, 0x30, 0x81, 0xc4, 0xa0,
1519 + 0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x37,
1520 + 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
1521 + 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x17,
1522 + 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
1523 + 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
1524 + 0x20, 0x49, 0x53, 0x53, 0x55, 0x45, 0x52, 0x30,
1525 + 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, 0x30,
1526 + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
1527 + 0x17, 0x0d, 0x34, 0x39, 0x30, 0x31, 0x30, 0x31,
1528 + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
1529 + 0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
1530 + 0x04, 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
1531 + 0x6c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52,
1532 + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
1533 + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
1534 + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
1535 + 0x42, 0x00, 0x04, 0x07, 0x88, 0x10, 0xdc, 0x62,
1536 + 0xd7, 0xe6, 0x9b, 0x7c, 0xad, 0x6e, 0x78, 0xb0,
1537 + 0x5f, 0x9a, 0x00, 0x11, 0x74, 0x2c, 0x8b, 0xaf,
1538 + 0x09, 0x65, 0x7c, 0x86, 0x8e, 0x55, 0xcb, 0x39,
1539 + 0x55, 0x72, 0xc6, 0x65, 0x71, 0xcd, 0x03, 0xdc,
1540 + 0x2a, 0x4f, 0x46, 0x5b, 0x14, 0xc8, 0x27, 0x74,
1541 + 0xab, 0xf4, 0x1f, 0xc1, 0x35, 0x0d, 0x42, 0xbc,
1542 + 0xc2, 0x9f, 0xb5, 0xc1, 0x79, 0xb6, 0x8b, 0xca,
1543 + 0xdb, 0xff, 0x82, 0x30, 0x0c, 0x06, 0x08, 0x2a,
1544 + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05,
1545 + 0x00, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21,
1546 + 0x00, 0xb1, 0x81, 0x81, 0x92, 0x0e, 0x76, 0x7c,
1547 + 0xeb, 0xf5, 0x37, 0xde, 0x27, 0xc4, 0x01, 0xc8,
1548 + 0x96, 0xc3, 0xe5, 0x9f, 0x47, 0x7e, 0x25, 0x92,
1549 + 0xa4, 0xba, 0x22, 0x25, 0xa3, 0x81, 0x19, 0xcf,
1550 + 0x0d, 0x02, 0x21, 0x00, 0xca, 0x92, 0xbe, 0x79,
1551 + 0xc7, 0x82, 0x84, 0x64, 0xc4, 0xc4, 0xf4, 0x3d,
1552 + 0x69, 0x79, 0x68, 0xc0, 0xf1, 0xba, 0xaf, 0x6c,
1553 + 0xbb, 0xdd, 0x54, 0x7d, 0x07, 0xe7, 0x53, 0x3b,
1554 + 0xc3, 0x1b, 0x87, 0x04};
1556 +//default server's key pair
1557 +static const unsigned char x509_priv_key[] = {
1558 + 0xaa, 0xa3, 0x46, 0xf1, 0x3c, 0x56, 0x5d, 0x08,
1559 + 0x5e, 0x59, 0xba, 0x7f, 0xd2, 0x21, 0x62, 0xc6,
1560 + 0xcc, 0x5d, 0xfa, 0x3f, 0xb5, 0x25, 0xa9, 0x89,
1561 + 0x4f, 0x32, 0xe8, 0x2a, 0xe0, 0xee, 0x9b, 0x4c};
1563 +static const unsigned char x509_pub_key_x[] = {
1564 + 0x07, 0x88, 0x10, 0xdc, 0x62, 0xd7, 0xe6, 0x9b,
1565 + 0x7c, 0xad, 0x6e, 0x78, 0xb0, 0x5f, 0x9a, 0x00,
1566 + 0x11, 0x74, 0x2c, 0x8b, 0xaf, 0x09, 0x65, 0x7c,
1567 + 0x86, 0x8e, 0x55, 0xcb, 0x39, 0x55, 0x72, 0xc6};
1569 +static const unsigned char x509_pub_key_y[] = {
1570 + 0x65, 0x71, 0xcd, 0x03, 0xdc, 0x2a, 0x4f, 0x46,
1571 + 0x5b, 0x14, 0xc8, 0x27, 0x74, 0xab, 0xf4, 0x1f,
1572 + 0xc1, 0x35, 0x0d, 0x42, 0xbc, 0xc2, 0x9f, 0xb5,
1573 + 0xc1, 0x79, 0xb6, 0x8b, 0xca, 0xdb, 0xff, 0x82};
1575 +//default CA pub key
1576 +static const unsigned char x509_ca_pub_x[] = {
1577 + 0x57, 0x94, 0x7f, 0x98, 0x7a, 0x02, 0x67, 0x09,
1578 + 0x25, 0xc1, 0xcb, 0x5a, 0xf5, 0x46, 0xfb, 0xad,
1579 + 0xf7, 0x68, 0x94, 0x8c, 0xa7, 0xe3, 0xf0, 0x5b,
1580 + 0xc3, 0x6b, 0x5c, 0x9b, 0xd3, 0x7d, 0x74, 0x12
1583 +static const unsigned char x509_ca_pub_y[] = {
1584 + 0xce, 0x68, 0xbc, 0x55, 0xf5, 0xf8, 0x1b, 0x3d,
1585 + 0xef, 0xed, 0x1f, 0x2b, 0xd2, 0x69, 0x5d, 0xcf,
1586 + 0x79, 0x16, 0xa6, 0xbd, 0x97, 0x96, 0x27, 0x60,
1587 + 0x5d, 0xd1, 0xb7, 0x93, 0xa2, 0x4a, 0x62, 0x4d
1590 +static const unsigned char client_pub_key_x[] = {
1591 + 0xe3, 0xd1, 0x67, 0x1e, 0xdc, 0x46, 0xf4, 0x19,
1592 + 0x50, 0x15, 0x2e, 0x3a, 0x2f, 0xd8, 0x68, 0x6b,
1593 + 0x37, 0x32, 0x84, 0x9e, 0x83, 0x81, 0xbf, 0x25,
1594 + 0x5d, 0xbb, 0x18, 0x07, 0x3c, 0xbd, 0xf3, 0xab};
1596 +static const unsigned char client_pub_key_y[] = {
1597 + 0xd3, 0xbf, 0x53, 0x59, 0xc9, 0x1e, 0xce, 0x5b,
1598 + 0x39, 0x6a, 0xe5, 0x60, 0xf3, 0x70, 0xdb, 0x66,
1599 + 0xb6, 0x80, 0xcb, 0x65, 0x0b, 0x35, 0x2a, 0x62,
1600 + 0x44, 0x89, 0x63, 0x64, 0x6f, 0x6f, 0xbd, 0xf0};
1602 +static unsigned char x509_server_cert[DTLS_MAX_CERT_SIZE];
1603 +static size_t x509_server_cert_len = 0;
1604 +static unsigned char x509_server_priv[DTLS_PRIVATE_KEY_SIZE+1];
1605 +static size_t x509_server_priv_is_set = 0;
1606 +static unsigned char x509_ca_pub[DTLS_PUBLIC_KEY_SIZE+1];
1607 +static size_t x509_ca_pub_is_set = 0;
1609 +static int x509_info_from_file = 0;
1610 +#endif /*DTLS_X509*/
1612 static const unsigned char ecdsa_priv_key[] = {
1613 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05,
1614 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF,
1615 @@ -37,7 +163,7 @@ static const unsigned char ecdsa_pub_key_y[] = {
1616 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31,
1617 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D,
1618 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70};
1620 +#endif /*DTLS_ECC*/
1622 /* SIGINT handler: set quit to 1 for graceful termination */
1624 @@ -46,6 +172,34 @@ handle_sigint(int signum) {
1630 +read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) {
1632 + ssize_t result = 0;
1634 + f = fopen(arg, "r");
1638 + while (!feof(f)) {
1639 + size_t bytes_read;
1640 + bytes_read = fread(buf, 1, max_buf_len, f);
1646 + buf += bytes_read;
1647 + result += bytes_read;
1648 + max_buf_len -= bytes_read;
1654 +#endif /*DTLS_X509*/
1658 #define PSK_SERVER_HINT "Server_identity"
1659 @@ -59,6 +213,8 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session,
1660 const unsigned char *id, size_t id_len,
1661 unsigned char *result, size_t result_length) {
1668 @@ -86,7 +242,7 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session,
1672 - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) {
1673 + for (i = 0; i < (int)(sizeof(psk)/sizeof(struct keymap_t)); i++) {
1674 if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) {
1675 if (result_length < psk[i].key_length) {
1676 dtls_warn("buffer too small for PSK");
1677 @@ -114,6 +270,8 @@ static int
1678 get_ecdsa_key(struct dtls_context_t *ctx,
1679 const session_t *session,
1680 const dtls_ecc_key_t **result) {
1683 static const dtls_ecc_key_t ecdsa_key = {
1684 .curve = DTLS_ECDH_CURVE_SECP256R1,
1685 .priv_key = ecdsa_priv_key,
1686 @@ -131,15 +289,120 @@ verify_ecdsa_key(struct dtls_context_t *ctx,
1687 const unsigned char *other_pub_x,
1688 const unsigned char *other_pub_y,
1692 + (void)other_pub_x;
1693 + (void)other_pub_y;
1697 #endif /* DTLS_ECC */
1701 +get_x509_key(struct dtls_context_t *ctx,
1702 + const session_t *session,
1703 + const dtls_ecc_key_t **result) {
1706 + static dtls_ecc_key_t ecdsa_key = {
1707 + .curve = DTLS_ECDH_CURVE_SECP256R1,
1708 + .priv_key = x509_priv_key,
1709 + .pub_key_x = x509_pub_key_x,
1710 + .pub_key_y = x509_pub_key_y
1712 + if (x509_info_from_file)
1713 + ecdsa_key.priv_key = x509_server_priv;
1715 + *result = &ecdsa_key;
1720 +get_x509_cert(struct dtls_context_t *ctx,
1721 + const session_t *session,
1722 + const unsigned char **cert,
1723 + size_t *cert_size)
1727 + if (x509_info_from_file)
1729 + *cert = x509_server_cert;
1730 + *cert_size = x509_server_cert_len;
1734 + *cert = g_server_certificate;
1735 + *cert_size = SERVER_CRT_LEN;
1741 +static int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
1743 + (void)cert_der_code;
1744 + (void)ca_public_key;
1748 +static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
1749 + const unsigned char *cert, size_t cert_size,
1756 + const unsigned char *ca_pub_x;
1757 + const unsigned char *ca_pub_y;
1758 + byte_array cert_der_code = BYTE_ARRAY_INITIALIZER;
1759 + byte_array ca_public_key = BYTE_ARRAY_INITIALIZER;
1760 + unsigned char ca_pub_key[DTLS_PUBLIC_KEY_SIZE];
1764 + if (x509_info_from_file)
1766 + ca_pub_x = x509_ca_pub;
1767 + ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
1771 + ca_pub_x = x509_ca_pub_x;
1772 + ca_pub_y = x509_ca_pub_y;
1775 + cert_der_code.data = (uint8_t *)cert;
1776 + cert_der_code.len = cert_size;
1778 + ca_public_key.len = DTLS_PUBLIC_KEY_SIZE;
1779 + ca_public_key.data = ca_pub_key;
1780 + memcpy(ca_public_key.data, ca_pub_x, DTLS_PUBLIC_KEY_SIZE/2);
1781 + memcpy(ca_public_key.data + DTLS_PUBLIC_KEY_SIZE/2, ca_pub_y, DTLS_PUBLIC_KEY_SIZE/2);
1783 + memcpy(x, client_pub_key_x, x_size);
1784 + memcpy(y, client_pub_key_y, y_size);
1786 + ret = (int) check_certificate(cert_der_code, ca_public_key);
1791 +static int is_x509_active(struct dtls_context_t *ctx)
1796 +#endif /* DTLS_X509 */
1799 #define DTLS_SERVER_CMD_CLOSE "server:close"
1800 #define DTLS_SERVER_CMD_RENEGOTIATE "server:renegotiate"
1803 -read_from_peer(struct dtls_context_t *ctx,
1804 +read_from_peer(struct dtls_context_t *ctx,
1805 session_t *session, uint8 *data, size_t len) {
1807 for (i = 0; i < len; i++)
1808 @@ -190,7 +453,7 @@ dtls_handle_read(struct dtls_context_t *ctx) {
1810 dtls_debug("got %d bytes from port %d\n", len,
1811 ntohs(session.addr.sin6.sin6_port));
1812 - if (sizeof(buf) < len) {
1813 + if ((int)(sizeof(buf)) < len) {
1814 dtls_warn("packet was truncated (%d bytes lost)\n", len - sizeof(buf));
1817 @@ -250,13 +513,21 @@ usage(const char *program, const char *version) {
1818 fprintf(stderr, "%s v%s -- DTLS server implementation\n"
1819 "(c) 2011-2014 Olaf Bergmann <bergmann@tzi.org>\n\n"
1820 "usage: %s [-A address] [-p port] [-v num] [-a enable|disable]\n"
1822 + " [-x file] [-r file] [-u file]"
1823 +#endif /* DTLS_X509 */
1824 "\t-A address\t\tlisten on specified address (default is ::)\n"
1825 "\t-p port\t\tlisten on specified port (default is %d)\n"
1826 "\t-v num\t\tverbosity level (default: 3)\n"
1827 "\t-a enable|disable\t(default: disable)\n"
1828 "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n"
1829 - "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n",
1830 - program, version, program, DEFAULT_PORT);
1831 + "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n"
1833 + "\t-x file\tread Server certificate from file\n"
1834 + "\t-r file\tread Server private key from file\n"
1835 + "\t-u file\tread CA public key from file\n"
1836 +#endif /* DTLS_X509 */
1837 + ,program, version, program, DEFAULT_PORT);
1840 static dtls_handler_t cb = {
1841 @@ -268,11 +539,18 @@ static dtls_handler_t cb = {
1842 #endif /* DTLS_PSK */
1844 .get_ecdsa_key = get_ecdsa_key,
1845 - .verify_ecdsa_key = verify_ecdsa_key
1846 + .verify_ecdsa_key = verify_ecdsa_key,
1847 #endif /* DTLS_ECC */
1849 + .get_x509_key = get_x509_key,
1850 + .verify_x509_cert = verify_x509_cert,
1851 + .get_x509_cert = get_x509_cert,
1852 + .is_x509_active = is_x509_active,
1859 main(int argc, char **argv) {
1860 dtls_context_t *the_context = NULL;
1861 log_t log_level = DTLS_LOG_WARN;
1862 @@ -312,6 +590,47 @@ main(int argc, char **argv) {
1863 if( strcmp(optarg, "enable") == 0)
1864 ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
1869 + ssize_t result = read_from_file(optarg, x509_server_cert, DTLS_MAX_CERT_SIZE);
1872 + dtls_warn("Cannot read Server certificate. Using default\n");
1876 + x509_server_cert_len = result;
1882 + ssize_t result = read_from_file(optarg, x509_server_priv, DTLS_PRIVATE_KEY_SIZE+1);
1885 + dtls_warn("Cannot read Server private key. Using default\n");
1889 + x509_server_priv_is_set = result;
1895 + ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
1898 + dtls_warn("Cannot read CA public key. Using default\n");
1902 + x509_ca_pub_is_set = result;
1906 +#endif /* DTLS_X509 */
1908 usage(argv[0], dtls_package_version());
1910 @@ -320,6 +639,23 @@ main(int argc, char **argv) {
1912 dtls_set_log_level(log_level);
1915 + if (x509_server_cert_len && x509_server_priv_is_set && x509_ca_pub_is_set)
1917 + x509_info_from_file = 1;
1919 + else if(!(x509_server_cert_len || x509_server_priv_is_set || x509_ca_pub_is_set))
1921 + x509_info_from_file = 0;
1925 + fprintf(stderr,"please set -x, -r, -u options simultaneously");
1926 + usage(argv[0], dtls_package_version());
1929 +#endif /* DTLS_X509 */
1931 /* init socket and set it to non-blocking */
1932 fd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
1934 diff --git a/extlibs/tinydtls/tinydtls.h b/extlibs/tinydtls/tinydtls.h
1935 index b1b8cdf..dd27c55 100644
1936 --- a/extlibs/tinydtls/tinydtls.h
1937 +++ b/extlibs/tinydtls/tinydtls.h
1939 /** Defined to 1 if tinydtls is built for Contiki OS */
1940 /* #undef WITH_CONTIKI */
1942 +/** Define to 1 if building with X.509 support */
1943 +#define DTLS_X509 1
1945 #endif /* _DTLS_TINYDTLS_H_ */
1946 diff --git a/extlibs/tinydtls/tinydtls.h.in b/extlibs/tinydtls/tinydtls.h.in
1947 index a2e6685..10a8d9a 100644
1948 --- a/extlibs/tinydtls/tinydtls.h.in
1949 +++ b/extlibs/tinydtls/tinydtls.h.in
1951 /** Defined to 1 if tinydtls is built for Contiki OS */
1954 +/** Define to 1 if building with X.509 support */
1957 #endif /* _DTLS_TINYDTLS_H_ */