Move the registration of callback functions to special functions
authorRichard Levitte <levitte@openssl.org>
Sun, 20 Feb 2000 23:43:02 +0000 (23:43 +0000)
committerRichard Levitte <levitte@openssl.org>
Sun, 20 Feb 2000 23:43:02 +0000 (23:43 +0000)
designed for that.  This removes the potential error to mix data and
function pointers.

Please note that I'm a little unsure how incorrect calls to the old
ctrl functions should be handled, in som cases.  I currently return 0
and that's it, but it may be more correct to generate a genuine error
in those cases.

28 files changed:
crypto/bio/bf_buff.c
crypto/bio/bf_nbio.c
crypto/bio/bf_null.c
crypto/bio/bio.h
crypto/bio/bio_lib.c
crypto/bio/bss_acpt.c
crypto/bio/bss_bio.c
crypto/bio/bss_conn.c
crypto/bio/bss_file.c
crypto/bio/bss_log.c
crypto/bio/bss_mem.c
crypto/bio/bss_null.c
crypto/bio/bss_rtcp.c
crypto/bio/bss_sock.c
crypto/comp/comp.h
crypto/evp/bio_b64.c
crypto/evp/bio_enc.c
crypto/evp/bio_md.c
crypto/evp/bio_ok.c
crypto/pkcs7/bio_ber.c
ssl/bio_ssl.c
ssl/s23_lib.c
ssl/s2_lib.c
ssl/s3_lib.c
ssl/ssl.h
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/t1_lib.c

index acd8148..ff0c907 100644 (file)
@@ -69,6 +69,7 @@ static int buffer_gets(BIO *h,char *str,int size);
 static long buffer_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int buffer_new(BIO *h);
 static int buffer_free(BIO *data);
+static long buffer_callback_ctrl(BIO *h,int cmd, void (*fp)());
 #define DEFAULT_BUFFER_SIZE    1024
 
 static BIO_METHOD methods_buffer=
@@ -82,6 +83,7 @@ static BIO_METHOD methods_buffer=
        buffer_ctrl,
        buffer_new,
        buffer_free,
+       buffer_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_buffer(void)
@@ -284,6 +286,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, char *ptr)
                ctx->ibuf_len=0;
                ctx->obuf_off=0;
                ctx->obuf_len=0;
+               if (b->next_bio == NULL) return(0);
                ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
                break;
        case BIO_CTRL_INFO:
@@ -300,12 +303,18 @@ static long buffer_ctrl(BIO *b, int cmd, long num, char *ptr)
        case BIO_CTRL_WPENDING:
                ret=(long)ctx->obuf_len;
                if (ret == 0)
+                       {
+                       if (b->next_bio == NULL) return(0);
                        ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+                       }
                break;
        case BIO_CTRL_PENDING:
                ret=(long)ctx->ibuf_len;
                if (ret == 0)
+                       {
+                       if (b->next_bio == NULL) return(0);
                        ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+                       }
                break;
        case BIO_C_SET_BUFF_READ_DATA:
                if (num > ctx->ibuf_size)
@@ -374,12 +383,14 @@ static long buffer_ctrl(BIO *b, int cmd, long num, char *ptr)
                        }
                break;
        case BIO_C_DO_STATE_MACHINE:
+               if (b->next_bio == NULL) return(0);
                BIO_clear_retry_flags(b);
                ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
                BIO_copy_next_retry(b);
                break;
 
        case BIO_CTRL_FLUSH:
+               if (b->next_bio == NULL) return(0);
                if (ctx->obuf_len <= 0)
                        {
                        ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
@@ -418,6 +429,7 @@ fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len-ctx->obuf_
                        ret=0;
                break;
        default:
+               if (b->next_bio == NULL) return(0);
                ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
                break;
                }
@@ -427,6 +439,20 @@ malloc_error:
        return(0);
        }
 
