1 /* $OpenBSD: tls_bio_cb.c,v 1.19 2017/01/12 16:18:39 jsing Exp $ */
3 * Copyright (c) 2016 Tobias Pape <tobias@netshed.de>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <openssl/bio.h>
25 #include "tls_internal.h"
27 static int bio_cb_write(BIO
*bio
, const char *buf
, int num
);
28 static int bio_cb_read(BIO
*bio
, char *buf
, int size
);
29 static int bio_cb_puts(BIO
*bio
, const char *str
);
30 static long bio_cb_ctrl(BIO
*bio
, int cmd
, long num
, void *ptr
);
32 static BIO_METHOD bio_cb_method
= {
34 .name
= "libtls_callbacks",
35 .bwrite
= bio_cb_write
,
44 return (&bio_cb_method
);
48 bio_cb_puts(BIO
*bio
, const char *str
)
50 return (bio_cb_write(bio
, str
, strlen(str
)));
54 bio_cb_ctrl(BIO
*bio
, int cmd
, long num
, void *ptr
)
59 case BIO_CTRL_GET_CLOSE
:
60 ret
= (long)bio
->shutdown
;
62 case BIO_CTRL_SET_CLOSE
:
63 bio
->shutdown
= (int)num
;
72 ret
= BIO_ctrl(bio
->next_bio
, cmd
, num
, ptr
);
79 bio_cb_write(BIO
*bio
, const char *buf
, int num
)
81 struct tls
*ctx
= bio
->ptr
;
84 BIO_clear_retry_flags(bio
);
85 rv
= (ctx
->write_cb
)(ctx
, buf
, num
, ctx
->cb_arg
);
86 if (rv
== TLS_WANT_POLLIN
) {
87 BIO_set_retry_read(bio
);
89 } else if (rv
== TLS_WANT_POLLOUT
) {
90 BIO_set_retry_write(bio
);
97 bio_cb_read(BIO
*bio
, char *buf
, int size
)
99 struct tls
*ctx
= bio
->ptr
;
102 BIO_clear_retry_flags(bio
);
103 rv
= (ctx
->read_cb
)(ctx
, buf
, size
, ctx
->cb_arg
);
104 if (rv
== TLS_WANT_POLLIN
) {
105 BIO_set_retry_read(bio
);
107 } else if (rv
== TLS_WANT_POLLOUT
) {
108 BIO_set_retry_write(bio
);
115 tls_set_cbs(struct tls
*ctx
, tls_read_cb read_cb
, tls_write_cb write_cb
,
121 if (read_cb
== NULL
|| write_cb
== NULL
) {
122 tls_set_errorx(ctx
, "no callbacks provided");
126 ctx
->read_cb
= read_cb
;
127 ctx
->write_cb
= write_cb
;
128 ctx
->cb_arg
= cb_arg
;
130 if ((bio
= BIO_new(bio_s_cb())) == NULL
) {
131 tls_set_errorx(ctx
, "failed to create callback i/o");
137 SSL_set_bio(ctx
->ssl_conn
, bio
, bio
);