6baafd8df9c62442e362c301e32562c0902a06a0
[platform/upstream/iotivity.git] / extlibs / tinydtls / 0001-add-support-of-X.509-into-tinyDTLS-external-library.patch
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
5
6 Change-Id: I560506e0c0828674969829c9e900ae08bacaeef1
7 Signed-off-by: Oleksii Udod <o.udod@samsung.com>
8 ---
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(-)
25
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'))
32  
33  root_dir = './'
34 -
35  tinydtls_src_path = root_dir
36  
37  env.AppendUnique(CPPPATH = [root_dir])
38 @@ -62,7 +61,7 @@ tinydtls_src = [
39  env.AppendUnique(TINYDTLS_SRC = tinydtls_src)
40  
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'])
45         else:
46                 env.AppendUnique(CPPDEFINES = ['NDEBUG'])
47 @@ -71,6 +70,7 @@ else:
48  
49  env.AppendUnique(CPPDEFINES = ['DTLSV12',  'WITH_SHA256', 'DTLS_CHECK_CONTENTTYPE'])
50  
51 +
52  libtinydtls = env.StaticLibrary('libtinydtls', env.get('TINYDTLS_SRC'), OBJPREFIX='libtinydtls_')
53  
54  ######################################################################
55 @@ -94,6 +94,7 @@ if not env.get('RELEASE'):
56         samples_env.PrependUnique(LIBS = ['tinydtls'])
57  
58         Alias("samples", [dtlsserver, dtlsclient])
59 +
60         samples_env.AppendTarget('samples')
61  
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])
69     DTLS_PSK=1])
70  
71 +AC_ARG_WITH(x509,
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])
74 +   DTLS_X509=1],
75 +  [])
76 +
77  CPPFLAGS="${CPPFLAGS} -DDTLSv12 -DWITH_SHA256"
78  OPT_OBJS="${OPT_OBJS} sha2/sha2.o"
79  
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,
85  }
86  #endif /* DTLS_PSK */
87  
88 -#ifdef DTLS_ECC
89 +#if defined(DTLS_ECC) || defined(DTLS_X509)
90  
91  int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
92                                  unsigned char *buf) {
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;
100  
101 -#ifdef DTLS_ECC && DTLS_PSK
102 +#if defined(DTLS_ECC) && defined(DTLS_PSK)
103    struct keyx_t {
104      dtls_handshake_parameters_ecc_t ecc;
105      dtls_handshake_parameters_psk_t psk;
106    } keyx;
107  #else /* DTLS_ECC && DTLS_PSK */
108    union {
109 -#ifdef DTLS_ECC
110 +#if defined(DTLS_ECC) || defined(DTLS_X509)
111      dtls_handshake_parameters_ecc_t ecc;
112  #endif /* DTLS_ECC */
113  #ifdef DTLS_PSK
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)
121  {
122 -#ifdef DTLS_ECC
123 +#if defined(DTLS_ECC) || defined(DTLS_X509)
124    return cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
125  #else
126    return 0;
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)
129  {
130  #ifdef DTLS_ECC
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));
134  #else
135    return 0;
136  #endif /* DTLS_ECC */
137  }
138  
139 +/** returns true if the application is configured for x509 */
140 +static inline int is_x509_supported(dtls_context_t *ctx, int is_client)
141 +{
142 +#ifdef DTLS_X509
143 +  return ctx && ctx->h && ((!is_client && ctx->h->get_x509_cert) ||
144 +               (is_client && ctx->h->verify_x509_cert));
145 +#else
146 +  return 0;
147 +#endif /* DTLS_X509 */
148 +}
149 +
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 */
155  }
156  
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)
160 +{
161 +#ifdef DTLS_X509
162 +  return ctx && ctx->h && ctx->h->get_x509_cert && ctx->h->verify_x509_cert;
163 +#else
164 +  return 0;
165 +#endif /* DTLS_X509 */
166 +}
167 +
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)
170  {
171 @@ -586,16 +608,19 @@ known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) {
172    int ecdsa;
173    int ecdh_anon;
174    int ecdhe_psk;
175 +  int x509;
176  
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);
182  
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));
189  }
190  
191  /**
192 @@ -744,7 +769,7 @@ calculate_key_block(dtls_context_t *ctx,
193      break;
194    }
195  #endif /* DTLS_PSK */
196 -#ifdef DTLS_ECC
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);
204  
205 +
206      if (cert_type == TLS_CERT_TYPE_RAW_PUBLIC_KEY)
207 -      return 0;
208 +        return 0;
209 +#ifdef DTLS_X509
210 +    if (cert_type == TLS_CERT_TYPE_X509)
211 +        return 0;
212 +#endif
213    }
214  
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))
218              goto error;
219          } else {
220 +#ifndef DTLS_X509
221           if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
222 +#else
223 +         if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
224 +             (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
225 +#endif
226             goto error;
227          }
228          break;
229 @@ -972,7 +1007,12 @@ dtls_check_tls_extension(dtls_peer_t *peer,
230           if (verify_ext_cert_type(data, j))
231              goto error;
232          } else {
233 +#ifndef DTLS_X509
234           if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
235 +#else
236 +         if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
237 +             (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
238 +#endif
239             goto error;
240          }
241          break;
242 @@ -1138,7 +1178,7 @@ check_client_keyexchange(dtls_context_t *ctx,
243                          dtls_handshake_parameters_t *handshake,
244                          uint8 *data, size_t length) {
245  
246 -#ifdef DTLS_ECC
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) ) {
250  
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 */
254  
255 -
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,
260  #undef mycookie
261  }
262  
263 -#ifdef DTLS_ECC
264 +#if defined(DTLS_ECC) || defined(DTLS_X509)
265  static int
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);
271      p += sizeof(uint16);
272 +#ifdef DTLS_X509
273 +    if (CALL(ctx, is_x509_active) == 0)
274 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
275 +    else
276 +#endif /* DTLS_X509 */
277 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
278  
279 -    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
280      p += sizeof(uint8);
281  
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);
285      p += sizeof(uint16);
286  
287 -    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
288 +#ifdef DTLS_X509
289 +    if (CALL(ctx, is_x509_active) == 0)
290 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
291 +    else
292 +#endif /* DTLS_X509 */
293 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
294 +
295      p += sizeof(uint8);
296  
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];
300    uint8 *p;
301  
302 -  /* Certificate 
303 +  /* Certificate
304     *
305     * Start message construction at beginning of buffer. */
306    p = buf;
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,
309                                  buf, p - buf);
310  }
311 +#endif /* DTLS_ECC */
312 +
313 +#ifdef DTLS_X509
314 +static int
315 +dtls_send_certificate_x509(dtls_context_t *ctx, dtls_peer_t *peer)
316 +{
317 +  uint8 buf[DTLS_MAX_CERT_SIZE];
318 +  uint8 *p;
319 +  int ret;
320 +  unsigned char *cert;
321 +  size_t cert_size;
322 +
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);
326 +
327 +  if (ret < 0) {
328 +    dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
329 +    return ret;
330 +  }
331 +
332 +  /* Certificate
333 +   *
334 +   * Start message construction at beginning of buffer. */
335 +  p = buf;
336 +
337 +  dtls_int_to_uint24(p, cert_size); /* certificates length */
338 +  p += sizeof(uint24);
339 +
340 +  memcpy(p, cert, cert_size);
341 +  p += cert_size;
342 +
343 +  assert(p - buf <= sizeof(buf));
344 +
345 +  return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE,
346 +                                buf, p - buf);
347 +}
348 +#endif /* DTLS_X509 */
349  
350 +#if defined(DTLS_X509) || defined(DTLS_ECC)
351  static uint8 *
352  dtls_add_ecdsa_signature_elem(uint8 *p, uint32_t *point_r, uint32_t *point_s)
353  {
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,
357                DTLS_EC_KEY_SIZE);
358 -
359    if(ecdsa) {
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,
364                                  buf, p - buf);
365  }
366 -#endif /* DTLS_ECC */
367 +#endif /* defined(DTLS_X509) || defined(DTLS_ECC) */
368  
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,
372  }
373  #endif /* DTLS_PSK */
374  
375 -#ifdef DTLS_ECC
376 +#if defined(DTLS_ECC) || defined(DTLS_X509)
377  static int
378  dtls_send_server_certificate_request(dtls_context_t *ctx, dtls_peer_t *peer)
379  {
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);
383  
384 -#ifdef DTLS_ECC
385 +#if defined(DTLS_ECC) || defined(DTLS_X509)
386    if(ecdh_anon) {
387        res = dtls_send_server_key_exchange_ecdh(ctx, peer, NULL);
388  
389 @@ -2413,13 +2501,24 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
390    else if (ecdsa) {
391      const dtls_ecc_key_t *ecdsa_key;
392  
393 -    res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
394 +#ifdef DTLS_X509
395 +    if (CALL(ctx, is_x509_active) == 0)
396 +      res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
397 +    else
398 +#endif /* DTLS_X509 */
399 +      res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
400 +
401      if (res < 0) {
402 -      dtls_crit("no ecdsa certificate to send in certificate\n");
403 +        dtls_debug("no ecdsa key to send\n");
404        return res;
405      }
406  
407 -    res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
408 +#ifdef DTLS_X509
409 +    if (CALL(ctx, is_x509_active) == 0)
410 +      res = dtls_send_certificate_x509(ctx, peer);
411 +    else
412 +#endif /* DTLS_X509 */
413 +      res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
414  
415      if (res < 0) {
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)
418      }
419  
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);
424 -
425        if (res < 0) {
426          dtls_debug("dtls_server_hello(with ECDSA): cannot prepare certificate Request record\n");
427          return res;
428 @@ -2554,7 +2652,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
429      break;
430    }
431  #endif /* DTLS_PSK */
432 -#ifdef DTLS_ECC
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)
438                                  buf, p - buf);
439  }
440  
441 -#ifdef DTLS_ECC
442 +#if defined(DTLS_ECC) || defined(DTLS_X509)
443  static int
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,
447    int ecdsa = 0;
448    int ecdh_anon = 0;
449    int ecdhe_psk = 0;
450 +  int x509 = 0;
451    dtls_handshake_parameters_t *handshake = peer->handshake_params;
452    dtls_tick_t now;
453  
454 @@ -2733,6 +2832,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
455          break;
456        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
457          ecdsa = is_ecdsa_supported(ctx, 1);
458 +        x509 = is_x509_supported(ctx, 1);
459          break;
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);
467          break;
468     }
469  
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;
474  
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);
479      p += sizeof(uint16);
480    }
481 -  if (ecdsa) {
482 +  if (ecdsa || x509) {
483      dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
484      p += sizeof(uint16);
485    }
486 @@ -2821,7 +2922,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
487      p += sizeof(uint16);
488    }
489  
490 -  if (ecdsa) {
491 +  if (ecdsa || x509) {
492      /* client certificate type extension */
493      dtls_int_to_uint16(p, TLS_EXT_CLIENT_CERTIFICATE_TYPE);
494      p += sizeof(uint16);
495 @@ -2834,7 +2935,13 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
496      dtls_int_to_uint8(p, 1);
497      p += sizeof(uint8);
498  
499 -    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
500 +#ifdef DTLS_X509
501 +    if (CALL(ctx, is_x509_active) == 0)
502 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
503 +    else
504 +#endif /* DTLS_X509 */
505 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
506 +
507      p += sizeof(uint8);
508  
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);
512      p += sizeof(uint8);
513  
514 -    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
515 +#ifdef DTLS_X509
516 +    if (CALL(ctx, is_x509_active) == 0)
517 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
518 +    else
519 +#endif /* DTLS_X509 */
520 +      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
521 +
522      p += sizeof(uint8);
523  
524      /* elliptic_curves */
525 @@ -2985,8 +3098,9 @@ check_server_hello_verify_request(dtls_context_t *ctx,
526  }
527  
528  #ifdef DTLS_ECC
529 +
530  static int
531 -check_server_certificate(dtls_context_t *ctx, 
532 +check_peer_certificate(dtls_context_t *ctx,
533                          dtls_peer_t *peer,
534                          uint8 *data, size_t data_length)
535  {
536 @@ -3036,7 +3150,41 @@ check_server_certificate(dtls_context_t *ctx,
537  
538    return 0;
539  }
540 +#endif /* DTLS_ECC */
541 +
542 +#ifdef DTLS_X509
543 +static int
544 +check_peer_certificate_x509(dtls_context_t *ctx,
545 +                        dtls_peer_t *peer,
546 +                        uint8 *data, size_t data_length)
547 +{
548 +  int ret;
549 +  dtls_handshake_parameters_t *config = peer->handshake_params;
550 +  int cert_length;
551 +
552 +  dtls_info("\n check_peer_certificate_x509\n");
553 +  update_hs_hash(peer, data, data_length);
554 +
555 +  assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher));
556 +
557 +  data += DTLS_HS_LENGTH;
558 +
559 +  cert_length = dtls_uint24_to_int(data);
560 +  data += sizeof(uint24);
561 +
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));
565 +  if (ret < 0) {
566 +    dtls_warn("The certificate was not accepted\n");
567 +    return ret;
568 +  }
569 +
570 +  return 0;
571 +}
572 +#endif /* DTLS_X509 */
573  
574 +#if defined(DTLS_X509) || defined(DTLS_ECC)
575  static int
576  check_server_key_exchange_ecdsa(dtls_context_t *ctx,
577                                 dtls_peer_t *peer,
578 @@ -3385,13 +3533,17 @@ check_certificate_request(dtls_context_t *ctx,
579  }
580  
581  static int
582 -check_server_hellodone(dtls_context_t *ctx, 
583 +check_server_hellodone(dtls_context_t *ctx,
584                       dtls_peer_t *peer,
585                       uint8 *data, size_t data_length)
586  {
587 -  int res;
588 +  int res = 0;
589  #ifdef DTLS_ECC
590    const dtls_ecc_key_t *ecdsa_key;
591 +#ifdef DTLS_X509
592 +  unsigned char *cert;
593 +  size_t cert_size;
594 +#endif /* DTLS_X509 */
595  #endif /* DTLS_ECC */
596  
597    dtls_handshake_parameters_t *handshake = peer->handshake_params;
598 @@ -3400,16 +3552,25 @@ check_server_hellodone(dtls_context_t *ctx,
599  
600    update_hs_hash(peer, data, data_length);
601  
602 -#ifdef DTLS_ECC
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) {
605 -
606 -    res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
607 +#ifdef DTLS_X509
608 +    if (CALL(ctx, is_x509_active) == 0)
609 +      res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
610 +    else
611 +#endif /* DTLS_X509 */
612 +      res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
613      if (res < 0) {
614 -      dtls_crit("no ecdsa certificate to send in certificate\n");
615 +      dtls_crit("no ecdsa key to use\n");
616        return res;
617      }
618  
619 -    res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
620 +#ifdef DTLS_X509
621 +    if (CALL(ctx, is_x509_active) == 0)
622 +      res = dtls_send_certificate_x509(ctx, peer);
623 +    else
624 +#endif /* DTLS_X509 */
625 +      res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
626  
627      if (res < 0) {
628        dtls_debug("dtls_server_hello: cannot prepare Certificate record\n");
629 @@ -3428,7 +3589,6 @@ check_server_hellodone(dtls_context_t *ctx,
630  
631  #ifdef DTLS_ECC
632    if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
633 -
634      res = dtls_send_certificate_verify_ecdh(ctx, peer, ecdsa_key);
635  
636      if (res < 0) {
637 @@ -3655,16 +3815,21 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
638  
639      break;
640  
641 -#ifdef DTLS_ECC
642 +#if defined(DTLS_ECC) || defined(DTLS_X509)
643    case DTLS_HT_CERTIFICATE:
644  
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);
648      }
649 -    err = check_server_certificate(ctx, peer, data, data_length);
650 +#ifdef DTLS_X509
651 +    if (CALL(ctx, is_x509_active) == 0)
652 +      err = check_peer_certificate_x509(ctx, peer, data, data_length);
653 +    else
654 +#endif /* DTLS_X509 */
655 +      err = check_peer_certificate(ctx, peer, data, data_length);
656      if (err < 0) {
657 -      dtls_warn("error in check_server_certificate err: %i\n", err);
658 +      dtls_warn("error in check_peer_certificate err: %i\n", err);
659        return err;
660      }
661      if (role == DTLS_CLIENT) {
662 @@ -3679,7 +3844,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
663  
664    case DTLS_HT_SERVER_KEY_EXCHANGE:
665  
666 -#ifdef DTLS_ECC
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);
673  
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
678      else
679        peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; //psk || ecdh_anon
680      break;
681  
682 -#ifdef DTLS_ECC
683 +#if defined(DTLS_ECC) || defined(DTLS_X509)
684    case DTLS_HT_CERTIFICATE_VERIFY:
685  
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,
688        return err;
689      }
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
694      else
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;
702          } else {
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);
707    if (res < 0)
708      dtls_warn("cannot send ClientHello\n");
709 -  else 
710 +  else
711      peer->state = DTLS_STATE_CLIENTHELLO;
712  
713    return res;
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
718 @@ -56,6 +56,10 @@
719  #define DTLS_VERSION 0xfefd    /* DTLS v1.2 */
720  #endif
721  
722 +#ifdef DTLS_X509
723 +#define DTLS_MAX_CERT_SIZE       1400
724 +#endif
725 +
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 {
730     *                session.
731     * @return @c 0 if result is set, or less than zero on error.
732     */
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);
737  
738 +
739    /**
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);
745     */
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,
751                           size_t key_size);
752  #endif /* DTLS_ECC */
753 +#ifdef DTLS_X509
754 +  /**
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.
760 +   *
761 +   * If ECDSA should not be supported, set this pointer to NULL.
762 +   *
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.
767 +   *
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
771 +   *                session.
772 +   * @return @c 0 if result is set, or less than zero on error.
773 +   */
774 +  int (*get_x509_key)(struct dtls_context_t *ctx,
775 +               const session_t *session,
776 +               const dtls_ecc_key_t **result);
777 +  /**
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.
783 +   *
784 +   * If X.509 should not be supported, set this pointer to NULL.
785 +   *
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.
790 +   *
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.
797 +   */
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);
802 +
803 +  /**
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
807 +   * less than zero.
808 +   *
809 +   * If X.509 should not be supported, set this pointer to NULL.
810 +   *
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.
815 +   *
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.
825 +   * error codes:
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);
832 +   */
833 +  int (*verify_x509_cert)(struct dtls_context_t *ctx,
834 +                          const session_t *session,
835 +                          const unsigned char *cert,
836 +                          size_t cert_size,
837 +               unsigned char *x,
838 +                          size_t x_size,
839 +               unsigned char *y,
840 +                          size_t y_size);
841 +
842 +  /**
843 +   * Called during handshake to check if certificate format should be X.509
844 +   *
845 +   * If X.509 should not be supported, set this pointer to NULL.
846 +   *
847 +   * @param ctx       The current dtls context.
848 +   * @return @c 0 if certificate format should be X.509, or less than zero on error.
849 +   */
850 +  int (*is_x509_active)(struct dtls_context_t *ctx);
851 +#endif /* DTLS_X509 */
852  } dtls_handler_t;
853  
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
859 @@ -66,9 +66,27 @@
860  #endif
861  #endif /* CONTIKI */
862  
863 +/* Define if building universal (internal helper macro) */
864 +/* #undef AC_APPLE_UNIVERSAL_BUILD */
865 +
866 +/* Define to 1 if building with X.509 support */
867 +#define DTLS_X509 1
868 +
869 +/* Define to 1 if you have the <arpa/inet.h> header file. */
870 +#define HAVE_ARPA_INET_H 1
871 +
872  /* Define to 1 if you have the <assert.h> header file. */
873  #define HAVE_ASSERT_H 1
874  
875 +/* Define to 1 if you have the <fcntl.h> header file. */
876 +#define HAVE_FCNTL_H 1
877 +
878 +/* Define to 1 if you have the `fls' function. */
879 +/* #undef HAVE_FLS */
880 +
881 +/* Define to 1 if you have the <inttypes.h> header file. */
882 +#define HAVE_INTTYPES_H 1
883 +
884  /* Define to 1 if your system has a GNU libc compatible `malloc' function, and
885     to 0 otherwise. */
886  #define HAVE_MALLOC 1
887 @@ -79,6 +97,21 @@
888  /* Define to 1 if you have the `memset' function. */
889  #define HAVE_MEMSET 1
890  
891 +/* Define to 1 if you have the <netdb.h> header file. */
892 +#define HAVE_NETDB_H 1
893 +
894 +/* Define to 1 if you have the <netinet/in.h> header file. */
895 +#define HAVE_NETINET_IN_H 1
896 +
897 +/* Define to 1 if you have the `select' function. */
898 +#define HAVE_SELECT 1
899 +
900 +/* Define to 1 if struct sockaddr_in6 has a member sin6_len. */
901 +/* #undef HAVE_SOCKADDR_IN6_SIN6_LEN */
902 +
903 +/* Define to 1 if you have the `socket' function. */
904 +#define HAVE_SOCKET 1
905 +
906  /* Define to 1 if you have the <stddef.h> header file. */
907  #define HAVE_STDDEF_H 1
908  
909 @@ -103,9 +136,27 @@
910  /* Define to 1 if you have the `strnlen' function. */
911  #define HAVE_STRNLEN 1
912  
913 +/* Define to 1 if you have the <sys/param.h> header file. */
914 +#define HAVE_SYS_PARAM_H 1
915 +
916 +/* Define to 1 if you have the <sys/socket.h> header file. */
917 +#define HAVE_SYS_SOCKET_H 1
918 +
919 +/* Define to 1 if you have the <sys/stat.h> header file. */
920 +#define HAVE_SYS_STAT_H 1
921 +
922 +/* Define to 1 if you have the <sys/time.h> header file. */
923 +#define HAVE_SYS_TIME_H 1
924 +
925 +/* Define to 1 if you have the <sys/types.h> header file. */
926 +#define HAVE_SYS_TYPES_H 1
927 +
928  /* Define to 1 if you have the <time.h> header file. */
929  #define HAVE_TIME_H 1
930  
931 +/* Define to 1 if you have the <unistd.h> header file. */
932 +#define HAVE_UNISTD_H 1
933 +
934  /* Define to 1 if you have the `vprintf' function. */
935  #define HAVE_VPRINTF 1
936  
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
941 @@ -68,6 +68,9 @@
942  /* Define if building universal (internal helper macro) */
943  #undef AC_APPLE_UNIVERSAL_BUILD
944  
945 +/* Define to 1 if building with X.509 support */
946 +#undef DTLS_X509
947 +
948  /* Define to 1 if you have the <arpa/inet.h> header file. */
949  #undef HAVE_ARPA_INET_H
950  
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 */
958  #ifdef WITH_CONTIKI
959 -#ifdef DTLS_ECC
960 +#if defined(DTLS_ECC) || defined(DTLS_X509)
961  #define DTLS_MAX_BUF 200
962  #else /* DTLS_ECC */
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 */
967  
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 */
972 +
973  
974  #define TLS_EXT_ELLIPTIC_CURVES_SECP256R1      23 /* see RFC 4492 */
975  
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
980 @@ -23,7 +23,7 @@
981   */
982  
983  #ifndef NETQ_MAXCNT
984 -#ifdef DTLS_ECC
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))
996  HEADERS:=
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
1009 @@ -16,9 +16,34 @@
1010  #include <netdb.h>
1011  #include <signal.h>
1012  
1013 -#include "global.h" 
1014 -#include "debug.h" 
1015 -#include "dtls.h" 
1016 +#include "global.h"
1017 +#include "debug.h"
1018 +#include "dtls.h"
1019 +
1020 +/**
1021 + * @struct byte_array
1022 + *
1023 + * General purpose byte array structure.
1024 + *
1025 + * Contains pointer to array of bytes and it's length.
1026 + */
1027 +
1028 +typedef struct
1029 +{
1030 +    uint8_t *data;    /**< Pointer to the byte array */
1031 +    size_t len;      /**< Data size */
1032 +} byte_array;
1033 +
1034 +
1035 +/**@def BYTE_ARRAY_INITIALIZER
1036 + *
1037 + * Initializes of existing byte array pointer to \a NULL.
1038 + */
1039 +#undef BYTE_ARRAY_INITIALIZER
1040 +#define BYTE_ARRAY_INITIALIZER {NULL, 0}
1041 +
1042 +#define DTLS_PRIVATE_KEY_SIZE        (32)
1043 +#define DTLS_PUBLIC_KEY_SIZE         (64)
1044  
1045  #define DEFAULT_PORT 20220
1046  
1047 @@ -26,6 +51,7 @@
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:"
1052  
1053  #ifdef __GNUC__
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;
1058  
1059 +#ifdef DTLS_X509
1060 +#define CLIENT_CRT_LEN 293
1061 +static const unsigned char g_client_certificate[CLIENT_CRT_LEN] = {
1062 +        0x00, 0x01, 0x22,
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,
1099 +        0xbc, 0x8e};
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};
1106 +
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};
1112 +
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};
1118 +
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
1125 +};
1126  
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
1132 +};
1133 +
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};
1140 +
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};
1146 +
1147 +
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;
1154 +
1155 +static int x509_info_from_file = 0;
1156 +#endif /*DTLS_X509*/
1157 +#ifdef DTLS_ECC
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};
1164  
1165 -#ifdef DTLS_PSK
1166 +#endif /*DTLS_ECC*/
1167 +#if defined(DTLS_PSK) || defined(DTLS_X509)
1168  ssize_t
1169  read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) {
1170    FILE *f;
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;
1174    }
1175 -
1176    fclose(f);
1177    return result;
1178  }
1179 -
1180 +#endif /*DTLS_PSK||DTLS_X509*/
1181 +#ifdef DTLS_PSK
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) {
1189 +    (void)ctx;
1190 +    (void)session;
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
1196    };
1197 -
1198    *result = &ecdsa_key;
1199    return 0;
1200  }
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,
1204                  size_t key_size) {
1205 +  (void)ctx;
1206 +  (void)session;
1207 +  (void)other_pub_x;
1208 +  (void)other_pub_y;
1209 +  (void)key_size;
1210    return 0;
1211  }
1212 +
1213  #endif /* DTLS_ECC */
1214  
1215 +#ifdef DTLS_X509
1216 +static int
1217 +get_x509_key(struct dtls_context_t *ctx,
1218 +          const session_t *session,
1219 +          const dtls_ecc_key_t **result) {
1220 +    (void)ctx;
1221 +    (void)session;
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
1227 +  };
1228 +  if (x509_info_from_file)
1229 +      ecdsa_key.priv_key = x509_client_priv;
1230 +  *result = &ecdsa_key;
1231 +  return 0;
1232 +}
1233 +
1234 +static int
1235 +get_x509_cert(struct dtls_context_t *ctx,
1236 +        const session_t *session,
1237 +        const unsigned char **cert,
1238 +        size_t *cert_size)
1239 +{
1240 +    (void)ctx;
1241 +    (void)session;
1242 +    if (x509_info_from_file)
1243 +    {
1244 +        *cert = x509_client_cert;
1245 +        *cert_size = x509_client_cert_len;
1246 +    }
1247 +    else
1248 +    {
1249 +        *cert = g_client_certificate;
1250 +        *cert_size = CLIENT_CRT_LEN;
1251 +    }
1252 +
1253 +    return 0;
1254 +}
1255 +
1256 +int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
1257 +{
1258 +    (void)cert_der_code;
1259 +    (void)ca_public_key;
1260 +    return 0;
1261 +}
1262 +
1263 +static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
1264 +                                  const unsigned char *cert, size_t cert_size,
1265 +                                  unsigned char *x,
1266 +                                  size_t x_size,
1267 +                                  unsigned char *y,
1268 +                                  size_t y_size)
1269 +{
1270 +    int ret;
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];
1276 +    (void)ctx;
1277 +    (void)session;
1278 +
1279 +    if (x509_info_from_file)
1280 +    {
1281 +        ca_pub_x = x509_ca_pub;
1282 +        ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
1283 +    }
1284 +    else
1285 +    {
1286 +        ca_pub_x = x509_ca_pub_x;
1287 +        ca_pub_y = x509_ca_pub_y;
1288 +    }
1289 +
1290 +    cert_der_code.data = (uint8_t *)cert;
1291 +    cert_der_code.len = cert_size;
1292 +
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);
1297 +
1298 +    memcpy(x, serv_pub_key_x, x_size);
1299 +    memcpy(y, serv_pub_key_y, y_size);
1300 +
1301 +    ret = (int) check_certificate(cert_der_code, ca_public_key);
1302 +
1303 +    return -ret;
1304 +}
1305 +
1306 +static int is_x509_active(struct dtls_context_t *ctx)
1307 +{
1308 +    (void)ctx;
1309 +    return 0;
1310 +}
1311 +
1312 +#endif /* DTLS_X509 */
1313 +
1314  static void
1315  try_send(struct dtls_context_t *ctx, session_t *dst) {
1316    int res;
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) {
1320    size_t i;
1321 +  (void)ctx;
1322 +  (void)session;
1323    for (i = 0; i < len; i++)
1324      printf("%c", data[i]);
1325    return 0;
1326 @@ -295,16 +528,24 @@ usage( const char *program, const char *version) {
1327  
1328    fprintf(stderr, "%s v%s -- DTLS client implementation\n"
1329           "(c) 2011-2014 Olaf Bergmann <bergmann@tzi.org>\n\n"
1330 +         "usage: %s"
1331  #ifdef DTLS_PSK
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 */
1337 +#ifdef DTLS_X509
1338 +          " [-x file] [-r file] [-u file]"
1339 +#endif /* DTLS_X509 */
1340 +          " [-o file] [-p port] [-v num] [-c num] addr [port]\n"
1341  #ifdef DTLS_PSK
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 */
1346 +#ifdef DTLS_X509
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 */
1356  #ifdef DTLS_ECC
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 */
1361 +#ifdef DTLS_X509
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 */
1367 +
1368  };
1369  
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 */
1374  
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) {
1377      switch (opt) {
1378  #ifdef DTLS_PSK
1379      case 'i' : {
1380 @@ -396,6 +644,47 @@ main(int argc, char **argv) {
1381        break;
1382      }
1383  #endif /* DTLS_PSK */
1384 +#ifdef DTLS_X509
1385 +    case 'x' :
1386 +    {
1387 +      ssize_t result = read_from_file(optarg, x509_client_cert, DTLS_MAX_CERT_SIZE);
1388 +      if (result < 0)
1389 +      {
1390 +          dtls_warn("Cannot read Client certificate. Using default\n");
1391 +      }
1392 +      else
1393 +      {
1394 +          x509_client_cert_len = result;
1395 +      }
1396 +      break;
1397 +    }
1398 +    case 'r' :
1399 +    {
1400 +      ssize_t result = read_from_file(optarg, x509_client_priv, DTLS_PRIVATE_KEY_SIZE+1);
1401 +      if (result < 0)
1402 +      {
1403 +          dtls_warn("Cannot read Client private key. Using default\n");
1404 +      }
1405 +      else
1406 +      {
1407 +          x509_client_priv_is_set = result;
1408 +      }
1409 +      break;
1410 +    }
1411 +    case 'u' :
1412 +    {
1413 +      ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
1414 +      if (result < 0)
1415 +      {
1416 +          dtls_warn("Cannot read CA public key. Using default\n");
1417 +      }
1418 +      else
1419 +      {
1420 +          x509_ca_pub_is_set = result;
1421 +      }
1422 +      break;
1423 +    }
1424 +#endif /* DTLS_X509 */
1425      case 'p' :
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) {
1429      case 'o' :
1430        output_file.length = strlen(optarg);
1431        output_file.s = (unsigned char *)malloc(output_file.length + 1);
1432 -      
1433 +
1434        if (!output_file.s) {
1435         dtls_crit("cannot set output file: insufficient memory\n");
1436         exit(-1);
1437 @@ -444,12 +733,29 @@ main(int argc, char **argv) {
1438    }
1439  
1440    dtls_set_log_level(log_level);
1441 -  
1442 +
1443    if (argc <= optind) {
1444      usage(argv[0], dtls_package_version());
1445      exit(1);
1446    }
1447 -  
1448 +
1449 +#ifdef DTLS_X509
1450 +  if (x509_client_cert_len && x509_client_priv_is_set && x509_ca_pub_is_set)
1451 +  {
1452 +      x509_info_from_file = 1;
1453 +  }
1454 +  else if(!(x509_client_cert_len || x509_client_priv_is_set || x509_ca_pub_is_set))
1455 +  {
1456 +      x509_info_from_file = 0;
1457 +  }
1458 +  else
1459 +  {
1460 +      fprintf(stderr,"please set -x, -r, -u options simultaneously");
1461 +      usage(argv[0], dtls_package_version());
1462 +      exit(1);
1463 +  }
1464 +#endif /* DTLS_X509 */
1465 +
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 @@
1474  #include <netdb.h>
1475  #include <signal.h>
1476  
1477 -#include "tinydtls.h" 
1478 -#include "dtls.h" 
1479 -#include "debug.h" 
1480 +#include "tinydtls.h"
1481 +#include "dtls.h"
1482 +#include "debug.h"
1483 +
1484 +#ifdef DTLS_X509
1485 +#define DTLS_PRIVATE_KEY_SIZE        (32)
1486 +#define DTLS_PUBLIC_KEY_SIZE         (64)
1487 +#endif
1488  
1489  #define DEFAULT_PORT 20220
1490  
1491 +/**
1492 + * @struct byte_array
1493 + *
1494 + * General purpose byte array structure.
1495 + *
1496 + * Contains pointer to array of bytes and it's length.
1497 + */
1498 +
1499 +typedef struct
1500 +{
1501 +    uint8_t *data;    /**< Pointer to the byte array */
1502 +    size_t len;      /**< Data size */
1503 +} byte_array;
1504 +
1505 +
1506 +/**@def BYTE_ARRAY_INITIALIZER
1507 + *
1508 + * Initializes of existing byte array pointer to \a NULL.
1509 + */
1510 +#undef BYTE_ARRAY_INITIALIZER
1511 +#define BYTE_ARRAY_INITIALIZER {NULL, 0}
1512 +
1513 +#ifdef DTLS_X509
1514 +#define X509_OPTIONS         "x:r:u:"
1515 +#define SERVER_CRT_LEN 295
1516 +static const unsigned char g_server_certificate[SERVER_CRT_LEN] = {
1517 +        0x00, 0x01, 0x24,
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};
1555 +
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};
1562 +
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};
1568 +
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};
1574 +
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
1581 +};
1582 +
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
1588 +};
1589 +
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};
1595 +
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};
1601 +
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;
1608 +
1609 +static int x509_info_from_file = 0;
1610 +#endif /*DTLS_X509*/
1611 +#ifdef DTLS_ECC
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};
1619 -
1620 +#endif /*DTLS_ECC*/
1621  #if 0
1622  /* SIGINT handler: set quit to 1 for graceful termination */
1623  void
1624 @@ -46,6 +172,34 @@ handle_sigint(int signum) {
1625  }
1626  #endif
1627  
1628 +#ifdef DTLS_X509
1629 +ssize_t
1630 +read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) {
1631 +  FILE *f;
1632 +  ssize_t result = 0;
1633 +
1634 +  f = fopen(arg, "r");
1635 +  if (f == NULL)
1636 +    return -1;
1637 +
1638 +  while (!feof(f)) {
1639 +    size_t bytes_read;
1640 +    bytes_read = fread(buf, 1, max_buf_len, f);
1641 +    if (ferror(f)) {
1642 +      result = -1;
1643 +      break;
1644 +    }
1645 +
1646 +    buf += bytes_read;
1647 +    result += bytes_read;
1648 +    max_buf_len -= bytes_read;
1649 +  }
1650 +
1651 +  fclose(f);
1652 +  return result;
1653 +}
1654 +#endif /*DTLS_X509*/
1655 +
1656  #ifdef DTLS_PSK
1657  
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) {
1662  
1663 +  (void)ctx;
1664 +  (void)session;
1665    struct keymap_t {
1666      unsigned char *id;
1667      size_t id_length;
1668 @@ -86,7 +242,7 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session,
1669    case DTLS_PSK_KEY:
1670      if (id) {
1671        int i;
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) {
1681 +    (void)ctx;
1682 +    (void)session;
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,
1689                  size_t key_size) {
1690 +  (void)ctx;
1691 +  (void)session;
1692 +  (void)other_pub_x;
1693 +  (void)other_pub_y;
1694 +  (void)key_size;
1695    return 0;
1696  }
1697  #endif /* DTLS_ECC */
1698  
1699 +#ifdef DTLS_X509
1700 +static int
1701 +get_x509_key(struct dtls_context_t *ctx,
1702 +          const session_t *session,
1703 +          const dtls_ecc_key_t **result) {
1704 +    (void)ctx;
1705 +    (void)session;
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
1711 +  };
1712 +  if (x509_info_from_file)
1713 +      ecdsa_key.priv_key = x509_server_priv;
1714 +
1715 +  *result = &ecdsa_key;
1716 +  return 0;
1717 +}
1718 +
1719 +static int
1720 +get_x509_cert(struct dtls_context_t *ctx,
1721 +               const session_t *session,
1722 +               const unsigned char **cert,
1723 +               size_t *cert_size)
1724 +{
1725 +    (void)ctx;
1726 +    (void)session;
1727 +    if (x509_info_from_file)
1728 +    {
1729 +        *cert = x509_server_cert;
1730 +        *cert_size = x509_server_cert_len;
1731 +    }
1732 +    else
1733 +    {
1734 +        *cert = g_server_certificate;
1735 +        *cert_size = SERVER_CRT_LEN;
1736 +    }
1737 +
1738 +    return 0;
1739 +}
1740 +
1741 +static int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
1742 +{
1743 +    (void)cert_der_code;
1744 +    (void)ca_public_key;
1745 +    return 0;
1746 +}
1747 +
1748 +static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
1749 +                                  const unsigned char *cert, size_t cert_size,
1750 +                                  unsigned char *x,
1751 +                                  size_t x_size,
1752 +                                  unsigned char *y,
1753 +                                  size_t y_size)
1754 +{
1755 +    int ret;
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];
1761 +    (void)ctx;
1762 +    (void)session;
1763 +
1764 +    if (x509_info_from_file)
1765 +    {
1766 +        ca_pub_x = x509_ca_pub;
1767 +        ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
1768 +    }
1769 +    else
1770 +    {
1771 +        ca_pub_x = x509_ca_pub_x;
1772 +        ca_pub_y = x509_ca_pub_y;
1773 +    }
1774 +
1775 +    cert_der_code.data = (uint8_t *)cert;
1776 +    cert_der_code.len = cert_size;
1777 +
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);
1782 +
1783 +    memcpy(x, client_pub_key_x, x_size);
1784 +    memcpy(y, client_pub_key_y, y_size);
1785 +
1786 +    ret = (int) check_certificate(cert_der_code, ca_public_key);
1787 +
1788 +  return -ret;
1789 +}
1790 +
1791 +static int is_x509_active(struct dtls_context_t *ctx)
1792 +{
1793 +    (void)ctx;
1794 +    return 0;
1795 +}
1796 +#endif /* DTLS_X509 */
1797 +
1798 +
1799  #define DTLS_SERVER_CMD_CLOSE "server:close"
1800  #define DTLS_SERVER_CMD_RENEGOTIATE "server:renegotiate"
1801  
1802  static int
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) {
1806    size_t i;
1807    for (i = 0; i < len; i++)
1808 @@ -190,7 +453,7 @@ dtls_handle_read(struct dtls_context_t *ctx) {
1809    } else {
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));
1815      }
1816    }
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"
1821 +#ifdef DTLS_X509
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"
1832 +#ifdef DTLS_X509
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);
1838  }
1839  
1840  static dtls_handler_t cb = {
1841 @@ -268,11 +539,18 @@ static dtls_handler_t cb = {
1842  #endif /* DTLS_PSK */
1843  #ifdef DTLS_ECC
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 */
1848 +#ifdef DTLS_X509
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,
1853 +#endif
1854 +
1855  };
1856  
1857 -int 
1858 +int
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;
1865        break;
1866 +#ifdef DTLS_X509
1867 +    case 'x' :
1868 +    {
1869 +      ssize_t result = read_from_file(optarg, x509_server_cert, DTLS_MAX_CERT_SIZE);
1870 +      if (result < 0)
1871 +      {
1872 +          dtls_warn("Cannot read Server certificate. Using default\n");
1873 +      }
1874 +      else
1875 +      {
1876 +          x509_server_cert_len = result;
1877 +      }
1878 +      break;
1879 +    }
1880 +    case 'r' :
1881 +    {
1882 +      ssize_t result = read_from_file(optarg, x509_server_priv, DTLS_PRIVATE_KEY_SIZE+1);
1883 +      if (result < 0)
1884 +      {
1885 +          dtls_warn("Cannot read Server private key. Using default\n");
1886 +      }
1887 +      else
1888 +      {
1889 +          x509_server_priv_is_set = result;
1890 +      }
1891 +      break;
1892 +    }
1893 +    case 'u' :
1894 +    {
1895 +      ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
1896 +      if (result < 0)
1897 +      {
1898 +          dtls_warn("Cannot read CA public key. Using default\n");
1899 +      }
1900 +      else
1901 +      {
1902 +          x509_ca_pub_is_set = result;
1903 +      }
1904 +      break;
1905 +    }
1906 +#endif /* DTLS_X509 */
1907      default:
1908        usage(argv[0], dtls_package_version());
1909        exit(1);
1910 @@ -320,6 +639,23 @@ main(int argc, char **argv) {
1911  
1912    dtls_set_log_level(log_level);
1913  
1914 +#ifdef DTLS_X509
1915 +  if (x509_server_cert_len && x509_server_priv_is_set && x509_ca_pub_is_set)
1916 +  {
1917 +      x509_info_from_file = 1;
1918 +  }
1919 +  else if(!(x509_server_cert_len || x509_server_priv_is_set || x509_ca_pub_is_set))
1920 +  {
1921 +      x509_info_from_file = 0;
1922 +  }
1923 +  else
1924 +  {
1925 +      fprintf(stderr,"please set -x, -r, -u options simultaneously");
1926 +      usage(argv[0], dtls_package_version());
1927 +      exit(1);
1928 +  }
1929 +#endif /* DTLS_X509 */
1930 +
1931    /* init socket and set it to non-blocking */
1932    fd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
1933  
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
1938 @@ -42,4 +42,7 @@
1939  /** Defined to 1 if tinydtls is built for Contiki OS */
1940  /* #undef WITH_CONTIKI */
1941  
1942 +/** Define to 1 if building with X.509 support */
1943 +#define DTLS_X509 1
1944 +
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
1950 @@ -41,4 +41,7 @@
1951  /** Defined to 1 if tinydtls is built for Contiki OS */
1952  #undef WITH_CONTIKI
1953  
1954 +/** Define to 1 if building with X.509 support */
1955 +#undef DTLS_X509
1956 +
1957  #endif /* _DTLS_TINYDTLS_H_ */
1958 -- 
1959 1.9.1
1960