+static long buffer_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 static int buffer_gets(BIO *b, char *buf, int size)
        {
        BIO_F_BUFFER_CTX *ctx;
index a525e79..5e574b7 100644 (file)
@@ -73,6 +73,7 @@ static int nbiof_gets(BIO *h,char *str,int size);
 static long nbiof_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int nbiof_new(BIO *h);
 static int nbiof_free(BIO *data);
+static long nbiof_callback_ctrl(BIO *h,int cmd,void (*fp)());
 typedef struct nbio_test_st
        {
        /* only set if we sent a 'should retry' error */
@@ -91,6 +92,7 @@ static BIO_METHOD methods_nbiof=
        nbiof_ctrl,
        nbiof_new,
        nbiof_free,
+       nbiof_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_nbio_test(void)
@@ -224,6 +226,20 @@ static long nbiof_ctrl(BIO *b, int cmd, long num, char *ptr)
        return(ret);
        }
 
+static long nbiof_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 static int nbiof_gets(BIO *bp, char *buf, int size)
        {
        if (bp->next_bio == NULL) return(0);
index 3254a55..0d183a6 100644 (file)
@@ -72,6 +72,7 @@ static int nullf_gets(BIO *h,char *str,int size);
 static long nullf_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int nullf_new(BIO *h);
 static int nullf_free(BIO *data);
+static long nullf_callback_ctrl(BIO *h,int cmd,void (*fp)());
 static BIO_METHOD methods_nullf=
        {
        BIO_TYPE_NULL_FILTER,
@@ -83,6 +84,7 @@ static BIO_METHOD methods_nullf=
        nullf_ctrl,
        nullf_new,
        nullf_free,
+       nullf_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_null(void)
@@ -152,6 +154,20 @@ static long nullf_ctrl(BIO *b, int cmd, long num, char *ptr)
        return(ret);
        }
 
+static long nullf_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 static int nullf_gets(BIO *bp, char *buf, int size)
        {
        if (bp->next_bio == NULL) return(0);
index 30fdb4a..8842a11 100644 (file)
@@ -219,6 +219,7 @@ typedef struct bio_method_st
        long (*ctrl)();
        int (*create)();
        int (*destroy)();
+       long (*callback_ctrl)();
        } BIO_METHOD;
 #else
 typedef struct bio_method_st
@@ -232,6 +233,7 @@ typedef struct bio_method_st
        long (_far *ctrl)();
        int (_far *create)();
        int (_far *destroy)();
+       long (_fat *callback_ctrl)();
        } BIO_METHOD;
 #endif
 
@@ -373,7 +375,7 @@ typedef struct bio_f_buffer_ctx_struct
 /* BIO_set_nbio(b,n) */
 #define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
 /* BIO *BIO_get_filter_bio(BIO *bio); */
-#define BIO_set_proxy_cb(b,cb) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(char *)(cb))
+#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
 #define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
 #define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
 
@@ -452,8 +454,8 @@ int BIO_read_filename(BIO *b,const char *name);
 size_t BIO_ctrl_pending(BIO *b);
 size_t BIO_ctrl_wpending(BIO *b);
 #define BIO_flush(b)           (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
-#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0,(char *)cbp)
-#define BIO_set_info_callback(b,cb) (int)BIO_ctrl(b,BIO_CTRL_SET_CALLBACK,0,(char *)cb)
+#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0,(void (**)())(cbp))
+#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,(void (*)())(cb))
 
 /* For the BIO_f_buffer() type */
 #define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
@@ -508,6 +510,7 @@ int BIO_gets(BIO *bp,char *buf, int size);
 int    BIO_write(BIO *b, const char *data, int len);
 int    BIO_puts(BIO *bp,const char *buf);
 long   BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
+long   BIO_callback_ctrl(BIO *bp,int cmd,void (*fp)());
 char * BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
 long   BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
 BIO *  BIO_push(BIO *b,BIO *append);
index ae225da..cf8e615 100644 (file)
@@ -317,16 +317,43 @@ long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
        return(ret);
        }
 
