Exemple #1
0
int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context,
                                    X509 *x, size_t chainidx)
{
    PACKET supported_groups_list;

    /* Each group is 2 bytes and we must have at least 1. */
    if (!PACKET_as_length_prefixed_2(pkt, &supported_groups_list)
            || PACKET_remaining(&supported_groups_list) == 0
            || (PACKET_remaining(&supported_groups_list) % 2) != 0) {
        SSLfatal(s, SSL_AD_DECODE_ERROR,
                 SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS, SSL_R_BAD_EXTENSION);
        return 0;
    }

    if (!s->hit || SSL_IS_TLS13(s)) {
        OPENSSL_free(s->session->ext.supportedgroups);
        s->session->ext.supportedgroups = NULL;
        s->session->ext.supportedgroups_len = 0;
        if (!tls1_save_u16(&supported_groups_list,
                           &s->session->ext.supportedgroups,
                           &s->session->ext.supportedgroups_len)) {
            SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                     SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS,
                     ERR_R_INTERNAL_ERROR);
            return 0;
        }
    }

    return 1;
}
Exemple #2
0
int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                       size_t chainidx, int *al)
{
    /*
     * Only take it if we asked for it - i.e if there is no CT validation
     * callback set, then a custom extension MAY be processing it, so we
     * need to let control continue to flow to that.
     */
    if (s->ct_validation_callback != NULL) {
        size_t size = PACKET_remaining(pkt);

        /* Simply copy it off for later processing */
        OPENSSL_free(s->ext.scts);
        s->ext.scts = NULL;

        s->ext.scts_len = size;
        if (size > 0) {
            s->ext.scts = OPENSSL_malloc(size);
            if (s->ext.scts == NULL
                    || !PACKET_copy_bytes(pkt, s->ext.scts, size)) {
                *al = SSL_AD_INTERNAL_ERROR;
                return 0;
            }
        }
    } else {
        if (custom_ext_parse(s, 0, TLSEXT_TYPE_signed_certificate_timestamp,
                             PACKET_data(pkt), PACKET_remaining(pkt), al) <= 0)
            return 0;
    }

    return 1;
}
Exemple #3
0
int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context,
                                    X509 *x, size_t chainidx, int *al)
{
    PACKET supported_groups_list;

    /* Each group is 2 bytes and we must have at least 1. */
    if (!PACKET_as_length_prefixed_2(pkt, &supported_groups_list)
            || PACKET_remaining(&supported_groups_list) == 0
            || (PACKET_remaining(&supported_groups_list) % 2) != 0) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    if (!s->hit || SSL_IS_TLS13(s)) {
        OPENSSL_free(s->session->ext.supportedgroups);
        s->session->ext.supportedgroups = NULL;
        s->session->ext.supportedgroups_len = 0;
        if (!PACKET_memdup(&supported_groups_list,
                           &s->session->ext.supportedgroups,
                           &s->session->ext.supportedgroups_len)) {
            *al = SSL_AD_INTERNAL_ERROR;
            return 0;
        }
    }

    return 1;
}
Exemple #4
0
static int test_PACKET_get_length_prefixed_1()
{
    unsigned char buf[BUF_LEN];
    const size_t len = 16;
    unsigned int i;
    PACKET pkt, short_pkt, subpkt;

    buf[0] = len;
    for (i = 1; i < BUF_LEN; i++) {
        buf[i] = (i * 2) & 0xff;
    }

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_buf_init(&short_pkt, buf, len)
            || !PACKET_get_length_prefixed_1(&pkt, &subpkt)
            ||  PACKET_remaining(&subpkt) != len
            || !PACKET_get_net_2(&subpkt, &i)
            ||  i != 0x0204
            ||  PACKET_get_length_prefixed_1(&short_pkt, &subpkt)
            ||  PACKET_remaining(&short_pkt) != len) {
        fprintf(stderr, "test_PACKET_get_length_prefixed_1() failed\n");
        return 0;
    }

    return 1;
}
Exemple #5
0
/*
 * Save the ALPN extension in a ClientHello.|pkt| holds the contents of the ALPN
 * extension, not including type and length. |al| is a pointer to the alert
 * value to send in the event of a failure. Returns: 1 on success, 0 on error.
 */
