diff options
author | FdaSilvaYY <fdasilvayy@gmail.com> | 2017-11-05 17:46:48 +0100 |
---|---|---|
committer | Bernd Edlinger <bernd.edlinger@hotmail.de> | 2017-11-05 17:46:48 +0100 |
commit | cf72c7579201086cee303eadcb60bd28eff78dd9 (patch) | |
tree | 35c096098b2527a814c95cc674bb54747e3054a0 /ssl/statem/extensions_clnt.c | |
parent | b82acc3c1a7f304c9df31841753a0fa76b5b3cda (diff) |
Implement Maximum Fragment Length TLS extension.
Based on patch from Tomasz Moń:
https://groups.google.com/forum/#!topic/mailing.openssl.dev/fQxXvCg1uQY
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/1008)
Diffstat (limited to 'ssl/statem/extensions_clnt.c')
-rw-r--r-- | ssl/statem/extensions_clnt.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index c1f98b42f7..ff2e0cf575 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -57,6 +57,31 @@ EXT_RETURN tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } +/* Push a Max Fragment Len extension into ClientHello */ +EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) +{ + if (s->ext.max_fragment_len_mode == TLSEXT_max_fragment_length_DISABLED) + return EXT_RETURN_NOT_SENT; + + /* Add Max Fragment Length extension if client enabled it. */ + /*- + * 4 bytes for this extension type and extension length + * 1 byte for the Max Fragment Length code value. + */ + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_max_fragment_length) + /* Sub-packet for Max Fragment Length extension (1 byte) */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes_u8(pkt, s->ext.max_fragment_len_mode) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + + return EXT_RETURN_SENT; +} + #ifndef OPENSSL_NO_SRP EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) @@ -1115,6 +1140,43 @@ int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, return 1; } +/* Parse the server's max fragment len extension packet */ +int tls_parse_stoc_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) +{ + unsigned int value; + + if (PACKET_remaining(pkt) != 1 || !PACKET_get_1(pkt, &value)) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + + /* |value| should contains a valid max-fragment-length code. */ + if (!IS_MAX_FRAGMENT_LENGTH_EXT_VALID(value)) { + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* Must be the same value as client-configured one who was sent to server */ + /*- + * RFC 6066: if a client receives a maximum fragment length negotiation + * response that differs from the length it requested, ... + * It must abort with SSL_AD_ILLEGAL_PARAMETER alert + */ + if (value != s->ext.max_fragment_len_mode) { + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* + * Maximum Fragment Length Negotiation succeeded. + * The negotiated Maximum Fragment Length is binding now. + */ + s->session->ext.max_fragment_len_mode = value; + + return 1; +} + int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) { |