#ifndef OPENSSL_NO_TLSEXT
/* Callbacks and structures for handling custom TLS Extensions:
- * cli_ext_first_cb - sends data for ClientHello TLS Extension
- * cli_ext_second_cb - receives data from ServerHello TLS Extension
- * srv_ext_first_cb - receives data from ClientHello TLS Extension
- * srv_ext_second_cb - sends data for ServerHello TLS Extension
+ * cli_ext_add_cb - sends data for ClientHello TLS Extension
+ * cli_ext_parse_cb - receives data from ServerHello TLS Extension
+ * srv_ext_parse_cb - receives data from ClientHello TLS Extension
+ * srv_ext_add_cb - sends data for ServerHello TLS Extension
*
* All these functions return nonzero on success. Zero will terminate
* the handshake (and return a specific TLS Fatal alert, if the function
* fatal TLS alert, if the callback returns zero.
*/
-typedef int (*custom_ext_add_cb)(SSL *s, unsigned short ext_type,
+typedef int (*custom_ext_add_cb)(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al,
+ size_t *outlen, int *al,
void *arg);
-typedef int (*custom_ext_parse_cb)(SSL *s, unsigned short ext_type,
+typedef int (*custom_ext_parse_cb)(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg);
-typedef custom_ext_add_cb custom_cli_ext_first_cb_fn;
-typedef custom_ext_parse_cb custom_cli_ext_second_cb_fn;
-typedef custom_ext_add_cb custom_srv_ext_second_cb_fn;
-typedef custom_ext_parse_cb custom_srv_ext_first_cb_fn;
-
#endif
#ifndef OPENSSL_NO_SSL_INTERN
* handled by OpenSSL will fail.
*
* NULL can be registered for any callback function. For the client
- * functions, a NULL custom_cli_ext_first_cb_fn sends an empty ClientHello
- * Extension, and a NULL custom_cli_ext_second_cb_fn ignores the ServerHello
+ * functions, a NULL custom_ext_add_cb sends an empty ClientHello
+ * Extension, and a NULL custom_ext_parse_cb ignores the ServerHello
* response (if any).
*
- * For the server functions, a NULL custom_srv_ext_first_cb_fn means the
+ * For the server functions, a NULL custom_ext_parse means the
* ClientHello extension's data will be ignored, but the extension will still
- * be noted and custom_srv_ext_second_cb_fn will still be invoked. A NULL
+ * be noted and custom_ext_add_cb will still be invoked. A NULL
* custom_srv_ext_second_cb doesn't send a ServerHello extension.
*/
-int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
- custom_cli_ext_first_cb_fn fn1,
- custom_cli_ext_second_cb_fn fn2, void *arg);
+int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned int ext_type,
+ custom_ext_add_cb add_cb,
+ custom_ext_parse_cb parse_cb, void *arg);
-int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
- custom_srv_ext_first_cb_fn fn1,
- custom_srv_ext_second_cb_fn fn2, void *arg);
+int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned int ext_type,
+ custom_ext_parse_cb parse_cb,
+ custom_ext_add_cb add_cb, void *arg);
#endif
/* This set based on extension callbacks */
int custom_ext_error = 0;
-static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
- const unsigned char* in, unsigned short inlen,
+static int serverinfo_cli_cb(SSL* s, unsigned int ext_type,
+ const unsigned char* in, size_t inlen,
int* al, void* arg)
{
if (ext_type == SCT_EXT_TYPE)
* 3 - ClientHello with "abc", "defg" response
*/
-static int custom_ext_0_cli_first_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_0_cli_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_0)
custom_ext_error = 1;
return -1; /* Don't send an extension */
}
-static int custom_ext_0_cli_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_0_cli_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
return 1;
}
-static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_1_cli_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_1)
custom_ext_error = 1;
return 1; /* Send "abc" */
}
-static int custom_ext_1_cli_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_1_cli_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
return 1;
}
-static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_2_cli_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_2)
custom_ext_error = 1;
return 1; /* Send "abc" */
}
-static int custom_ext_2_cli_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_2_cli_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_2)
return 1;
}
-static int custom_ext_3_cli_first_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_3_cli_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_3)
custom_ext_error = 1;
return 1; /* Send "abc" */
}
-static int custom_ext_3_cli_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_3_cli_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_3)
return 1;
}
-/* custom_ext_0_cli_first_cb returns -1 - the server won't receive a callback for this extension */
-static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type,
+/* custom_ext_0_cli_parse_cb returns -1 - the server won't receive a callback for this extension */
+static int custom_ext_0_srv_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
return 1;
}
/* 'generate' callbacks are always called, even if the 'receive' callback isn't called */
-static int custom_ext_0_srv_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_0_srv_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
return -1; /* Don't send an extension */
}
-static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_1_srv_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_1)
return 1;
}
-static int custom_ext_1_srv_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_1_srv_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
return -1; /* Don't send an extension */
}
-static int custom_ext_2_srv_first_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_2_srv_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_2)
return 1;
}
-static int custom_ext_2_srv_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_2_srv_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
*out = NULL;
*outlen = 0;
return 1; /* Send empty extension */
}
-static int custom_ext_3_srv_first_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_3_srv_parse_cb(SSL *s, unsigned int ext_type,
const unsigned char *in,
- unsigned short inlen, int *al,
+ size_t inlen, int *al,
void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_3)
return 1;
}
-static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
+static int custom_ext_3_srv_add_cb(SSL *s, unsigned int ext_type,
const unsigned char **out,
- unsigned short *outlen, int *al, void *arg)
+ size_t *outlen, int *al, void *arg)
{
*out = (const unsigned char*)custom_ext_srv_string;
*outlen = strlen(custom_ext_srv_string);
if (custom_ext)
{
SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_0,
- custom_ext_0_cli_first_cb,
- custom_ext_0_cli_second_cb, NULL);
+ custom_ext_0_cli_add_cb,
+ custom_ext_0_cli_parse_cb, NULL);
SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_1,
- custom_ext_1_cli_first_cb,
- custom_ext_1_cli_second_cb, NULL);
+ custom_ext_1_cli_add_cb,
+ custom_ext_1_cli_parse_cb, NULL);
SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_2,
- custom_ext_2_cli_first_cb,
- custom_ext_2_cli_second_cb, NULL);
+ custom_ext_2_cli_add_cb,
+ custom_ext_2_cli_parse_cb, NULL);
SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_3,
- custom_ext_3_cli_first_cb,
- custom_ext_3_cli_second_cb, NULL);
+ custom_ext_3_cli_add_cb,
+ custom_ext_3_cli_parse_cb, NULL);
SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_0,
- custom_ext_0_srv_first_cb,
- custom_ext_0_srv_second_cb, NULL);
+ custom_ext_0_srv_parse_cb,
+ custom_ext_0_srv_add_cb, NULL);
SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_1,
- custom_ext_1_srv_first_cb,
- custom_ext_1_srv_second_cb, NULL);
+ custom_ext_1_srv_parse_cb,
+ custom_ext_1_srv_add_cb, NULL);
SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_2,
- custom_ext_2_srv_first_cb,
- custom_ext_2_srv_second_cb, NULL);
+ custom_ext_2_srv_parse_cb,
+ custom_ext_2_srv_add_cb, NULL);
SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_3,
- custom_ext_3_srv_first_cb,
- custom_ext_3_srv_second_cb, NULL);
+ custom_ext_3_srv_parse_cb,
+ custom_ext_3_srv_add_cb, NULL);
}
if (alpn_server)
/* pass received custom extension data to the application for parsing */
int custom_ext_parse(SSL *s, int server,
- unsigned short ext_type,
+ unsigned int ext_type,
const unsigned char *ext_data,
- unsigned short ext_size,
+ size_t ext_size,
int *al)
{
custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext;
for (i = 0; i < exts->meths_count; i++)
{
const unsigned char *out = NULL;
- unsigned short outlen = 0;
+ size_t outlen = 0;
meth = exts->meths + i;
if (server)
if (cb_retval == -1)
continue; /* skip this extension */
}
- if (4 > limit - ret || outlen > limit - ret - 4)
+ if (4 > limit - ret || outlen > (size_t)(limit - ret - 4))
return 0;
s2n(meth->ext_type, ret);
s2n(outlen, ret);
/* Set callbacks for a custom extension */
static int custom_ext_set(custom_ext_methods *exts,
- unsigned short ext_type,
+ unsigned int ext_type,
custom_ext_parse_cb parse_cb,
custom_ext_add_cb add_cb,
void *arg)
#endif
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;
/* Application level functions to add custom extension callbacks */
-int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
- custom_cli_ext_first_cb_fn fn1,
- custom_cli_ext_second_cb_fn fn2, void *arg)
+int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned int ext_type,
+ custom_ext_add_cb add_cb,
+ custom_ext_parse_cb parse_cb, void *arg)
+
{
- return custom_ext_set(&ctx->cert->cli_ext, ext_type, fn2, fn1, arg);
+ return custom_ext_set(&ctx->cert->cli_ext, ext_type, parse_cb, add_cb,
+ arg);
}
-int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
- custom_srv_ext_first_cb_fn fn1,
- custom_srv_ext_second_cb_fn fn2, void *arg)
+int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned int ext_type,
+ custom_ext_parse_cb parse_cb,
+ custom_ext_add_cb add_cb, void *arg)
{
- return custom_ext_set(&ctx->cert->srv_ext, ext_type, fn1, fn2, arg);
+ return custom_ext_set(&ctx->cert->srv_ext, ext_type, parse_cb, add_cb,
+ arg);
}
#endif