int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, int *al)
{
    PACKET protocol_list, save_protocol_list, protocol;

    if (s->s3->tmp.finish_md_len != 0)
        return 1;

    if (!PACKET_as_length_prefixed_2(pkt, &protocol_list)
        || PACKET_remaining(&protocol_list) < 2) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    save_protocol_list = protocol_list;
    do {
        /* Protocol names can't be empty. */
        if (!PACKET_get_length_prefixed_1(&protocol_list, &protocol)
                || PACKET_remaining(&protocol) == 0) {
            *al = SSL_AD_DECODE_ERROR;
            return 0;
        }
    } while (PACKET_remaining(&protocol_list) != 0);

    if (!PACKET_memdup(&save_protocol_list,
                       &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) {
        *al = TLS1_AD_INTERNAL_ERROR;
        return 0;
    }

    return 1;
}
Exemple #6
0
/*
 * Save the ALPN extension in a ClientHello.|pkt| holds the contents of the ALPN
 * extension, not including type and length. |al| is a pointer to the alert
 * value to send in the event of a failure. Returns: 1 on success, 0 on error.
 */
int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                        size_t chainidx, int *al)
{
    PACKET protocol_list, save_protocol_list, protocol;

    if (!SSL_IS_FIRST_HANDSHAKE(s))
        return 1;

    if (!PACKET_as_length_prefixed_2(pkt, &protocol_list)
        || PACKET_remaining(&protocol_list) < 2) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    save_protocol_list = protocol_list;
    do {
        /* Protocol names can't be empty. */
        if (!PACKET_get_length_prefixed_1(&protocol_list, &protocol)
                || PACKET_remaining(&protocol) == 0) {
            *al = SSL_AD_DECODE_ERROR;
            return 0;
        }
    } while (PACKET_remaining(&protocol_list) != 0);

    OPENSSL_free(s->s3->alpn_proposed);
    s->s3->alpn_proposed = NULL;
    s->s3->alpn_proposed_len = 0;
    if (!PACKET_memdup(&save_protocol_list,
                       &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) {
        *al = SSL_AD_INTERNAL_ERROR;
        return 0;
    }

    return 1;
}
Exemple #7
0
int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, int *al)
{
    size_t len;

    /* We must have requested it. */
    if (!s->s3->alpn_sent) {
        *al = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
    }
    /*-
     * The extension data consists of:
     *   uint16 list_length
     *   uint8 proto_length;
     *   uint8 proto[proto_length];
     */
    if (!PACKET_get_net_2_len(pkt, &len)
        || PACKET_remaining(pkt) != len || !PACKET_get_1_len(pkt, &len)
        || PACKET_remaining(pkt) != len) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }
    OPENSSL_free(s->s3->alpn_selected);
    s->s3->alpn_selected = OPENSSL_malloc(len);
    if (s->s3->alpn_selected == NULL) {
        *al = SSL_AD_INTERNAL_ERROR;
        return 0;
    }
    if (!PACKET_copy_bytes(pkt, s->s3->alpn_selected, len)) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }
    s->s3->alpn_selected_len = len;

    return 1;
}
Exemple #8
0
static int test_PACKET_get_length_prefixed_3()
{
    unsigned char buf[1024];
    const size_t len = 516;  /* 0x000204 */
    unsigned int i;
    PACKET pkt, short_pkt, subpkt;

    for (i = 0; i < 1024; i++) {
        buf[i] = (i * 2) & 0xff;
    }

    if (       !PACKET_buf_init(&pkt, buf, 1024)
            || !PACKET_buf_init(&short_pkt, buf, len)
            || !PACKET_get_length_prefixed_3(&pkt, &subpkt)
            ||  PACKET_remaining(&subpkt) != len
            || !PACKET_get_net_2(&subpkt, &i)
            ||  i != 0x0608
            ||  PACKET_get_length_prefixed_3(&short_pkt, &subpkt)
            ||  PACKET_remaining(&short_pkt) != len) {
        fprintf(stderr, "test_PACKET_get_length_prefixed_3() failed\n");
        return 0;
    }

    return 1;
}
Exemple #9
0
/*-
 * The servername extension is treated as follows:
 *
 * - Only the hostname type is supported with a maximum length of 255.
 * - The servername is rejected if too long or if it contains zeros,
 *   in which case an fatal alert is generated.
 * - The servername field is maintained together with the session cache.
 * - When a session is resumed, the servername call back invoked in order
 *   to allow the application to position itself to the right context.
 * - The servername is acknowledged if it is new for a session or when
 *   it is identical to a previously used for the same session.
 *   Applications can control the behaviour.  They can at any time
 *   set a 'desirable' servername for a new SSL object. This can be the
 *   case for example with HTTPS when a Host: header field is received and
 *   a renegotiation is requested. In this case, a possible servername
 *   presented in the new client hello is only acknowledged if it matches
 *   the value of the Host: field.
 * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
 *   if they provide for changing an explicit servername context for the
 *   session, i.e. when the session has been established with a servername
 *   extension.
 * - On session reconnect, the servername extension may be absent.
 */
