- {
- if (exts->meths)
- OPENSSL_free(exts->meths);
- }
-
-/* Set callbacks for a custom extension */
-static int custom_ext_set(custom_ext_methods *exts,
- unsigned short ext_type,
- custom_ext_parse_cb parse_cb,
- custom_ext_add_cb add_cb,
- void *arg)
- {
- custom_ext_method *meth;
- /* 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;
- meth->parse_cb = parse_cb;
- meth->add_cb = add_cb;
- meth->ext_type = ext_type;
- meth->arg = arg;
- exts->meths_count++;
- return 1;
- }
+{
+ OPENSSL_free(exts->meths);
+}
+
+/* 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;
+}