Fix for SRTP Memory Leak
CVE-2014-3513 This issue was reported to OpenSSL on 26th September 2014, based on an origi issue and patch developed by the LibreSSL project. Further analysis of the i was performed by the OpenSSL team. The fix was developed by the OpenSSL team. Reviewed-by: Tim Hudson <tjh@openssl.org>
This commit is contained in:
parent
7d07c75c5b
commit
2b0532f398
@ -168,25 +168,6 @@ static int find_profile_by_name(char *profile_name,
|
|||||||
return 1;
|
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)
|
static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out)
|
||||||
{
|
{
|
||||||
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
|
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
|
||||||
@ -209,11 +190,19 @@ static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTE
|
|||||||
if(!find_profile_by_name(ptr,&p,
|
if(!find_profile_by_name(ptr,&p,
|
||||||
col ? col-ptr : (int)strlen(ptr)))
|
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);
|
sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
|
SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
|
||||||
|
sk_SRTP_PROTECTION_PROFILE_free(profiles);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,13 +294,12 @@ int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max
|
|||||||
|
|
||||||
int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
|
int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
|
||||||
{
|
{
|
||||||
SRTP_PROTECTION_PROFILE *cprof,*sprof;
|
SRTP_PROTECTION_PROFILE *sprof;
|
||||||
STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr;
|
STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
|
||||||
int ct;
|
int ct;
|
||||||
int mki_len;
|
int mki_len;
|
||||||
int i,j;
|
int i, srtp_pref;
|
||||||
int id;
|
unsigned int id;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Length value + the MKI length */
|
/* Length value + the MKI length */
|
||||||
if(len < 3)
|
if(len < 3)
|
||||||
@ -341,8 +329,10 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srvr=SSL_get_srtp_profiles(s);
|
||||||
clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
|
s->srtp_profile = NULL;
|
||||||
|
/* Search all profiles for a match initially */
|
||||||
|
srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
|
||||||
|
|
||||||
while(ct)
|
while(ct)
|
||||||
{
|
{
|
||||||
@ -350,13 +340,21 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
|
|||||||
ct-=2;
|
ct-=2;
|
||||||
len-=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);
|
sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
|
||||||
}
|
if (sprof->id == id)
|
||||||
else
|
{
|
||||||
{
|
s->srtp_profile = sprof;
|
||||||
; /* Ignore */
|
srtp_pref = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,36 +369,7 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
srvr=SSL_get_srtp_profiles(s);
|
return 0;
|
||||||
|
|
||||||
/* 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)
|
int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
|
||||||
|
@ -643,7 +643,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_SRTP
|
#ifndef OPENSSL_NO_SRTP
|
||||||
if(SSL_get_srtp_profiles(s))
|
if(SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s))
|
||||||
{
|
{
|
||||||
int el;
|
int el;
|
||||||
|
|
||||||
@ -806,7 +806,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_SRTP
|
#ifndef OPENSSL_NO_SRTP
|
||||||
if(s->srtp_profile)
|
if(SSL_IS_DTLS(s) && s->srtp_profile)
|
||||||
{
|
{
|
||||||
int el;
|
int el;
|
||||||
|
|
||||||
@ -1444,7 +1444,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||||||
|
|
||||||
/* session ticket processed earlier */
|
/* session ticket processed earlier */
|
||||||
#ifndef OPENSSL_NO_SRTP
|
#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,
|
if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
|
||||||
al))
|
al))
|
||||||
@ -1698,7 +1699,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef OPENSSL_NO_SRTP
|
#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,
|
if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
|
||||||
al))
|
al))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user