Add DTLS-SRTP.
authorBen Laurie <ben@openssl.org>
Tue, 15 Nov 2011 22:59:20 +0000 (22:59 +0000)
committerBen Laurie <ben@openssl.org>
Tue, 15 Nov 2011 22:59:20 +0000 (22:59 +0000)
12 files changed:
CHANGES
apps/s_client.c
apps/s_server.c
crypto/stack/safestack.h
ssl/Makefile
ssl/d1_srtp.c [new file with mode: 0644]
ssl/srtp.h [new file with mode: 0644]
ssl/ssl.h
ssl/ssl_err.c
ssl/ssl_lib.c
ssl/t1_lib.c
ssl/tls1.h

diff --git a/CHANGES b/CHANGES
index d5e535b..927b9e7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
      security.
      [Emilia K√§sper <emilia.kasper@esat.kuleuven.be> (Google)]
 
+  *) Add DTLS-SRTP negotiation from RFC 5764.
+     [Eric Rescorla]
+
+  *) Add DTLS-SRTP negotiation from RFC 5764.
+     [Eric Rescorla]
+
   *) Add Next Protocol Negotiation,
      http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be
      disabled with a no-npn flag to config or Configure. Code donated
index ef45e43..5527dc2 100644 (file)
@@ -359,6 +359,7 @@ static void sc_usage(void)
 # endif
 #endif
        BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+       BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list");
        }
 
 #ifndef OPENSSL_NO_TLSEXT
@@ -487,6 +488,7 @@ static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
        }
 
 #endif
+       char *srtp_profiles = NULL;
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /* This the context that we pass to next_proto_cb */
@@ -935,7 +937,12 @@ int MAIN(int argc, char **argv)
                        jpake_secret = *++argv;
                        }
 #endif
-               else
+               else if (strcmp(*argv,"-use_srtp") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       srtp_profiles = *(++argv);
+                       }
+                else
                        {
                        BIO_printf(bio_err,"unknown option %s\n",*argv);
                        badop=1;
@@ -1105,6 +1112,8 @@ bad:
                        BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
                SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
                }
+       if (srtp_profiles != NULL)
+               SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
 #endif
        if (bugs)
                SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
@@ -2027,6 +2036,14 @@ static void print_stuff(BIO *bio, SSL *s, int full)
        }
 #endif
 
+       {
+       SRTP_PROTECTION_PROFILE *srtp_profile=SSL_get_selected_srtp_profile(s);
+       if(srtp_profile)
+               BIO_printf(bio,"SRTP Extension negotiated, profile=%s\n",
+                          srtp_profile->name);
+       }
        SSL_SESSION_print(bio,SSL_get_session(s));
        BIO_printf(bio,"---\n");
        if (peer != NULL)
index 35b24ee..e462c99 100644 (file)
@@ -309,6 +309,7 @@ static long socket_mtu;
 static int cert_chain = 0;
 #endif
 
+
 #ifndef OPENSSL_NO_PSK
 static char *psk_identity="Client_identity";
 char *psk_key=NULL; /* by default PSK is not used */
@@ -545,6 +546,7 @@ static void sv_usage(void)
 # ifndef OPENSSL_NO_NEXTPROTONEG
        BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
 # endif
+        BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list");
 #endif
        }
 
@@ -910,6 +912,7 @@ int MAIN(int, char **);
 #ifndef OPENSSL_NO_JPAKE
 static char *jpake_secret = NULL;
 #endif
+static char *srtp_profiles = NULL;
 
 int MAIN(int argc, char *argv[])
        {
@@ -1324,6 +1327,11 @@ int MAIN(int argc, char *argv[])
                        jpake_secret = *(++argv);
                        }
 #endif
+               else if (strcmp(*argv,"-use_srtp") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       srtp_profiles = *(++argv);
+                       }
                else
                        {
                        BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -1540,6 +1548,9 @@ bad:
        else
                SSL_CTX_sess_set_cache_size(ctx,128);
 
+       if (srtp_profiles != NULL)
+               SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
+
 #if 0
        if (cipher == NULL) cipher=getenv("SSL_CIPHER");
 #endif
@@ -2391,10 +2402,19 @@ static int init_ssl_connection(SSL *con)
                BIO_printf(bio_s_out, "\n");
                }
 #endif
