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

📄 d1_srvr.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ssl/d1_srvr.c *//*  * DTLS implementation written by Nagendra Modadugu * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.   *//* ==================================================================== * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    openssl-core@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" *    nor may "OpenSSL" appear in their names without prior written *    permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com).  This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * *//* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. *  * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to.  The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code.  The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). *  * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *    "This product includes cryptographic software written by *     Eric Young (eay@cryptsoft.com)" *    The word 'cryptographic' can be left out if the rouines from the library *    being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from  *    the apps directory (application code) you must include an acknowledgement: *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" *  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed.  i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */#include <stdio.h>#include "ssl_locl.h"#include <openssl/buffer.h>#include <openssl/rand.h>#include <openssl/objects.h>#include <openssl/evp.h>#include <openssl/x509.h>#include <openssl/md5.h>#ifndef OPENSSL_NO_DH#include <openssl/dh.h>#endifstatic SSL_METHOD *dtls1_get_server_method(int ver);static int dtls1_send_hello_verify_request(SSL *s);static SSL_METHOD *dtls1_get_server_method(int ver)	{	if (ver == DTLS1_VERSION)		return(DTLSv1_server_method());	else		return(NULL);	}IMPLEMENT_dtls1_meth_func(DTLSv1_server_method,			dtls1_accept,			ssl_undefined_function,			dtls1_get_server_method)int dtls1_accept(SSL *s)	{	BUF_MEM *buf;	unsigned long l,Time=(unsigned long)time(NULL);	void (*cb)(const SSL *ssl,int type,int val)=NULL;	long num1;	int ret= -1;	int new_state,state,skip=0;	RAND_add(&Time,sizeof(Time),0);	ERR_clear_error();	clear_sys_error();	if (s->info_callback != NULL)		cb=s->info_callback;	else if (s->ctx->info_callback != NULL)		cb=s->ctx->info_callback;	/* init things to blank */	s->in_handshake++;	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);	if (s->cert == NULL)		{		SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);		return(-1);		}	for (;;)		{		state=s->state;		switch (s->state)			{		case SSL_ST_RENEGOTIATE:			s->new_session=1;			/* s->state=SSL_ST_ACCEPT; */		case SSL_ST_BEFORE:		case SSL_ST_ACCEPT:		case SSL_ST_BEFORE|SSL_ST_ACCEPT:		case SSL_ST_OK|SSL_ST_ACCEPT:			s->server=1;			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);			if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00))				{				SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);				return -1;				}			s->type=SSL_ST_ACCEPT;			if (s->init_buf == NULL)				{				if ((buf=BUF_MEM_new()) == NULL)					{					ret= -1;					goto end;					}				if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))					{					ret= -1;					goto end;					}				s->init_buf=buf;				}			if (!ssl3_setup_buffers(s))				{				ret= -1;				goto end;				}			s->init_num=0;			if (s->state != SSL_ST_RENEGOTIATE)				{				/* Ok, we now need to push on a buffering BIO so that				 * the output is sent in a way that TCP likes :-)				 */				if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }				ssl3_init_finished_mac(s);				s->state=SSL3_ST_SR_CLNT_HELLO_A;				s->ctx->stats.sess_accept++;				}			else				{				/* s->state == SSL_ST_RENEGOTIATE,				 * we will just send a HelloRequest */				s->ctx->stats.sess_accept_renegotiate++;				s->state=SSL3_ST_SW_HELLO_REQ_A;				}            if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))                s->d1->send_cookie = 1;            else                s->d1->send_cookie = 0;			break;		case SSL3_ST_SW_HELLO_REQ_A:		case SSL3_ST_SW_HELLO_REQ_B:			s->shutdown=0;			ret=dtls1_send_hello_request(s);			if (ret <= 0) goto end;			s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;			s->state=SSL3_ST_SW_FLUSH;			s->init_num=0;			ssl3_init_finished_mac(s);			break;		case SSL3_ST_SW_HELLO_REQ_C:			s->state=SSL_ST_OK;			break;		case SSL3_ST_SR_CLNT_HELLO_A:		case SSL3_ST_SR_CLNT_HELLO_B:		case SSL3_ST_SR_CLNT_HELLO_C:			s->shutdown=0;			ret=ssl3_get_client_hello(s);			if (ret <= 0) goto end;			s->new_session = 2;			if ( s->d1->send_cookie)				s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;			else				s->state = SSL3_ST_SW_SRVR_HELLO_A;			s->init_num=0;			break;					case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:		case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:			ret = dtls1_send_hello_verify_request(s);			if ( ret <= 0) goto end;			s->d1->send_cookie = 0;			s->state=SSL3_ST_SW_FLUSH;			s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;			break;					case SSL3_ST_SW_SRVR_HELLO_A:		case SSL3_ST_SW_SRVR_HELLO_B:			ret=dtls1_send_server_hello(s);			if (ret <= 0) goto end;			if (s->hit)				s->state=SSL3_ST_SW_CHANGE_A;			else				s->state=SSL3_ST_SW_CERT_A;			s->init_num=0;			break;		case SSL3_ST_SW_CERT_A:		case SSL3_ST_SW_CERT_B:			/* Check if it is anon DH */			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))				{				ret=dtls1_send_server_certificate(s);				if (ret <= 0) goto end;				}			else				skip=1;			s->state=SSL3_ST_SW_KEY_EXCH_A;			s->init_num=0;			break;		case SSL3_ST_SW_KEY_EXCH_A:		case SSL3_ST_SW_KEY_EXCH_B:			l=s->s3->tmp.new_cipher->algorithms;			/* clear this, it may get reset by			 * send_server_key_exchange */			if ((s->options & SSL_OP_EPHEMERAL_RSA)#ifndef OPENSSL_NO_KRB5				&& !(l & SSL_KRB5)#endif /* OPENSSL_NO_KRB5 */				)				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key				 * even when forbidden by protocol specs				 * (handshake may fail as clients are not required to				 * be able to handle this) */				s->s3->tmp.use_rsa_tmp=1;			else				s->s3->tmp.use_rsa_tmp=0;			/* only send if a DH key exchange, fortezza or			 * RSA but we have a sign only certificate */			if (s->s3->tmp.use_rsa_tmp			    || (l & (SSL_DH|SSL_kFZA))			    || ((l & SSL_kRSA)				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)					)				    )				)			    )				{				ret=dtls1_send_server_key_exchange(s);				if (ret <= 0) goto end;				}			else				skip=1;			s->state=SSL3_ST_SW_CERT_REQ_A;			s->init_num=0;			break;		case SSL3_ST_SW_CERT_REQ_A:		case SSL3_ST_SW_CERT_REQ_B:			if (/* don't request cert unless asked for it: */				!(s->verify_mode & SSL_VERIFY_PEER) ||				/* if SSL_VERIFY_CLIENT_ONCE is set,				 * don't request cert during re-negotiation: */				((s->session->peer != NULL) &&				 (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||				/* never request cert in anonymous ciphersuites				 * (see section "Certificate request" in SSL 3 drafts				 * and in RFC 2246): */				((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&				 /* ... except when the application insists on verification				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||                                 /* never request cert in Kerberos ciphersuites */                                (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))				{				/* no cert request */				skip=1;				s->s3->tmp.cert_request=0;				s->state=SSL3_ST_SW_SRVR_DONE_A;				}			else				{				s->s3->tmp.cert_request=1;				ret=dtls1_send_certificate_request(s);				if (ret <= 0) goto end;#ifndef NETSCAPE_HANG_BUG				s->state=SSL3_ST_SW_SRVR_DONE_A;#else				s->state=SSL3_ST_SW_FLUSH;				s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;#endif				s->init_num=0;				}			break;		case SSL3_ST_SW_SRVR_DONE_A:		case SSL3_ST_SW_SRVR_DONE_B:			ret=dtls1_send_server_done(s);			if (ret <= 0) goto end;			s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;			s->state=SSL3_ST_SW_FLUSH;			s->init_num=0;			break;				case SSL3_ST_SW_FLUSH:			/* number of bytes to be flushed */			num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);			if (num1 > 0)				{				s->rwstate=SSL_WRITING;				num1=BIO_flush(s->wbio);				if (num1 <= 0) { ret= -1; goto end; }				s->rwstate=SSL_NOTHING;				}			s->state=s->s3->tmp.next_state;			break;		case SSL3_ST_SR_CERT_A:		case SSL3_ST_SR_CERT_B:			/* Check for second client hello (MS SGC) */			ret = ssl3_check_client_hello(s);			if (ret <= 0)				goto end;			if (ret == 2)				s->state = SSL3_ST_SR_CLNT_HELLO_C;			else {				/* could be sent for a DH cert, even if we				 * have not asked for it :-) */				ret=ssl3_get_client_certificate(s);				if (ret <= 0) goto end;				s->init_num=0;				s->state=SSL3_ST_SR_KEY_EXCH_A;			}			break;		case SSL3_ST_SR_KEY_EXCH_A:		case SSL3_ST_SR_KEY_EXCH_B:			ret=ssl3_get_client_key_exchange(s);			if (ret <= 0) goto end;			s->state=SSL3_ST_SR_CERT_VRFY_A;			s->init_num=0;			/* We need to get hashes here so if there is			 * a client cert, it can be verified */ 			s->method->ssl3_enc->cert_verify_mac(s,				&(s->s3->finish_dgst1),				&(s->s3->tmp.cert_verify_md[0]));			s->method->ssl3_enc->cert_verify_mac(s,				&(s->s3->finish_dgst2),				&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));			break;		case SSL3_ST_SR_CERT_VRFY_A:		case SSL3_ST_SR_CERT_VRFY_B:			/* we should decide if we expected this one */			ret=ssl3_get_cert_verify(s);			if (ret <= 0) goto end;			s->state=SSL3_ST_SR_FINISHED_A;			s->init_num=0;			break;		case SSL3_ST_SR_FINISHED_A:		case SSL3_ST_SR_FINISHED_B:			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,				SSL3_ST_SR_FINISHED_B);			if (ret <= 0) goto end;			if (s->hit)				s->state=SSL_ST_OK;			else				s->state=SSL3_ST_SW_CHANGE_A;			s->init_num=0;			break;		case SSL3_ST_SW_CHANGE_A:		case SSL3_ST_SW_CHANGE_B:			s->session->cipher=s->s3->tmp.new_cipher;			if (!s->method->ssl3_enc->setup_key_block(s))				{ ret= -1; goto end; }			ret=dtls1_send_change_cipher_spec(s,				SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);			if (ret <= 0) goto end;			s->state=SSL3_ST_SW_FINISHED_A;			s->init_num=0;			if (!s->method->ssl3_enc->change_cipher_state(s,				SSL3_CHANGE_CIPHER_SERVER_WRITE))				{				ret= -1;				goto end;				}			dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);			break;		case SSL3_ST_SW_FINISHED_A:		case SSL3_ST_SW_FINISHED_B:			ret=dtls1_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);#if 0			BUF_MEM_free(s->init_buf);			s->init_buf=NULL;#endif			/* 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=dtls1_accept;				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);				}						ret = 1;			/* done handshaking, next message is client hello */			s->d1->handshake_read_seq = 0;			/* next message is server hello */			s->d1->handshake_write_seq = 0;			goto end;			/* break; */		default:			SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE);			ret= -1;			goto end;			/* break; */			}				if (!s->s3->tmp.reuse_message && !skip)			{			if (s->debug)				{

⌨️ 快捷键说明

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