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 <openssl/crypto.h>
12 #include <openssl/x509.h>
13 #include <openssl/pem.h>
14 #include <openssl/ssl.h>
15 #include <openssl/err.h>
18 #ifndef ROCKSOCK_FILENAME
19 #define ROCKSOCK_FILENAME __FILE__
22 #pragma RcB2 LINK "-lssl" "-lcrypto" "-lz"
24 void rocksock_init_ssl(void) {
26 SSL_load_error_strings();
27 SSLeay_add_ssl_algorithms();
30 void rocksock_free_ssl(void) {
31 // TODO: there are still 3 memblocks allocated from SSL_library_init (88 bytes)
35 CRYPTO_cleanup_all_ex_data();
38 const char* rocksock_ssl_strerror(rocksock
*sock
, int error
) {
39 return ERR_reason_error_string(error
);
43 int rocksock_ssl_send(rocksock
* sock
, char* buf
, size_t sz
) {
44 int ret
= SSL_write(sock
->ssl
, buf
, sz
);
45 if (ret
< 0 && SSL_get_error(sock
->ssl
, ret
) == SSL_ERROR_WANT_WRITE
) errno
= EWOULDBLOCK
;
49 int rocksock_ssl_recv(rocksock
* sock
, char* buf
, size_t sz
) {
50 int ret
= SSL_read(sock
->ssl
, buf
, sz
);
51 if (ret
< 0 && SSL_get_error(sock
->ssl
, ret
) == SSL_ERROR_WANT_READ
) errno
= EWOULDBLOCK
;
55 int rocksock_ssl_connect_fd(rocksock
* sock
) {
56 sock
->sslctx
= SSL_CTX_new(SSLv23_client_method());
58 ERR_print_errors_fp(stderr
);
59 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_SSL_GENERIC
, ROCKSOCK_FILENAME
, __LINE__
);
61 sock
->ssl
= SSL_new(sock
->sslctx
);
63 ERR_print_errors_fp(stderr
);
64 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_SSL_GENERIC
, ROCKSOCK_FILENAME
, __LINE__
);
66 SSL_set_fd(sock
->ssl
, sock
->socket
);
67 int ret
= SSL_connect(sock
->ssl
);
69 if((ret
= SSL_get_error(sock
->ssl
, ret
)) == SSL_ERROR_WANT_READ
)
70 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_HIT_CONNECTTIMEOUT
, ROCKSOCK_FILENAME
, __LINE__
);
71 //ERR_print_errors_fp(stderr);
72 //printf("%dxxx\n", SSL_get_error(sock->ssl, ret));
73 return rocksock_seterror(sock
, RS_ET_SSL
, ret
, ROCKSOCK_FILENAME
, __LINE__
);
78 void rocksock_ssl_free_context(rocksock
*sock
) {
80 SSL_shutdown(sock
->ssl
);
82 SSL_CTX_free(sock
->sslctx
);
87 int rocksock_ssl_pending(rocksock
*sock
) {
88 return SSL_pending(sock
->ssl
);
91 int rocksock_ssl_peek(rocksock
* sock
, int *result
) {
94 ret
= SSL_peek(sock
->ssl
, buf
, 1);
95 if(ret
>= 0) *result
= 1;
97 ret
= SSL_get_error(sock
->ssl
, ret
);
98 if(ret
== SSL_ERROR_WANT_READ
)
99 return rocksock_seterror(sock
, RS_ET_OWN
, RS_E_HIT_READTIMEOUT
, ROCKSOCK_FILENAME
, __LINE__
);
100 return rocksock_seterror(sock
, RS_ET_SSL
, ret
, ROCKSOCK_FILENAME
, __LINE__
);
102 return rocksock_seterror(sock
, RS_ET_OWN
, 0, NULL
, 0);