+       {
+       SRTP_PROTECTION_PROFILE *srtp_profile
+         = SSL_get_selected_srtp_profile(con);
+
+       if(srtp_profile)
+               BIO_printf(bio_s_out,"SRTP Extension negotiated, profile=%s\n",
+                          srtp_profile->name);
+       }
        if (SSL_cache_hit(con)) BIO_printf(bio_s_out,"Reused session-id\n");
        if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
                TLS1_FLAGS_TLS_PADDING_BUG)
-               BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n");
+               BIO_printf(bio_s_out,
+                          "Peer has incorrect TLSv1 block padding\n");
 #ifndef OPENSSL_NO_KRB5
        client_princ = kssl_ctx_get0_client_princ(SSL_get0_kssl_ctx(con));
        if (client_princ != NULL)
index 401cc22..e9c99b8 100644 (file)
@@ -1525,6 +1525,28 @@ DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
 #define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
 #define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st))
 
+#define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp))
+#define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE)
+#define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i))
+#define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val))
+#define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val))
+#define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i))
+#define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr))
+#define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i))
+#define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp))
+#define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st)
+#define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func))
+#define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st))
+#define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st))
+
 #define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
 #define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
 #define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
index 77538d4..b90ebb1 100644 (file)
@@ -26,7 +26,7 @@ LIBSRC=       \
        s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c          s23_pkt.c \
        t1_meth.c   t1_srvr.c t1_clnt.c  t1_lib.c  t1_enc.c \
        d1_meth.c   d1_srvr.c d1_clnt.c  d1_lib.c  d1_pkt.c \
-       d1_both.c d1_enc.c \
+       d1_both.c d1_enc.c d1_srtp.c \
        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 \
@@ -37,7 +37,7 @@ LIBOBJ= \
        s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o          s23_pkt.o \
        t1_meth.o   t1_srvr.o t1_clnt.o  t1_lib.o  t1_enc.o \
        d1_meth.o   d1_srvr.o d1_clnt.o  d1_lib.o  d1_pkt.o \
-       d1_both.o d1_enc.o \
+       d1_both.o d1_enc.o d1_srtp.o\
        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 \
