Make maximum certifcate chain size accepted from the peer application
authorLutz Jänicke <jaenicke@openssl.org>
Tue, 11 Sep 2001 13:08:51 +0000 (13:08 +0000)
committerLutz Jänicke <jaenicke@openssl.org>
Tue, 11 Sep 2001 13:08:51 +0000 (13:08 +0000)
settable (proposed by "Douglas E. Engert" <deengert@anl.gov>).

CHANGES
doc/ssl/SSL_CTX_set_max_cert_list.pod [new file with mode: 0644]
doc/ssl/ssl.pod
ssl/s3_clnt.c
ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl_lib.c

diff --git a/CHANGES b/CHANGES
index 7ae61a558ffa7a7560609b325547ba397266b0a5..3b467094cba307d22bf4835bd68904ed3f18506d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
          *) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7
          +) applies to 0.9.7 only
 
+  +) Make maximum certificate chain size accepted from the peer application
+     settable (SSL*_get/set_max_cert_list()), as proposed by
+     "Douglas E. Engert" <deengert@anl.gov>.
+     [Lutz Jaenicke]
+
   +) Add support for shared libraries for Unixware-7 and support including
      shared libraries for OpenUNIX-8 (Boyd Lynn Gerber <gerberb@zenez.com>).
      [Lutz Jaenicke]
diff --git a/doc/ssl/SSL_CTX_set_max_cert_list.pod b/doc/ssl/SSL_CTX_set_max_cert_list.pod
new file mode 100644 (file)
index 0000000..da68cb9
--- /dev/null
@@ -0,0 +1,77 @@
+=pod
+
+=head1 NAME
+
+SSL_CTX_set_max_cert_list, SSL_CTX_get_max_cert_list, SSL_set_max_cert_list, SSL_get_max_cert_list, - manipulate allowed for the peer's certificate chain
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ long SSL_CTX_set_max_cert_list(SSL_CTX *ctx, long size);
+ long SSL_CTX_get_max_cert_list(SSL_CTX *ctx);
+
+ long SSL_set_max_cert_list(SSL *ssl, long size);
+ long SSL_get_max_cert_list(SSL *ctx);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set_max_cert_list() sets the maximum size allowed for the peer's
+certificate chain for all SSL objects created from B<ctx> to be <size> bytes.
+The SSL objects inherit the setting valid for B<ctx> at the time
+L<SSL_new(3)|SSL_new(3)> is being called.
+
+SSL_CTX_get_max_cert_list() returns the currently set maximum size for B<ctx>.
+
+SSL_set_max_cert_list() sets the maximum size allowed for the peer's
+certificate chain for B<ssl> to be <size> bytes. This setting stays valid
+until a new value is set.
+
+SSL_get_max_cert_list() returns the currently set maximum size for B<ssl>.
+
+=head1 NOTES
+
+During the handshake process, the peer may send a certificate chain.
+The TLS/SSL standard does not give any maximum size of the certificate chain.
+The OpenSSL library handles incoming data by a dynamically allocated buffer.
+In order to prevent this buffer from growing without bounds due to data
+received from a faulty or malicious peer, a maximum size for the certificate
+chain is set.
+
+The default value for the maximum certificate chain size is 100kB (30kB
+on the 16bit DOS platform). This should be sufficient for usual certificate
+chains (OpenSSL's default maximum chain length is 10, see
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>, and certificates
+without special extensions have a typical size of 1-2kB).
+
+For special applications it can be necessary to extend the maximum certificate
+chain size allowed to be sent by the peer, see e.g. the work on
+"Internet X.509 Public Key Infrastructure Proxy Certificate Profile"
+and "TLS Delegation Protocol" at http://www.ietf.org/ and
+http://www.globus.org/ .
+
+Under normal conditions it should never be necessary to set a value smaller
+than the default, as the buffer is handled dynamically and only uses the
+memory actually required by the data sent by the peer.
+
+If the maximum certificate chain size allowed is exceeded, the handshake will
+fail with a SSL_R_EXCESSIVE_MESSAGE_SIZE error.
+
+=head1 RETURN VALUES
+
+SSL_CTX_set_max_cert_list() and SSL_set_max_cert_list() return the previously
+set value.
+
+SSL_CTX_get_max_cert_list() and SSL_get_max_cert_list() return the currently
+set value.
+
+=head1 SEE ALSO
+
+L<ssl(3)|ssl(3)>, L<SSL_new(3)|SSL_new(3)>,
+L<SSL_CTX_set_verify(3)|SSL_CTX_set_verify(3)>
+
+=head1 HISTORY
+
+SSL*_set/get_max_cert_list() have been introduced in OpenSSL 0.9.7.
+
+=cut
index 6845f4f76d58cabdbfeea414d354e644c54b1500..89b321edec8f0e57f14e5a3b1b0095cb40ff2af0 100644 (file)
@@ -669,6 +669,7 @@ L<SSL_CTX_set_client_CA_list(3)|SSL_CTX_set_client_CA_list(3)>,
 L<SSL_CTX_set_default_passwd_cb(3)|SSL_CTX_set_default_passwd_cb(3)>,
 L<SSL_CTX_set_generate_session_id(3)|SSL_CTX_set_generate_session_id(3)>,
 L<SSL_CTX_set_info_callback(3)|SSL_CTX_set_info_callback(3)>,
