treat orderly shutdown as error
[rofl0r-rocksock.git] / rocksock_cyassl.c
blob036e7d122b8eb8595ab9a5606e45f6bff640b633
1 /*
2 * author: rofl0r (C) 2011 - 2013
3 * License: LGPL 2.1+ with static linking exception
4 */
6 #include "rocksock_ssl_internal.h"
7 #include "rocksock_internal.h"
9 #include <cyassl/ssl.h>
12 #ifndef ROCKSOCK_FILENAME
13 #define ROCKSOCK_FILENAME __FILE__
14 #endif
16 //RcB: LINK "-lcyassl"
18 void rocksock_init_ssl(void) {
19 CyaSSL_Init();
20 //CyaSSL_Debugging_ON(); /* cyassl needs to be compiled with --enable-debug */
23 void rocksock_free_ssl(void) {
24 CyaSSL_Cleanup();
27 const char* rocksock_ssl_strerror(rocksock *sock, int error) {
28 return CyaSSL_ERR_reason_error_string(error);
31 #include <errno.h>
32 int rocksock_ssl_send(rocksock* sock, char* buf, size_t sz) {
33 int ret = CyaSSL_write(sock->ssl, buf, sz);
34 if (ret < 0 && CyaSSL_get_error(sock->ssl, ret) == SSL_ERROR_WANT_WRITE) errno = EWOULDBLOCK;
35 return ret;
38 int rocksock_ssl_recv(rocksock* sock, char* buf, size_t sz) {
39 int ret = CyaSSL_read(sock->ssl, buf, sz);
40 if (ret < 0 && CyaSSL_get_error(sock->ssl, ret) == SSL_ERROR_WANT_READ) errno = EWOULDBLOCK;
41 return ret;
44 int rocksock_ssl_connect_fd(rocksock* sock) {
45 sock->sslctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
46 if (!sock->sslctx) {
47 return rocksock_seterror(sock, RS_ET_OWN, RS_E_SSL_GENERIC, ROCKSOCK_FILENAME, __LINE__);
50 /* FIXME cyassl needs explicit passing of certificates
51 however the location may vary by system.
52 until resolved, certificate checks are disabled */
53 CyaSSL_CTX_set_verify(sock->sslctx, SSL_VERIFY_NONE, 0);
55 sock->ssl = CyaSSL_new(sock->sslctx);
56 if (!sock->ssl) {
57 return rocksock_seterror(sock, RS_ET_OWN, RS_E_SSL_GENERIC, ROCKSOCK_FILENAME, __LINE__);
60 CyaSSL_set_fd(sock->ssl, sock->socket);
61 //CyaSSL_set_using_nonblock(sock->ssl, 0);
63 int ret = CyaSSL_connect(sock->ssl);
64 if(ret != SSL_SUCCESS) {
65 /* when CyaSSL_connect gets interrupted by a timeout, it reports LENGTH_ERROR instead of
66 SSL_ERROR_WANT_READ as it's supposed to do (see cyassl github issue #65).
67 since that value is not exported we can't catch it without hardcoding the value, so we will wait for a fix */
68 if((ret = CyaSSL_get_error(sock->ssl, ret)) == SSL_ERROR_WANT_READ)
69 return rocksock_seterror(sock, RS_ET_OWN, RS_E_HIT_CONNECTTIMEOUT, ROCKSOCK_FILENAME, __LINE__);
70 return rocksock_seterror(sock, RS_ET_SSL, ret, ROCKSOCK_FILENAME, __LINE__);
72 return 0;
75 void rocksock_ssl_free_context(rocksock *sock) {
76 if(sock->ssl) {
77 CyaSSL_shutdown(sock->ssl);
78 CyaSSL_free(sock->ssl);
79 CyaSSL_CTX_free(sock->sslctx);
80 sock->ssl = 0;
84 int rocksock_ssl_pending(rocksock *sock) {
85 return CyaSSL_pending(sock->ssl);
88 int rocksock_ssl_peek(rocksock* sock, int *result) {
89 int ret;
90 char buf[4];
91 ret = CyaSSL_peek(sock->ssl, buf, 1);
92 if(ret >= 0) *result = 1;
93 else {
94 ret = CyaSSL_get_error(sock->ssl, 0);
95 if(ret == SSL_ERROR_WANT_READ) return rocksock_seterror(sock, RS_ET_OWN, RS_E_HIT_READTIMEOUT, ROCKSOCK_FILENAME, __LINE__);
96 return rocksock_seterror(sock, RS_ET_SSL, ret, ROCKSOCK_FILENAME, __LINE__);
98 return rocksock_seterror(sock, RS_ET_NO_ERROR, 0, NULL, 0);