From 0a4fe37fc6248e5efadcda34015eff122e01b1db Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 10 Aug 2014 12:08:08 +0100 Subject: [PATCH] Custom extension revision. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Use the same structure for client and server custom extensions. Add utility functions in new file t1_ext.c. Use new utility functions to handle custom server and client extensions and remove a lot of code duplication. Reviewed-by: Emilia Käsper (cherry picked from commit ecf4d660902dcef6e0afc51d52926f00d409ee6b) Conflicts: ssl/ssl_lib.c ssl/ssl_locl.h ssl/t1_lib.c --- ssl/Makefile | 24 +++++- ssl/s23_clnt.c | 2 +- ssl/ssl.h | 20 ++--- ssl/ssl_cert.c | 34 ++------ ssl/ssl_lib.c | 70 ----------------- ssl/ssl_locl.h | 37 ++++++--- ssl/t1_ext.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++++ ssl/t1_lib.c | 96 +++-------------------- 8 files changed, 283 insertions(+), 209 deletions(-) create mode 100644 ssl/t1_ext.c diff --git a/ssl/Makefile b/ssl/Makefile index c018b643f2..5179f66fe5 100644 --- a/ssl/Makefile +++ b/ssl/Makefile @@ -24,7 +24,7 @@ LIBSRC= \ s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \ s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c s3_cbc.c \ s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ - t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ + t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c t1_ext.c \ d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \ d1_both.c d1_enc.c d1_srtp.c \ ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \ @@ -35,7 +35,7 @@ LIBOBJ= \ s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \ s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ - t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \ + t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o t1_ext.o \ d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \ d1_both.o d1_enc.o d1_srtp.o\ ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \ @@ -997,6 +997,26 @@ t1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h t1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h t1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h t1_enc.o: t1_enc.c +t1_ext.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h +t1_ext.o: ../include/openssl/buffer.h ../include/openssl/comp.h +t1_ext.o: ../include/openssl/crypto.h ../include/openssl/dsa.h +t1_ext.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h +t1_ext.o: ../include/openssl/ec.h ../include/openssl/ecdh.h +t1_ext.o: ../include/openssl/ecdsa.h ../include/openssl/err.h +t1_ext.o: ../include/openssl/evp.h ../include/openssl/hmac.h +t1_ext.o: ../include/openssl/kssl.h ../include/openssl/lhash.h +t1_ext.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h +t1_ext.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h +t1_ext.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h +t1_ext.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h +t1_ext.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h +t1_ext.o: ../include/openssl/safestack.h ../include/openssl/sha.h +t1_ext.o: ../include/openssl/srtp.h ../include/openssl/ssl.h +t1_ext.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h +t1_ext.o: ../include/openssl/ssl3.h ../include/openssl/stack.h +t1_ext.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h +t1_ext.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h +t1_ext.o: t1_ext.c t1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h t1_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h t1_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index e3f8a342d6..5177f060c2 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -363,7 +363,7 @@ static int ssl23_client_hello(SSL *s) if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL) ssl2_compat = 0; #endif - if (s->cert->custom_cli_ext_records_count != 0) + if (s->cert->cli_ext.meths_count != 0) ssl2_compat = 0; } #endif diff --git a/ssl/ssl.h b/ssl/ssl.h index d113b43a39..823bf0625b 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -405,21 +405,21 @@ typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, S * "al" is a TLS "AlertDescription" from 0-255 which WILL be sent as a * fatal TLS alert, if the callback returns zero. */ -typedef int (*custom_cli_ext_first_cb_fn)(SSL *s, unsigned short ext_type, + +typedef int (*custom_ext_add_cb)(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, int *al, void *arg); -typedef int (*custom_cli_ext_second_cb_fn)(SSL *s, unsigned short ext_type, + unsigned short *outlen, int *al, + void *arg); + +typedef int (*custom_ext_parse_cb)(SSL *s, unsigned short ext_type, const unsigned char *in, unsigned short inlen, int *al, void *arg); -typedef int (*custom_srv_ext_first_cb_fn)(SSL *s, unsigned short ext_type, - const unsigned char *in, - unsigned short inlen, int *al, - void *arg); -typedef int (*custom_srv_ext_second_cb_fn)(SSL *s, unsigned short ext_type, - const unsigned char **out, - unsigned short *outlen, 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 diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index f0035d768d..b5098eb996 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -435,24 +435,10 @@ CERT *ssl_cert_dup(CERT *cert) ret->ciphers_raw = NULL; #ifndef OPENSSL_NO_TLSEXT - if (cert->custom_cli_ext_records_count) - { - ret->custom_cli_ext_records = BUF_memdup(cert->custom_cli_ext_records, sizeof(custom_cli_ext_record) * cert->custom_cli_ext_records_count); - if (ret->custom_cli_ext_records == NULL) - goto err; - ret->custom_cli_ext_records_count = - cert->custom_cli_ext_records_count; - } - - if (cert->custom_srv_ext_records_count) - { - ret->custom_srv_ext_records = BUF_memdup(cert->custom_srv_ext_records, sizeof(custom_srv_ext_record) * cert->custom_srv_ext_records_count); - if (ret->custom_srv_ext_records == NULL) - goto err; - ret->custom_srv_ext_records_count = - cert->custom_srv_ext_records_count; - } - + if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) + goto err; + if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) + goto err; #endif return(ret); @@ -474,10 +460,8 @@ err: #endif #ifndef OPENSSL_NO_TLSEXT - if (ret->custom_cli_ext_records) - OPENSSL_free(ret->custom_cli_ext_records); - if (ret->custom_srv_ext_records) - OPENSSL_free(ret->custom_srv_ext_records); + custom_exts_free(&ret->cli_ext); + custom_exts_free(&ret->srv_ext); #endif ssl_cert_clear_certs(ret); @@ -571,10 +555,8 @@ void ssl_cert_free(CERT *c) if (c->ciphers_raw) OPENSSL_free(c->ciphers_raw); #ifndef OPENSSL_NO_TLSEXT - if (c->custom_cli_ext_records) - OPENSSL_free(c->custom_cli_ext_records); - if (c->custom_srv_ext_records) - OPENSSL_free(c->custom_srv_ext_records); + custom_exts_free(&c->cli_ext); + custom_exts_free(&c->srv_ext); #endif OPENSSL_free(c); } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 173d9b4904..f779ce66d7 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1726,76 +1726,6 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned } # endif -static int cert_set_custom_cli_ext(CERT *cert, unsigned short ext_type, - custom_cli_ext_first_cb_fn fn1, - custom_cli_ext_second_cb_fn fn2, void* arg) - { - size_t i; - custom_cli_ext_record* record; - - /* Check for duplicates */ - for (i=0; i < cert->custom_cli_ext_records_count; i++) - if (ext_type == cert->custom_cli_ext_records[i].ext_type) - return 0; - - cert->custom_cli_ext_records = OPENSSL_realloc(cert->custom_cli_ext_records, - (cert->custom_cli_ext_records_count + 1) * - sizeof(custom_cli_ext_record)); - if (!cert->custom_cli_ext_records) { - cert->custom_cli_ext_records_count = 0; - return 0; - } - cert->custom_cli_ext_records_count++; - record = &cert->custom_cli_ext_records[cert->custom_cli_ext_records_count - 1]; - record->ext_type = ext_type; - record->fn1 = fn1; - record->fn2 = fn2; - record->arg = arg; - return 1; - } - -static int cert_set_custom_srv_ext(CERT *cert, unsigned short ext_type, - custom_srv_ext_first_cb_fn fn1, - custom_srv_ext_second_cb_fn fn2, void* arg) - { - size_t i; - custom_srv_ext_record* record; - - /* Check for duplicates */ - for (i=0; i < cert->custom_srv_ext_records_count; i++) - if (ext_type == cert->custom_srv_ext_records[i].ext_type) - return 0; - - cert->custom_srv_ext_records = OPENSSL_realloc(cert->custom_srv_ext_records, - (cert->custom_srv_ext_records_count + 1) * - sizeof(custom_srv_ext_record)); - if (!cert->custom_srv_ext_records) { - cert->custom_srv_ext_records_count = 0; - return 0; - } - cert->custom_srv_ext_records_count++; - record = &cert->custom_srv_ext_records[cert->custom_srv_ext_records_count - 1]; - record->ext_type = ext_type; - record->fn1 = fn1; - record->fn2 = fn2; - record->arg = arg; - return 1; - } - -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) - { - return cert_set_custom_cli_ext(ctx->cert, ext_type, fn1, fn2,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) - { - return cert_set_custom_srv_ext(ctx->cert, ext_type, fn1, fn2,arg); - } - /* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit * length-prefixed strings). diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 655bca1231..f9a67b3832 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -528,17 +528,15 @@ typedef struct cert_pkey_st typedef struct { unsigned short ext_type; - custom_cli_ext_first_cb_fn fn1; - custom_cli_ext_second_cb_fn fn2; + custom_ext_add_cb add_cb; + custom_ext_parse_cb parse_cb; void *arg; -} custom_cli_ext_record; +} custom_ext_method; typedef struct { - unsigned short ext_type; - custom_srv_ext_first_cb_fn fn1; - custom_srv_ext_second_cb_fn fn2; - void *arg; -} custom_srv_ext_record; + custom_ext_method *meths; + size_t meths_count; +} custom_ext_methods; typedef struct cert_st { @@ -635,11 +633,9 @@ typedef struct cert_st unsigned char *ciphers_raw; size_t ciphers_rawlen; - /* Arrays containing the callbacks for custom TLS Extensions. */ - custom_cli_ext_record *custom_cli_ext_records; - size_t custom_cli_ext_records_count; - custom_srv_ext_record *custom_srv_ext_records; - size_t custom_srv_ext_records_count; + /* Custom extension methods for server and client */ + custom_ext_methods cli_ext; + custom_ext_methods srv_ext; int references; /* >1 only if SSL_copy_session_id is used */ } CERT; @@ -1382,6 +1378,21 @@ void tls_fips_digest_extra( int srp_verify_server_param(SSL *s, int *al); +/* t1_ext.c */ + +int custom_ext_parse(SSL *s, int server, + unsigned short ext_type, + const unsigned char *ext_data, + unsigned short ext_size, + int *al); +int custom_ext_add(SSL *s, int server, + unsigned char **pret, + unsigned char *limit, + int *al); + +int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src); +void custom_exts_free(custom_ext_methods *exts); + #else #define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer diff --git a/ssl/t1_ext.c b/ssl/t1_ext.c new file mode 100644 index 0000000000..ba6d3ded74 --- /dev/null +++ b/ssl/t1_ext.c @@ -0,0 +1,209 @@ +/* ssl/t1_ext.c */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Custom extension utility functions */ + +#include "ssl_locl.h" + +#ifndef OPENSSL_NO_TLSEXT + +/* Find a custom extension from the list */ + +static custom_ext_method *custom_ext_find(custom_ext_methods *exts, + unsigned short ext_type) + { + size_t i; + custom_ext_method *meth = exts->meths; + for (i = 0; i < exts->meths_count; i++, meth++) + { + if (ext_type == meth->ext_type) + return meth; + } + return NULL; + } + +/* pass received custom extension data to the application for parsing */ + +int custom_ext_parse(SSL *s, int server, + unsigned short ext_type, + const unsigned char *ext_data, + unsigned short 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 or no parse function set, return success */ + if (!meth || !meth->parse_cb) + return 1; + + return meth->parse_cb(s, ext_type, ext_data, ext_size, al, meth->arg); + } + +/* request custom extension data from the application and add to the + * return buffer + */ + +int custom_ext_add(SSL *s, int server, + unsigned char **pret, + unsigned char *limit, + int *al) + { + custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext; + custom_ext_method *meth; + unsigned char *ret = *pret; + size_t i; + + for (i = 0; i < exts->meths_count; i++) + { + const unsigned char *out = NULL; + unsigned short outlen = 0; + meth = exts->meths + i; + + /* For servers no callback omits extension, + * For clients it sends empty extension. + */ + if (server && !meth->add_cb) + continue; + if (meth->add_cb) + { + int cb_retval = 0; + cb_retval = meth->add_cb(s, meth->ext_type, + &out, &outlen, al, + meth->arg); + if (cb_retval == 0) + return 0; /* error */ + if (cb_retval == -1) + continue; /* skip this extension */ + } + if (4 > limit - ret || outlen > limit - ret - 4) + return 0; + s2n(meth->ext_type, ret); + s2n(outlen, ret); + if (outlen) + { + memcpy(ret, out, outlen); + ret += outlen; + } + } + *pret = ret; + return 1; + } + +/* Copy table of custom extensions */ + +int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src) + { + if (src->meths_count) + { + dst->meths = BUF_memdup(src->meths, sizeof(custom_ext_method) * src->meths_count); + if (dst->meths == NULL) + return 0; + dst->meths_count = src->meths_count; + } + return 1; + } + +void custom_exts_free(custom_ext_methods *exts) + { + 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; + } + +/* 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) + { + return custom_ext_set(&ctx->cert->cli_ext, ext_type, fn2, fn1, 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) + { + return custom_ext_set(&ctx->cert->srv_ext, ext_type, fn1, fn2, arg); + } +#endif diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 78cdc52914..3b3e0e334f 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1446,38 +1446,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c } /* Add custom TLS Extensions to ClientHello */ - if (s->cert->custom_cli_ext_records_count) - { - size_t i; - custom_cli_ext_record* record; - - for (i = 0; i < s->cert->custom_cli_ext_records_count; i++) - { - const unsigned char* out = NULL; - unsigned short outlen = 0; + if (!custom_ext_add(s, 0, &ret, limit, al)) + return NULL; - record = &s->cert->custom_cli_ext_records[i]; - /* NULL callback sends empty extension */ - /* -1 from callback omits extension */ - if (record->fn1) - { - int cb_retval = 0; - cb_retval = record->fn1(s, record->ext_type, - &out, &outlen, al, - record->arg); - if (cb_retval == 0) - return NULL; /* error */ - if (cb_retval == -1) - continue; /* skip this extension */ - } - if (limit < ret + 4 + outlen) - return NULL; - s2n(record->ext_type, ret); - s2n(outlen, ret); - memcpy(ret, out, outlen); - ret += outlen; - } - } /* Add padding to workaround bugs in F5 terminators. * See https://tools.ietf.org/html/draft-agl-tls-padding-03 * @@ -1520,8 +1491,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c int extdatalen=0; unsigned char *orig = buf; unsigned char *ret = buf; - size_t i; - custom_srv_ext_record *record; #ifndef OPENSSL_NO_NEXTPROTONEG int next_proto_neg_seen; #endif @@ -1706,32 +1675,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c } } #endif - - for (i = 0; i < s->cert->custom_srv_ext_records_count; i++) - { - const unsigned char *out = NULL; - unsigned short outlen = 0; - int cb_retval = 0; - - record = &s->cert->custom_srv_ext_records[i]; - - /* NULL callback or -1 omits extension */ - if (!record->fn2) - continue; - cb_retval = record->fn2(s, record->ext_type, - &out, &outlen, al, - record->arg); - if (cb_retval == 0) - return NULL; /* error */ - if (cb_retval == -1) - continue; /* skip this extension */ - if (limit < ret + 4 + outlen) - return NULL; - s2n(record->ext_type, ret); - s2n(outlen, ret); - memcpy(ret, out, outlen); - ret += outlen; - } + if (!custom_ext_add(s, 1, &ret, limit, al)) + return NULL; if (s->s3->alpn_selected) { @@ -2444,19 +2389,10 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char * so call the callback and record the extension number so that * an appropriate ServerHello may be later returned. */ - else if (!s->hit && s->cert->custom_srv_ext_records_count) + else if (!s->hit) { - custom_srv_ext_record *record; - - for (i=0; i < s->cert->custom_srv_ext_records_count; i++) - { - record = &s->cert->custom_srv_ext_records[i]; - if (type == record->ext_type) - { - if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg)) - return 0; - } - } + if (!custom_ext_parse(s, 1, type, data, size, al)) + return 0; } data+=size; @@ -2782,22 +2718,8 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char /* If this extension type was not otherwise handled, but * matches a custom_cli_ext_record, then send it to the c * callback */ - else if (s->cert->custom_cli_ext_records_count) - { - size_t i; - custom_cli_ext_record* record; - - for (i = 0; i < s->cert->custom_cli_ext_records_count; i++) - { - record = &s->cert->custom_cli_ext_records[i]; - if (record->ext_type == type) - { - if (record->fn2 && !record->fn2(s, type, data, size, al, record->arg)) - return 0; - break; - } - } - } + else if (!custom_ext_parse(s, 0, type, data, size, al)) + return 0; data += size; } -- 2.25.1