src/wolfSSL/src/internal.c
static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
                           RecordLayerHeader* rh, word16 *size)
{
    if (!ssl->options.dtls) {
#ifdef HAVE_FUZZER
        if (ssl->fuzzerCb)
            ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
                    ssl->fuzzerCtx);
#endif
        XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
        *inOutIdx += RECORD_HEADER_SZ;
        ato16(rh->length, size);
    }
    else {
#ifdef WOLFSSL_DTLS
        /* type and version in same sport */
        XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
        *inOutIdx += ENUM_LEN + VERSION_SZ;
        ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
        *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
        ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
        *inOutIdx += 4;  /* advance past rest of seq */
        ato16(input + *inOutIdx, size);
        *inOutIdx += LENGTH_SZ;
#ifdef HAVE_FUZZER
        if (ssl->fuzzerCb)
            ssl->fuzzerCb(ssl, input + *inOutIdx - LENGTH_SZ - 8 - ENUM_LEN -
                           VERSION_SZ, ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ,
                           FUZZ_HEAD, ssl->fuzzerCtx);
#endif
#endif
    }

#ifdef WOLFSSL_DTLS
    if (ssl->options.dtls &&
        (!DtlsCheckWindow(&ssl->keys.dtls_state) ||
         (ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) {
            return SEQUENCE_ERROR;
    }
#endif

    /* catch version mismatch */
    if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
        if (ssl->options.side == WOLFSSL_SERVER_END &&
            ssl->options.acceptState < ACCEPT_FIRST_REPLY_DONE)

            WOLFSSL_MSG("Client attempting to connect with different version");
        else if (ssl->options.side == WOLFSSL_CLIENT_END &&
                                 ssl->options.downgrade &&
                                 ssl->options.connectState < FIRST_REPLY_DONE)
            WOLFSSL_MSG("Server attempting to accept with different version");
        else if (ssl->options.dtls
                    && (ssl->options.acceptState == ACCEPT_BEGIN
                    || ssl->options.acceptState == CLIENT_HELLO_SENT))
            /* Do not check version until Server Hello or Hello Again (2) */
            WOLFSSL_MSG("Use version for formatting only in DTLS till ");
        else {
            WOLFSSL_MSG("SSL version error");
            return VERSION_ERROR;              /* only use requested version */
        }
    }

    /* record layer length check */
#ifdef HAVE_MAX_FRAGMENT
    if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
        SendAlert(ssl, alert_fatal, record_overflow);
        return LENGTH_ERROR;
    }
#else
    if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
        return LENGTH_ERROR;
#endif

    /* verify record type here as well */
    switch (rh->type) {
        case handshake:
        case change_cipher_spec:
        case application_data:
        case alert:
            break;
        case no_type:
        default:
            WOLFSSL_MSG("Unknown Record Type");
            return UNKNOWN_RECORD_TYPE;
    }

    /* haven't decrypted this record yet */
    ssl->keys.decryptedCur = 0;

    return 0;
}
/* do all verify and sanity checks on record header */
do all verify and sanity checks on record header
do all verify and sanity checks on record header
static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
                           RecordLayerHeader* rh, word16 *size)
{
    if (!ssl->options.dtls) {
#ifdef HAVE_FUZZER
        if (ssl->fuzzerCb)
            ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
                    ssl->fuzzerCtx);
#endif
        XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
        *inOutIdx += RECORD_HEADER_SZ;
        ato16(rh->length, size);
    }
    else {
#ifdef WOLFSSL_DTLS
        XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
        *inOutIdx += ENUM_LEN + VERSION_SZ;
        ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
        *inOutIdx += 4; 
        ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
        *inOutIdx += 4;  
        ato16(input + *inOutIdx, size);
        *inOutIdx += LENGTH_SZ;
#ifdef HAVE_FUZZER
        if (ssl->fuzzerCb)
            ssl->fuzzerCb(ssl, input + *inOutIdx - LENGTH_SZ - 8 - ENUM_LEN -
                           VERSION_SZ, ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ,
                           FUZZ_HEAD, ssl->fuzzerCtx);
#endif
#endif
    }
#ifdef WOLFSSL_DTLS
    if (ssl->options.dtls &&
        (!DtlsCheckWindow(&ssl->keys.dtls_state) ||
         (ssl->options.handShakeDone && ssl->keys.dtls_state.curEpoch == 0))) {
            return SEQUENCE_ERROR;
    }
