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

📄 d1_pkt.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * 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;    dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */    return(1);decryption_failed_or_bad_record_mac:	/* Separate 'decryption_failed' alert was introduced with TLS 1.0,	 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption	 * failure is directly visible from the ciphertext anyway,	 * we should not reveal which kind of error occured -- this	 * might become visible to an attacker (e.g. via logfile) */	al=SSL_AD_BAD_RECORD_MAC;	SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	return(0);}/* Call this to get a new input record. * It will return <= 0 if more data is needed, normally due to an error * or non-blocking IO. * When it finishes, one packet has been decoded and can be found in * ssl->s3->rrec.type    - is the type of record * ssl->s3->rrec.data, 	 - data * ssl->s3->rrec.length, - number of bytes *//* used only by dtls1_read_bytes */int dtls1_get_record(SSL *s)	{	int ssl_major,ssl_minor,al;	int i,n;	SSL3_RECORD *rr;	SSL_SESSION *sess;	unsigned char *p;	short version;	DTLS1_BITMAP *bitmap;    unsigned int is_next_epoch;	rr= &(s->s3->rrec);	sess=s->session;    /* The epoch may have changed.  If so, process all the     * pending records.  This is a non-blocking operation. */    if ( ! dtls1_process_buffered_records(s))        return 0;	/* if we're renegotiating, then there may be buffered records */	if (dtls1_get_processed_record(s))		return 1;	/* get something from the wire */again:	/* check if we have the header */	if (	(s->rstate != SSL_ST_READ_BODY) ||		(s->packet_length < DTLS1_RT_HEADER_LENGTH)) 		{		n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);		/* read timeout is handled by dtls1_read_bytes */		if (n <= 0) return(n); /* error or non-blocking */		OPENSSL_assert(s->packet_length == DTLS1_RT_HEADER_LENGTH);		s->rstate=SSL_ST_READ_BODY;		p=s->packet;		/* Pull apart the header into the DTLS1_RECORD */		rr->type= *(p++);		ssl_major= *(p++);		ssl_minor= *(p++);		version=(ssl_major<<8)|ssl_minor;        /* sequence number is 64 bits, with top 2 bytes = epoch */ 		n2s(p,rr->epoch);		memcpy(&(s->s3->read_sequence[2]), p, 6);		p+=6;		n2s(p,rr->length);		/* Lets check version */		if (s->first_packet)			{			s->first_packet=0;			}		else			{			if (version != s->version)				{				SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);				/* Send back error using their				 * version number :-) */				s->version=version;				al=SSL_AD_PROTOCOL_VERSION;				goto f_err;				}			}		if ((version & 0xff00) != (DTLS1_VERSION & 0xff00))			{			SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);			goto err;			}		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)			{			al=SSL_AD_RECORD_OVERFLOW;			SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);			goto f_err;			}		/* now s->rstate == SSL_ST_READ_BODY */		}	/* s->rstate == SSL_ST_READ_BODY, get and decode the data */	if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH)		{		/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */		i=rr->length;		n=ssl3_read_n(s,i,i,1);		if (n <= 0) return(n); /* error or non-blocking io */		/* this packet contained a partial record, dump it */		if ( n != i)			{			s->packet_length = 0;			goto again;			}		/* now n == rr->length,		 * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */		}	s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */	/* match epochs.  NULL means the packet is dropped on the floor */	bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);	if ( bitmap == NULL)        {        s->packet_length = 0;  /* dump this record */        goto again;   /* get another record */		}	/* check whether this is a repeat, or aged record */	if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))		{		s->packet_length=0; /* dump this record */		goto again;     /* get another record */		}	/* just read a 0 length packet */	if (rr->length == 0) goto again;    /* If this record is from the next epoch (either HM or ALERT), buffer it     * since it cannot be processed at this time.     * Records from the next epoch are marked as received even though they are      * not processed, so as to prevent any potential resource DoS attack */    if (is_next_epoch)        {        dtls1_record_bitmap_update(s, bitmap);        dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);        s->packet_length = 0;        goto again;        }    if ( ! dtls1_process_record(s))        return(0);	dtls1_clear_timeouts(s);  /* done waiting */	return(1);f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	return(0);	}/* 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 dtls1_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);    /* XXX: check what the second '&& type' is about */	if ((type && (type != SSL3_RT_APPLICATION_DATA) && 		(type != SSL3_RT_HANDSHAKE) && type) ||	    (peek && (type != SSL3_RT_APPLICATION_DATA)))		{		SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);		return -1;		}	/* check whether there's a handshake message (client hello?) waiting */	if ( (ret = have_handshake_fragment(s, type, buf, len, peek)))		return ret;	/* Now s->d1->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_DTLS1_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=dtls1_get_record(s);		if (ret <= 0) 			{			ret = dtls1_read_failed(s, ret);			/* anything other than a timeout is an error */			if (ret <= 0)  				return(ret);			else				goto start;			}		}	/* 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_DTLS1_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);		goto 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;		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_DTLS1_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 k, dest_maxlen = 0;		unsigned char *dest = NULL;		unsigned int *dest_len = NULL;		if (rr->type == SSL3_RT_HANDSHAKE)			{			dest_maxlen = sizeof s->d1->handshake_fragment;			dest = s->d1->handshake_fragment;			dest_len = &s->d1->handshake_fragment_len;			}		else if (rr->type == SSL3_RT_ALERT)			{			dest_maxlen = sizeof(s->d1->alert_fragment);			dest = s->d1->alert_fragment;			dest_len = &s->d1->alert_fragment_len;			}		else	/* else it's a CCS message */			OPENSSL_assert(rr->type == SSL3_RT_CHANGE_CIPHER_SPEC);		if (dest_maxlen > 0)			{            /* XDTLS:  In a pathalogical case, the Client Hello             *  may be fragmented--don't always expect dest_maxlen bytes */			if ( rr->length < dest_maxlen)				{				s->rstate=SSL_ST_READ_HEADER;				rr->length = 0;				goto start;				}			/* now move 'n' bytes: */			for ( k = 0; k < dest_maxlen; k++)				{				dest[k] = rr->data[rr->off++];				rr->length--;				}			*dest_len = dest_maxlen;			}		}	/* s->d1->handshake_fragment_len == 12  iff  rr->type == SSL3_RT_HANDSHAKE;	 * s->d1->alert_fragment_len == 7      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->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&		(s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&		(s->session != NULL) && (s->session->cipher != NULL))		{		s->d1->handshake_fragment_len = 0;		if ((s->d1->handshake_fragment[1] != 0) ||			(s->d1->handshake_fragment[2] != 0) ||			(s->d1->handshake_fragment[3] != 0))			{			al=SSL_AD_DECODE_ERROR;			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);			goto err;			}		/* no need to check sequence number on HELLO REQUEST messages */		if (s->msg_callback)			s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 				s->d1->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_DTLS1_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->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH)		{

⌨️ 快捷键说明

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