PageRenderTime 33ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/net/ip/tinydtls/tests/secure-server.c

https://gitlab.com/david.furminieux/zephyr-os
C | 862 lines | 670 code | 132 blank | 60 comment | 125 complexity | 8d616f4ac6679dfb9ab6a5fdc853a340 MD5 | raw file
  1. /* secure-server -- A (broken) DTLS server example
  2. *
  3. * Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
  4. *
  5. * Permission is hereby granted, free of charge, to any person
  6. * obtaining a copy of this software and associated documentation
  7. * files (the "Software"), to deal in the Software without
  8. * restriction, including without limitation the rights to use, copy,
  9. * modify, merge, publish, distribute, sublicense, and/or sell copies
  10. * of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  20. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  21. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. */
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #include <fcntl.h>
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <sys/select.h>
  32. #include <sys/types.h>
  33. #include <sys/socket.h>
  34. #include <netinet/in.h>
  35. #include <arpa/inet.h>
  36. #include <netdb.h>
  37. #include <sys/stat.h>
  38. #include <errno.h>
  39. #include <signal.h>
  40. #include <openssl/ssl.h>
  41. #include <openssl/bio.h>
  42. #include <openssl/err.h>
  43. #include <openssl/rand.h>
  44. #ifdef WITH_DTLS
  45. #define SERVER_CERT_PEM "./server-cert.pem"
  46. #define SERVER_KEY_PEM "./server-key.pem"
  47. #define CA_CERT_PEM "./ca-cert.pem"
  48. #endif
  49. #ifdef HAVE_ASSERT_H
  50. # include <assert.h>
  51. #else
  52. # define assert(x)
  53. #endif /* HAVE_ASSERT_H */
  54. static int quit=0;
  55. /* SIGINT handler: set quit to 1 for graceful termination */
  56. void
  57. handle_sigint(int signum) {
  58. quit = 1;
  59. }
  60. int
  61. check_connect(int sockfd, char *buf, int buflen,
  62. struct sockaddr *src, int *ifindex) {
  63. /* for some reason, the definition in netinet/in.h is not exported */
  64. #ifndef IN6_PKTINFO
  65. struct in6_pktinfo
  66. {
  67. struct in6_addr ipi6_addr; /* src/dst IPv6 address */
  68. unsigned int ipi6_ifindex; /* send/recv interface index */
  69. };
  70. #endif
  71. size_t bytes;
  72. struct iovec iov[1] = { {buf, buflen} };
  73. char cmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
  74. struct in6_pktinfo *p = NULL;
  75. struct msghdr msg = { 0 };
  76. struct cmsghdr *cmsg;
  77. msg.msg_name = src;
  78. msg.msg_namelen = sizeof(struct sockaddr_in6);
  79. msg.msg_iov = iov;
  80. msg.msg_iovlen = 1;
  81. msg.msg_control = cmsgbuf;
  82. msg.msg_controllen = sizeof(cmsgbuf);
  83. bytes = recvmsg(sockfd, &msg, MSG_DONTWAIT | MSG_PEEK);
  84. if (bytes < 0) {
  85. perror("recvmsg");
  86. return bytes;
  87. }
  88. /* TODO: handle msg.msg_flags & MSG_TRUNC */
  89. if (msg.msg_flags & MSG_CTRUNC) {
  90. fprintf(stderr, "control was truncated!\n");
  91. return -1;
  92. }
  93. if (ifindex) {
  94. /* Here we try to retrieve the interface index where the packet was received */
  95. *ifindex = 0;
  96. for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
  97. cmsg = CMSG_NXTHDR(&msg, cmsg)) {
  98. if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
  99. p = (struct in6_pktinfo *)(CMSG_DATA(cmsg));
  100. *ifindex = p->ipi6_ifindex;
  101. break;
  102. }
  103. }
  104. }
  105. return bytes;
  106. }
  107. typedef enum { UNKNOWN=0, DTLS=1 } protocol_t;
  108. protocol_t
  109. demux_protocol(const char *buf, int len) {
  110. return DTLS;
  111. }
  112. #ifdef WITH_DTLS
  113. typedef enum {
  114. PEER_ST_ESTABLISHED, PEER_ST_PENDING, PEER_ST_CLOSED
  115. } peer_state_t;
  116. typedef struct {
  117. peer_state_t state;
  118. unsigned long h;
  119. SSL *ssl;
  120. } ssl_peer_t;
  121. #define MAX_SSL_PENDING 2 /* must be less than MAX_SSL_PEERS */
  122. #define MAX_SSL_PEERS 10 /* MAX_SSL_PENDING of these might be pending */
  123. ssl_peer_t *ssl_peer_storage[MAX_SSL_PEERS];
  124. static int pending = 0;
  125. void
  126. check_peers() {
  127. typedef struct bio_dgram_data_st
  128. {
  129. union {
  130. struct sockaddr sa;
  131. struct sockaddr_in sa_in;
  132. struct sockaddr_in6 sa_in6;
  133. } peer;
  134. unsigned int connected;
  135. unsigned int _errno;
  136. unsigned int mtu;
  137. struct timeval next_timeout;
  138. struct timeval socket_timeout;
  139. } bio_dgram_data;
  140. struct sockaddr_in6 peer;
  141. int i;
  142. BIO *bio;
  143. for (i = 0; i < MAX_SSL_PEERS; i++) {
  144. if (ssl_peer_storage[i]) {
  145. if (!ssl_peer_storage[i]->ssl)
  146. fprintf(stderr, "invalid SSL object for peer %d!\n",i);
  147. else {
  148. bio = SSL_get_rbio(ssl_peer_storage[i]->ssl);
  149. if (bio) {
  150. (void) BIO_dgram_get_peer(bio, (struct sockaddr *)&peer);
  151. if (peer.sin6_port && ssl_peer_storage[i]->h != ntohs(peer.sin6_port)) {
  152. fprintf(stderr, " bio %p: port differs from hash: %d != %d! (%sconnected)\n", bio,
  153. ssl_peer_storage[i]->h,
  154. ntohs(((struct sockaddr_in6 *)&peer)->sin6_port),
  155. ((bio_dgram_data *)bio->ptr)->connected ? "" : "not ");
  156. }
  157. }
  158. }
  159. }
  160. }
  161. }
  162. /** Creates a hash value from the first num bytes of s, taking init as
  163. * initialization value. */
  164. static inline unsigned long
  165. _hash(unsigned long init, const char *s, int num) {
  166. int c;
  167. while (num--)
  168. while ( (c = *s++) ) {
  169. init = ((init << 7) + init) + c;
  170. }
  171. return init;
  172. }
  173. static inline unsigned long
  174. hash_peer(const struct sockaddr *peer, int ifindex) {
  175. unsigned long h;
  176. /* initialize hash value to interface index */
  177. h = _hash(0, (char *)&ifindex, sizeof(int));
  178. #define CAST(TYPE,VAR) ((TYPE)VAR)
  179. assert(peer);
  180. switch (peer->sa_family) {
  181. case AF_INET:
  182. return ntohs(CAST(const struct sockaddr_in *, peer)->sin_port);
  183. h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_addr,
  184. sizeof(struct in_addr));
  185. h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_port,
  186. sizeof(in_port_t));
  187. break;
  188. case AF_INET6:
  189. return ntohs(CAST(const struct sockaddr_in6 *, peer)->sin6_port);
  190. h = _hash(h,
  191. (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_addr,
  192. sizeof(struct in6_addr));
  193. h = _hash(h,
  194. (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_port,
  195. sizeof(in_port_t));
  196. break;
  197. default:
  198. /* last resort */
  199. h = _hash(h, (char *)peer, sizeof(struct sockaddr));
  200. }
  201. return 42;
  202. return h;
  203. }
  204. /* Returns index of peer object for specified address/ifindex pair. */
  205. int
  206. get_index_of_peer(const struct sockaddr *peer, int ifindex) {
  207. unsigned long h;
  208. int idx;
  209. #ifndef NDEBUG
  210. char addr[INET6_ADDRSTRLEN];
  211. char port[6];
  212. #endif
  213. if (!peer)
  214. return -1;
  215. h = hash_peer(peer,ifindex);
  216. for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
  217. if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->h == h) {
  218. #ifndef NDEBUG
  219. getnameinfo((struct sockaddr *)peer, sizeof(struct sockaddr_in6),
  220. addr, sizeof(addr), port, sizeof(port),
  221. NI_NUMERICHOST | NI_NUMERICSERV);
  222. fprintf(stderr, "get_index_of_peer: [%s]:%s => %lu\n",
  223. addr, port, h);
  224. #endif
  225. return idx;
  226. }
  227. }
  228. return -1;
  229. }
  230. SSL *
  231. get_ssl(SSL_CTX *ctx, int sockfd, struct sockaddr *src, int ifindex) {
  232. int idx;
  233. BIO *bio;
  234. SSL *ssl;
  235. #ifndef NDEBUG
  236. struct sockaddr_storage peer;
  237. char addr[INET6_ADDRSTRLEN];
  238. char port[6];
  239. int i;
  240. #endif
  241. idx = get_index_of_peer(src,ifindex);
  242. if (idx >= 0) {
  243. fprintf(stderr,"found peer %d ",idx);
  244. switch (ssl_peer_storage[idx]->state) {
  245. case PEER_ST_ESTABLISHED: fprintf(stderr,"established\n"); break;
  246. case PEER_ST_PENDING: fprintf(stderr,"pending\n"); break;
  247. case PEER_ST_CLOSED: fprintf(stderr,"closed\n"); break;
  248. default:
  249. OPENSSL_assert(0);
  250. }
  251. #ifndef NDEBUG
  252. memset(&peer, 0, sizeof(peer));
  253. (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer);
  254. getnameinfo((struct sockaddr *)&peer, sizeof(peer),
  255. addr, sizeof(addr), port, sizeof(port),
  256. NI_NUMERICHOST | NI_NUMERICSERV);
  257. fprintf(stderr," [%s]:%s \n", addr, port);
  258. #endif
  259. return ssl_peer_storage[idx]->ssl;
  260. }
  261. /* none found, create new if sufficient space available */
  262. if (pending < MAX_SSL_PENDING) {
  263. for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
  264. if (ssl_peer_storage[idx] == NULL) { /* found space */
  265. ssl = SSL_new(ctx);
  266. if (ssl) {
  267. bio = BIO_new_dgram(sockfd, BIO_NOCLOSE);
  268. if (!bio) {
  269. SSL_free(ssl);
  270. return NULL;
  271. }
  272. SSL_set_bio(ssl, bio, bio);
  273. SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
  274. SSL_set_accept_state(ssl);
  275. ssl_peer_storage[idx] = (ssl_peer_t *) malloc(sizeof(ssl_peer_t));
  276. if (!ssl_peer_storage[idx]) {
  277. SSL_free(ssl);
  278. return NULL;
  279. }
  280. ssl_peer_storage[idx]->state = PEER_ST_PENDING;
  281. ssl_peer_storage[idx]->h = hash_peer(src,ifindex);
  282. ssl_peer_storage[idx]->ssl = ssl;
  283. pending++;
  284. fprintf(stderr,
  285. "created new SSL peer %d for ssl object %p (storage: %p)\n",
  286. idx, ssl, ssl_peer_storage[idx]);
  287. #ifndef NDEBUG
  288. if (getnameinfo((struct sockaddr *)&src, sizeof(src),
  289. addr, sizeof(addr), port, sizeof(port),
  290. NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
  291. perror("getnameinfo");
  292. fprintf(stderr, "port was %u\n", ntohs(((struct sockaddr_in6 *)src)->sin6_port));
  293. } else {
  294. fprintf(stderr," [%s]:%s \n", addr, port);
  295. }
  296. #endif
  297. OPENSSL_assert(ssl_peer_storage[idx]->ssl == ssl);
  298. fprintf(stderr,"%d objects pending\n", pending);
  299. check_peers();
  300. return ssl;
  301. }
  302. }
  303. }
  304. } else {
  305. fprintf(stderr, "too many pending SSL objects\n");
  306. return NULL;
  307. }
  308. fprintf(stderr, "too many peers\n");
  309. return NULL;
  310. }
  311. /** Deletes peer stored at index idx and frees allocated memory. */
  312. static inline void
  313. delete_peer(int idx) {
  314. if (idx < 0 || !ssl_peer_storage[idx])
  315. return;
  316. if (ssl_peer_storage[idx]->state == PEER_ST_PENDING)
  317. pending--;
  318. OPENSSL_assert(ssl_peer_storage[idx]->ssl);
  319. SSL_free(ssl_peer_storage[idx]->ssl);
  320. free(ssl_peer_storage[idx]);
  321. ssl_peer_storage[idx] = NULL;
  322. printf("deleted peer %d\n",idx);
  323. }
  324. /** Deletes all closed objects from ssl_peer_storage. */
  325. void
  326. remove_closed() {
  327. int idx;
  328. for (idx = 0; idx < MAX_SSL_PEERS; idx++)
  329. if (ssl_peer_storage[idx]
  330. && ssl_peer_storage[idx]->state == PEER_ST_CLOSED)
  331. delete_peer(idx);
  332. }
  333. #define min(a,b) ((a) < (b) ? (a) : (b))
  334. unsigned int
  335. psk_server_callback(SSL *ssl, const char *identity,
  336. unsigned char *psk, unsigned int max_psk_len) {
  337. static char keybuf[] = "secretPSK";
  338. printf("psk_server_callback: check identity of client %s\n", identity);
  339. memcpy(psk, keybuf, min(strlen(keybuf), max_psk_len));
  340. return min(strlen(keybuf), max_psk_len);
  341. }
  342. #endif
  343. #ifdef WITH_DTLS
  344. /**
  345. * This function tracks the status changes from libssl to manage local
  346. * object state.
  347. */
  348. void
  349. info_callback(const SSL *ssl, int where, int ret) {
  350. int idx, i;
  351. struct sockaddr_storage peer;
  352. struct sockaddr_storage peer2;
  353. char addr[INET6_ADDRSTRLEN];
  354. char port[6];
  355. if (where & SSL_CB_LOOP) /* do not care for intermediary states */
  356. return;
  357. memset(&peer, 0, sizeof(peer));
  358. (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
  359. /* lookup SSL object */ /* FIXME: need to get the ifindex */
  360. idx = get_index_of_peer((struct sockaddr *)&peer, 0);
  361. if (idx >= 0)
  362. fprintf(stderr, "info_callback: assert: %d < 0 || %p == %p (storage: %p)\n",
  363. idx, ssl, ssl_peer_storage[idx]->ssl, ssl_peer_storage[idx]);
  364. if (idx >= 0 && ssl != ssl_peer_storage[idx]->ssl) {
  365. getnameinfo((struct sockaddr *)&peer, sizeof(peer),
  366. addr, sizeof(addr), port, sizeof(port),
  367. NI_NUMERICHOST | NI_NUMERICSERV);
  368. fprintf(stderr," ssl: [%s]:%s ", addr, port);
  369. (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer2);
  370. getnameinfo((struct sockaddr *)&peer2, sizeof(peer2),
  371. addr, sizeof(addr), port, sizeof(port),
  372. NI_NUMERICHOST | NI_NUMERICSERV);
  373. fprintf(stderr," ssl_peer_storage[idx]->ssl: [%s]:%s\n", addr, port);
  374. fprintf(stderr, " hash:%lu h: %lu\n",
  375. hash_peer((const struct sockaddr *)&peer, 0),
  376. ssl_peer_storage[idx]->h);
  377. for (i = 0; i < MAX_SSL_PEERS; i++) {
  378. if (ssl_peer_storage[i]) {
  379. fprintf(stderr, "%02d: %p ssl: %p ",
  380. i, ssl_peer_storage[i] ,ssl_peer_storage[i]->ssl);
  381. (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[i]->ssl), &peer2);
  382. getnameinfo((struct sockaddr *)&peer2, sizeof(peer2),
  383. addr, sizeof(addr), port, sizeof(port),
  384. NI_NUMERICHOST | NI_NUMERICSERV);
  385. fprintf(stderr," peer: [%s]:%s h: %lu\n", addr, port, ssl_peer_storage[i]->h);
  386. }
  387. }
  388. fprintf(stderr, "***** ASSERT FAILED ******\n");
  389. memset(&peer, 0, sizeof(peer));
  390. (void) BIO_dgram_get_peer(SSL_get_wbio(ssl), &peer);
  391. idx = get_index_of_peer((struct sockaddr *)&peer, 0);
  392. fprintf(stderr, " get_index_of_peer for wbio returns %d, type is %04x\n",
  393. idx, where);
  394. }
  395. #if 1
  396. check_peers();
  397. OPENSSL_assert((idx < 0) || (ssl == ssl_peer_storage[idx]->ssl));
  398. #endif
  399. if (where & SSL_CB_ALERT) {
  400. #ifndef NDEBUG
  401. if (ret != 0)
  402. fprintf(stderr,"%s:%s:%s\n", SSL_alert_type_string(ret),
  403. SSL_alert_desc_string(ret), SSL_alert_desc_string_long(ret));
  404. #endif
  405. /* examine alert type */
  406. switch (*SSL_alert_type_string(ret)) {
  407. case 'F':
  408. /* move SSL object from pending to close */
  409. if (idx >= 0) {
  410. ssl_peer_storage[idx]->state = PEER_ST_CLOSED;
  411. pending--;
  412. }
  413. break;
  414. case 'W':
  415. if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) {
  416. if (where == SSL_CB_WRITE_ALERT)
  417. fprintf(stderr,"sent CLOSE_NOTIFY\n");
  418. else /* received CN */
  419. fprintf(stderr,"received CLOSE_NOTIFY\n");
  420. }
  421. break;
  422. default: /* handle unknown alert types */
  423. #ifndef NDEBUG
  424. printf("not handled!\n");
  425. #endif
  426. }
  427. }
  428. if (where & SSL_CB_HANDSHAKE_DONE) {
  429. /* move SSL object from pending to established */
  430. printf("HANDSHAKE_DONE ");
  431. if (idx >= 0) {
  432. if (ssl_peer_storage[idx]->state == PEER_ST_PENDING) {
  433. ssl_peer_storage[idx]->state = PEER_ST_ESTABLISHED;
  434. pending--;
  435. printf("moved SSL object %d to ESTABLISHED\n", idx);
  436. printf("%d objects pending\n", pending);
  437. } else {
  438. #ifndef NDEBUG
  439. printf("huh, object %d was not pending? (%d)\n", idx,
  440. ssl_peer_storage[idx]->state);
  441. #endif
  442. }
  443. return;
  444. }
  445. return;
  446. }
  447. return;
  448. }
  449. #endif
  450. #ifdef WITH_DTLS
  451. /* checks if ssl object was closed and can be removed */
  452. int
  453. check_close(SSL *ssl) {
  454. int res, err, idx;
  455. struct sockaddr_storage peer;
  456. memset(&peer, 0, sizeof(peer));
  457. (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
  458. res = 0;
  459. if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) {
  460. printf("SSL_RECEIVED_SHUTDOWN\n");
  461. res = SSL_shutdown(ssl);
  462. if (res == 0) {
  463. printf("must call SSL_shutdown again\n");
  464. res = SSL_shutdown(ssl);
  465. }
  466. if (res < 0) {
  467. err = SSL_get_error(ssl,res);
  468. fprintf(stderr, "shutdown: SSL error %d: %s\n", err,
  469. ERR_error_string(err, NULL));
  470. }
  471. /* we can close the SSL object anyway */
  472. /* FIXME: need to get ifindex from somewhere */
  473. idx = get_index_of_peer((struct sockaddr *)&peer, 0);
  474. OPENSSL_assert(idx < 0 || ssl == ssl_peer_storage[idx]->ssl);
  475. if (idx >= 0) {
  476. ssl_peer_storage[idx]->state = PEER_ST_CLOSED;
  477. printf("moved SSL object %d to CLOSED\n",idx);
  478. }
  479. }
  480. return res;
  481. }
  482. int
  483. check_timeout() {
  484. int i, result, err;
  485. for (i = 0; i < MAX_SSL_PEERS; i++) {
  486. if (ssl_peer_storage[i]) {
  487. OPENSSL_assert(ssl_peer_storage[i]->ssl);
  488. result = DTLSv1_handle_timeout(ssl_peer_storage[i]->ssl);
  489. if (result < 0) {
  490. err = SSL_get_error(ssl_peer_storage[i]->ssl,result);
  491. fprintf(stderr, "dtls1_handle_timeout (%d): %s\n",
  492. err, ERR_error_string(err, NULL));
  493. }
  494. }
  495. }
  496. /* remove outdated obbjects? */
  497. return 0;
  498. }
  499. #endif /* WITH_DTLS */
  500. int
  501. _read(SSL_CTX *ctx, int sockfd) {
  502. char buf[2000];
  503. struct sockaddr_in6 src;
  504. int len, ifindex, i;
  505. char addr[INET6_ADDRSTRLEN];
  506. char port[6];
  507. socklen_t sz = sizeof(struct sockaddr_in6);
  508. #ifdef WITH_DTLS
  509. SSL *ssl;
  510. int err;
  511. #endif
  512. /* Retrieve remote address and interface index as well as the first
  513. few bytes of the message to demultiplex protocols. */
  514. memset(&src, 0, sizeof(struct sockaddr_in6));
  515. len = check_connect(sockfd, buf, 4, (struct sockaddr *)&src, &ifindex);
  516. if (len < 0) /* error */
  517. return len;
  518. #ifndef NDEBUG
  519. fprintf(stderr,"received packet");
  520. if (getnameinfo((struct sockaddr *)&src, sizeof(src),
  521. addr, sizeof(addr), port, sizeof(port),
  522. NI_NUMERICHOST | NI_NUMERICSERV) == 0)
  523. fprintf(stderr," from [%s]:%s", addr, port);
  524. fprintf(stderr," on interface %d\n", ifindex);
  525. #endif
  526. switch (demux_protocol(buf, len)) {
  527. #ifdef WITH_DTLS
  528. case DTLS :
  529. ssl = get_ssl(ctx, sockfd, (struct sockaddr *)&src, ifindex);
  530. if (!ssl) {
  531. fprintf(stderr, "cannot create new SSL object\n");
  532. /* return recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT);*/
  533. len = recvfrom(sockfd, buf, sizeof(buf), MSG_DONTWAIT,
  534. (struct sockaddr *)&src, &sz);
  535. getnameinfo((struct sockaddr *)&src, sz,
  536. addr, sizeof(addr), port, sizeof(port),
  537. NI_NUMERICHOST | NI_NUMERICSERV);
  538. printf("discarded %d bytes from [%s]:%s\n", len, addr, port);
  539. return len;
  540. }
  541. len = SSL_read(ssl, buf, sizeof(buf));
  542. break;
  543. #endif
  544. case UNKNOWN:
  545. default :
  546. len = recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT);
  547. }
  548. if (len > 0) {
  549. printf("here is the data:\n");
  550. for (i=0; i<len; i++)
  551. printf("%c",buf[i]);
  552. } if (len == 0) { /* session closed? */
  553. #ifdef WITH_DTLS
  554. if (check_close(ssl) <= 0) {
  555. fprintf(stderr, "not closed\n");
  556. }
  557. #endif
  558. } else {
  559. #ifdef WITH_DTLS
  560. err = SSL_get_error(ssl,len);
  561. switch (err) {
  562. case SSL_ERROR_WANT_READ:
  563. fprintf(stderr, "SSL_ERROR_WANT_READ\n");
  564. return 0;
  565. case SSL_ERROR_WANT_WRITE:
  566. fprintf(stderr, "SSL_ERROR_WANT_WRITE\n");
  567. return 0;
  568. default:
  569. fprintf(stderr, "read: SSL error %d: %s\n", err,
  570. ERR_error_string(err, NULL));
  571. return 0;
  572. }
  573. #else
  574. perror("recv");
  575. #endif
  576. }
  577. return len;
  578. }
  579. int
  580. _write(SSL_CTX *ctx, int sockfd) {
  581. int res = 0;
  582. #ifdef WITH_DTLS
  583. SSL *ssl;
  584. int err;
  585. ssl = get_ssl(ctx, sockfd, NULL, 1);
  586. if (!ssl) {
  587. fprintf(stderr, "no SSL object for writing");
  588. return 0;
  589. }
  590. res = SSL_write(ssl, NULL, 0);
  591. if (res < 0) {
  592. /*
  593. if (SSL_want_write(ssl))
  594. return 0;
  595. */
  596. /* FIXME: check SSL_want_read(ssl) */
  597. err = SSL_get_error(ssl,res);
  598. fprintf(stderr,"SSL_write returned %d (%s)\n", err, ERR_error_string(err, NULL));
  599. } else {
  600. printf("SSL_write successful\n");
  601. }
  602. #else
  603. #endif
  604. return res;
  605. }
  606. int
  607. generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) {
  608. /* FIXME: generate secure client-specific cookie */
  609. #define DUMMYSTR "ABCDEFGHIJKLMNOP"
  610. *cookie_len = strlen(DUMMYSTR);
  611. memcpy(cookie, DUMMYSTR, *cookie_len);
  612. return 1;
  613. }
  614. int
  615. verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len) {
  616. /* FIXME */
  617. return 1;
  618. }
  619. enum { READ, WRITE };
  620. int
  621. main(int argc, char **argv) {
  622. int sockfd = 0;
  623. int on = 1;
  624. struct sockaddr_in6 listen_addr = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 };
  625. size_t addr_size = sizeof(struct sockaddr_in6);
  626. fd_set fds[2];
  627. int result, flags;
  628. int idx, res = 0;
  629. struct timeval timeout;
  630. struct sigaction act, oact;
  631. #ifdef WITH_DTLS
  632. SSL_CTX *ctx;
  633. memset(ssl_peer_storage, 0, sizeof(ssl_peer_storage));
  634. SSL_load_error_strings();
  635. SSL_library_init();
  636. ctx = SSL_CTX_new(DTLSv1_server_method());
  637. SSL_CTX_set_cipher_list(ctx, "ALL");
  638. SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
  639. res = SSL_CTX_use_certificate_file(ctx, SERVER_CERT_PEM, SSL_FILETYPE_PEM);
  640. if (res != 1) {
  641. fprintf(stderr, "cannot read server certificate from file '%s' (%s)\n",
  642. SERVER_CERT_PEM, ERR_error_string(res,NULL));
  643. goto end;
  644. }
  645. res = SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_PEM, SSL_FILETYPE_PEM);
  646. if (res != 1) {
  647. fprintf(stderr, "cannot read server key from file '%s' (%s)\n",
  648. SERVER_KEY_PEM, ERR_error_string(res,NULL));
  649. goto end;
  650. }
  651. res = SSL_CTX_check_private_key (ctx);
  652. if (res != 1) {
  653. fprintf(stderr, "invalid private key\n");
  654. goto end;
  655. }
  656. res = SSL_CTX_load_verify_locations(ctx, CA_CERT_PEM, NULL);
  657. if (res != 1) {
  658. fprintf(stderr, "cannot read ca file '%s'\n", CA_CERT_PEM);
  659. goto end;
  660. }
  661. /* Client has to authenticate */
  662. /* Client has to authenticate */
  663. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
  664. SSL_CTX_set_read_ahead(ctx, 1); /* disable read-ahead */
  665. SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
  666. SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);
  667. SSL_CTX_use_psk_identity_hint(ctx, "Enter password for CoAP-Gateway");
  668. SSL_CTX_set_psk_server_callback(ctx, psk_server_callback);
  669. SSL_CTX_set_info_callback(ctx, info_callback);
  670. #endif
  671. sockfd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
  672. if ( sockfd < 0 ) {
  673. perror("socket");
  674. return -1;
  675. }
  676. if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0)
  677. perror("setsockopt SO_REUSEADDR");
  678. flags = fcntl(sockfd, F_GETFL, 0);
  679. if (flags < 0 || fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
  680. perror("fcntl");
  681. return -1;
  682. }
  683. on = 1;
  684. if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) {
  685. perror("setsockopt IPV6_PKTINFO");
  686. }
  687. if (bind (sockfd, (const struct sockaddr *)&listen_addr, addr_size) < 0) {
  688. perror("bind");
  689. res = -2;
  690. goto end;
  691. }
  692. act.sa_handler = handle_sigint;
  693. sigemptyset(&act.sa_mask);
  694. act.sa_flags = 0;
  695. sigaction(SIGINT, &act, &oact);
  696. while (!quit) {
  697. FD_ZERO(&fds[READ]);
  698. FD_ZERO(&fds[WRITE]);
  699. FD_SET(sockfd, &fds[READ]);
  700. timeout.tv_sec = 1;
  701. timeout.tv_usec = 0;
  702. result = select( FD_SETSIZE, &fds[READ], &fds[WRITE], 0, &timeout);
  703. if (result < 0) { /* error */
  704. if (errno != EINTR)
  705. perror("select");
  706. } else if (result > 0) { /* read from socket */
  707. if ( FD_ISSET( sockfd, &fds[READ]) ) {
  708. _read(ctx, sockfd); /* read received data */
  709. } else if ( FD_ISSET( sockfd, &fds[WRITE]) ) { /* write to socket */
  710. _write(ctx, sockfd); /* write data */
  711. }
  712. } else { /* timeout */
  713. check_timeout();
  714. }
  715. remove_closed();
  716. }
  717. end:
  718. #ifdef WITH_DTLS
  719. for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
  720. if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->ssl) {
  721. if (ssl_peer_storage[idx]->state == PEER_ST_ESTABLISHED)
  722. SSL_shutdown(ssl_peer_storage[idx]->ssl);
  723. SSL_free(ssl_peer_storage[idx]->ssl);
  724. }
  725. }
  726. SSL_CTX_free(ctx);
  727. #endif
  728. close(sockfd); /* don't care if we close stdin at this point */
  729. return res;
  730. }