summaryrefslogtreecommitdiff
path: root/external/openssl/CVE-2014-3513.patch
blob: 96d4584c38ead9a5dd372cd2a55364f0ebc47d85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
diff -up openssl-1.0.1e/ssl/d1_srtp.c.srtp-leak openssl-1.0.1e/ssl/d1_srtp.c
--- a/a/ssl/d1_srtp.c.srtp-leak	2013-02-11 16:26:04.000000000 +0100
+++ b/b/ssl/d1_srtp.c	2014-10-15 13:23:34.253040160 +0200
@@ -168,25 +168,6 @@ static int find_profile_by_name(char *pr
 	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;
@@ -209,11 +190,19 @@ static int ssl_ctx_make_profiles(const c
 		if(!find_profile_by_name(ptr,&p,
 					 col ? col-ptr : (int)strlen(ptr)))
 			{
+			if (sk_SRTP_PROTECTION_PROFILE_find(profiles,p) >= 0)
+				{
+				SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+				sk_SRTP_PROTECTION_PROFILE_free(profiles);
+				return 1;
+				}
+
 			sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
 			}
 		else
 			{
 			SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+			sk_SRTP_PROTECTION_PROFILE_free(profiles);
 			return 1;
 			}
 
@@ -305,13 +294,12 @@ int ssl_add_clienthello_use_srtp_ext(SSL
 
 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;
+	SRTP_PROTECTION_PROFILE *sprof;
+	STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
         int ct;
         int mki_len;
-	int i,j;
-	int id;
-	int ret;
+	int i, srtp_pref;
+	unsigned int id;
 
          /* Length value + the MKI length */
         if(len < 3)
@@ -341,22 +329,32 @@ int ssl_parse_clienthello_use_srtp_ext(S
 		return 1;
 		}
 
+	srvr=SSL_get_srtp_profiles(s);
+	s->srtp_profile = NULL;
+	/* Search all profiles for a match initially */
+	srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
         
-	clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
-
 	while(ct)
 		{
 		n2s(d,id);
 		ct-=2;
                 len-=2;
 
-		if(!find_profile_by_num(id,&cprof))
+		/*
+		 * Only look for match in profiles of higher preference than
+		 * current match.
+		 * If no profiles have been have been configured then this
+		 * does nothing.
+		 */
+		for (i = 0; i < srtp_pref; i++)
 			{
-			sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof);
-			}
-		else
-			{
-			; /* Ignore */
+			sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
+			if (sprof->id == id)
+				{
+				s->srtp_profile = sprof;
+				srtp_pref = i;
+				break;
+				}
 			}
 		}
 
@@ -371,36 +369,7 @@ int ssl_parse_clienthello_use_srtp_ext(S
 		return 1;
 		}
 
-	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;
+	return 0;
 	}
 
 int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
diff -up openssl-1.0.1e/ssl/t1_lib.c.srtp-leak openssl-1.0.1e/ssl/t1_lib.c
--- a/a/ssl/t1_lib.c.srtp-leak	2014-10-15 13:19:59.955202293 +0200
+++ b/b/ssl/t1_lib.c	2014-10-15 13:23:34.254040182 +0200
@@ -696,7 +696,7 @@ unsigned char *ssl_add_clienthello_tlsex
 #endif
 
 #ifndef OPENSSL_NO_SRTP
-        if(SSL_get_srtp_profiles(s))
+	if(SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s))
                 {
                 int el;
 
@@ -829,7 +829,7 @@ unsigned char *ssl_add_serverhello_tlsex
 #endif
 
 #ifndef OPENSSL_NO_SRTP
-        if(s->srtp_profile)
+	if(SSL_IS_DTLS(s) && s->srtp_profile)
                 {
                 int el;
 
@@ -1377,7 +1377,8 @@ int ssl_parse_clienthello_tlsext(SSL *s,
 
 		/* session ticket processed earlier */
 #ifndef OPENSSL_NO_SRTP
-		else if (type == TLSEXT_TYPE_use_srtp)
+		else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
+			 && type == TLSEXT_TYPE_use_srtp)
 			{
 			if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
 							      al))
@@ -1631,7 +1632,7 @@ int ssl_parse_serverhello_tlsext(SSL *s,
 			}
 #endif
 #ifndef OPENSSL_NO_SRTP
-		else if (type == TLSEXT_TYPE_use_srtp)
+		else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp)
 			{
                         if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
 							      al))