36 #include <openssl/ssl.h>
37 #include <openssl/err.h>
41 #include <sys/socket.h>
42 #include <arpa/inet.h>
83 #define COOKIE_SECRET_LENGTH 32
84 static unsigned char *cookie_secret = NULL;
86 static int generate_cookie(SSL *
ssl,
unsigned char *cookie,
unsigned int *cookie_len) {
93 memset(&peer, 0,
sizeof(peer));
94 BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
101 static int verify_cookie(SSL *ssl,
unsigned char *cookie,
unsigned int cookie_len) {
109 memset(&peer, 0,
sizeof(peer));
110 BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
120 static int _ssl_shutdown(
struct ssldata *ssl) {
123 if ((ret = SSL_shutdown(ssl->
ssl)) < 1) {
127 ret = SSL_shutdown(ssl->
ssl);
131 err = SSL_get_error(ssl->
ssl, ret);
133 case SSL_ERROR_WANT_READ:
136 case SSL_ERROR_WANT_WRITE:
141 case SSL_ERROR_SYSCALL:
147 printf(
"SSL Shutdown unknown error %i\n", err);
155 static int socket_select(
int sock,
int read) {
160 FD_SET(sock, &act_set);
165 selfd = select(sock + 1, &act_set, NULL, NULL, &tv);
167 selfd = select(sock + 1, NULL, &act_set, NULL, &tv);
181 int ret, selfd, cnt = 0;
189 while (ssl->
ssl && (ret = _ssl_shutdown(ssl) && (cnt < 3))) {
190 selfd = socket_select(sock, ret);
204 static void free_ssldata(
void *data) {
212 SSL_CTX_free(ssl->
ctx);
217 static int verify_callback (
int ok, X509_STORE_CTX *
ctx) {
221 static struct ssldata *sslinit(
const char *cacert,
const char *cert,
const char *key,
int verify,
const SSL_METHOD *
meth,
int flags) {
226 if (!(ssl =
objalloc(
sizeof(*ssl), free_ssldata))) {
232 if (!(ssl->
ctx = SSL_CTX_new(meth))) {
237 if (!stat(cacert, &finfo)) {
238 if (S_ISDIR(finfo.st_mode) && (SSL_CTX_load_verify_locations(ssl->
ctx, NULL, cacert) == 1)) {
241 if (SSL_CTX_load_verify_locations(ssl->
ctx, cacert, NULL) == 1) {
246 if (!ret && (SSL_CTX_use_certificate_file(ssl->
ctx, cert, SSL_FILETYPE_PEM) == 1)) {
249 if (!ret && (SSL_CTX_use_PrivateKey_file(ssl->
ctx, key, SSL_FILETYPE_PEM) == 1)) {
253 if (!ret && (SSL_CTX_check_private_key (ssl->
ctx) == 1)) {
269 SSL_CTX_set_verify(ssl->
ctx, verify, verify_callback);
270 SSL_CTX_set_verify_depth(ssl->
ctx, 1);
287 extern void *
tlsv1_init(
const char *cacert,
const char *cert,
const char *key,
int verify) {
288 const SSL_METHOD *meth = TLSv1_method();
290 return (sslinit(cacert, cert, key, verify, meth,
SSL_TLSV1));
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();
302 return (sslinit(cacert, cert, key, verify, meth,
SSL_SSLV2));
311 extern void *
sslv3_init(
const char *cacert,
const char *cert,
const char *key,
int verify) {
312 const SSL_METHOD *meth = SSLv3_method();
315 ssl = sslinit(cacert, cert, key, verify, meth,
SSL_SSLV3);
325 extern void *
dtlsv1_init(
const char *cacert,
const char *cert,
const char *key,
int verify) {
326 const SSL_METHOD *meth = DTLSv1_method();
329 ssl = sslinit(cacert, cert, key, verify, meth,
SSL_DTLSV1);
331 SSL_CTX_set_read_ahead(ssl->
ctx, 1);
336 static void sslsockstart(
struct fwsocket *sock,
struct ssldata *orig,
int accept) {
347 ssl->
ssl = SSL_new(orig->
ctx);
350 ssl->
ssl = SSL_new(ssl->
ctx);
354 ssl->
bio = BIO_new_socket(sock->
sock, BIO_NOCLOSE);
356 SSL_set_bio(ssl->
ssl, ssl->
bio, ssl->
bio);
358 SSL_accept(ssl->
ssl);
361 SSL_connect(ssl->
ssl);
385 sslsockstart(sock, orig, 1);
408 socklen_t salen =
sizeof(*addr);
409 int ret, err, syserr;
413 if (addr && (sock->
type == SOCK_DGRAM)) {
414 ret = recvfrom(sock->
sock, buf, num, 0, &addr->
sa, &salen);
417 ret = read(sock->
sock, buf, num);
419 ret = recv(sock->
sock, buf, num, 0);
437 ret = SSL_read(ssl->
ssl, buf, num);
438 err = SSL_get_error(ssl->
ssl, ret);
446 case SSL_ERROR_WANT_X509_LOOKUP:
447 printf(
"Want X509\n");
449 case SSL_ERROR_WANT_READ:
450 printf(
"Read Want Read\n");
452 case SSL_ERROR_WANT_WRITE:
453 printf(
"Read Want write\n");
455 case SSL_ERROR_ZERO_RETURN:
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);
509 struct ssldata *ssl = (sock) ? sock->
ssl : NULL;
510 int ret, err, syserr;
518 if (addr && (sock->
type == SOCK_DGRAM)) {
521 ret = sendto(sock->
sock, buf, num, MSG_NOSIGNAL, (
const struct sockaddr *)&addr->
un,
sizeof(addr->
un));
523 ret = sendto(sock->
sock, buf, num, MSG_NOSIGNAL, &sock->
addr.
sa,
sizeof(sock->
addr.
ss));
525 ret = sendto(sock->
sock, buf, num, MSG_NOSIGNAL, &addr->
sa,
sizeof(*addr));
529 ret = sendto(sock->
sock, buf, num, 0, &sock->
addr.
sa,
sizeof(sock->
addr.
ss));
531 ret = sendto(sock->
sock, buf, num, 0, &addr->
sa,
sizeof(*addr));
537 ret = sendto(sock->
sock, buf, num, MSG_NOSIGNAL, &sock->
addr.
sa,
sizeof(sock->
addr.
ss));
539 ret = send(sock->
sock, buf, num, MSG_NOSIGNAL);
543 ret = sendto(sock->
sock, buf, num, 0, &sock->
addr.
sa,
sizeof(sock->
addr.
ss));
545 ret = send(sock->
sock, buf, num, 0);
567 if (ssl && ssl->
ssl) {
569 if (SSL_state(ssl->
ssl) != SSL_ST_OK) {
571 return (SSL_ERROR_SSL);
573 ret = SSL_write(ssl->
ssl, buf, num);
574 err = SSL_get_error(ssl->
ssl, ret);
587 case SSL_ERROR_WANT_READ:
588 printf(
"Send Want Read\n");
590 case SSL_ERROR_WANT_WRITE:
591 printf(
"Send Want write\n");
593 case SSL_ERROR_WANT_X509_LOOKUP:
594 printf(
"Want X509\n");
596 case SSL_ERROR_ZERO_RETURN:
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);
641 SSL_load_error_strings();
642 OpenSSL_add_ssl_algorithms();
650 struct timeval timeout;
654 ssl->
bio = BIO_new_dgram(sock->
sock, BIO_NOCLOSE);
659 BIO_ctrl(ssl->
bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
662 BIO_ctrl(ssl->
bio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
666 if ((ssl->
ssl = SSL_new(orig->
ctx))) {
674 ssl->
ssl = SSL_new(ssl->
ctx);
676 SSL_set_bio(ssl->
ssl, ssl->
bio, ssl->
bio);
692 dtlssetopts(ssl, NULL, sock);
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);
699 SSL_set_options(ssl->
ssl, SSL_OP_COOKIE_EXCHANGE);
704 static void dtlsaccept(
struct fwsocket *sock) {
711 BIO_set_fd(ssl->
bio, sock->
sock, BIO_NOCLOSE);
712 BIO_ctrl(ssl->
bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &sock->
addr);
715 SSL_accept(ssl->
ssl);
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");
742 if (!(newssl =
objalloc(
sizeof(*newssl), free_ssldata))) {
748 dtlssetopts(newssl, ssl, sock);
749 memset(&client, 0,
sizeof(client));
750 if (DTLSv1_listen(newssl->
ssl, &client) <= 0) {
762 memcpy(&newsock->
addr, &client,
sizeof(newsock->
addr));
764 setsockopt(newsock->
sock, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on));
766 setsockopt(newsock->
sock, SOL_SOCKET, SO_REUSEPORT, &on,
sizeof(on));
782 static void dtlsconnect(
struct fwsocket *sock) {
789 dtlssetopts(ssl, NULL, sock);
794 BIO_ctrl(ssl->
bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &sock->
addr);
796 SSL_connect(ssl->
ssl);
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");
821 sslsockstart(sock, NULL, 0);
832 if (!sock || !sock->
ssl || !sock->
ssl->
ssl) {
837 if (!DTLSv1_get_timeout(sock->
ssl->
ssl, timeleft)) {
838 timeleft->tv_sec = 0;
839 timeleft->tv_usec = defusec;
852 DTLSv1_handle_timeout(sock->
ssl->
ssl);
const SSL_METHOD * meth
SSL method.
SSL data structure for enabling encryption on sockets.
union sockstruct addr
system socket data structure.
void * sslv3_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for SSLv3.
void ssl_shutdown(void *ssl, int sock)
Shutdown the SSL connection.
struct sockaddr_un un
Unix sockets.
int objref(void *data)
Reference a object.
#define testflag(obj, flag)
Atomically test a flag in the flags field of a referenced object.
struct fwsocket * dtls_listenssl(struct fwsocket *sock)
Implementation of "listen" for DTLSv1.
int socketread(struct fwsocket *sock, void *buf, int num)
Read from a socket into a buffer.
int objlock(void *data)
Lock the reference.
void sha256hmac(unsigned char *buff, const void *data, unsigned long len, const void *key, unsigned long klen)
Hash Message Authentication Codes (HMAC) SHA2-256.
void dtlshandltimeout(struct fwsocket *sock)
Handle DTLSv1 timeout.
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
int socketwrite(struct fwsocket *sock, const void *buf, int num)
Write a buffer to a socket.
struct ssldata * parent
Parent structure.
void sslstartup(void)
Initialise SSL support this should be called at startup.
void * sslv2_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for SSLv2 (If available)
void * dtlsv1_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for DTLSv1.
void * tlsv1_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for TLSv1.
#define setflag(obj, flag)
Atomically set a flag in the flags field of a referenced object.
This session is server mode.
int socketread_d(struct fwsocket *sock, void *buf, int num, union sockstruct *addr)
Read from a socket into a buffer.
DTS Application library API Include file.
void tlsaccept(struct fwsocket *sock, struct ssldata *orig)
Create SSL session for new connection.
SSL has been requested on this socket dont allow clear read/send.
void startsslclient(struct fwsocket *sock)
Start SSL on a client socket.
UDP connection is listening.
SSLFLAGS
SSL configuration flags.
#define COOKIE_SECRET_LENGTH
length of cookie secret using SHA2-256 HMAC
int proto
Socket protocol.
int sha256cmp(unsigned char *digest1, unsigned char *digest2)
Compare two SHA2-256 hashes.
struct ssldata * ssl
SSL structure for encryption.
int genrand(void *buf, int len)
Generate random sequence.
SSL_CTX * ctx
OpenSSL context.
void dtlstimeout(struct fwsocket *sock, struct timeval *timeleft, int defusec)
Get DTLSv1 timeout setting todefault timeout.
int socketwrite_d(struct fwsocket *sock, const void *buf, int num, union sockstruct *addr)
Write a buffer to a socket.
struct fwsocket * make_socket(int family, int type, int proto, void *ssl)
Allocate a socket structure and return reference.
int objunlock(void *data)
Unlock a reference.
This session is client mode.
struct sockaddr_storage ss
Sockaddr storage is a "magic" struct been able to hold IPv4 or IPv6.
struct sockaddr sa
Base socket addr structure.
SSLv2 This may not be available due to security issues.
void dtsl_serveropts(struct fwsocket *sock)
Start up the DTLSv1 Server.
Socket union describing all address types.
enum sock_flags flags
Socket control flags.
int objunref(void *data)
Drop reference held.
The socket is going away stop processing in its thread.