@@ -45,7 +45,7 @@ LIBOBJ= \
 
 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 srtp.h
 HEADER=        $(EXHEADER) ssl_locl.h kssl_lcl.h
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c
new file mode 100644 (file)
index 0000000..c6fd68d
--- /dev/null
@@ -0,0 +1,434 @@
+/* ssl/t1_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * 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 (tjh@cryptsoft.com).
+ * 
+ * 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 (eay@cryptsoft.com)"
+ *    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 (tjh@cryptsoft.com)"
+ * 
+ * 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-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/*
+  DTLS code by Eric Rescorla <ekr@rtfm.com>
+
+  Copyright (C) 2006, Network Resonance, Inc.
+  Copyright (C) 2011, RTFM, Inc.
+*/
+
+#ifndef OPENSSL_NO_SRTP
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+#include "srtp.h"
+
+
+static SRTP_PROTECTION_PROFILE srtp_known_profiles[]=
+    {
+    {
+    "SRTP_AES128_CM_SHA1_80",
+    SRTP_AES128_CM_SHA1_80,
+    },
+    {
+    "SRTP_AES128_CM_SHA1_32",
+    SRTP_AES128_CM_SHA1_32,
+    },
+#if 0
+    {
+    "SRTP_NULL_SHA1_80",
+    SRTP_NULL_SHA1_80,
+    },
+    {
+    "SRTP_NULL_SHA1_32",
+    SRTP_NULL_SHA1_32,
+    },
+#endif
+    {0}
+    };
+
+static int find_profile_by_name(char *profile_name,
+                               SRTP_PROTECTION_PROFILE **pptr,unsigned len)
+       {
+       SRTP_PROTECTION_PROFILE *p;
+
+       p=srtp_known_profiles;
+       while(p->name)
+               {
+               if((len == strlen(p->name)) && !strncmp(p->name,profile_name,
+                                                       len))
+                       {
+                       *pptr=p;
+                       return 0;
+                       }
+
+               p++;
+               }
+
+       return 1;
+       }
+
+static int find_profile_by_num(unsigned profile_num,
+                              SRTP_PROTECTION_PROFILE **pptr)
+       {
+       SRTP_PROTECTION_PROFILE *p;
+
+       p=srtp_known_profiles;
+       while(p->name)
+               {
+               if(p->id == profile_num)
+                       {
+                       *pptr=p;
+                       return 0;
+                       }
+               p++;
+               }
+
+       return 1;
+       }
+
+static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out)
+       {
+       STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
+
+       char *col;
+       char *ptr=(char *)profiles_string;
+    
+       SRTP_PROTECTION_PROFILE *p;
+
+       if(!(profiles=sk_SRTP_PROTECTION_PROFILE_new_null()))
+               {
+               SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+               return 1;
+               }
+    
+       do
+               {
+               col=strchr(ptr,':');
+
+               if(!find_profile_by_name(ptr,&p,
+                                        col ? col-ptr : (int)strlen(ptr)))
+                       {
+                       sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
+                       }
+               else
+                       {
+                       SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+                       return 1;
+                       }
+
+               if(col) ptr=col+1;
+               } while (col);
+
+       *out=profiles;
+    
+       return 0;
+       }
+    
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,const char *profiles)
+       {
+       return ssl_ctx_make_profiles(profiles,&ctx->srtp_profiles);
+       }
+
+int SSL_set_tlsext_use_srtp(SSL *s,const char *profiles)
+       {
+       return ssl_ctx_make_profiles(profiles,&s->srtp_profiles);
+       }
+
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
+       {
+       if(s != NULL)
+               {
+               if(s->srtp_profiles != NULL)
+                       {
+                       return s->srtp_profiles;
+                       }
+               else if((s->ctx != NULL) &&
+                       (s->ctx->srtp_profiles != NULL))
+                       {
+                       return s->ctx->srtp_profiles;
+                       }
+               }
+
+       return NULL;
+       }
+
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
+       {
+       return s->srtp_profile;
+       }
+
+/* Note: this function returns 0 length if there are no 
+   profiles specified */
+int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
+       {
+       int ct=0;
+       int i;
+       STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0;
+       SRTP_PROTECTION_PROFILE *prof;
+    
+       clnt=SSL_get_srtp_profiles(s);    
+       ct=sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
+
+       if(p)
+               {
+               if(ct==0)
+                       {
+                       SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
+                       return 1;
+                       }
+
+               if((ct*2) > maxlen)
+                       {
+                       SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+                       return 1;
+                       }
+
+               for(i=0;i<ct;i++)
+                       {
+                       prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
+                       s2n(prof->id,p);
+                       }
+               }
+       *len=ct*2;
+    
+       return 0;
+       }
+
+
+int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
+       {
+       SRTP_PROTECTION_PROFILE *cprof,*sprof;
+       STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr;
+       int i,j;
+       int id;
+       int ret;
+    
+       if(len%2)
+               {
+               SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+               *al=SSL_AD_DECODE_ERROR;
+               return 1;
+               }
+
+       clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
+
+       while(len)
+               {
+               n2s(d,id);
+               len-=2;
+
+               if(!find_profile_by_num(id,&cprof))
+                       {
+                       sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof);
+                       }
+               else
+                       {
+                       ; /* Ignore */
+                       }
+               }
+
+       srvr=SSL_get_srtp_profiles(s);
+
+       /* Pick our most preferred profile. If no profiles have been
+        configured then the outer loop doesn't run 
+        (sk_SRTP_PROTECTION_PROFILE_num() = -1)
+        and so we just return without doing anything */
+       for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(srvr);i++)
+               {
+               sprof=sk_SRTP_PROTECTION_PROFILE_value(srvr,i);
+
+               for(j=0;j<sk_SRTP_PROTECTION_PROFILE_num(clnt);j++)
+                       {
+                       cprof=sk_SRTP_PROTECTION_PROFILE_value(clnt,j);
+            
+                       if(cprof->id==sprof->id)
+                               {
+                               s->srtp_profile=sprof;
+                               *al=0;
+                               ret=0;
+                               goto done;
+                               }
+                       }
+               }
+
+       ret=0;
+    
+done:
+       if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt);
+
+       return ret;
+       }
+
+int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
+       {
+       if(p)
+               {
+               if(maxlen < 2)
+                       {
+                       SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+                       return 1;
+                       }
+
+               if(s->srtp_profile==0)
+                       {
+                       SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_USE_SRTP_NOT_NEGOTIATED);
+                       return 1;
+                       }
+
+               s2n(s->srtp_profile->id,p);
+               }    
+       *len=2;
+    
+       return 0;
+       }
+    
+
+int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
+       {
+       unsigned id;
+       int i;
+       STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
+       SRTP_PROTECTION_PROFILE *prof;
+
+       if(len!=2)
+               {
+               SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+               *al=SSL_AD_DECODE_ERROR;
+               return 1;
+               }
+
+       n2s(d,id);
+
+       clnt=SSL_get_srtp_profiles(s);
+
+       /* Throw an error if the server gave us an unsolicited extension */
+       if (clnt == NULL)
+               {
+               SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_NO_SRTP_PROFILES);
+               *al=SSL_AD_DECODE_ERROR;
+               return 1;
+               }
+    
+       /* Check to see if the server gave us something we support
+          (and presumably offered)
+       */
+       for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(clnt);i++)
+               {
+               prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i);
+           
+               if(prof->id == id)
+                       {
+                       s->srtp_profile=prof;
+                       *al=0;
+                       return 0;
+                       }
+               }
+
+       SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+       *al=SSL_AD_DECODE_ERROR;
+       return 1;
+       }
+
+
+#endif
diff --git a/ssl/srtp.h b/ssl/srtp.h
new file mode 100644 (file)
index 0000000..e4ddf8c
--- /dev/null
@@ -0,0 +1,150 @@
+/* ssl/tls1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * 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 (tjh@cryptsoft.com).
+ * 
+ * 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 (eay@cryptsoft.com)"
+ *    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 (tjh@cryptsoft.com)"
+ * 
+ * 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-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/*
+  DTLS code by Eric Rescorla <ekr@rtfm.com>
+
+  Copyright (C) 2006, Network Resonance, Inc.
+  Copyright (C) 2011, RTFM, Inc.
+*/
+
+#ifndef HEADER_D1_SRTP_H
+#define HEADER_D1_SRTP_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+     
+#define SRTP_AES128_CM_SHA1_80 0x0001
+#define SRTP_AES128_CM_SHA1_32 0x0002
+#define SRTP_AES128_F8_SHA1_80 0x0003
+#define SRTP_AES128_F8_SHA1_32 0x0004
+#define SRTP_NULL_SHA1_80      0x0005
+#define SRTP_NULL_SHA1_32      0x0006
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
+int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
+int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
+int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
+int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
index 7f15173..9d46d6b 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -369,6 +369,15 @@ typedef struct ssl_session_st SSL_SESSION;
 
 DECLARE_STACK_OF(SSL_CIPHER)
 
