summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-02-04 17:41:54 +0100
committerFelix Fietkau <nbd@openwrt.org>2013-02-04 22:55:57 +0100
commitf48abdecd43435809777629e20a257448a68a578 (patch)
tree9be573de84585cb9f91bd5a03e06124e41f4bb6a
parentad9606401da9bb32bbf4003eea1f0e93b8e8f16c (diff)
downloadustream-ssl-f48abdecd43435809777629e20a257448a68a578.tar.gz
split cyassl and openssl sources, add ssl library abstraction
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-rw-r--r--CMakeLists.txt6
-rw-r--r--ustream-internal.h41
-rw-r--r--ustream-io-cyassl.c70
-rw-r--r--ustream-io-openssl.c (renamed from ustream-io.c)56
-rw-r--r--ustream-openssl.c148
-rw-r--r--ustream-openssl.h (renamed from ustream-io.h)21
-rw-r--r--ustream-ssl.c156
-rw-r--r--ustream-ssl.h2
8 files changed, 307 insertions, 193 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f39ca23..6af1750 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,13 +10,15 @@ IF(APPLE)
LINK_DIRECTORIES(/opt/local/lib)
ENDIF()
-IF (CYASSL)
+IF(CYASSL)
+ SET(SSL_SRC ustream-io-cyassl.c ustream-openssl.c)
SET(SSL_LIB cyassl m)
ELSE()
+ SET(SSL_SRC ustream-io-openssl.c ustream-openssl.c)
SET(SSL_LIB crypto ssl)
ENDIF()
-ADD_LIBRARY(ustream-ssl SHARED ustream-ssl.c ustream-io.c)
+ADD_LIBRARY(ustream-ssl SHARED ustream-ssl.c ${SSL_SRC})
TARGET_LINK_LIBRARIES(ustream-ssl ubox ${SSL_LIB})
ADD_EXECUTABLE(ustream-example ustream-example.c)
diff --git a/ustream-internal.h b/ustream-internal.h
new file mode 100644
index 0000000..40f1d4e
--- /dev/null
+++ b/ustream-internal.h
@@ -0,0 +1,41 @@
+/*
+ * ustream-ssl - library for SSL over ustream
+ *
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __USTREAM_BIO_H
+#define __USTREAM_BIO_H
+
+#define __hidden __attribute__((visibility("hidden")))
+
+#include "ustream-openssl.h"
+
+enum ssl_conn_status {
+ U_SSL_OK = 0,
+ U_SSL_PENDING = -1,
+ U_SSL_ERROR = -2,
+};
+
+void ustream_set_io(void *ctx, void *ssl, struct ustream *s);
+void *__ustream_ssl_context_new(bool server);
+int __ustream_ssl_set_crt_file(void *ctx, const char *file);
+int __ustream_ssl_set_key_file(void *ctx, const char *file);
+void __ustream_ssl_context_free(void *ctx);
+enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us);
+int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len);
+int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len);
+
+#endif
diff --git a/ustream-io-cyassl.c b/ustream-io-cyassl.c
new file mode 100644
index 0000000..1787cd0
--- /dev/null
+++ b/ustream-io-cyassl.c
@@ -0,0 +1,70 @@
+/*
+ * ustream-ssl - library for SSL over ustream
+ *
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+#include <libubox/ustream.h>
+
+#include "ustream-ssl.h"
+#include "ustream-internal.h"
+
+/* not defined in the header file */
+typedef int (*CallbackIORecv)(char *buf, int sz, void *ctx);
+typedef int (*CallbackIOSend)(char *buf, int sz, void *ctx);
+
+void SetCallbackIORecv_Ctx(SSL_CTX*, CallbackIORecv);
+void SetCallbackIOSend_Ctx(SSL_CTX*, CallbackIOSend);
+void SetCallbackIO_ReadCtx(SSL* ssl, void *rctx);
+void SetCallbackIO_WriteCtx(SSL* ssl, void *wctx);
+
+static int s_ustream_read(char *buf, int len, void *ctx)
+{
+ struct ustream *s = ctx;
+ char *sbuf;
+ int slen;
+
+ if (s->eof)
+ return -3;
+
+ sbuf = ustream_get_read_buf(s, &slen);
+ if (slen > len)
+ slen = len;
+
+ if (!slen)
+ return -2;
+
+ memcpy(buf, sbuf, slen);
+ ustream_consume(s, slen);
+
+ return slen;
+}
+
+static int s_ustream_write(char *buf, int len, void *ctx)
+{
+ struct ustream *s = ctx;
+
+ return ustream_write(s, buf, len, false);
+}
+
+__hidden void ustream_set_io(void *ctx, void *ssl, struct ustream *conn)
+{
+ SetCallbackIO_ReadCtx(ssl, conn);
+ SetCallbackIO_WriteCtx(ssl, conn);
+ SetCallbackIORecv_Ctx(ctx, s_ustream_read);
+ SetCallbackIOSend_Ctx(ctx, s_ustream_write);
+}
diff --git a/ustream-io.c b/ustream-io-openssl.c
index b04b844..41e69f7 100644
--- a/ustream-io.c
+++ b/ustream-io-openssl.c
@@ -20,58 +20,8 @@
#include <libubox/ustream.h>
-#include "ustream-io.h"
#include "ustream-ssl.h"
-
-#ifdef CYASSL_OPENSSL_H_
-
-/* not defined in the header file */
-typedef int (*CallbackIORecv)(char *buf, int sz, void *ctx);
-typedef int (*CallbackIOSend)(char *buf, int sz, void *ctx);
-
-void SetCallbackIORecv_Ctx(SSL_CTX*, CallbackIORecv);
-void SetCallbackIOSend_Ctx(SSL_CTX*, CallbackIOSend);
-void SetCallbackIO_ReadCtx(SSL* ssl, void *rctx);
-void SetCallbackIO_WriteCtx(SSL* ssl, void *wctx);
-
-static int s_ustream_read(char *buf, int len, void *ctx)
-{
- struct ustream *s = ctx;
- char *sbuf;
- int slen;
-
- if (s->eof)
- return -3;
-
- sbuf = ustream_get_read_buf(s, &slen);
- if (slen > len)
- slen = len;
-
- if (!slen)
- return -2;
-
- memcpy(buf, sbuf, slen);
- ustream_consume(s, slen);
-
- return slen;
-}
-
-static int s_ustream_write(char *buf, int len, void *ctx)
-{
- struct ustream *s = ctx;
-
- return ustream_write(s, buf, len, false);
-}
-
-void ustream_set_io(SSL_CTX *ctx, SSL *ssl, struct ustream *conn)
-{
- SetCallbackIO_ReadCtx(ssl, conn);
- SetCallbackIO_WriteCtx(ssl, conn);
- SetCallbackIORecv_Ctx(ctx, s_ustream_read);
- SetCallbackIOSend_Ctx(ctx, s_ustream_write);
-}
-
-#else
+#include "ustream-internal.h"
static int
s_ustream_new(BIO *b)
@@ -185,10 +135,8 @@ static BIO *ustream_bio_new(struct ustream *s)
return bio;
}
-void ustream_set_io(SSL_CTX *ctx, SSL *ssl, struct ustream *conn)
+__hidden void ustream_set_io(void *ctx, void *ssl, struct ustream *conn)
{
BIO *bio = ustream_bio_new(conn);
SSL_set_bio(ssl, bio, bio);
}
-
-#endif
diff --git a/ustream-openssl.c b/ustream-openssl.c
new file mode 100644
index 0000000..2d569f3
--- /dev/null
+++ b/ustream-openssl.c
@@ -0,0 +1,148 @@
+/*
+ * ustream-ssl - library for SSL over ustream
+ *
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ustream-ssl.h"
+#include "ustream-internal.h"
+
+__hidden void * __ustream_ssl_context_new(bool server)
+{
+ static bool _init = false;
+ const void *m;
+ SSL_CTX *c;
+
+ if (!_init) {
+ SSL_load_error_strings();
+ SSL_library_init();
+ _init = true;
+ }
+
+#ifdef CYASSL_OPENSSL_H_
+ if (server)
+ m = SSLv23_server_method();
+ else
+ m = SSLv23_client_method();
+#else
+ if (server)
+ m = TLSv1_server_method();
+ else
+ m = TLSv1_client_method();
+#endif
+
+ c = SSL_CTX_new((void *) m);
+ if (!c)
+ return NULL;
+
+ if (server)
+ SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL);
+
+ return c;
+}
+
+__hidden int __ustream_ssl_set_crt_file(void *ctx, const char *file)
+{
+ int ret;
+
+ ret = SSL_CTX_use_certificate_file(ctx, file, SSL_FILETYPE_PEM);
+ if (ret < 1)
+ ret = SSL_CTX_use_certificate_file(ctx, file, SSL_FILETYPE_ASN1);
+
+ if (ret < 1)
+ return -1;
+
+ return 0;
+}
+
+__hidden int __ustream_ssl_set_key_file(void *ctx, const char *file)
+{
+ int ret;
+
+ ret = SSL_CTX_use_PrivateKey_file(ctx, file, SSL_FILETYPE_PEM);
+ if (ret < 1)
+ ret = SSL_CTX_use_PrivateKey_file(ctx, file, SSL_FILETYPE_ASN1);
+
+ if (ret < 1)
+ return -1;
+
+ return 0;
+}
+
+__hidden void __ustream_ssl_context_free(void *ctx)
+{
+ SSL_CTX_free(ctx);
+}
+
+static void ustream_ssl_error(struct ustream_ssl *us, int ret)
+{
+ us->error = ret;
+ uloop_timeout_set(&us->error_timer, 0);
+}
+
+__hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us)
+{
+ void *ssl = us->ssl;
+ int r;
+
+ if (us->server)
+ r = SSL_accept(ssl);
+ else
+ r = SSL_connect(ssl);
+
+ if (r == 1)
+ return U_SSL_OK;
+
+ r = SSL_get_error(ssl, r);
+ if (r == SSL_ERROR_WANT_READ || r == SSL_ERROR_WANT_WRITE)
+ return U_SSL_PENDING;
+
+ ustream_ssl_error(us, r);
+ return U_SSL_ERROR;
+}
+
+__hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len)
+{
+ void *ssl = us->ssl;
+ int ret = SSL_write(ssl, buf, len);
+
+ if (ret < 0) {
+ int err = SSL_get_error(ssl, ret);
+ if (err == SSL_ERROR_WANT_WRITE)
+ return 0;
+
+ ustream_ssl_error(us, err);
+ return -1;
+ }
+
+ return ret;
+}
+
+__hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len)
+{
+ int ret = SSL_read(us->ssl, buf, len);
+
+ if (ret < 0) {
+ ret = SSL_get_error(us->ssl, ret);
+ if (ret == SSL_ERROR_WANT_READ)
+ return U_SSL_PENDING;
+
+ ustream_ssl_error(us, ret);
+ return U_SSL_ERROR;
+ }
+
+ return ret;
+}
+
diff --git a/ustream-io.h b/ustream-openssl.h
index 1e660e7..76d2bad 100644
--- a/ustream-io.h
+++ b/ustream-openssl.h
@@ -16,14 +16,27 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef __USTREAM_BIO_H
-#define __USTREAM_BIO_H
+#ifndef __USTREAM_OPENSSL_H
+#define __USTREAM_OPENSSL_H
#include <openssl/ssl.h>
#include <openssl/err.h>
+#include <stdbool.h>
-#include "ustream-ssl.h"
+static inline void *__ustream_ssl_session_new(void *ctx)
+{
+ return SSL_new(ctx);
+}
-void ustream_set_io(SSL_CTX *ctx, SSL *ssl, struct ustream *s);
+static inline void __ustream_ssl_session_free(void *ssl)
+{
+ SSL_shutdown(ssl);
+ SSL_free(ssl);
+}
+
+static inline char *__ustream_ssl_strerror(int error, char *buffer, int len)
+{
+ return ERR_error_string(error, buffer);
+}
#endif
diff --git a/ustream-ssl.c b/ustream-ssl.c
index bbc6b11..0ae5df6 100644
--- a/ustream-ssl.c
+++ b/ustream-ssl.c
@@ -17,26 +17,10 @@
*/
#include <errno.h>
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
#include <libubox/ustream.h>
-#include "ustream-io.h"
-#include "ustream-ssl.h"
-
-static void ssl_init(void)
-{
- static bool _init = false;
-
- if (_init)
- return;
-
- SSL_load_error_strings();
- SSL_library_init();
- _init = true;
-}
+#include "ustream-ssl.h"
+#include "ustream-internal.h"
static void ustream_ssl_error_cb(struct uloop_timeout *t)
{
@@ -45,39 +29,19 @@ static void ustream_ssl_error_cb(struct uloop_timeout *t)
int error = us->error;
if (us->notify_error)
- us->notify_error(us, error, ERR_error_string(us->error, buffer));
-}
-
-static void ustream_ssl_error(struct ustream_ssl *us, int error)
-{
- us->error = error;
- uloop_timeout_set(&us->error_timer, 0);
+ us->notify_error(us, error, __ustream_ssl_strerror(us->error, buffer, sizeof(buffer)));
}
static void ustream_ssl_check_conn(struct ustream_ssl *us)
{
- int ret;
-
if (us->connected || us->error)
return;
- if (us->server)
- ret = SSL_accept(us->ssl);
- else
- ret = SSL_connect(us->ssl);
-
- if (ret == 1) {
+ if (__ustream_ssl_connect(us) == U_SSL_OK) {
us->connected = true;
if (us->notify_connected)
us->notify_connected(us);
- return;
}
-
- ret = SSL_get_error(us->ssl, ret);
- if (ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE)
- return;
-
- ustream_ssl_error(us, ret);
}
static bool __ustream_ssl_poll(struct ustream *s)
@@ -96,24 +60,21 @@ static bool __ustream_ssl_poll(struct ustream *s)
if (!len)
break;
- ret = SSL_read(us->ssl, buf, len);
- if (ret < 0) {
- ret = SSL_get_error(us->ssl, ret);
-
- if (ret == SSL_ERROR_WANT_READ)
- break;
-
- ustream_ssl_error(us, ret);
- break;
- }
- if (ret == 0) {
+ ret = __ustream_ssl_read(us, buf, len);
+ switch (ret) {
+ case U_SSL_PENDING:
+ return more;
+ case U_SSL_ERROR:
+ return false;
+ case 0:
us->stream.eof = true;
ustream_state_change(&us->stream);
- break;
+ return false;
+ default:
+ ustream_fill_read(&us->stream, ret);
+ more = true;
+ continue;
}
-
- ustream_fill_read(&us->stream, ret);
- more = true;
} while (1);
return more;
@@ -141,7 +102,6 @@ static void ustream_ssl_notify_state(struct ustream *s)
static int ustream_ssl_write(struct ustream *s, const char *buf, int len, bool more)
{
struct ustream_ssl *us = container_of(s, struct ustream_ssl, stream);
- int ret;
if (!us->connected || us->error)
return 0;
@@ -149,14 +109,7 @@ static int ustream_ssl_write(struct ustream *s, const char *buf, int len, bool m
if (us->conn->w.data_bytes)
return 0;
- ret = SSL_write(us->ssl, buf, len);
- if (ret < 0) {
- int err = SSL_get_error(us->ssl, ret);
- if (err == SSL_ERROR_WANT_WRITE)
- return 0;
- }
-
- return ret;
+ return __ustream_ssl_write(us, buf, len);
}
static void ustream_ssl_set_read_blocked(struct ustream *s)
@@ -178,8 +131,7 @@ static void ustream_ssl_free(struct ustream *s)
}
uloop_timeout_cancel(&us->error_timer);
- SSL_shutdown(us->ssl);
- SSL_free(us->ssl);
+ __ustream_ssl_session_free(us->ssl);
us->ctx = NULL;
us->ssl = NULL;
us->conn = NULL;
@@ -212,68 +164,6 @@ static void ustream_ssl_stream_init(struct ustream_ssl *us)
ustream_init_defaults(s);
}
-static void *_ustream_ssl_context_new(bool server)
-{
- SSL_CTX *c;
- const void *m;
-
- ssl_init();
-
-#ifdef CYASSL_OPENSSL_H_
- if (server)
- m = SSLv23_server_method();
- else
- m = SSLv23_client_method();
-#else
- if (server)
- m = TLSv1_server_method();
- else
- m = TLSv1_client_method();
-#endif
-
- c = SSL_CTX_new((void *) m);
- if (!c)
- return NULL;
-
- if (server)
- SSL_CTX_set_verify(c, SSL_VERIFY_NONE, NULL);
-
- return c;
-}
-
-static int _ustream_ssl_context_set_crt_file(void *ctx, const char *file)
-{
- int ret;
-
- ret = SSL_CTX_use_certificate_file(ctx, file, SSL_FILETYPE_PEM);
- if (ret < 1)
- ret = SSL_CTX_use_certificate_file(ctx, file, SSL_FILETYPE_ASN1);
-
- if (ret < 1)
- return -1;
-
- return 0;
-}
-
-static int _ustream_ssl_context_set_key_file(void *ctx, const char *file)
-{
- int ret;
-
- ret = SSL_CTX_use_PrivateKey_file(ctx, file, SSL_FILETYPE_PEM);
- if (ret < 1)
- ret = SSL_CTX_use_PrivateKey_file(ctx, file, SSL_FILETYPE_ASN1);
-
- if (ret < 1)
- return -1;
-
- return 0;
-}
-
-static void _ustream_ssl_context_free(void *ctx)
-{
- SSL_CTX_free(ctx);
-}
-
static int _ustream_ssl_init(struct ustream_ssl *us, struct ustream *conn, void *ctx, bool server)
{
us->error_timer.cb = ustream_ssl_error_cb;
@@ -281,7 +171,7 @@ static int _ustream_ssl_init(struct ustream_ssl *us, struct ustream *conn, void
us->conn = conn;
us->ctx = ctx;
- us->ssl = SSL_new(us->ctx);
+ us->ssl = __ustream_ssl_session_new(us->ctx);
if (!us->ssl)
return -ENOMEM;
@@ -293,9 +183,9 @@ static int _ustream_ssl_init(struct ustream_ssl *us, struct ustream *conn, void
}
const struct ustream_ssl_ops ustream_ssl_ops = {
- .context_new = _ustream_ssl_context_new,
- .context_set_crt_file = _ustream_ssl_context_set_crt_file,
- .context_set_key_file = _ustream_ssl_context_set_key_file,
- .context_free = _ustream_ssl_context_free,
+ .context_new = __ustream_ssl_context_new,
+ .context_set_crt_file = __ustream_ssl_set_crt_file,
+ .context_set_key_file = __ustream_ssl_set_key_file,
+ .context_free = __ustream_ssl_context_free,
.init = _ustream_ssl_init,
};
diff --git a/ustream-ssl.h b/ustream-ssl.h
index 21d89d5..aa1ced5 100644
--- a/ustream-ssl.h
+++ b/ustream-ssl.h
@@ -19,6 +19,8 @@
#ifndef __USTREAM_SSL_H
#define __USTREAM_SSL_H
+#include <libubox/ustream.h>
+
struct ustream_ssl {
struct ustream stream;
struct ustream *conn;