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 <openssl/crypto.h>
10 #include <openssl/x509.h>
11 #include <openssl/pem.h>
12 #include <openssl/ssl.h>
13 #include <openssl/err.h>
16 #ifndef ROCKSOCK_FILENAME
17 #define ROCKSOCK_FILENAME __FILE__
20 //RcB: LINK "-lssl -lcrypto -lz"
22 void rocksock_init_ssl(void) {
24 SSL_load_error_strings();
25 SSLeay_add_ssl_algorithms();
28 void rocksock_free_ssl(void) {
29 // TODO: there are still 3 memblocks allocated from SSL_library_init (88 bytes)
33 CRYPTO_cleanup_all_ex_data();
36 const char* rocksock_ssl_strerror(rocksock
*sock
, int error
) {
37 return ERR_reason_error_string(SSL_get_error(sock
->ssl
, error
));
41 int rocksock_ssl_send(rocksock
* sock
, char* buf
, size_t sz
) {
42 int ret
= SSL_write(sock
->ssl
, buf
, sz
);
43 if (ret
< 0 && SSL_get_error(sock
->ssl
, ret
) == SSL_ERROR_WANT_WRITE
) errno
= EWOULDBLOCK
;
47 int rocksock_ssl_recv(rocksock
* sock
, char* buf
, size_t sz
) {
48 int ret
= SSL_read(sock
->ssl
, buf
, sz
);
49 if (ret
< 0 && SSL_get_error(sock
->ssl
, ret
) == SSL_ERROR_WANT_READ
) errno
= EWOULDBLOCK
;
53 int rocksock_ssl_connect_fd(rocksock
* sock
) {
54 sock
->sslctx
= SSL_CTX_new(SSLv23_client_method());
56 ERR_print_errors_fp(stderr
);
57 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_SSL_GENERIC
, ROCKSOCK_FILENAME
, __LINE__
);
59 sock
->ssl
= SSL_new(sock
->sslctx
);
61 ERR_print_errors_fp(stderr
);
62 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_SSL_GENERIC
, ROCKSOCK_FILENAME
, __LINE__
);
64 SSL_set_fd(sock
->ssl
, sock
->socket
);
65 int ret
= SSL_connect(sock
->ssl
);
67 if((ret
= SSL_get_error(sock
->ssl
, ret
)) == SSL_ERROR_WANT_READ
)
68 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_HIT_CONNECTTIMEOUT
, ROCKSOCK_FILENAME
, __LINE__
);
69 //ERR_print_errors_fp(stderr);
70 //printf("%dxxx\n", SSL_get_error(sock->ssl, ret));
71 return rocksock_seterror(sock
, RS_ET_SSL
, ret
, ROCKSOCK_FILENAME
, __LINE__
);
76 void rocksock_ssl_free_context(rocksock
*sock
) {
78 SSL_shutdown(sock
->ssl
);
80 SSL_CTX_free(sock
->sslctx
);
85 int rocksock_ssl_pending(rocksock
*sock
) {
86 return SSL_pending(sock
->ssl
);
89 int rocksock_ssl_peek(rocksock
* sock
, int *result
) {
93 ret
= SSL_peek(sock
->ssl
, buf
, 1);
94 if(ret
>= 0) *result
= 1;
96 ret
= SSL_get_error(sock
->ssl
, ret
);
97 if(ret
== SSL_ERROR_WANT_READ
)
98 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_HIT_READTIMEOUT
, ROCKSOCK_FILENAME
, __LINE__
); //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);