summaryrefslogtreecommitdiffstats
path: root/ssl/statem/extensions_clnt.c
diff options
context:
space:
mode:
authorFdaSilvaYY <fdasilvayy@gmail.com>2017-11-05 17:46:48 +0100
committerBernd Edlinger <bernd.edlinger@hotmail.de>2017-11-05 17:46:48 +0100
commitcf72c7579201086cee303eadcb60bd28eff78dd9 (patch)
tree35c096098b2527a814c95cc674bb54747e3054a0 /ssl/statem/extensions_clnt.c
parentb82acc3c1a7f304c9df31841753a0fa76b5b3cda (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.c62
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)
{