Gets around VC++ compiler pickiness. (long != double)
[openssl.git] / crypto / bio / bss_bio.c
1 /* crypto/bio/bss_bio.c  -*- Mode: C; c-file-style: "eay" -*- */
2
3 /* Special method for a BIO where the other endpoint is also a BIO
4  * of this kind, handled by the same thread (i.e. the "peer" is actually
5  * ourselves, wearing a different hat).
6  * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
7  * for which no specific BIO method is available.
8  * See ssl/ssltest.c for some hints on how this can be used. */
9
10 #ifndef BIO_PAIR_DEBUG
11 # undef NDEBUG /* avoid conflicting definitions */
12 # define NDEBUG
13 #endif
14
15 #include <assert.h>
16 #include <limits.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include <openssl/bio.h>
21 #include <openssl/err.h>
22 #include <openssl/crypto.h>
23
24 static int bio_new(BIO *bio);
25 static int bio_free(BIO *bio);
26 static int bio_read(BIO *bio, char *buf, int size);
27 static int bio_write(BIO *bio, char *buf, int num);
28 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
29 static int bio_puts(BIO *bio, char *str);
30
31 static int bio_make_pair(BIO *bio1, BIO *bio2);
32 static void bio_destroy_pair(BIO *bio);
33
34 static BIO_METHOD methods_biop =
35 {
36         BIO_TYPE_BIO,
37         "BIO pair",
38         bio_write,
39         bio_read,
40         bio_puts,
41         NULL /* no bio_gets */,
42         bio_ctrl,
43         bio_new,
44         bio_free,
45         NULL /* no bio_callback_ctrl */
46 };
47
48 BIO_METHOD *BIO_s_bio(void)
49         {
50         return &methods_biop;
51         }
52
53 struct bio_bio_st
54 {
55         BIO *peer;     /* NULL if buf == NULL.
56                         * If peer != NULL, then peer->ptr is also a bio_bio_st,
57                         * and its "peer" member points back to us.
58                         * peer != NULL iff init != 0 in the BIO. */
59         
60         /* This is for what we write (i.e. reading uses peer's struct): */
61         int closed;     /* valid iff peer != NULL */
62         size_t len;     /* valid iff buf != NULL; 0 if peer == NULL */
63         size_t offset;  /* valid iff buf != NULL; 0 if len == 0 */
64         size_t size;
65         char *buf;      /* "size" elements (if != NULL) */
66
67         size_t request; /* valid iff peer != NULL; 0 if len != 0,
68                          * otherwise set by peer to number of bytes
69                          * it (unsuccessfully) tried to read,
70                          * never more than buffer space (size-len) warrants. */
71 };
72
73 static int bio_new(BIO *bio)
74         {
75         struct bio_bio_st *b;
76         
77         b = Malloc(sizeof *b);
78         if (b == NULL)
79                 return 0;
80
81         b->peer = NULL;
82         b->size = 17*1024; /* enough for one TLS record (just a default) */
83         b->buf = NULL;
84
85         bio->ptr = b;
86         return 1;
87         }
88
89
90 static int bio_free(BIO *bio)
91         {
92         struct bio_bio_st *b;
93
94         if (bio == NULL)
95                 return 0;
96         b = bio->ptr;
97
98         assert(b != NULL);
99
100         if (b->peer)
101                 bio_destroy_pair(bio);
102         
103         if (b->buf != NULL)
104                 {
105                 Free(b->buf);
106                 }
107
108         Free(b);
109
110         return 1;
111         }
112
113
114
115 static int bio_read(BIO *bio, char *buf, int size_)
116         {
117         size_t size = size_;
118         size_t rest;
119         struct bio_bio_st *b, *peer_b;
120
121         BIO_clear_retry_flags(bio);
122
123         if (!bio->init)
124                 return 0;
125
126         b = bio->ptr;
127         assert(b != NULL);
128         assert(b->peer != NULL);
129         peer_b = b->peer->ptr;
130         assert(peer_b != NULL);
131         assert(peer_b->buf != NULL);
132
133         peer_b->request = 0; /* will be set in "retry_read" situation */
134
135         if (buf == NULL || size == 0)
136                 return 0;
137
138         if (peer_b->len == 0)
139                 {
140                 if (peer_b->closed)
141                         return 0; /* writer has closed, and no data is left */
142                 else
143                         {
144                         BIO_set_retry_read(bio); /* buffer is empty */
145                         if (size <= peer_b->size)
146                                 peer_b->request = size;
147                         else
148                                 /* don't ask for more than the peer can
149                                  * deliver in one write */
150                                 peer_b->request = peer_b->size;
151                         return -1;
152                         }
153                 }
154
155         /* we can read */
156         if (peer_b->len < size)
157                 size = peer_b->len;
158
159         /* now read "size" bytes */
160         
161         rest = size;
162         
163         assert(rest > 0);
164         do /* one or two iterations */
165                 {
166                 size_t chunk;
167                 
168                 assert(rest <= peer_b->len);
169                 if (peer_b->offset + rest <= peer_b->size)
170                         chunk = rest;
171                 else
172                         /* wrap around ring buffer */
173                         chunk = peer_b->size - peer_b->offset;
174                 assert(peer_b->offset + chunk <= peer_b->size);
175                 
176                 memcpy(buf, peer_b->buf + peer_b->offset, chunk);
177                 
178                 peer_b->len -= chunk;
179                 if (peer_b->len)
180                         {
181                         peer_b->offset += chunk;
182                         assert(peer_b->offset <= peer_b->size);
183                         if (peer_b->offset == peer_b->size)
184                                 peer_b->offset = 0;
185                         buf += chunk;
186                         }
187                 else
188                         {
189                         /* buffer now empty, no need to advance "buf" */
190                         assert(chunk == rest);
191                         peer_b->offset = 0;
192                         }
193                 rest -= chunk;
194                 }
195         while (rest);
196         
197         return size;
198         }
199
200 /* non-copying interface: provide pointer to available data in buffer
201  *    bio_nread0:  return number of available bytes
202  *    bio_nread:   also advance index
203  * (example usage:  bio_nread0(), read from buffer, bio_nread()
204  *  or just         bio_nread(), read from buffer)
205  */
206 /* WARNING: The non-copying interface is largely untested as of yet
207  * and may contain bugs. */
208 static size_t bio_nread0(BIO *bio, char **buf)
209         {
210         struct bio_bio_st *b, *peer_b;
211         size_t num;
212         
213         BIO_clear_retry_flags(bio);
214
215         if (!bio->init)
216                 return 0;
217         
218         b = bio->ptr;
219         assert(b != NULL);
220         assert(b->peer != NULL);
221         peer_b = b->peer->ptr;
222         assert(peer_b != NULL);
223         assert(peer_b->buf != NULL);
224         
225         peer_b->request = 0;
226         
227         if (peer_b->len == 0)
228                 {
229                 char dummy;
230                 
231                 /* avoid code duplication -- nothing available for reading */
232                 return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
233                 }
234
235         num = peer_b->len;
236         if (peer_b->size < peer_b->offset + num)
237                 /* no ring buffer wrap-around for non-copying interface */
238                 num = peer_b->size - peer_b->offset;
239         assert(num > 0);
240
241         if (buf != NULL)
242                 *buf = peer_b->buf + peer_b->offset;
243         return num;
244         }
245
246 static size_t bio_nread(BIO *bio, char **buf, size_t num)
247         {
248         struct bio_bio_st *b, *peer_b;
249         size_t available;
250
251         available = bio_nread0(bio, buf);
252         if (num > available)
253                 num = available;
254         if (num == 0)
255                 return num;
256
257         b = bio->ptr;
258         peer_b = b->peer->ptr;
259
260         peer_b->len -= num;
261         if (peer_b->len) 
262                 {
263                 peer_b->offset += num;
264                 assert(peer_b->offset <= peer_b->size);
265                 if (peer_b->offset == peer_b->size)
266                         peer_b->offset = 0;
267                 }
268         else
269                 peer_b->offset = 0;
270
271         return num;
272         }
273
274
275 static int bio_write(BIO *bio, char *buf, int num_)
276         {
277         size_t num = num_;
278         size_t rest;
279         struct bio_bio_st *b;
280
281         BIO_clear_retry_flags(bio);
282
283         if (!bio->init || buf == NULL || num == 0)
284                 return 0;
285
286         b = bio->ptr;           
287         assert(b != NULL);
288         assert(b->peer != NULL);
289         assert(b->buf != NULL);
290
291         b->request = 0;
292         if (b->closed)
293                 {
294                 /* we already closed */
295                 BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
296                 return -1;
297                 }
298
299         assert(b->len <= b->size);
300
301         if (b->len == b->size)
302                 {
303                 BIO_set_retry_write(bio); /* buffer is full */
304                 return -1;
305                 }
306
307         /* we can write */
308         if (num > b->size - b->len)
309                 num = b->size - b->len;
310         
311         /* now write "num" bytes */
312
313         rest = num;
314         
315         assert(rest > 0);
316         do /* one or two iterations */
317                 {
318                 size_t write_offset;
319                 size_t chunk;
320
321                 assert(b->len + rest <= b->size);
322
323                 write_offset = b->offset + b->len;
324                 if (write_offset >= b->size)
325                         write_offset -= b->size;
326                 /* b->buf[write_offset] is the first byte we can write to. */
327
328                 if (write_offset + rest <= b->size)
329                         chunk = rest;
330                 else
331                         /* wrap around ring buffer */
332                         chunk = b->size - write_offset;
333                 
334                 memcpy(b->buf + write_offset, buf, chunk);
335                 
336                 b->len += chunk;
337
338                 assert(b->len <= b->size);
339                 
340                 rest -= chunk;
341                 buf += chunk;
342                 }
343         while (rest);
344
345         return num;
346         }
347
348 /* non-copying interface: provide pointer to region to write to
349  *   bio_nwrite0:  check how much space is available
350  *   bio_nwrite:   also increase length
351  * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
352  *  or just         bio_nwrite(), write to buffer)
353  */
354 static size_t bio_nwrite0(BIO *bio, char **buf)
355         {
356         struct bio_bio_st *b;
357         size_t num;
358         size_t write_offset;
359
360         BIO_clear_retry_flags(bio);
361
362         if (!bio->init)
363                 return 0;
364
365         b = bio->ptr;           
366         assert(b != NULL);
367         assert(b->peer != NULL);
368         assert(b->buf != NULL);
369
370         b->request = 0;
371         if (b->closed)
372                 {
373                 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
374                 return -1;
375                 }
376
377         assert(b->len <= b->size);
378
379         if (b->len == b->size)
380                 {
381                 BIO_set_retry_write(bio);
382                 return -1;
383                 }
384
385         num = b->size - b->len;
386         write_offset = b->offset + b->len;
387         if (write_offset >= b->size)
388                 write_offset -= b->size;
389         if (write_offset + num > b->size)
390                 /* no ring buffer wrap-around for non-copying interface
391                  * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
392                  * BIO_nwrite may have to be called twice) */
393                 num = b->size - write_offset;
394
395         if (buf != NULL)
396                 *buf = b->buf + write_offset;
397         assert(write_offset + num <= b->size);
398
399         return num;
400         }
401
402 static size_t bio_nwrite(BIO *bio, char **buf, size_t num)
403         {
404         struct bio_bio_st *b;
405         size_t space;
406
407         space = bio_nwrite0(bio, buf);
408         if (num > space)
409                 num = space;
410         if (num == 0)
411                 return num;
412         b = bio->ptr;
413         assert(b != NULL);
414         b->len += num;
415         assert(b->len <= b->size);
416
417         return num;
418         }
419
420
421 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
422         {
423         long ret;
424         struct bio_bio_st *b = bio->ptr;
425         
426         assert(b != NULL);
427
428         switch (cmd)
429                 {
430         /* specific CTRL codes */
431
432         case BIO_C_SET_WRITE_BUF_SIZE:
433                 if (b->peer)
434                         {
435                         BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
436                         ret = 0;
437                         }
438                 else if (num == 0)
439                         {
440                         BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
441                         ret = 0;
442                         }
443                 else
444                         {
445                         size_t new_size = num;
446
447                         if (b->size != new_size)
448                                 {
449                                 if (b->buf) 
450                                         {
451                                         Free(b->buf);
452                                         b->buf = NULL;
453                                         }
454                                 b->size = new_size;
455                                 }
456                         ret = 1;
457                         }
458                 break;
459
460         case BIO_C_GET_WRITE_BUF_SIZE:
461                 num = (long) b->size;
462
463         case BIO_C_MAKE_BIO_PAIR:
464                 {
465                 BIO *other_bio = ptr;
466                 
467                 if (bio_make_pair(bio, other_bio))
468                         ret = 1;
469                 else
470                         ret = 0;
471                 }
472                 break;
473                 
474         case BIO_C_DESTROY_BIO_PAIR:
475                 /* Effects both BIOs in the pair -- call just once!
476                  * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
477                 bio_destroy_pair(bio);
478                 ret = 1;
479                 break;
480
481         case BIO_C_GET_WRITE_GUARANTEE:
482                 /* How many bytes can the caller feed to the next write
483                  * without having to keep any? */
484                 if (b->peer == NULL || b->closed)
485                         ret = 0;
486                 else
487                         ret = (long) b->size - b->len;
488                 break;
489
490         case BIO_C_GET_READ_REQUEST:
491                 /* If the peer unsuccessfully tried to read, how many bytes
492                  * were requested?  (As with BIO_CTRL_PENDING, that number
493                  * can usually be treated as boolean.) */
494                 ret = (long) b->request;
495                 break;
496
497         case BIO_C_RESET_READ_REQUEST:
498                 /* Reset request.  (Can be useful after read attempts
499                  * at the other side that are meant to be non-blocking,
500                  * e.g. when probing SSL_read to see if any data is
501                  * available.) */
502                 b->request = 0;
503                 ret = 1;
504                 break;
505
506         case BIO_C_SHUTDOWN_WR:
507                 /* similar to shutdown(..., SHUT_WR) */
508                 b->closed = 1;
509                 ret = 1;
510                 break;
511
512         case BIO_C_NREAD:
513                 /* non-copying read */
514                 ret = (long) bio_nread(bio, ptr, (size_t) num);
515                 break;
516                 
517         case BIO_C_NWRITE0:
518                 /* prepare for non-copying write */
519                 ret = (long) bio_nwrite0(bio, ptr);
520                 break;
521
522         case BIO_C_NWRITE:
523                 /* non-copying write */
524                 ret = (long) bio_nwrite(bio, ptr, (size_t) num);
525                 break;
526                 
527
528         /* standard CTRL codes follow */
529
530         case BIO_CTRL_RESET:
531                 if (b->buf != NULL)
532                         {
533                         b->len = 0;
534                         b->offset = 0;
535                         }
536                 ret = 0;
537                 break;          
538
539         case BIO_CTRL_GET_CLOSE:
540                 ret = bio->shutdown;
541                 break;
542
543         case BIO_CTRL_SET_CLOSE:
544                 bio->shutdown = (int) num;
545                 ret = 1;
546                 break;
547
548         case BIO_CTRL_PENDING:
549                 if (b->peer != NULL)
550                         {
551                         struct bio_bio_st *peer_b = b->peer->ptr;
552                         
553                         ret = (long) peer_b->len;
554                         }
555                 else
556                         ret = 0;
557                 break;
558
559         case BIO_CTRL_WPENDING:
560                 if (b->buf != NULL)
561                         ret = (long) b->len;
562                 else
563                         ret = 0;
564                 break;
565
566         case BIO_CTRL_DUP:
567                 /* See BIO_dup_chain for circumstances we have to expect. */
568                 {
569                 BIO *other_bio = ptr;
570                 struct bio_bio_st *other_b;
571                 
572                 assert(other_bio != NULL);
573                 other_b = other_bio->ptr;
574                 assert(other_b != NULL);
575                 
576                 assert(other_b->buf == NULL); /* other_bio is always fresh */
577
578                 other_b->size = b->size;
579                 }
580
581                 ret = 1;
582                 break;
583
584         case BIO_CTRL_FLUSH:
585                 ret = 1;
586                 break;
587
588         case BIO_CTRL_EOF:
589                 {
590                 BIO *other_bio = ptr;
591                 
592                 if (other_bio)
593                         {
594                         struct bio_bio_st *other_b = other_bio->ptr;
595                         
596                         assert(other_b != NULL);
597                         ret = other_b->len == 0 && other_b->closed;
598                         }
599                 else
600                         ret = 1;
601                 }
602                 break;
603
604         default:
605                 ret = 0;
606                 }
607         return ret;
608         }
609
610 static int bio_puts(BIO *bio, char *str)
611         {
612         return bio_write(bio, str, strlen(str));
613         }
614
615
616 static int bio_make_pair(BIO *bio1, BIO *bio2)
617         {
618         struct bio_bio_st *b1, *b2;
619
620         assert(bio1 != NULL);
621         assert(bio2 != NULL);
622
623         b1 = bio1->ptr;
624         b2 = bio2->ptr;
625         
626         if (b1->peer != NULL || b2->peer != NULL)
627                 {
628                 BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
629                 return 0;
630                 }
631         
632         if (b1->buf == NULL)
633                 {
634                 b1->buf = Malloc(b1->size);
635                 if (b1->buf == NULL)
636                         {
637                         BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
638                         return 0;
639                         }
640                 b1->len = 0;
641                 b1->offset = 0;
642                 }
643         
644         if (b2->buf == NULL)
645                 {
646                 b2->buf = Malloc(b2->size);
647                 if (b2->buf == NULL)
648                         {
649                         BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
650                         return 0;
651                         }
652                 b2->len = 0;
653                 b2->offset = 0;
654                 }
655         
656         b1->peer = bio2;
657         b1->closed = 0;
658         b1->request = 0;
659         b2->peer = bio1;
660         b2->closed = 0;
661         b2->request = 0;
662
663         bio1->init = 1;
664         bio2->init = 1;
665
666         return 1;
667         }
668
669 static void bio_destroy_pair(BIO *bio)
670         {
671         struct bio_bio_st *b = bio->ptr;
672
673         if (b != NULL)
674                 {
675                 BIO *peer_bio = b->peer;
676
677                 if (peer_bio != NULL)
678                         {
679                         struct bio_bio_st *peer_b = peer_bio->ptr;
680
681                         assert(peer_b != NULL);
682                         assert(peer_b->peer == bio);
683
684                         peer_b->peer = NULL;
685                         peer_bio->init = 0;
686                         assert(peer_b->buf != NULL);
687                         peer_b->len = 0;
688                         peer_b->offset = 0;
689                         
690                         b->peer = NULL;
691                         bio->init = 0;
692                         assert(b->buf != NULL);
693                         b->len = 0;
694                         b->offset = 0;
695                         }
696                 }
697         }
698  
699
700 /* Exported convenience functions */
701 int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
702         BIO **bio2_p, size_t writebuf2)
703          {
704          BIO *bio1 = NULL, *bio2 = NULL;
705          long r;
706          int ret = 0;
707
708          bio1 = BIO_new(BIO_s_bio());
709          if (bio1 == NULL)
710                  goto err;
711          bio2 = BIO_new(BIO_s_bio());
712          if (bio2 == NULL)
713                  goto err;
714
715          if (writebuf1)
716                  {
717                  r = BIO_set_write_buf_size(bio1, writebuf1);
718                  if (!r)
719                          goto err;
720                  }
721          if (writebuf2)
722                  {
723                  r = BIO_set_write_buf_size(bio2, writebuf2);
724                  if (!r)
725                          goto err;
726                  }
727
728          r = BIO_make_bio_pair(bio1, bio2);
729          if (!r)
730                  goto err;
731          ret = 1;
732
733  err:
734          if (ret == 0)
735                  {
736                  if (bio1)
737                          {
738                          BIO_free(bio1);
739                          bio1 = NULL;
740                          }
741                  if (bio2)
742                          {
743                          BIO_free(bio2);
744                          bio2 = NULL;
745                          }
746                  }
747
748          *bio1_p = bio1;
749          *bio2_p = bio2;
750          return ret;
751          }
752
753 size_t BIO_ctrl_get_write_guarantee(BIO *bio)
754         {
755         return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
756         }
757
758 size_t BIO_ctrl_get_read_request(BIO *bio)
759         {
760         return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
761         }
762
763 int BIO_ctrl_reset_read_request(BIO *bio)
764         {
765         return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
766         }
767
768
769 /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
770  * (conceivably some other BIOs could allow non-copying reads and writes too.)
771  */
772 int BIO_nread0(BIO *bio, char **buf)
773         {
774         long ret;
775
776         if (!bio->init)
777                 {
778                 BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
779                 return -2;
780                 }
781
782         ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
783         if (ret > INT_MAX)
784                 return INT_MAX;
785         else
786                 return (int) ret;
787         }
788
789 int BIO_nread(BIO *bio, char **buf, int num)
790         {
791         int ret;
792
793         if (!bio->init)
794                 {
795                 BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
796                 return -2;
797                 }
798
799         ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
800         if (ret > 0)
801                 bio->num_read += ret;
802         return ret;
803         }
804
805 int BIO_nwrite0(BIO *bio, char **buf)
806         {
807         long ret;
808
809         if (!bio->init)
810                 {
811                 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
812                 return -2;
813                 }
814
815         ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
816         if (ret > INT_MAX)
817                 return INT_MAX;
818         else
819                 return (int) ret;
820         }
821
822 int BIO_nwrite(BIO *bio, char **buf, int num)
823         {
824         int ret;
825
826         if (!bio->init)
827                 {
828                 BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
829                 return -2;
830                 }
831
832         ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
833         if (ret > 0)
834                 bio->num_read += ret;
835         return ret;
836         }