3 #include <openssl/ssl.h>
4 #include <openssl/err.h>
6 #include <libubox/ustream.h>
7 #include "ustream-io.h"
8 #include "ustream-ssl.h"
10 static void ssl_init(void)
12 static bool _init
= false;
17 SSL_load_error_strings();
23 static void ustream_ssl_error_cb(struct uloop_timeout
*t
)
25 struct ustream_ssl
*us
= container_of(t
, struct ustream_ssl
, error_timer
);
26 static char buffer
[128];
27 int error
= us
->error
;
30 us
->notify_error(us
, error
, ERR_error_string(us
->error
, buffer
));
33 static void ustream_ssl_error(struct ustream_ssl
*us
, int error
)
36 uloop_timeout_set(&us
->error_timer
, 0);
39 static void ustream_ssl_check_conn(struct ustream_ssl
*us
)
43 if (us
->connected
|| us
->error
)
47 ret
= SSL_accept(us
->ssl
);
49 ret
= SSL_connect(us
->ssl
);
53 if (us
->notify_connected
)
54 us
->notify_connected(us
);
58 ret
= SSL_get_error(us
->ssl
, ret
);
59 if (ret
== SSL_ERROR_WANT_READ
|| ret
== SSL_ERROR_WANT_WRITE
)
62 ustream_ssl_error(us
, ret
);
65 static void ustream_ssl_notify_read(struct ustream
*s
, int bytes
)
67 struct ustream_ssl
*us
= container_of(s
->next
, struct ustream_ssl
, stream
);
71 ustream_ssl_check_conn(us
);
72 if (!us
->connected
|| us
->error
)
75 buf
= ustream_reserve(&us
->stream
, 1, &len
);
80 ret
= SSL_read(us
->ssl
, buf
, len
);
82 ret
= SSL_get_error(us
->ssl
, ret
);
84 if (ret
== SSL_ERROR_WANT_READ
)
87 ustream_ssl_error(us
, ret
);
91 us
->stream
.eof
= true;
92 ustream_state_change(&us
->stream
);
102 ustream_fill_read(&us
->stream
, wr
);
105 static void ustream_ssl_notify_write(struct ustream
*s
, int bytes
)
107 struct ustream_ssl
*us
= container_of(s
->next
, struct ustream_ssl
, stream
);
109 ustream_ssl_check_conn(us
);
110 ustream_write_pending(s
->next
);
113 static void ustream_ssl_notify_state(struct ustream
*s
)
115 s
->next
->write_error
= true;
116 ustream_state_change(s
->next
);
119 static int ustream_ssl_write(struct ustream
*s
, const char *buf
, int len
, bool more
)
121 struct ustream_ssl
*us
= container_of(s
, struct ustream_ssl
, stream
);
124 if (!us
->connected
|| us
->error
)
127 if (us
->conn
->w
.data_bytes
)
130 ret
= SSL_write(us
->ssl
, buf
, len
);
132 int err
= SSL_get_error(us
->ssl
, ret
);
133 if (err
== SSL_ERROR_WANT_WRITE
)
140 static void ustream_ssl_set_read_blocked(struct ustream
*s
)
142 struct ustream_ssl
*us
= container_of(s
, struct ustream_ssl
, stream
);
144 ustream_set_read_blocked(us
->conn
, !!s
->read_blocked
);
147 static void ustream_ssl_free(struct ustream
*s
)
149 struct ustream_ssl
*us
= container_of(s
, struct ustream_ssl
, stream
);
152 us
->conn
->next
= NULL
;
153 us
->conn
->notify_read
= NULL
;
154 us
->conn
->notify_write
= NULL
;
155 us
->conn
->notify_state
= NULL
;
158 uloop_timeout_cancel(&us
->error_timer
);
159 SSL_shutdown(us
->ssl
);
164 us
->connected
= false;
168 static void ustream_ssl_stream_init(struct ustream_ssl
*us
)
170 struct ustream
*conn
= us
->conn
;
171 struct ustream
*s
= &us
->stream
;
173 conn
->notify_read
= ustream_ssl_notify_read
;
174 conn
->notify_write
= ustream_ssl_notify_write
;
175 conn
->notify_state
= ustream_ssl_notify_state
;
177 s
->free
= ustream_ssl_free
;
178 s
->write
= ustream_ssl_write
;
179 s
->set_read_blocked
= ustream_ssl_set_read_blocked
;
180 ustream_init_defaults(s
);
183 static void *_ustream_ssl_context_new(bool server
)
185 #ifdef CYASSL_OPENSSL_H_
194 #ifdef CYASSL_OPENSSL_H_
196 m
= SSLv23_server_method();
198 m
= SSLv23_client_method();
201 m
= TLSv1_server_method();
203 m
= TLSv1_client_method();
211 SSL_CTX_set_verify(c
, SSL_VERIFY_NONE
, NULL
);
216 static int _ustream_ssl_context_set_crt_file(void *ctx
, const char *file
)
220 ret
= SSL_CTX_use_certificate_file(ctx
, file
, SSL_FILETYPE_PEM
);
222 ret
= SSL_CTX_use_certificate_file(ctx
, file
, SSL_FILETYPE_ASN1
);
227 static int _ustream_ssl_context_set_key_file(void *ctx
, const char *file
)
231 ret
= SSL_CTX_use_PrivateKey_file(ctx
, file
, SSL_FILETYPE_PEM
);
233 ret
= SSL_CTX_use_PrivateKey_file(ctx
, file
, SSL_FILETYPE_ASN1
);
238 static void _ustream_ssl_context_free(void *ctx
)
243 static int _ustream_ssl_init(struct ustream_ssl
*us
, struct ustream
*conn
, void *ctx
, bool server
)
245 us
->error_timer
.cb
= ustream_ssl_error_cb
;
250 us
->ssl
= SSL_new(us
->ctx
);
254 conn
->next
= &us
->stream
;
255 ustream_set_io(ctx
, us
->ssl
, conn
);
256 ustream_ssl_stream_init(us
);
261 const struct ustream_ssl_ops ustream_ssl_ops
= {
262 .context_new
= _ustream_ssl_context_new
,
263 .context_set_crt_file
= _ustream_ssl_context_set_crt_file
,
264 .context_set_key_file
= _ustream_ssl_context_set_key_file
,
265 .context_free
= _ustream_ssl_context_free
,
266 .init
= _ustream_ssl_init
,