xref: /freebsd/crypto/openssl/ssl/d1_srtp.c (revision 1f13597d10e771d5546d31839150812bde8e4a56)
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