int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, int *al)
{
    unsigned int servname_type;
    PACKET sni, hostname;

    if (!PACKET_as_length_prefixed_2(pkt, &sni)
        /* ServerNameList must be at least 1 byte long. */
        || PACKET_remaining(&sni) == 0) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    /*
     * Although the server_name extension was intended to be
     * extensible to new name types, RFC 4366 defined the
     * syntax inextensibly and OpenSSL 1.0.x parses it as
     * such.
     * RFC 6066 corrected the mistake but adding new name types
     * is nevertheless no longer feasible, so act as if no other
     * SNI types can exist, to simplify parsing.
     *
     * Also note that the RFC permits only one SNI value per type,
     * i.e., we can only have a single hostname.
     */
    if (!PACKET_get_1(&sni, &servname_type)
        || servname_type != TLSEXT_NAMETYPE_host_name
        || !PACKET_as_length_prefixed_2(&sni, &hostname)) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    if (!s->hit) {
        if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) {
            *al = TLS1_AD_UNRECOGNIZED_NAME;
            return 0;
        }

        if (PACKET_contains_zero_byte(&hostname)) {
            *al = TLS1_AD_UNRECOGNIZED_NAME;
            return 0;
        }

        if (!PACKET_strndup(&hostname, &s->session->tlsext_hostname)) {
            *al = TLS1_AD_INTERNAL_ERROR;
            return 0;
        }

        s->servername_done = 1;
    } else {
        /*
         * TODO(openssl-team): if the SNI doesn't match, we MUST
         * fall back to a full handshake.
         */
        s->servername_done = s->session->tlsext_hostname
            && PACKET_equal(&hostname, s->session->tlsext_hostname,
                            strlen(s->session->tlsext_hostname));
    }

    return 1;
}
Exemple #10
0
int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, int *al)
{
    unsigned int group_id;
    PACKET encoded_pt;
    EVP_PKEY *ckey = s->s3->tmp.pkey, *skey = NULL;

    /* Sanity check */
    if (ckey == NULL) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    if (!PACKET_get_net_2(pkt, &group_id)) {
        *al = SSL_AD_HANDSHAKE_FAILURE;
        SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, SSL_R_LENGTH_MISMATCH);
        return 0;
    }

    if (group_id != s->s3->group_id) {
        /*
         * This isn't for the group that we sent in the original
         * key_share!
         */
        *al = SSL_AD_HANDSHAKE_FAILURE;
        SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, SSL_R_BAD_KEY_SHARE);
        return 0;
    }

    if (!PACKET_as_length_prefixed_2(pkt, &encoded_pt)
            || PACKET_remaining(&encoded_pt) == 0) {
        *al = SSL_AD_DECODE_ERROR;
        SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, SSL_R_LENGTH_MISMATCH);
        return 0;
    }

    skey = ssl_generate_pkey(ckey);
    if (skey == NULL) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
                                        PACKET_remaining(&encoded_pt))) {
        *al = SSL_AD_DECODE_ERROR;
        SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, SSL_R_BAD_ECPOINT);
        return 0;
    }

    if (ssl_derive(s, ckey, skey, 1) == 0) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        EVP_PKEY_free(skey);
        return 0;
    }
    EVP_PKEY_free(skey);

    return 1;
}
Exemple #11
0
/*
 * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
 * elements of zero length are allowed and the set of elements must exactly
 * fill the length of the block. Returns 1 on success or 0 on failure.
 */
