diff options
author | Ben Laurie <ben@openssl.org> | 2011-11-15 23:02:16 +0000 |
---|---|---|
committer | Ben Laurie <ben@openssl.org> | 2011-11-15 23:02:16 +0000 |
commit | 060a38a2c06145df02d04af20e31bacf30f192e2 (patch) | |
tree | c6af6dd58887d79dfec6ed5cec8973244a28df64 | |
parent | 58402976b4ebbcdac63e2b2f3afe8b5fe261cf5d (diff) |
Add DTLS-SRTP.
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | apps/s_client.c | 19 | ||||
-rw-r--r-- | apps/s_server.c | 22 | ||||
-rw-r--r-- | crypto/stack/safestack.h | 22 | ||||
-rw-r--r-- | ssl/Makefile | 6 | ||||
-rw-r--r-- | ssl/d1_srtp.c | 434 | ||||
-rw-r--r-- | ssl/srtp.h | 150 | ||||
-rw-r--r-- | ssl/ssl.h | 30 | ||||
-rw-r--r-- | ssl/ssl_err.c | 12 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 6 | ||||
-rw-r--r-- | ssl/t1_lib.c | 53 | ||||
-rw-r--r-- | ssl/tls1.h | 3 |
12 files changed, 755 insertions, 5 deletions
@@ -4,6 +4,9 @@ Changes between 1.0.0f and 1.0.1 [xx XXX xxxx] + *) 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 diff --git a/apps/s_client.c b/apps/s_client.c index 5f251a4247..94e03c9c00 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -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) diff --git a/apps/s_server.c b/apps/s_server.c index 19f4fb25e2..14cffa6fa9 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -305,6 +305,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 */ @@ -540,6 +541,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 } @@ -901,6 +903,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[]) { @@ -1307,6 +1310,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); @@ -1522,6 +1530,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 @@ -2361,10 +2372,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) diff --git a/crypto/stack/safestack.h b/crypto/stack/safestack.h index fa74584fff..ea3aa0d800 100644 --- a/crypto/stack/safestack.h +++ b/crypto/stack/safestack.h @@ -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)) diff --git a/ssl/Makefile b/ssl/Makefile index 4b5112c144..2a88c62ea1 100644 --- a/ssl/Makefile +++ b/ssl/Makefile @@ -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 index 0000000000..c6fd68d6db --- /dev/null +++ b/ssl/d1_srtp.c @@ -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 index 0000000000..e4ddf8c468 --- /dev/null +++ b/ssl/srtp.h @@ -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 + @@ -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); @@ -959,6 +968,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 @@ -1319,6 +1333,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 */ @@ -1335,6 +1352,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" { @@ -2129,10 +2147,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 @@ -2149,6 +2169,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 @@ -2177,8 +2198,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 @@ -2265,6 +2288,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_BAD_SRP_G_LENGTH 348 #define SSL_R_BAD_SRP_N_LENGTH 349 #define SSL_R_BAD_SRP_S_LENGTH 350 +#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 @@ -2303,6 +2327,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 @@ -2379,6 +2404,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 @@ -2425,6 +2451,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 354 +#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 @@ -2505,6 +2534,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_UNSUPPORTED_PROTOCOL 258 #define SSL_R_UNSUPPORTED_SSL_VERSION 259 #define SSL_R_UNSUPPO |