1*1f13597dSJung-uk Kim /* ssl/t1_lib.c */ 2*1f13597dSJung-uk Kim /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*1f13597dSJung-uk Kim * All rights reserved. 4*1f13597dSJung-uk Kim * 5*1f13597dSJung-uk Kim * This package is an SSL implementation written 6*1f13597dSJung-uk Kim * by Eric Young (eay@cryptsoft.com). 7*1f13597dSJung-uk Kim * The implementation was written so as to conform with Netscapes SSL. 8*1f13597dSJung-uk Kim * 9*1f13597dSJung-uk Kim * This library is free for commercial and non-commercial use as long as 10*1f13597dSJung-uk Kim * the following conditions are aheared to. The following conditions 11*1f13597dSJung-uk Kim * apply to all code found in this distribution, be it the RC4, RSA, 12*1f13597dSJung-uk Kim * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*1f13597dSJung-uk Kim * included with this distribution is covered by the same copyright terms 14*1f13597dSJung-uk Kim * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*1f13597dSJung-uk Kim * 16*1f13597dSJung-uk Kim * Copyright remains Eric Young's, and as such any Copyright notices in 17*1f13597dSJung-uk Kim * the code are not to be removed. 18*1f13597dSJung-uk Kim * If this package is used in a product, Eric Young should be given attribution 19*1f13597dSJung-uk Kim * as the author of the parts of the library used. 20*1f13597dSJung-uk Kim * This can be in the form of a textual message at program startup or 21*1f13597dSJung-uk Kim * in documentation (online or textual) provided with the package. 22*1f13597dSJung-uk Kim * 23*1f13597dSJung-uk Kim * Redistribution and use in source and binary forms, with or without 24*1f13597dSJung-uk Kim * modification, are permitted provided that the following conditions 25*1f13597dSJung-uk Kim * are met: 26*1f13597dSJung-uk Kim * 1. Redistributions of source code must retain the copyright 27*1f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer. 28*1f13597dSJung-uk Kim * 2. Redistributions in binary form must reproduce the above copyright 29*1f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer in the 30*1f13597dSJung-uk Kim * documentation and/or other materials provided with the distribution. 31*1f13597dSJung-uk Kim * 3. All advertising materials mentioning features or use of this software 32*1f13597dSJung-uk Kim * must display the following acknowledgement: 33*1f13597dSJung-uk Kim * "This product includes cryptographic software written by 34*1f13597dSJung-uk Kim * Eric Young (eay@cryptsoft.com)" 35*1f13597dSJung-uk Kim * The word 'cryptographic' can be left out if the rouines from the library 36*1f13597dSJung-uk Kim * being used are not cryptographic related :-). 37*1f13597dSJung-uk Kim * 4. If you include any Windows specific code (or a derivative thereof) from 38*1f13597dSJung-uk Kim * the apps directory (application code) you must include an acknowledgement: 39*1f13597dSJung-uk Kim * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*1f13597dSJung-uk Kim * 41*1f13597dSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*1f13597dSJung-uk Kim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*1f13597dSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*1f13597dSJung-uk Kim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*1f13597dSJung-uk Kim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*1f13597dSJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*1f13597dSJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*1f13597dSJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*1f13597dSJung-uk Kim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*1f13597dSJung-uk Kim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*1f13597dSJung-uk Kim * SUCH DAMAGE. 52*1f13597dSJung-uk Kim * 53*1f13597dSJung-uk Kim * The licence and distribution terms for any publically available version or 54*1f13597dSJung-uk Kim * derivative of this code cannot be changed. i.e. this code cannot simply be 55*1f13597dSJung-uk Kim * copied and put under another distribution licence 56*1f13597dSJung-uk Kim * [including the GNU Public Licence.] 57*1f13597dSJung-uk Kim */ 58*1f13597dSJung-uk Kim /* ==================================================================== 59*1f13597dSJung-uk Kim * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 60*1f13597dSJung-uk Kim * 61*1f13597dSJung-uk Kim * Redistribution and use in source and binary forms, with or without 62*1f13597dSJung-uk Kim * modification, are permitted provided that the following conditions 63*1f13597dSJung-uk Kim * are met: 64*1f13597dSJung-uk Kim * 65*1f13597dSJung-uk Kim * 1. Redistributions of source code must retain the above copyright 66*1f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer. 67*1f13597dSJung-uk Kim * 68*1f13597dSJung-uk Kim * 2. Redistributions in binary form must reproduce the above copyright 69*1f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer in 70*1f13597dSJung-uk Kim * the documentation and/or other materials provided with the 71*1f13597dSJung-uk Kim * distribution. 72*1f13597dSJung-uk Kim * 73*1f13597dSJung-uk Kim * 3. All advertising materials mentioning features or use of this 74*1f13597dSJung-uk Kim * software must display the following acknowledgment: 75*1f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 76*1f13597dSJung-uk Kim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77*1f13597dSJung-uk Kim * 78*1f13597dSJung-uk Kim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79*1f13597dSJung-uk Kim * endorse or promote products derived from this software without 80*1f13597dSJung-uk Kim * prior written permission. For written permission, please contact 81*1f13597dSJung-uk Kim * openssl-core@openssl.org. 82*1f13597dSJung-uk Kim * 83*1f13597dSJung-uk Kim * 5. Products derived from this software may not be called "OpenSSL" 84*1f13597dSJung-uk Kim * nor may "OpenSSL" appear in their names without prior written 85*1f13597dSJung-uk Kim * permission of the OpenSSL Project. 86*1f13597dSJung-uk Kim * 87*1f13597dSJung-uk Kim * 6. Redistributions of any form whatsoever must retain the following 88*1f13597dSJung-uk Kim * acknowledgment: 89*1f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 90*1f13597dSJung-uk Kim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91*1f13597dSJung-uk Kim * 92*1f13597dSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93*1f13597dSJung-uk Kim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94*1f13597dSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95*1f13597dSJung-uk Kim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96*1f13597dSJung-uk Kim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97*1f13597dSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98*1f13597dSJung-uk Kim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99*1f13597dSJung-uk Kim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100*1f13597dSJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101*1f13597dSJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102*1f13597dSJung-uk Kim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103*1f13597dSJung-uk Kim * OF THE POSSIBILITY OF SUCH DAMAGE. 104*1f13597dSJung-uk Kim * ==================================================================== 105*1f13597dSJung-uk Kim * 106*1f13597dSJung-uk Kim * This product includes cryptographic software written by Eric Young 107*1f13597dSJung-uk Kim * (eay@cryptsoft.com). This product includes software written by Tim 108*1f13597dSJung-uk Kim * Hudson (tjh@cryptsoft.com). 109*1f13597dSJung-uk Kim * 110*1f13597dSJung-uk Kim */ 111*1f13597dSJung-uk Kim /* 112*1f13597dSJung-uk Kim DTLS code by Eric Rescorla <ekr@rtfm.com> 113*1f13597dSJung-uk Kim 114*1f13597dSJung-uk Kim Copyright (C) 2006, Network Resonance, Inc. 115*1f13597dSJung-uk Kim Copyright (C) 2011, RTFM, Inc. 116*1f13597dSJung-uk Kim */ 117*1f13597dSJung-uk Kim 118*1f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRTP 119*1f13597dSJung-uk Kim 120*1f13597dSJung-uk Kim #include <stdio.h> 121*1f13597dSJung-uk Kim #include <openssl/objects.h> 122*1f13597dSJung-uk Kim #include "ssl_locl.h" 123*1f13597dSJung-uk Kim #include "srtp.h" 124*1f13597dSJung-uk Kim 125*1f13597dSJung-uk Kim 126*1f13597dSJung-uk Kim static SRTP_PROTECTION_PROFILE srtp_known_profiles[]= 127*1f13597dSJung-uk Kim { 128*1f13597dSJung-uk Kim { 129*1f13597dSJung-uk Kim "SRTP_AES128_CM_SHA1_80", 130*1f13597dSJung-uk Kim SRTP_AES128_CM_SHA1_80, 131*1f13597dSJung-uk Kim }, 132*1f13597dSJung-uk Kim { 133*1f13597dSJung-uk Kim "SRTP_AES128_CM_SHA1_32", 134*1f13597dSJung-uk Kim SRTP_AES128_CM_SHA1_32, 135*1f13597dSJung-uk Kim }, 136*1f13597dSJung-uk Kim #if 0 137*1f13597dSJung-uk Kim { 138*1f13597dSJung-uk Kim "SRTP_NULL_SHA1_80", 139*1f13597dSJung-uk Kim SRTP_NULL_SHA1_80, 140*1f13597dSJung-uk Kim }, 141*1f13597dSJung-uk Kim { 142*1f13597dSJung-uk Kim "SRTP_NULL_SHA1_32", 143*1f13597dSJung-uk Kim SRTP_NULL_SHA1_32, 144*1f13597dSJung-uk Kim }, 145*1f13597dSJung-uk Kim #endif 146*1f13597dSJung-uk Kim {0} 147*1f13597dSJung-uk Kim }; 148*1f13597dSJung-uk Kim 149*1f13597dSJung-uk Kim static int find_profile_by_name(char *profile_name, 150*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE **pptr,unsigned len) 151*1f13597dSJung-uk Kim { 152*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *p; 153*1f13597dSJung-uk Kim 154*1f13597dSJung-uk Kim p=srtp_known_profiles; 155*1f13597dSJung-uk Kim while(p->name) 156*1f13597dSJung-uk Kim { 157*1f13597dSJung-uk Kim if((len == strlen(p->name)) && !strncmp(p->name,profile_name, 158*1f13597dSJung-uk Kim len)) 159*1f13597dSJung-uk Kim { 160*1f13597dSJung-uk Kim *pptr=p; 161*1f13597dSJung-uk Kim return 0; 162*1f13597dSJung-uk Kim } 163*1f13597dSJung-uk Kim 164*1f13597dSJung-uk Kim p++; 165*1f13597dSJung-uk Kim } 166*1f13597dSJung-uk Kim 167*1f13597dSJung-uk Kim return 1; 168*1f13597dSJung-uk Kim } 169*1f13597dSJung-uk Kim 170*1f13597dSJung-uk Kim static int find_profile_by_num(unsigned profile_num, 171*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE **pptr) 172*1f13597dSJung-uk Kim { 173*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *p; 174*1f13597dSJung-uk Kim 175*1f13597dSJung-uk Kim p=srtp_known_profiles; 176*1f13597dSJung-uk Kim while(p->name) 177*1f13597dSJung-uk Kim { 178*1f13597dSJung-uk Kim if(p->id == profile_num) 179*1f13597dSJung-uk Kim { 180*1f13597dSJung-uk Kim *pptr=p; 181*1f13597dSJung-uk Kim return 0; 182*1f13597dSJung-uk Kim } 183*1f13597dSJung-uk Kim p++; 184*1f13597dSJung-uk Kim } 185*1f13597dSJung-uk Kim 186*1f13597dSJung-uk Kim return 1; 187*1f13597dSJung-uk Kim } 188*1f13597dSJung-uk Kim 189*1f13597dSJung-uk Kim static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out) 190*1f13597dSJung-uk Kim { 191*1f13597dSJung-uk Kim STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; 192*1f13597dSJung-uk Kim 193*1f13597dSJung-uk Kim char *col; 194*1f13597dSJung-uk Kim char *ptr=(char *)profiles_string; 195*1f13597dSJung-uk Kim 196*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *p; 197*1f13597dSJung-uk Kim 198*1f13597dSJung-uk Kim if(!(profiles=sk_SRTP_PROTECTION_PROFILE_new_null())) 199*1f13597dSJung-uk Kim { 200*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); 201*1f13597dSJung-uk Kim return 1; 202*1f13597dSJung-uk Kim } 203*1f13597dSJung-uk Kim 204*1f13597dSJung-uk Kim do 205*1f13597dSJung-uk Kim { 206*1f13597dSJung-uk Kim col=strchr(ptr,':'); 207*1f13597dSJung-uk Kim 208*1f13597dSJung-uk Kim if(!find_profile_by_name(ptr,&p, 209*1f13597dSJung-uk Kim col ? col-ptr : (int)strlen(ptr))) 210*1f13597dSJung-uk Kim { 211*1f13597dSJung-uk Kim sk_SRTP_PROTECTION_PROFILE_push(profiles,p); 212*1f13597dSJung-uk Kim } 213*1f13597dSJung-uk Kim else 214*1f13597dSJung-uk Kim { 215*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); 216*1f13597dSJung-uk Kim return 1; 217*1f13597dSJung-uk Kim } 218*1f13597dSJung-uk Kim 219*1f13597dSJung-uk Kim if(col) ptr=col+1; 220*1f13597dSJung-uk Kim } while (col); 221*1f13597dSJung-uk Kim 222*1f13597dSJung-uk Kim *out=profiles; 223*1f13597dSJung-uk Kim 224*1f13597dSJung-uk Kim return 0; 225*1f13597dSJung-uk Kim } 226*1f13597dSJung-uk Kim 227*1f13597dSJung-uk Kim int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,const char *profiles) 228*1f13597dSJung-uk Kim { 229*1f13597dSJung-uk Kim return ssl_ctx_make_profiles(profiles,&ctx->srtp_profiles); 230*1f13597dSJung-uk Kim } 231*1f13597dSJung-uk Kim 232*1f13597dSJung-uk Kim int SSL_set_tlsext_use_srtp(SSL *s,const char *profiles) 233*1f13597dSJung-uk Kim { 234*1f13597dSJung-uk Kim return ssl_ctx_make_profiles(profiles,&s->srtp_profiles); 235*1f13597dSJung-uk Kim } 236*1f13597dSJung-uk Kim 237*1f13597dSJung-uk Kim 238*1f13597dSJung-uk Kim STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) 239*1f13597dSJung-uk Kim { 240*1f13597dSJung-uk Kim if(s != NULL) 241*1f13597dSJung-uk Kim { 242*1f13597dSJung-uk Kim if(s->srtp_profiles != NULL) 243*1f13597dSJung-uk Kim { 244*1f13597dSJung-uk Kim return s->srtp_profiles; 245*1f13597dSJung-uk Kim } 246*1f13597dSJung-uk Kim else if((s->ctx != NULL) && 247*1f13597dSJung-uk Kim (s->ctx->srtp_profiles != NULL)) 248*1f13597dSJung-uk Kim { 249*1f13597dSJung-uk Kim return s->ctx->srtp_profiles; 250*1f13597dSJung-uk Kim } 251*1f13597dSJung-uk Kim } 252*1f13597dSJung-uk Kim 253*1f13597dSJung-uk Kim return NULL; 254*1f13597dSJung-uk Kim } 255*1f13597dSJung-uk Kim 256*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) 257*1f13597dSJung-uk Kim { 258*1f13597dSJung-uk Kim return s->srtp_profile; 259*1f13597dSJung-uk Kim } 260*1f13597dSJung-uk Kim 261*1f13597dSJung-uk Kim /* Note: this function returns 0 length if there are no 262*1f13597dSJung-uk Kim profiles specified */ 263*1f13597dSJung-uk Kim int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen) 264*1f13597dSJung-uk Kim { 265*1f13597dSJung-uk Kim int ct=0; 266*1f13597dSJung-uk Kim int i; 267*1f13597dSJung-uk Kim STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0; 268*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *prof; 269*1f13597dSJung-uk Kim 270*1f13597dSJung-uk Kim clnt=SSL_get_srtp_profiles(s); 271*1f13597dSJung-uk Kim ct=sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */ 272*1f13597dSJung-uk Kim 273*1f13597dSJung-uk Kim if(p) 274*1f13597dSJung-uk Kim { 275*1f13597dSJung-uk Kim if(ct==0) 276*1f13597dSJung-uk Kim { 277*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); 278*1f13597dSJung-uk Kim return 1; 279*1f13597dSJung-uk Kim } 280*1f13597dSJung-uk Kim 281*1f13597dSJung-uk Kim if((2 + ct*2 + 1) > maxlen) 282*1f13597dSJung-uk Kim { 283*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); 284*1f13597dSJung-uk Kim return 1; 285*1f13597dSJung-uk Kim } 286*1f13597dSJung-uk Kim 287*1f13597dSJung-uk Kim /* Add the length */ 288*1f13597dSJung-uk Kim s2n(ct * 2, p); 289*1f13597dSJung-uk Kim for(i=0;i<ct;i++) 290*1f13597dSJung-uk Kim { 291*1f13597dSJung-uk Kim prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i); 292*1f13597dSJung-uk Kim s2n(prof->id,p); 293*1f13597dSJung-uk Kim } 294*1f13597dSJung-uk Kim 295*1f13597dSJung-uk Kim /* Add an empty use_mki value */ 296*1f13597dSJung-uk Kim *p++ = 0; 297*1f13597dSJung-uk Kim } 298*1f13597dSJung-uk Kim 299*1f13597dSJung-uk Kim *len=2 + ct*2 + 1; 300*1f13597dSJung-uk Kim 301*1f13597dSJung-uk Kim return 0; 302*1f13597dSJung-uk Kim } 303*1f13597dSJung-uk Kim 304*1f13597dSJung-uk Kim 305*1f13597dSJung-uk Kim int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al) 306*1f13597dSJung-uk Kim { 307*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *cprof,*sprof; 308*1f13597dSJung-uk Kim STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr; 309*1f13597dSJung-uk Kim int ct; 310*1f13597dSJung-uk Kim int mki_len; 311*1f13597dSJung-uk Kim int i,j; 312*1f13597dSJung-uk Kim int id; 313*1f13597dSJung-uk Kim int ret; 314*1f13597dSJung-uk Kim 315*1f13597dSJung-uk Kim /* Length value + the MKI length */ 316*1f13597dSJung-uk Kim if(len < 3) 317*1f13597dSJung-uk Kim { 318*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); 319*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 320*1f13597dSJung-uk Kim return 1; 321*1f13597dSJung-uk Kim } 322*1f13597dSJung-uk Kim 323*1f13597dSJung-uk Kim /* Pull off the length of the cipher suite list */ 324*1f13597dSJung-uk Kim n2s(d, ct); 325*1f13597dSJung-uk Kim len -= 2; 326*1f13597dSJung-uk Kim 327*1f13597dSJung-uk Kim /* Check that it is even */ 328*1f13597dSJung-uk Kim if(ct%2) 329*1f13597dSJung-uk Kim { 330*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); 331*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 332*1f13597dSJung-uk Kim return 1; 333*1f13597dSJung-uk Kim } 334*1f13597dSJung-uk Kim 335*1f13597dSJung-uk Kim /* Check that lengths are consistent */ 336*1f13597dSJung-uk Kim if(len < (ct + 1)) 337*1f13597dSJung-uk Kim { 338*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); 339*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 340*1f13597dSJung-uk Kim return 1; 341*1f13597dSJung-uk Kim } 342*1f13597dSJung-uk Kim 343*1f13597dSJung-uk Kim 344*1f13597dSJung-uk Kim clnt=sk_SRTP_PROTECTION_PROFILE_new_null(); 345*1f13597dSJung-uk Kim 346*1f13597dSJung-uk Kim while(ct) 347*1f13597dSJung-uk Kim { 348*1f13597dSJung-uk Kim n2s(d,id); 349*1f13597dSJung-uk Kim ct-=2; 350*1f13597dSJung-uk Kim len-=2; 351*1f13597dSJung-uk Kim 352*1f13597dSJung-uk Kim if(!find_profile_by_num(id,&cprof)) 353*1f13597dSJung-uk Kim { 354*1f13597dSJung-uk Kim sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof); 355*1f13597dSJung-uk Kim } 356*1f13597dSJung-uk Kim else 357*1f13597dSJung-uk Kim { 358*1f13597dSJung-uk Kim ; /* Ignore */ 359*1f13597dSJung-uk Kim } 360*1f13597dSJung-uk Kim } 361*1f13597dSJung-uk Kim 362*1f13597dSJung-uk Kim /* Now extract the MKI value as a sanity check, but discard it for now */ 363*1f13597dSJung-uk Kim mki_len = *d; 364*1f13597dSJung-uk Kim d++; len--; 365*1f13597dSJung-uk Kim 366*1f13597dSJung-uk Kim if (mki_len != len) 367*1f13597dSJung-uk Kim { 368*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE); 369*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 370*1f13597dSJung-uk Kim return 1; 371*1f13597dSJung-uk Kim } 372*1f13597dSJung-uk Kim 373*1f13597dSJung-uk Kim srvr=SSL_get_srtp_profiles(s); 374*1f13597dSJung-uk Kim 375*1f13597dSJung-uk Kim /* Pick our most preferred profile. If no profiles have been 376*1f13597dSJung-uk Kim configured then the outer loop doesn't run 377*1f13597dSJung-uk Kim (sk_SRTP_PROTECTION_PROFILE_num() = -1) 378*1f13597dSJung-uk Kim and so we just return without doing anything */ 379*1f13597dSJung-uk Kim for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(srvr);i++) 380*1f13597dSJung-uk Kim { 381*1f13597dSJung-uk Kim sprof=sk_SRTP_PROTECTION_PROFILE_value(srvr,i); 382*1f13597dSJung-uk Kim 383*1f13597dSJung-uk Kim for(j=0;j<sk_SRTP_PROTECTION_PROFILE_num(clnt);j++) 384*1f13597dSJung-uk Kim { 385*1f13597dSJung-uk Kim cprof=sk_SRTP_PROTECTION_PROFILE_value(clnt,j); 386*1f13597dSJung-uk Kim 387*1f13597dSJung-uk Kim if(cprof->id==sprof->id) 388*1f13597dSJung-uk Kim { 389*1f13597dSJung-uk Kim s->srtp_profile=sprof; 390*1f13597dSJung-uk Kim *al=0; 391*1f13597dSJung-uk Kim ret=0; 392*1f13597dSJung-uk Kim goto done; 393*1f13597dSJung-uk Kim } 394*1f13597dSJung-uk Kim } 395*1f13597dSJung-uk Kim } 396*1f13597dSJung-uk Kim 397*1f13597dSJung-uk Kim ret=0; 398*1f13597dSJung-uk Kim 399*1f13597dSJung-uk Kim done: 400*1f13597dSJung-uk Kim if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt); 401*1f13597dSJung-uk Kim 402*1f13597dSJung-uk Kim return ret; 403*1f13597dSJung-uk Kim } 404*1f13597dSJung-uk Kim 405*1f13597dSJung-uk Kim int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen) 406*1f13597dSJung-uk Kim { 407*1f13597dSJung-uk Kim if(p) 408*1f13597dSJung-uk Kim { 409*1f13597dSJung-uk Kim if(maxlen < 5) 410*1f13597dSJung-uk Kim { 411*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); 412*1f13597dSJung-uk Kim return 1; 413*1f13597dSJung-uk Kim } 414*1f13597dSJung-uk Kim 415*1f13597dSJung-uk Kim if(s->srtp_profile==0) 416*1f13597dSJung-uk Kim { 417*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,SSL_R_USE_SRTP_NOT_NEGOTIATED); 418*1f13597dSJung-uk Kim return 1; 419*1f13597dSJung-uk Kim } 420*1f13597dSJung-uk Kim s2n(2, p); 421*1f13597dSJung-uk Kim s2n(s->srtp_profile->id,p); 422*1f13597dSJung-uk Kim *p++ = 0; 423*1f13597dSJung-uk Kim } 424*1f13597dSJung-uk Kim *len=5; 425*1f13597dSJung-uk Kim 426*1f13597dSJung-uk Kim return 0; 427*1f13597dSJung-uk Kim } 428*1f13597dSJung-uk Kim 429*1f13597dSJung-uk Kim 430*1f13597dSJung-uk Kim int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al) 431*1f13597dSJung-uk Kim { 432*1f13597dSJung-uk Kim unsigned id; 433*1f13597dSJung-uk Kim int i; 434*1f13597dSJung-uk Kim int ct; 435*1f13597dSJung-uk Kim 436*1f13597dSJung-uk Kim STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; 437*1f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *prof; 438*1f13597dSJung-uk Kim 439*1f13597dSJung-uk Kim if(len!=5) 440*1f13597dSJung-uk Kim { 441*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); 442*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 443*1f13597dSJung-uk Kim return 1; 444*1f13597dSJung-uk Kim } 445*1f13597dSJung-uk Kim 446*1f13597dSJung-uk Kim n2s(d, ct); 447*1f13597dSJung-uk Kim if(ct!=2) 448*1f13597dSJung-uk Kim { 449*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); 450*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 451*1f13597dSJung-uk Kim return 1; 452*1f13597dSJung-uk Kim } 453*1f13597dSJung-uk Kim 454*1f13597dSJung-uk Kim n2s(d,id); 455*1f13597dSJung-uk Kim if (*d) /* Must be no MKI, since we never offer one */ 456*1f13597dSJung-uk Kim { 457*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_MKI_VALUE); 458*1f13597dSJung-uk Kim *al=SSL_AD_ILLEGAL_PARAMETER; 459*1f13597dSJung-uk Kim return 1; 460*1f13597dSJung-uk Kim } 461*1f13597dSJung-uk Kim 462*1f13597dSJung-uk Kim clnt=SSL_get_srtp_profiles(s); 463*1f13597dSJung-uk Kim 464*1f13597dSJung-uk Kim /* Throw an error if the server gave us an unsolicited extension */ 465*1f13597dSJung-uk Kim if (clnt == NULL) 466*1f13597dSJung-uk Kim { 467*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_NO_SRTP_PROFILES); 468*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 469*1f13597dSJung-uk Kim return 1; 470*1f13597dSJung-uk Kim } 471*1f13597dSJung-uk Kim 472*1f13597dSJung-uk Kim /* Check to see if the server gave us something we support 473*1f13597dSJung-uk Kim (and presumably offered) 474*1f13597dSJung-uk Kim */ 475*1f13597dSJung-uk Kim for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(clnt);i++) 476*1f13597dSJung-uk Kim { 477*1f13597dSJung-uk Kim prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i); 478*1f13597dSJung-uk Kim 479*1f13597dSJung-uk Kim if(prof->id == id) 480*1f13597dSJung-uk Kim { 481*1f13597dSJung-uk Kim s->srtp_profile=prof; 482*1f13597dSJung-uk Kim *al=0; 483*1f13597dSJung-uk Kim return 0; 484*1f13597dSJung-uk Kim } 485*1f13597dSJung-uk Kim } 486*1f13597dSJung-uk Kim 487*1f13597dSJung-uk Kim SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); 488*1f13597dSJung-uk Kim *al=SSL_AD_DECODE_ERROR; 489*1f13597dSJung-uk Kim return 1; 490*1f13597dSJung-uk Kim } 491*1f13597dSJung-uk Kim 492*1f13597dSJung-uk Kim 493*1f13597dSJung-uk Kim #endif 494