summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2011-05-12 14:38:01 +0000
committerDr. Stephen Henson <steve@openssl.org>2011-05-12 14:38:01 +0000
commit8f82912460c3066fc222d8e5893187df0566fc18 (patch)
tree9edca03eded9e84504358441d752e82dc07a16ee
parentf76b1baf8683e278aa4fc8992168fc6e375f0585 (diff)
Process signature algorithms during TLS v1.2 client authentication.
Make sure message is long enough for signature algorithms.
-rw-r--r--ssl/s3_clnt.c28
-rw-r--r--ssl/ssl.h1
-rw-r--r--ssl/ssl_err.c1
-rw-r--r--ssl/ssl_locl.h1
-rw-r--r--ssl/t1_lib.c7
5 files changed, 27 insertions, 11 deletions
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.
*/