diff options
author | David Benjamin <davidben@chromium.org> | 2014-06-25 07:27:17 +0400 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2014-06-27 00:42:27 +0400 |
commit | 03973096f416e694b676160ca481553bb44738eb (patch) | |
tree | ae05170c9a5e9660c46ca1e137345071846be0bc /ssl/d1_srtp.c | |
parent | 8adf4f1d891679df91e1d1551527b6fc0c8a7d15 (diff) |
Port ServerHello extension parsing to CBS.
This gives us systematic bounds-checking on all the parses. Also adds a
convenience function, CBS_memdup, for saving the current contents of a CBS.
Change-Id: I17dad74575f03121aee3f771037b8806ff99d0c3
Reviewed-on: https://boringssl-review.googlesource.com/1031
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'ssl/d1_srtp.c')
-rw-r--r-- | ssl/d1_srtp.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c index e98b5125..c27d7664 100644 --- a/ssl/d1_srtp.c +++ b/ssl/d1_srtp.c @@ -118,6 +118,7 @@ #include <stdio.h> +#include <openssl/bytestring.h> #include <openssl/obj.h> #include <openssl/err.h> @@ -429,35 +430,37 @@ int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max } -int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al) +int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) { - unsigned id; + CBS profile_ids, srtp_mki; + uint16_t profile_id; int i; - int ct; STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; SRTP_PROTECTION_PROFILE *prof; - if(len!=5) - { - OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al=SSL_AD_DECODE_ERROR; - return 1; - } - - n2s(d, ct); - if(ct!=2) + /* The extension consists of a u16-prefixed profile ID list containing a + * single uint16_t profile ID, then followed by a u8-prefixed srtp_mki + * field. + * + * See https://tools.ietf.org/html/rfc5764#section-4.1.1 + */ + if (!CBS_get_u16_length_prefixed(cbs, &profile_ids) || + !CBS_get_u16(&profile_ids, &profile_id) || + CBS_len(&profile_ids) != 0 || + !CBS_get_u8_length_prefixed(cbs, &srtp_mki) || + CBS_len(cbs) != 0) { OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al=SSL_AD_DECODE_ERROR; + *out_alert = SSL_AD_DECODE_ERROR; return 1; } - n2s(d,id); - if (*d) /* Must be no MKI, since we never offer one */ + if (CBS_len(&srtp_mki) != 0) { + /* Must be no MKI, since we never offer one. */ OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext, SSL_R_BAD_SRTP_MKI_VALUE); - *al=SSL_AD_ILLEGAL_PARAMETER; + *out_alert = SSL_AD_ILLEGAL_PARAMETER; return 1; } @@ -467,7 +470,7 @@ int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al if (clnt == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext, SSL_R_NO_SRTP_PROFILES); - *al=SSL_AD_DECODE_ERROR; + *out_alert = SSL_AD_DECODE_ERROR; return 1; } @@ -478,16 +481,16 @@ int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al { prof=sk_SRTP_PROTECTION_PROFILE_value(clnt,i); - if(prof->id == id) + if(prof->id == profile_id) { s->srtp_profile=prof; - *al=0; + *out_alert = 0; return 0; } } OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al=SSL_AD_DECODE_ERROR; + *out_alert = SSL_AD_ILLEGAL_PARAMETER; return 1; } |