Avoid warnings.
[openssl.git] / crypto / bio / bss_bio.c
1 /* crypto/bio/bss_bio.c  -*- Mode: C; c-file-style: "eay" -*- */
2
3 /*  *** Not yet finished (or even tested). *** */
4
5 /* Special method for a BIO where the other endpoint is also a BIO
6  * of this kind, handled by the same thread.
7  * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
8  * for which no specific BIO method is available. */
9
10 #include <assert.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include <openssl/bio.h>
15 #include <openssl/err.h>
16 #include <openssl/crypto.h>
17
18 static int bio_new(BIO *bio);
19 static int bio_free(BIO *bio);
20 static int bio_read(BIO *bio, char *buf, int size);
21 static int bio_write(BIO *bio, char *buf, int num);
22 static long bio_ctrl(BIO *bio, int cmd, long num, char *ptr);
23 static int bio_puts(BIO *bio, char *str);
24
25 static int bio_make_pair(BIO *bio1, BIO *bio2);
26 static void bio_destroy_pair(BIO *bio);
27
28 static BIO_METHOD methods_biop =
29 {
30         BIO_TYPE_BIO,
31         "BIO pair",
32         bio_write,
33         bio_read,
34         bio_puts,
35         NULL /* no bio_gets */,
36         bio_ctrl,
37         bio_new,
38         bio_free
39 };
40
41 BIO_METHOD *BIO_s_bio(void)
42         {
43         return &methods_biop;
44         }
45
46 struct bio_bio_st
47 {
48         BIO *peer;     /* NULL if buf == NULL.
49                         * If peer != NULL, then peer->ptr is also a bio_bio_st,
50                         * and its "peer" member points back to us.
51                         * peer != NULL iff init != 0 in the BIO. */
52         
53         /* This is for what we write (i.e. reading uses peer's struct): */
54         int closed;     /* valid iff peer != NULL */
55         size_t len;     /* valid iff buf != NULL; 0 if peer == NULL */
56         size_t offset;  /* valid iff buf != NULL; 0 if len == 0 */
57         size_t size;
58         char *buf;      /* "size" elements (if != NULL) */
59
60         size_t request; /* valid iff peer != NULL; 0 if len != 0;
61                          * otherwise set by peer to number of bytes
62                          * it (unsuccesfully) tried to read. */
63 };
64
65 static int bio_new(BIO *bio)
66         {
67         struct bio_bio_st *b;
68         
69         b = Malloc(sizeof *b);
70         if (b == NULL)
71                 return 0;
72
73         b->peer = NULL;
74         b->size = 17*1024; /* enough for one TLS record (just a default) */
75         b->buf = NULL;
76
77         return 1;
78         }
79
80
81 static int bio_free(BIO *bio)
82         {
83         struct bio_bio_st *b;
84
85         if (bio == NULL)
86                 return 0;
87         b = bio->ptr;
88
89         assert(b != NULL);
90
91         if (b->peer)
92                 bio_destroy_pair(bio);
93         
94         if (b->buf != NULL)
95                 {
96                 Free(b->buf);
97                 }
98
99         Free(b);
100
101         return 1;
102         }
103
104
105
106 static int bio_read(BIO *bio, char *buf, int size)
107         {
108         /* XXX */
109         return -1;
110         }
111
112 static int bio_write(BIO *bio, char *buf, int num)
113         {
114         /* XXX */
115         return -1;
116         }
117         
118 static long bio_ctrl(BIO *bio, int cmd, long num, char *ptr)
119         {
120         long ret;
121         struct bio_bio_st *b = bio->ptr;
122         
123         assert(b != NULL);
124
125         switch (cmd)
126                 {
127                 /* XXX Additional commands: */
128                 /* - Set buffer size */
129                 /* - make pair */
130                 /* - destroy pair */
131                 /* - get number of bytes that the next write will accept */
132                 /* - get number of bytes requested by peer */
133                 /* - send "close" */
134
135         case BIO_CTRL_RESET:
136                 if (b->buf != NULL)
137                         {
138                         b->len = 0;
139                         b->offset = 0;
140                         }
141                 ret = 0;
142                 break;          
143
144         case BIO_CTRL_GET_CLOSE:
145                 ret = bio->shutdown;
146                 break;
147
148         case BIO_CTRL_SET_CLOSE:
149                 bio->shutdown = (int) num;
150                 ret = 1;
151                 break;
152
153         case BIO_CTRL_PENDING:
154                 if (b->peer != NULL)
155                         {
156                         struct bio_bio_st *peer_b =b->peer->ptr;
157                         
158                         ret = (long) peer_b->len;
159                         }
160                 else
161                         ret = 0;
162                 break;
163
164         case BIO_CTRL_WPENDING:
165                 if (b->buf != NULL)
166                         ret = (long) b->len;
167                 else
168                         ret = 0;
169                 break;
170
171         case BIO_CTRL_DUP:
172                 /* XXX */
173                 ret = 1;
174                 break;
175
176         case BIO_CTRL_FLUSH:
177                 ret = 1;
178                 break;
179
180         default:
181                 ret = 0;
182                 }
183         return ret;
184         }
185
186 static int bio_puts(BIO *bio, char *str)
187         {
188         return bio_write(bio, str, strlen(str));
189         }
190
191 /* Until bio_make_pair is used, make a dummy function use it for -pedantic */
192 void dummy() { bio_make_pair(NULL,NULL); }
193
194 static int bio_make_pair(BIO *bio1, BIO *bio2)
195         {
196         struct bio_bio_st *b1, *b2;
197
198         assert(bio1 != NULL);
199         assert(bio2 != NULL);
200
201         b1 = bio1->ptr;
202         b2 = bio2->ptr;
203         
204         if (b1->peer != NULL || b2->peer != NULL)
205                 {
206                 BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
207                 return 0;
208                 }
209         
210         if (b1->buf == NULL)
211                 {
212                 b1->buf = Malloc(b1->size);
213                 if (b1->buf == NULL)
214                         {
215                         BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
216                         return 0;
217                         }
218                 b1->len = 0;
219                 b1->offset = 0;
220                 }
221         
222         if (b2->buf == NULL)
223                 {
224                 b2->buf = Malloc(b2->size);
225                 if (b2->buf == NULL)
226                         {
227                         BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
228                         return 0;
229                         }
230                 b2->len = 0;
231                 b2->offset = 0;
232                 }
233         
234         b1->peer = bio2;
235         b1->closed = 0;
236         b1->request = 0;
237         b2->peer = bio1;
238         b2->closed = 0;
239         b2->request = 0;
240
241         bio1->init = 1;
242         bio2->init = 1;
243
244         return 1;
245         }
246
247 static void bio_destroy_pair(BIO *bio)
248         {
249         struct bio_bio_st *b = bio->ptr;
250
251         if (b != NULL)
252                 {
253                 BIO *peer_bio = b->peer;
254
255                 if (peer_bio != NULL)
256                         {
257                         struct bio_bio_st *peer_b = peer_bio->ptr;
258
259                         assert(peer_b != NULL);
260                         assert(peer_b->peer == bio);
261
262                         peer_b->peer = NULL;
263                         peer_bio->init = 0;
264                         assert(peer_b->buf != NULL);
265                         peer_b->len = 0;
266                         peer_b->offset = 0;
267                         
268                         b->peer = NULL;
269                         bio->init = 0;
270                         assert(b->buf != NULL);
271                         b->len = 0;
272                         b->offset = 0;
273                         }
274                 }
275         }