From c0f5dd070b7fa701b0d72e909206bffd4b7031dc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lutz=20J=C3=A4nicke?= Date: Tue, 11 Sep 2001 13:08:51 +0000 Subject: [PATCH] Make maximum certifcate chain size accepted from the peer application settable (proposed by "Douglas E. Engert" ). --- CHANGES | 5 ++ doc/ssl/SSL_CTX_set_max_cert_list.pod | 77 +++++++++++++++++++++++++++ doc/ssl/ssl.pod | 1 + ssl/s3_clnt.c | 18 ++----- ssl/s3_srvr.c | 12 +---- ssl/ssl.h | 21 +++++++- ssl/ssl_lib.c | 15 ++++++ 7 files changed, 123 insertions(+), 26 deletions(-) create mode 100644 doc/ssl/SSL_CTX_set_max_cert_list.pod diff --git a/CHANGES b/CHANGES index 7ae61a558f..3b467094cb 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,11 @@ *) 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" . + [Lutz Jaenicke] + +) Add support for shared libraries for Unixware-7 and support including shared libraries for OpenUNIX-8 (Boyd Lynn Gerber ). [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 index 0000000000..da68cb9fc2 --- /dev/null +++ b/doc/ssl/SSL_CTX_set_max_cert_list.pod @@ -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 + + 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 to be bytes. +The SSL objects inherit the setting valid for B at the time +L is being called. + +SSL_CTX_get_max_cert_list() returns the currently set maximum size for B. + +SSL_set_max_cert_list() sets the maximum size allowed for the peer's +certificate chain for B to be bytes. This setting stays valid +until a new value is set. + +SSL_get_max_cert_list() returns the currently set maximum size for B. + +=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, 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, L, +L + +=head1 HISTORY + +SSL*_set/get_max_cert_list() have been introduced in OpenSSL 0.9.7. + +=cut diff --git a/doc/ssl/ssl.pod b/doc/ssl/ssl.pod index 6845f4f76d..89b321edec 100644 --- a/doc/ssl/ssl.pod +++ b/doc/ssl/ssl.pod @@ -669,6 +669,7 @@ L, L, L, L, +L, L, L, L, diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 18133f3da5..36068780e7 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -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); diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 4d0d80065a..de84080844 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -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); diff --git a/ssl/ssl.h b/ssl/ssl.h index c5f24eb51c..538d11a0c0 100644 --- 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 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 8aec403c5a..89c3c2d4f4 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -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)); -- 2.25.1