00001 /* 00002 * Copyright (C) 2001, 2004, 2005 Free Software Foundation 00003 * 00004 * Author: Nikos Mavrogiannopoulos 00005 * 00006 * This file is part of GNUTLS. 00007 * 00008 * The GNUTLS library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 00021 * USA 00022 * 00023 */ 00024 00025 /* This file contains the code for the Max Record Size TLS extension. 00026 */ 00027 00028 #include "gnutls_int.h" 00029 #include "gnutls_errors.h" 00030 #include "gnutls_num.h" 00031 #include <ext_max_record.h> 00032 00033 /* 00034 * In case of a server: if a MAX_RECORD_SIZE extension type is received then it stores 00035 * into the session the new value. The server may use MHD_gnutls_get_max_record_size(), 00036 * in order to access it. 00037 * 00038 * In case of a client: If a different max record size (than the default) has 00039 * been specified then it sends the extension. 00040 * 00041 */ 00042 00043 int 00044 MHD_gtls_max_record_recv_params (MHD_gtls_session_t session, 00045 const opaque * data, size_t _data_size) 00046 { 00047 ssize_t new_size; 00048 ssize_t data_size = _data_size; 00049 00050 if (session->security_parameters.entity == GNUTLS_SERVER) 00051 { 00052 if (data_size > 0) 00053 { 00054 DECR_LEN (data_size, 1); 00055 00056 new_size = MHD_gtls_mre_num2record (data[0]); 00057 00058 if (new_size < 0) 00059 { 00060 MHD_gnutls_assert (); 00061 return new_size; 00062 } 00063 00064 session->security_parameters.max_record_send_size = new_size; 00065 session->security_parameters.max_record_recv_size = new_size; 00066 } 00067 } 00068 else 00069 { /* CLIENT SIDE - we must check if the sent record size is the right one 00070 */ 00071 if (data_size > 0) 00072 { 00073 00074 if (data_size != 1) 00075 { 00076 MHD_gnutls_assert (); 00077 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; 00078 } 00079 00080 new_size = MHD_gtls_mre_num2record (data[0]); 00081 00082 if (new_size < 0 00083 || new_size != session->internals.proposed_record_size) 00084 { 00085 MHD_gnutls_assert (); 00086 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; 00087 } 00088 else 00089 { 00090 session->security_parameters.max_record_recv_size = 00091 session->internals.proposed_record_size; 00092 } 00093 00094 } 00095 00096 00097 } 00098 00099 return 0; 00100 } 00101 00102 /* returns data_size or a negative number on failure 00103 */ 00104 int 00105 MHD_gtls_max_record_send_params (MHD_gtls_session_t session, opaque * data, 00106 size_t data_size) 00107 { 00108 uint16_t len; 00109 /* this function sends the client extension data (dnsname) */ 00110 #if MHD_DEBUG_TLS 00111 if (session->security_parameters.entity == GNUTLS_CLIENT) 00112 { 00113 00114 if (session->internals.proposed_record_size != DEFAULT_MAX_RECORD_SIZE) 00115 { 00116 len = 1; 00117 if (data_size < len) 00118 { 00119 MHD_gnutls_assert (); 00120 return GNUTLS_E_SHORT_MEMORY_BUFFER; 00121 } 00122 00123 data[0] = 00124 (uint8_t) MHD_gtls_mre_record2num (session->internals. 00125 proposed_record_size); 00126 return len; 00127 } 00128 00129 } 00130 else 00131 #endif 00132 { /* server side */ 00133 00134 if (session->security_parameters.max_record_recv_size != 00135 DEFAULT_MAX_RECORD_SIZE) 00136 { 00137 len = 1; 00138 if (data_size < len) 00139 { 00140 MHD_gnutls_assert (); 00141 return GNUTLS_E_SHORT_MEMORY_BUFFER; 00142 } 00143 00144 data[0] = 00145 (uint8_t) 00146 MHD_gtls_mre_record2num 00147 (session->security_parameters.max_record_recv_size); 00148 return len; 00149 } 00150 00151 00152 } 00153 00154 return 0; 00155 } 00156 00157 /* Maps numbers to record sizes according to the 00158 * extensions draft. 00159 */ 00160 int 00161 MHD_gtls_mre_num2record (int num) 00162 { 00163 switch (num) 00164 { 00165 case 1: 00166 return 512; 00167 case 2: 00168 return 1024; 00169 case 3: 00170 return 2048; 00171 case 4: 00172 return 4096; 00173 default: 00174 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; 00175 } 00176 } 00177 00178 /* Maps record size to numbers according to the 00179 * extensions draft. 00180 */ 00181 int 00182 MHD_gtls_mre_record2num (uint16_t record_size) 00183 { 00184 switch (record_size) 00185 { 00186 case 512: 00187 return 1; 00188 case 1024: 00189 return 2; 00190 case 2048: 00191 return 3; 00192 case 4096: 00193 return 4; 00194 default: 00195 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; 00196 } 00197 00198 }