Newer
Older
/*
* Copyright 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
*/
#include <assert.h>
#include <openssl/ocsp.h>
#include "../ssl_locl.h"
#include "statem_locl.h"
int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx, int *al)
{
/* Add RI if renegotiating */
if (!s->renegotiate)
return 1;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_sub_memcpy_u8(pkt, s->s3->previous_client_finished,
s->s3->previous_client_finished_len)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx, int *al)
return 1;
/* Add TLS extension servername to the Client Hello message */
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
/* Sub-packet for server_name extension */
|| !WPACKET_start_sub_packet_u16(pkt)
/* Sub-packet for servername list (always 1 hostname)*/
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
|| !WPACKET_sub_memcpy_u16(pkt, s->ext.hostname,
strlen(s->ext.hostname))
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#ifndef OPENSSL_NO_SRP
int tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x,
size_t chainidx, int *al)
{
/* Add SRP username if there is one */
if (s->srp_ctx.login == NULL)
return 1;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
/* Sub-packet for SRP extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u8(pkt)
/* login must not be zero...internal error if so */
|| !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
|| !WPACKET_memcpy(pkt, s->srp_ctx.login,
strlen(s->srp_ctx.login))
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SRP, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
#ifndef OPENSSL_NO_EC
static int use_ecc(SSL *s)
{
unsigned long alg_k, alg_a;
STACK_OF(SSL_CIPHER) *cipher_stack = NULL;
/* See if we support any ECC ciphersuites */
if (s->version == SSL3_VERSION)
return 0;
cipher_stack = SSL_get_ciphers(s);
end = sk_SSL_CIPHER_num(cipher_stack);
for (i = 0; i < end; i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
alg_k = c->algorithm_mkey;
alg_a = c->algorithm_auth;
if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
|| (alg_a & SSL_aECDSA)
|| c->min_tls >= TLS1_3_VERSION)
break;
}
}
int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx, int *al)
{
if (s->early_data_state != SSL_EARLY_DATA_CONNECTING
|| s->session->ext.max_early_data == 0) {
s->max_early_data = 0;
return 1;
}
s->max_early_data = s->session->ext.max_early_data;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data)
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context,
X509 *x, size_t chainidx, int *al)
{
const unsigned char *pformats;
size_t num_formats;
if (!use_ecc(s))
return 1;
/* Add TLS extension ECPointFormats to the ClientHello message */
tls1_get_formatlist(s, &pformats, &num_formats);
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
/* Sub-packet for formats extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt,
unsigned int context, X509 *x,
{
const unsigned char *pcurves = NULL, *pcurvestmp;
size_t num_curves = 0, i;
if (!use_ecc(s))
return 1;
/*
* Add TLS extension supported_groups to the ClientHello message
*/
/* TODO(TLS1.3): Add support for DHE groups */
if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
ERR_R_INTERNAL_ERROR);
return 0;
}
pcurvestmp = pcurves;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups)
/* Sub-packet for supported_groups extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u16(pkt)) {
ERR_R_INTERNAL_ERROR);
return 0;
}
/* Copy curve ID if supported */
for (i = 0; i < num_curves; i++, pcurvestmp += 2) {
if (tls_curve_allowed(s, pcurvestmp, SSL_SECOP_CURVE_SUPPORTED)) {
if (!WPACKET_put_bytes_u8(pkt, pcurvestmp[0])
|| !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) {
ERR_R_INTERNAL_ERROR);
return 0;
}
}
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
ERR_R_INTERNAL_ERROR);
return 0;
}
Loading
Loading full blame…