Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send BUFFER_ERROR if size does not meet minimum Requirements #7602

Merged
merged 1 commit into from
Jun 7, 2024

Conversation

night1rider
Copy link
Contributor

@night1rider night1rider commented May 30, 2024

PR in response to #7275

Send a BUFFER_ERROR if size does not meet the minimum requirement for the extension.

src/tls.c Outdated
@@ -19,6 +19,23 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

// Define minimum size constants used in parsing macros
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use C style commenting /* */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

src/tls.c Outdated Show resolved Hide resolved
src/tls.c Outdated Show resolved Hide resolved
@lealem47
Copy link
Contributor

lealem47 commented May 31, 2024

Macro list I came up with after doing the math on the extension_data field for the various extensions referencing their RFC's. The minimum size check should only be done for the first group if parsing the client hello, as the extension_data for those extensions will be empty in the server hello. The second group can be checked regardless.

/* Check if parsing client hello */
#define SNI_MIN_SIZE   4
#define EDI_MIN_SIZE   0
#define TCA_MIN_SIZE   2
#define CSR_MIN_SIZE   5
#define PKM_MIN_SIZE   1
#define CSR2_MIN_SIZE  7


/* Check regardless */
#define CID_MIN_SIZE   1
#define ALPN_MIN_SIZE  2
#define SRTP_MIN_SIZE  3
#define KS_MIN_SIZE    1
#define ETM_MIN_SIZE   0
#define PSK_MIN_SIZE   2
#define CCT_MIN_SIZE   1
#define SCT_MIN_SIZE   1
#define PHA_MIN_SIZE   0
#define THM_MIN_SIZE   0
#define SA_MIN_SIZE    2
#define SAC_MIN_SIZE   2
#define EC_MIN_SIZE    2
#define MFL_MIN_SIZE   1
#define CKE_MIN_SIZE   3
#define SV_MIN_SIZE    2
#define SCR_MIN_SIZE   1
#define PF_MIN_SIZE    1
#define CAN_MIN_SIZE   3
#define QTP_MIN_SIZE   0
#define STK_MIN_SIZE   0

src/tls.c Outdated Show resolved Hide resolved
@lealem47 lealem47 removed their assignment May 31, 2024
@night1rider night1rider force-pushed the Parsing-bug branch 2 times, most recently from 2176467 to 4fbdb37 Compare June 3, 2024 18:20
@night1rider night1rider marked this pull request as ready for review June 4, 2024 16:08
@dgarske dgarske self-requested a review June 4, 2024 16:32
@night1rider
Copy link
Contributor Author

Retest this please

src/tls.c Outdated
@@ -1978,14 +1978,18 @@ int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
#define ALPN_FREE_ALL TLSX_ALPN_FreeAll
#define ALPN_GET_SIZE TLSX_ALPN_GetSize
#define ALPN_WRITE TLSX_ALPN_Write
#define ALPN_PARSE TLSX_ALPN_ParseAndSet
#define ALPN_PARSE(a, b, c, d, e) (((e) == client_hello ? \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the parse macro the right place to fix this min check? Have you looked a code size impact? Using IDE/GCC-ARM is a good way to gauge code size impact.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to see the macro doing this.
The macro is do either call or not.
Can you generically check? Table with values and look it up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed the feedback and left a comment on the PR

wolfssl/ssl.h Outdated Show resolved Hide resolved
@night1rider
Copy link
Contributor Author

Retest this please

wolfssl/ssl.h Outdated
#define WOLFSSL_STK_MIN_SIZE_SERVER 0
#endif

#define TLSX_SERVER_NAME_DEFINE 0x0000 /* a.k.a. SNI */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the extension enums already defined in internal.h for these values? You'd have to remove all the guards around some of them for this fix so that they are always defined but I don't see why we couldn't do that.

