Process signature algorithms during TLS v1.2 client authentication.

Make sure message is long enough for signature algorithms.

(backport from HEAD).
This commit is contained in:
Dr. Stephen Henson 2011-05-12 17:44:59 +00:00
parent d768a816aa
commit 376838a606
5 changed files with 27 additions and 11 deletions

View File

@ -1775,7 +1775,7 @@ int ssl3_get_certificate_request(SSL *s)
{ {
int ok,ret=0; int ok,ret=0;
unsigned long n,nc,l; unsigned long n,nc,l;
unsigned int llen,sigalglen, ctype_num,i; unsigned int llen, ctype_num,i;
X509_NAME *xn=NULL; X509_NAME *xn=NULL;
const unsigned char *p,*q; const unsigned char *p,*q;
unsigned char *d; unsigned char *d;
@ -1834,14 +1834,24 @@ int ssl3_get_certificate_request(SSL *s)
/* HACK! For now just skip over signatature algorithms */ /* HACK! For now just skip over signatature algorithms */
if (s->version >= TLS1_2_VERSION) if (s->version >= TLS1_2_VERSION)
{ {
n2s(p, sigalglen); n2s(p, llen);
p += sigalglen; /* Check we have enough room for signature algorithms and
sigalglen += 2; * 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 */ /* get the CA RDNs */
n2s(p,llen); n2s(p,llen);
@ -1854,7 +1864,7 @@ fclose(out);
} }
#endif #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); ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH);

View File

@ -2357,6 +2357,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_SERVERHELLO_TLSEXT 275 #define SSL_R_SERVERHELLO_TLSEXT 275
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
#define SSL_R_SHORT_READ 219 #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_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
#define SSL_R_SRP_A_CALC 354 #define SSL_R_SRP_A_CALC 354
#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221

View File

@ -473,6 +473,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"}, {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"}, {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"}, {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_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_SRP_A_CALC) ,"error with the srp params"},
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"}, {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},

View File

@ -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 ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
int *al); int *al);
long ssl_get_algorithm2(SSL *s); long ssl_get_algorithm2(SSL *s);
int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
#endif #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, static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
const unsigned char *sess_id, int sesslen, const unsigned char *sess_id, int sesslen,
SSL_SESSION **psess); SSL_SESSION **psess);
static int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
#endif #endif
SSL3_ENC_METHOD TLSv1_enc_data={ 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 */ /* 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; int i, idx;
const EVP_MD *md; 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 */ /* Extension ignored for TLS versions below 1.2 */
if (s->version < TLS1_2_VERSION) if (s->version < TLS1_2_VERSION)
return 1; return 1;
/* Should never happen */
if (!c)
return 0;
c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL; c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL;
c->pkeys[SSL_PKEY_RSA_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 /* Set any remaining keys to default values. NOTE: if alg is not
* supported it stays as NULL. * supported it stays as NULL.
*/ */