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

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

index 0541de95b9308f30e46b756395c23b7943e8477b..5d3dfcc3890bc2d5353dc8b2204f1a75da054132 100644 (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);
index 755dd853dcf2e2da7ec774dc73c572f744641821..1c1a4956fecaa8d5cd74d689c196c87a644b31e4 100644 (file)
--- 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
index 76c8e1e33e2d1990407d7acd83a04ddee2a43946..ceb4b98199d750194b0515168a01972d1ec6e7ce 100644 (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"},
index 78958d4506b0e6dc434db06f8dbaab87d3752a81..1c17de74e54b0af796a0844ffc23b295d86b943f 100644 (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
index 66fef29746386dd017d9d32837a04f66378e034a..928295eab80744ee2d213baf1a703e5c3a0cdcf0 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={
@@ -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.
         */