+long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret;
+       long (*cb)();
+
+       if (b == NULL) return(0);
+
+       if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
+               {
+               BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
+               return(-2);
+               }
+
+       cb=b->callback;
+
+       if ((cb != NULL) &&
+               ((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
+               return(ret);
+
+       ret=b->method->callback_ctrl(b,cmd,fp);
+
+       if (cb != NULL)
+               ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
+                       0,ret);
+       return(ret);
+       }
+
 /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
  * do; but those macros have inappropriate return type, and for interfacing
  * from other programming languages, C macros aren't much of a help anyway. */
 size_t BIO_ctrl_pending(BIO *bio)
-    {
+       {
        return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
        }
 
 size_t BIO_ctrl_wpending(BIO *bio)
-    {
+       {
        return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
        }
 
index 47af80f..9afa636 100644 (file)
@@ -118,6 +118,7 @@ static BIO_METHOD methods_acceptp=
        acpt_ctrl,
        acpt_new,
        acpt_free,
+       NULL,
        };
 
 BIO_METHOD *BIO_s_accept(void)
index 36c89cc..0d0f935 100644 (file)
@@ -41,7 +41,8 @@ static BIO_METHOD methods_biop =
        NULL /* no bio_gets */,
        bio_ctrl,
        bio_new,
-       bio_free
+       bio_free,
+       NULL /* no bio_callback_ctrl */
 };
 
 BIO_METHOD *BIO_s_bio(void)
index 6deee1a..22d00b3 100644 (file)
@@ -98,18 +98,13 @@ typedef struct bio_connect_st
        int (*info_callback)();
        } BIO_CONNECT;
 
-union int_fn_to_char_u
-       {
-       char *char_p;
-       int (*fn_p)();
-       };
-
 static int conn_write(BIO *h,char *buf,int num);
 static int conn_read(BIO *h,char *buf,int size);
 static int conn_puts(BIO *h,char *str);
 static long conn_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int conn_new(BIO *h);
 static int conn_free(BIO *data);
+static long conn_callback_ctrl(BIO *h,int cmd,void *(*fp)());
 
 static int conn_state(BIO *b, BIO_CONNECT *c);
 static void conn_close_socket(BIO *data);
@@ -127,6 +122,7 @@ static BIO_METHOD methods_connectp=
        conn_ctrl,
        conn_new,
        conn_free,
+       conn_callback_ctrl,
        };
 
 static int conn_state(BIO *b, BIO_CONNECT *c)
@@ -571,24 +567,23 @@ static long conn_ctrl(BIO *b, int cmd, long num, char *ptr)
                break;
        case BIO_CTRL_DUP:
                {
-               union int_fn_to_char_u tmp_cb;
-               
                dbio=(BIO *)ptr;
                if (data->param_port)
                        BIO_set_conn_port(dbio,data->param_port);
                if (data->param_hostname)
                        BIO_set_conn_hostname(dbio,data->param_hostname);
                BIO_set_nbio(dbio,data->nbio);
-               tmp_cb.fn_p=data->info_callback;
-               (void)BIO_set_info_callback(dbio,tmp_cb.char_p);
+               (void)BIO_set_info_callback(dbio,(void *(*)())(data->info_callback));
                }
                break;
        case BIO_CTRL_SET_CALLBACK:
                {
-               union int_fn_to_char_u tmp_cb;
-               
-               tmp_cb.char_p=ptr;
-               data->info_callback=tmp_cb.fn_p;
+#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
+               BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               ret = -1;
+#else
+               ret=0;
+#endif
                }
                break;
        case BIO_CTRL_GET_CALLBACK:
@@ -606,6 +601,27 @@ static long conn_ctrl(BIO *b, int cmd, long num, char *ptr)
        return(ret);
        }
 