typedef enum {
    TLSX_SERVER_NAME                = 0x0000, /* a.k.a. SNI  */
    TLSX_MAX_FRAGMENT_LENGTH        = 0x0001,
    TLSX_TRUSTED_CA_KEYS            = 0x0003,
    TLSX_TRUNCATED_HMAC             = 0x0004,
    TLSX_STATUS_REQUEST             = 0x0005, /* a.k.a. OCSP stapling   */
    TLSX_SUPPORTED_GROUPS           = 0x000a, /* a.k.a. Supported Curves */
    TLSX_EC_POINT_FORMATS           = 0x000b,
    TLSX_SIGNATURE_ALGORITHMS       = 0x000d, /* HELLO_EXT_SIG_ALGO */
    TLSX_USE_SRTP                   = 0x000e, /* 14 */
    TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */
    TLSX_STATUS_REQUEST_V2          = 0x0011, /* a.k.a. OCSP stapling v2 */
    TLSX_CLIENT_CERTIFICATE_TYPE    = 0x0013, /* RFC8446 */
    TLSX_SERVER_CERTIFICATE_TYPE    = 0x0014, /* RFC8446 */
    TLSX_ENCRYPT_THEN_MAC           = 0x0016, /* RFC 7366 */
    TLSX_EXTENDED_MASTER_SECRET     = 0x0017, /* HELLO_EXT_EXTMS */
    TLSX_SESSION_TICKET             = 0x0023,
    TLSX_PRE_SHARED_KEY             = 0x0029,
    TLSX_EARLY_DATA                 = 0x002a,
    TLSX_SUPPORTED_VERSIONS         = 0x002b,
    TLSX_COOKIE                     = 0x002c,
    TLSX_PSK_KEY_EXCHANGE_MODES     = 0x002d,
    TLSX_CERTIFICATE_AUTHORITIES    = 0x002f,
    TLSX_POST_HANDSHAKE_AUTH        = 0x0031,
    TLSX_SIGNATURE_ALGORITHMS_CERT  = 0x0032,
    TLSX_KEY_SHARE                  = 0x0033,
    TLSX_CONNECTION_ID              = 0x0036,
    TLSX_KEY_QUIC_TP_PARAMS         = 0x0039, /* RFC 9001, ch. 8.2 */
    TLSX_CKS                        = 0xff92, /* X9.146; ff indicates personal
                                               * use and 92 is hex for 146. */
    TLSX_RENEGOTIATION_INFO         = 0xff01,
    TLSX_KEY_QUIC_TP_PARAMS_DRAFT   = 0xffa5, /* from draft-ietf-quic-tls-27 */
    TLSX_ECH                        = 0xfe0d, /* from draft-ietf-tls-esni-13 */
} TLSX_Type;

Copy link
Contributor Author

@night1rider night1rider Jun 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be changed in this PR, I am mainly unsure of due to lack of knowledge of if this may break something. However on first glance I don't see what it would break if the guards where removed. It would also increase code size slightly I would assume.

@night1rider night1rider force-pushed the Parsing-bug branch 3 times, most recently from d1d9cce to 729ce8e Compare June 5, 2024 23:26
@night1rider
Copy link
Contributor Author

I removed the logic from the macro (I added these macros), and squashed it out of the pr.

I switch this over, to a jump table due to the enum highest value for TLSX_Type being too large to setup a lookup table with structs.
I copied the TLSX_Type values to #define because the current enum values are guarded, but I need them available even if some TLSX are not on in the build, to fix the bug. I didn't want to remove the guards on the enum type since I am unsure of the implications of that change. Essentially even if the Client/Server doesn't support an extension like CSR or SNI we still obtain the hello_client/server message and need to check that its (size is) valid since it will effect the other extension offsets during the offset calculations

Code impact wise for this initial solution using IDE/GCC-ARM makefile
Master Commit: 70d317e

/usr/bin/arm-none-eabi-size ./Build/WolfSSLServer.elf
   text    data     bss     dec     hex filename
 140519     136      52  140707   225a3 ./Build/WolfSSLServer.elf
/usr/bin/arm-none-eabi-size ./Build/WolfSSLClient.elf
   text    data     bss     dec     hex filename
 140537     136      52  140725   225b5 ./Build/WolfSSLClient.elf

This PR Commit as of writing this:

/usr/bin/arm-none-eabi-size ./Build/WolfSSLServer.elf
   text    data     bss     dec     hex filename
 140775     136      52  140963   226a3 ./Build/WolfSSLServer.elf
/usr/bin/arm-none-eabi-size ./Build/WolfSSLClient.elf
   text    data     bss     dec     hex filename
 140793     136      52  140981   226b5 ./Build/WolfSSLClient.elf

For WolfSSLServer.elf:
text: +256 bytes (0.182%)
data: 0 bytes (no change)
bss: 0 bytes (no change)
dec: +256 bytes (0.182%)
For WolfSSLClient.elf:
text: +256 bytes (0.182%)
data: 0 bytes (no change)
bss: 0 bytes (no change)
dec: +256 bytes (0.182%)