static int ssl_next_proto_validate(PACKET *pkt)
{
    PACKET tmp_protocol;

    while (PACKET_remaining(pkt)) {
        if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol)
            || PACKET_remaining(&tmp_protocol) == 0)
            return 0;
    }

    return 1;
}
static int test_PACKET_remaining(PACKET *pkt)
{
    if (        PACKET_remaining(pkt) != BUF_LEN
            || !PACKET_forward(pkt, BUF_LEN - 1)
            ||  PACKET_remaining(pkt) != 1
            || !PACKET_forward(pkt, 1)
            ||  PACKET_remaining(pkt) != 0) {
        fprintf(stderr, "test_PACKET_remaining() failed\n");
        return 0;
    }

    return 1;
}
Exemple #13
0
static int test_PACKET_remaining()
{
    PACKET pkt;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, sizeof(smbuf))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 1))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), 1)
            || !TEST_true(PACKET_forward(&pkt, 1))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), 0)))
        return 0;

    return 1;
}
Exemple #14
0
static int get_sni_from_client_hello(BIO *bio, char **sni)
{
    long len;
    unsigned char *data;
    PACKET pkt = {0}, pkt2 = {0}, pkt3 = {0}, pkt4 = {0}, pkt5 = {0};
    unsigned int servname_type = 0, type = 0;
    int ret = 0;

    len = BIO_get_mem_data(bio, (char **)&data);
    if (!TEST_true(PACKET_buf_init(&pkt, data, len))
               /* Skip the record header */
            || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH)
               /* Skip the handshake message header */
            || !TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH))
               /* Skip client version and random */
            || !TEST_true(PACKET_forward(&pkt, CLIENT_VERSION_LEN
                                               + SSL3_RANDOM_SIZE))
               /* Skip session id */
            || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2))
               /* Skip ciphers */
            || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &pkt2))
               /* Skip compression */
            || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2))
               /* Extensions len */
            || !TEST_true(PACKET_as_length_prefixed_2(&pkt, &pkt2)))
        goto end;

    /* Loop through all extensions for SNI */
    while (PACKET_remaining(&pkt2)) {
        if (!TEST_true(PACKET_get_net_2(&pkt2, &type))
                || !TEST_true(PACKET_get_length_prefixed_2(&pkt2, &pkt3)))
            goto end;
        if (type == TLSEXT_TYPE_server_name) {
            if (!TEST_true(PACKET_get_length_prefixed_2(&pkt3, &pkt4))
                    || !TEST_uint_ne(PACKET_remaining(&pkt4), 0)
                    || !TEST_true(PACKET_get_1(&pkt4, &servname_type))
                    || !TEST_uint_eq(servname_type, TLSEXT_NAMETYPE_host_name)
                    || !TEST_true(PACKET_get_length_prefixed_2(&pkt4, &pkt5))
                    || !TEST_uint_le(PACKET_remaining(&pkt5), TLSEXT_MAXLEN_host_name)
                    || !TEST_false(PACKET_contains_zero_byte(&pkt5))
                    || !TEST_true(PACKET_strndup(&pkt5, sni)))
                goto end;
            ret = 1;
            goto end;
        }
    }
end:
    return ret;
}
Exemple #15
0
static int test_PACKET_buf_init()
{
    unsigned char buf1[BUF_LEN];
    PACKET pkt;

    /* Also tests PACKET_remaining() */
    if (!TEST_true(PACKET_buf_init(&pkt, buf1, 4))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), 4)
            || !TEST_true(PACKET_buf_init(&pkt, buf1, BUF_LEN))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
            || !TEST_false(PACKET_buf_init(&pkt, buf1, -1)))
        return 0;

    return 1;
}
Exemple #16
0
/*
 * Parse the server's renegotiation binding and abort if it's not right
 */