+static long conn_callback_ctrl(BIO *b, int cmd, void *(*fp)())
+       {
+       long ret=1;
+       BIO_CONNECT *data;
+
+       data=(BIO_CONNECT *)b->ptr;
+
+       switch (cmd)
+               {
+       case BIO_CTRL_SET_CALLBACK:
+               {
+               data->info_callback=(int (*)())fp;
+               }
+               break;
+       default:
+               ret=0;
+               break;
+               }
+       return(ret);
+       }
+
 static int conn_puts(BIO *bp, char *str)
        {
        int n,ret;
index 2a113cb..0d44dc3 100644 (file)
@@ -91,6 +91,7 @@ static BIO_METHOD methods_filep=
        file_ctrl,
        file_new,
        file_free,
+       NULL,
        };
 
 BIO *BIO_new_file(const char *filename, const char *mode)
index b52fbe1..4308b19 100644 (file)
@@ -100,6 +100,7 @@ static BIO_METHOD methods_slg=
        slg_ctrl,
        slg_new,
        slg_free,
+       NULL,
        };
 
 BIO_METHOD *BIO_s_log(void)
index d9a2280..41eab92 100644 (file)
@@ -79,6 +79,7 @@ static BIO_METHOD mem_method=
        mem_ctrl,
        mem_new,
        mem_free,
+       NULL,
        };
 
 /* bio->num is used to hold the value to return on 'empty', if it is
index d04be88..aee18e3 100644 (file)
@@ -79,6 +79,7 @@ static BIO_METHOD null_method=
        null_ctrl,
        null_new,
        null_free,
+       NULL,
        };
 
 BIO_METHOD *BIO_s_null(void)
index 2ef0400..4ad0739 100644 (file)
@@ -107,6 +107,7 @@ static BIO_METHOD rtcp_method=
        rtcp_ctrl,
        rtcp_new,
        rtcp_free,
+       NULL,
        };
 
 BIO_METHOD *BIO_s_rtcp(void)
index 1b8d040..8ce80ef 100644 (file)
@@ -95,6 +95,7 @@ static BIO_METHOD methods_sockp=
        sock_ctrl,
        sock_new,
        sock_free,
+       NULL,
        };
 
 BIO_METHOD *BIO_s_socket(void)
@@ -112,6 +113,7 @@ static BIO_METHOD methods_fdp=
        fd_ctrl,
        fd_new,
        fd_free,
+       NULL,
        };
 
 BIO_METHOD *BIO_s_fd(void)
index 93bd9c3..811cb58 100644 (file)
@@ -17,6 +17,7 @@ typedef struct comp_method_st
        int (*compress)();
        int (*expand)();
        long (*ctrl)();
+       long (*callback_ctrl)();
        } COMP_METHOD;
 
 typedef struct comp_ctx_st
index 913bafa..bd5e24f 100644 (file)
@@ -69,6 +69,7 @@ static int b64_read(BIO *h,char *buf,int size);
 static long b64_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int b64_new(BIO *h);
 static int b64_free(BIO *data);
+static long b64_callback_ctrl(BIO *h,int cmd,void (*fp)());
 #define B64_BLOCK_SIZE 1024
 #define B64_BLOCK_SIZE2        768
 #define B64_NONE       0
@@ -100,6 +101,7 @@ static BIO_METHOD methods_b64=
        b64_ctrl,
        b64_new,
        b64_free,
+       b64_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_base64(void)
@@ -522,3 +524,17 @@ again:
        return(ret);
        }
 
+static long b64_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
index 36a6018..629bf4b 100644 (file)
@@ -69,6 +69,7 @@ static int enc_read(BIO *h,char *buf,int size);
 static long enc_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int enc_new(BIO *h);
 static int enc_free(BIO *data);
+static long enc_callback_ctrl(BIO *h,int cmd,void (*fp)());
 #define ENC_BLOCK_SIZE (1024*4)
 
 typedef struct enc_struct
@@ -92,6 +93,7 @@ static BIO_METHOD methods_enc=
        enc_ctrl,
        enc_new,
        enc_free,
+       enc_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_cipher(void)
@@ -368,6 +370,20 @@ again:
        return(ret);
        }
 
+static long enc_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 /*
 void BIO_set_cipher_ctx(b,c)
 BIO *b;
index 317167f..aef928d 100644 (file)
@@ -72,6 +72,8 @@ static int md_gets(BIO *h,char *str,int size);
 static long md_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int md_new(BIO *h);
 static int md_free(BIO *data);
+static long md_callback_ctrl(BIO *h,int cmd,void (*fp)());
+
 static BIO_METHOD methods_md=
        {
        BIO_TYPE_MD,"message digest",
@@ -82,6 +84,7 @@ static BIO_METHOD methods_md=
        md_ctrl,
        md_new,
        md_free,
+       md_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_md(void)
@@ -220,6 +223,20 @@ static long md_ctrl(BIO *b, int cmd, long num, char *ptr)
        return(ret);
        }
 
+static long md_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 static int md_gets(BIO *bp, char *buf, int size)
        {
        EVP_MD_CTX *ctx;
index a04efa7..e6ff5f2 100644 (file)
@@ -130,6 +130,8 @@ static int ok_read(BIO *h,char *buf,int size);
 static long ok_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int ok_new(BIO *h);
 static int ok_free(BIO *data);
+static long ok_callback_ctrl(BIO *h,int cmd,void (*fp)());
+
 static void sig_out(BIO* b);
 static void sig_in(BIO* b);
 static void block_out(BIO* b);
@@ -173,6 +175,7 @@ static BIO_METHOD methods_ok=
        ok_ctrl,
        ok_new,
        ok_free,
+       ok_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_reliable(void)
@@ -428,6 +431,20 @@ static long ok_ctrl(BIO *b, int cmd, long num, char *ptr)
        return(ret);
        }
 
+static long ok_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 static void longswap(void *_ptr, int len)
 {
 #ifndef L_ENDIAN
index 25831e5..4803966 100644 (file)
@@ -69,6 +69,7 @@ static int ber_read(BIO *h,char *buf,int size);
 static long ber_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int ber_new(BIO *h);
 static int ber_free(BIO *data);
+static long ber_callback_ctrl(BIO *h,int cmd,void *(*fp)());
 #define BER_BUF_SIZE   (32)
 
 /* This is used to hold the state of the BER objects being read. */
