From: Dr. Stephen Henson Date: Thu, 12 May 2011 14:38:01 +0000 (+0000) Subject: Process signature algorithms during TLS v1.2 client authentication. X-Git-Tag: OpenSSL-fips-2_0-rc1~435 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=8f82912460c3066fc222d8e5893187df0566fc18 Process signature algorithms during TLS v1.2 client authentication. Make sure message is long enough for signature algorithms. --- diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 0541de95b9..5d3dfcc389 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -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); diff --git a/ssl/ssl.h b/ssl/ssl.h index 755dd853dc..1c1a4956fe 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -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 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 76c8e1e33e..ceb4b98199 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -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"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 78958d4506..1c17de74e5 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -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 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 66fef29746..928295eab8 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={ @@ -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. */