int ssl_parse_serverhello_renegotiate_ext(SSL *s, PACKET *pkt, int *al)
{
    unsigned int expected_len = s->s3->previous_client_finished_len
        + s->s3->previous_server_finished_len;
    unsigned int ilen;
    const unsigned char *data;

    /* Check for logic errors */
    OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
    OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);

    /* Parse the length byte */
    if (!PACKET_get_1(pkt, &ilen)) {
        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
               SSL_R_RENEGOTIATION_ENCODING_ERR);
        *al = SSL_AD_ILLEGAL_PARAMETER;
        return 0;
    }

    /* Consistency check */
    if (PACKET_remaining(pkt) != ilen) {
        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
               SSL_R_RENEGOTIATION_ENCODING_ERR);
        *al = SSL_AD_ILLEGAL_PARAMETER;
        return 0;
    }

    /* Check that the extension matches */
    if (ilen != expected_len) {
        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
               SSL_R_RENEGOTIATION_MISMATCH);
        *al = SSL_AD_HANDSHAKE_FAILURE;
        return 0;
    }

    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_client_finished_len)
            || memcmp(data, s->s3->previous_client_finished,
               s->s3->previous_client_finished_len) != 0) {
        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
               SSL_R_RENEGOTIATION_MISMATCH);
        *al = SSL_AD_HANDSHAKE_FAILURE;
        return 0;
    }

    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_server_finished_len)
            || memcmp(data, s->s3->previous_server_finished,
               s->s3->previous_server_finished_len) != 0) {
        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
               SSL_R_RENEGOTIATION_MISMATCH);
        *al = SSL_AD_ILLEGAL_PARAMETER;
        return 0;
    }
#ifdef OPENSSL_RI_DEBUG
    fprintf(stderr, "%s RI extension received by client\n",
            ilen ? "Non-empty" : "Empty");
#endif
    s->s3->send_connection_binding = 1;

    return 1;
}
Exemple #17
0
/*
 * Process a psk_kex_modes extension received in the ClientHello. |pkt| contains
 * the raw PACKET data for the extension. Returns 1 on success or 0 on failure.
 */
int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context,
                                 X509 *x, size_t chainidx)
{
#ifndef OPENSSL_NO_TLS1_3
    PACKET psk_kex_modes;
    unsigned int mode;

    if (!PACKET_as_length_prefixed_1(pkt, &psk_kex_modes)
            || PACKET_remaining(&psk_kex_modes) == 0) {
        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES,
                 SSL_R_BAD_EXTENSION);
        return 0;
    }

    while (PACKET_get_1(&psk_kex_modes, &mode)) {
        if (mode == TLSEXT_KEX_MODE_KE_DHE)
            s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE_DHE;
        else if (mode == TLSEXT_KEX_MODE_KE
                && (s->options & SSL_OP_ALLOW_NO_DHE_KEX) != 0)
            s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE;
    }
#endif

    return 1;
}
Exemple #18
0
int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, int *al)
{
    unsigned int ecpointformatlist_length;
    PACKET ecptformatlist;

    if (!PACKET_as_length_prefixed_1(pkt, &ecptformatlist)) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }
    if (!s->hit) {
        ecpointformatlist_length = PACKET_remaining(&ecptformatlist);
        s->session->tlsext_ecpointformatlist_length = 0;

        OPENSSL_free(s->session->tlsext_ecpointformatlist);
        s->session->tlsext_ecpointformatlist =
             OPENSSL_malloc(ecpointformatlist_length);
        if (s->session->tlsext_ecpointformatlist == NULL) {
            *al = SSL_AD_INTERNAL_ERROR;
            return 0;
        }

        s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;

        if (!PACKET_copy_bytes(&ecptformatlist,
                               s->session->tlsext_ecpointformatlist,
                               ecpointformatlist_length)) {
            *al = SSL_AD_INTERNAL_ERROR;
            return 0;
        }
    }

    return 1;
}
Exemple #19
0
static int test_PACKET_remaining(unsigned char buf[BUF_LEN])
{
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            ||  PACKET_remaining(&pkt) != BUF_LEN
            || !PACKET_forward(&pkt, BUF_LEN - 1)
            ||  PACKET_remaining(&pkt) != 1
            || !PACKET_forward(&pkt, 1)
            ||  PACKET_remaining(&pkt) != 0) {
        fprintf(stderr, "test_PACKET_remaining() failed\n");
        return 0;
    }

    return 1;
}
Exemple #20
0
int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, unsigned int context,
                                  X509 *x, size_t chainidx, int *al)
{
    /*
     * MUST only be sent if we've requested a status
     * request message. In TLS <= 1.2 it must also be empty.
     */
    if (s->ext.status_type == TLSEXT_STATUSTYPE_nothing
            || (!SSL_IS_TLS13(s) && PACKET_remaining(pkt) > 0)) {
        *al = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
    }

    if (SSL_IS_TLS13(s)) {
        /* We only know how to handle this if it's for the first Certificate in
         * the chain. We ignore any other repsonses.
         */
        if (chainidx != 0)
            return 1;
        return tls_process_cert_status_body(s, pkt, al);
    }

    /* Set flag to expect CertificateStatus message */
    s->ext.status_expected = 1;

    return 1;
}
Exemple #21
0
int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context,
                                 X509 *x, size_t chainidx, int *al)
{
    unsigned int ecpointformats_len;
    PACKET ecptformatlist;

    if (!PACKET_as_length_prefixed_1(pkt, &ecptformatlist)) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }
    if (!s->hit) {
        ecpointformats_len = PACKET_remaining(&ecptformatlist);
        s->session->ext.ecpointformats_len = 0;

        OPENSSL_free(s->session->ext.ecpointformats);
        s->session->ext.ecpointformats = OPENSSL_malloc(ecpointformats_len);
        if (s->session->ext.ecpointformats == NULL) {
            *al = SSL_AD_INTERNAL_ERROR;
            return 0;
        }

        s->session->ext.ecpointformats_len = ecpointformats_len;

        if (!PACKET_copy_bytes(&ecptformatlist,
                               s->session->ext.ecpointformats,
                               ecpointformats_len)) {
            *al = SSL_AD_INTERNAL_ERROR;
            return 0;
        }
    }

    return 1;
}
Exemple #22
0
/*
 * Parse the server's renegotiation binding and abort if it's not right
 */
