2 * author: rofl0r (C) 2011 - 2013
3 * License: LGPL 2.1+ with static linking exception
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__
18 #pragma RcB2 LINK "-lwolfssl"
20 void rocksock_init_ssl(void) {
22 //CyaSSL_Debugging_ON(); /* cyassl needs to be compiled with --enable-debug */
25 void rocksock_free_ssl(void) {
29 const char* rocksock_ssl_strerror(rocksock
*sock
, int error
) {
30 return CyaSSL_ERR_reason_error_string(error
);
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
;
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
;
46 int rocksock_ssl_connect_fd(rocksock
* sock
) {
47 sock
->sslctx
= CyaSSL_CTX_new(CyaSSLv23_client_method());
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
);
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__
);
77 void rocksock_ssl_free_context(rocksock
*sock
) {
79 CyaSSL_shutdown(sock
->ssl
);
80 CyaSSL_free(sock
->ssl
);
81 CyaSSL_CTX_free(sock
->sslctx
);
86 int rocksock_ssl_pending(rocksock
*sock
) {
87 return CyaSSL_pending(sock
->ssl
);
90 int rocksock_ssl_peek(rocksock
* sock
, int *result
) {
93 ret
= CyaSSL_peek(sock
->ssl
, buf
, 1);
94 if(ret
>= 0) *result
= 1;
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);