Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / btls / btls-bio.c
1 //
2 //  btls-bio.c
3 //  MonoBtls
4 //
5 //  Created by Martin Baulig on 14/11/15.
6 //  Copyright (c) 2015 Xamarin. All rights reserved.
7 //
8
9 #include <btls-ssl.h>
10 #include <btls-bio.h>
11 #include <errno.h>
12
13 struct MonoBtlsBio {
14         const void *instance;
15         MonoBtlsReadFunc read_func;
16         MonoBtlsWriteFunc write_func;
17         MonoBtlsControlFunc control_func;
18 };
19
20 #if 0
21 static void
22 mono_debug (const char *message)
23 {
24         BIO *bio_err;
25         bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
26         fprintf (stderr, "DEBUG: %s\n", message);
27         ERR_print_errors (bio_err);
28 }
29 #endif
30
31 static int
32 mono_read (BIO *bio, char *out, int outl)
33 {
34         MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
35         int ret, wantMore;
36
37         if (!mono)
38                 return -1;
39
40         ret = mono->read_func (mono->instance, out, outl, &wantMore);
41
42         if (ret < 0) {
43                 errno = EIO;
44                 return -1;
45         }
46         if (ret > 0)
47                 return ret;
48
49         if (wantMore) {
50                 errno = EAGAIN;
51                 BIO_set_retry_read (bio);
52                 return -1;
53         }
54
55         return 0;
56 }
57
58 static int
59 mono_write (BIO *bio, const char *in, int inl)
60 {
61         MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
62
63         if (!mono)
64                 return -1;
65
66         return mono->write_func (mono->instance, in, inl);
67 }
68
69 static long
70 mono_ctrl (BIO *bio, int cmd, long num, void *ptr)
71 {
72         MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
73
74         if (!mono)
75                 return -1;
76
77         // fprintf (stderr, "mono_ctrl: %x - %lx - %p\n", cmd, num, ptr);
78         switch (cmd) {
79                 case BIO_CTRL_FLUSH:
80                         return mono->control_func (mono->instance, MONO_BTLS_CONTROL_COMMAND_FLUSH, 0);
81                 default:
82                         return -1;
83         }
84         return -1;
85 }
86
87 static int
88 mono_new (BIO *bio)
89 {
90         // mono_debug("mono_new!\n");
91         bio->init = 0;
92         bio->num = -1;
93         bio->flags = 0;
94         return 1;
95 }
96
97 static int
98 mono_free (BIO *bio)
99 {
100         // mono_debug ("mono_free!\n");
101         if (bio->ptr) {
102                 MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
103
104                 bio->ptr = NULL;
105                 mono->instance = NULL;
106                 mono->read_func = NULL;
107                 mono->write_func = NULL;
108                 mono->control_func = NULL;
109                 free (mono);
110         }
111         return 1;
112 }
113
114 static const BIO_METHOD mono_method = {
115         BIO_TYPE_NONE, "mono", mono_write, mono_read,
116         NULL, NULL, mono_ctrl, mono_new, mono_free, NULL
117 };
118
119 MONO_API BIO *
120 mono_btls_bio_mono_new (void)
121 {
122         BIO *bio;
123         MonoBtlsBio *monoBio;
124
125         bio = BIO_new (&mono_method);
126         if (!bio)
127                 return NULL;
128
129         monoBio = calloc (1, sizeof (MonoBtlsBio));
130         if (!monoBio) {
131                 BIO_free (bio);
132                 return NULL;
133         }
134
135         bio->ptr = monoBio;
136         bio->init = 0;
137
138         return bio;
139 }
140
141 MONO_API void
142 mono_btls_bio_mono_initialize (BIO *bio, const void *instance,
143                               MonoBtlsReadFunc read_func, MonoBtlsWriteFunc write_func,
144                               MonoBtlsControlFunc control_func)
145 {
146         MonoBtlsBio *monoBio = bio->ptr;
147
148         monoBio->instance = instance;
149         monoBio->read_func = read_func;
150         monoBio->write_func = write_func;
151         monoBio->control_func = control_func;
152
153         bio->init = 1;
154 }
155
156 MONO_API int
157 mono_btls_bio_read (BIO *bio, void *data, int len)
158 {
159         return BIO_read (bio, data, len);
160 }
161
162 MONO_API int
163 mono_btls_bio_write (BIO *bio, const void *data, int len)
164 {
165         return BIO_write (bio, data, len);
166 }
167
168 MONO_API int
169 mono_btls_bio_flush (BIO *bio)
170 {
171         return BIO_flush (bio);
172 }
173
174 MONO_API int
175 mono_btls_bio_indent (BIO *bio, unsigned indent, unsigned max_indent)
176 {
177         return BIO_indent (bio, indent, max_indent);
178 }
179
180 MONO_API int
181 mono_btls_bio_hexdump (BIO *bio, const uint8_t *data, int len, unsigned indent)
182 {
183         return BIO_hexdump (bio, data, len, indent);
184 }
185
186 MONO_API void
187 mono_btls_bio_print_errors (BIO *bio)
188 {
189         BIO_print_errors (bio);
190 }
191
192 MONO_API void
193 mono_btls_bio_free (BIO *bio)
194 {
195         BIO_free (bio);
196 }
197
198 MONO_API BIO *
199 mono_btls_bio_mem_new (void)
200 {
201         return BIO_new (BIO_s_mem ());
202 }
203
204 MONO_API int
205 mono_btls_bio_mem_get_data (BIO *bio, void **data)
206 {
207         return (int)BIO_get_mem_data (bio, (char**)data);
208 }