@@ -115,6 +116,7 @@ static BIO_METHOD methods_ber=
        ber_ctrl,
        ber_new,
        ber_free,
+       ber_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_ber(void)
@@ -409,6 +411,20 @@ again:
        return(ret);
        }
 
+static long ber_callback_ctrl(BIO *b, int cmd, void *(*fp)())
+       {
+       long ret=1;
+
+       if (b->next_bio == NULL) return(0);
+       switch (cmd)
+               {
+       default:
+               ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 /*
 void BIO_set_cipher_ctx(b,c)
 BIO *b;
index aa29699..d73c41a 100644 (file)
@@ -71,6 +71,7 @@ static int ssl_puts(BIO *h,char *str);
 static long ssl_ctrl(BIO *h,int cmd,long arg1,char *arg2);
 static int ssl_new(BIO *h);
 static int ssl_free(BIO *data);
+static long ssl_callback_ctrl(BIO *h,int cmd,void (*fp)());
 typedef struct bio_ssl_st
        {
        SSL *ssl; /* The ssl handle :-) */
@@ -92,12 +93,7 @@ static BIO_METHOD methods_sslp=
        ssl_ctrl,
        ssl_new,
        ssl_free,
-       };
-
-union void_fn_to_char_u
-       {
-       char *char_p;
-       void (*fn_p)();
+       ssl_callback_ctrl,
        };
 
 BIO_METHOD *BIO_f_ssl(void)
@@ -451,10 +447,12 @@ static long ssl_ctrl(BIO *b, int cmd, long num, char *ptr)
                break;
        case BIO_CTRL_SET_CALLBACK:
                {
-               union void_fn_to_char_u tmp_cb;
-
-               tmp_cb.char_p = ptr;
-               SSL_set_info_callback(ssl,tmp_cb.fn_p);
+#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
+               BIOerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               ret = -1;
+#else
+               ret=0;
+#endif
                }
                break;
        case BIO_CTRL_GET_CALLBACK:
@@ -472,6 +470,28 @@ static long ssl_ctrl(BIO *b, int cmd, long num, char *ptr)
        return(ret);
        }
 
