⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3_pkt.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 3 页
字号:
			{			al=SSL_AD_DECOMPRESSION_FAILURE;			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);			goto f_err;			}		}	if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra)		{		al=SSL_AD_RECORD_OVERFLOW;		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);		goto f_err;		}	rr->off=0;	/* So at this point the following is true	 * ssl->s3->rrec.type 	is the type of record	 * ssl->s3->rrec.length	== number of bytes in record	 * ssl->s3->rrec.off	== offset to first valid byte	 * ssl->s3->rrec.data	== where to take bytes from, increment	 *			   after use :-).	 */	/* we have pulled in a full packet so zero things */	s->packet_length=0;	/* just read a 0 length packet */	if (rr->length == 0) goto again;	return(1);f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	return(ret);	}int ssl3_do_uncompress(SSL *ssl)	{#ifndef OPENSSL_NO_COMP	int i;	SSL3_RECORD *rr;	rr= &(ssl->s3->rrec);	i=COMP_expand_block(ssl->expand,rr->comp,		SSL3_RT_MAX_PLAIN_LENGTH,rr->data,(int)rr->length);	if (i < 0)		return(0);	else		rr->length=i;	rr->data=rr->comp;#endif	return(1);	}int ssl3_do_compress(SSL *ssl)	{#ifndef OPENSSL_NO_COMP	int i;	SSL3_RECORD *wr;	wr= &(ssl->s3->wrec);	i=COMP_compress_block(ssl->compress,wr->data,		SSL3_RT_MAX_COMPRESSED_LENGTH,		wr->input,(int)wr->length);	if (i < 0)		return(0);	else		wr->length=i;	wr->input=wr->data;#endif	return(1);	}/* Call this to write data in records of type 'type' * It will return <= 0 if not all data has been sent or non-blocking IO. */int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)	{	const unsigned char *buf=buf_;	unsigned int tot,n,nw;	int i;	s->rwstate=SSL_NOTHING;	tot=s->s3->wnum;	s->s3->wnum=0;	if (SSL_in_init(s) && !s->in_handshake)		{		i=s->handshake_func(s);		if (i < 0) return(i);		if (i == 0)			{			SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);			return -1;			}		}	n=(len-tot);	for (;;)		{		if (n > SSL3_RT_MAX_PLAIN_LENGTH)			nw=SSL3_RT_MAX_PLAIN_LENGTH;		else			nw=n;		i=do_ssl3_write(s, type, &(buf[tot]), nw, 0);		if (i <= 0)			{			s->s3->wnum=tot;			return i;			}		if ((i == (int)n) ||			(type == SSL3_RT_APPLICATION_DATA &&			 (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))			{			/* next chunk of data should get another prepended empty fragment			 * in ciphersuites with known-IV weakness: */			s->s3->empty_fragment_done = 0;						return tot+i;			}		n-=i;		tot+=i;		}	}static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,			 unsigned int len, int create_empty_fragment)	{	unsigned char *p,*plen;	int i,mac_size,clear=0;	int prefix_len = 0;	SSL3_RECORD *wr;	SSL3_BUFFER *wb;	SSL_SESSION *sess;	/* first check if there is a SSL3_BUFFER still being written	 * out.  This will happen with non blocking IO */	if (s->s3->wbuf.left != 0)		return(ssl3_write_pending(s,type,buf,len));	/* If we have an alert to send, lets send it */	if (s->s3->alert_dispatch)		{		i=s->method->ssl_dispatch_alert(s);		if (i <= 0)			return(i);		/* if it went, fall through and send more stuff */		}	if (len == 0 && !create_empty_fragment)		return 0;	wr= &(s->s3->wrec);	wb= &(s->s3->wbuf);	sess=s->session;	if (	(sess == NULL) ||		(s->enc_write_ctx == NULL) ||		(s->write_hash == NULL))		clear=1;	if (clear)		mac_size=0;	else		mac_size=EVP_MD_size(s->write_hash);	/* 'create_empty_fragment' is true only when this function calls itself */	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)		{		/* countermeasure against known-IV weakness in CBC ciphersuites		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)			{			/* recursive function call with 'create_empty_fragment' set;			 * this prepares and buffers the data for an empty fragment			 * (these 'prefix_len' bytes are sent out later			 * together with the actual payload) */			prefix_len = do_ssl3_write(s, type, buf, 0, 1);			if (prefix_len <= 0)				goto err;			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)				{				/* insufficient space */				SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);				goto err;				}			}				s->s3->empty_fragment_done = 1;		}	p = wb->buf + prefix_len;	/* write the header */	*(p++)=type&0xff;	wr->type=type;	*(p++)=(s->version>>8);	*(p++)=s->version&0xff;	/* field where we are to write out packet length */	plen=p; 	p+=2;	/* lets setup the record stuff. */	wr->data=p;	wr->length=(int)len;	wr->input=(unsigned char *)buf;	/* we now 'read' from wr->input, wr->length bytes into	 * wr->data */	/* first we compress */	if (s->compress != NULL)		{		if (!ssl3_do_compress(s))			{			SSLerr(SSL_F_DO_SSL3_WRITE,SSL_R_COMPRESSION_FAILURE);			goto err;			}		}	else		{		memcpy(wr->data,wr->input,wr->length);		wr->input=wr->data;		}	/* we should still have the output to wr->data and the input	 * from wr->input.  Length should be wr->length.	 * wr->data still points in the wb->buf */	if (mac_size != 0)		{		s->method->ssl3_enc->mac(s,&(p[wr->length]),1);		wr->length+=mac_size;		wr->input=p;		wr->data=p;		}	/* ssl3_enc can only have an error on read */	s->method->ssl3_enc->enc(s,1);	/* record length after mac and block padding */	s2n(wr->length,plen);	/* we should now have	 * wr->data pointing to the encrypted data, which is	 * wr->length long */	wr->type=type; /* not needed but helps for debugging */	wr->length+=SSL3_RT_HEADER_LENGTH;	if (create_empty_fragment)		{		/* we are in a recursive call;		 * just return the length, don't write out anything here		 */		return wr->length;		}	/* now let's set up wb */	wb->left = prefix_len + wr->length;	wb->offset = 0;	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */	s->s3->wpend_tot=len;	s->s3->wpend_buf=buf;	s->s3->wpend_type=type;	s->s3->wpend_ret=len;	/* we now just need to write the buffer */	return ssl3_write_pending(s,type,buf,len);err:	return -1;	}/* if s->s3->wbuf.left != 0, we need to call this */int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,	unsigned int len)	{	int i;/* XXXX */	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);		return(-1);		}	for (;;)		{		clear_sys_error();		if (s->wbio != NULL)			{			s->rwstate=SSL_WRITING;			i=BIO_write(s->wbio,				(char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]),				(unsigned int)s->s3->wbuf.left);			}		else			{			SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET);			i= -1;			}		if (i == s->s3->wbuf.left)			{			s->s3->wbuf.left=0;			s->rwstate=SSL_NOTHING;			return(s->s3->wpend_ret);			}		else if (i <= 0)			return(i);		s->s3->wbuf.offset+=i;		s->s3->wbuf.left-=i;		}	}/* Return up to 'len' payload bytes received in 'type' records. * 'type' is one of the following: * *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) *   -  0 (during a shutdown, no data has to be returned) * * If we don't have stored data to work from, read a SSL/TLS record first * (possibly multiple records if we still don't have anything to return). * * This function must handle any surprises the peer may have for us, such as * Alert records (e.g. close_notify), ChangeCipherSpec records (not really * a surprise, but handled as if it were), or renegotiation requests. * Also if record payloads contain fragments too small to process, we store * them until there is enough for the respective protocol (the record protocol * may use arbitrary fragmentation and even interleaving): *     Change cipher spec protocol *             just 1 byte needed, no need for keeping anything stored *     Alert protocol *             2 bytes needed (AlertLevel, AlertDescription) *     Handshake protocol *             4 bytes needed (HandshakeType, uint24 length) -- we just have *             to detect unexpected Client Hello and Hello Request messages *             here, anything else is handled by higher layers *     Application data protocol *             none of our business */int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)	{	int al,i,j,ret;	unsigned int n;	SSL3_RECORD *rr;	void (*cb)(const SSL *ssl,int type2,int val)=NULL;	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */		if (!ssl3_setup_buffers(s))			return(-1);	if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) ||	    (peek && (type != SSL3_RT_APPLICATION_DATA)))		{		SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);		return -1;		}	if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0))		/* (partially) satisfy request from storage */		{		unsigned char *src = s->s3->handshake_fragment;		unsigned char *dst = buf;		unsigned int k;		/* peek == 0 */		n = 0;		while ((len > 0) && (s->s3->handshake_fragment_len > 0))			{			*dst++ = *src++;			len--; s->s3->handshake_fragment_len--;			n++;			}		/* move any remaining fragment bytes: */		for (k = 0; k < s->s3->handshake_fragment_len; k++)			s->s3->handshake_fragment[k] = *src++;		return n;	}	/* Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */	if (!s->in_handshake && SSL_in_init(s))		{		/* type == SSL3_RT_APPLICATION_DATA */		i=s->handshake_func(s);		if (i < 0) return(i);		if (i == 0)			{			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);			return(-1);			}		}start:	s->rwstate=SSL_NOTHING;	/* s->s3->rrec.type	    - is the type of record	 * s->s3->rrec.data,    - data	 * s->s3->rrec.off,     - offset into 'data' for next read	 * s->s3->rrec.length,  - number of bytes. */	rr = &(s->s3->rrec);	/* get new packet if necessary */	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))		{		ret=ssl3_get_record(s);		if (ret <= 0) return(ret);		}	/* we now have a packet which can be read and processed */	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,	                               * reset by ssl3_get_finished */		&& (rr->type != SSL3_RT_HANDSHAKE))		{		al=SSL_AD_UNEXPECTED_MESSAGE;		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);		goto f_err;		}	/* If the other end has shut down, throw anything we read away	 * (even in 'peek' mode) */	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)		{		rr->length=0;		s->rwstate=SSL_NOTHING;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -