2 * author: rofl0r (C) 2011 - 2013
3 * License: LGPL 2.1+ with static linking exception
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__
16 //RcB: LINK "-lcyassl"
18 void rocksock_init_ssl(void) {
20 //CyaSSL_Debugging_ON(); /* cyassl needs to be compiled with --enable-debug */
23 void rocksock_free_ssl(void) {
27 const char* rocksock_ssl_strerror(rocksock
*sock
, int error
) {
28 return CyaSSL_ERR_reason_error_string(error
);
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
;
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
;
44 int rocksock_ssl_connect_fd(rocksock
* sock
) {
45 sock
->sslctx
= CyaSSL_CTX_new(CyaSSLv23_client_method());
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
);
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__
);
75 void rocksock_ssl_free_context(rocksock
*sock
) {
77 CyaSSL_shutdown(sock
->ssl
);
78 CyaSSL_free(sock
->ssl
);
79 CyaSSL_CTX_free(sock
->sslctx
);
84 int rocksock_ssl_pending(rocksock
*sock
) {
85 return CyaSSL_pending(sock
->ssl
);
88 int rocksock_ssl_peek(rocksock
* sock
, int *result
) {
91 ret
= CyaSSL_peek(sock
->ssl
, buf
, 1);
92 if(ret
>= 0) *result
= 1;
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);