+L<SSL_CTX_set_max_cert_list(3)|SSL_CTX_set_max_cert_list(3)>,
 L<SSL_CTX_set_mode(3)|SSL_CTX_set_mode(3)>,
 L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)>,
 L<SSL_CTX_set_quiet_shutdown(3)|SSL_CTX_set_quiet_shutdown(3)>,
index 18133f3da5ae7fd9c7a53d3db13f33e0f2468ccf..36068780e7f5044f5d1074c0dbfb5ea833b3cb2c 100644 (file)
@@ -695,11 +695,7 @@ static int ssl3_get_server_certificate(SSL *s)
                SSL3_ST_CR_CERT_A,
                SSL3_ST_CR_CERT_B,
                -1,
-#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
-               1024*30, /* 30k max cert list :-) */
-#else
-               1024*100, /* 100k max cert list :-) */
-#endif
+               s->max_cert_list,
                &ok);
 
        if (!ok) return((int)n);
@@ -890,11 +886,7 @@ static int ssl3_get_key_exchange(SSL *s)
                SSL3_ST_CR_KEY_EXCH_A,
                SSL3_ST_CR_KEY_EXCH_B,
                -1,
-#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
-               1024*30,  /* 30k max cert list :-) */
-#else
-               1024*100, /* 100k max cert list :-) */
-#endif
+               s->max_cert_list,
                &ok);
 
        if (!ok) return((int)n);
@@ -1196,11 +1188,7 @@ static int ssl3_get_certificate_request(SSL *s)
                SSL3_ST_CR_CERT_REQ_A,
                SSL3_ST_CR_CERT_REQ_B,
                -1,
-#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
-               1024*30,  /* 30k max cert list :-) */
-#else
-               1024*100, /* 100k max cert list :-) */
-#endif
+               s->max_cert_list,
                &ok);
 
        if (!ok) return((int)n);
index 4d0d80065a8e80feff0546267e17cc2e7a95f605..de840808447d6c663238beb242290887021d776b 100644 (file)
@@ -550,11 +550,7 @@ static int ssl3_check_client_hello(SSL *s)
                SSL3_ST_SR_CERT_A,
                SSL3_ST_SR_CERT_B,
                -1,
-#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
-               1024*30, /* 30k max cert list :-) */
-#else
-               1024*100, /* 100k max cert list :-) */
-#endif
+               s->max_cert_list,
                &ok);
        if (!ok) return((int)n);
        s->s3->tmp.reuse_message = 1;
@@ -1775,11 +1771,7 @@ static int ssl3_get_client_certificate(SSL *s)
                SSL3_ST_SR_CERT_A,
                SSL3_ST_SR_CERT_B,
                -1,
-#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
-               1024*30, /* 30k max cert list :-) */
-#else
-               1024*100, /* 100k max cert list :-) */
-#endif
+               s->max_cert_list,
                &ok);
 
        if (!ok) return((int)n);
index c5f24eb51c38f28f2d69fabe72b0e4f2bf60af17..538d11a0c0ecce69f86efeb2a0253eafd0f92e55 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -391,6 +391,12 @@ typedef struct ssl_session_st
 #define SSL_get_mode(ssl) \
         SSL_ctrl(ssl,SSL_CTRL_MODE,0,NULL)
 
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
+#else
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */
+#endif
+
 #define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT     (1024*20)
 
 /* This callback type is used inside SSL_CTX, SSL, and in the functions that set
@@ -427,6 +433,7 @@ struct ssl_ctx_st
        SSL_METHOD *method;
        unsigned long options;
        unsigned long mode;
+       long max_cert_list;
 
        STACK_OF(SSL_CIPHER) *cipher_list;
        /* same as above but sorted for lookup */