+/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
+typedef struct srtp_protection_profile_st
+       {
+       const char *name;
+       unsigned long id;
+       } SRTP_PROTECTION_PROFILE;
+
+DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
+
 typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
 typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
 
@@ -966,6 +975,11 @@ struct ssl_ctx_st
 #ifndef OPENSSL_NO_SRP
        SRP_CTX srp_ctx; /* ctx for SRP authentication */
 #endif
+
+#ifndef OPENSSL_NO_TLSEXT
+        /* SRTP profiles we are willing to do from RFC 5764 */
+        STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;  
+#endif
        };
 
 #endif
@@ -1327,6 +1341,9 @@ struct ssl_st
 #endif
 
 #define session_ctx initial_ctx
+
+        STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;  /* What we'll do */
+        SRTP_PROTECTION_PROFILE *srtp_profile;            /* What's been chosen */
 #else
 #define session_ctx ctx
 #endif /* OPENSSL_NO_TLSEXT */
@@ -1343,6 +1360,7 @@ struct ssl_st
 #include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
 #include <openssl/dtls1.h> /* Datagram TLS */
 #include <openssl/ssl23.h>
+#include <openssl/srtp.h>  /* Support for the use_srtp extension */
 
 #ifdef  __cplusplus
 extern "C" {
@@ -2144,10 +2162,12 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL3_WRITE_PENDING                        159
 #define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT       298
 #define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT                277
+#define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT          307
 #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK        215
 #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK       216
 #define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT       299
 #define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT                278
+#define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT          308
 #define SSL_F_SSL_BAD_METHOD                            160
 #define SSL_F_SSL_BYTES_TO_CIPHER_LIST                  161
 #define SSL_F_SSL_CERT_DUP                              221
@@ -2164,6 +2184,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_CREATE_CIPHER_LIST                    166
 #define SSL_F_SSL_CTRL                                  232
 #define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY                         168
+#define SSL_F_SSL_CTX_MAKE_PROFILES                     309
 #define SSL_F_SSL_CTX_NEW                               169
 #define SSL_F_SSL_CTX_SET_CIPHER_LIST                   269
 #define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE            290
@@ -2192,8 +2213,10 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_NEW                                   186
 #define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT     300
 #define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT              302
+#define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT        310
 #define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT     301
 #define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT              303
+#define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT        311
 #define SSL_F_SSL_PEEK                                  270
 #define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT            281
 #define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT            282
@@ -2280,6 +2303,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_BAD_SRP_G_LENGTH                          350
 #define SSL_R_BAD_SRP_N_LENGTH                          351
 #define SSL_R_BAD_SRP_S_LENGTH                          352
+#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST          360
 #define SSL_R_BAD_SSL_FILETYPE                          124
 #define SSL_R_BAD_SSL_SESSION_ID_LENGTH                         125
 #define SSL_R_BAD_STATE                                         126
@@ -2318,6 +2342,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE        322
 #define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE       323
 #define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER              310
+#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST        361
 #define SSL_R_ENCRYPTED_LENGTH_TOO_LONG                         150
 #define SSL_R_ERROR_GENERATING_TMP_RSA_KEY              282
 #define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST             151
@@ -2394,6 +2419,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_NO_RENEGOTIATION                          339
 #define SSL_R_NO_REQUIRED_DIGEST                        324
 #define SSL_R_NO_SHARED_CIPHER                          193
+#define SSL_R_NO_SRTP_PROFILES                          362
 #define SSL_R_NO_VERIFY_CALLBACK                        194
 #define SSL_R_NULL_SSL_CTX                              195
 #define SSL_R_NULL_SSL_METHOD_PASSED                    196
@@ -2440,6 +2466,9 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_SIGNATURE_ALGORITHMS_ERROR                359
 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE     220
 #define SSL_R_SRP_A_CALC                                356
+#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES          363
+#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG     364
+#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE           365
 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE              221
 #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG               299
 #define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT            321
@@ -2520,6 +2549,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_UNSUPPORTED_PROTOCOL                      258
 #define SSL_R_UNSUPPORTED_SSL_VERSION                   259
 #define SSL_R_UNSUPPORTED_STATUS_TYPE                   329
+#define SSL_R_USE_SRTP_NOT_NEGOTIATED                   366
 #define SSL_R_WRITE_BIO_NOT_SET                                 260
 #define SSL_R_WRONG_CIPHER_RETURNED                     261
 #define SSL_R_WRONG_MESSAGE_TYPE                        262
index ceb4b98..b899dcb 100644 (file)
@@ -1,6 +1,6 @@
 /* ssl/ssl_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2010 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2011 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
@@ -180,10 +180,12 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING),   "SSL3_WRITE_PENDING"},
 {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),  "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
 {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT),   "SSL_ADD_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT),     "SSL_ADD_CLIENTHELLO_USE_SRTP_EXT"},
 {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK),   "SSL_add_dir_cert_subjects_to_stack"},
 {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK),  "SSL_add_file_cert_subjects_to_stack"},
 {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT),  "SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"},
 {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT),   "SSL_ADD_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT),     "SSL_ADD_SERVERHELLO_USE_SRTP_EXT"},
 {ERR_FUNC(SSL_F_SSL_BAD_METHOD),       "SSL_BAD_METHOD"},
 {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST),     "SSL_BYTES_TO_CIPHER_LIST"},
 {ERR_FUNC(SSL_F_SSL_CERT_DUP), "SSL_CERT_DUP"},
@@ -200,6 +202,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST),       "SSL_CREATE_CIPHER_LIST"},
 {ERR_FUNC(SSL_F_SSL_CTRL),     "SSL_ctrl"},
 {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY),    "SSL_CTX_check_private_key"},
+{ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES),        "SSL_CTX_MAKE_PROFILES"},
 {ERR_FUNC(SSL_F_SSL_CTX_NEW),  "SSL_CTX_new"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST),      "SSL_CTX_set_cipher_list"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE),       "SSL_CTX_set_client_cert_engine"},
@@ -228,8 +231,10 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL_NEW),      "SSL_new"},
 {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT),        "SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"},
 {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), "SSL_PARSE_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT),   "SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT"},
 {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT),        "SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"},
 {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), "SSL_PARSE_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT),   "SSL_PARSE_SERVERHELLO_USE_SRTP_EXT"},
 {ERR_FUNC(SSL_F_SSL_PEEK),     "SSL_peek"},
 {ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT),       "SSL_PREPARE_CLIENTHELLO_TLSEXT"},
 {ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT),       "SSL_PREPARE_SERVERHELLO_TLSEXT"},
@@ -319,6 +324,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH)      ,"bad srp g length"},
 {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH)      ,"bad srp n length"},
 {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH)      ,"bad srp s length"},
+{ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST),"bad srtp protection profile list"},
 {ERR_REASON(SSL_R_BAD_SSL_FILETYPE)      ,"bad ssl filetype"},
 {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"},
 {ERR_REASON(SSL_R_BAD_STATE)             ,"bad state"},
@@ -357,6 +363,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),"ecc cert should have rsa signature"},
 {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),"ecc cert should have sha1 signature"},
 {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"},
+{ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST),"empty srtp protection profile list"},
 {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
 {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
 {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),"error in received cipher list"},
@@ -433,6 +440,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_NO_RENEGOTIATION)      ,"no renegotiation"},
 {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST)    ,"digest requred for handshake isn't computed"},
 {ERR_REASON(SSL_R_NO_SHARED_CIPHER)      ,"no shared cipher"},
+{ERR_REASON(SSL_R_NO_SRTP_PROFILES)      ,"no srtp profiles"},
 {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK)    ,"no verify callback"},
 {ERR_REASON(SSL_R_NULL_SSL_CTX)          ,"null ssl ctx"},
 {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED),"null ssl method passed"},
@@ -479,6 +487,9 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR),"signature algorithms error"},
 {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
 {ERR_REASON(SSL_R_SRP_A_CALC)            ,"error with the srp params"},
+{ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES),"srtp could not allocate profiles"},
+{ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG),"srtp protection profile list too long"},
+{ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE),"srtp unknown protection profile"},
 {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
 {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"},
 {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"},
@@ -559,6 +570,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL)  ,"unsupported protocol"},
 {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"},
 {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE),"unsupported status type"},
+{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED),"use srtp not negotiated"},
 {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET)     ,"write bio not set"},
 {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) ,"wrong cipher returned"},
 {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE)    ,"wrong message type"},
index 3a87572..14664cf 100644 (file)
@@ -596,6 +596,9 @@ void SSL_free(SSL *s)
                OPENSSL_free(s->next_proto_negotiated);
 #endif
 
+        if (s->srtp_profiles)
+            sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+
        OPENSSL_free(s);
        }
 
@@ -1935,6 +1938,9 @@ void SSL_CTX_free(SSL_CTX *a)
        a->comp_methods = NULL;
 #endif
 
+        if (a->srtp_profiles)
+                sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
+
 #ifndef OPENSSL_NO_PSK
        if (a->psk_identity_hint)
                OPENSSL_free(a->psk_identity_hint);
index 93869fa..473bd94 100644 (file)
@@ -629,6 +629,25 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                }
 #endif
 
+        if(SSL_get_srtp_profiles(s))
+                {
+                int el;
+
+                ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
+                
+                if((limit - p - 4 - el) < 0) return NULL;
+
+                s2n(TLSEXT_TYPE_use_srtp,ret);
+                s2n(el,ret);
+
+                if(ssl_add_clienthello_use_srtp_ext(s, ret, &el, el))
+                       {
+                       SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                       return NULL;
+                       }
+                ret += el;
+                }
+
        if ((extdatalen = ret-p-2)== 0) 
                return p;
 
@@ -741,6 +760,26 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                ret += sol;
                }
 #endif
+
+        if(s->srtp_profile)
+                {
+                int el;
+
+                ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
+                
+                if((limit - p - 4 - el) < 0) return NULL;
+
+                s2n(TLSEXT_TYPE_use_srtp,ret);
+                s2n(el,ret);
+
+                if(ssl_add_serverhello_use_srtp_ext(s, ret, &el, el))
+                       {
+                       SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+                       return NULL;
+                       }
+                ret+=el;
+                }
+
        if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) 
                && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
                { const unsigned char cryptopro_ext[36] = {
@@ -1208,6 +1247,13 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 #endif
 
                /* session ticket processed earlier */
+               else if (type == TLSEXT_TYPE_use_srtp)
+                        {
+                       if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
+                                                             al))
+                               return 0;
+                        }
+
                data+=size;
                }
                                
@@ -1422,6 +1468,13 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                                return 0;
                        renegotiate_seen = 1;
                        }
+               else if (type == TLSEXT_TYPE_use_srtp)
+                        {
+                        if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
+                                                             al))
+                                return 0;
+                        }
+
                data+=size;             
                }
 
index 14b5d9b..f443bb1 100644 (file)
@@ -255,6 +255,9 @@ extern "C" {
 #define TLSEXT_hash_sha384                             5
 #define TLSEXT_hash_sha512                             6
 
+/* ExtensionType value from RFC5764 */
+#define TLSEXT_TYPE_use_srtp                           14
+
 #ifndef OPENSSL_NO_TLSEXT
 
 #define TLSEXT_MAXLEN_host_name 255