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 int err
= CyaSSL_get_error(sock
->ssl
, 0);
29 return CyaSSL_ERR_reason_error_string(err
);
32 int rocksock_ssl_send(rocksock
* sock
, char* buf
, size_t sz
) {
34 do ret
= CyaSSL_write(sock
->ssl
, buf
, sz
);
35 while (ret
<= 0 && CyaSSL_get_error(sock
->ssl
, ret
) == SSL_ERROR_WANT_WRITE
);
39 int rocksock_ssl_recv(rocksock
* sock
, char* buf
, size_t sz
) {
41 do ret
= CyaSSL_read(sock
->ssl
, buf
, sz
);
42 while (ret
<= 0 && CyaSSL_get_error(sock
->ssl
, ret
) == SSL_ERROR_WANT_READ
);
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 return rocksock_seterror(sock
, RS_ET_SSL
, ret
, ROCKSOCK_FILENAME
, __LINE__
);
72 void rocksock_ssl_free_context(rocksock
*sock
) {
74 CyaSSL_shutdown(sock
->ssl
);
75 CyaSSL_free(sock
->ssl
);
76 CyaSSL_CTX_free(sock
->sslctx
);
81 int rocksock_ssl_pending(rocksock
*sock
) {
82 return CyaSSL_pending(sock
->ssl
);
85 int rocksock_ssl_peek(rocksock
* sock
, int *result
) {
89 ret
= CyaSSL_peek(sock
->ssl
, buf
, 1);
90 if(ret
>= 0) *result
= 1;
91 /* when SSL_peek returns 0, it means a disconnect.
92 there's no way to get "peek was successful, no error, but also no data"
93 and that means that it must block until data is there or an error happened.
94 we have to return 1 in that case as well so the subsequent read returns 0,
95 which is the proper way to detect a disconnect. */
97 ret
= CyaSSL_get_error(sock
->ssl
, 0);
98 if(ret
== SSL_ERROR_WANT_READ
) goto again
;
99 return rocksock_seterror(sock
, RS_ET_SSL
, ret
, ROCKSOCK_FILENAME
, __LINE__
);
101 return rocksock_seterror(sock
, RS_ET_NO_ERROR
, 0, NULL
, 0);