Exemplo n.º 1
0
/* Pass received custom extension data to the application for parsing. */
int custom_ext_parse(SSL *s, int server,
                     unsigned int ext_type,
                     const unsigned char *ext_data, size_t ext_size, int *al)
{
    custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext;
    custom_ext_method *meth;
    meth = custom_ext_find(exts, ext_type);
    /* If not found return success */
    if (!meth)
        return 1;
    if (!server) {
        /*
         * If it's ServerHello we can't have any extensions not sent in
         * ClientHello.
         */
        if (!(meth->ext_flags & SSL_EXT_FLAG_SENT)) {
            *al = TLS1_AD_UNSUPPORTED_EXTENSION;
            return 0;
        }
    }
    /* If already present it's a duplicate */
    if (meth->ext_flags & SSL_EXT_FLAG_RECEIVED) {
        *al = TLS1_AD_DECODE_ERROR;
        return 0;
    }
    meth->ext_flags |= SSL_EXT_FLAG_RECEIVED;
    /* If no parse function set return success */
    if (!meth->parse_cb)
        return 1;

    return meth->parse_cb(s, ext_type, ext_data, ext_size, al,
                          meth->parse_arg);
}
Exemplo n.º 2
0
/* Set callbacks for a custom extension. */
static int custom_ext_meth_add(custom_ext_methods *exts,
                               unsigned int ext_type,
                               custom_ext_add_cb add_cb,
                               custom_ext_free_cb free_cb,
                               void *add_arg,
                               custom_ext_parse_cb parse_cb, void *parse_arg)
{
    custom_ext_method *meth, *tmp;
    /*
     * Check application error: if add_cb is not set free_cb will never be
     * called.
     */
    if (!add_cb && free_cb)
        return 0;
    /*
     * Don't add if extension supported internally, but make exception
     * for extension types that previously were not supported, but now are.
     */
    if (SSL_extension_supported(ext_type) &&
        ext_type != TLSEXT_TYPE_signed_certificate_timestamp)
        return 0;
    /* Extension type must fit in 16 bits */
    if (ext_type > 0xffff)
        return 0;
    /* Search for duplicate */
    if (custom_ext_find(exts, ext_type))
        return 0;
    tmp = OPENSSL_realloc(exts->meths,
                          (exts->meths_count + 1) * sizeof(custom_ext_method));

    if (tmp == NULL) {
        OPENSSL_free(exts->meths);
        exts->meths = NULL;
        exts->meths_count = 0;
        return 0;
    }

    exts->meths = tmp;
    meth = exts->meths + exts->meths_count;
    memset(meth, 0, sizeof(*meth));
    meth->parse_cb = parse_cb;
    meth->add_cb = add_cb;
    meth->free_cb = free_cb;
    meth->ext_type = ext_type;
    meth->add_arg = add_arg;
    meth->parse_arg = parse_arg;
    exts->meths_count++;
    return 1;
}
Exemplo n.º 3
0
/* Pass received custom extension data to the application for parsing. */
int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type,
                     const unsigned char *ext_data, size_t ext_size, X509 *x,
                     size_t chainidx, int *al)
{
    custom_ext_methods *exts = &s->cert->custext;
    custom_ext_method *meth;
    ENDPOINT role = ENDPOINT_BOTH;

    if ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0)
        role = s->server ? ENDPOINT_SERVER : ENDPOINT_CLIENT;

    meth = custom_ext_find(exts, role, ext_type, NULL);
    /* If not found return success */
    if (!meth)
        return 1;

    /* Check if extension is defined for our protocol. If not, skip */
    if (!extension_is_relevant(s, meth->context, context))
        return 1;

    if ((context & (SSL_EXT_TLS1_2_SERVER_HELLO
                    | SSL_EXT_TLS1_3_SERVER_HELLO
                    | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS)) != 0) {
        /*
         * If it's ServerHello or EncryptedExtensions we can't have any
         * extensions not sent in ClientHello.
         */
        if ((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0) {
            *al = TLS1_AD_UNSUPPORTED_EXTENSION;
            return 0;
        }
    }

    /*
     * Extensions received in the ClientHello are marked with the
     * SSL_EXT_FLAG_RECEIVED. This is so we know to add the equivalent
     * extensions in the ServerHello/EncryptedExtensions message
     */
    if ((context & SSL_EXT_CLIENT_HELLO) != 0)
        meth->ext_flags |= SSL_EXT_FLAG_RECEIVED;

    /* If no parse function set return success */
    if (!meth->parse_cb)
        return 1;

    return meth->parse_cb(s, ext_type, context, ext_data, ext_size, x, chainidx,
                          al, meth->parse_arg);
}
Exemplo n.º 4
0
/* Copy the flags from src to dst for any extensions that exist in both */
int custom_exts_copy_flags(custom_ext_methods *dst,
                           const custom_ext_methods *src)
{
    size_t i;
    custom_ext_method *methsrc = src->meths;

    for (i = 0; i < src->meths_count; i++, methsrc++) {
        custom_ext_method *methdst = custom_ext_find(dst, methsrc->role,
                                                     methsrc->ext_type, NULL);

        if (methdst == NULL)
            continue;

        methdst->ext_flags = methsrc->ext_flags;
    }

    return 1;
}
Exemplo n.º 5
0
/* Set callbacks for a custom extension. */
static int custom_ext_meth_add(custom_ext_methods *exts,
                               unsigned int ext_type,
                               custom_ext_add_cb add_cb,
                               custom_ext_free_cb free_cb,
                               void *add_arg,
                               custom_ext_parse_cb parse_cb, void *parse_arg)
{
    custom_ext_method *meth;
    /*
     * Check application error: if add_cb is not set free_cb will never be
     * called.
     */
    if (!add_cb && free_cb)
        return 0;
    /* Don't add if extension supported internally. */
    if (SSL_extension_supported(ext_type))
        return 0;
    /* Extension type must fit in 16 bits */
    if (ext_type > 0xffff)
        return 0;
    /* Search for duplicate */
    if (custom_ext_find(exts, ext_type))
        return 0;
    exts->meths = OPENSSL_realloc(exts->meths,
                                  (exts->meths_count +
                                   1) * sizeof(custom_ext_method));

    if (!exts->meths) {
        exts->meths_count = 0;
        return 0;
    }

    meth = exts->meths + exts->meths_count;
    memset(meth, 0, sizeof(*meth));
    meth->parse_cb = parse_cb;
    meth->add_cb = add_cb;
    meth->free_cb = free_cb;
    meth->ext_type = ext_type;
    meth->add_arg = add_arg;
    meth->parse_arg = parse_arg;
    exts->meths_count++;
    return 1;
}
Exemplo n.º 6
0
static int add_custom_ext_intern(SSL_CTX *ctx, ENDPOINT role,
                                 unsigned int ext_type,
                                 unsigned int context,
                                 SSL_custom_ext_add_cb_ex add_cb,
                                 SSL_custom_ext_free_cb_ex free_cb,
                                 void *add_arg,
                                 SSL_custom_ext_parse_cb_ex parse_cb,
                                 void *parse_arg)
{
    custom_ext_methods *exts = &ctx->cert->custext;
    custom_ext_method *meth, *tmp;

    /*
     * Check application error: if add_cb is not set free_cb will never be
     * called.
     */
    if (add_cb == NULL && free_cb != NULL)
        return 0;

#ifndef OPENSSL_NO_CT
    /*
     * We don't want applications registering callbacks for SCT extensions
     * whilst simultaneously using the built-in SCT validation features, as
     * these two things may not play well together.
     */
    if (ext_type == TLSEXT_TYPE_signed_certificate_timestamp
            && (context & SSL_EXT_CLIENT_HELLO) != 0
            && SSL_CTX_ct_is_enabled(ctx))
        return 0;
#endif

    /*
     * Don't add if extension supported internally, but make exception
     * for extension types that previously were not supported, but now are.
     */
    if (SSL_extension_supported(ext_type)
            && ext_type != TLSEXT_TYPE_signed_certificate_timestamp)
        return 0;

    /* Extension type must fit in 16 bits */
    if (ext_type > 0xffff)
        return 0;
    /* Search for duplicate */
    if (custom_ext_find(exts, role, ext_type, NULL))
        return 0;
    tmp = OPENSSL_realloc(exts->meths,
                          (exts->meths_count + 1) * sizeof(custom_ext_method));
    if (tmp == NULL)
        return 0;

    exts->meths = tmp;
    meth = exts->meths + exts->meths_count;
    memset(meth, 0, sizeof(*meth));
    meth->role = role;
    meth->context = context;
    meth->parse_cb = parse_cb;
    meth->add_cb = add_cb;
    meth->free_cb = free_cb;
    meth->ext_type = ext_type;
    meth->add_arg = add_arg;
    meth->parse_arg = parse_arg;
    exts->meths_count++;
    return 1;
}
Exemplo n.º 7
0
/* Return true if a client custom extension exists, false otherwise */
int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, unsigned int ext_type)
{
    return custom_ext_find(&ctx->cert->custext, ENDPOINT_CLIENT, ext_type,
                           NULL) != NULL;
}
Exemplo n.º 8
0
/* Return true if a client custom extension exists, false otherwise */
int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, unsigned int ext_type)
{
    return custom_ext_find(&ctx->cert->cli_ext, ext_type) != NULL;
}