/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include "../ssl_locl.h"
#include "statem_locl.h"
#include <openssl/buffer.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
/*
* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
* SSL3_RT_CHANGE_CIPHER_SPEC)
*/
int ssl3_do_write(SSL *s, int type)
{
int ret;
ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off],
s->init_num);
if (ret < 0)
return (-1);
if (type == SSL3_RT_HANDSHAKE)
/*
* should not be done for 'Hello Request's, but in that case we'll
* ignore the result anyway
*/
if (!ssl3_finish_mac(s,
(unsigned char *)&s->init_buf->data[s->init_off],
ret))
return -1;
if (ret == s->init_num) {
if (s->msg_callback)
s->msg_callback(1, s->version, type, s->init_buf->data,
(size_t)(s->init_off + s->init_num), s,
s->msg_callback_arg);
return (1);
}
s->init_off += ret;
s->init_num -= ret;
return (0);
}
int tls_close_construct_packet(SSL *s, WPACKET *pkt)
{
size_t msglen;
if (!WPACKET_get_length(pkt, &msglen)
|| msglen > INT_MAX
|| !WPACKET_finish(pkt))
return 0;
s->init_num = (int)msglen;
s->init_off = 0;
return 1;
}
int tls_construct_finished(SSL *s, const char *sender, int slen)
{
unsigned char *p;
int i;
unsigned long l;
p = ssl_handshake_start(s);
i = s->method->ssl3_enc->final_finish_mac(s,
sender, slen,
s->s3->tmp.finish_md);
if (i <= 0)
return 0;
s->s3->tmp.finish_md_len = i;
memcpy(p, s->s3->tmp.finish_md, i);
l = i;
/*
* Copy the finished so we can use it for renegotiation checks
*/
if (!s->server) {
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;
}
if (