split cyassl and openssl sources, add ssl library abstraction
authorFelix Fietkau <nbd@openwrt.org>
Mon, 4 Feb 2013 16:41:54 +0000 (17:41 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 4 Feb 2013 21:55:57 +0000 (22:55 +0100)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
CMakeLists.txt
ustream-internal.h [new file with mode: 0644]
ustream-io-cyassl.c [new file with mode: 0644]
ustream-io-openssl.c [new file with mode: 0644]
ustream-io.c [deleted file]
ustream-io.h [deleted file]
ustream-openssl.c [new file with mode: 0644]
ustream-openssl.h [new file with mode: 0644]
ustream-ssl.c
ustream-ssl.h

index f39ca23384b114df33ac5aad529ec1ca49b1e4db..6af1750d9b0b655528aaad27ec6c22cb7124f4a2 100644 (file)
@@ -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 (file)
index 0000000..40f1d4e
--- /dev/null
@@ -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 (file)
index 0000000..1787cd0
--- /dev/null
@@ -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-openssl.c b/ustream-io-openssl.c
new file mode 100644 (file)
index 0000000..41e69f7
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * 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"
+
+static int
+s_ustream_new(BIO *b)
+{
+       b->init = 1;
+       b->num = 0;
+       b->ptr = NULL;
+       b->flags = 0;
+       return 1;
+}
+
+static int
+s_ustream_free(BIO *b)
+{
+       if (!b)
+               return 0;
+
+       b->ptr = NULL;
+       b->init = 0;
+       b->flags = 0;
+       return 1;
+}
+
+static int
+s_ustream_read(BIO *b, char *buf, int len)
+{
+       struct ustream *s;
+       char *sbuf;
+       int slen;
+
+       if (!buf || len <= 0)
+               return 0;
+
+       s = (struct ustream *)b->ptr;
+       if (!s)
+               return 0;
+
+       sbuf = ustream_get_read_buf(s, &slen);
+
+       BIO_clear_retry_flags(b);
+       if (!slen) {
+               BIO_set_retry_read(b);
+               return -1;
+       }
+
+       if (slen > len)
+               slen = len;
+
+       memcpy(buf, sbuf, slen);
+       ustream_consume(s, slen);
+
+       return slen;
+}
+
+static int
+s_ustream_write(BIO *b, const char *buf, int len)
+{
+       struct ustream *s;
+
+       if (!buf || len <= 0)
+               return 0;
+
+       s = (struct ustream *)b->ptr;
+       if (!s)
+               return 0;
+
+       return ustream_write(s, buf, len, false);
+}
+
+static int
+s_ustream_gets(BIO *b, char *buf, int len)
+{
+       return -1;
+}
+
+static int
+s_ustream_puts(BIO *b, const char *str)
+{
+       return s_ustream_write(b, str, strlen(str));
+}
+
+static long s_ustream_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+       switch (cmd) {
+       case BIO_CTRL_FLUSH:
+               return 1;
+       default:
+               return 0;
+       };
+}
+
+static BIO_METHOD methods_ustream = {
+       100 | BIO_TYPE_SOURCE_SINK,
+       "ustream",
+       s_ustream_write,
+       s_ustream_read,
+       s_ustream_puts,
+       s_ustream_gets,
+       s_ustream_ctrl,
+       s_ustream_new,
+       s_ustream_free,
+       NULL,
+};
+
+static BIO *ustream_bio_new(struct ustream *s)
+{
+       BIO *bio;
+
+       bio = BIO_new(&methods_ustream);
+       bio->ptr = s;
+       return bio;
+}
+
+__hidden void ustream_set_io(void *ctx, void *ssl, struct ustream *conn)
+{
+       BIO *bio = ustream_bio_new(conn);
+       SSL_set_bio(ssl, bio, bio);
+}
diff --git a/ustream-io.c b/ustream-io.c
deleted file mode 100644 (file)
index b04b844..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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-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
-
-static int
-s_ustream_new(BIO *b)
-{
-       b->init = 1;
-       b->num = 0;
-       b->ptr = NULL;
-       b->flags = 0;
-       return 1;
-}
-
-static int
-s_ustream_free(BIO *b)
-{
-       if (!b)
-               return 0;
-
-       b->ptr = NULL;
-       b->init = 0;
-       b->flags = 0;
-       return 1;
-}
-
-static int
-s_ustream_read(BIO *b, char *buf, int len)
-{
-       struct ustream *s;
-       char *sbuf;
-       int slen;
-
-       if (!buf || len <= 0)
-               return 0;
-
-       s = (struct ustream *)b->ptr;
-       if (!s)
-               return 0;
-
-       sbuf = ustream_get_read_buf(s, &slen);
-
-       BIO_clear_retry_flags(b);
-       if (!slen) {
-               BIO_set_retry_read(b);
-               return -1;
-       }
-
-       if (slen > len)
-               slen = len;
-
-       memcpy(buf, sbuf, slen);
-       ustream_consume(s, slen);
-
-       return slen;
-}
-
-static int
-s_ustream_write(BIO *b, const char *buf, int len)
-{
-       struct ustream *s;
-
-       if (!buf || len <= 0)
-               return 0;
-
-       s = (struct ustream *)b->ptr;
-       if (!s)
-               return 0;
-
-       return ustream_write(s, buf, len, false);
-}
-
-static int
-s_ustream_gets(BIO *b, char *buf, int len)
-{
-       return -1;
-}
-
-static int
-s_ustream_puts(BIO *b, const char *str)
-{
-       return s_ustream_write(b, str, strlen(str));
-}
-
-static long s_ustream_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
-       switch (cmd) {
-       case BIO_CTRL_FLUSH:
-               return 1;
-       default:
-               return 0;
-       };
-}
-
-static BIO_METHOD methods_ustream = {
-       100 | BIO_TYPE_SOURCE_SINK,
-       "ustream",
-       s_ustream_write,
-       s_ustream_read,
-       s_ustream_puts,
-       s_ustream_gets,
-       s_ustream_ctrl,
-       s_ustream_new,
-       s_ustream_free,
-       NULL,
-};
-
-static BIO *ustream_bio_new(struct ustream *s)
-{
-       BIO *bio;
-
-       bio = BIO_new(&methods_ustream);
-       bio->ptr = s;
-       return bio;
-}
-
-void ustream_set_io(SSL_CTX *ctx, SSL *ssl, struct ustream *conn)
-{
-       BIO *bio = ustream_bio_new(conn);
-       SSL_set_bio(ssl, bio, bio);
-}
-
-#endif
diff --git a/ustream-io.h b/ustream-io.h
deleted file mode 100644 (file)
index 1e660e7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-#include "ustream-ssl.h"
-
-void ustream_set_io(SSL_CTX *ctx, SSL *ssl, struct ustream *s);
-
-#endif
diff --git a/ustream-openssl.c b/ustream-openssl.c
new file mode 100644 (file)
index 0000000..2d569f3
--- /dev/null
@@ -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-openssl.h b/ustream-openssl.h
new file mode 100644 (file)
index 0000000..76d2bad
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_OPENSSL_H
+#define __USTREAM_OPENSSL_H
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <stdbool.h>
+
+static inline void *__ustream_ssl_session_new(void *ctx)
+{
+       return SSL_new(ctx);
+}
+
+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
index bbc6b1132871414f588a07e60bf5430fc4dbf538..0ae5df678adc4b441010638f356dd6b97d43ddce 100644 (file)
  */
 
 #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,
 };
index 21d89d57e3136d4d1bf40237c7f7750f518b0a49..aa1ced5943b3228cfc1494918a7901f62d81a87f 100644 (file)
@@ -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;