DTS Application Library  0.2.3
Application library containing referenced objects and interfaces to common libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
sslutil.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2012 Gregory Nietsky <gregory@distrotetch.co.za>
3  http://www.distrotech.co.za
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
30 #include <stdint.h>
31 #ifdef __WIN32__
32 #include <winsock2.h>
33 #include <windows.h>
34 #include <ws2tcpip.h>
35 #endif
36 #include <openssl/ssl.h>
37 #include <openssl/err.h>
38 #include <sys/stat.h>
39 #include <unistd.h>
40 #ifndef __WIN32__
41 #include <sys/socket.h>
42 #include <arpa/inet.h>
43 #endif
44 
45 #include "include/dtsapp.h"
46 
48 enum SSLFLAGS {
50  SSL_TLSV1 = 1 << 0,
52  SSL_SSLV2 = 1 << 1,
54  SSL_SSLV3 = 1 << 2,
56  SSL_DTLSV1 = 1 << 3,
58  SSL_CLIENT = 1 << 4,
60  SSL_SERVER = 1 << 5,
62  SSL_DTLSCON = 1 << 6
63 };
64 
66 struct ssldata {
68  SSL_CTX *ctx;
70  SSL *ssl;
72  BIO *bio;
75  int flags;
77  const SSL_METHOD *meth;
79  struct ssldata *parent;
80 };
81 
83 #define COOKIE_SECRET_LENGTH 32
84 static unsigned char *cookie_secret = NULL;
85 
86 static int generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) {
87  union sockstruct peer;
88 
89  if (!ssl || !cookie_secret || (*cookie_len < COOKIE_SECRET_LENGTH)) {
90  return (0);
91  }
92 
93  memset(&peer, 0, sizeof(peer));
94  BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
95  sha256hmac(cookie, &peer, sizeof(peer), cookie_secret, COOKIE_SECRET_LENGTH);
96  *cookie_len = COOKIE_SECRET_LENGTH;
97 
98  return (1);
99 }
100 
101 static int verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len) {
102  union sockstruct peer;
103  unsigned char hmac[COOKIE_SECRET_LENGTH];
104 
105  if (!ssl || !cookie_secret || (cookie_len != COOKIE_SECRET_LENGTH)) {
106  return (0);
107  }
108 
109  memset(&peer, 0, sizeof(peer));
110  BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
111  sha256hmac(hmac, &peer, sizeof(peer), cookie_secret, COOKIE_SECRET_LENGTH);
112 
113  if (!sha256cmp(hmac, cookie)) {
114  return (1);
115  }
116 
117  return (0);
118 }
119 
120 static int _ssl_shutdown(struct ssldata *ssl) {
121  int err, ret = 0;
122 
123  if ((ret = SSL_shutdown(ssl->ssl)) < 1) {
124  objunlock(ssl);
125  if (ret == 0) {
126  objlock(ssl);
127  ret = SSL_shutdown(ssl->ssl);
128  } else {
129  objlock(ssl);
130  }
131  err = SSL_get_error(ssl->ssl, ret);
132  switch(err) {
133  case SSL_ERROR_WANT_READ:
134  ret = 1;
135  break;
136  case SSL_ERROR_WANT_WRITE:
137  ret = -1;
138  break;
139  case SSL_ERROR_SSL:
140  /*ignore im going away now*/
141  case SSL_ERROR_SYSCALL:
142  /* ignore this as documented*/
143  case SSL_ERROR_NONE:
144  /* nothing to see here moving on*/
145  break;
146  default:
147  printf("SSL Shutdown unknown error %i\n", err);
148  break;
149  }
150  }
151  return ret;
152 }
153 
154 
155 static int socket_select(int sock, int read) {
156  int selfd;
157  struct timeval tv;
158  fd_set act_set;
159  FD_ZERO(&act_set);
160  FD_SET(sock, &act_set);
161  tv.tv_sec = 0;
162  tv.tv_usec = 100000;
163 
164  if (read == 1) {
165  selfd = select(sock + 1, &act_set, NULL, NULL, &tv);
166  } else {
167  selfd = select(sock + 1, NULL, &act_set, NULL, &tv);
168  }
169  return selfd;
170 }
171 
179 extern void ssl_shutdown(void *data, int sock) {
180  struct ssldata *ssl = data;
181  int ret, selfd, cnt = 0;
182 
183  if (!ssl) {
184  return;
185  }
186 
187  objlock(ssl);
188 
189  while (ssl->ssl && (ret = _ssl_shutdown(ssl) && (cnt < 3))) {
190  selfd = socket_select(sock, ret);
191  if (selfd <= 0) {
192  break;
193  }
194  cnt++;
195  }
196 
197  if (ssl->ssl) {
198  SSL_free(ssl->ssl);
199  ssl->ssl = NULL;
200  }
201  objunlock(ssl);
202 }
203 
204 static void free_ssldata(void *data) {
205  struct ssldata *ssl = data;
206 
207  if (ssl->parent) {
208  objunref(ssl->parent);
209  }
210 
211  if (ssl->ctx) {
212  SSL_CTX_free(ssl->ctx);
213  ssl->ctx = NULL;
214  }
215 }
216 
217 static int verify_callback (int ok, X509_STORE_CTX *ctx) {
218  return (1);
219 }
220 
221 static struct ssldata *sslinit(const char *cacert, const char *cert, const char *key, int verify, const SSL_METHOD *meth, int flags) {
222  struct ssldata *ssl;
223  struct stat finfo;
224  int ret = -1;
225 
226  if (!(ssl = objalloc(sizeof(*ssl), free_ssldata))) {
227  return NULL;
228  }
229 
230  ssl->flags = flags;
231  ssl->meth = meth;
232  if (!(ssl->ctx = SSL_CTX_new(meth))) {
233  objunref(ssl);
234  return NULL;
235  }
236 
237  if (!stat(cacert, &finfo)) {
238  if (S_ISDIR(finfo.st_mode) && (SSL_CTX_load_verify_locations(ssl->ctx, NULL, cacert) == 1)) {
239  ret = 0;
240  } else
241  if (SSL_CTX_load_verify_locations(ssl->ctx, cacert, NULL) == 1) {
242  ret = 0;
243  }
244  }
245 
246  if (!ret && (SSL_CTX_use_certificate_file(ssl->ctx, cert, SSL_FILETYPE_PEM) == 1)) {
247  ret = 0;
248  }
249  if (!ret && (SSL_CTX_use_PrivateKey_file(ssl->ctx, key, SSL_FILETYPE_PEM) == 1)) {
250  ret = 0;
251  }
252 
253  if (!ret && (SSL_CTX_check_private_key (ssl->ctx) == 1)) {
254  ret= 0;
255  }
256 
257  /*XXX Should create a tmp 512 bit rsa key for RSA ciphers also need DH
258  http://www.openssl.org/docs/ssl/SSL_CTX_set_cipher_list.html
259  SSL_CTX_set_cipher_list*/
260 
261  if (!ret) {
262  /* XXX CRL verification
263  X509_VERIFY_PARAM *param;
264  param = X509_VERIFY_PARAM_new();
265  X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
266  SSL_CTX_set1_param(ctx, param);
267  X509_VERIFY_PARAM_free(param);
268  */
269  SSL_CTX_set_verify(ssl->ctx, verify, verify_callback);
270  SSL_CTX_set_verify_depth(ssl->ctx, 1);
271  }
272 
273  if (ret) {
274  objunref(ssl);
275  return NULL;
276  }
277 
278  return (ssl);
279 }
280 
281 
287 extern void *tlsv1_init(const char *cacert, const char *cert, const char *key, int verify) {
288  const SSL_METHOD *meth = TLSv1_method();
289 
290  return (sslinit(cacert, cert, key, verify, meth, SSL_TLSV1));
291 }
292 
298 #ifndef OPENSSL_NO_SSL2
299 extern void *sslv2_init(const char *cacert, const char *cert, const char *key, int verify) {
300  const SSL_METHOD *meth = SSLv2_method();
301 
302  return (sslinit(cacert, cert, key, verify, meth, SSL_SSLV2));
303 }
304 #endif
305 
311 extern void *sslv3_init(const char *cacert, const char *cert, const char *key, int verify) {
312  const SSL_METHOD *meth = SSLv3_method();
313  struct ssldata *ssl;
314 
315  ssl = sslinit(cacert, cert, key, verify, meth, SSL_SSLV3);
316 
317  return (ssl);
318 }
319 
325 extern void *dtlsv1_init(const char *cacert, const char *cert, const char *key, int verify) {
326  const SSL_METHOD *meth = DTLSv1_method();
327  struct ssldata *ssl;
328 
329  ssl = sslinit(cacert, cert, key, verify, meth, SSL_DTLSV1);
330  /* XXX BIO_CTRL_DGRAM_MTU_DISCOVER*/
331  SSL_CTX_set_read_ahead(ssl->ctx, 1);
332 
333  return (ssl);
334 }
335 
336 static void sslsockstart(struct fwsocket *sock, struct ssldata *orig,int accept) {
337  struct ssldata *ssl = sock->ssl;
338 
339  if (!ssl) {
340  return;
341  }
342 
343  objlock(sock);
344  objlock(ssl);
345  if (orig) {
346  objlock(orig);
347  ssl->ssl = SSL_new(orig->ctx);
348  objunlock(orig);
349  } else {
350  ssl->ssl = SSL_new(ssl->ctx);
351  }
352 
353  if (ssl->ssl) {
354  ssl->bio = BIO_new_socket(sock->sock, BIO_NOCLOSE);
355  objunlock(sock);
356  SSL_set_bio(ssl->ssl, ssl->bio, ssl->bio);
357  if (accept) {
358  SSL_accept(ssl->ssl);
359  ssl->flags |= SSL_SERVER;
360  } else {
361  SSL_connect(ssl->ssl);
362  ssl->flags |= SSL_CLIENT;
363  }
364  if (orig) {
365  objref(orig);
366  ssl->parent = orig;
367  }
368  objunlock(ssl);
369  } else {
370  objunlock(ssl);
371  objunref(ssl);
372  sock->ssl = NULL;
373  objunlock(sock);
374  return;
375  }
376 }
377 
382 extern void tlsaccept(struct fwsocket *sock, struct ssldata *orig) {
383  setflag(sock, SOCK_FLAG_SSL);
384  if ((sock->ssl = objalloc(sizeof(*sock->ssl), free_ssldata))) {
385  sslsockstart(sock, orig, 1);
386  }
387 }
388 
406 extern int socketread_d(struct fwsocket *sock, void *buf, int num, union sockstruct *addr) {
407  struct ssldata *ssl = sock->ssl;
408  socklen_t salen = sizeof(*addr);
409  int ret, err, syserr;
410 
411  if (!ssl && !testflag(sock, SOCK_FLAG_SSL)) {
412  objlock(sock);
413  if (addr && (sock->type == SOCK_DGRAM)) {
414  ret = recvfrom(sock->sock, buf, num, 0, &addr->sa, &salen);
415  } else {
416 #ifndef __WIN32
417  ret = read(sock->sock, buf, num);
418 #else
419  ret = recv(sock->sock, buf, num, 0);
420 #endif
421  }
422  if (ret == 0) {
423  sock->flags |= SOCK_FLAG_CLOSE;
424  }
425  objunlock(sock);
426  return (ret);
427  } else if (!ssl) {
428  return -1;
429  }
430 
431  objlock(ssl);
432  /* ive been shutdown*/
433  if (!ssl->ssl) {
434  objunlock(ssl);
435  return (-1);
436  }
437  ret = SSL_read(ssl->ssl, buf, num);
438  err = SSL_get_error(ssl->ssl, ret);
439  if (ret == 0) {
440  sock->flags |= SOCK_FLAG_CLOSE;
441  }
442  objunlock(ssl);
443  switch (err) {
444  case SSL_ERROR_NONE:
445  break;
446  case SSL_ERROR_WANT_X509_LOOKUP:
447  printf("Want X509\n");
448  break;
449  case SSL_ERROR_WANT_READ:
450  printf("Read Want Read\n");
451  break;
452  case SSL_ERROR_WANT_WRITE:
453  printf("Read Want write\n");
454  break;
455  case SSL_ERROR_ZERO_RETURN:
456  case SSL_ERROR_SSL:
457  objlock(sock);
458  objunref(sock->ssl);
459  sock->ssl = NULL;
460  objunlock(sock);
461  break;
462  case SSL_ERROR_SYSCALL:
463  syserr = ERR_get_error();
464  if (syserr || (!syserr && (ret == -1))) {
465  printf("R syscall %i %i\n", syserr, ret);
466  }
467  break;
468  default
469  :
470  printf("other\n");
471  break;
472  }
473 
474  return (ret);
475 }
476 
489 extern int socketread(struct fwsocket *sock, void *buf, int num) {
490  return (socketread_d(sock, buf, num, NULL));
491 }
492 
493 
508 extern int socketwrite_d(struct fwsocket *sock, const void *buf, int num, union sockstruct *addr) {
509  struct ssldata *ssl = (sock) ? sock->ssl : NULL;
510  int ret, err, syserr;
511 
512  if (!sock) {
513  return (-1);
514  }
515 
516  if (!ssl && !testflag(sock, SOCK_FLAG_SSL)) {
517  objlock(sock);
518  if (addr && (sock->type == SOCK_DGRAM)) {
519 #ifndef __WIN32
520  if (sock->flags & SOCK_FLAG_UNIX) {
521  ret = sendto(sock->sock, buf, num, MSG_NOSIGNAL, (const struct sockaddr *)&addr->un, sizeof(addr->un));
522  } else if (sock->flags & SOCK_FLAG_MCAST) {
523  ret = sendto(sock->sock, buf, num, MSG_NOSIGNAL, &sock->addr.sa, sizeof(sock->addr.ss));
524  } else {
525  ret = sendto(sock->sock, buf, num, MSG_NOSIGNAL, &addr->sa, sizeof(*addr));
526  }
527 #else
528  if (sock->flags & SOCK_FLAG_MCAST) {
529  ret = sendto(sock->sock, buf, num, 0, &sock->addr.sa, sizeof(sock->addr.ss));
530  } else {
531  ret = sendto(sock->sock, buf, num, 0, &addr->sa, sizeof(*addr));
532  }
533 #endif
534  } else {
535 #ifndef __WIN32
536  if (sock->flags & SOCK_FLAG_MCAST) {
537  ret = sendto(sock->sock, buf, num, MSG_NOSIGNAL, &sock->addr.sa, sizeof(sock->addr.ss));
538  } else {
539  ret = send(sock->sock, buf, num, MSG_NOSIGNAL);
540  }
541 #else
542  if (sock->flags & SOCK_FLAG_MCAST) {
543  ret = sendto(sock->sock, buf, num, 0, &sock->addr.sa, sizeof(sock->addr.ss));
544  } else {
545  ret = send(sock->sock, buf, num, 0);
546  }
547 #endif
548  }
549  if (ret == -1) {
550  switch(errno) {
551  case EBADF:
552  case EPIPE:
553 #ifndef __WIN32
554  case ENOTCONN:
555  case ENOTSOCK:
556 #endif
557  sock->flags |= SOCK_FLAG_CLOSE;
558  break;
559  }
560  }
561  objunlock(sock);
562  return (ret);
563  } else if (!ssl) {
564  return -1;
565  }
566 
567  if (ssl && ssl->ssl) {
568  objlock(ssl);
569  if (SSL_state(ssl->ssl) != SSL_ST_OK) {
570  objunlock(ssl);
571  return (SSL_ERROR_SSL);
572  }
573  ret = SSL_write(ssl->ssl, buf, num);
574  err = SSL_get_error(ssl->ssl, ret);
575  objunlock(ssl);
576  } else {
577  return -1;
578  }
579 
580  if (ret == -1) {
581  setflag(sock, SOCK_FLAG_CLOSE);
582  }
583 
584  switch(err) {
585  case SSL_ERROR_NONE:
586  break;
587  case SSL_ERROR_WANT_READ:
588  printf("Send Want Read\n");
589  break;
590  case SSL_ERROR_WANT_WRITE:
591  printf("Send Want write\n");
592  break;
593  case SSL_ERROR_WANT_X509_LOOKUP:
594  printf("Want X509\n");
595  break;
596  case SSL_ERROR_ZERO_RETURN:
597  case SSL_ERROR_SSL:
598  objlock(sock);
599  objunref(sock->ssl);
600  sock->ssl = NULL;
601  objunlock(sock);
602  break;
603  case SSL_ERROR_SYSCALL:
604  syserr = ERR_get_error();
605  if (syserr || (!syserr && (ret == -1))) {
606  printf("W syscall %i %i\n", syserr, ret);
607  }
608  break;
609  default:
610  printf("other\n");
611  break;
612  }
613 
614  return (ret);
615 }
616 
629 extern int socketwrite(struct fwsocket *sock, const void *buf, int num) {
630  return (socketwrite_d(sock, buf, num, NULL));
631 }
632 
639 extern void sslstartup(void) {
640  SSL_library_init();
641  SSL_load_error_strings();
642  OpenSSL_add_ssl_algorithms();
643 
644  if ((cookie_secret = malloc(COOKIE_SECRET_LENGTH))) {
645  genrand(cookie_secret, COOKIE_SECRET_LENGTH);
646  }
647 }
648 
649 static void dtlssetopts(struct ssldata *ssl, struct ssldata *orig, struct fwsocket *sock) {
650  struct timeval timeout;
651 
652  objlock(sock);
653  objlock(ssl);
654  ssl->bio = BIO_new_dgram(sock->sock, BIO_NOCLOSE);
655  objunlock(sock);
656 
657  timeout.tv_sec = 5;
658  timeout.tv_usec = 0;
659  BIO_ctrl(ssl->bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
660  timeout.tv_sec = 5;
661  timeout.tv_usec = 0;
662  BIO_ctrl(ssl->bio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
663 
664  if (orig) {
665  objlock(orig);
666  if ((ssl->ssl = SSL_new(orig->ctx))) {
667  objunlock(orig);
668  objref(orig);
669  ssl->parent = orig;
670  } else {
671  objunlock(orig);
672  }
673  } else {
674  ssl->ssl = SSL_new(ssl->ctx);
675  }
676  SSL_set_bio(ssl->ssl, ssl->bio, ssl->bio);
677  objunlock(ssl);
678  setflag(sock, SOCK_FLAG_SSL);
679 }
680 
685 extern void dtsl_serveropts(struct fwsocket *sock) {
686  struct ssldata *ssl = sock->ssl;
687 
688  if (!ssl) {
689  return;
690  }
691 
692  dtlssetopts(ssl, NULL, sock);
693 
694  objlock(ssl);
695  SSL_CTX_set_cookie_generate_cb(ssl->ctx, generate_cookie);
696  SSL_CTX_set_cookie_verify_cb(ssl->ctx, verify_cookie);
697  SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
698 
699  SSL_set_options(ssl->ssl, SSL_OP_COOKIE_EXCHANGE);
700  ssl->flags |= SSL_SERVER;
701  objunlock(ssl);
702 }
703 
704 static void dtlsaccept(struct fwsocket *sock) {
705  struct ssldata *ssl = sock->ssl;
706 
707  objlock(sock);
708  objlock(ssl);
709  ssl->flags |= SSL_SERVER;
710 
711  BIO_set_fd(ssl->bio, sock->sock, BIO_NOCLOSE);
712  BIO_ctrl(ssl->bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &sock->addr);
713  objunlock(sock);
714 
715  SSL_accept(ssl->ssl);
716 
717  if (SSL_get_peer_certificate(ssl->ssl)) {
718  printf ("A------------------------------------------------------------\n");
719  X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl->ssl)), 1, XN_FLAG_MULTILINE);
720  printf("\n\n Cipher: %s", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl->ssl)));
721  printf ("\n------------------------------------------------------------\n\n");
722  }
723  objunlock(ssl);
724 }
725 
726 
731 extern struct fwsocket *dtls_listenssl(struct fwsocket *sock) {
732  struct ssldata *ssl = sock->ssl;
733  struct ssldata *newssl;
734  struct fwsocket *newsock;
735  union sockstruct client;
736 #ifndef __WIN32__
737  int on = 1;
738 #else
739 /* unsigned long on = 1;*/
740 #endif
741 
742  if (!(newssl = objalloc(sizeof(*newssl), free_ssldata))) {
743  return NULL;
744  }
745 
746  newssl->flags |= SSL_DTLSCON;
747 
748  dtlssetopts(newssl, ssl, sock);
749  memset(&client, 0, sizeof(client));
750  if (DTLSv1_listen(newssl->ssl, &client) <= 0) {
751  objunref(newssl);
752  return NULL;
753  }
754 
755  objlock(sock);
756  if (!(newsock = make_socket(sock->addr.sa.sa_family, sock->type, sock->proto, newssl))) {
757  objunlock(sock);
758  objunref(newssl);
759  return NULL;
760  }
761  objunlock(sock);
762  memcpy(&newsock->addr, &client, sizeof(newsock->addr));
763 #ifndef __WIN32__
764  setsockopt(newsock->sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
765 #ifdef SO_REUSEPORT
766  setsockopt(newsock->sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
767 #endif
768 #else
769 /* ioctlsocket(newsock->sock, FIONBIO, (unsigned long*)&on);*/
770 #endif
771  objlock(sock);
772  bind(newsock->sock, &sock->addr.sa, sizeof(sock->addr));
773  objunlock(sock);
774  connect(newsock->sock, &newsock->addr.sa, sizeof(newsock->addr));
775 
776  dtlsaccept(newsock);
777  setflag(newsock, SOCK_FLAG_SSL);
778 
779  return (newsock);
780 }
781 
782 static void dtlsconnect(struct fwsocket *sock) {
783  struct ssldata *ssl = sock->ssl;
784 
785  if (!ssl) {
786  return;
787  }
788 
789  dtlssetopts(ssl, NULL, sock);
790 
791  objlock(sock);
792  objlock(ssl);
793  ssl->flags |= SSL_CLIENT;
794  BIO_ctrl(ssl->bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &sock->addr);
795  objunlock(sock);
796  SSL_connect(ssl->ssl);
797 
798  if (SSL_get_peer_certificate(ssl->ssl)) {
799  printf ("C------------------------------------------------------------\n");
800  X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl->ssl)), 1, XN_FLAG_MULTILINE);
801  printf("\n\n Cipher: %s", SSL_CIPHER_get_name(SSL_get_current_cipher(ssl->ssl)));
802  printf ("\n------------------------------------------------------------\n\n");
803  }
804  objunlock(ssl);
805 }
806 
811 extern void startsslclient(struct fwsocket *sock) {
812  if (!sock || !sock->ssl || (sock->ssl->flags & SSL_SERVER)) {
813  return;
814  }
815 
816  switch(sock->type) {
817  case SOCK_DGRAM:
818  dtlsconnect(sock);
819  break;
820  case SOCK_STREAM:
821  sslsockstart(sock, NULL, 0);
822  break;
823  }
824 }
825 
831 extern void dtlstimeout(struct fwsocket *sock, struct timeval *timeleft, int defusec) {
832  if (!sock || !sock->ssl || !sock->ssl->ssl) {
833  return;
834  }
835 
836  objlock(sock->ssl);
837  if (!DTLSv1_get_timeout(sock->ssl->ssl, timeleft)) {
838  timeleft->tv_sec = 0;
839  timeleft->tv_usec = defusec;
840  }
841  objunlock(sock->ssl);
842 }
843 
846 extern void dtlshandltimeout(struct fwsocket *sock) {
847  if (!sock->ssl) {
848  return;
849  }
850 
851  objlock(sock->ssl);
852  DTLSv1_handle_timeout(sock->ssl->ssl);
853  objunlock(sock->ssl);
854 }
855 
const SSL_METHOD * meth
SSL method.
Definition: sslutil.c:77
SSL data structure for enabling encryption on sockets.
Definition: sslutil.c:66
union sockstruct addr
system socket data structure.
Definition: dtsapp.h:143
void * sslv3_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for SSLv3.
Definition: sslutil.c:311
void ssl_shutdown(void *ssl, int sock)
Shutdown the SSL connection.
Definition: sslutil.c:179
struct sockaddr_un un
Unix sockets.
Definition: dtsapp.h:85
int objref(void *data)
Reference a object.
Definition: refobj.c:153
#define testflag(obj, flag)
Atomically test a flag in the flags field of a referenced object.
Definition: dtsapp.h:932
struct fwsocket * dtls_listenssl(struct fwsocket *sock)
Implementation of &quot;listen&quot; for DTLSv1.
Definition: sslutil.c:731
int socketread(struct fwsocket *sock, void *buf, int num)
Read from a socket into a buffer.
Definition: sslutil.c:489
int objlock(void *data)
Lock the reference.
Definition: refobj.c:269
Socket data structure.
Definition: dtsapp.h:131
int flags
SSL flags.
Definition: sslutil.c:75
Multicast Socket.
Definition: dtsapp.h:112
void sha256hmac(unsigned char *buff, const void *data, unsigned long len, const void *key, unsigned long klen)
Hash Message Authentication Codes (HMAC) SHA2-256.
Definition: util.c:314
DTLSv1 (UDP Connections)
Definition: sslutil.c:56
void dtlshandltimeout(struct fwsocket *sock)
Handle DTLSv1 timeout.
Definition: sslutil.c:846
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
Definition: refobj.c:129
int socketwrite(struct fwsocket *sock, const void *buf, int num)
Write a buffer to a socket.
Definition: sslutil.c:629
struct ssldata * parent
Parent structure.
Definition: sslutil.c:79
void sslstartup(void)
Initialise SSL support this should be called at startup.
Definition: sslutil.c:639
void * sslv2_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for SSLv2 (If available)
Definition: sslutil.c:299
void * dtlsv1_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for DTLSv1.
Definition: sslutil.c:325
TLSv1.
Definition: sslutil.c:50
void * tlsv1_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for TLSv1.
Definition: sslutil.c:287
#define setflag(obj, flag)
Atomically set a flag in the flags field of a referenced object.
Definition: dtsapp.h:925
This session is server mode.
Definition: sslutil.c:60
int sock
Socket FD.
Definition: dtsapp.h:133
int socketread_d(struct fwsocket *sock, void *buf, int num, union sockstruct *addr)
Read from a socket into a buffer.
Definition: sslutil.c:406
DTS Application library API Include file.
void tlsaccept(struct fwsocket *sock, struct ssldata *orig)
Create SSL session for new connection.
Definition: sslutil.c:382
SSL has been requested on this socket dont allow clear read/send.
Definition: dtsapp.h:108
void startsslclient(struct fwsocket *sock)
Start SSL on a client socket.
Definition: sslutil.c:811
UDP connection is listening.
Definition: sslutil.c:62
SSLFLAGS
SSL configuration flags.
Definition: sslutil.c:48
#define COOKIE_SECRET_LENGTH
length of cookie secret using SHA2-256 HMAC
Definition: sslutil.c:83
int proto
Socket protocol.
Definition: dtsapp.h:135
int sha256cmp(unsigned char *digest1, unsigned char *digest2)
Compare two SHA2-256 hashes.
Definition: util.c:243
struct ssldata * ssl
SSL structure for encryption.
Definition: dtsapp.h:146
int genrand(void *buf, int len)
Generate random sequence.
Definition: util.c:82
SSLv3.
Definition: sslutil.c:54
SSL_CTX * ctx
OpenSSL context.
Definition: sslutil.c:68
void dtlstimeout(struct fwsocket *sock, struct timeval *timeleft, int defusec)
Get DTLSv1 timeout setting todefault timeout.
Definition: sslutil.c:831
int socketwrite_d(struct fwsocket *sock, const void *buf, int num, union sockstruct *addr)
Write a buffer to a socket.
Definition: sslutil.c:508
struct fwsocket * make_socket(int family, int type, int proto, void *ssl)
Allocate a socket structure and return reference.
Definition: socket.c:120
int objunlock(void *data)
Unlock a reference.
Definition: refobj.c:301
This session is client mode.
Definition: sslutil.c:58
BIO * bio
OpenSSL BIO.
Definition: sslutil.c:72
struct sockaddr_storage ss
Sockaddr storage is a &quot;magic&quot; struct been able to hold IPv4 or IPv6.
Definition: dtsapp.h:92
struct sockaddr sa
Base socket addr structure.
Definition: dtsapp.h:82
int type
Socket type.
Definition: dtsapp.h:137
SSLv2 This may not be available due to security issues.
Definition: sslutil.c:52
void dtsl_serveropts(struct fwsocket *sock)
Start up the DTLSv1 Server.
Definition: sslutil.c:685
SSL * ssl
OpenSSL ssl.
Definition: sslutil.c:70
Socket union describing all address types.
Definition: dtsapp.h:80
enum sock_flags flags
Socket control flags.
Definition: dtsapp.h:140
int objunref(void *data)
Drop reference held.
Definition: refobj.c:184
UNIX Domain Socket.
Definition: dtsapp.h:110
The socket is going away stop processing in its thread.
Definition: dtsapp.h:106