@@ -727,6 +734,7 @@ struct ssl_st
        int references;
        unsigned long options; /* protocol behaviour */
        unsigned long mode; /* API behaviour */
+       long max_cert_list;
        int first_packet;
        int client_version;     /* what was passed, used for
                                 * SSLv3/TLS rollback check */
@@ -918,7 +926,7 @@ size_t SSL_get_peer_finished(SSL *s, void *buf, size_t count);
 #define SSL_CTRL_SESS_TIMEOUTS                 30
 #define SSL_CTRL_SESS_CACHE_FULL               31
 #define SSL_CTRL_OPTIONS                       32
-#define SSL_CTRL_MODE                  33
+#define SSL_CTRL_MODE                          33
 
 #define SSL_CTRL_GET_READ_AHEAD                        40
 #define SSL_CTRL_SET_READ_AHEAD                        41
@@ -927,6 +935,9 @@ size_t SSL_get_peer_finished(SSL *s, void *buf, size_t count);
 #define SSL_CTRL_SET_SESS_CACHE_MODE           44
 #define SSL_CTRL_GET_SESS_CACHE_MODE           45
 
+#define SSL_CTRL_GET_MAX_CERT_LIST             50
+#define SSL_CTRL_SET_MAX_CERT_LIST             51
+
 #define SSL_session_reused(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
 #define SSL_num_renegotiations(ssl) \
@@ -1230,6 +1241,14 @@ int SSL_get_ex_data_X509_STORE_CTX_idx(void );
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
 #define SSL_CTX_set_read_ahead(ctx,m) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
+#define SSL_CTX_get_max_cert_list(ctx) \
+       SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_CTX_set_max_cert_list(ctx,m) \
+       SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+#define SSL_get_max_cert_list(ssl) \
+       SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_set_max_cert_list(ssl,m) \
+       SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
 
      /* NB: the keylength is only applicable when is_export is true */
 #ifndef OPENSSL_NO_RSA
index 8aec403c5a57530fe9efe2461b0d9ad3c0cf4951..89c3c2d4f498460ea8b625b9fdc0f229844085d0 100644 (file)
@@ -234,6 +234,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
        s->options=ctx->options;
        s->mode=ctx->mode;
+       s->max_cert_list=ctx->max_cert_list;
        s->read_ahead=ctx->read_ahead; /* used to happen in SSL_clear */
        SSL_clear(s);
 
@@ -851,6 +852,12 @@ long SSL_ctrl(SSL *s,int cmd,long larg,char *parg)
                return(s->options|=larg);
        case SSL_CTRL_MODE:
                return(s->mode|=larg);
+       case SSL_CTRL_GET_MAX_CERT_LIST:
+               return(s->max_cert_list);
+       case SSL_CTRL_SET_MAX_CERT_LIST:
+               l=s->max_cert_list;
+               s->max_cert_list=larg;
+               return(l);
        default:
                return(s->method->ssl_ctrl(s,cmd,larg,parg));
                }
@@ -882,6 +889,12 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,char *parg)
                l=ctx->read_ahead;
                ctx->read_ahead=larg;
                return(l);
+       case SSL_CTRL_GET_MAX_CERT_LIST:
+               return(ctx->max_cert_list);
+       case SSL_CTRL_SET_MAX_CERT_LIST:
+               l=ctx->max_cert_list;
+               ctx->max_cert_list=larg;
+               return(l);
 
        case SSL_CTRL_SET_SESS_CACHE_SIZE:
                l=ctx->session_cache_size;
@@ -1221,6 +1234,7 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        ret->app_verify_callback=NULL;
        ret->app_verify_arg=NULL;
 
+       ret->max_cert_list=SSL_MAX_CERT_LIST_DEFAULT;
        ret->read_ahead=0;
        ret->verify_mode=SSL_VERIFY_NONE;
        ret->verify_depth=-1; /* Don't impose a limit (but x509_lu.c does) */
@@ -1790,6 +1804,7 @@ SSL *SSL_dup(SSL *s)
                        s->sid_ctx, s->sid_ctx_length);
                }
 
+       SSL_set_max_cert_list(ret,SSL_get_max_cert_list(s));
        SSL_set_read_ahead(ret,SSL_get_read_ahead(s));
        SSL_set_verify(ret,SSL_get_verify_mode(s),
                SSL_get_verify_callback(s));