예제 #1
0
int dtls1_send_hello_verify_request(SSL *s)
{
    unsigned int len;
    unsigned char *buf;

    if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) {
        buf = (unsigned char *)s->init_buf->data;

        if (s->ctx->app_gen_cookie_cb == NULL ||
            s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
                                      &(s->d1->cookie_len)) == 0 ||
            s->d1->cookie_len > 255) {
            SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,
                   SSL_R_COOKIE_GEN_CALLBACK_FAILURE);
            s->state = SSL_ST_ERR;
            return 0;
        }

        len = dtls1_raw_hello_verify_request(&buf[DTLS1_HM_HEADER_LENGTH],
                                             s->d1->cookie, s->d1->cookie_len);

        dtls1_set_message_header(s, buf, DTLS1_MT_HELLO_VERIFY_REQUEST, len, 0,
                                 len);
        len += DTLS1_HM_HEADER_LENGTH;

        s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
        /* number of bytes to write */
        s->init_num = len;
        s->init_off = 0;
    }

    /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
    return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
}
예제 #2
0
int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) {
  uint8_t *message = (uint8_t *)s->init_buf->data;
  const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
  uint8_t serialised_header[DTLS1_HM_HEADER_LENGTH];
  uint8_t *p = serialised_header;

  s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
  s->d1->next_handshake_write_seq++;

  dtls1_set_message_header(s, htype, len, s->d1->handshake_write_seq, 0, len);
  s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
  s->init_off = 0;

  /* Buffer the message to handle re-xmits */
  dtls1_buffer_message(s, 0);

  /* Add the new message to the handshake hash. Serialize the message
   * header as if it were a single fragment. */
  *p++ = msg_hdr->type;
  l2n3(msg_hdr->msg_len, p);
  s2n(msg_hdr->seq, p);
  l2n3(0, p);
  l2n3(msg_hdr->msg_len, p);
  return ssl3_finish_mac(s, serialised_header, sizeof(serialised_header)) &&
         ssl3_finish_mac(s, message + DTLS1_HM_HEADER_LENGTH, len);
}
int dtls1_send_hello_verify_request(SSL *s)
	{
	unsigned int msg_len;
	unsigned char *msg, *buf, *p;

	if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A)
		{
		buf = (unsigned char *)s->init_buf->data;

		msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
		/* Always use DTLS 1.0 version: see RFC 6347 */
		*(p++) = DTLS1_VERSION >> 8;
		*(p++) = DTLS1_VERSION & 0xFF;

		if (s->ctx->app_gen_cookie_cb == NULL ||
		     s->ctx->app_gen_cookie_cb(s, s->d1->cookie, &(s->d1->cookie_len)) == 0)
			{
			OPENSSL_PUT_ERROR(SSL, dtls1_send_hello_verify_request, ERR_R_INTERNAL_ERROR);
			return 0;
			}

		*(p++) = (unsigned char) s->d1->cookie_len;
		memcpy(p, s->d1->cookie, s->d1->cookie_len);
		p += s->d1->cookie_len;
		msg_len = p - msg;

		dtls1_set_message_header(s, buf,
			DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, msg_len);

		s->state=DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
		/* number of bytes to write */
		s->init_num=p-buf;
		s->init_off=0;
		}
예제 #4
0
파일: d1_both.c 프로젝트: aosm/OpenSSL098
int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
	{
	unsigned char *p,*d;
	int i;
	unsigned long l;

	if (s->state == a)
		{
		d=(unsigned char *)s->init_buf->data;
		p= &(d[DTLS1_HM_HEADER_LENGTH]);

		i=s->method->ssl3_enc->final_finish_mac(s,
			&(s->s3->finish_dgst1),
			&(s->s3->finish_dgst2),
			sender,slen,s->s3->tmp.finish_md);
		s->s3->tmp.finish_md_len = i;
		memcpy(p, s->s3->tmp.finish_md, i);
		p+=i;
		l=i;

	/* Copy the finished so we can use it for
	 * renegotiation checks
	 */
	if(s->type == SSL_ST_CONNECT)
		{
		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
		memcpy(s->s3->previous_client_finished, 
		       s->s3->tmp.finish_md, i);
		s->s3->previous_client_finished_len=i;
		}
	else
		{
		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
		memcpy(s->s3->previous_server_finished, 
		       s->s3->tmp.finish_md, i);
		s->s3->previous_server_finished_len=i;
		}

#ifdef OPENSSL_SYS_WIN16
		/* MSVC 1.5 does not clear the top bytes of the word unless
		 * I do this.
		 */
		l&=0xffff;
#endif

		d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
		s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH;
		s->init_off=0;

		/* buffer the message to handle re-xmits */
		dtls1_buffer_message(s, 0);

		s->state=b;
		}

	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
	}
