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

📄 s3_pkt.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 3 页
字号:
		return(0);		}	if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */		{		/* make sure that we are not getting application data when we		 * are doing a handshake for the first time */		if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&			(s->enc_read_ctx == NULL))			{			al=SSL_AD_UNEXPECTED_MESSAGE;			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);			goto f_err;			}		if (len <= 0) return(len);		if ((unsigned int)len > rr->length)			n = rr->length;		else			n = (unsigned int)len;		memcpy(buf,&(rr->data[rr->off]),n);		if (!peek)			{			rr->length-=n;			rr->off+=n;			if (rr->length == 0)				{				s->rstate=SSL_ST_READ_HEADER;				rr->off=0;				}			}		return(n);		}	/* If we get here, then type != rr->type; if we have a handshake	 * message, then it was unexpected (Hello Request or Client Hello). */	/* In case of record types for which we have 'fragment' storage,	 * fill that so that we can process the data at a fixed place.	 */		{		unsigned int dest_maxlen = 0;		unsigned char *dest = NULL;		unsigned int *dest_len = NULL;		if (rr->type == SSL3_RT_HANDSHAKE)			{			dest_maxlen = sizeof s->s3->handshake_fragment;			dest = s->s3->handshake_fragment;			dest_len = &s->s3->handshake_fragment_len;			}		else if (rr->type == SSL3_RT_ALERT)			{			dest_maxlen = sizeof s->s3->alert_fragment;			dest = s->s3->alert_fragment;			dest_len = &s->s3->alert_fragment_len;			}		if (dest_maxlen > 0)			{			n = dest_maxlen - *dest_len; /* available space in 'dest' */			if (rr->length < n)				n = rr->length; /* available bytes */			/* now move 'n' bytes: */			while (n-- > 0)				{				dest[(*dest_len)++] = rr->data[rr->off++];				rr->length--;				}			if (*dest_len < dest_maxlen)				goto start; /* fragment was too small */			}		}	/* s->s3->handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;	 * s->s3->alert_fragment_len == 2      iff  rr->type == SSL3_RT_ALERT.	 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */	/* If we are a client, check for an incoming 'Hello Request': */	if ((!s->server) &&		(s->s3->handshake_fragment_len >= 4) &&		(s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&		(s->session != NULL) && (s->session->cipher != NULL))		{		s->s3->handshake_fragment_len = 0;		if ((s->s3->handshake_fragment[1] != 0) ||			(s->s3->handshake_fragment[2] != 0) ||			(s->s3->handshake_fragment[3] != 0))			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);			goto f_err;			}		if (s->msg_callback)			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->s3->handshake_fragment, 4, s, s->msg_callback_arg);		if (SSL_is_init_finished(s) &&			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&			!s->s3->renegotiate)			{			ssl3_renegotiate(s);			if (ssl3_renegotiate_check(s))				{				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);					}				if (!(s->mode & SSL_MODE_AUTO_RETRY))					{					if (s->s3->rbuf.left == 0) /* no read-ahead left? */						{						BIO *bio;						/* In the case where we try to read application data,						 * but we trigger an SSL handshake, we return -1 with						 * the retry option set.  Otherwise renegotiation may						 * cause nasty problems in the blocking world */						s->rwstate=SSL_READING;						bio=SSL_get_rbio(s);						BIO_clear_retry_flags(bio);						BIO_set_retry_read(bio);						return(-1);						}					}				}			}		/* we either finished a handshake or ignored the request,		 * now try again to obtain the (application) data we were asked for */		goto start;		}	if (s->s3->alert_fragment_len >= 2)		{		int alert_level = s->s3->alert_fragment[0];		int alert_descr = s->s3->alert_fragment[1];		s->s3->alert_fragment_len = 0;		if (s->msg_callback)			s->msg_callback(0, s->version, SSL3_RT_ALERT, s->s3->alert_fragment, 2, s, s->msg_callback_arg);		if (s->info_callback != NULL)			cb=s->info_callback;		else if (s->ctx->info_callback != NULL)			cb=s->ctx->info_callback;		if (cb != NULL)			{			j = (alert_level << 8) | alert_descr;			cb(s, SSL_CB_READ_ALERT, j);			}		if (alert_level == 1) /* warning */			{			s->s3->warn_alert = alert_descr;			if (alert_descr == SSL_AD_CLOSE_NOTIFY)				{				s->shutdown |= SSL_RECEIVED_SHUTDOWN;				return(0);				}			}		else if (alert_level == 2) /* fatal */			{			char tmp[16];			s->rwstate=SSL_NOTHING;			s->s3->fatal_alert = alert_descr;			SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);			BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);			ERR_add_error_data(2,"SSL alert number ",tmp);			s->shutdown|=SSL_RECEIVED_SHUTDOWN;			SSL_CTX_remove_session(s->ctx,s->session);			return(0);			}		else			{			al=SSL_AD_ILLEGAL_PARAMETER;			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);			goto f_err;			}		goto start;		}	if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */		{		s->rwstate=SSL_NOTHING;		rr->length=0;		return(0);		}	if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)		{		/* 'Change Cipher Spec' is just a single byte, so we know		 * exactly what the record payload has to look like */		if (	(rr->length != 1) || (rr->off != 0) ||			(rr->data[0] != SSL3_MT_CCS))			{			al=SSL_AD_ILLEGAL_PARAMETER;			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);			goto f_err;			}		/* Check we have a cipher to change to */		if (s->s3->tmp.new_cipher == NULL)			{			al=SSL_AD_UNEXPECTED_MESSAGE;			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);			goto f_err;			}		rr->length=0;		if (s->msg_callback)			s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, s->msg_callback_arg);		s->s3->change_cipher_spec=1;		if (!ssl3_do_change_cipher_spec(s))			goto err;		else			goto start;		}	/* Unexpected handshake message (Client Hello, or protocol violation) */	if ((s->s3->handshake_fragment_len >= 4) &&	!s->in_handshake)		{		if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))			{#if 0 /* worked only because C operator preferences are not as expected (and       * because this is not really needed for clients except for detecting       * protocol violations): */			s->state=SSL_ST_BEFORE|(s->server)				?SSL_ST_ACCEPT				:SSL_ST_CONNECT;#else			s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;#endif			s->new_session=1;			}		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);			}		if (!(s->mode & SSL_MODE_AUTO_RETRY))			{			if (s->s3->rbuf.left == 0) /* no read-ahead left? */				{				BIO *bio;				/* In the case where we try to read application data,				 * but we trigger an SSL handshake, we return -1 with				 * the retry option set.  Otherwise renegotiation may				 * cause nasty problems in the blocking world */				s->rwstate=SSL_READING;				bio=SSL_get_rbio(s);				BIO_clear_retry_flags(bio);				BIO_set_retry_read(bio);				return(-1);				}			}		goto start;		}	switch (rr->type)		{	default:#ifndef OPENSSL_NO_TLS		/* TLS just ignores unknown message types */		if (s->version == TLS1_VERSION)			{			rr->length = 0;			goto start;			}#endif		al=SSL_AD_UNEXPECTED_MESSAGE;		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);		goto f_err;	case SSL3_RT_CHANGE_CIPHER_SPEC:	case SSL3_RT_ALERT:	case SSL3_RT_HANDSHAKE:		/* we already handled all of these, with the possible exception		 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that		 * should not happen when type != rr->type */		al=SSL_AD_UNEXPECTED_MESSAGE;		SSLerr(SSL_F_SSL3_READ_BYTES,ERR_R_INTERNAL_ERROR);		goto f_err;	case SSL3_RT_APPLICATION_DATA:		/* At this point, we were expecting handshake data,		 * but have application data.  If the library was		 * running inside ssl3_read() (i.e. in_read_app_data		 * is set) and it makes sense to read application data		 * at this point (session renegotiation not yet started),		 * we will indulge it.		 */		if (s->s3->in_read_app_data &&			(s->s3->total_renegotiations != 0) &&			((				(s->state & SSL_ST_CONNECT) &&				(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&				(s->state <= SSL3_ST_CR_SRVR_HELLO_A)				) || (					(s->state & SSL_ST_ACCEPT) &&					(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&					(s->state >= SSL3_ST_SR_CLNT_HELLO_A)					)				))			{			s->s3->in_read_app_data=2;			return(-1);			}		else			{			al=SSL_AD_UNEXPECTED_MESSAGE;			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);			goto f_err;			}		}	/* not reached */f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	return(-1);	}int ssl3_do_change_cipher_spec(SSL *s)	{	int i;	const char *sender;	int slen;	if (s->state & SSL_ST_ACCEPT)		i=SSL3_CHANGE_CIPHER_SERVER_READ;	else		i=SSL3_CHANGE_CIPHER_CLIENT_READ;	if (s->s3->tmp.key_block == NULL)		{		s->session->cipher=s->s3->tmp.new_cipher;		if (!s->method->ssl3_enc->setup_key_block(s)) return(0);		}	if (!s->method->ssl3_enc->change_cipher_state(s,i))		return(0);	/* we have to record the message digest at	 * this point so we can get it before we read	 * the finished message */	if (s->state & SSL_ST_CONNECT)		{		sender=s->method->ssl3_enc->server_finished_label;		slen=s->method->ssl3_enc->server_finished_label_len;		}	else		{		sender=s->method->ssl3_enc->client_finished_label;		slen=s->method->ssl3_enc->client_finished_label_len;		}	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,		&(s->s3->finish_dgst1),		&(s->s3->finish_dgst2),		sender,slen,s->s3->tmp.peer_finish_md);	return(1);	}void ssl3_send_alert(SSL *s, int level, int desc)	{	/* Map tls/ssl alert value to correct one */	desc=s->method->ssl3_enc->alert_value(desc);	if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)		desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */	if (desc < 0) return;	/* If a fatal one, remove from cache */	if ((level == 2) && (s->session != NULL))		SSL_CTX_remove_session(s->ctx,s->session);	s->s3->alert_dispatch=1;	s->s3->send_alert[0]=level;	s->s3->send_alert[1]=desc;	if (s->s3->wbuf.left == 0) /* data still being written out? */		s->method->ssl_dispatch_alert(s);	/* else data is still being written out, we will get written	 * some time in the future */	}int ssl3_dispatch_alert(SSL *s)	{	int i,j;	void (*cb)(const SSL *ssl,int type,int val)=NULL;	s->s3->alert_dispatch=0;	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0);	if (i <= 0)		{		s->s3->alert_dispatch=1;		}	else		{		/* Alert sent to BIO.  If it is important, flush it now.		 * If the message does not get sent due to non-blocking IO,		 * we will not worry too much. */		if (s->s3->send_alert[0] == SSL3_AL_FATAL)			(void)BIO_flush(s->wbio);		if (s->msg_callback)			s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s, s->msg_callback_arg);		if (s->info_callback != NULL)			cb=s->info_callback;		else if (s->ctx->info_callback != NULL)			cb=s->ctx->info_callback;		if (cb != NULL)			{			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];			cb(s,SSL_CB_WRITE_ALERT,j);			}		}	return(i);	}

⌨️ 快捷键说明

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