int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context,
                               X509 *x, size_t chainidx, int *al)
{
    size_t expected_len = s->s3->previous_client_finished_len
        + s->s3->previous_server_finished_len;
    size_t ilen;
    const unsigned char *data;

    /* Check for logic errors */
    assert(expected_len == 0 || s->s3->previous_client_finished_len != 0);
    assert(expected_len == 0 || s->s3->previous_server_finished_len != 0);

    /* Parse the length byte */
    if (!PACKET_get_1_len(pkt, &ilen)) {
        SSLerr(SSL_F_TLS_PARSE_STOC_RENEGOTIATE,
               SSL_R_RENEGOTIATION_ENCODING_ERR);
        *al = SSL_AD_ILLEGAL_PARAMETER;
        return 0;
    }

    /* Consistency check */
    if (PACKET_remaining(pkt) != ilen) {
        SSLerr(SSL_F_TLS_PARSE_STOC_RENEGOTIATE,
               SSL_R_RENEGOTIATION_ENCODING_ERR);
        *al = SSL_AD_ILLEGAL_PARAMETER;
        return 0;
    }

    /* Check that the extension matches */
    if (ilen != expected_len) {
        SSLerr(SSL_F_TLS_PARSE_STOC_RENEGOTIATE,
               SSL_R_RENEGOTIATION_MISMATCH);
        *al = SSL_AD_HANDSHAKE_FAILURE;
        return 0;
    }

    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_client_finished_len)
        || memcmp(data, s->s3->previous_client_finished,
                  s->s3->previous_client_finished_len) != 0) {
        SSLerr(SSL_F_TLS_PARSE_STOC_RENEGOTIATE,
               SSL_R_RENEGOTIATION_MISMATCH);
        *al = SSL_AD_HANDSHAKE_FAILURE;
        return 0;
    }

    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_server_finished_len)
        || memcmp(data, s->s3->previous_server_finished,
                  s->s3->previous_server_finished_len) != 0) {
        SSLerr(SSL_F_TLS_PARSE_STOC_RENEGOTIATE,
               SSL_R_RENEGOTIATION_MISMATCH);
        *al = SSL_AD_ILLEGAL_PARAMETER;
        return 0;
    }
    s->s3->send_connection_binding = 1;

    return 1;
}
Exemple #23
0
int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, int *al)
{
    PACKET supported_sig_algs;

    if (!PACKET_as_length_prefixed_2(pkt, &supported_sig_algs)
            || (PACKET_remaining(&supported_sig_algs) % 2) != 0
            || PACKET_remaining(&supported_sig_algs) == 0) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    if (!s->hit && !tls1_save_sigalgs(s, PACKET_data(&supported_sig_algs),
                                      PACKET_remaining(&supported_sig_algs))) {
        *al = TLS1_AD_INTERNAL_ERROR;
        return 0;
    }

    return 1;
}
Exemple #24
0
int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, int *al)
{
    if (s->tls_session_ticket_ext_cb != NULL &&
        !s->tls_session_ticket_ext_cb(s, PACKET_data(pkt),
                                      PACKET_remaining(pkt),
                                      s->tls_session_ticket_ext_cb_arg)) {
        *al = SSL_AD_INTERNAL_ERROR;
        return 0;
    }

    if (!tls_use_ticket(s) || PACKET_remaining(pkt) > 0) {
        *al = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
    }

    s->tlsext_ticket_expected = 1;

    return 1;
}
Exemple #25
0
int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context,
                              X509 *x, size_t chainidx, int *al)
{
    if (PACKET_remaining(pkt) != 0) {
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    return 1;
}
Exemple #26
0
static int test_PACKET_null_init()
{
    PACKET pkt;

    PACKET_null_init(&pkt);
    if (!TEST_size_t_eq(PACKET_remaining(&pkt), 0)
            || !TEST_false(PACKET_forward(&pkt, 1)))
        return 0;

    return 1;
}
static int test_PACKET_copy_bytes(PACKET *pkt, size_t start)
{
    unsigned char bytes[4];

    if (       !PACKET_goto_bookmark(pkt, start)
            || !PACKET_copy_bytes(pkt, bytes, 4)
            ||  bytes[0] != 2 || bytes[1] != 4
            ||  bytes[2] != 6 || bytes[3] != 8
            ||  PACKET_remaining(pkt) != BUF_LEN - 4
            || !PACKET_forward(pkt, BUF_LEN - 8)
            || !PACKET_copy_bytes(pkt, bytes, 4)
            ||  bytes[0] != 0xf8 || bytes[1] != 0xfa
            ||  bytes[2] != 0xfc || bytes[3] != 0xfe
            ||  PACKET_remaining(pkt)) {
        fprintf(stderr, "test_PACKET_copy_bytes() failed\n");
        return 0;
    }

    return 1;
}
Exemple #28
0
int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, unsigned int context,
                                  X509 *x, size_t chainidx, int *al)
{
    if (s->ext.session_ticket_cb != NULL &&
        !s->ext.session_ticket_cb(s, PACKET_data(pkt),
                              PACKET_remaining(pkt),
                              s->ext.session_ticket_cb_arg)) {
        *al = SSL_AD_INTERNAL_ERROR;
        return 0;
    }

    if (!tls_use_ticket(s) || PACKET_remaining(pkt) > 0) {
        *al = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
    }

    s->ext.ticket_expected = 1;

    return 1;
}
Exemple #29
0
static int test_PACKET_get_sub_packet()
{
    PACKET pkt, subpkt;
    unsigned long i;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_get_sub_packet(&pkt, &subpkt, 4))
            || !TEST_true(PACKET_get_net_4(&subpkt, &i))
            || !TEST_ulong_eq(i, 0x02040608UL)
            || !TEST_size_t_eq(PACKET_remaining(&subpkt), 0)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
            || !TEST_true(PACKET_get_sub_packet(&pkt, &subpkt, 4))
            || !TEST_true(PACKET_get_net_4(&subpkt, &i))
            || !TEST_ulong_eq(i, 0xf8fafcfeUL)
            || !TEST_size_t_eq(PACKET_remaining(&subpkt), 0)
            || !TEST_false(PACKET_get_sub_packet(&pkt, &subpkt, 4)))
        return 0;

    return 1;
}
Exemple #30
0
static int test_PACKET_copy_bytes(unsigned char buf[BUF_LEN])
{
    unsigned char bytes[4];
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_copy_bytes(&pkt, bytes, 4)
            ||  bytes[0] != 2 || bytes[1] != 4
            ||  bytes[2] != 6 || bytes[3] != 8
            ||  PACKET_remaining(&pkt) != BUF_LEN - 4
            || !PACKET_forward(&pkt, BUF_LEN - 8)
            || !PACKET_copy_bytes(&pkt, bytes, 4)
            ||  bytes[0] != 0xf8 || bytes[1] != 0xfa
            ||  bytes[2] != 0xfc || bytes[3] != 0xfe
            ||  PACKET_remaining(&pkt)) {
        fprintf(stderr, "test_PACKET_copy_bytes() failed\n");
        return 0;
    }

    return 1;
}