예제 #5
0
파일: d1_both.c 프로젝트: aosm/OpenSSL098
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
	{
	unsigned char *p;
	int i;
	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
	BUF_MEM *buf;

	/* TLSv1 sends a chain with nothing in it, instead of an alert */
	buf=s->init_buf;
	if (!BUF_MEM_grow_clean(buf,10))
		{
		SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
		return(0);
		}
	if (x != NULL)
		{
		X509_STORE_CTX xs_ctx;
  
		if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
  			{
  			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
  			return(0);
  			}
  
		X509_verify_cert(&xs_ctx);
		/* Don't leave errors in the queue */
		ERR_clear_error();
		for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
  			{
			x = sk_X509_value(xs_ctx.chain, i);

			if (!dtls1_add_cert_to_buf(buf, &l, x))
  				{
				X509_STORE_CTX_cleanup(&xs_ctx);
				return 0;
  				}
  			}
  		X509_STORE_CTX_cleanup(&xs_ctx);
  		}
	/* Thawte special :-) */
	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
		{
		x=sk_X509_value(s->ctx->extra_certs,i);
		if (!dtls1_add_cert_to_buf(buf, &l, x))
			return 0;
		}

	l-= (3 + DTLS1_HM_HEADER_LENGTH);

	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
	l2n3(l,p);
	l+=3;
	p=(unsigned char *)&(buf->data[0]);
	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);

	l+=DTLS1_HM_HEADER_LENGTH;
	return(l);
	}
예제 #6
0
static void dtls1_set_handshake_header(SSL *s, int htype, unsigned long len)
	{
	unsigned char *p = (unsigned char *)s->init_buf->data;
	dtls1_set_message_header(s, p, htype, len, 0, len);
	s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
	s->init_off = 0;
	/* Buffer the message to handle re-xmits */
	dtls1_buffer_message(s, 0);
	}
예제 #7
0
int dtls1_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 = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0);

		s->state=SSL3_ST_SW_HELLO_REQ_B;
		/* number of bytes to write */
		s->init_num=DTLS1_HM_HEADER_LENGTH;
		s->init_off=0;

		/* no need to buffer this message, since there are no retransmit 
		 * requests for it */
		}

	/* SSL3_ST_SW_HELLO_REQ_B */
	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
	}
예제 #8
0
int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
	{
	unsigned char *p,*d;
	int i;
	unsigned long l;

	if (s->state == a)
		{
		d=(unsigned char *)s->init_buf->data;
		p= &(d[DTLS1_HM_HEADER_LENGTH]);

		i=s->method->ssl3_enc->final_finish_mac(s,
			&(s->s3->finish_dgst1),
			&(s->s3->finish_dgst2),
			sender,slen,s->s3->tmp.finish_md);
		s->s3->tmp.finish_md_len = i;
		memcpy(p, s->s3->tmp.finish_md, i);
		p+=i;
		l=i;

#ifdef OPENSSL_SYS_WIN16
		/* MSVC 1.5 does not clear the top bytes of the word unless
		 * I do this.
		 */
		l&=0xffff;
#endif

		d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
		s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH;
		s->init_off=0;

		/* buffer the message to handle re-xmits */
		dtls1_buffer_message(s, 0);

		s->state=b;
		}

	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
	}
예제 #9
0
int dtls1_send_hello_verify_request(SSL *s)
  {
  unsigned int msg_len;
  unsigned char *msg, *buf, *p;

  if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A)
    {
    buf = (unsigned char *)s->init_buf->data;

    msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
    *(p++) = s->version >> 8;
    *(p++) = s->version & 0xFF;

    *(p++) = (unsigned char) s->d1->cookie_len;
        if ( s->ctx->app_gen_cookie_cb != NULL &&
            s->ctx->app_gen_cookie_cb(s, s->d1->cookie, 
                &(s->d1->cookie_len)) == 0)
            {
      SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR);
            return 0;
            }
        /* else the cookie is assumed to have 
         * been initialized by the application */

    memcpy(p, s->d1->cookie, s->d1->cookie_len);
    p += s->d1->cookie_len;
    msg_len = p - msg;

    dtls1_set_message_header(s, buf,
      DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, msg_len);

    s->state=DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
    /* number of bytes to write */
    s->init_num=p-buf;
    s->init_off=0;

    /* buffer the message to handle re-xmits */
    dtls1_buffer_message(s, 0);
    }