+static long ssl_callback_ctrl(BIO *b, int cmd, void (*fp)())
+       {
+       SSL *ssl;
+       BIO_SSL *bs;
+       long ret=1;
+
+       bs=(BIO_SSL *)b->ptr;
+       ssl=bs->ssl;
+       switch (cmd)
+               {
+       case BIO_CTRL_SET_CALLBACK:
+               {
+               SSL_set_info_callback(ssl,fp);
+               }
+               break;
+       default:
+               ret=BIO_callback_ctrl(ssl->rbio,cmd,fp);
+               break;
+               }
+       return(ret);
+       }
+
 static int ssl_puts(BIO *bp, char *str)
        {
        int n,ret;
index 41843df..dded7a1 100644 (file)
@@ -92,6 +92,9 @@ static SSL_METHOD SSLv23_data= {
        ssl_bad_method,
        ssl23_default_timeout,
        &ssl3_undef_enc_method,
+       ssl_undefined_function,
+       ssl3_callback_ctrl,
+       ssl3_ctx_callback_ctrl,
        };
 
 static long ssl23_default_timeout(void)
index 47713ec..5ddba23 100644 (file)
@@ -230,6 +230,9 @@ static SSL_METHOD SSLv2_data= {
        ssl_bad_method,
        ssl2_default_timeout,
        &ssl3_undef_enc_method,
+       ssl_undefined_function,
+       ssl2_callback_ctrl,     /* local */
+       ssl2_ctx_callback_ctrl, /* local */
        };
 
 static long ssl2_default_timeout(void)
@@ -335,11 +338,21 @@ long ssl2_ctrl(SSL *s, int cmd, long larg, char *parg)
        return(ret);
        }
 
+long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp)())
+       {
+       return(0);
+       }
+
 long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg)
        {
        return(0);
        }
 
+long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)())
+       {
+       return(0);
+       }
+
 /* This function needs to check if the ciphers required are actually
  * available */
 SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
index 7c71f5e..87525fa 100644 (file)
@@ -608,18 +608,9 @@ static SSL_METHOD SSLv3_data= {
        ssl_bad_method,
        ssl3_default_timeout,
        &SSLv3_enc_data,
-       };
-
-union rsa_fn_to_char_u
-       {
-       char *char_p;
-       RSA *(*fn_p)(SSL *, int, int);
-       };
-
-union dh_fn_to_char_u
-       {
-       char *char_p;
-       DH *(*fn_p)(SSL *, int, int);
+       ssl_undefined_function,
+       ssl3_callback_ctrl,
+       ssl3_ctx_callback_ctrl,
        };
 
 static long ssl3_default_timeout(void)
@@ -792,10 +783,8 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, char *parg)
                break;
        case SSL_CTRL_SET_TMP_RSA_CB:
                {
-               union rsa_fn_to_char_u rsa_tmp_cb;
-
-               rsa_tmp_cb.char_p = parg;
-               s->cert->rsa_tmp_cb = rsa_tmp_cb.fn_p;
+               SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return(ret);
                }
                break;
 #endif
