mirror of https://github.com/openssl/openssl.git
				
				
				
			Create BIO_write_ex() which handles size_t arguments
Also extend BIO_METHOD to be able to supply an implementation for the new BIO_write_ex function. Reviewed-by: Richard Levitte <levitte@openssl.org>
This commit is contained in:
		
							parent
							
								
									d07aee2c7a
								
							
						
					
					
						commit
						3befffa39d
					
				|  | @ -78,6 +78,8 @@ static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, | |||
| static const BIO_METHOD methods_asn1 = { | ||||
|     BIO_TYPE_ASN1, | ||||
|     "asn1", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     asn1_bio_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -25,6 +25,8 @@ static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); | |||
| static const BIO_METHOD methods_buffer = { | ||||
|     BIO_TYPE_BUFFER, | ||||
|     "buffer", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     buffer_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -30,6 +30,8 @@ static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); | |||
| static const BIO_METHOD methods_linebuffer = { | ||||
|     BIO_TYPE_LINEBUFFER, | ||||
|     "linebuffer", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     linebuffer_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -34,6 +34,8 @@ typedef struct nbio_test_st { | |||
| static const BIO_METHOD methods_nbiof = { | ||||
|     BIO_TYPE_NBIO_TEST, | ||||
|     "non-blocking IO test filter", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     nbiof_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -27,6 +27,8 @@ static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); | |||
| static const BIO_METHOD methods_nullf = { | ||||
|     BIO_TYPE_NULL_FILTER, | ||||
|     "NULL filter", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     nullf_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ static ERR_STRING_DATA BIO_str_functs[] = { | |||
|     {ERR_FUNC(BIO_F_BIO_SOCK_INFO), "BIO_sock_info"}, | ||||
|     {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"}, | ||||
|     {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"}, | ||||
|     {ERR_FUNC(BIO_F_BIO_WRITE_EX), "BIO_write_ex"}, | ||||
|     {ERR_FUNC(BIO_F_BUFFER_CTRL), "buffer_ctrl"}, | ||||
|     {ERR_FUNC(BIO_F_CONN_CTRL), "conn_ctrl"}, | ||||
|     {ERR_FUNC(BIO_F_CONN_STATE), "conn_state"}, | ||||
|  |  | |||
|  | @ -284,35 +284,54 @@ int BIO_read_ex(BIO *b, void *out, size_t outl, size_t *read) | |||
| 
 | ||||
| int BIO_write(BIO *b, const void *in, int inl) | ||||
| { | ||||
|     int i; | ||||
|     long (*cb) (BIO *, int, const char *, int, long, long); | ||||
|     size_t written; | ||||
|     int ret; | ||||
| 
 | ||||
|     if (inl < 0) | ||||
|         return 0; | ||||
| 
 | ||||
|     ret = BIO_write_ex(b, in, (size_t)inl, &written); | ||||
| 
 | ||||
|     if (ret > 0) { | ||||
|         /* *written should always be <= inl */ | ||||
|         ret = (int)written; | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| int BIO_write_ex(BIO *b, const void *in, size_t inl, size_t *written) | ||||
| { | ||||
|     int ret; | ||||
| 
 | ||||
|     if (b == NULL) | ||||
|         return (0); | ||||
| 
 | ||||
|     cb = b->callback; | ||||
|     if ((b->method == NULL) || (b->method->bwrite == NULL)) { | ||||
|         BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD); | ||||
|         BIOerr(BIO_F_BIO_WRITE_EX, BIO_R_UNSUPPORTED_METHOD); | ||||
|         return (-2); | ||||
|     } | ||||
| 
 | ||||
|     if ((cb != NULL) && | ||||
|         ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0)) | ||||
|         return (i); | ||||
|     if ((b->callback != NULL || b->callback_ex != NULL) && | ||||
|         ((ret = bio_call_callback(b, BIO_CB_WRITE, in, inl, 0, 0L, 1L, written, | ||||
|                                   NULL)) <= 0)) | ||||
|         return ret; | ||||
| 
 | ||||
|     if (!b->init) { | ||||
|         BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED); | ||||
|         return (-2); | ||||
|         BIOerr(BIO_F_BIO_WRITE_EX, BIO_R_UNINITIALIZED); | ||||
|         return -2; | ||||
|     } | ||||
| 
 | ||||
|     i = b->method->bwrite(b, in, inl); | ||||
|     ret = b->method->bwrite(b, in, inl, written); | ||||
| 
 | ||||
|     if (i > 0) | ||||
|         b->num_write += (uint64_t)i; | ||||
|     if (ret > 0) | ||||
|         b->num_write += (uint64_t)*written; | ||||
| 
 | ||||
|     if (cb != NULL) | ||||
|         i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i); | ||||
|     return (i); | ||||
|     if (b->callback != NULL || b->callback_ex != NULL) | ||||
|         ret = bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0, | ||||
|                                 0L, ret, written, NULL); | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| int BIO_puts(BIO *b, const char *in) | ||||
|  |  | |||
|  | @ -50,13 +50,48 @@ void BIO_meth_free(BIO_METHOD *biom) | |||
| } | ||||
| 
 | ||||
| int (*BIO_meth_get_write(BIO_METHOD *biom)) (BIO *, const char *, int) | ||||
| { | ||||
|     return biom->bwrite_old; | ||||
| } | ||||
| 
 | ||||
| int (*BIO_meth_get_write_ex(BIO_METHOD *biom)) (BIO *, const char *, size_t, | ||||
|                                                 size_t *) | ||||
| { | ||||
|     return biom->bwrite; | ||||
| } | ||||
| 
 | ||||
| /* Conversion for old style bwrite to new style */ | ||||
| int bwrite_conv(BIO *bio, const char *in, size_t inl, size_t *written) | ||||
| { | ||||
|     int ret; | ||||
| 
 | ||||
|     if (inl > INT_MAX) | ||||
|         return 0; | ||||
| 
 | ||||
|     ret = bio->method->bwrite_old(bio, in, (int)inl); | ||||
| 
 | ||||
|     if (ret <= 0) { | ||||
|         *written = 0; | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     *written = (size_t)ret; | ||||
| 
 | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| int BIO_meth_set_write(BIO_METHOD *biom, | ||||
|                        int (*bwrite) (BIO *, const char *, int)) | ||||
| { | ||||
|     biom->bwrite_old = bwrite; | ||||
|     biom->bwrite = bwrite_conv; | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| int BIO_meth_set_write_ex(BIO_METHOD *biom, | ||||
|                        int (*bwrite) (BIO *, const char *, size_t, size_t *)) | ||||
| { | ||||
|     biom->bwrite_old = NULL; | ||||
|     biom->bwrite = bwrite; | ||||
|     return 1; | ||||
| } | ||||
|  | @ -102,6 +137,7 @@ int BIO_meth_set_read(BIO_METHOD *biom, | |||
| int BIO_meth_set_read_ex(BIO_METHOD *biom, | ||||
|                          int (*bread) (BIO *, char *, size_t, size_t *)) | ||||
| { | ||||
|     biom->bread_old = NULL; | ||||
|     biom->bread = bread; | ||||
|     return 1; | ||||
| } | ||||
|  |  | |||
|  | @ -54,6 +54,8 @@ static void BIO_ACCEPT_free(BIO_ACCEPT *a); | |||
| static const BIO_METHOD methods_acceptp = { | ||||
|     BIO_TYPE_ACCEPT, | ||||
|     "socket accept", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     acpt_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -39,6 +39,8 @@ static void bio_destroy_pair(BIO *bio); | |||
| static const BIO_METHOD methods_biop = { | ||||
|     BIO_TYPE_BIO, | ||||
|     "BIO pair", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     bio_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -58,6 +58,8 @@ void BIO_CONNECT_free(BIO_CONNECT *a); | |||
| static const BIO_METHOD methods_connectp = { | ||||
|     BIO_TYPE_CONNECT, | ||||
|     "socket connect", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     conn_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -73,6 +73,8 @@ static void get_current_time(struct timeval *t); | |||
| static const BIO_METHOD methods_dgramp = { | ||||
|     BIO_TYPE_DGRAM, | ||||
|     "datagram socket", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     dgram_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -59,6 +59,8 @@ int BIO_fd_should_retry(int s); | |||
| 
 | ||||
| static const BIO_METHOD methods_fdp = { | ||||
|     BIO_TYPE_FD, "file descriptor", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     fd_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -51,6 +51,8 @@ static int file_free(BIO *data); | |||
| static const BIO_METHOD methods_filep = { | ||||
|     BIO_TYPE_FILE, | ||||
|     "FILE pointer", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     file_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -86,6 +86,8 @@ static void xcloselog(BIO *bp); | |||
| 
 | ||||
| static const BIO_METHOD methods_slg = { | ||||
|     BIO_TYPE_MEM, "syslog", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     slg_write, | ||||
|     NULL, | ||||
|     NULL, | ||||
|  |  | |||
|  | @ -26,6 +26,8 @@ static int mem_buf_sync(BIO *h); | |||
| static const BIO_METHOD mem_method = { | ||||
|     BIO_TYPE_MEM, | ||||
|     "memory buffer", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     mem_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  | @ -41,6 +43,8 @@ static const BIO_METHOD mem_method = { | |||
| static const BIO_METHOD secmem_method = { | ||||
|     BIO_TYPE_MEM, | ||||
|     "secure memory buffer", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     mem_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -22,6 +22,8 @@ static int null_free(BIO *data); | |||
| static const BIO_METHOD null_method = { | ||||
|     BIO_TYPE_NULL, | ||||
|     "NULL", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     null_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -38,6 +38,8 @@ int BIO_sock_should_retry(int s); | |||
| static const BIO_METHOD methods_sockp = { | ||||
|     BIO_TYPE_SOCKET, | ||||
|     "socket", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     sock_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -48,6 +48,8 @@ typedef struct b64_struct { | |||
| 
 | ||||
| static const BIO_METHOD methods_b64 = { | ||||
|     BIO_TYPE_BASE64, "base64 encoding", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     b64_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -47,6 +47,8 @@ typedef struct enc_struct { | |||
| 
 | ||||
| static const BIO_METHOD methods_enc = { | ||||
|     BIO_TYPE_CIPHER, "cipher", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     enc_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -33,6 +33,8 @@ static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); | |||
| 
 | ||||
| static const BIO_METHOD methods_md = { | ||||
|     BIO_TYPE_MD, "message digest", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     md_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -109,6 +109,8 @@ typedef struct ok_struct { | |||
| 
 | ||||
| static const BIO_METHOD methods_ok = { | ||||
|     BIO_TYPE_CIPHER, "reliable", | ||||
|     /* TODO: Convert to new style write function */ | ||||
|     bwrite_conv, | ||||
|     ok_write, | ||||
|     /* TODO: Convert to new style read function */ | ||||
|     bread_conv, | ||||
|  |  | |||
|  | @ -12,7 +12,8 @@ | |||
| struct bio_method_st { | ||||
|     int type; | ||||
|     const char *name; | ||||
|     int (*bwrite) (BIO *, const char *, int); | ||||
|     int (*bwrite) (BIO *, const char *, size_t, size_t *); | ||||
|     int (*bwrite_old) (BIO *, const char *, int); | ||||
|     int (*bread) (BIO *, char *, size_t, size_t *); | ||||
|     int (*bread_old) (BIO *, char *, int); | ||||
|     int (*bputs) (BIO *, const char *); | ||||
|  | @ -28,4 +29,5 @@ void bio_cleanup(void); | |||
| 
 | ||||
| 
 | ||||
| /* Old style to new style BIO_METHOD conversion functions */ | ||||
| int bwrite_conv(BIO *bio, const char *in, size_t inl, size_t *written); | ||||
| int bread_conv(BIO *bio, char *out, size_t outl, size_t *read); | ||||
|  |  | |||
|  | @ -556,6 +556,7 @@ int BIO_read(BIO *b, void *data, int len); | |||
| int BIO_read_ex(BIO *b, void *out, size_t outl, size_t *read); | ||||
| int BIO_gets(BIO *bp, char *buf, int size); | ||||
| int BIO_write(BIO *b, const void *data, int len); | ||||
| int BIO_write_ex(BIO *b, const void *in, size_t inl, size_t *written); | ||||
| int BIO_puts(BIO *bp, const char *buf); | ||||
| int BIO_indent(BIO *b, int indent, int max); | ||||
| long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); | ||||
|  | @ -743,8 +744,12 @@ __bio_h__attr__((__format__(__printf__, 3, 0))); | |||
| BIO_METHOD *BIO_meth_new(int type, const char *name); | ||||
| void BIO_meth_free(BIO_METHOD *biom); | ||||
| int (*BIO_meth_get_write(BIO_METHOD *biom)) (BIO *, const char *, int); | ||||
| int (*BIO_meth_get_write_ex(BIO_METHOD *biom)) (BIO *, const char *, size_t, | ||||
|                                                 size_t *); | ||||
| int BIO_meth_set_write(BIO_METHOD *biom, | ||||
|                        int (*write) (BIO *, const char *, int)); | ||||
| int BIO_meth_set_write_ex(BIO_METHOD *biom, | ||||
|                        int (*bwrite) (BIO *, const char *, size_t, size_t *)); | ||||
| int (*BIO_meth_get_read(BIO_METHOD *biom)) (BIO *, char *, int); | ||||
| int (*BIO_meth_get_read_ex(BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *); | ||||
| int BIO_meth_set_read(BIO_METHOD *biom, | ||||
|  | @ -812,6 +817,7 @@ int ERR_load_BIO_strings(void); | |||
| # define BIO_F_BIO_SOCK_INFO                              141 | ||||
| # define BIO_F_BIO_SOCK_INIT                              112 | ||||
| # define BIO_F_BIO_WRITE                                  113 | ||||
| # define BIO_F_BIO_WRITE_EX                               119 | ||||
| # define BIO_F_BUFFER_CTRL                                114 | ||||
| # define BIO_F_CONN_CTRL                                  127 | ||||
| # define BIO_F_CONN_STATE                                 115 | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
| #include <openssl/err.h> | ||||
| #include "ssl_locl.h" | ||||
| 
 | ||||
| static int ssl_write(BIO *h, const char *buf, int num); | ||||
| static int ssl_write(BIO *h, const char *buf, size_t num, size_t *written); | ||||
| static int ssl_read(BIO *b, char *out, size_t outl, size_t *read); | ||||
| static int ssl_puts(BIO *h, const char *str); | ||||
| static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); | ||||
|  | @ -36,6 +36,7 @@ typedef struct bio_ssl_st { | |||
| static const BIO_METHOD methods_sslp = { | ||||
|     BIO_TYPE_SSL, "ssl", | ||||
|     ssl_write, | ||||
|     NULL, | ||||
|     ssl_read, | ||||
|     NULL, | ||||
|     ssl_puts, | ||||
|  | @ -106,13 +107,15 @@ static int ssl_read(BIO *b, char *out, size_t outl, size_t *read) | |||
|         return -1; | ||||
| 
 | ||||
|     ret = SSL_read(ssl, out, outl); | ||||
|     if (ret > 0) | ||||
|         *read = ret; | ||||
| 
 | ||||
|     switch (SSL_get_error(ssl, ret)) { | ||||
|     case SSL_ERROR_NONE: | ||||
|         if (ret <= 0) | ||||
|             break; | ||||
|         if (sb->renegotiate_count > 0) { | ||||
|             sb->byte_count += ret; | ||||
|             sb->byte_count += *read; | ||||
|             if (sb->byte_count > sb->renegotiate_count) { | ||||
|                 sb->byte_count = 0; | ||||
|                 sb->num_renegotiates++; | ||||
|  | @ -159,15 +162,10 @@ static int ssl_read(BIO *b, char *out, size_t outl, size_t *read) | |||
| 
 | ||||
|     BIO_set_retry_reason(b, retry_reason); | ||||
| 
 | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
| 
 | ||||
|     *read = (size_t)ret; | ||||
| 
 | ||||
|     return 1; | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static int ssl_write(BIO *b, const char *out, int outl) | ||||
| static int ssl_write(BIO *b, const char *out, size_t outl, size_t *written) | ||||
| { | ||||
|     int ret, r = 0; | ||||
|     int retry_reason = 0; | ||||
|  | @ -181,9 +179,9 @@ static int ssl_write(BIO *b, const char *out, int outl) | |||
| 
 | ||||
|     BIO_clear_retry_flags(b); | ||||
| 
 | ||||
|     /*
 | ||||
|      * ret=SSL_do_handshake(ssl); if (ret > 0) | ||||
|      */ | ||||
|     if (outl > INT_MAX) | ||||
|         return 0; | ||||
| 
 | ||||
|     ret = SSL_write(ssl, out, outl); | ||||
| 
 | ||||
|     switch (SSL_get_error(ssl, ret)) { | ||||
|  | @ -230,6 +228,12 @@ static int ssl_write(BIO *b, const char *out, int outl) | |||
|     } | ||||
| 
 | ||||
|     BIO_set_retry_reason(b, retry_reason); | ||||
| 
 | ||||
|     if (ret > 0) { | ||||
|         *written = ret; | ||||
|         ret = 1; | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4213,3 +4213,6 @@ BIO_set_callback_ex                     4163	1_1_1	EXIST::FUNCTION: | |||
| BIO_get_callback_ex                     4164	1_1_1	EXIST::FUNCTION: | ||||
| BIO_meth_set_read_ex                    4165	1_1_1	EXIST::FUNCTION: | ||||
| BIO_meth_get_read_ex                    4166	1_1_1	EXIST::FUNCTION: | ||||
| BIO_write_ex                            4167	1_1_1	EXIST::FUNCTION: | ||||
| BIO_meth_get_write_ex                   4168	1_1_1	EXIST::FUNCTION: | ||||
| BIO_meth_set_write_ex                   4169	1_1_1	EXIST::FUNCTION: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue