[PATCH] TLS hello extensions and supplemental data

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] TLS hello extensions and supplemental data

Davide Vernizzi-3
Hi devs,

we are sending you our patch that provides a framework for supporting
TLS Hello Extensions (RFC 4366) and Supplemental Data (RFC 4680). It is
intended to help developers who want to add support for new TLS
extensions into OpenSSL.

Our framework treats every extension as an object, with data to be
exchanged during the handshake and methods that implement the extension
logic. Supplemental Data are part of such objects, to adhere with RFC
4680:

        Information provided in a supplemental data object MUST be intended
        to be used exclusively by applications and protocols above the TLS
        protocol layer.  Any such data MUST NOT need to be processed by the
        TLS protocol.

By having this unified view for extensions, it is easy to support once
for all some of the requirements imposed by RFCs, for instance (RFC
4366):

      * There MUST NOT be more than one extension of the same type.
      * In the event that a client requests additional functionality
        using the extended client hello, and this functionality is not
        supplied by the server, the client MAY abort the handshake.

We started developing it because we are using extensions in our research
and we found that writing new extensions is quite a pain ;-).

We also created a blog with instructions and examples on
installation/use of the framework:

http://tlsext-general.blogspot.com/

The work is not yet finished, but mature enough to be tested/commented.
If you think it is worth, we can allocate some time to improve the error
management and to port existing extensions within our framework.

We tested the patch against the latest snapshot available (2008/12/14).

Any comment/request is more than welcome.

Davide and Emanuele.

---
diff -urN openssl-SNAP-20081204/apps/Makefile o-tlsext/apps/Makefile
--- openssl-SNAP-20081204/apps/Makefile 2008-12-02 03:00:14.000000000
+0100
+++ o-tlsext/apps/Makefile 2008-12-11 12:53:13.000000000 +0100
@@ -817,6 +817,7 @@
 s_client.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
 s_client.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
 s_client.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+s_client.o: ../include/openssl/t1_ext.h ../include/openssl/t1_ext_test.h
 s_client.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
apps.h
 s_client.o: s_apps.h s_client.c timeouts.h

s_server.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
@@ -840,6 +841,7 @@
 s_server.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
 s_server.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
 s_server.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_server.o: ../include/openssl/t1_ext.h ../include/openssl/t1_ext_test.h
 s_server.o: ../include/openssl/ui.h ../include/openssl/x509.h
 s_server.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
apps.h
 s_server.o: s_apps.h s_server.c timeouts.h
diff -urN openssl-SNAP-20081204/apps/s_client.c o-tlsext/apps/s_client.c
--- openssl-SNAP-20081204/apps/s_client.c 2008-11-24 19:00:17.000000000
+0100
+++ o-tlsext/apps/s_client.c 2008-12-11 12:53:17.000000000 +0100
@@ -901,6 +901,11 @@
 #endif
 
  con=SSL_new(ctx);
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ SSL_TLSEXT_TEST_client_init(con);
+#endif
+
  if (sess_in)
  {
  SSL_SESSION *sess;
diff -urN openssl-SNAP-20081204/apps/s_server.c o-tlsext/apps/s_server.c
--- openssl-SNAP-20081204/apps/s_server.c 2008-12-01 00:00:28.000000000
+0100
+++ o-tlsext/apps/s_server.c 2008-12-11 12:53:20.000000000 +0100
@@ -1787,6 +1787,9 @@
  tlscstatp.err = bio_err;
  SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
  }
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ SSL_TLSEXT_TEST_server_init(con);
+#endif
 #endif
 #ifndef OPENSSL_NO_KRB5
  if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
diff -urN openssl-SNAP-20081204/ssl/Makefile o-tlsext/ssl/Makefile
--- openssl-SNAP-20081204/ssl/Makefile 2008-06-04 13:02:01.000000000
+0200
+++ o-tlsext/ssl/Makefile 2008-12-11 12:52:46.000000000 +0100
@@ -30,7 +30,8 @@
  ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
  ssl_ciph.c ssl_stat.c ssl_rsa.c \
  ssl_asn1.c ssl_txt.c ssl_algs.c \
- bio_ssl.c ssl_err.c kssl.c
+ bio_ssl.c ssl_err.c kssl.c \
+ t1_ext.c t1_ext_test.c
 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
\
@@ -41,11 +42,12 @@
  ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
  ssl_ciph.o ssl_stat.o ssl_rsa.o \
  ssl_asn1.o ssl_txt.o ssl_algs.o \
- bio_ssl.o ssl_err.o kssl.o
+ bio_ssl.o ssl_err.o kssl.o \
+ t1_ext.o t1_ext_test.o
 
 SRC= $(LIBSRC)
 
-EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h
+EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h dtls1.h kssl.h t1_ext.h
t1_ext_test.h
 HEADER= $(EXHEADER) ssl_locl.h kssl_lcl.h
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
@@ -954,3 +956,5 @@
 t1_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
 t1_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
ssl_locl.h
 t1_srvr.o: t1_srvr.c
+t1_ext.o: ../include/openssl/ssl.h ../include/openssl/t1_ext.h t1_ext.c
+t1_ext_test.o: ../include/openssl/ssl.h ../include/openssl/t1_ext.h ../include/openssl/t1_ext_test.h t1_ext_test.c
diff -urN openssl-SNAP-20081204/ssl/s3_clnt.c o-tlsext/ssl/s3_clnt.c
--- openssl-SNAP-20081204/ssl/s3_clnt.c 2008-11-15 19:00:22.000000000
+0100
+++ o-tlsext/ssl/s3_clnt.c 2008-12-11 13:02:37.000000000 +0100
@@ -282,13 +282,26 @@
  case SSL3_ST_CR_SRVR_HELLO_B:
  ret=ssl3_get_server_hello(s);
  if (ret <= 0) goto end;
-
  if (s->hit)
  s->state=SSL3_ST_CR_FINISHED_A;
  else
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ s->state=SSL3_ST_CR_SRVR_SUPP_DATA_A;
+#else
  s->state=SSL3_ST_CR_CERT_A;
+#endif
+ s->init_num=0;
+ break;
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ case SSL3_ST_CR_SRVR_SUPP_DATA_A:
+ /* CR_SRVR_SUPP_DATA implementation */
+ ret=ssl3_get_server_supp_data(s);
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_CR_CERT_A;
  s->init_num=0;
  break;
+#endif
 
  case SSL3_ST_CR_CERT_A:
  case SSL3_ST_CR_CERT_B:
@@ -362,6 +375,20 @@
  case SSL3_ST_CR_SRVR_DONE_B:
  ret=ssl3_get_server_done(s);
  if (ret <= 0) goto end;
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ /* CR_SRVR_DONE goes to CW_CLNT_SUPP_DATA */
+ s->state=SSL3_ST_CW_CLNT_SUPP_DATA_A;
+ s->init_num=0;
+ break;
+
+ case SSL3_ST_CW_CLNT_SUPP_DATA_A:
+ /* CW_CLNT_SUPP_DATA implementation */
+ ret=ssl3_send_client_supp_data(s);
+ if (ret <= 0) goto end;
+ /* CW_CLNT_SUPP_DATA goes to... as CR_SRVR_DONE did */
+#endif
+
  if (s->s3->tmp.cert_req)
  s->state=SSL3_ST_CW_CERT_A;
  else
@@ -595,6 +622,11 @@
  BUF_MEM_free(buf);
  if (cb != NULL)
  cb(s,SSL_CB_CONNECT_EXIT,ret);
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ ssl_tlsext_general_client_finish_cb(s);
+#endif
+
  return(ret);
  }
 
diff -urN openssl-SNAP-20081204/ssl/s3_srvr.c o-tlsext/ssl/s3_srvr.c
--- openssl-SNAP-20081204/ssl/s3_srvr.c 2008-11-15 19:00:22.000000000
+0100
+++ o-tlsext/ssl/s3_srvr.c 2008-12-11 13:02:37.000000000 +0100
@@ -327,9 +327,23 @@
  s->state=SSL3_ST_SW_CHANGE_A;
 #endif
  else
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ s->state=SSL3_ST_SW_SRVR_SUPP_DATA_A;
+#else
  s->state=SSL3_ST_SW_CERT_A;
+#endif
+ s->init_num=0;
+ break;
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ case SSL3_ST_SW_SRVR_SUPP_DATA_A:
+ /* SW_SRVR_SUPP_DATA implementation */
+ ret=ssl3_send_server_supp_data(s);
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_SW_CERT_A;
  s->init_num=0;
  break;
+#endif
 
  case SSL3_ST_SW_CERT_A:
  case SSL3_ST_SW_CERT_B:
@@ -455,8 +469,12 @@
  s->state=SSL3_ST_SW_SRVR_DONE_A;
 #else
  s->state=SSL3_ST_SW_FLUSH;
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ s->s3->tmp.next_state=SSL3_ST_SR_CLNT_SUPP_DATA_A;
+#else
  s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
 #endif
+#endif
  s->init_num=0;
  }
  break;
@@ -465,7 +483,11 @@
  case SSL3_ST_SW_SRVR_DONE_B:
  ret=ssl3_send_server_done(s);
  if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ s->s3->tmp.next_state=SSL3_ST_SR_CLNT_SUPP_DATA_A;
+#else
  s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+#endif
  s->state=SSL3_ST_SW_FLUSH;
  s->init_num=0;
  break;
@@ -484,6 +506,17 @@
  s->state=s->s3->tmp.next_state;
  break;
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ case SSL3_ST_SR_CLNT_SUPP_DATA_A:
+ case SSL3_ST_SR_CLNT_SUPP_DATA_B:
+ /* SR_CLNT_SUPP_DATA implementation */
+ ret=ssl3_get_client_supp_data(s);
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_SR_CERT_A;
+ s->init_num=0;
+ break;
+#endif
+
  case SSL3_ST_SR_CERT_A:
  case SSL3_ST_SR_CERT_B:
  /* Check for second client hello (MS SGC) */
@@ -692,6 +725,11 @@
  s->in_handshake--;
  if (cb != NULL)
  cb(s,SSL_CB_ACCEPT_EXIT,ret);
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ ssl_tlsext_general_server_finish_cb(s);
+#endif
+
  return(ret);
  }
 
diff -urN openssl-SNAP-20081204/ssl/ssl3.h o-tlsext/ssl/ssl3.h
--- openssl-SNAP-20081204/ssl/ssl3.h 2008-10-12 17:00:22.000000000 +0200
+++ o-tlsext/ssl/ssl3.h 2008-12-11 12:56:55.000000000 +0100
@@ -548,6 +548,11 @@
 #define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT)
 #define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT)
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+#define SSL3_ST_CR_SRVR_SUPP_DATA_A (0x124|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CLNT_SUPP_DATA_A (0x166|SSL_ST_CONNECT)
+#endif
+
 /* server */
 /* extra state */
 #define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT)
@@ -593,6 +598,12 @@
 #define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT)
 #define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT)
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+#define SSL3_ST_SW_SRVR_SUPP_DATA_A (0x136|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_SUPP_DATA_A (0x176|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_SUPP_DATA_B (0x177|SSL_ST_ACCEPT)
+#endif
+
 #define SSL3_MT_HELLO_REQUEST 0
 #define SSL3_MT_CLIENT_HELLO 1
 #define SSL3_MT_SERVER_HELLO 2
@@ -607,6 +618,9 @@
 #define SSL3_MT_CERTIFICATE_STATUS 22
 #define DTLS1_MT_HELLO_VERIFY_REQUEST    3
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+#define TLS1_MT_SUPPLEMENTAL_DATA 23
+#endif
 
 #define SSL3_MT_CCS 1
 
diff -urN openssl-SNAP-20081204/ssl/ssl.h o-tlsext/ssl/ssl.h
--- openssl-SNAP-20081204/ssl/ssl.h 2008-11-16 14:00:23.000000000 +0100
+++ o-tlsext/ssl/ssl.h 2008-12-11 12:56:55.000000000 +0100
@@ -1161,6 +1161,11 @@
  void *tls_session_secret_cb_arg;
 
  SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ STACK_OF(TLSEXT_GENERAL) *tlsext_general;
+#endif
+
 #define session_ctx initial_ctx
 #else
 #define session_ctx ctx
@@ -1174,6 +1179,10 @@
 #include <openssl/ssl2.h>
 #include <openssl/ssl3.h>
 #include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+#include <openssl/t1_ext.h> /* General framework for TLS Extensions */
+#include <openssl/t1_ext_test.h>
+#endif
 #include <openssl/dtls1.h> /* Datagram TLS */
 #include <openssl/ssl23.h>
 
diff -urN openssl-SNAP-20081204/ssl/ssl_lib.c o-tlsext/ssl/ssl_lib.c
--- openssl-SNAP-20081204/ssl/ssl_lib.c 2008-11-12 05:00:37.000000000
+0100
+++ o-tlsext/ssl/ssl_lib.c 2008-12-11 13:02:37.000000000 +0100
@@ -352,6 +352,12 @@
  s->tlsext_ocsp_resplen = -1;
  CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
  s->initial_ctx=ctx;
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ s->tlsext_general = sk_TLSEXT_GENERAL_new_null();
+ if (s->tlsext_general == NULL)
+ goto err;
+#endif
 #endif
 
  s->verify_result=X509_V_OK;
@@ -560,6 +566,10 @@
  sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
  if (s->tlsext_ocsp_resp)
  OPENSSL_free(s->tlsext_ocsp_resp);
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ if (s->tlsext_general != NULL)
+
sk_TLSEXT_GENERAL_pop_free(s->tlsext_general,SSL_TLSEXT_GENERAL_free);
+#endif
 #endif
 
  if (s->client_CA != NULL)
diff -urN openssl-SNAP-20081204/ssl/t1_ext.c o-tlsext/ssl/t1_ext.c
--- openssl-SNAP-20081204/ssl/t1_ext.c 1970-01-01 01:00:00.000000000
+0100
+++ o-tlsext/ssl/t1_ext.c 2008-12-11 13:02:37.000000000 +0100
@@ -0,0 +1,1504 @@
+/* ssl/t1_ext.c */
+/* Copyright (C) 1995-1998 Eric Young ([hidden email])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([hidden email]).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long
as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL
documentation
+ * included with this distribution is covered by the same copyright
terms
+ * except that the holder is Tim Hudson ([hidden email]).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given
attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young ([hidden email])"
+ *    The word 'cryptographic' can be left out if the rouines from the
library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative
thereof) from
+ *    the apps directory (application code) you must include an
acknowledgement:
+ *    "This product includes software written by Tim Hudson
([hidden email])"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available
version or
+ * derivative of this code cannot be changed.  i.e. this code cannot
simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2008 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
+ *    [hidden email].
+ *
+ * 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
+ * ([hidden email]).  This product includes software written by Tim
+ * Hudson ([hidden email]).
+ *
+ */
+/* ====================================================================
+ * Copyright (C) 2008 Davide Vernizzi and Emanuele Cesena
([hidden email])
+ * All rights reserved.
+ *
+ * General TLS Extension framework, implementing RFC 4366 and RFC 4680.
+ */
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+
+/*TODO
+ * 1. functions for find
+ * 2. optimise search for sd<->ext (ssl3_get_[client|server]_supp_data)
+ */
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL CORE
+ *
+ *********************************************************************/
+
+/**
+ * Destructor of a ::TLSEXT_GENERAL object.
+ * It is called by the stack destructor.
+ */
+void SSL_TLSEXT_GENERAL_free(TLSEXT_GENERAL * e) {
+ if (e == NULL) return;
+
+ if (e->client_data) OPENSSL_free(e->client_data);
+ if (e->client_ctx_data) OPENSSL_free(e->client_ctx_data);
+
+ if (e->server_data) OPENSSL_free(e->server_data);
+ if (e->server_ctx_data) OPENSSL_free(e->server_ctx_data);
+
+ if (e->client_supp_data)
+
sk_SUPP_DATA_ENTRY_pop_free(e->client_supp_data,SSL_SUPP_DATA_ENTRY_free);
+ if (e->server_supp_data)
+
sk_SUPP_DATA_ENTRY_pop_free(e->server_supp_data,SSL_SUPP_DATA_ENTRY_free);
+
+ OPENSSL_free(e);
+}
+
+
+/**
+ * Destructor of a ::SUPP_DATA_ENTRY object.
+ * It is called by the stack destructor.
+ */
+void SSL_SUPP_DATA_ENTRY_free(SUPP_DATA_ENTRY * sd) {
+ if (sd == NULL) return;
+
+ if (sd->data) OPENSSL_free(sd->data);
+
+ OPENSSL_free(sd);
+}
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL INTERFACE
+ *
+ *********************************************************************/
+
+/*********************************************************************
+ * CREATION
+ *********************************************************************/
+
+/**
+ * Create a new extension of type \p type and push it in the stack of
an ::SSL object \p ssl.
+ *
+ * The function enforces the following property.
+ *
+ * RFC 4366:
+ * \verbatim There MUST NOT be more than one extension of the same type
\endverbatim
+ *
+ * @param ssl ::SSL object containing the extension stack
+ * @param type extension type (SHOULD be defined by IANA)
+ * @return the extension created
+ */
+TLSEXT_GENERAL* SSL_TLSEXT_GENERAL_new(SSL * s, int type) {
+ int i;
+ TLSEXT_GENERAL * ext = NULL;
+
+ if (s == NULL || s->tlsext_general == NULL) {
+ return NULL;
+ }
+
+ /* Check if the ext to be registered is unique
+ *
+ * RFC4366:
+ * There MUST NOT be more than one extension of the same type.
+ */
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ ext = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (ext->type == type) {
+ return NULL;
+ }
+ }
+
+ ext = NULL;
+ ext = (TLSEXT_GENERAL *)OPENSSL_malloc(sizeof(TLSEXT_GENERAL));
+ if (ext == NULL) {
+ return(NULL);
+ }
+
+ ext->type = type;
+
+ ext->client_data_length = 0;
+ ext->client_data = NULL;
+ ext->client_ctx_data = NULL;
+
+ ext->server_data_length = 0;
+ ext->server_data = NULL;
+ ext->server_ctx_data = NULL;
+
+ ext->client_supp_data = NULL;
+ ext->server_supp_data = NULL;
+
+ ext->client_required = 0;
+ ext->server_send = 0;
+ ext->received = 0;
+
+ ext->client_ext_callback = NULL;
+ ext->client_supp_data_callback = NULL;
+ ext->client_finish_callback = NULL;
+ ext->server_ext_callback = NULL;
+ ext->server_supp_data_callback = NULL;
+ ext->server_finish_callback = NULL;
+
+ sk_TLSEXT_GENERAL_push(s->tlsext_general, ext);
+
+ return ext;
+}
+
+
+/**
+ * Create a new supplemental data entry of type \p type and push it in
the \b Client stack of a ::TLSEXT_GENERAL object \p ext.
+ *
+ * We guarantee uniqness as for extensions (see
SSL_TLSEXT_GENERAL_new()).
+ *
+ * @param ssl ::SSL object containing the extension stack
+ * @param type extension type (SHOULD be defined by IANA)
+ * @return the supplemental data entry created
+ */
+SUPP_DATA_ENTRY* SSL_TLSEXT_GENERAL_client_supp_data_new(TLSEXT_GENERAL
* ext, int type) {
+ int i;
+ SUPP_DATA_ENTRY * sd = NULL;
+
+ if (ext == NULL) {
+ return NULL;
+ }
+
+ if (ext->client_supp_data == NULL) {
+ /* initialize the stack */
+ ext->client_supp_data = sk_SUPP_DATA_ENTRY_new_null();
+ if (ext->client_supp_data == NULL) {
+ return NULL;
+ }
+ }
+ else {
+ /* guarantee uniqness */
+ for (i = 0; i < sk_SUPP_DATA_ENTRY_num(ext->client_supp_data); i++) {
+ sd = sk_SUPP_DATA_ENTRY_value(ext->client_supp_data, i);
+ if (sd->type == type) {
+ return NULL;
+ }
+ }
+ }
+
+ /* add supp data */
+ sd = NULL;
+ sd = (SUPP_DATA_ENTRY *)OPENSSL_malloc(sizeof(SUPP_DATA_ENTRY));
+ if (sd == NULL) {
+ return(NULL);
+ }
+
+ sd->type = type;
+ sd->length = 0;
+ sd->data = NULL;
+
+ sk_SUPP_DATA_ENTRY_push(ext->client_supp_data, sd);
+
+ return sd;
+}
+
+
+/**
+ * Create a new supplemental data entry of type \p type and push it in
the \b Server stack of a ::TLSEXT_GENERAL object \p ext.
+ *
+ * We guarantee uniqness as for extensions (see
SSL_TLSEXT_GENERAL_new()).
+ *
+ * @param ssl ::SSL object containing the extension stack
+ * @param type extension type (SHOULD be defined by IANA)
+ * @return the supplemental data entry created
+ */
+SUPP_DATA_ENTRY* SSL_TLSEXT_GENERAL_server_supp_data_new(TLSEXT_GENERAL
* ext, int type) {
+ int i;
+ SUPP_DATA_ENTRY * sd = NULL;
+
+ if (ext == NULL) {
+ return NULL;
+ }
+
+ if (ext->server_supp_data == NULL) {
+ /* initialize the stack */
+ ext->server_supp_data = sk_SUPP_DATA_ENTRY_new_null();
+ if (ext->server_supp_data == NULL) {
+ return NULL;
+ }
+ }
+ else {
+ /* guarantee uniqness */
+ for (i = 0; i < sk_SUPP_DATA_ENTRY_num(ext->server_supp_data); i++) {
+ sd = sk_SUPP_DATA_ENTRY_value(ext->server_supp_data, i);
+ if (sd->type == type) {
+ return NULL;
+ }
+ }
+ }
+
+ /* add supp data */
+ sd = NULL;
+ sd = (SUPP_DATA_ENTRY *)OPENSSL_malloc(sizeof(SUPP_DATA_ENTRY));
+ if (sd == NULL) {
+ return(NULL);
+ }
+
+ sd->type = type;
+ sd->length = 0;
+ sd->data = NULL;
+
+ sk_SUPP_DATA_ENTRY_push(ext->server_supp_data, sd);
+
+ return sd;
+}
+
+
+/*********************************************************************
+ * CLIENT SIDE
+ *********************************************************************/
+
+/**
+ * Set the client data to send within the extension \p ext (Client
Hello).
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param length lenght of \p data
+ * @param data data to transmit within the extension
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_client_data(TLSEXT_GENERAL * ext, unsigned int
length, unsigned char * data) {
+ if (ext == NULL || length < 0) {
+ return(-1);
+ }
+
+ ext->client_data_length = length;
+ if (length == 0) {
+ ext->client_data = NULL;
+ }
+ else {
+ ext->client_data = (unsigned char *)OPENSSL_malloc(length);
+ if (ext->client_data == NULL) {
+ return(-1);
+ }
+ memcpy(ext->client_data, data, length);
+ }
+
+ return 0;
+}
+
+
+/**
+ * Set a client supplemental data entry related to the extension \p
ext.
+ *
+ * The supplemental data entry MUST be created with
SSL_TLSEXT_GENERAL_client_supp_data_new()
+ * before setting its payload.
+ * It will be transmitted within the Supplemental Data handshake
message.
+ *
+ * @param ext extension to set the supplemental data entry into
+ * @param type the type of the supplemental data entry. It MUST be
registered before with SSL_TLSEXT_GENERAL_client_supp_data_new()
+ * @param length lenght of \p data
+ * @param data data to transmit within the supplemental data
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_client_supp_data(TLSEXT_GENERAL * ext, int type,
unsigned int length, unsigned char * data) {
+ int i;
+ SUPP_DATA_ENTRY * sd = NULL;
+
+ if (ext == NULL || ext->client_supp_data == NULL) {
+ return(-1);
+ }
+
+ for (i = 0; i < sk_SUPP_DATA_ENTRY_num(ext->client_supp_data); i++) {
+ sd = sk_SUPP_DATA_ENTRY_value(ext->client_supp_data, i);
+
+ if (sd->type == type) {
+ sd->length = length;
+
+ if (length > 0) {
+ sd->data = (unsigned char *)OPENSSL_malloc(length);
+ if (sd->data == NULL) {
+ return(-1);
+ }
+ memcpy(sd->data, data, length);
+ }
+ else {
+ sd->data = NULL;
+ }
+
+ /* There is only one supp_data for each type */
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+
+/**
+ * Set the context data available to the client within the callback
functions.
+ * The context data can be used to exchange data from/to the
application and \p libssl
+ * and is usually used within callback functions.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param ctx_data pointer to the context data. SHOULD be casted to
<tt>(void *)</tt>
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_client_ctx_set(TLSEXT_GENERAL * ext, void *
ctx_data) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->client_ctx_data = ctx_data;
+
+ return 0;
+}
+
+
+/**
+ * Return the context data available to the client.
+ * The context data can be used to exchange data from/to the
application and \p libssl
+ * and is usually used within callback functions.
+ * The result need to be casted to the proper type.
+ *
+ * @param ext extension to get from
+ * @return the context data. It SHOULD be casted to the proper type
+ * @return \p NULL error
+ */
+void * SSL_TLSEXT_GENERAL_client_ctx_get(TLSEXT_GENERAL * ext) {
+ if (ext == NULL) {
+ return NULL;
+ }
+ return ext->client_ctx_data;
+}
+
+
+/**
+ * Set the callback function the client will use to handle the TLS
Extension \p ext
+ * (received within the Server Hello).
+ *
+ * The callback is called immediately after receiving the Server
Hello,
+ * thus before receiving any further message from the server.
+ * See ssl_parse_serverhello_tlsext_general() for more details.
+ *
+ * The callback MUST have prototype:
+ * \code
+ * void callback(SSL *, TLSEXT_GENERAL *);
+ * \endcode
+ * and MAY use context data to communication with the application.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param cb_ptr pointer to the callback function
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_client_ext_cb(TLSEXT_GENERAL * ext, void *
cb_ptr) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->client_ext_callback = cb_ptr;
+
+ return 0;
+}
+
+
+/**
+ * Set the callback function the client will use to create the
supplemental data entry
+ * to send within the client's Supplemental Data message.
+ *
+ * The callback is called immediately before sending the Supplemental
Data message
+ * and allows to access any data received from the server (e.g.
supplemental data
+ * or certificate).
+ *
+ * The callback MUST have prototype:
+ * \code
+ * void callback(SSL *, TLSEXT_GENERAL *);
+ * \endcode
+ * and MAY use context data to communication with the application.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param cb_ptr pointer to the callback function
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_client_supp_data_cb(TLSEXT_GENERAL * ext, void *
cb_ptr) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->client_supp_data_callback = cb_ptr;
+
+ return 0;
+}
+
+
+/**
+ * Set the callback function the client will use to handle the
supplemental data
+ * received from the server.
+ *
+ * The callback is called at the end of the handshake, according to RFC
4680:
+ \verbatim
+ Information provided in a supplemental data object MUST be intended
+ to be used exclusibely by applications and protocols above the TLS
+ protocol layer.  Any such data MUST NOT need to be processed by the
+ TLS protocol.
+ \endverbatim
+ *
+ * The callback MUST have prototype:
+ * \code
+ * void callback(SSL *, TLSEXT_GENERAL *);
+ * \endcode
+ * and MAY use context data to communication with the application.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param cb_ptr pointer to the callback function
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_client_finish_cb(TLSEXT_GENERAL * ext, void *
cb_ptr) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->client_finish_callback = cb_ptr;
+
+ return 0;
+}
+
+
+/*********************************************************************
+ * SERVER SIDE
+ *********************************************************************/
+
+/**
+ * Set the server data to send within the extension \p ext (Server
Hello).
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param length lenght of \p data
+ * @param data data to transmit within the extension
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_server_data(TLSEXT_GENERAL * ext, unsigned int
length, unsigned char * data) {
+ if (ext == NULL || length < 0) {
+ return(-1);
+ }
+
+ ext->server_data_length = length;
+ if (length == 0) {
+ ext->server_data = NULL;
+ }
+ else {
+ ext->server_data = (unsigned char *)OPENSSL_malloc(length);
+ if (ext->server_data == NULL) {
+ return(-1);
+ }
+ memcpy(ext->server_data, data, length);
+ }
+
+ return 0;
+}
+
+
+/**
+ * Set a server supplemental data entry related to the extension \p
ext.
+ *
+ * The supplemental data entry MUST be created with
SSL_TLSEXT_GENERAL_server_supp_data_new()
+ * before setting its payload.
+ * It will be transmitted within the Supplemental Data handshake
message.
+ *
+ * @param ext extension to set the supplemental data entry into
+ * @param type the type of the supplemental data entry. It MUST be
registered before with SSL_TLSEXT_GENERAL_server_supp_data_new()
+ * @param length lenght of \p data
+ * @param data data to transmit within the supplemental data
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_server_supp_data(TLSEXT_GENERAL * ext, int type,
unsigned int length, unsigned char * data) {
+ int i;
+ SUPP_DATA_ENTRY * sd = NULL;
+
+ if (ext == NULL || ext->server_supp_data == NULL) {
+ return(-1);
+ }
+
+ for (i = 0; i < sk_SUPP_DATA_ENTRY_num(ext->server_supp_data); i++) {
+ sd = sk_SUPP_DATA_ENTRY_value(ext->server_supp_data, i);
+
+ if (sd->type == type) {
+ sd->length = length;
+
+ if (length > 0) {
+ sd->data = (unsigned char *)OPENSSL_malloc(length);
+ if (sd->data == NULL) {
+ return(-1);
+ }
+ memcpy(sd->data, data, length);
+ }
+ else {
+ sd->data = NULL;
+ }
+
+ /* There is only one supp_data for each type */
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+
+/**
+ * Set the context data available to the server within the callback
functions.
+ * The context data can be used to exchange data from/to the
application and \p libssl
+ * and is usually used within callback functions.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param ctx_data pointer to the context data. SHOULD be casted to
<tt>(void *)</tt>
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_server_ctx_set(TLSEXT_GENERAL * ext, void *
ctx_data) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->server_ctx_data = ctx_data;
+
+ return 0;
+}
+
+
+/**
+ * Return the context data available to the server.
+ * The context data can be used to exchange data from/to the
application and \p libssl
+ * and is usually used within callback functions.
+ * The result need to be casted to the proper type.
+ *
+ * @param ext extension to get from.
+ * @return the context data. It SHOULD be casted to the proper type
+ * @return \p NULL error
+ */
+void * SSL_TLSEXT_GENERAL_server_ctx_get(TLSEXT_GENERAL * ext) {
+ if (ext == NULL) {
+ return NULL;
+ }
+ return ext->server_ctx_data;
+}
+
+
+/**
+ * Set the callback function the server will use to handle the TLS
Extension \p ext
+ * (received within the Client Hello).
+ *
+ * The callback is called immediately after receiving the Client
Hello,
+ * thus before sending the Server Hello.
+ * It is used to process the data received from the client
+ * and to create the response to send within the Server Hello.
+ * See ssl_parse_clienthello_tlsext_general() for more details.
+ *
+ * The callback MUST have prototype:
+ * \code
+ * void callback(SSL *, TLSEXT_GENERAL *);
+ * \endcode
+ * and MAY use context data to communication with the application.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param cb_ptr pointer to the callback function
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_server_ext_cb(TLSEXT_GENERAL * ext, void *
cb_ptr) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->server_ext_callback = cb_ptr;
+
+ return 0;
+}
+
+
+/**
+ * Set the callback function the server will use to create the
supplemental data entry
+ * to send within the server's Supplemental Data message.
+ *
+ * The callback is called immediately before sending the Supplemental
Data message.
+ *
+ * The callback MUST have prototype:
+ * \code
+ * void callback(SSL *, TLSEXT_GENERAL *);
+ * \endcode
+ * and MAY use context data to communication with the application.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param cb_ptr pointer to the callback function
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_server_supp_data_cb(TLSEXT_GENERAL * ext, void *
cb_ptr) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->server_supp_data_callback = cb_ptr;
+
+ return 0;
+}
+
+
+/**
+ * Set the callback function the server will use to handle the
supplemental data
+ * received from the client.
+ *
+ * The callback is called at the end of the handshake, according to RFC
4680:
+ \verbatim
+ Information provided in a supplemental data object MUST be intended
+ to be used exclusibely by applications and protocols above the TLS
+ protocol layer.  Any such data MUST NOT need to be processed by the
+ TLS protocol.
+ \endverbatim
+ *
+ * The callback MUST have prototype:
+ * \code
+ * void callback(SSL *, TLSEXT_GENERAL *);
+ * \endcode
+ * and MAY use context data to communication with the application.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @param cb_ptr pointer to the callback function
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_server_finish_cb(TLSEXT_GENERAL * ext, void *
cb_ptr) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->server_finish_callback = cb_ptr;
+
+ return 0;
+}
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL APPLICATION INTERFACE
+ *
+ *********************************************************************/
+
+/**
+ * Instruct the server to respond with the extension \p ext.
+ *
+ * It MUST be called only if the client sent the extension \p ext, so
usually
+ * by the \p server_ext_callback.
+ *
+ * This fuction is part of the Application Interface, however it SHOULD
only be used
+ * in a TLS Extension implementation.
+ * In any case it SHOULD at least be wrapped by the TLS Extension.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_server_send(TLSEXT_GENERAL * ext) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->server_send = 1;
+
+ return 0;
+}
+
+
+/**
+ * Force the client to abort the handshake if the server does not reply
with the extension \p ext.
+ *
+ * This function is part of the Application Interface,
+ * so it SHOULD be wrapped by the TLS Extension implementation.
+ *
+ * @param ext extension to set. It SHOULD be initialized with
SSL_TLSEXT_GENERAL_new()
+ * @return 0 success
+ * @return -1 error
+ */
+int SSL_TLSEXT_GENERAL_client_required(TLSEXT_GENERAL * ext) {
+ if (ext == NULL) {
+ return(-1);
+ }
+
+ ext->client_required = 1;
+
+ return 0;
+}
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL PATCH TO LIBSSL
+ *
+ *********************************************************************/
+
+/*********************************************************************
+ * t1_lib.c
+ *********************************************************************/
+
+/**
+ * Process the extensions within the ::SSL object \p s and append their
content
+ * to the buffer \p p, thus generating the payload for the Client Hello
message.
+ *
+ * This is a patch to ssl_add_clienthello_tlsext() (\p libssl), from
which inherits the prototype.
+ * @TODO: include within \p libssl.
+ */
+unsigned char * ssl_add_clienthello_tlsext_general(SSL *s, unsigned
char *p, unsigned char *limit) {
+ int i;
+ TLSEXT_GENERAL *e;
+ unsigned char * ret = p;
+
+ if (ret>=limit) return NULL; /* this really never occurs, but ... */
+
+ /* Parsing the STACK */
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+
+ /* Check for enough space:
+ * - 2 for the type of the extension
+ * - 2 for the size of the extension
+ * - e->client_data_length for the actual data
+ */
+ if ((long)(limit - ret - 4 - (e->client_data_length)) < 0)
+ return NULL;
+
+ s2n (e->type, ret); /* type of the extension */
+ s2n (e->client_data_length, ret); /* length of the extension */
+
+ memcpy (ret, e->client_data, e->client_data_length); /* actual data
of the extension */
+ ret += e->client_data_length;
+
+ /* Usefull if the same connection is used many time.
+ * See SSL_clear()
+ * TODO: maybe to move within SSL_clear()?
+ */
+ e->received = 0;
+ }
+
+ return ret;
+}
+
+
+/**
+ * Process the extensions within the ::SSL object \p s and append their
content
+ * to the buffer \p p, thus generating the payload for the Server Hello
message.
+ *
+ * This is a patch to ssl_add_serverhello_tlsext() (\p libssl), from
which inherits the prototype.
+ * @TODO: include within \p libssl.
+ */
+unsigned char * ssl_add_serverhello_tlsext_general(SSL *s, unsigned
char *p, unsigned char *limit) {
+ int i;
+ TLSEXT_GENERAL *e;
+ unsigned char * ret = p;
+
+ if (ret>=limit) return NULL; /* this really never occurs, but ... */
+
+ /* Parsing the STACK */
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+
+ if (e->server_send) {
+ /* Check for enough space:
+ * - 2 for the type of the extension
+ * - 2 for the size of the extension
+ * - e->server_data_length for the actual data
+ */
+ if ((long)(limit - ret - 4 - (e->server_data_length)) < 0)
+ return NULL;
+
+ s2n (e->type, ret); /* type of the extension */
+ s2n (e->server_data_length, ret); /* length of the extension */
+
+ memcpy (ret, e->server_data, e->server_data_length); /* actual data
of the extension */
+ ret += e->server_data_length;
+
+ /* Usefull if the same connection is used many time.
+ * See SSL_clear()
+ * TODO: maybe to move within SSL_clear()?
+ */
+ e->received = 0;
+ }
+ }
+
+ return ret;
+}
+
+
+/**
+ * Handle an extension received in the Client Hello message
+ * and specified in TLV format (\p type, \p size, \p data),
+ * add it to the stack of received extensions
+ * and call the related callback function.
+ *
+ * This is a patch to ssl_parse_clienthello_tlsext() (\p libssl), from
which inherits the prototype.
+ * @TODO: include within \p libssl.
+ * @TODO: MUST be the last extension type to parse.
+ */
+int ssl_parse_clienthello_tlsext_general(SSL *s, unsigned short type,
unsigned short size, unsigned char *data) {
+ int i;
+ TLSEXT_GENERAL * e;
+ void (*pt_func) (SSL *, TLSEXT_GENERAL *) = NULL;
+
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e != NULL && e->type == type) {
+
+ /* Check if the ext was not already received
+ *
+ * RFC4366:
+ * There MUST NOT be more than one extension of the same type.
+ */
+ if (e->received != 0)
+ return 0;
+
+ /* set client data */
+ if (SSL_TLSEXT_GENERAL_client_data(e, size, data) < 0)
+ return 0;
+
+ e->received = 1;
+
+ /* call server callback */
+ if ((pt_func = (void *) e->server_ext_callback) != NULL)
+ (*pt_func) (s, e);
+
+ return 1;
+ }
+ }
+
+ /* extension not found within the stack */
+ return -1;
+}
+
+
+/**
+ * Handle an extension received in the Server Hello message
+ * and specified in TLV format (\p type, \p size, \p data),
+ * add it to the stack of received General Extensions
+ * and call the related callback function.
+ *
+ * This is a patch to ssl_parse_serverhello_tlsext() (\p libssl), from
which inherits the prototype.
+ * @TODO: include within \p libssl.
+ * @TODO: MUST be the last extension type to parse.
+ */
+int ssl_parse_serverhello_tlsext_general(SSL *s, unsigned short type,
unsigned short size, unsigned char *data) {
+ int i;
+ TLSEXT_GENERAL * e;
+ void (*pt_func) (SSL *, TLSEXT_GENERAL *) = NULL;
+
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e != NULL && e->type == type) {
+
+ /* Check if the ext was not already received
+ *
+ * RFC4366:
+ * There MUST NOT be more than one extension of the same type.
+ */
+ if (e->received != 0)
+ return 0;
+
+ /* set client data */
+ if(SSL_TLSEXT_GENERAL_server_data(e, size, data) < 0)
+ return 0;
+
+ e->received = 1;
+
+ /* call server callback */
+ if( (pt_func = (void *) e->client_ext_callback) != NULL)
+ (*pt_func) (s, e);
+
+ return 1;
+ }
+ }
+
+ /* extension not found within the stack */
+ return -1;
+}
+
+
+/**
+ * Check for required extensions.
+ *  
+ * This function is used by the client to verify if any extension
flagged
+ * as "required" was not received from the server. In this case the
+ * handshake is aborted.
+ *
+ * This is a patch to ssl_parse_serverhello_tlsext() (\p libssl).
+ *
+ * RFC 4366:
+ \verbatim
+ In the event that a client requests additional functionality using
+ the extended client hello, and this functionality is not supplied by
+ the server, the client MAY abort the handshake.
+ \endverbatim
+ *
+ * If the client does not want to abort the handshake, it has not
+ * to flag the extension as required.
+ */
+int ssl_parse_serverhello_tlsext_general_required (SSL * s) {
+ int i;
+ TLSEXT_GENERAL * e;
+
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e->client_required == 1 && e->received == 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/*********************************************************************
+ * s3_clnt.c
+ *********************************************************************/
+
+/**
+ * Receive the server SupplementalData handshake message (if any).
+ *  
+ * This is a patch to ssl3_connect() (\p libssl).
+ *
+ * Differences between ssl3_get_server_supp_data() and
ssl3_get_client_supp_data():
+ * -# Condition to select the extensions pool: <tt>(ext->received ==
1)</tt> vs <tt>(ext->server_send == 1)</tt>.
+ * -# Supplemental data entry pool: <tt>ext->client_supp_data</tt> vs
<tt>ext->server_supp_data</tt>.
+ * -# Parameters of <tt>s->method->ssl_get_message</tt>.
+ * -# Call to ssl3_get_server_supp_data() vs
ssl3_get_client_supp_data().
+ */
+int ssl3_get_server_supp_data(SSL * s) {
+ int i, j, hit = 0;
+ int ok;
+ long n;
+ TLSEXT_GENERAL * e, * ext;
+ SUPP_DATA_ENTRY * sd;
+ unsigned char * p;
+ unsigned short n_type = 0, n_length = 0;
+
+ /* error since s and s->tlsext_general SHOULD be initialized */
+ if (s == NULL || s->tlsext_general == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e->received == 1 && e->server_supp_data != NULL) {
+ hit = 1;
+ break;
+ }
+ }
+
+ if (hit == 0) {
+ return 1;
+ }
+
+ n = s->method->ssl_get_message(s,
+ SSL3_ST_CR_SRVR_SUPP_DATA_A,
+ SSL3_ST_CR_SRVR_SUPP_DATA_A,
+ TLS1_MT_SUPPLEMENTAL_DATA,
+ ((1 << 24) - 1), /*TODO check the correct length from RFC4680 */
+ &ok
+ );
+
+ if (!ok || s->init_msg == NULL) {
+ return -1;
+ }
+
+ p = s->init_msg;
+
+ while (n > 0) {
+ n2s(p,n_type);
+ n2s(p,n_length);
+
+ /* find the right supp data and related extension */
+ for (hit = i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++)
{
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e->received == 1 && e->server_supp_data != NULL) {
+ for (j = 0; j < sk_SUPP_DATA_ENTRY_num(e->server_supp_data); j++) {
+ sd = sk_SUPP_DATA_ENTRY_value(e->server_supp_data, j);
+ if (sd->type == n_type) {
+ hit = 1;
+ ext = e;
+ break;
+ }
+ }
+ }
+ }
+
+ /* non-expected supp data entry received */
+ if (hit == 0) {
+ return -1;
+ }
+
+ /* copy data within the server supp data stack of e */
+ if (SSL_TLSEXT_GENERAL_server_supp_data(ext, n_type, n_length, p) <
0) {
+ return -1;
+ }
+
+ p += n_length;
+ n -= (n_length + 4);
+ }
+
+ /* Should never happens, but... */
+ if (n < 0) {
+ return -1;
+ }
+
+ return 1;
+}
+
+
+/**
+ * Send the client SupplementalData handshake message (if any).
+ *  
+ * This is a patch to ssl3_connect() (\p libssl).
+ *
+ * Differences between ssl3_send_client_supp_data() and
ssl3_send_server_supp_data():
+ * -# Condition to select the extensions pool: <tt>(ext->received ==
1)</tt> vs <tt>(ext->server_send == 1)</tt>.
+ * -# Supplemental data entry pool: <tt>ext->client_supp_data</tt> vs
<tt>ext->server_supp_data</tt>.
+ * -# The callback to invoke: <tt>ext->client_supp_data_callback()</tt>
vs <tt>ext->server_supp_data_callback</tt>.
+ */
+int ssl3_send_client_supp_data(SSL * s) {
+ int i, j;
+ int hit = 0, ret;
+ TLSEXT_GENERAL * e;
+ void (*pt_func) (SSL *, TLSEXT_GENERAL *) = NULL;
+ SUPP_DATA_ENTRY * sd;
+ unsigned char * p;
+ unsigned short n_type = 0, n_length = 0;
+
+ /* error since s and s->tlsext_general SHOULD be initialized */
+ if (s == NULL || s->tlsext_general == NULL) {
+ return -1;
+ }
+
+ p = (unsigned char *) s->init_buf->data;
+ s->init_num = 0;
+ p += 4; /* leave space for type and length of SupplementalData
handshake message */
+
+ /* for each extension the server agreed on... */
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+
+ if (e->received == 1 && e->client_supp_data != NULL) {
+ /* we have supp data to send */
+ hit = 1;
+
+ /* first we call the callback */
+ if( (pt_func = (void *) e->client_supp_data_callback) != NULL)
+ (*pt_func) (s, e);
+
+ /*TODO
+ * 1. ext->client_supp_data COULD be != NULL but empty, in case of
error... Check!
+ * 2. RFC4680:
+ *    If present, the SupplementalData handshake message MUST
contain a
+ *    non-empty SupplementalDataEntry structure [...]
+ * What does empty means? lengh = 0 is or not empty? For us not
empty. Check!
+ */
+ /* ...for each supp data entry of that extension... */
+ for (j = 0; j < sk_SUPP_DATA_ENTRY_num(e->client_supp_data); j++) {
+ sd = sk_SUPP_DATA_ENTRY_value(e->client_supp_data, j);
+
+ n_type = (unsigned short) sd->type;
+ n_length = (unsigned short) sd->length;
+
+ /* type */
+ s2n(n_type,p);
+
+ /* length */
+ s2n(n_length,p);
+
+ /* value */
+ if (sd->length > 0) {
+ memcpy(p, sd->data, sd->length);
+ p += sd->length;
+ }
+
+ s->init_num += sd->length + 4;
+ }
+ }
+ }
+
+ if (hit == 1) {
+ p = (unsigned char *) s->init_buf->data;
+
+ /* type */
+ (*p) = TLS1_MT_SUPPLEMENTAL_DATA;
+ p ++;
+
+ /* length */
+ l2n3(s->init_num,p);
+
+ s->init_num += 4;
+ ret = ssl3_do_write (s, SSL3_RT_HANDSHAKE);
+
+ return ret;
+ }
+
+ /* no supp data to send */
+ return 1;
+}
+
+
+/**
+ * For each negotiated extension, invoke the client finish callback.
+ *
+ * This is a patch to ssl3_connect() (\p libssl).
+ *
+ * The callbacks are invoked at the end of the handshake, according to
+ * RFC 4680:
+ \verbatim
+ Information provided in a supplemental data object MUST be intended
+ to be used exclusibely by applications and protocols above the TLS
+ protocol layer.  Any such data MUST NOT need to be processed by the
+ TLS protocol.
+ \endverbatim
+ */
+int ssl_tlsext_general_client_finish_cb(SSL * s) {
+ int i;
+ TLSEXT_GENERAL * e;
+ void (*pt_func) (SSL *, TLSEXT_GENERAL *) = NULL;
+
+ /* error since s and s->tlsext_general SHOULD be initialized */
+ if (s == NULL || s->tlsext_general == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e->received == 1 && e->client_finish_callback != NULL) {
+ /* invoke the callback */
+ if( (pt_func = (void *) e->client_finish_callback) != NULL)
+ (*pt_func) (s, e);
+ }
+ }
+
+ return 1;
+}
+
+
+/*********************************************************************
+ * s3_srvr.c
+ *********************************************************************/
+
+/**
+ * Send the server SupplementalData handshake message (if any).
+ *  
+ * This is a patch to ssl3_accept() (\p libssl).
+ *
+ * Differences between ssl3_send_client_supp_data() and
ssl3_send_server_supp_data():
+ * -# Condition to select the extensions pool: <tt>(ext->received ==
1)</tt> vs <tt>(ext->server_send == 1)</tt>.
+ * -# Supplemental data entry pool: <tt>ext->client_supp_data</tt> vs
<tt>ext->server_supp_data</tt>.
+ * -# The callback to invoke: <tt>ext->client_supp_data_callback()</tt>
vs <tt>ext->server_supp_data_callback</tt>.
+ */
+int ssl3_send_server_supp_data(SSL * s) {
+ int i, j;
+ int hit = 0, ret;
+ TLSEXT_GENERAL * e;
+ void (*pt_func) (SSL *, TLSEXT_GENERAL *) = NULL;
+ SUPP_DATA_ENTRY * sd;
+ unsigned char * p;
+ unsigned short n_type = 0, n_length = 0;
+
+ /* error since s and s->tlsext_general SHOULD be initialized */
+ if (s == NULL || s->tlsext_general == NULL) {
+ return -1;
+ }
+
+ p = (unsigned char *) s->init_buf->data;
+ s->init_num = 0;
+ p += 4; /* leave space for type and length of SupplementalData
handshake message */
+
+ /* for each extension the server agreed on... */
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+
+ if (e->server_send == 1 && e->server_supp_data != NULL) {
+ /* we have supp data to send */
+ hit = 1;
+
+ /* first we call the callback */
+ if( (pt_func = (void *) e->server_supp_data_callback) != NULL)
+ (*pt_func) (s, e);
+
+ /*TODO
+ * 1. ext->client_supp_data COULD be != NULL but empty, in case of
error... Check!
+ * 2. RFC4680:
+ *    If present, the SupplementalData handshake message MUST
contain a
+ *    non-empty SupplementalDataEntry structure [...]
+ * What does empty means? lengh = 0 is or not empty? For us not
empty. Check!
+ */
+ /* ...for each supp data entry of that extension... */
+ for (j = 0; j < sk_SUPP_DATA_ENTRY_num(e->server_supp_data); j++) {
+ sd = sk_SUPP_DATA_ENTRY_value(e->server_supp_data, j);
+
+ n_type = (unsigned short) sd->type;
+ n_length = (unsigned short) sd->length;
+
+ /* type */
+ s2n(n_type,p);
+
+ /* length */
+ s2n(n_length,p);
+
+ /* value */
+ if (sd->length > 0) {
+ memcpy(p, sd->data, sd->length);
+ p += sd->length;
+ }
+
+ s->init_num += sd->length + 4;
+ }
+ }
+ }
+
+ if (hit == 1) {
+ p = (unsigned char *) s->init_buf->data;
+
+ /* type */
+ (*p) = TLS1_MT_SUPPLEMENTAL_DATA;
+ p ++;
+
+ /* length */
+ l2n3(s->init_num,p);
+
+ s->init_num += 4;
+ ret = ssl3_do_write (s, SSL3_RT_HANDSHAKE);
+
+ return ret;
+ }
+
+ /* no supp data to send */
+ return 1;
+}
+
+
+/**
+ * Receive the client SupplementalData handshake message (if any).
+ *  
+ * This is a patch to ssl3_accept() (\p libssl).
+ *
+ * Differences between ssl3_get_server_supp_data() and
ssl3_get_client_supp_data():
+ * -# Condition to select the extensions pool: <tt>(ext->received ==
1)</tt> vs <tt>(ext->server_send == 1)</tt>.
+ * -# Supplemental data entry pool: <tt>ext->client_supp_data</tt> vs
<tt>ext->server_supp_data</tt>.
+ * -# Parameters of <tt>s->method->ssl_get_message</tt>.
+ * -# Call to ssl3_get_server_supp_data() vs
ssl3_get_client_supp_data().
+ */
+int ssl3_get_client_supp_data(SSL * s) {
+ int i, j, hit = 0;
+ int ok;
+ long n;
+ TLSEXT_GENERAL * e, * ext;
+ SUPP_DATA_ENTRY * sd;
+ unsigned char * p;
+ unsigned short n_type = 0, n_length = 0;
+
+ /* error since s and s->tlsext_general SHOULD be initialized */
+ if (s == NULL || s->tlsext_general == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e->server_send == 1 && e->client_supp_data != NULL) {
+ hit = 1;
+ break;
+ }
+ }
+
+ if (hit == 0) {
+ return 1;
+ }
+
+ n = s->method->ssl_get_message(s,
+ SSL3_ST_SR_CLNT_SUPP_DATA_A,
+ SSL3_ST_SR_CLNT_SUPP_DATA_A,
+ TLS1_MT_SUPPLEMENTAL_DATA,
+ ((1 << 24) - 1), /*TODO check the correct length from RFC4680 */
+ &ok
+ );
+
+ if (!ok || s->init_msg == NULL) {
+ return -1;
+ }
+
+ p = s->init_msg;
+
+ while (n > 0) {
+ n2s(p,n_type);
+ n2s(p,n_length);
+
+ /* find the right supp data and related extension */
+ for (hit = i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++)
{
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e->server_send == 1 && e->client_supp_data != NULL) {
+ for (j = 0; j < sk_SUPP_DATA_ENTRY_num(e->client_supp_data); j++) {
+ sd = sk_SUPP_DATA_ENTRY_value(e->client_supp_data, j);
+ if (sd->type == n_type) {
+ hit = 1;
+ ext = e;
+ break;
+ }
+ }
+ }
+ }
+
+ /* non-expected supp data entry received */
+ if (hit == 0) {
+ return -1;
+ }
+
+ /* copy data within the client supp data stack of e */
+ if (SSL_TLSEXT_GENERAL_client_supp_data(ext, n_type, n_length, p) <
0) {
+ return -1;
+ }
+
+ p += n_length;
+ n -= (n_length + 4);
+ }
+
+ /* Should never happens, but... */
+ if (n < 0) {
+ return -1;
+ }
+
+ return 1;
+}
+
+
+/**
+ * For each negotiated extension, invoke the server finish callback.
+ *
+ * This is a patch to ssl3_accept() (\p libssl).
+ *
+ * The callbacks are invoked at the end of the handshake, according to
+ * RFC 4680:
+ \verbatim
+ Information provided in a supplemental data object MUST be intended
+ to be used exclusibely by applications and protocols above the TLS
+ protocol layer.  Any such data MUST NOT need to be processed by the
+ TLS protocol.
+ \endverbatim
+ */
+int ssl_tlsext_general_server_finish_cb(SSL * s) {
+ int i;
+ TLSEXT_GENERAL * e;
+ void (*pt_func) (SSL *, TLSEXT_GENERAL *) = NULL;
+
+ /* error since s and s->tlsext_general SHOULD be initialized */
+ if (s == NULL || s->tlsext_general == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < sk_TLSEXT_GENERAL_num(s->tlsext_general); i++) {
+ e = sk_TLSEXT_GENERAL_value(s->tlsext_general, i);
+ if (e->server_send == 1 && e->server_finish_callback != NULL) {
+ /* invoke the callback */
+ if( (pt_func = (void *) e->server_finish_callback) != NULL)
+ (*pt_func) (s, e);
+ }
+ }
+
+ return 1;
+}
+
+
+#endif /*OPENSSL_NO_TLSEXT_GENERAL*/
diff -urN openssl-SNAP-20081204/ssl/t1_ext.h o-tlsext/ssl/t1_ext.h
--- openssl-SNAP-20081204/ssl/t1_ext.h 1970-01-01 01:00:00.000000000
+0100
+++ o-tlsext/ssl/t1_ext.h 2008-12-11 12:56:55.000000000 +0100
@@ -0,0 +1,372 @@
+/* ssl/t1_ext.h */
+/* Copyright (C) 1995-1998 Eric Young ([hidden email])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([hidden email]).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long
as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL
documentation
+ * included with this distribution is covered by the same copyright
terms
+ * except that the holder is Tim Hudson ([hidden email]).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given
attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young ([hidden email])"
+ *    The word 'cryptographic' can be left out if the rouines from the
library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative
thereof) from
+ *    the apps directory (application code) you must include an
acknowledgement:
+ *    "This product includes software written by Tim Hudson
([hidden email])"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available
version or
+ * derivative of this code cannot be changed.  i.e. this code cannot
simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2008 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
+ *    [hidden email].
+ *
+ * 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
+ * ([hidden email]).  This product includes software written by Tim
+ * Hudson ([hidden email]).
+ *
+ */
+/* ====================================================================
+ * Copyright (C) 2008 Davide Vernizzi and Emanuele Cesena
([hidden email])
+ * All rights reserved.
+ *
+ * General TLS Extension framework, implementing RFC 4366 and RFC 4680.
+ */
+#ifndef HEADER_T1_EXT_H
+#define HEADER_T1_EXT_H
+
+/* Disable TLSEXT_GENERAL if TLSEXT are disabled */
+#ifdef OPENSSL_NO_TLSEXT
+#define OPENSSL_NO_TLSEXT_GENERAL
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+
+/** \defgroup TLSEXT_GENERAL General TLS Extensions framework
+ General framework for TLS Extensions (RFC 4366) and Supplemental Data
(RFC 4680) support.
+ */
+/*@{*/
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL CORE
+ *
+ *********************************************************************/
+
+/** \defgroup TLSEXT_GENERAL_core Core
+ Core functions and data structures.
+ */
+/*@{*/
+
+/*********************************************************************
+ * DATA STRUCTURES
+ *********************************************************************/
+
+typedef struct tlsext_general_st TLSEXT_GENERAL;
+typedef struct supp_data_entry_st SUPP_DATA_ENTRY;
+
+/**
+ * Object to handle TLS Extensions defined in RFC 4366
+ * and supplemental data defined in RFC 4680.
+ * By RFC 4680, supplemental data MUST be negotiated using a TLS
Extension.
+ * This object contains a single extension (possibly with related
supplemental data)
+ * and the ::SSL object contains a stack of ::TLSEXT_GENERAL.
+ */
+struct tlsext_general_st {
+ int type;
+
+ /* client data */
+ unsigned int client_data_length;
+ unsigned char * client_data;
+ void * client_ctx_data;
+
+ /* server data */
+ unsigned int server_data_length;
+ unsigned char * server_data;
+ void * server_ctx_data;
+
+ /* supplemental data */
+ STACK_OF(SUPP_DATA_ENTRY) * client_supp_data;
+ STACK_OF(SUPP_DATA_ENTRY) * server_supp_data;
+
+ /* flags */
+ int client_required; /* tell if the client has to abort in case the
server ignores the extension */
+ int server_send; /* tell if the server should send this extension */
+ int received; /* tell if the extension has been received:
+   used both to check for duplicates
+   and to have a list of the extensions negotiated */
+
+ /* client callbacks */
+ void (*client_ext_callback)(void *, struct tlsext_general_st *);
+ void (*client_supp_data_callback)(void *, struct tlsext_general_st *);
+ void (*client_finish_callback)(void *, struct tlsext_general_st *);
+
+ /* server callbacks */
+ void (*server_ext_callback)(void *, struct tlsext_general_st *);
+ void (*server_supp_data_callback)(void *, struct tlsext_general_st *);
+ void (*server_finish_callback)(void *, struct tlsext_general_st *);
+};
+
+
+/**
+ * Object to handle a single Supplemental Data Entry as defined in RFC
4680.
+ * It is described in TLV format (resp. \p type, \p length, \p data).
+ */
+struct supp_data_entry_st {
+ int type;
+ int length;
+ unsigned char * data;
+};
+
+
+/*********************************************************************
+ * STACKS
+ *********************************************************************/
+
+DECLARE_STACK_OF(TLSEXT_GENERAL)
+
+#define sk_TLSEXT_GENERAL_new(st) SKM_sk_new(TLSEXT_GENERAL, (st))
+#define sk_TLSEXT_GENERAL_new_null() SKM_sk_new_null(TLSEXT_GENERAL)
+#define sk_TLSEXT_GENERAL_free(st) SKM_sk_free(TLSEXT_GENERAL, (st))
+#define sk_TLSEXT_GENERAL_num(st) SKM_sk_num(TLSEXT_GENERAL, (st))
+#define sk_TLSEXT_GENERAL_value(st, i) SKM_sk_value(TLSEXT_GENERAL,
(st), (i))
+#define sk_TLSEXT_GENERAL_set(st, i, val) SKM_sk_set(TLSEXT_GENERAL,
(st), (i), (val))
+#define sk_TLSEXT_GENERAL_zero(st) SKM_sk_zero(TLSEXT_GENERAL, (st))
+#define sk_TLSEXT_GENERAL_push(st, val) SKM_sk_push(TLSEXT_GENERAL,
(st), (val))
+#define sk_TLSEXT_GENERAL_unshift(st, val)
SKM_sk_unshift(TLSEXT_GENERAL, (st), (val))
+#define sk_TLSEXT_GENERAL_find(st, val) SKM_sk_find(TLSEXT_GENERAL,
(st), (val))
+#define sk_TLSEXT_GENERAL_find_ex(st, val)
SKM_sk_find_ex(TLSEXT_GENERAL, (st), (val))
+#define sk_TLSEXT_GENERAL_delete(st, i) SKM_sk_delete(TLSEXT_GENERAL,
(st), (i))
+#define sk_TLSEXT_GENERAL_delete_ptr(st, ptr)
SKM_sk_delete_ptr(TLSEXT_GENERAL, (st), (ptr))
+#define sk_TLSEXT_GENERAL_insert(st, val, i)
SKM_sk_insert(TLSEXT_GENERAL, (st), (val), (i))
+#define sk_TLSEXT_GENERAL_set_cmp_func(st, cmp)
SKM_sk_set_cmp_func(TLSEXT_GENERAL, (st), (cmp))
+#define sk_TLSEXT_GENERAL_dup(st) SKM_sk_dup(TLSEXT_GENERAL, st)
+#define sk_TLSEXT_GENERAL_pop_free(st, free_func)
SKM_sk_pop_free(TLSEXT_GENERAL, (st), (free_func))
+#define sk_TLSEXT_GENERAL_shift(st) SKM_sk_shift(TLSEXT_GENERAL, (st))
+#define sk_TLSEXT_GENERAL_pop(st) SKM_sk_pop(TLSEXT_GENERAL, (st))
+#define sk_TLSEXT_GENERAL_is_sorted(st)
SKM_sk_is_sorted(TLSEXT_GENERAL, (st))
+
+DECLARE_STACK_OF(SUPP_DATA_ENTRY)
+
+#define sk_SUPP_DATA_ENTRY_new(st) SKM_sk_new(SUPP_DATA_ENTRY, (st))
+#define sk_SUPP_DATA_ENTRY_new_null() SKM_sk_new_null(SUPP_DATA_ENTRY)
+#define sk_SUPP_DATA_ENTRY_free(st) SKM_sk_free(SUPP_DATA_ENTRY, (st))
+#define sk_SUPP_DATA_ENTRY_num(st) SKM_sk_num(SUPP_DATA_ENTRY, (st))
+#define sk_SUPP_DATA_ENTRY_value(st, i) SKM_sk_value(SUPP_DATA_ENTRY,
(st), (i))
+#define sk_SUPP_DATA_ENTRY_set(st, i, val) SKM_sk_set(SUPP_DATA_ENTRY,
(st), (i), (val))
+#define sk_SUPP_DATA_ENTRY_zero(st) SKM_sk_zero(SUPP_DATA_ENTRY, (st))
+#define sk_SUPP_DATA_ENTRY_push(st, val) SKM_sk_push(SUPP_DATA_ENTRY,
(st), (val))
+#define sk_SUPP_DATA_ENTRY_unshift(st, val)
SKM_sk_unshift(SUPP_DATA_ENTRY, (st), (val))
+#define sk_SUPP_DATA_ENTRY_find(st, val) SKM_sk_find(SUPP_DATA_ENTRY,
(st), (val))
+#define sk_SUPP_DATA_ENTRY_find_ex(st, val)
SKM_sk_find_ex(SUPP_DATA_ENTRY, (st), (val))
+#define sk_SUPP_DATA_ENTRY_delete(st, i) SKM_sk_delete(SUPP_DATA_ENTRY,
(st), (i))
+#define sk_SUPP_DATA_ENTRY_delete_ptr(st, ptr)
SKM_sk_delete_ptr(SUPP_DATA_ENTRY, (st), (ptr))
+#define sk_SUPP_DATA_ENTRY_insert(st, val, i)
SKM_sk_insert(SUPP_DATA_ENTRY, (st), (val), (i))
+#define sk_SUPP_DATA_ENTRY_set_cmp_func(st, cmp)
SKM_sk_set_cmp_func(SUPP_DATA_ENTRY, (st), (cmp))
+#define sk_SUPP_DATA_ENTRY_dup(st) SKM_sk_dup(SUPP_DATA_ENTRY, st)
+#define sk_SUPP_DATA_ENTRY_pop_free(st, free_func)
SKM_sk_pop_free(SUPP_DATA_ENTRY, (st), (free_func))
+#define sk_SUPP_DATA_ENTRY_shift(st) SKM_sk_shift(SUPP_DATA_ENTRY,
(st))
+#define sk_SUPP_DATA_ENTRY_pop(st) SKM_sk_pop(SUPP_DATA_ENTRY, (st))
+#define sk_SUPP_DATA_ENTRY_is_sorted(st)
SKM_sk_is_sorted(SUPP_DATA_ENTRY, (st))
+
+/*********************************************************************
+ * FUNCTIONS
+ *********************************************************************/
+
+void SSL_TLSEXT_GENERAL_free(TLSEXT_GENERAL * ext);
+void SSL_SUPP_DATA_ENTRY_free(SUPP_DATA_ENTRY * sd);
+
+/*@}*/
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL INTERFACE
+ *
+ *********************************************************************/
+
+/** \defgroup TLSEXT_GENERAL_iface Interface
+ Main interface to build TLS Extensions on.
+ */
+/*@{*/
+
+/*********************************************************************
+ * CREATION
+ *********************************************************************/
+TLSEXT_GENERAL* SSL_TLSEXT_GENERAL_new(SSL * ssl, int type);
+SUPP_DATA_ENTRY* SSL_TLSEXT_GENERAL_client_supp_data_new(TLSEXT_GENERAL
* ext, int type);
+SUPP_DATA_ENTRY* SSL_TLSEXT_GENERAL_server_supp_data_new(TLSEXT_GENERAL
* ext, int type);
+
+
+/*********************************************************************
+ * CLIENT SIDE
+ *********************************************************************/
+int SSL_TLSEXT_GENERAL_client_data(TLSEXT_GENERAL * ext, unsigned int
length, unsigned char * data);
+int SSL_TLSEXT_GENERAL_client_supp_data(TLSEXT_GENERAL * ext, int type,
unsigned int length, unsigned char * data);
+int SSL_TLSEXT_GENERAL_client_ctx_set(TLSEXT_GENERAL * ext, void *
ctx_data);
+void * SSL_TLSEXT_GENERAL_client_ctx_get(TLSEXT_GENERAL * ext);
+
+int SSL_TLSEXT_GENERAL_client_ext_cb(TLSEXT_GENERAL * ext, void *
cb_ptr);
+int SSL_TLSEXT_GENERAL_client_supp_data_cb(TLSEXT_GENERAL * ext, void *
cb_ptr);
+int SSL_TLSEXT_GENERAL_client_finish_cb(TLSEXT_GENERAL * ext, void *
cb_ptr);
+
+
+/*********************************************************************
+ * SERVER SIDE
+ *********************************************************************/
+int SSL_TLSEXT_GENERAL_server_data(TLSEXT_GENERAL * ext, unsigned int
length, unsigned char * data);
+int SSL_TLSEXT_GENERAL_server_supp_data(TLSEXT_GENERAL * ext, int type,
unsigned int length, unsigned char * data);
+int SSL_TLSEXT_GENERAL_server_ctx_set(TLSEXT_GENERAL * ext, void *
ctx_data);
+void * SSL_TLSEXT_GENERAL_server_ctx_get(TLSEXT_GENERAL * ext);
+
+int SSL_TLSEXT_GENERAL_server_ext_cb(TLSEXT_GENERAL * ext, void *
cb_ptr);
+int SSL_TLSEXT_GENERAL_server_supp_data_cb(TLSEXT_GENERAL * ext, void *
cb_ptr);
+int SSL_TLSEXT_GENERAL_server_finish_cb(TLSEXT_GENERAL * ext, void *
cb_ptr);
+
+/*@}*/
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL APPLICATION INTERFACE
+ *
+ *********************************************************************/
+
+/** \defgroup TLSEXT_GENERAL_appiface Application Interface
+ Subset of the \ref TLSEXT_GENERAL_appiface "Interface" any TLS
Extension SHOULD provide to the application.
+ */
+/*@{*/
+
+int SSL_TLSEXT_GENERAL_server_send(TLSEXT_GENERAL * ext);
+int SSL_TLSEXT_GENERAL_client_required(TLSEXT_GENERAL * ext);
+
+/*@}*/
+
+
+/*********************************************************************
+ *
+ * TLSEXT_GENERAL PATCH TO LIBSSL
+ *
+ *********************************************************************/
+
+/** \defgroup TLSEXT_GENERAL_patch Patch to libssl
+ Patch to the existant \p libssl. These functions SHOULD be included in
the \p libssl code.
+ */
+/*@{*/
+
+
+/*********************************************************************
+ * t1_lib.c
+ *********************************************************************/
+unsigned char * ssl_add_clienthello_tlsext_general(SSL *s, unsigned
char *p, unsigned char *limit);
+unsigned char * ssl_add_serverhello_tlsext_general(SSL *s, unsigned
char *p, unsigned char *limit);
+int ssl_parse_clienthello_tlsext_general(SSL *s, unsigned short type,
unsigned short size, unsigned char *data);
+int ssl_parse_serverhello_tlsext_general(SSL *s, unsigned short type,
unsigned short size, unsigned char *data);
+int ssl_parse_serverhello_tlsext_general_required (SSL * s);
+
+
+/*********************************************************************
+ * s3_clnt.c
+ *********************************************************************/
+int ssl3_get_server_supp_data(SSL * s);
+int ssl3_send_client_supp_data(SSL * s);
+int ssl_tlsext_general_client_finish_cb(SSL * s);
+
+
+/*********************************************************************
+ * s3_srvr.c
+ *********************************************************************/
+int ssl3_send_server_supp_data(SSL * s);
+int ssl3_get_client_supp_data(SSL * s);
+int ssl_tlsext_general_server_finish_cb(SSL * s);
+
+/*@}*/
+
+/*@}*/
+
+#endif /*OPENSSL_NO_TLSEXT_GENERAL*/
+
+#endif /*HEADER_T1_EXT_H*/
diff -urN openssl-SNAP-20081204/ssl/t1_ext_test.c
o-tlsext/ssl/t1_ext_test.c
--- openssl-SNAP-20081204/ssl/t1_ext_test.c 1970-01-01
01:00:00.000000000 +0100
+++ o-tlsext/ssl/t1_ext_test.c 2008-12-11 13:02:37.000000000 +0100
@@ -0,0 +1,251 @@
+/* ssl/t1_ext_test.c */
+/* Copyright (C) 1995-1998 Eric Young ([hidden email])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([hidden email]).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long
as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL
documentation
+ * included with this distribution is covered by the same copyright
terms
+ * except that the holder is Tim Hudson ([hidden email]).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given
attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young ([hidden email])"
+ *    The word 'cryptographic' can be left out if the rouines from the
library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative
thereof) from
+ *    the apps directory (application code) you must include an
acknowledgement:
+ *    "This product includes software written by Tim Hudson
([hidden email])"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available
version or
+ * derivative of this code cannot be changed.  i.e. this code cannot
simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2008 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
+ *    [hidden email].
+ *
+ * 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
+ * ([hidden email]).  This product includes software written by Tim
+ * Hudson ([hidden email]).
+ *
+ */
+/* ====================================================================
+ * Copyright (C) 2008 Davide Vernizzi and Emanuele Cesena
([hidden email])
+ * All rights reserved.
+ *
+ * General TLS Extension framework, implementing RFC 4366 and RFC 4680.
+ */
+#include "t1_ext_test.h"
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+
+/*
+ * Please look at the manual for documentation
+ */
+
+/*********************************************************************
+ * CLIENT SIDE
+ *********************************************************************/
+
+void SSL_TLSEXT_TEST_client_init(SSL * s) {
+ TLSEXT_GENERAL * e;
+
+ /* a very simple extension */
+ e = SSL_TLSEXT_GENERAL_new(s, 65000);
+ SSL_TLSEXT_GENERAL_client_data(e, 8, "test-c1\0");
+ SSL_TLSEXT_GENERAL_client_ext_cb(e, ssl_tlsext_test_client_ext_cb);
+
+ /* the server will send supplemental data */
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65100);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65101);
+ SSL_TLSEXT_GENERAL_client_finish_cb(e,
ssl_tlsext_test_client_finish_cb);
+
+ /* an enhanced extension */
+ e = SSL_TLSEXT_GENERAL_new(s, 65001);
+ SSL_TLSEXT_GENERAL_client_supp_data_new(e, 65010);
+ SSL_TLSEXT_GENERAL_client_supp_data_new(e, 65011);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65200);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65201);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65202);
+
+ SSL_TLSEXT_GENERAL_client_data(e, 0, NULL);
+ SSL_TLSEXT_GENERAL_client_ext_cb(e, ssl_tlsext_test_client_ext_cb);
+ SSL_TLSEXT_GENERAL_client_supp_data_cb(e,
ssl_tlsext_test_client_supp_data_cb);
+ SSL_TLSEXT_GENERAL_client_finish_cb(e,
ssl_tlsext_test_client_finish_cb);
+ SSL_TLSEXT_GENERAL_client_required(e);
+}
+
+void ssl_tlsext_test_client_ext_cb(SSL * s, TLSEXT_GENERAL * e) {
+ fprintf(stderr, "TEST: %d\n", e->type);
+ fprintf(stderr, "TEST: %d\n", e->server_data_length);
+ fprintf(stderr, "TEST: %s\n", e->server_data);
+}
+
+void ssl_tlsext_test_client_supp_data_cb(SSL * s, TLSEXT_GENERAL * e) {
+ SSL_TLSEXT_GENERAL_client_supp_data(e, 65010, 9, "test-sd0\0");
+ SSL_TLSEXT_GENERAL_client_supp_data(e, 65011, 9, "test-sd1\0");
+}
+
+void ssl_tlsext_test_client_finish_cb(SSL * s, TLSEXT_GENERAL * e) {
+ int i;
+ SUPP_DATA_ENTRY * sd;
+
+ if (e->server_supp_data) {
+ for (i = 0; i < sk_SUPP_DATA_ENTRY_num(e->server_supp_data); i++) {
+ sd = sk_SUPP_DATA_ENTRY_value(e->server_supp_data, i);
+ fprintf(stderr, "TEST: %s -> SD %d (%d) %s\n", e->server_data,
sd->type, sd->length, sd->data);
+ }
+ }
+}
+
+
+/*********************************************************************
+ * SERVER SIDE
+ *********************************************************************/
+
+void SSL_TLSEXT_TEST_server_init(SSL * s) {
+ TLSEXT_GENERAL * e;
+
+ /* a very simple extension */
+ e = SSL_TLSEXT_GENERAL_new(s, 65000);
+ SSL_TLSEXT_GENERAL_server_ext_cb(e, ssl_tlsext_test_server_ext_cb);
+
+ /* the server will send supplemental data */
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65100);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65101);
+ SSL_TLSEXT_GENERAL_server_supp_data_cb(e,
ssl_tlsext_test_server_supp_data_cb);
+ /* SSL_TLSEXT_GENERAL_server_finish_cb(e,
ssl_tlsext_test_server_finish_cb); */
+
+ /* an enhanced extension */
+ e = SSL_TLSEXT_GENERAL_new(s, 65001);
+ SSL_TLSEXT_GENERAL_client_supp_data_new(e, 65010);
+ SSL_TLSEXT_GENERAL_client_supp_data_new(e, 65011);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65200);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65201);
+ SSL_TLSEXT_GENERAL_server_supp_data_new(e, 65202);
+
+ SSL_TLSEXT_GENERAL_server_ext_cb(e, ssl_tlsext_test_server_ext_cb);
+ SSL_TLSEXT_GENERAL_server_supp_data_cb(e,
ssl_tlsext_test_server_supp_data_cb);
+ SSL_TLSEXT_GENERAL_server_finish_cb(e,
ssl_tlsext_test_server_finish_cb);
+
+ /* an extension the server knows, but the client doesn't request */
+ e = SSL_TLSEXT_GENERAL_new(s, 65002);
+    /* ... */
+ SSL_TLSEXT_GENERAL_server_ext_cb(e, ssl_tlsext_test_server_ext_cb);
+ SSL_TLSEXT_GENERAL_server_supp_data_cb(e,
ssl_tlsext_test_server_supp_data_cb);
+ SSL_TLSEXT_GENERAL_server_finish_cb(e,
ssl_tlsext_test_server_finish_cb);
+}
+
+void ssl_tlsext_test_server_ext_cb(SSL * s, TLSEXT_GENERAL * e) {
+ fprintf(stderr, "TEST: %d\n", e->type);
+ fprintf(stderr, "TEST: %d\n", e->client_data_length);
+ fprintf(stderr, "TEST: %s\n", e->client_data);
+
+ /* generate the response, maybe accessing data from client */
+ SSL_TLSEXT_GENERAL_server_data(e, 11, "srvr-reply\0");
+ SSL_TLSEXT_GENERAL_server_send(e);
+}
+
+void ssl_tlsext_test_server_supp_data_cb(SSL * s, TLSEXT_GENERAL * e) {
+ if (e->type == 65000) {
+ SSL_TLSEXT_GENERAL_server_supp_data(e, 65100, 10, "test-Ssd0\0");
+ SSL_TLSEXT_GENERAL_server_supp_data(e, 65101, 10, "test-Ssd1\0");
+ }
+ if (e->type == 65001) {
+ SSL_TLSEXT_GENERAL_server_supp_data(e, 65200, 10, "test-Ssd0\0");
+ SSL_TLSEXT_GENERAL_server_supp_data(e, 65202, 10, "test-Ssd2\0");
+ }
+}
+
+void ssl_tlsext_test_server_finish_cb(SSL * s, TLSEXT_GENERAL * e) {
+ int i;
+ SUPP_DATA_ENTRY * sd;
+
+ if (e->client_supp_data) {
+ for (i = 0; i < sk_SUPP_DATA_ENTRY_num(e->client_supp_data); i++) {
+ sd = sk_SUPP_DATA_ENTRY_value(e->client_supp_data, i);
+ fprintf(stderr, "TEST: %s -> SD %d (%d) %s\n", e->client_data,
sd->type, sd->length, sd->data);
+ }
+ }
+}
+
+
+#endif /*OPENSSL_NO_TLSEXT_GENERAL*/
diff -urN openssl-SNAP-20081204/ssl/t1_ext_test.h
o-tlsext/ssl/t1_ext_test.h
--- openssl-SNAP-20081204/ssl/t1_ext_test.h 1970-01-01
01:00:00.000000000 +0100
+++ o-tlsext/ssl/t1_ext_test.h 2008-12-11 12:56:55.000000000 +0100
@@ -0,0 +1,137 @@
+/* ssl/t1_ext_test.h */
+/* Copyright (C) 1995-1998 Eric Young ([hidden email])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([hidden email]).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long
as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL
documentation
+ * included with this distribution is covered by the same copyright
terms
+ * except that the holder is Tim Hudson ([hidden email]).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given
attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young ([hidden email])"
+ *    The word 'cryptographic' can be left out if the rouines from the
library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative
thereof) from
+ *    the apps directory (application code) you must include an
acknowledgement:
+ *    "This product includes software written by Tim Hudson
([hidden email])"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available
version or
+ * derivative of this code cannot be changed.  i.e. this code cannot
simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2008 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
+ *    [hidden email].
+ *
+ * 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
+ * ([hidden email]).  This product includes software written by Tim
+ * Hudson ([hidden email]).
+ *
+ */
+/* ====================================================================
+ * Copyright (C) 2008 Davide Vernizzi and Emanuele Cesena
([hidden email])
+ * All rights reserved.
+ *
+ * General TLS Extension framework, implementing RFC 4366 and RFC 4680.
+ */
+#ifndef HEADER_T1_EXT_TEST_H
+#define HEADER_T1_EXT_TEST_H
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+
+/*TODO Correctly set the include */
+#include <openssl/ssl.h>
+
+void SSL_TLSEXT_TEST_client_init(SSL * s);
+void ssl_tlsext_test_client_ext_cb(SSL * s, TLSEXT_GENERAL * e);
+void ssl_tlsext_test_client_supp_data_cb(SSL * s, TLSEXT_GENERAL * e);
+void ssl_tlsext_test_client_finish_cb(SSL * s, TLSEXT_GENERAL * e);
+
+void SSL_TLSEXT_TEST_server_init(SSL * s);
+void ssl_tlsext_test_server_ext_cb(SSL * s, TLSEXT_GENERAL * e);
+void ssl_tlsext_test_server_supp_data_cb(SSL * s, TLSEXT_GENERAL * e);
+void ssl_tlsext_test_server_finish_cb(SSL * s, TLSEXT_GENERAL * e);
+
+#endif /*OPENSSL_NO_TLSEXT_GENERAL*/
+
+#endif /*HEADER_T1_EXT_TEST_H*/
diff -urN openssl-SNAP-20081204/ssl/t1_lib.c o-tlsext/ssl/t1_lib.c
--- openssl-SNAP-20081204/ssl/t1_lib.c 2008-11-15 19:00:23.000000000
+0100
+++ o-tlsext/ssl/t1_lib.c 2008-12-11 13:02:37.000000000 +0100
@@ -460,6 +460,14 @@
  i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
  }
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ if (s->tlsext_general != NULL)
+ {
+ ret = ssl_add_clienthello_tlsext_general(s, ret, limit);
+ if (ret == NULL) return NULL;
+ }
+#endif
+
  if ((extdatalen = ret-p-2)== 0)
  return p;
 
