2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions
5 * 1. Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * 3. Neither the name of the Institute nor the names of its contributors
11 * may be used to endorse or promote products derived from this software
12 * without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * This file is part of the Contiki operating system.
31 #include "contiki-lib.h"
32 #include "contiki-net.h"
35 #include "net/rpl/rpl.h"
36 #endif /* UIP_CONF_IPV6_RPL */
43 #define DEBUG DEBUG_PRINT
45 #include "net/ip/uip-debug.h"
50 #ifdef ENABLE_POWERTRACE
51 #include "powertrace.h"
54 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
55 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
57 #define MAX_PAYLOAD_LEN 120
59 static struct uip_udp_conn *server_conn;
61 static dtls_context_t *dtls_context;
63 static const unsigned char ecdsa_priv_key[] = {
64 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05,
65 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF,
66 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70,
67 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4};
69 static const unsigned char ecdsa_pub_key_x[] = {
70 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06,
71 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A,
72 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2,
73 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A};
75 static const unsigned char ecdsa_pub_key_y[] = {
76 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA,
77 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31,
78 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D,
79 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70};
82 read_from_peer(struct dtls_context_t *ctx,
83 session_t *session, uint8 *data, size_t len) {
85 for (i = 0; i < len; i++)
86 PRINTF("%c", data[i]);
88 /* echo incoming application data */
89 dtls_write(ctx, session, data, len);
94 send_to_peer(struct dtls_context_t *ctx,
95 session_t *session, uint8 *data, size_t len) {
97 struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx);
99 uip_ipaddr_copy(&conn->ripaddr, &session->addr);
100 conn->rport = session->port;
103 PRINT6ADDR(&conn->ripaddr);
104 PRINTF(":%u\n", uip_ntohs(conn->rport));
106 uip_udp_packet_send(conn, data, len);
108 /* Restore server connection to allow data from any node */
109 memset(&conn->ripaddr, 0, sizeof(conn->ripaddr));
110 memset(&conn->rport, 0, sizeof(conn->rport));
116 /* This function is the "key store" for tinyDTLS. It is called to
117 * retrieve a key for the given identity within this particular
120 get_psk_info(struct dtls_context_t *ctx, const session_t *session,
121 dtls_credentials_type_t type,
122 const unsigned char *id, size_t id_len,
123 unsigned char *result, size_t result_length) {
131 { (unsigned char *)"Client_identity", 15,
132 (unsigned char *)"secretPSK", 9 },
133 { (unsigned char *)"default identity", 16,
134 (unsigned char *)"\x11\x22\x33", 3 },
135 { (unsigned char *)"\0", 2,
136 (unsigned char *)"", 1 }
139 if (type != DTLS_PSK_KEY) {
145 for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) {
146 if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) {
147 if (result_length < psk[i].key_length) {
148 dtls_warn("buffer too small for PSK");
149 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
152 memcpy(result, psk[i].key, psk[i].key_length);
153 return psk[i].key_length;
158 return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR);
160 #endif /* DTLS_PSK */
164 get_ecdsa_key(struct dtls_context_t *ctx,
165 const session_t *session,
166 const dtls_ecdsa_key_t **result) {
167 static const dtls_ecdsa_key_t ecdsa_key = {
168 .curve = DTLS_ECDH_CURVE_SECP256R1,
169 .priv_key = ecdsa_priv_key,
170 .pub_key_x = ecdsa_pub_key_x,
171 .pub_key_y = ecdsa_pub_key_y
174 *result = &ecdsa_key;
179 verify_ecdsa_key(struct dtls_context_t *ctx,
180 const session_t *session,
181 const unsigned char *other_pub_x,
182 const unsigned char *other_pub_y,
186 #endif /* DTLS_ECC */
188 PROCESS(udp_server_process, "UDP server process");
189 AUTOSTART_PROCESSES(&udp_server_process);
190 /*---------------------------------------------------------------------------*/
192 dtls_handle_read(dtls_context_t *ctx) {
196 uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr);
197 session.port = UIP_UDP_BUF->srcport;
198 session.size = sizeof(session.addr) + sizeof(session.port);
200 dtls_handle_message(ctx, &session, uip_appdata, uip_datalen());
203 /*---------------------------------------------------------------------------*/
205 print_local_addresses(void)
210 PRINTF("Server IPv6 addresses: \n");
211 for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
212 state = uip_ds6_if.addr_list[i].state;
213 if(uip_ds6_if.addr_list[i].isused &&
214 (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
215 PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
223 create_rpl_dag(uip_ipaddr_t *ipaddr)
225 struct uip_ds6_addr *root_if;
227 root_if = uip_ds6_addr_lookup(ipaddr);
228 if(root_if != NULL) {
232 rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr);
233 dag = rpl_get_any_dag();
234 uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
235 rpl_set_prefix(dag, &prefix, 64);
236 PRINTF("created a new RPL dag\n");
238 PRINTF("failed to create a new RPL DAG\n");
245 static dtls_handler_t cb = {
246 .write = send_to_peer,
247 .read = read_from_peer,
250 .get_psk_info = get_psk_info,
251 #endif /* DTLS_PSK */
253 .get_ecdsa_key = get_ecdsa_key,
254 .verify_ecdsa_key = verify_ecdsa_key
255 #endif /* DTLS_ECC */
259 /* struct uip_ds6_addr *root_if; */
260 #endif /* UIP_CONF_ROUTER */
262 PRINTF("DTLS server started\n");
265 memset(&tmp_addr, 0, sizeof(rimeaddr_t));
266 if(get_eui64_from_eeprom(tmp_addr.u8));
268 memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8);
273 /* uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); */
274 /* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */
275 /* uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); */
277 /* create_rpl_dag(&ipaddr); */
279 /* uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); */
281 uip_ip6addr(&ipaddr, 0xaaaa, 0,0,0,0x0200,0,0,0x0003);
282 uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
284 create_rpl_dag(&ipaddr);
285 #endif /* UIP_CONF_ROUTER */
287 server_conn = udp_new(NULL, 0, NULL);
288 udp_bind(server_conn, UIP_HTONS(20220));
290 dtls_set_log_level(DTLS_LOG_DEBUG);
292 dtls_context = dtls_new_context(server_conn);
294 dtls_set_handler(dtls_context, &cb);
297 /*---------------------------------------------------------------------------*/
298 PROCESS_THREAD(udp_server_process, ev, data)
305 print_local_addresses();
308 dtls_emerg("cannot create context\n");
312 #ifdef ENABLE_POWERTRACE
313 powertrace_start(CLOCK_SECOND * 2);
317 PROCESS_WAIT_EVENT();
318 if(ev == tcpip_event) {
319 dtls_handle_read(dtls_context);
322 if (bytes_read > 0) {
323 /* dtls_handle_message(dtls_context, &the_session, readbuf, bytes_read); */
324 read_from_peer(dtls_context, &the_session, readbuf, bytes_read);
326 dtls_handle_message(ctx, &session, uip_appdata, bytes_read);
332 /*---------------------------------------------------------------------------*/