@@ -824,10 +813,52 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, char *parg)
                break;
        case SSL_CTRL_SET_TMP_DH_CB:
                {
-               union dh_fn_to_char_u dh_tmp_cb;
+               SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return(ret);
+               }
+               break;
+#endif
+       default:
+               break;
+               }
+       return(ret);
+       }
 
-               dh_tmp_cb.char_p = parg;
-               s->cert->dh_tmp_cb = dh_tmp_cb.fn_p;
+long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)())
+       {
+       int ret=0;
+
+#if !defined(NO_DSA) || !defined(NO_RSA)
+       if (
+#ifndef NO_RSA
+           cmd == SSL_CTRL_SET_TMP_RSA_CB ||
+#endif
+#ifndef NO_DSA
+           cmd == SSL_CTRL_SET_TMP_DH_CB ||
+#endif
+               0)
+               {
+               if (!ssl_cert_inst(&s->cert))
+                       {
+                       SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
+                       return(0);
+                       }
+               }
+#endif
+
+       switch (cmd)
+               {
+#ifndef NO_RSA
+       case SSL_CTRL_SET_TMP_RSA_CB:
+               {
+               s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
+               }
+               break;
+#endif
+#ifndef NO_DH
+       case SSL_CTRL_SET_TMP_DH_CB:
+               {
+               s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
                }
                break;
 #endif
@@ -885,10 +916,8 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg)
                /* break; */
        case SSL_CTRL_SET_TMP_RSA_CB:
                {
-               union rsa_fn_to_char_u rsa_tmp_cb;
-
-               rsa_tmp_cb.char_p = parg;
-               cert->rsa_tmp_cb = rsa_tmp_cb.fn_p;
+               SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return(0);
                }
                break;
 #endif
@@ -917,10 +946,8 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg)
                /*break; */
        case SSL_CTRL_SET_TMP_DH_CB:
                {
-               union dh_fn_to_char_u dh_tmp_cb;
-
-               dh_tmp_cb.char_p = parg;
-               cert->dh_tmp_cb = dh_tmp_cb.fn_p;
+               SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return(0);
                }
                break;
 #endif
@@ -940,6 +967,34 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg)
        return(1);
        }
 
+long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)())
+       {
+       CERT *cert;
+
+       cert=ctx->cert;
+
+       switch (cmd)
+               {
+#ifndef NO_RSA
+       case SSL_CTRL_SET_TMP_RSA_CB:
+               {
+               cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
+               }
+               break;
+#endif
+#ifndef NO_DH
+       case SSL_CTRL_SET_TMP_DH_CB:
+               {
+               cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
+               }
+               break;
+#endif
+       default:
+               return(0);
+               }
+       return(1);
+       }
+
 /* This function needs to check if the ciphers required are actually
  * available */
 SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
index 6f31992..040304b 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -210,6 +210,8 @@ typedef struct ssl_method_st
        long (*get_timeout)(void);
        struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
        int (*ssl_version)();
