rocksock_readline: change semantics: trailing \n is removed
[rofl0r-rocksock.git] / rocksock_cyassl.c
blob1707bba03d2f0acbbca907a1c88febc5f9131e32
1 /*
2 * author: rofl0r (C) 2011 - 2013
3 * License: LGPL 2.1+ with static linking exception
4 */
6 #ifdef USE_CYASSL
8 #include "rocksock_ssl_internal.h"
9 #include "rocksock_internal.h"
11 #include <cyassl/ssl.h>
14 #ifndef ROCKSOCK_FILENAME
15 #define ROCKSOCK_FILENAME __FILE__
16 #endif
18 //RcB: LINK "-lcyassl"
20 void rocksock_init_ssl(void) {
21 CyaSSL_Init();
22 //CyaSSL_Debugging_ON(); /* cyassl needs to be compiled with --enable-debug */
25 void rocksock_free_ssl(void) {
26 CyaSSL_Cleanup();
29 const char* rocksock_ssl_strerror(rocksock *sock, int error) {
30 return CyaSSL_ERR_reason_error_string(error);
33 #include <errno.h>
34 int rocksock_ssl_send(rocksock* sock, char* buf, size_t sz) {
35 int ret = CyaSSL_write(sock->ssl, buf, sz);
36 if (ret < 0 && CyaSSL_get_error(sock->ssl, ret) == SSL_ERROR_WANT_WRITE) errno = EWOULDBLOCK;
37 return ret;
40 int rocksock_ssl_recv(rocksock* sock, char* buf, size_t sz) {
41 int ret = CyaSSL_read(sock->ssl, buf, sz);
42 if (ret < 0 && CyaSSL_get_error(sock->ssl, ret) == SSL_ERROR_WANT_READ) errno = EWOULDBLOCK;
43 return ret;
46 int rocksock_ssl_connect_fd(rocksock* sock) {
47 sock->sslctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
48 if (!sock->sslctx) {
49 return rocksock_seterror(sock, RS_ET_OWN, RS_E_SSL_GENERIC, ROCKSOCK_FILENAME, __LINE__);
52 /* FIXME cyassl needs explicit passing of certificates
53 however the location may vary by system.
54 until resolved, certificate checks are disabled */
55 CyaSSL_CTX_set_verify(sock->sslctx, SSL_VERIFY_NONE, 0);
57 sock->ssl = CyaSSL_new(sock->sslctx);
58 if (!sock->ssl) {
59 return rocksock_seterror(sock, RS_ET_OWN, RS_E_SSL_GENERIC, ROCKSOCK_FILENAME, __LINE__);
62 CyaSSL_set_fd(sock->ssl, sock->socket);
63 //CyaSSL_set_using_nonblock(sock->ssl, 0);
65 int ret = CyaSSL_connect(sock->ssl);
66 if(ret != SSL_SUCCESS) {
67 /* when CyaSSL_connect gets interrupted by a timeout, it reports LENGTH_ERROR instead of
68 SSL_ERROR_WANT_READ as it's supposed to do (see cyassl github issue #65).
69 since that value is not exported we can't catch it without hardcoding the value, so we will wait for a fix */
70 if((ret = CyaSSL_get_error(sock->ssl, ret)) == SSL_ERROR_WANT_READ)
71 return rocksock_seterror(sock, RS_ET_OWN, RS_E_HIT_CONNECTTIMEOUT, ROCKSOCK_FILENAME, __LINE__);
72 return rocksock_seterror(sock, RS_ET_SSL, ret, ROCKSOCK_FILENAME, __LINE__);
74 return 0;
77 void rocksock_ssl_free_context(rocksock *sock) {
78 if(sock->ssl) {
79 CyaSSL_shutdown(sock->ssl);
80 CyaSSL_free(sock->ssl);
81 CyaSSL_CTX_free(sock->sslctx);
82 sock->ssl = 0;
86 int rocksock_ssl_pending(rocksock *sock) {
87 return CyaSSL_pending(sock->ssl);
90 int rocksock_ssl_peek(rocksock* sock, int *result) {
91 int ret;
92 char buf[4];
93 ret = CyaSSL_peek(sock->ssl, buf, 1);
94 if(ret >= 0) *result = 1;
95 else {
96 ret = CyaSSL_get_error(sock->ssl, 0);
97 if(ret == SSL_ERROR_WANT_READ) return rocksock_seterror(sock, RS_ET_OWN, RS_E_HIT_READTIMEOUT, ROCKSOCK_FILENAME, __LINE__);
98 return rocksock_seterror(sock, RS_ET_SSL, ret, ROCKSOCK_FILENAME, __LINE__);
100 return rocksock_seterror(sock, RS_ET_OWN, 0, NULL, 0);
103 #endif