@@ -553,6 +561,14 @@
 
  }
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ if (s->tlsext_general != NULL)
+ {
+ ret = ssl_add_serverhello_tlsext_general(s, ret, limit);
+ if (ret == NULL) return NULL;
+ }
+#endif
+
  if ((extdatalen = ret-p-2)== 0)
  return p;
 
@@ -883,6 +899,19 @@
  s->tlsext_status_type = -1;
  }
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ else /* TLSEXT_GENERAL must be the last */
+ {
+ if (s->tlsext_general != NULL)
+ {
+ if( ssl_parse_clienthello_tlsext_general(s, type, size, data) ==
0 )
+ {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
+ }
+#endif
  /* session ticket processed earlier */
  data+=size;
  }
@@ -1018,6 +1047,37 @@
  s->tlsext_status_expected = 1;
  }
 
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ else /* TLSEXT_GENERAL must be the last */
+ {
+ int retval = -1;
+ if (s->tlsext_general != NULL)
+ {
+ retval = ssl_parse_serverhello_tlsext_general(s, type, size, data);
+ /* Error from tlsext_general parser,
+ * e.g. copying data within the stack */
+ if( retval == 0 )
+ {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
+ /* Extension not found,
+ * i.e. the server sent an extension the client did not required
+ *
+ * RFC4366:
+ * [...] the extension type MUST NOT appear in the extended server
+ * hello unless the same extension type appeared in the
corresponding
+ * client hello.
+ * */
+ if( retval == -1 )
+ {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ }
+#endif
+
  data+=size;
  }
 
@@ -1047,7 +1107,28 @@
  }
  }
  }
-
+
+#ifndef OPENSSL_NO_TLSEXT_GENERAL
+ /* Check for required extensions
+ * This function is used by the client to verify if any extension
flagged
+ * as "required" was not received from the server. In this case the
+ * handshake is aborted.
+ *
+ * RFC4366:
+ * In the event that a client requests additional functionality using
+ * the extended client hello, and this functionality is not supplied
by
+ * the server, the client MAY abort the handshake.
+ *
+ * If the client does not want to abort the handshake, it has not
+ * to flag the extension as required.
+ */
+ if (!ssl_parse_serverhello_tlsext_general_required(s))
+ {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+#endif
+
  *p = data;
  return 1;
  }

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [hidden email]
Automated List Manager                           [hidden email]