#endif
    if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
        if (ssl->options.side == WOLFSSL_SERVER_END &&
            ssl->options.acceptState < ACCEPT_FIRST_REPLY_DONE)
            WOLFSSL_MSG("Client attempting to connect with different version");
        else if (ssl->options.side == WOLFSSL_CLIENT_END &&
                                 ssl->options.downgrade &&
                                 ssl->options.connectState < FIRST_REPLY_DONE)
            WOLFSSL_MSG("Server attempting to accept with different version");
        else if (ssl->options.dtls
                    && (ssl->options.acceptState == ACCEPT_BEGIN
                    || ssl->options.acceptState == CLIENT_HELLO_SENT))
            WOLFSSL_MSG("Use version for formatting only in DTLS till ");
        else {
            WOLFSSL_MSG("SSL version error");
            return VERSION_ERROR;              
        }
    }
#ifdef HAVE_MAX_FRAGMENT
    if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
        SendAlert(ssl, alert_fatal, record_overflow);
        return LENGTH_ERROR;
    }
#else
    if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
        return LENGTH_ERROR;
#endif
    switch (rh->type) {
        case handshake:
        case change_cipher_spec:
        case application_data:
        case alert:
            break;
        case no_type:
        default:
            WOLFSSL_MSG("Unknown Record Type");
            return UNKNOWN_RECORD_TYPE;
    }
    ssl->keys.decryptedCur = 0;
    return 0;
}
static int GetRecordHeader ( WOLFSSL * ssl , const byte * input , word32 * inOutIdx , RecordLayerHeader * rh , word16 * size ) { if ( ! ssl -> options . dtls ) { #ifdef HAVE_FUZZER if ( ssl -> fuzzerCb ) ssl -> fuzzerCb ( ssl , input + * inOutIdx , RECORD_HEADER_SZ , FUZZ_HEAD , ssl -> fuzzerCtx ) ; #endif XMEMCPY ( rh , input + * inOutIdx , RECORD_HEADER_SZ ) ; * inOutIdx += RECORD_HEADER_SZ ; ato16 ( rh -> length , size ) ; } else { #ifdef WOLFSSL_DTLS XMEMCPY ( rh , input + * inOutIdx , ENUM_LEN + VERSION_SZ ) ; * inOutIdx += ENUM_LEN + VERSION_SZ ; ato16 ( input + * inOutIdx , & ssl -> keys . dtls_state . curEpoch ) ; * inOutIdx += 4 ; ato32 ( input + * inOutIdx , & ssl -> keys . dtls_state . curSeq ) ; * inOutIdx += 4 ; ato16 ( input + * inOutIdx , size ) ; * inOutIdx += LENGTH_SZ ; #ifdef HAVE_FUZZER if ( ssl -> fuzzerCb ) ssl -> fuzzerCb ( ssl , input + * inOutIdx - LENGTH_SZ - 8 - ENUM_LEN - VERSION_SZ , ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ , FUZZ_HEAD , ssl -> fuzzerCtx ) ; #endif #endif } #ifdef WOLFSSL_DTLS if ( ssl -> options . dtls && ( ! DtlsCheckWindow ( & ssl -> keys . dtls_state ) || ( ssl -> options . handShakeDone && ssl -> keys . dtls_state . curEpoch == 0 ) ) ) { return SEQUENCE_ERROR ; } #endif if ( rh -> pvMajor != ssl -> version . major || rh -> pvMinor != ssl -> version . minor ) { if ( ssl -> options . side == WOLFSSL_SERVER_END && ssl -> options . acceptState < ACCEPT_FIRST_REPLY_DONE ) WOLFSSL_MSG ( " " ) ; else if ( ssl -> options . side == WOLFSSL_CLIENT_END && ssl -> options . downgrade && ssl -> options . connectState < FIRST_REPLY_DONE ) WOLFSSL_MSG ( " " ) ; else if ( ssl -> options . dtls && ( ssl -> options . acceptState == ACCEPT_BEGIN || ssl -> options . acceptState == CLIENT_HELLO_SENT ) ) WOLFSSL_MSG ( " " ) ; else { WOLFSSL_MSG ( " " ) ; return VERSION_ERROR ; } } #ifdef HAVE_MAX_FRAGMENT if ( * size > ( ssl -> max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA ) ) { SendAlert ( ssl , alert_fatal , record_overflow ) ; return LENGTH_ERROR ; } #else if ( * size > ( MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA ) ) return LENGTH_ERROR ; #endif switch ( rh -> type ) { case handshake : case change_cipher_spec : case application_data : case alert : break ; case no_type : default : WOLFSSL_MSG ( " " ) ; return UNKNOWN_RECORD_TYPE ; } ssl -> keys . decryptedCur = 0 ; return 0 ; }
do all verify and sanity checks on record header
do all verify and sanity checks on record header
/* type and version in same sport */ /* advance past epoch, skip first 2 seq bytes for now */ /* advance past rest of seq */ /* catch version mismatch */ /* Do not check version until Server Hello or Hello Again (2) */ /* only use requested version */ /* record layer length check */ /* verify record type here as well */ /* haven't decrypted this record yet */