Process signature algorithms during TLS v1.2 client authentication.
authorDr. Stephen Henson <steve@openssl.org>
Thu, 12 May 2011 17:44:59 +0000 (17:44 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 12 May 2011 17:44:59 +0000 (17:44 +0000)
Make sure message is long enough for signature algorithms.

(backport from HEAD).

ssl/s3_clnt.c
ssl/ssl.h
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/t1_lib.c

index b8e2b89df4579b402958b776528162b283a8ee3e..75f0a8e052027a240bad66ce3a45c5eed9fd9e54 100644 (file)
@@ -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);
index 26e6077e1de401ec4ca673a50396f26b696a90f6..f5e6cc00e938dfc71133b33ad5305c4f3a3724fa 100644 (file)
--- 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
index 46f45ce76b9d39e948f16e6fb8b98bf9346999a6..895b00a973410b93eb98032511e41dd2778da33c 100644 (file)
@@ -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"},
index 8eb986065a04988293158bd3165a0f496c736b99..9847e5eb516f77f8b947f48c70bc900c8ef2d0c5 100644 (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 *al);
 long ssl_get_algorithm2(SSL *s);
+int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
 #endif
index 9bed9a33dc32fed9dcabf0de2eb18cc133ac15aa..bf721929d7fdbce4da7d33e43a5b7ee1dfc4eb6b 100644 (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={
@@ -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.
         */