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 acd81481389247a8790e628effc9a9f55e7eebc2..ff0c9070ae101422ab094bb36d14e14553777f94 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 a525e79d4fb28f68b82b62a094176da52c048cfd..5e574b7231648da8885fa1644f429a45e8a65f06 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 3254a55dce7fcf213e822f24f3b2f752b5d92906..0d183a6d9a46796e0b1d2000cb30795a9576144a 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 30fdb4a3ebbe6933344d4f4b54aa55e0b21ef1b4..8842a1182cd65682b855c9f7d186464ec62036fc 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 ae225da986bcca00f886f96fbf736c6bf7e5a6bc..cf8e6150fd5a4f732a3d8dcceae1f36097bd3762 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 47af80f76d51d2976f88952b908b1300dbb2af06..9afa6364069d9f7ac78f5cfb2c8a2bb4e657680c 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 36c89ccbf5766f674120fcf59ccb786621c7d110..0d0f9356f7dabbd24f4bbd2273e5b9cf54b933b9 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 6deee1a35fd8fe29e050b45fd197b3420d6d718f..22d00b369ecbc2ec0923b0d1212507e950948e6f 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 2a113cbfff5a43250d750c49a8e8726244f17225..0d44dc388968975751f5d535277118b92be62b18 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 b52fbe1d4c61c9d4352bba092ae63abde9e8a24a..4308b196633630e72eb35188416770a295107ca2 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 d9a2280d8f0994a87608eec2c74e477f1eec8859..41eab92415e2cbb38bf2db852490b162179cd2f7 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 d04be888e53fab72ea73871b8bbc88887defcba5..aee18e3ada46f50d8739e9da5f40124928e87ac8 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 2ef040057e3fad4ba03f22cb4ca49d5d11066a24..4ad0739464b9d19473f87f19d609363575eb549c 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 1b8d04002d745fc0cdcdb818f1ed008aad852f14..8ce80ef68d2b0ffa31acf20d307b4b8c46f56094 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 93bd9c34c80c44610f31a6821ae07b7b156d349c..811cb5833d3b518198c9df1339c15d78e6d55d5d 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 913bafa5f79e60aa3308d38e985054b42bdfc037..bd5e24f993985a966582fcf430a76dc4a6b5fa9f 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 36a601897d37c7714dc757aec5d294f7fefe36d7..629bf4b95d9675db4d2e0fb21a548af3ccc3a0bc 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 317167f9c46db3f58a8524fa66519db7d5f9569b..aef928dd8fb2ee123fc9d547af28af79b0bfbc8d 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 a04efa7508284cbaa840d33e9389beabd16d5021..e6ff5f2cdb6b2c4015088e7cb2c35031f00c5c33 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 25831e577ec0366f23fd3df25a90e2f6814e6c7c..4803966fd2b1eb96cb0a0f2fdf445462298966dc 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 aa296996e665254e5ce094367caf0e1897b812d2..d73c41adcdc219597b49f14bed480cd286fa89dd 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 41843dfea21fde8af5c931ad701b61af4d641eaf..dded7a19c5a56ebe3378872635b6ab52a4f3b8ec 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 47713ec9f9d7d844d0ab47cf4d6a75cc927617f0..5ddba23a066208011202b774beb0e2fe114d34ab 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 7c71f5e3211f6dea1d6829ca5776f29277cd5362..87525faab496aca9496499e4296f484f4b8e8838 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 6f31992e5da5fb2d525570031042fe44d5e4bf2c..040304b7744e62b95c968c3a3573e0306d394890 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 3c71d5b367967c18e332a72bdac1a8a894c6d071..8a9d2894f1b7d4f0981fb364c770a00669916695 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 eb28917b20037278bb4b5de910bdb959d3c5dc98..0f819021f01c81c966e7907cd9e9a4ba32760f47 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 531969b4219cdff5e08fe7926da0e2db4695a6cf..ca6c03d5af18654c7c1413b2bf4deac8749f63cd 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