Commit e1056435 authored by Bodo Möller's avatar Bodo Möller
Browse files

New functions SSL[_CTX]_{set,get}_mode; the initial set of mode flags is

SSL_MODE_ENABLE_PARTIAL_WRITE, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER.
parent e0371fe4
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -4,6 +4,22 @@

 Changes between 0.9.3a and 0.9.4

  *) Introduce "mode" for SSL structures (with defaults in SSL_CTX),
     which largely parallels "options", but is for changing API behaviour,
     whereas "options" are about protocol behaviour.
     Initial "mode" flags (still experimental) are:

     SSL_MODE_ENABLE_PARTIAL_WRITE   Allow SSL_write to report success when
                                     a single record has been written.
     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER  Don't insist that SSL_write
                                     retries use the same buffer location.
                                     (But all of the contents must be
                                     copied!)
     [Bodo Moeller]

  *) Bugfix: SSL_set_mode ignored its parameter, only SSL_CTX_set_mode
     worked.

  *) Fix problems with no-hmac etc.
     [Ulf Möller, pointed out by Brian Wellington <bwelling@tislabs.com>]

+9 −3
Original line number Diff line number Diff line
@@ -391,7 +391,11 @@ int ssl2_write(SSL *s, const void *_buf, int len)
			s->s2->wnum=tot;
			return(i);
			}
		if (i == (int)n) return(tot+i);
		if ((i == (int)n) ||
			(s->mode | SSL_MODE_ENABLE_PARTIAL_WRITE))
			{
			return(tot+i);
			}
		
		n-=i;
		tot+=i;
@@ -406,7 +410,9 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)

	/* check that they have given us the same buffer to
	 * write */
	if ((s->s2->wpend_tot > (int)len) || (s->s2->wpend_buf != buf))
	if ((s->s2->wpend_tot > (int)len) ||
		((s->s2->wpend_buf != buf) &&
		 (!s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)))
		{
		SSLerr(SSL_F_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
		return(-1);
+9 −2
Original line number Diff line number Diff line
@@ -468,7 +468,12 @@ int ssl3_write_bytes(SSL *s, int type, const void *_buf, int len)
		if (type == SSL3_RT_HANDSHAKE)
			ssl3_finish_mac(s,&(buf[tot]),i);

		if (i == (int)n) return(tot+i);
		if ((i == (int)n) ||
			(type == SSL3_RT_APPLICATION_DATA &&
			(s->mode | SSL_MODE_ENABLE_PARTIAL_WRITE)))
			{
			return(tot+i);
			}

		n-=i;
		tot+=i;
@@ -596,7 +601,9 @@ static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
	int i;

/* XXXX */
	if ((s->s3->wpend_tot > (int)len) || (s->s3->wpend_buf != buf)
	if ((s->s3->wpend_tot > (int)len)
		|| ((s->s3->wpend_buf != buf) &&
			(!s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
		|| (s->s3->wpend_type != type))
		{
		SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
+29 −5
Original line number Diff line number Diff line
@@ -295,18 +295,39 @@ typedef struct ssl_session_st
#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x80000000L
#define SSL_OP_ALL					0x000FFFFFL

#define SSL_OP_NO_SSLv2					0x01000000L
#define SSL_OP_NO_SSLv3					0x02000000L
#define SSL_OP_NO_TLSv1					0x04000000L

/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
 * when just a single record has been written): */
#define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
/* Make it possible to retry SSL_write() with changed buffer location
 * (buffer contents must stay the same!); this is not the default to avoid
 * the misconception that non-blocking SSL_write() behaves like
 * non-blocking write(): */
#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L

/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
 * they cannot be used to clear bits. */

#define SSL_CTX_set_options(ctx,op) \
	SSL_CTX_ctrl(ctx,SSL_CTRL_OPTIONS,op,NULL)
#define SSL_CTX_get_options(ctx) \
	SSL_CTX_ctrl(ctx,SSL_CTRL_OPTIONS,0,NULL)
#define SSL_set_options(ssl,op) \
	SSL_ctrl(ssl,SSL_CTRL_OPTIONS,0,NULL)
	SSL_ctrl(ssl,SSL_CTRL_OPTIONS,op,NULL)
#define SSL_get_options(ssl) \
        SSL_ctrl(ssl,SSL_CTRL_OPTIONS,0,NULL)

#define SSL_OP_NO_SSLv2					0x01000000L
#define SSL_OP_NO_SSLv3					0x02000000L
#define SSL_OP_NO_TLSv1					0x04000000L
#define SSL_CTX_set_mode(ctx,op) \
	SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,op,NULL)
#define SSL_CTX_get_mode(ctx) \
	SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,0,NULL)
#define SSL_set_mode(ssl,op) \
	SSL_ctrl(ssl,SSL_CTRL_MODE,op,NULL)
#define SSL_get_mode(ssl) \
        SSL_ctrl(ssl,SSL_CTRL_MODE,0,NULL)

#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT	(1024*20)

@@ -327,6 +348,7 @@ struct ssl_ctx_st
	{
	SSL_METHOD *method;
	unsigned long options;
	unsigned long mode;

	STACK_OF(SSL_CIPHER) *cipher_list;
	/* same as above but sorted for lookup */
@@ -605,7 +627,8 @@ struct ssl_st
	STACK_OF(X509_NAME) *client_CA;

	int references;
	unsigned long options;
	unsigned long options; /* protocol behaviour */
	unsigned long mode; /* API behaviour */
	int first_packet;
	int client_version;	/* what was passed, used for
				 * SSLv3/TLS rolback check */
@@ -780,6 +803,7 @@ struct ssl_st
#define SSL_CTRL_SESS_TIMEOUTS			30
#define SSL_CTRL_SESS_CACHE_FULL		31
#define SSL_CTRL_OPTIONS			32
#define SSL_CTRL_MODE			33

#define SSL_CTRL_GET_READ_AHEAD			40
#define SSL_CTRL_SET_READ_AHEAD			41
+5 −0
Original line number Diff line number Diff line
@@ -215,6 +215,7 @@ SSL *SSL_new(SSL_CTX *ctx)
	s->references=1;
	s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
	s->options=ctx->options;
	s->mode=ctx->mode;
	SSL_clear(s);

	CRYPTO_new_ex_data(ssl_meth,(char *)s,&s->ex_data);
@@ -695,6 +696,8 @@ long SSL_ctrl(SSL *s,int cmd,long larg,char *parg)
		return(l);
	case SSL_CTRL_OPTIONS:
		return(s->options|=larg);
	case SSL_CTRL_MODE:
		return(s->mode|=larg);
	default:
		return(s->method->ssl_ctrl(s,cmd,larg,parg));
		}
@@ -752,6 +755,8 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
		return(ctx->stats.sess_cache_full);
	case SSL_CTRL_OPTIONS:
		return(ctx->options|=larg);
	case SSL_CTRL_MODE:
		return(ctx->mode|=larg);
	default:
		return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
		}