Process signature algorithms during TLS v1.2 client authentication.

Make sure message is long enough for signature algorithms.
This commit is contained in:
Dr. Stephen Henson 2011-05-12 14:38:01 +00:00
parent f76b1baf86
commit 8f82912460
5 changed files with 27 additions and 11 deletions

View File

@ -1793,7 +1793,7 @@ int ssl3_get_certificate_request(SSL *s)
{
int ok,ret=0;
unsigned long n,nc,l;
unsigned int llen,sigalglen, ctype_num,i;
unsigned int llen, ctype_num,i;
X509_NAME *xn=NULL;
const unsigned char *p,*q;
unsigned char *d;
@ -1852,14 +1852,24 @@ int ssl3_get_certificate_request(SSL *s)
/* HACK! For now just skip over signatature algorithms */
if (s->version >= TLS1_2_VERSION)
{
n2s(p, sigalglen);
p += sigalglen;
sigalglen += 2;
n2s(p, llen);
/* Check we have enough room for signature algorithms and
* following length value.
*/
if ((unsigned long)(p - d + llen + 2) > n)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
if ((llen & 1) || !tls1_process_sigalgs(s, p, llen))
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_SIGNATURE_ALGORITHMS_ERROR);
goto err;
}
p += llen;
}
else
sigalglen = 0;
/* get the CA RDNs */
n2s(p,llen);
@ -1872,7 +1882,7 @@ fclose(out);
}
#endif
if ((llen+ctype_num+sigalglen+2+1) != n)
if ((unsigned long)(p - d + llen) != n)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);

View File

@ -2433,6 +2433,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_SERVERHELLO_TLSEXT 275
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
#define SSL_R_SHORT_READ 219
#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 359
#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
#define SSL_R_SRP_A_CALC 356
#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221

View File

@ -476,6 +476,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
{ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR),"signature algorithms error"},
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
{ERR_REASON(SSL_R_SRP_A_CALC) ,"error with the srp params"},
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},

View File

@ -1095,4 +1095,5 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
int *al);
long ssl_get_algorithm2(SSL *s);
int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
#endif

View File

@ -122,7 +122,6 @@ const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
const unsigned char *sess_id, int sesslen,
SSL_SESSION **psess);
static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
#endif
SSL3_ENC_METHOD TLSv1_enc_data={
@ -2090,7 +2089,7 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg)
/* Set preferred digest for each key type */
static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
{
int i, idx;
const EVP_MD *md;
@ -2098,6 +2097,9 @@ static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
/* Extension ignored for TLS versions below 1.2 */
if (s->version < TLS1_2_VERSION)
return 1;
/* Should never happen */
if (!c)
return 0;
c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL;
c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL;
@ -2142,6 +2144,7 @@ static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
}
/* Set any remaining keys to default values. NOTE: if alg is not
* supported it stays as NULL.
*/