[BTLS]: Add the native BTLS sources.
[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                 return -1;
44         if (ret > 0)
45                 return ret;
46
47         if (wantMore) {
48                 errno = EAGAIN;
49                 BIO_set_retry_read (bio);
50                 return -1;
51         }
52
53         return 0;
54 }
55
56 static int
57 mono_write (BIO *bio, const char *in, int inl)
58 {
59         MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
60
61         if (!mono)
62                 return -1;
63
64         return mono->write_func (mono->instance, in, inl);
65 }
66
67 static long
68 mono_ctrl (BIO *bio, int cmd, long num, void *ptr)
69 {
70         MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
71
72         if (!mono)
73                 return -1;
74
75         // fprintf (stderr, "mono_ctrl: %x - %lx - %p\n", cmd, num, ptr);
76         switch (cmd) {
77                 case BIO_CTRL_FLUSH:
78                         return mono->control_func (mono->instance, MONO_BTLS_CONTROL_COMMAND_FLUSH, 0);
79                 default:
80                         return -1;
81         }
82         return -1;
83 }
84
85 static int
86 mono_new (BIO *bio)
87 {
88         // mono_debug("mono_new!\n");
89         bio->init = 0;
90         bio->num = -1;
91         bio->flags = 0;
92         return 1;
93 }
94
95 static int
96 mono_free (BIO *bio)
97 {
98         // mono_debug ("mono_free!\n");
99         if (bio->ptr) {
100                 MonoBtlsBio *mono = (MonoBtlsBio *)bio->ptr;
101
102                 bio->ptr = NULL;
103                 mono->instance = NULL;
104                 mono->read_func = NULL;
105                 mono->write_func = NULL;
106                 mono->control_func = NULL;
107                 free (mono);
108         }
109         return 1;
110 }
111
112 static const BIO_METHOD mono_method = {
113         BIO_TYPE_NONE, "mono", mono_write, mono_read,
114         NULL, NULL, mono_ctrl, mono_new, mono_free, NULL
115 };
116
117 BIO *
118 mono_btls_bio_mono_new (void)
119 {
120         BIO *bio;
121         MonoBtlsBio *monoBio;
122
123         bio = BIO_new (&mono_method);
124         if (!bio)
125                 return NULL;
126
127         monoBio = calloc (1, sizeof (MonoBtlsBio));
128         if (!monoBio) {
129                 BIO_free (bio);
130                 return NULL;
131         }
132
133         bio->ptr = monoBio;
134         bio->init = 0;
135
136         return bio;
137 }
138
139 void
140 mono_btls_bio_mono_initialize (BIO *bio, const void *instance,
141                               MonoBtlsReadFunc read_func, MonoBtlsWriteFunc write_func,
142                               MonoBtlsControlFunc control_func)
143 {
144         MonoBtlsBio *monoBio = bio->ptr;
145
146         monoBio->instance = instance;
147         monoBio->read_func = read_func;
148         monoBio->write_func = write_func;
149         monoBio->control_func = control_func;
150
151         bio->init = 1;
152 }
153
154 int
155 mono_btls_bio_read (BIO *bio, void *data, int len)
156 {
157         return BIO_read (bio, data, len);
158 }
159
160 int
161 mono_btls_bio_write (BIO *bio, const void *data, int len)
162 {
163         return BIO_write (bio, data, len);
164 }
165
166 int
167 mono_btls_bio_flush (BIO *bio)
168 {
169         return BIO_flush (bio);
170 }
171
172 int
173 mono_btls_bio_indent (BIO *bio, unsigned indent, unsigned max_indent)
174 {
175         return BIO_indent (bio, indent, max_indent);
176 }
177
178 int
179 mono_btls_bio_hexdump (BIO *bio, const uint8_t *data, int len, unsigned indent)
180 {
181         return BIO_hexdump (bio, data, len, indent);
182 }
183
184 void
185 mono_btls_bio_print_errors (BIO *bio)
186 {
187         BIO_print_errors (bio);
188 }
189
190 void
191 mono_btls_bio_free (BIO *bio)
192 {
193         BIO_free (bio);
194 }
195
196 BIO *
197 mono_btls_bio_mem_new (void)
198 {
199         return BIO_new (BIO_s_mem ());
200 }
201
202 int
203 mono_btls_bio_mem_get_data (BIO *bio, void **data)
204 {
205         return (int)BIO_get_mem_data (bio, (char**)data);
206 }