diff options
| author | Parménides GV <parmegv@sdf.org> | 2014-06-11 11:56:59 +0200 | 
|---|---|---|
| committer | Parménides GV <parmegv@sdf.org> | 2014-06-11 19:50:54 +0200 | 
| commit | 3e121542d8b7ab5201c47bbd3ba5611a23c54759 (patch) | |
| tree | a6035639e7baa88dd122d0d4e85791726606389a /app/openssl/ssl/d1_both.c | |
| parent | ac69881af1b7bfcdd185989f3e434556b1d62fed (diff) | |
Correctly connects to millipede.
Location keyword on android.cfg isn't supported, EIP corresponding code
has been commented out. I think we should support it in ics-openvpn, so
that we can show the location instead of the server name.
I've updated all opensssl, openvpn, etc. subprojects from rev 813 of
ics-openvpn, and jni too.
Diffstat (limited to 'app/openssl/ssl/d1_both.c')
| -rw-r--r-- | app/openssl/ssl/d1_both.c | 224 | 
1 files changed, 211 insertions, 13 deletions
diff --git a/app/openssl/ssl/d1_both.c b/app/openssl/ssl/d1_both.c index 2180c6d4..2e8cf681 100644 --- a/app/openssl/ssl/d1_both.c +++ b/app/openssl/ssl/d1_both.c @@ -158,7 +158,6 @@ static unsigned char bitmask_end_values[]   = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1  /* XDTLS:  figure out the right values */  static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; -static unsigned int dtls1_min_mtu(void);  static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);  static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,   	unsigned long frag_len); @@ -215,6 +214,12 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)  static void  dtls1_hm_fragment_free(hm_fragment *frag)  	{ + +	if (frag->msg_header.is_ccs) +		{ +		EVP_CIPHER_CTX_free(frag->msg_header.saved_retransmit_state.enc_write_ctx); +		EVP_MD_CTX_destroy(frag->msg_header.saved_retransmit_state.write_hash); +		}  	if (frag->fragment) OPENSSL_free(frag->fragment);  	if (frag->reassembly) OPENSSL_free(frag->reassembly);  	OPENSSL_free(frag); @@ -228,14 +233,14 @@ int dtls1_do_write(SSL *s, int type)  	unsigned int len, frag_off, mac_size, blocksize;  	/* AHA!  Figure out the MTU, and stick to the right size */ -	if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) +	if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))  		{  		s->d1->mtu =   			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);  		/* I've seen the kernel return bogus numbers when it doesn't know  		 * (initial write), so just make sure we have a reasonable number */ -		if ( s->d1->mtu < dtls1_min_mtu()) +		if (s->d1->mtu < dtls1_min_mtu())  			{  			s->d1->mtu = 0;  			s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); @@ -264,11 +269,10 @@ int dtls1_do_write(SSL *s, int type)  			return ret;  		mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);  		} - -	OPENSSL_assert(mtu > 0);  /* should have something reasonable now */ -  #endif +	OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());  /* should have something reasonable now */ +  	if ( s->init_off == 0  && type == SSL3_RT_HANDSHAKE)  		OPENSSL_assert(s->init_num ==   			(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); @@ -315,9 +319,10 @@ int dtls1_do_write(SSL *s, int type)  				s->init_off -= DTLS1_HM_HEADER_LENGTH;  				s->init_num += DTLS1_HM_HEADER_LENGTH; -				/* write atleast DTLS1_HM_HEADER_LENGTH bytes */ -				if ( len <= DTLS1_HM_HEADER_LENGTH)   -					len += DTLS1_HM_HEADER_LENGTH; +				if ( s->init_num > curr_mtu) +					len = curr_mtu; +				else +					len = s->init_num;  				}  			dtls1_fix_message_header(s, frag_off,  @@ -795,7 +800,13 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)  		*ok = 0;  		return i;  		} -	OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH); +	/* Handshake fails if message header is incomplete */ +	if (i != DTLS1_HM_HEADER_LENGTH) +		{ +		al=SSL_AD_UNEXPECTED_MESSAGE; +		SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); +		goto f_err; +		}  	/* parse the message fragment header */  	dtls1_get_message_header(wire, &msg_hdr); @@ -867,7 +878,12 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)  	/* XDTLS:  an incorrectly formatted fragment should cause the   	 * handshake to fail */ -	OPENSSL_assert(i == (int)frag_len); +	if (i != (int)frag_len) +		{ +		al=SSL3_AD_ILLEGAL_PARAMETER; +		SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL3_AD_ILLEGAL_PARAMETER); +		goto f_err; +		}  	*ok = 1; @@ -1075,7 +1091,11 @@ int dtls1_read_failed(SSL *s, int code)  		return code;  		} -	if ( ! SSL_in_init(s))  /* done, no need to send a retransmit */ +#ifndef OPENSSL_NO_HEARTBEATS +	if (!SSL_in_init(s) && !s->tlsext_hb_pending)  /* done, no need to send a retransmit */ +#else +	if (!SSL_in_init(s))  /* done, no need to send a retransmit */ +#endif  		{  		BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);  		return code; @@ -1367,7 +1387,7 @@ dtls1_write_message_header(SSL *s, unsigned char *p)  	return p;  	} -static unsigned int  +unsigned int   dtls1_min_mtu(void)  	{  	return (g_probable_mtu[(sizeof(g_probable_mtu) /  @@ -1408,3 +1428,181 @@ dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)  	ccs_hdr->type = *(data++);  	} + +int dtls1_shutdown(SSL *s) +	{ +	int ret; +#ifndef OPENSSL_NO_SCTP +	if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && +	    !(s->shutdown & SSL_SENT_SHUTDOWN)) +		{ +		ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); +		if (ret < 0) return -1; + +		if (ret == 0) +			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, NULL); +		} +#endif +	ret = ssl3_shutdown(s); +#ifndef OPENSSL_NO_SCTP +	BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL); +#endif +	return ret; +	} + +#ifndef OPENSSL_NO_HEARTBEATS +int +dtls1_process_heartbeat(SSL *s) +	{ +	unsigned char *p = &s->s3->rrec.data[0], *pl; +	unsigned short hbtype; +	unsigned int payload; +	unsigned int padding = 16; /* Use minimum padding */ + +	if (s->msg_callback) +		s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, +			&s->s3->rrec.data[0], s->s3->rrec.length, +			s, s->msg_callback_arg); + +	/* Read type and payload length first */ +	if (1 + 2 + 16 > s->s3->rrec.length) +		return 0; /* silently discard */ +	hbtype = *p++; +	n2s(p, payload); +	if (1 + 2 + payload + 16 > s->s3->rrec.length) +		return 0; /* silently discard per RFC 6520 sec. 4 */ +	pl = p; + +	if (hbtype == TLS1_HB_REQUEST) +		{ +		unsigned char *buffer, *bp; +		unsigned int write_length = 1 /* heartbeat type */ + +					    2 /* heartbeat length */ + +					    payload + padding; +		int r; + +		if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) +			return 0; + +		/* Allocate memory for the response, size is 1 byte +		 * message type, plus 2 bytes payload length, plus +		 * payload, plus padding +		 */ +		buffer = OPENSSL_malloc(write_length); +		bp = buffer; + +		/* Enter response type, length and copy payload */ +		*bp++ = TLS1_HB_RESPONSE; +		s2n(payload, bp); +		memcpy(bp, pl, payload); +		bp += payload; +		/* Random padding */ +		RAND_pseudo_bytes(bp, padding); + +		r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); + +		if (r >= 0 && s->msg_callback) +			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, +				buffer, write_length, +				s, s->msg_callback_arg); + +		OPENSSL_free(buffer); + +		if (r < 0) +			return r; +		} +	else if (hbtype == TLS1_HB_RESPONSE) +		{ +		unsigned int seq; + +		/* We only send sequence numbers (2 bytes unsigned int), +		 * and 16 random bytes, so we just try to read the +		 * sequence number */ +		n2s(pl, seq); + +		if (payload == 18 && seq == s->tlsext_hb_seq) +			{ +			dtls1_stop_timer(s); +			s->tlsext_hb_seq++; +			s->tlsext_hb_pending = 0; +			} +		} + +	return 0; +	} + +int +dtls1_heartbeat(SSL *s) +	{ +	unsigned char *buf, *p; +	int ret; +	unsigned int payload = 18; /* Sequence number + random bytes */ +	unsigned int padding = 16; /* Use minimum padding */ + +	/* Only send if peer supports and accepts HB requests... */ +	if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || +	    s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) +		{ +		SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); +		return -1; +		} + +	/* ...and there is none in flight yet... */ +	if (s->tlsext_hb_pending) +		{ +		SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_TLS_HEARTBEAT_PENDING); +		return -1; +		} + +	/* ...and no handshake in progress. */ +	if (SSL_in_init(s) || s->in_handshake) +		{ +		SSLerr(SSL_F_DTLS1_HEARTBEAT,SSL_R_UNEXPECTED_MESSAGE); +		return -1; +		} + +	/* Check if padding is too long, payload and padding +	 * must not exceed 2^14 - 3 = 16381 bytes in total. +	 */ +	OPENSSL_assert(payload + padding <= 16381); + +	/* Create HeartBeat message, we just use a sequence number +	 * as payload to distuingish different messages and add +	 * some random stuff. +	 *  - Message Type, 1 byte +	 *  - Payload Length, 2 bytes (unsigned int) +	 *  - Payload, the sequence number (2 bytes uint) +	 *  - Payload, random bytes (16 bytes uint) +	 *  - Padding +	 */ +	buf = OPENSSL_malloc(1 + 2 + payload + padding); +	p = buf; +	/* Message Type */ +	*p++ = TLS1_HB_REQUEST; +	/* Payload length (18 bytes here) */ +	s2n(payload, p); +	/* Sequence number */ +	s2n(s->tlsext_hb_seq, p); +	/* 16 random bytes */ +	RAND_pseudo_bytes(p, 16); +	p += 16; +	/* Random padding */ +	RAND_pseudo_bytes(p, padding); + +	ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); +	if (ret >= 0) +		{ +		if (s->msg_callback) +			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, +				buf, 3 + payload + padding, +				s, s->msg_callback_arg); + +		dtls1_start_timer(s); +		s->tlsext_hb_pending = 1; +		} + +	OPENSSL_free(buf); + +	return ret; +	} +#endif  | 
