Skip to content
extensions.c 40.8 KiB
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 "../ssl_locl.h"
#include "statem_locl.h"

static int final_renegotiate(SSL *s, unsigned int context, int sent,
static int init_server_name(SSL *s, unsigned int context);
static int final_server_name(SSL *s, unsigned int context, int sent,
static int final_ec_pt_formats(SSL *s, unsigned int context, int sent,
static int init_session_ticket(SSL *s, unsigned int context);
#ifndef OPENSSL_NO_OCSP
static int init_status_request(SSL *s, unsigned int context);
#ifndef OPENSSL_NO_NEXTPROTONEG
static int init_npn(SSL *s, unsigned int context);
static int init_alpn(SSL *s, unsigned int context);
static int final_alpn(SSL *s, unsigned int context, int sent, int *al);
static int init_sig_algs(SSL *s, unsigned int context);
static int init_srp(SSL *s, unsigned int context);
static int init_etm(SSL *s, unsigned int context);
static int init_ems(SSL *s, unsigned int context);
static int final_ems(SSL *s, unsigned int context, int sent, int *al);
static int init_psk_kex_modes(SSL *s, unsigned int context);
Matt Caswell's avatar
Matt Caswell committed
#ifndef OPENSSL_NO_EC
static int final_key_share(SSL *s, unsigned int context, int sent, int *al);
Matt Caswell's avatar
Matt Caswell committed
#endif
static int init_srtp(SSL *s, unsigned int context);
static int final_sig_algs(SSL *s, unsigned int context, int sent, int *al);
/* Structure to define a built-in extension */
typedef struct extensions_definition_st {
    /* The defined type for the extension */
    unsigned int type;
    /*
     * The context that this extension applies to, e.g. what messages and
     * protocol versions
     */
    unsigned int context;
     * Initialise extension before parsing. Always called for relevant contexts
     * even if extension not present
    int (*init)(SSL *s, unsigned int context);
    /* Parse extension sent from client to server */
    int (*parse_ctos)(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                      size_t chainidx, int *al);
    /* Parse extension send from server to client */
    int (*parse_stoc)(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                      size_t chainidx, int *al);
    /* Construct extension sent from server to client */
    int (*construct_stoc)(SSL *s, WPACKET *pkt, unsigned int context, X509 *x,
                          size_t chainidx, int *al);
    /* Construct extension sent from client to server */
    int (*construct_ctos)(SSL *s, WPACKET *pkt, unsigned int context, X509 *x,
                          size_t chainidx, int *al);
     * Finalise extension after parsing. Always called where an extensions was
     * initialised even if the extension was not present. |sent| is set to 1 if
     * the extension was seen, or 0 otherwise.
    int (*final)(SSL *s, unsigned int context, int sent, int *al);
} EXTENSION_DEFINITION;

 * Definitions of all built-in extensions. NOTE: Changes in the number or order
FdaSilvaYY's avatar
FdaSilvaYY committed
 * of these extensions should be mirrored with equivalent changes to the 
 * indexes ( TLSEXT_IDX_* ) defined in ssl_locl.h.
 * Each extension has an initialiser, a client and
 * server side parser and a finaliser. The initialiser is called (if the
 * extension is relevant to the given context) even if we did not see the
 * extension in the message that we received. The parser functions are only
 * called if we see the extension in the message. The finalisers are always
 * called if the initialiser was called.
 * There are also server and client side constructor functions which are always
 * called during message construction if the extension is relevant for the
 * given context.
 * The initialisation, parsing, finalisation and construction functions are
 * always called in the order defined in this list. Some extensions may depend
 * on others having been processed first, so the order of this list is
 * significant.
 * The extension context is defined by a series of flags which specify which
 * messages the extension is relevant to. These flags also specify whether the
FdaSilvaYY's avatar
FdaSilvaYY committed
 * extension is relevant to a particular protocol or protocol version.
 * TODO(TLS1.3): Make sure we have a test to check the consistency of these
#define INVALID_EXTENSION { 0x10000, 0, NULL, NULL, NULL, NULL, NULL, NULL }
static const EXTENSION_DEFINITION ext_defs[] = {
    {
        TLSEXT_TYPE_renegotiate,
        EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_SSL3_ALLOWED
        | EXT_TLS1_2_AND_BELOW_ONLY,
        NULL, tls_parse_ctos_renegotiate, tls_parse_stoc_renegotiate,
        tls_construct_stoc_renegotiate, tls_construct_ctos_renegotiate,
        final_renegotiate
    },
    {
        TLSEXT_TYPE_server_name,
        EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
        | EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
        init_server_name,
        tls_parse_ctos_server_name, tls_parse_stoc_server_name,
        tls_construct_stoc_server_name, tls_construct_ctos_server_name,
        final_server_name
    },
#ifndef OPENSSL_NO_SRP
    {
        TLSEXT_TYPE_srp,
        EXT_CLIENT_HELLO | EXT_TLS1_2_AND_BELOW_ONLY,
        init_srp, tls_parse_ctos_srp, NULL, NULL, tls_construct_ctos_srp, NULL
#else
    INVALID_EXTENSION,
    {
        TLSEXT_TYPE_early_data_info,
        EXT_TLS1_3_NEW_SESSION_TICKET,
        NULL, NULL, tls_parse_stoc_early_data_info,
        tls_construct_stoc_early_data_info, NULL, NULL
#ifndef OPENSSL_NO_EC
    {
        TLSEXT_TYPE_ec_point_formats,
        EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY,
        NULL, tls_parse_ctos_ec_pt_formats, tls_parse_stoc_ec_pt_formats,
        tls_construct_stoc_ec_pt_formats, tls_construct_ctos_ec_pt_formats,
        final_ec_pt_formats
    },
    {
        TLSEXT_TYPE_supported_groups,
        EXT_CLIENT_HELLO | EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
        NULL, tls_parse_ctos_supported_groups, NULL,
        NULL /* TODO(TLS1.3): Need to add this */,
        tls_construct_ctos_supported_groups, NULL
#else
    INVALID_EXTENSION,
    INVALID_EXTENSION,
#endif
    {
        TLSEXT_TYPE_session_ticket,
        EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY,
        init_session_ticket, tls_parse_ctos_session_ticket,
        tls_parse_stoc_session_ticket, tls_construct_stoc_session_ticket,
        tls_construct_ctos_session_ticket, NULL
    },
    {
        TLSEXT_TYPE_signature_algorithms,
        EXT_CLIENT_HELLO,
        init_sig_algs, tls_parse_ctos_sig_algs, NULL, NULL,
        tls_construct_ctos_sig_algs, final_sig_algs
    {
        TLSEXT_TYPE_status_request,
        EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
        | EXT_TLS1_3_CERTIFICATE,
        init_status_request, tls_parse_ctos_status_request,
        tls_parse_stoc_status_request, tls_construct_stoc_status_request,
        tls_construct_ctos_status_request, NULL
#else
    INVALID_EXTENSION,
#ifndef OPENSSL_NO_NEXTPROTONEG
    {
        TLSEXT_TYPE_next_proto_neg,
        EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY,
        init_npn, tls_parse_ctos_npn, tls_parse_stoc_npn,
        tls_construct_stoc_next_proto_neg, tls_construct_ctos_npn, NULL
#else
    INVALID_EXTENSION,
        /*
         * Must appear in this list after server_name so that finalisation
         * happens after server_name callbacks
         */
        TLSEXT_TYPE_application_layer_protocol_negotiation,
        EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
        | EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
        init_alpn, tls_parse_ctos_alpn, tls_parse_stoc_alpn,
Loading
Loading full blame…