summaryrefslogtreecommitdiff
path: root/src/lib/libssl/bio_ssl.c
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:14 +0000
committerryker <>1998-10-05 20:13:14 +0000
commitaeeae06a79815dc190061534d47236cec09f9e32 (patch)
tree851692b9c2f9c04f077666855641900f19fdb217 /src/lib/libssl/bio_ssl.c
parenta4f79641824cbf9f60ca9d1168d1fcc46717a82a (diff)
downloadopenbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.gz
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.bz2
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libssl/bio_ssl.c')
-rw-r--r--src/lib/libssl/bio_ssl.c585
1 files changed, 585 insertions, 0 deletions
diff --git a/src/lib/libssl/bio_ssl.c b/src/lib/libssl/bio_ssl.c
new file mode 100644
index 0000000000..58a6d69b9b
--- /dev/null
+++ b/src/lib/libssl/bio_ssl.c
@@ -0,0 +1,585 @@
1/* ssl/bio_ssl.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62#include <errno.h>
63#include "crypto.h"
64#include "bio.h"
65#include "err.h"
66#include "ssl.h"
67
68#ifndef NOPROTO
69static int ssl_write(BIO *h,char *buf,int num);
70static int ssl_read(BIO *h,char *buf,int size);
71static int ssl_puts(BIO *h,char *str);
72static long ssl_ctrl(BIO *h,int cmd,long arg1,char *arg2);
73static int ssl_new(BIO *h);
74static int ssl_free(BIO *data);
75#else
76static int ssl_write();
77static int ssl_read();
78static int ssl_puts();
79static long ssl_ctrl();
80static int ssl_new();
81static int ssl_free();
82#endif
83
84typedef struct bio_ssl_st
85 {
86 SSL *ssl; /* The ssl handle :-) */
87 /* re-negotiate every time the total number of bytes is this size */
88 int num_renegotiates;
89 unsigned long renegotiate_count;
90 unsigned long byte_count;
91 unsigned long renegotiate_timeout;
92 unsigned long last_time;
93 } BIO_SSL;
94
95static BIO_METHOD methods_sslp=
96 {
97 BIO_TYPE_SSL,"ssl",
98 ssl_write,
99 ssl_read,
100 ssl_puts,
101 NULL, /* ssl_gets, */
102 ssl_ctrl,
103 ssl_new,
104 ssl_free,
105 };
106
107BIO_METHOD *BIO_f_ssl()
108 {
109 return(&methods_sslp);
110 }
111
112static int ssl_new(bi)
113BIO *bi;
114 {
115 BIO_SSL *bs;
116
117 bs=(BIO_SSL *)Malloc(sizeof(BIO_SSL));
118 if (bs == NULL)
119 {
120 BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
121 return(0);
122 }
123 memset(bs,0,sizeof(BIO_SSL));
124 bi->init=0;
125 bi->ptr=(char *)bs;
126 bi->flags=0;
127 return(1);
128 }
129
130static int ssl_free(a)
131BIO *a;
132 {
133 BIO_SSL *bs;
134
135 if (a == NULL) return(0);
136 bs=(BIO_SSL *)a->ptr;
137 if (bs->ssl != NULL) SSL_shutdown(bs->ssl);
138 if (a->shutdown)
139 {
140 if (a->init && (bs->ssl != NULL))
141 SSL_free(bs->ssl);
142 a->init=0;
143 a->flags=0;
144 }
145 if (a->ptr != NULL)
146 Free(a->ptr);
147 return(1);
148 }
149
150static int ssl_read(b,out,outl)
151BIO *b;
152char *out;
153int outl;
154 {
155 int ret=1;
156 BIO_SSL *sb;
157 SSL *ssl;
158 int retry_reason=0;
159 int r=0;
160
161 if (out == NULL) return(0);
162 sb=(BIO_SSL *)b->ptr;
163 ssl=sb->ssl;
164
165 BIO_clear_retry_flags(b);
166
167#if 0
168 if (!SSL_is_init_finished(ssl))
169 {
170/* ret=SSL_do_handshake(ssl); */
171 if (ret > 0)
172 {
173
174 outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
175 ret= -1;
176 goto end;
177 }
178 }
179#endif
180/* if (ret > 0) */
181 ret=SSL_read(ssl,out,outl);
182
183 switch (SSL_get_error(ssl,ret))
184 {
185 case SSL_ERROR_NONE:
186 if (ret <= 0) break;
187 if (sb->renegotiate_count > 0)
188 {
189 sb->byte_count+=ret;
190 if (sb->byte_count > sb->renegotiate_count)
191 {
192 sb->byte_count=0;
193 sb->num_renegotiates++;
194 SSL_renegotiate(ssl);
195 r=1;
196 }
197 }
198 if ((sb->renegotiate_timeout > 0) && (!r))
199 {
200 unsigned long tm;
201
202 tm=(unsigned long)time(NULL);
203 if (tm > sb->last_time+sb->renegotiate_timeout)
204 {
205 sb->last_time=tm;
206 sb->num_renegotiates++;
207 SSL_renegotiate(ssl);
208 }
209 }
210
211 break;
212 case SSL_ERROR_WANT_READ:
213 BIO_set_retry_read(b);
214 break;
215 case SSL_ERROR_WANT_WRITE:
216 BIO_set_retry_write(b);
217 break;
218 case SSL_ERROR_WANT_X509_LOOKUP:
219 BIO_set_retry_special(b);
220 retry_reason=BIO_RR_SSL_X509_LOOKUP;
221 break;
222 case SSL_ERROR_WANT_CONNECT:
223 BIO_set_retry_special(b);
224 retry_reason=BIO_RR_CONNECT;
225 break;
226 case SSL_ERROR_SYSCALL:
227 case SSL_ERROR_SSL:
228 case SSL_ERROR_ZERO_RETURN:
229 default:
230 break;
231 }
232
233 b->retry_reason=retry_reason;
234 return(ret);
235 }
236
237static int ssl_write(b,out,outl)
238BIO *b;
239char *out;
240int outl;
241 {
242 int ret,r=0;
243 int retry_reason=0;
244 SSL *ssl;
245 BIO_SSL *bs;
246
247 if (out == NULL) return(0);
248 bs=(BIO_SSL *)b->ptr;
249 ssl=bs->ssl;
250
251 BIO_clear_retry_flags(b);
252
253/* ret=SSL_do_handshake(ssl);
254 if (ret > 0) */
255 ret=SSL_write(ssl,out,outl);
256
257 switch (SSL_get_error(ssl,ret))
258 {
259 case SSL_ERROR_NONE:
260 if (ret <= 0) break;
261 if (bs->renegotiate_count > 0)
262 {
263 bs->byte_count+=ret;
264 if (bs->byte_count > bs->renegotiate_count)
265 {
266 bs->byte_count=0;
267 bs->num_renegotiates++;
268 SSL_renegotiate(ssl);
269 r=1;
270 }
271 }
272 if ((bs->renegotiate_timeout > 0) && (!r))
273 {
274 unsigned long tm;
275
276 tm=(unsigned long)time(NULL);
277 if (tm > bs->last_time+bs->renegotiate_timeout)
278 {
279 bs->last_time=tm;
280 bs->num_renegotiates++;
281 SSL_renegotiate(ssl);
282 }
283 }
284 break;
285 case SSL_ERROR_WANT_WRITE:
286 BIO_set_retry_write(b);
287 break;
288 case SSL_ERROR_WANT_READ:
289 BIO_set_retry_read(b);
290 break;
291 case SSL_ERROR_WANT_X509_LOOKUP:
292 BIO_set_retry_special(b);
293 retry_reason=BIO_RR_SSL_X509_LOOKUP;
294 break;
295 case SSL_ERROR_WANT_CONNECT:
296 BIO_set_retry_special(b);
297 retry_reason=BIO_RR_CONNECT;
298 case SSL_ERROR_SYSCALL:
299 case SSL_ERROR_SSL:
300 default:
301 break;
302 }
303
304 b->retry_reason=retry_reason;
305 return(ret);
306 }
307
308static long ssl_ctrl(b,cmd,num,ptr)
309BIO *b;
310int cmd;
311long num;
312char *ptr;
313 {
314 SSL **sslp,*ssl;
315 BIO_SSL *bs;
316 BIO *dbio,*bio;
317 long ret=1;
318
319 bs=(BIO_SSL *)b->ptr;
320 ssl=bs->ssl;
321 if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))
322 return(0);
323 switch (cmd)
324 {
325 case BIO_CTRL_RESET:
326 SSL_shutdown(ssl);
327
328 if (ssl->handshake_func == ssl->method->ssl_connect)
329 SSL_set_connect_state(ssl);
330 else if (ssl->handshake_func == ssl->method->ssl_accept)
331 SSL_set_accept_state(ssl);
332
333 SSL_clear(ssl);
334
335 if (b->next_bio != NULL)
336 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
337 else if (ssl->rbio != NULL)
338 ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
339 else
340 ret=1;
341 break;
342 case BIO_CTRL_INFO:
343 ret=0;
344 break;
345 case BIO_C_SSL_MODE:
346 if (num) /* client mode */
347 SSL_set_connect_state(ssl);
348 else
349 SSL_set_accept_state(ssl);
350 break;
351 case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
352 ret=bs->renegotiate_timeout;
353 if (num < 60) num=5;
354 bs->renegotiate_timeout=(unsigned long)num;
355 bs->last_time=(unsigned long)time(NULL);
356 break;
357 case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
358 ret=bs->renegotiate_count;
359 if ((long)num >=512)
360 bs->renegotiate_count=(unsigned long)num;
361 break;
362 case BIO_C_GET_SSL_NUM_RENEGOTIATES:
363 ret=bs->num_renegotiates;
364 break;
365 case BIO_C_SET_SSL:
366 if (ssl != NULL)
367 ssl_free(b);
368 b->shutdown=(int)num;
369 ssl=(SSL *)ptr;
370 ((BIO_SSL *)b->ptr)->ssl=ssl;
371 bio=SSL_get_rbio(ssl);
372 if (bio != NULL)
373 {
374 if (b->next_bio != NULL)
375 BIO_push(bio,b->next_bio);
376 b->next_bio=bio;
377 CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO);
378 }
379 b->init=1;
380 break;
381 case BIO_C_GET_SSL:
382 if (ptr != NULL)
383 {
384 sslp=(SSL **)ptr;
385 *sslp=ssl;
386 }
387 else
388 ret=0;
389 break;
390 case BIO_CTRL_GET_CLOSE:
391 ret=b->shutdown;
392 break;
393 case BIO_CTRL_SET_CLOSE:
394 b->shutdown=(int)num;
395 break;
396 case BIO_CTRL_WPENDING:
397 ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
398 break;
399 case BIO_CTRL_PENDING:
400 ret=SSL_pending(ssl);
401 if (ret == 0)
402 ret=BIO_pending(ssl->rbio);
403 break;
404 case BIO_CTRL_FLUSH:
405 BIO_clear_retry_flags(b);
406 ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
407 BIO_copy_next_retry(b);
408 break;
409 case BIO_CTRL_PUSH:
410 if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio))
411 {
412 SSL_set_bio(ssl,b->next_bio,b->next_bio);
413 CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
414 }
415 break;
416 case BIO_CTRL_POP:
417 /* ugly bit of a hack */
418 if (ssl->rbio != ssl->wbio) /* we are in trouble :-( */
419 {
420 BIO_free_all(ssl->wbio);
421 }
422 ssl->wbio=NULL;
423 ssl->rbio=NULL;
424 break;
425 case BIO_C_DO_STATE_MACHINE:
426 BIO_clear_retry_flags(b);
427
428 b->retry_reason=0;
429 ret=(int)SSL_do_handshake(ssl);
430
431 switch (SSL_get_error(ssl,(int)ret))
432 {
433 case SSL_ERROR_WANT_READ:
434 BIO_set_flags(b,
435 BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
436 break;
437 case SSL_ERROR_WANT_WRITE:
438 BIO_set_flags(b,
439 BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
440 break;
441 case SSL_ERROR_WANT_CONNECT:
442 BIO_set_flags(b,
443 BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);
444 b->retry_reason=b->next_bio->retry_reason;
445 break;
446 default:
447 break;
448 }
449 break;
450 case BIO_CTRL_DUP:
451 dbio=(BIO *)ptr;
452 if (((BIO_SSL *)dbio->ptr)->ssl != NULL)
453 SSL_free(((BIO_SSL *)dbio->ptr)->ssl);
454 ((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl);
455 ((BIO_SSL *)dbio->ptr)->renegotiate_count=
456 ((BIO_SSL *)b->ptr)->renegotiate_count;
457 ((BIO_SSL *)dbio->ptr)->byte_count=
458 ((BIO_SSL *)b->ptr)->byte_count;
459 ((BIO_SSL *)dbio->ptr)->renegotiate_timeout=
460 ((BIO_SSL *)b->ptr)->renegotiate_timeout;
461 ((BIO_SSL *)dbio->ptr)->last_time=
462 ((BIO_SSL *)b->ptr)->last_time;
463 ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL);
464 break;
465 case BIO_C_GET_FD:
466 ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
467 break;
468 case BIO_CTRL_SET_CALLBACK:
469 SSL_set_info_callback(ssl,(void (*)())ptr);
470 break;
471 case BIO_CTRL_GET_CALLBACK:
472 {
473 void (**fptr)();
474
475 fptr=(void (**)())ptr;
476 *fptr=SSL_get_info_callback(ssl);
477 }
478 break;
479 default:
480 ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
481 break;
482 }
483 return(ret);
484 }
485
486static int ssl_puts(bp,str)
487BIO *bp;
488char *str;
489 {
490 int n,ret;
491
492 n=strlen(str);
493 ret=BIO_write(bp,str,n);
494 return(ret);
495 }
496
497BIO *BIO_new_buffer_ssl_connect(ctx)
498SSL_CTX *ctx;
499 {
500 BIO *ret=NULL,*buf=NULL,*ssl=NULL;
501
502 if ((buf=BIO_new(BIO_f_buffer())) == NULL)
503 return(NULL);
504 if ((ssl=BIO_new_ssl_connect(ctx)) == NULL)
505 goto err;
506 if ((ret=BIO_push(buf,ssl)) == NULL)
507 goto err;
508 return(ret);
509err:
510 if (buf != NULL) BIO_free(buf);
511 if (ssl != NULL) BIO_free(ssl);
512 return(NULL);
513 }
514
515BIO *BIO_new_ssl_connect(ctx)
516SSL_CTX *ctx;
517 {
518 BIO *ret=NULL,*con=NULL,*ssl=NULL;
519
520 if ((con=BIO_new(BIO_s_connect())) == NULL)
521 return(NULL);
522 if ((ssl=BIO_new_ssl(ctx,1)) == NULL)
523 goto err;
524 if ((ret=BIO_push(ssl,con)) == NULL)
525 goto err;
526 return(ret);
527err:
528 if (con != NULL) BIO_free(con);
529 if (ret != NULL) BIO_free(ret);
530 return(NULL);
531 }
532
533BIO *BIO_new_ssl(ctx,client)
534SSL_CTX *ctx;
535int client;
536 {
537 BIO *ret;
538 SSL *ssl;
539
540 if ((ret=BIO_new(BIO_f_ssl())) == NULL)
541 return(NULL);
542 if ((ssl=SSL_new(ctx)) == NULL)
543 {
544 BIO_free(ret);
545 return(NULL);
546 }
547 if (client)
548 SSL_set_connect_state(ssl);
549 else
550 SSL_set_accept_state(ssl);
551
552 BIO_set_ssl(ret,ssl,BIO_CLOSE);
553 return(ret);
554 }
555
556int BIO_ssl_copy_session_id(t,f)
557BIO *t,*f;
558 {
559 t=BIO_find_type(t,BIO_TYPE_SSL);
560 f=BIO_find_type(f,BIO_TYPE_SSL);
561 if ((t == NULL) || (f == NULL))
562 return(0);
563 if ( (((BIO_SSL *)t->ptr)->ssl == NULL) ||
564 (((BIO_SSL *)f->ptr)->ssl == NULL))
565 return(0);
566 SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl);
567 return(1);
568 }
569
570void BIO_ssl_shutdown(b)
571BIO *b;
572 {
573 SSL *s;
574
575 while (b != NULL)
576 {
577 if (b->method->type == BIO_TYPE_SSL)
578 {
579 s=((BIO_SSL *)b->ptr)->ssl;
580 SSL_shutdown(s);
581 break;
582 }
583 b=b->next_bio;
584 }
585 }