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

📄 s3_srvr.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
				}			break;		case SSL3_ST_SW_FINISHED_A:		case SSL3_ST_SW_FINISHED_B:			ret=ssl3_send_finished(s,				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,				s->method->ssl3_enc->server_finished_label,				s->method->ssl3_enc->server_finished_label_len);			if (ret <= 0) goto end;			s->state=SSL3_ST_SW_FLUSH;			if (s->hit)				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;			else				s->s3->tmp.next_state=SSL_ST_OK;			s->init_num=0;			break;		case SSL_ST_OK:			/* clean a few things up */			ssl3_cleanup_key_block(s);			BUF_MEM_free(s->init_buf);			s->init_buf=NULL;			/* remove buffering on output */			ssl_free_wbio_buffer(s);			s->init_num=0;			if (s->new_session == 2) /* skipped if we just sent a HelloRequest */				{				/* actually not necessarily a 'new' session unless				 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */								s->new_session=0;								ssl_update_cache(s,SSL_SESS_CACHE_SERVER);								s->ctx->stats.sess_accept_good++;				/* s->server=1; */				s->handshake_func=ssl3_accept;				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);				}						ret = 1;			goto end;			/* break; */		default:			SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_UNKNOWN_STATE);			ret= -1;			goto end;			/* break; */			}				if (!s->s3->tmp.reuse_message && !skip)			{			if (s->debug)				{				if ((ret=BIO_flush(s->wbio)) <= 0)					goto end;				}			if ((cb != NULL) && (s->state != state))				{				new_state=s->state;				s->state=state;				cb(s,SSL_CB_ACCEPT_LOOP,1);				s->state=new_state;				}			}		skip=0;		}end:	/* BIO_flush(s->wbio); */	s->in_handshake--;	if (cb != NULL)		cb(s,SSL_CB_ACCEPT_EXIT,ret);	return(ret);	}int ssl3_send_hello_request(SSL *s)	{	unsigned char *p;	if (s->state == SSL3_ST_SW_HELLO_REQ_A)		{		p=(unsigned char *)s->init_buf->data;		*(p++)=SSL3_MT_HELLO_REQUEST;		*(p++)=0;		*(p++)=0;		*(p++)=0;		s->state=SSL3_ST_SW_HELLO_REQ_B;		/* number of bytes to write */		s->init_num=4;		s->init_off=0;		}	/* SSL3_ST_SW_HELLO_REQ_B */	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));	}int ssl3_check_client_hello(SSL *s)	{	int ok;	long n;	/* this function is called when we really expect a Certificate message,	 * so permit appropriate message length */	n=s->method->ssl_get_message(s,		SSL3_ST_SR_CERT_A,		SSL3_ST_SR_CERT_B,		-1,		s->max_cert_list,		&ok);	if (!ok) return((int)n);	s->s3->tmp.reuse_message = 1;	if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)		{		/* Throw away what we have done so far in the current handshake,		 * which will now be aborted. (A full SSL_clear would be too much.)		 * I hope that tmp.dh is the only thing that may need to be cleared		 * when a handshake is not completed ... */#ifndef OPENSSL_NO_DH		if (s->s3->tmp.dh != NULL)			{			DH_free(s->s3->tmp.dh);			s->s3->tmp.dh = NULL;			}#endif		return 2;		}	return 1;}int ssl3_get_client_hello(SSL *s)	{	int i,j,ok,al,ret= -1;	unsigned int cookie_len;	long n;	unsigned long id;	unsigned char *p,*d,*q;	SSL_CIPHER *c;#ifndef OPENSSL_NO_COMP	SSL_COMP *comp=NULL;#endif	STACK_OF(SSL_CIPHER) *ciphers=NULL;	/* We do this so that we will respond with our native type.	 * If we are TLSv1 and we get SSLv3, we will respond with TLSv1,	 * This down switching should be handled by a different method.	 * If we are SSLv3, we will respond with SSLv3, even if prompted with	 * TLSv1.	 */	if (s->state == SSL3_ST_SR_CLNT_HELLO_A)		{		s->first_packet=1;		s->state=SSL3_ST_SR_CLNT_HELLO_B;		}	n=s->method->ssl_get_message(s,		SSL3_ST_SR_CLNT_HELLO_B,		SSL3_ST_SR_CLNT_HELLO_C,		SSL3_MT_CLIENT_HELLO,		SSL3_RT_MAX_PLAIN_LENGTH,		&ok);	if (!ok) return((int)n);	d=p=(unsigned char *)s->init_msg;	/* use version from inside client hello, not from record header	 * (may differ: see RFC 2246, Appendix E, second paragraph) */	s->client_version=(((int)p[0])<<8)|(int)p[1];	p+=2;	if (s->client_version < s->version)		{		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);		if ((s->client_version>>8) == SSL3_VERSION_MAJOR) 			{			/* similar to ssl3_get_record, send alert using remote version number */			s->version = s->client_version;			}		al = SSL_AD_PROTOCOL_VERSION;		goto f_err;		}	/* load the client random */	memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE);	p+=SSL3_RANDOM_SIZE;	/* get the session-id */	j= *(p++);	s->hit=0;	/* Versions before 0.9.7 always allow session reuse during renegotiation	 * (i.e. when s->new_session is true), option	 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is new with 0.9.7.	 * Maybe this optional behaviour should always have been the default,	 * but we cannot safely change the default behaviour (or new applications	 * might be written that become totally unsecure when compiled with	 * an earlier library version)	 */	if (j == 0 || (s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))		{		if (!ssl_get_new_session(s,1))			goto err;		}	else		{		i=ssl_get_prev_session(s,p,j);		if (i == 1)			{ /* previous session */			s->hit=1;			}		else if (i == -1)			goto err;		else /* i == 0 */			{			if (!ssl_get_new_session(s,1))				goto err;			}		}	p+=j;	if (SSL_version(s) == DTLS1_VERSION)		{		/* cookie stuff */		cookie_len = *(p++);		if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&			s->d1->send_cookie == 0)			{			/* HelloVerifyMessage has already been sent */			if ( cookie_len != s->d1->cookie_len)				{				al = SSL_AD_HANDSHAKE_FAILURE;				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);				goto f_err;				}			}		/* 		 * The ClientHello may contain a cookie even if the		 * HelloVerify message has not been sent--make sure that it		 * does not cause an overflow.		 */		if ( cookie_len > sizeof(s->d1->rcvd_cookie))			{			/* too much data */			al = SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);			goto f_err;			}		/* verify the cookie if appropriate option is set. */		if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) &&			cookie_len > 0)			{			memcpy(s->d1->rcvd_cookie, p, cookie_len);			if ( s->ctx->app_verify_cookie_cb != NULL)				{				if ( s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,					cookie_len) == 0)					{					al=SSL_AD_HANDSHAKE_FAILURE;					SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 						SSL_R_COOKIE_MISMATCH);					goto f_err;					}				/* else cookie verification succeeded */				}			else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie, 						  s->d1->cookie_len) != 0) /* default verification */				{					al=SSL_AD_HANDSHAKE_FAILURE;					SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, 						SSL_R_COOKIE_MISMATCH);					goto f_err;				}			}		p += cookie_len;		}	n2s(p,i);	if ((i == 0) && (j != 0))		{		/* we need a cipher if we are not resuming a session */		al=SSL_AD_ILLEGAL_PARAMETER;		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED);		goto f_err;		}	if ((p+i) >= (d+n))		{		/* not enough data */		al=SSL_AD_DECODE_ERROR;		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);		goto f_err;		}	if ((i > 0) && (ssl_bytes_to_cipher_list(s,p,i,&(ciphers))		== NULL))		{		goto err;		}	p+=i;	/* If it is a hit, check that the cipher is in the list */	if ((s->hit) && (i > 0))		{		j=0;		id=s->session->cipher->id;#ifdef CIPHER_DEBUG		printf("client sent %d ciphers\n",sk_num(ciphers));#endif		for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)			{			c=sk_SSL_CIPHER_value(ciphers,i);#ifdef CIPHER_DEBUG			printf("client [%2d of %2d]:%s\n",				i,sk_num(ciphers),SSL_CIPHER_get_name(c));#endif			if (c->id == id)				{				j=1;				break;				}			}		if (j == 0)			{			if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))				{				/* Very bad for multi-threading.... */				s->session->cipher=sk_SSL_CIPHER_value(ciphers, 0);				}			else				{				/* we need to have the cipher in the cipher				 * list if we are asked to reuse it */				al=SSL_AD_ILLEGAL_PARAMETER;				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);				goto f_err;				}			}		}	/* compression */	i= *(p++);	if ((p+i) > (d+n))		{		/* not enough data */		al=SSL_AD_DECODE_ERROR;		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);		goto f_err;		}	q=p;	for (j=0; j<i; j++)		{		if (p[j] == 0) break;		}	p+=i;	if (j >= i)		{		/* no compress */		al=SSL_AD_DECODE_ERROR;		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_COMPRESSION_SPECIFIED);		goto f_err;		}	/* Worst case, we will use the NULL compression, but if we have other	 * options, we will now look for them.  We have i-1 compression	 * algorithms from the client, starting at q. */	s->s3->tmp.new_compression=NULL;#ifndef OPENSSL_NO_COMP	if (s->ctx->comp_methods != NULL)		{ /* See if we have a match */		int m,nn,o,v,done=0;		nn=sk_SSL_COMP_num(s->ctx->comp_methods);		for (m=0; m<nn; m++)			{			comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);			v=comp->id;			for (o=0; o<i; o++)				{				if (v == q[o])					{					done=1;					break;					}				}			if (done) break;			}		if (done)			s->s3->tmp.new_compression=comp;		else			comp=NULL;		}#endif	/* TLS does not mind if there is extra stuff */#if 0   /* SSL 3.0 does not mind either, so we should disable this test         * (was enabled in 0.9.6d through 0.9.6j and 0.9.7 through 0.9.7b,         * in earlier SSLeay/OpenSSL releases this test existed but was buggy) */	if (s->version == SSL3_VERSION)		{		if (p < (d+n))			{			/* wrong number of bytes,			 * there could be more to follow */			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);			goto f_err;			}		}#endif	/* Given s->session->ciphers and SSL_get_ciphers, we must	 * pick a cipher */	if (!s->hit)		{#ifdef OPENSSL_NO_COMP		s->session->compress_meth=0;#else		s->session->compress_meth=(comp == NULL)?0:comp->id;#endif		if (s->session->ciphers != NULL)			sk_SSL_CIPHER_free(s->session->ciphers);		s->session->ciphers=ciphers;		if (ciphers == NULL)			{			al=SSL_AD_ILLEGAL_PARAMETER;			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED);			goto f_err;			}		ciphers=NULL;		c=ssl3_choose_cipher(s,s->session->ciphers,				     SSL_get_ciphers(s));		if (c == NULL)			{			al=SSL_AD_HANDSHAKE_FAILURE;			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);			goto f_err;			}		s->s3->tmp.new_cipher=c;		}	else		{		/* Session-id reuse */#ifdef REUSE_CIPHER_BUG		STACK_OF(SSL_CIPHER) *sk;		SSL_CIPHER *nc=NULL;		SSL_CIPHER *ec=NULL;		if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)			{			sk=s->session->ciphers;			for (i=0; i<sk_SSL_CIPHER_num(sk); i++)				{				c=sk_SSL_CIPHER_value(sk,i);				if (c->algorithms & SSL_eNULL)					nc=c;				if (SSL_C_IS_EXPORT(c))					ec=c;				}			if (nc != NULL)				s->s3->tmp.new_cipher=nc;			else if (ec != NULL)				s->s3->tmp.new_cipher=ec;			else				s->s3->tmp.new_cipher=s->session->cipher;			}		else#endif		s->s3->tmp.new_cipher=s->session->cipher;		}		/* we now have the following setup. 	 * client_random	 * cipher_list 		- our prefered list of ciphers	 * ciphers 		- the clients prefered list of ciphers	 * compression		- basically ignored right now	 * ssl version is set	- sslv3	 * s->session		- The ssl session has been setup.	 * s->hit		- session reuse flag	 * s->tmp.new_cipher	- the new cipher to use.	 */	ret=1;	if (0)		{f_err:		ssl3_send_alert(s,SSL3_AL_FATAL,al);		}err:	if (ciphers != NULL) sk_SSL_CIPHER_free(ciphers);	return(ret);	}int ssl3_send_server_hello(SSL *s)	{	unsigned char *buf;	unsigned char *p,*d;	int i,sl;	unsigned long l,Time;	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)		{

⌨️ 快捷键说明

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