예제 #10
0
파일: d1_clnt.c 프로젝트: SylvestreG/bitrig
int
dtls1_client_hello(SSL *s)
{
	unsigned char *buf;
	unsigned char *p, *d;
	unsigned int i;
	unsigned long l;

	buf = (unsigned char *)s->init_buf->data;
	if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
		SSL_SESSION *sess = s->session;
		if ((s->session == NULL) ||
		    (s->session->ssl_version != s->version) ||
		    (!sess->session_id_length && !sess->tlsext_tick) ||
		    (s->session->not_resumable)) {
			if (!ssl_get_new_session(s, 0))
				goto err;
		}
		/* else use the pre-loaded session */

		p = s->s3->client_random;

		/* if client_random is initialized, reuse it, we are
		 * required to use same upon reply to HelloVerify */
		for (i = 0; p[i]=='\0' && i < sizeof(s->s3->client_random); i++)
			;
		if (i == sizeof(s->s3->client_random))
			RAND_pseudo_bytes(p, sizeof(s->s3->client_random));

		/* Do the message type and length last */
		d = p = &(buf[DTLS1_HM_HEADER_LENGTH]);

		*(p++) = s->version >> 8;
		*(p++) = s->version&0xff;
		s->client_version = s->version;

		/* Random stuff */
		memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
		p += SSL3_RANDOM_SIZE;

		/* Session ID */
		if (s->new_session)
			i = 0;
		else
			i = s->session->session_id_length;
		*(p++) = i;
		if (i != 0) {
			if (i > sizeof s->session->session_id) {
				SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
				    ERR_R_INTERNAL_ERROR);
				goto err;
			}
			memcpy(p, s->session->session_id, i);
			p += i;
		}

		/* cookie stuff */
		if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
			goto err;
		}
		*(p++) = s->d1->cookie_len;
		memcpy(p, s->d1->cookie, s->d1->cookie_len);
		p += s->d1->cookie_len;

		/* Ciphers supported */
		i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0);
		if (i == 0) {
			SSLerr(SSL_F_DTLS1_CLIENT_HELLO,
			    SSL_R_NO_CIPHERS_AVAILABLE);
			goto err;
		}
		s2n(i, p);
		p += i;

		/* add in (no) COMPRESSION */
		*(p++) = 1;
		*(p++) = 0; /* Add the NULL method */

		if ((p = ssl_add_clienthello_tlsext(s, p,
		    buf + SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) {
			SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
			goto err;
		}

		l = (p - d);
		d = buf;

		d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO,
		    l, 0, l);

		s->state = SSL3_ST_CW_CLNT_HELLO_B;
		/* number of bytes to write */
		s->init_num = p - buf;
		s->init_off = 0;

		/* buffer the message to handle re-xmits */
		dtls1_buffer_message(s, 0);
	}
예제 #11
0
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
	{
	unsigned char *p;
	int n,i;
	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
	BUF_MEM *buf;
	X509_STORE_CTX xs_ctx;
	X509_OBJECT obj;

	/* TLSv1 sends a chain with nothing in it, instead of an alert */
	buf=s->init_buf;
	if (!BUF_MEM_grow_clean(buf,10))
		{
		SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
		return(0);
		}
	if (x != NULL)
		{
		if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
			{
			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
			return(0);
			}

		for (;;)
			{
			n=i2d_X509(x,NULL);
			if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
				{
				SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
				return(0);
				}
			p=(unsigned char *)&(buf->data[l]);
			l2n3(n,p);
			i2d_X509(x,&p);
			l+=n+3;
			if (X509_NAME_cmp(X509_get_subject_name(x),
				X509_get_issuer_name(x)) == 0) break;

			i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
				X509_get_issuer_name(x),&obj);
			if (i <= 0) break;
			x=obj.data.x509;
			/* Count is one too high since the X509_STORE_get uped the
			 * ref count */
			X509_free(x);
			}

		X509_STORE_CTX_cleanup(&xs_ctx);
		}

	/* Thawte special :-) */
	if (s->ctx->extra_certs != NULL)
	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
		{
		x=sk_X509_value(s->ctx->extra_certs,i);
		n=i2d_X509(x,NULL);
		if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
			{
			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
			return(0);
			}
		p=(unsigned char *)&(buf->data[l]);
		l2n3(n,p);
		i2d_X509(x,&p);
		l+=n+3;
		}

	l-= (3 + DTLS1_HM_HEADER_LENGTH);

	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
	l2n3(l,p);
	l+=3;
	p=(unsigned char *)&(buf->data[0]);
	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);

	l+=DTLS1_HM_HEADER_LENGTH;
	return(l);
	}