Home | History | Annotate | Download | only in patches
      1 From c8b1f7ec56704c1116795aec9ca61db654b433bf Mon Sep 17 00:00:00 2001
      2 From: Alex Klyubin <klyubin (a] google.com>
      3 Date: Mon, 19 May 2014 11:27:33 -0700
      4 Subject: psk_client_callback, 128-byte id bug.
      5 
      6 Fix a bug in handling of 128 byte long PSK identity in
      7 psk_client_callback.
      8 
      9 OpenSSL supports PSK identities of up to (and including) 128 bytes in
     10 length. PSK identity is obtained via the psk_client_callback,
     11 implementors of which are expected to provide a NULL-terminated
     12 identity. However, the callback is invoked with only 128 bytes of
     13 storage thus making it impossible to return a 128 byte long identity and
     14 the required additional NULL byte.
     15 
     16 This CL fixes the issue by passing in a 129 byte long buffer into the
     17 psk_client_callback. As a safety precaution, this CL also zeroes out the
     18 buffer before passing it into the callback, uses strnlen for obtaining
     19 the length of the identity returned by the callback, and aborts the
     20 handshake if the identity (without the NULL terminator) is longer than
     21 128 bytes.
     22 ---
     23  ssl/s3_clnt.c | 20 ++++++++++++++------
     24  1 file changed, 14 insertions(+), 6 deletions(-)
     25 
     26 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
     27 index 03b96e8..0e22afc 100644
     28 --- a/ssl/s3_clnt.c
     29 +++ b/ssl/s3_clnt.c
     30 @@ -2328,7 +2328,8 @@ int ssl3_send_client_key_exchange(SSL *s)
     31  #ifndef OPENSSL_NO_PSK
     32  		if (alg_a & SSL_aPSK)
     33  			{
     34 -			char identity[PSK_MAX_IDENTITY_LEN];
     35 +			char identity[PSK_MAX_IDENTITY_LEN + 1];
     36 +			size_t identity_len;
     37  			unsigned char *t = NULL;
     38  			unsigned char pre_ms[PSK_MAX_PSK_LEN*2+4];
     39  			unsigned int pre_ms_len = 0;
     40 @@ -2342,8 +2343,9 @@ int ssl3_send_client_key_exchange(SSL *s)
     41  				goto err;
     42  				}
     43  
     44 +			memset(identity, 0, sizeof(identity));
     45  			psk_len = s->psk_client_callback(s, s->session->psk_identity_hint,
     46 -				identity, PSK_MAX_IDENTITY_LEN, psk, sizeof(psk));
     47 +				identity, sizeof(identity), psk, sizeof(psk));
     48  			if (psk_len > PSK_MAX_PSK_LEN)
     49  				{
     50  				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
     51 @@ -2356,6 +2358,13 @@ int ssl3_send_client_key_exchange(SSL *s)
     52  					SSL_R_PSK_IDENTITY_NOT_FOUND);
     53  				goto psk_err;
     54  				}
     55 +			identity_len = strnlen(identity, sizeof(identity));
     56 +			if (identity_len > PSK_MAX_IDENTITY_LEN)
     57 +				{
     58 +				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
     59 +					ERR_R_INTERNAL_ERROR);
     60 +				goto psk_err;
     61 +				}
     62  
     63  			if (!(alg_k & SSL_kEECDH))
     64  				{
     65 @@ -2372,10 +2381,9 @@ int ssl3_send_client_key_exchange(SSL *s)
     66  					s->method->ssl3_enc->generate_master_secret(s,
     67  						s->session->master_key,
     68  						pre_ms, pre_ms_len);
     69 -				n = strlen(identity);
     70 -				s2n(n, p);
     71 -				memcpy(p, identity, n);
     72 -				n += 2;
     73 +				s2n(identity_len, p);
     74 +				memcpy(p, identity, identity_len);
     75 +				n = 2 + identity_len;
     76  				}
     77  
     78  			if (s->session->psk_identity != NULL)
     79 -- 
     80 2.0.0.526.g5318336
     81 
     82