From 376838a6064c07e53806a025a82f5ade4a8edca3 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 12 May 2011 17:44:59 +0000 Subject: [PATCH] Process signature algorithms during TLS v1.2 client authentication. Make sure message is long enough for signature algorithms. (backport from HEAD). --- ssl/s3_clnt.c | 28 +++++++++++++++++++--------- ssl/ssl.h | 1 + ssl/ssl_err.c | 1 + ssl/ssl_locl.h | 1 + ssl/t1_lib.c | 7 +++++-- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index b8e2b89df4..75f0a8e052 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -1775,7 +1775,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; @@ -1834,14 +1834,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); @@ -1854,7 +1864,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); diff --git a/ssl/ssl.h b/ssl/ssl.h index 26e6077e1d..f5e6cc00e9 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -2357,6 +2357,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 354 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 46f45ce76b..895b00a973 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -473,6 +473,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"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 8eb986065a..9847e5eb51 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1091,4 +1091,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 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 9bed9a33dc..bf721929d7 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -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={ @@ -1976,7 +1975,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; @@ -1984,6 +1983,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; @@ -2028,6 +2030,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. */ -- 2.25.1