+       long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)());
+       long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)());
        } SSL_METHOD;
 
 /* Lets make this into an ASN.1 type structure as follows
index 3c71d5b..8a9d289 100644 (file)
@@ -794,6 +794,15 @@ long SSL_ctrl(SSL *s,int cmd,long larg,char *parg)
                }
        }
 
+long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)())
+       {
+       switch(cmd)
+               {
+       default:
+               return(s->method->ssl_callback_ctrl(s,cmd,fp));
+               }
+       }
+
 long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
        {
        long l;
@@ -853,6 +862,15 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
                }
        }
 
+long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)())
+       {
+       switch(cmd)
+               {
+       default:
+               return(ctx->method->ssl_ctx_callback_ctrl(ctx,cmd,fp));
+               }
+       }
+
 int ssl_cipher_id_cmp(SSL_CIPHER *a,SSL_CIPHER *b)
        {
        long l;
@@ -1988,21 +2006,14 @@ void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
                                                          int is_export,
                                                          int keylength))
     {
-    union rsa_fn_to_char_u rsa_tmp_cb;
-
-    rsa_tmp_cb.fn_p = cb;
-    SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,0,rsa_tmp_cb.char_p);
+    SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_RSA_CB,(void (*)())cb);
     }
-#endif
 
-#ifndef NO_RSA
-void SSL_set_tmp_rsa_callback(SSL *ssl,RSA *(*cb)(SSL *ssl,int is_export,
-                                                         int keylength))
+void SSL_set_tmp_rsa_callback(SSL *ssl,RSA *(*cb)(SSL *ssl,
+                                                 int is_export,
+                                                 int keylength))
     {
-    union rsa_fn_to_char_u rsa_tmp_cb;
-
-    rsa_tmp_cb.fn_p = cb;
-    SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA_CB,0,rsa_tmp_cb.char_p);
+    SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_RSA_CB,(void (*)())cb);
     }
 #endif
 
@@ -2031,19 +2042,13 @@ RSA *cb(SSL *ssl,int is_export,int keylength)
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
                                                        int keylength))
     {
-    union dh_fn_to_char_u dh_tmp_cb;
-
-    dh_tmp_cb.fn_p = dh;
-    SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,0,dh_tmp_cb.char_p);
+    SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,(void (*)())dh);
     }
 
 void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
-                                                       int keylength))
+                                               int keylength))
     {
-    union dh_fn_to_char_u dh_tmp_cb;
-
-    dh_tmp_cb.fn_p = dh;
-    SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,0,dh_tmp_cb.char_p);
+    SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)())dh);
     }
 #endif
 
index eb28917..0f81902 100644 (file)
@@ -468,6 +468,8 @@ int ssl2_shutdown(SSL *s);
 void   ssl2_clear(SSL *s);
 long   ssl2_ctrl(SSL *s,int cmd, long larg, char *parg);
 long   ssl2_ctx_ctrl(SSL_CTX *s,int cmd, long larg, char *parg);
+long   ssl2_callback_ctrl(SSL *s,int cmd, void (*fp)());
+long   ssl2_ctx_callback_ctrl(SSL_CTX *s,int cmd, void (*fp)());
 int    ssl2_pending(SSL *s);
 
 SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
@@ -514,6 +516,8 @@ int ssl3_shutdown(SSL *s);
 void   ssl3_clear(SSL *s);
 long   ssl3_ctrl(SSL *s,int cmd, long larg, char *parg);
 long   ssl3_ctx_ctrl(SSL_CTX *s,int cmd, long larg, char *parg);
+long   ssl3_callback_ctrl(SSL *s,int cmd, void (*fp)());
+long   ssl3_ctx_callback_ctrl(SSL_CTX *s,int cmd, void (*fp)());
 int    ssl3_pending(SSL *s);
 
 int ssl23_accept(SSL *s);
@@ -525,6 +529,7 @@ int tls1_new(SSL *s);
 void tls1_free(SSL *s);
 void tls1_clear(SSL *s);
 long tls1_ctrl(SSL *s,int cmd, long larg, char *parg);
+long tls1_callback_ctrl(SSL *s,int cmd, void (*fp)());
 SSL_METHOD *tlsv1_base_method(void );
 
 int ssl_init_wbio_buffer(SSL *s, int push);
index 531969b..ca6c03d 100644 (file)
@@ -101,6 +101,9 @@ static SSL_METHOD TLSv1_data= {
        ssl_bad_method,
        tls1_default_timeout,
        &TLSv1_enc_data,
+       ssl_undefined_function,
+       ssl3_callback_ctrl,
+       ssl3_ctx_callback_ctrl,
        };
 
 static long tls1_default_timeout(void)
@@ -138,4 +141,9 @@ long tls1_ctrl(SSL *s, int cmd, long larg, char *parg)
        {
        return(0);
        }
+
+long tls1_callback_ctrl(SSL *s, int cmd, void *(*fp)())
+       {
+       return(0);
+       }
 #endif