This will be a flat increase to all builds that use HAVE_TLS_EXTENSIONS.

It can be reduced with the usage of either NO_WOLFSSL_SERVER or NO_WOLFSSL_CLIENT

@dgarske @SparkiDev @ejohnstown thoughts?

Copy link
Contributor

@dgarske dgarske left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your updated solution is much better. Almost there.

@@ -2891,6 +2891,39 @@ typedef enum {
#endif
} TLSX_Type;

/* Same list a the above enum TLSX_Type */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if you could just make the above TLSX_Type types always available and use those directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these... _DEFINE types (not used now)

wolfssl/ssl.h Outdated
@@ -5371,6 +5371,176 @@ WOLFSSL_API int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer,
#define DTLS1_2_VERSION 0xFEFD
#define DTLS1_3_VERSION 0xFEFC

/* Define minimum size constants used in parsing macros */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe how these "min" values were established. I recall you saying they came from @lealem47

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dgarske The values were established adding up the minimum sizes of the data types in the required structs for the extension_data field for the various extensions referencing their RFC's (primarily https://datatracker.ietf.org/doc/html/rfc6066 and https://datatracker.ietf.org/doc/html/rfc8446). I assumed zero-length when applicable. For example, WOLFSSL_CSR_MIN_SIZE_CLIENT = 5 was derived from the struct below.

      struct {
          CertificateStatusType status_type;
          select (status_type) {
              case ocsp: OCSPStatusRequest;
          } request;
      } CertificateStatusRequest;

      enum { ocsp(1), (255) } CertificateStatusType;

      struct {
          ResponderID responder_id_list<0..2^16-1>;
          Extensions  request_extensions;
      } OCSPStatusRequest;

      opaque ResponderID<1..2^16-1>;
      opaque Extensions<0..2^16-1>;

The CertificateStatusRequest extension has a status_type (1 or 255, which is 1 byte). The OCSPStatusRequest consists of two opaques, the responder_id_list and request_extensions. Both of those start with a 16-bit length, so 4 bytes total of 0 lengths. So 5 total. My math on these should be double-checked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add code comments and feedback from Lealem.

@dgarske dgarske removed their assignment Jun 6, 2024
src/tls.c Outdated
@@ -14366,6 +14366,134 @@ int TLSX_ParseVersion(WOLFSSL* ssl, const byte* input, word16 length,
return ret;
}
#endif
#ifndef NO_WOLFSSL_SERVER
static word16 TLSX_GetMinSize_Client(word16* type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function start brace on new line please

src/tls.c Outdated
#endif

#ifndef NO_WOLFSSL_CLIENT
static word16 TLSX_GetMinSize_Server(const word16 *type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

#define TLSXT_USE_SRTP 0x000e /* 14 */
#define TLSXT_APPLICATION_LAYER_PROTOCOL 0x0010 /* a.k.a. ALPN */
#define TLSXT_STATUS_REQUEST_V2 0x0011 /* a.k.a. OCSP stapling v2 */
#define TLSXT_CLIENT_CERTIFICATE 0x0013 /* RFC8446 */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Add space to align 0x0013

@@ -2891,6 +2891,39 @@ typedef enum {
#endif
} TLSX_Type;

/* Same list a the above enum TLSX_Type */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these... _DEFINE types (not used now)

wolfssl/ssl.h Outdated
@@ -5371,6 +5371,176 @@ WOLFSSL_API int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer,
#define DTLS1_2_VERSION 0xFEFD
#define DTLS1_3_VERSION 0xFEFC

/* Define minimum size constants used in parsing macros */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add code comments and feedback from Lealem.

@night1rider
Copy link
Contributor Author

Retest this please

@night1rider night1rider force-pushed the Parsing-bug branch 2 times, most recently from 0dd0b88 to a06f19d Compare June 7, 2024 15:53
dgarske
dgarske previously approved these changes Jun 7, 2024
@JacobBarthelmeh JacobBarthelmeh merged commit f7bc78c into wolfSSL:master Jun 7, 2024
111 checks passed
jefferyq2 pushed a commit to jefferyq2/wolfssl that referenced this pull request Jun 9, 2024
Send BUFFER_ERROR if size does not meet minimum Requirements
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants