wolfSSL / wolfssl

The wolfSSL library is a small, fast, portable implementation of TLS/SSL for embedded devices to the cloud. wolfSSL supports up to TLS 1.3 and DTLS 1.3!
https://www.wolfssl.com
GNU General Public License v2.0
2.35k stars 834 forks source link

[Bug]: DTLS1.3 - Server doesn't include key_share extention in hello_retry_request #5813

Closed FrantisekKrenzelok closed 1 year ago

FrantisekKrenzelok commented 1 year ago

Contact Details

fkrenzel@redhat.com

Version

v5.5.3-stable

Description

The client sends key_share extension but the server doesn't reply with it. As you can see in the log bellow, the server receives the extension from the first client hello, yet it is not send back possibly not even handled. It is only later during Server Hello that the extension is replied back to client.

client                                                              server
ClientHello
+key_share
+...
                -------->
                                   Hello Retry Request
                                       +cookie
                                                                -key_share
                                              +...
                <--------
ClientHello
+cookie
+key_share
+...
                -------->
                                      Server Hello
                                    +key_share
                                          +...
                <--------

reference:

Reproduction steps

./configure --enable-dtls --enable-dtls13 --enable-tls13 make ./examples/client/client -u -v 4 127.0.0.1 ./examples/server/server -u -v 4

Relevant log output

Server log:
wolfSSL Entering wolfSSL_Init
wolfSSL Entering wolfCrypt_Init
wolfSSL Entering DTLSv1_3_server_method_ex
wolfSSL Entering wolfSSL_CTX_new_ex
wolfSSL Entering wolfSSL_CertManagerNew
wolfSSL Leaving WOLFSSL_CTX_new, return 0
wolfSSL Entering wolfSSL_CTX_use_certificate_chain_file
Getting dynamic buffer
wolfSSL Entering PemToDer
Growing Tmp Chain Buffer
Processing Cert Chain
wolfSSL Entering PemToDer
   Consumed another Cert in Chain
Finished Processing Cert Chain
Checking cert signature type
wolfSSL Entering GetExplicitVersion
wolfSSL Entering wc_GetSerialNumber
Got Cert Header
wolfSSL Entering GetObjectId()
Got Algo ID
Getting Name
Getting Cert Name
Getting Name
Getting Cert Name
Got Subject Name
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
Got Key
Not ECDSA cert signature
wolfSSL Entering wolfSSL_CTX_use_PrivateKey_file
Getting dynamic buffer
wolfSSL Entering PemToDer
wolfSSL Entering GetAlgoId
wolfSSL Entering wolfSSL_CTX_set_verify
wolfSSL_CTX_load_verify_locations_ex
Getting dynamic buffer
Processing CA PEM file
wolfSSL Entering PemToDer
Adding a CA
wolfSSL Entering GetExplicitVersion
wolfSSL Entering wc_GetSerialNumber
Got Cert Header
wolfSSL Entering GetObjectId()
Got Algo ID
Getting Name
Getting Cert Name
Getting Name
Getting Cert Name
Got Subject Name
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
Got Key
Parsed Past Key
wolfSSL Entering DecodeCertExtensions
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeSubjKeyId
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeAuthKeyId
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeBasicCaConstraint
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeAltNames
    Unsupported name type, skipping
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeExtKeyUsage
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
    Parsed new CA
    Freeing Parsed CA
    Freeing der CA
        OK Freeing der CA
wolfSSL Leaving AddCA, return 0
   Processed a CA
Processed at least one valid CA. Other stuff OK
wolfSSL Entering SSL_new
wolfSSL Leaving SSL_new, return 0
wolfSSL Entering wolfSSL_SetHsDoneCb
wolfSSL Entering SSL_set_fd
wolfSSL Entering SSL_set_read_fd
wolfSSL Leaving SSL_set_read_fd, return 1
wolfSSL Entering SSL_set_write_fd
wolfSSL Leaving SSL_set_write_fd, return 1
Getting dynamic buffer
wolfSSL Entering PemToDer
wolfSSL Entering wolfSSL_SetTmpDH
wolfSSL Leaving wolfSSL_SetTmpDH, return 0
wolfSSL Entering SSL_accept()
growing input buffer
wolfSSL Leaving wolfSSL_dtls_get_current_timeout(), return 1
wolfSSL Entering EmbedReceiveFrom()
wolfSSL Entering wolfSSL_dtls_get_using_nonblock
wolfSSL Entering Dtls13RtxAddAck
received record layer msg
got HANDSHAKE
wolfSSL Entering Dtls13RtxMsgRecvd
wolfSSL Entering Dtls13RtxFlushBuffered
wolfSSL Entering DoTls13HandShakeMsgType
processing client hello
wolfSSL Entering DoTls13ClientHello
Supported Versions extension received
Adding signature algorithms extension
Skipping Supported Versions - already processed
Signature Algorithms extension received
Supported Groups extension received
Encrypt-Then-Mac extension received
Key Share extension received
wolfSSL Entering MatchSuite
wolfSSL Entering VerifyServerSuite
wolfSSL Entering EccMakeKey
wolfSSL Leaving EccMakeKey, return 0
Verified suite validity
Derive Early Secret
wolfSSL Leaving DoTls13ClientHello, return 0
wolfSSL Leaving DoTls13HandShakeMsgType(), return 0
Shrinking input buffer
accept state ACCEPT_CLIENT_HELLO_DONE
wolfSSL Entering SSL_accept_TLSv13()
wolfSSL Entering SendTls13ServerHello
wolfSSL Sending HelloRetryRequest
growing output buffer
Supported Versions extension to write
Cookie extension to write
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Leaving SendTls13ServerHello, return 0
wolfSSL Entering Dtls13RtxFlushAcks
wolfSSL Entering Dtls13RtxFlushBuffered
growing input buffer
wolfSSL Leaving wolfSSL_dtls_get_current_timeout(), return 1
wolfSSL Entering EmbedReceiveFrom()
wolfSSL Entering wolfSSL_dtls_get_using_nonblock
wolfSSL Entering Dtls13RtxAddAck
received record layer msg
got HANDSHAKE
wolfSSL Entering Dtls13RtxMsgRecvd
wolfSSL Entering Dtls13RtxFlushBuffered
wolfSSL Entering DoTls13HandShakeMsgType
processing client hello
wolfSSL Entering DoTls13ClientHello
Supported Versions extension received
Adding signature algorithms extension
Skipping Supported Versions - already processed
Signature Algorithms extension received
Cookie extension received
Supported Groups extension received
Encrypt-Then-Mac extension received
Key Share extension received
wolfSSL Entering MatchSuite
wolfSSL Entering VerifyServerSuite
wolfSSL Entering EccMakeKey
wolfSSL Leaving EccMakeKey, return 0
Verified suite validity
Derive Early Secret
wolfSSL Leaving DoTls13ClientHello, return 0
wolfSSL Leaving DoTls13HandShakeMsgType(), return 0
Shrinking input buffer
accept state ACCEPT_CLIENT_HELLO_DONE
accept state ACCEPT_HELLO_RETRY_REQUEST_DONE
accept state ACCEPT_FIRST_REPLY_DONE
accept state ACCEPT_SECOND_REPLY_DONE
wolfSSL Entering SendTls13ServerHello
growing output buffer
Key Share extension to write
Supported Versions extension to write
wolfSSL Entering Dtls13RtxFlushAcks
wolfSSL Entering Dtls13RtxNewRecord
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering Dtls13RtxAddRecord
wolfSSL Leaving SendTls13ServerHello, return 0
accept state SERVER_HELLO_SENT
accept state ACCEPT_THIRD_REPLY_DONE
wolfSSL Entering EccSharedSecret
wolfSSL Leaving EccSharedSecret, return 0
wolfSSL Entering SendTls13EncryptedExtensions
Derive Handshake Secret
Derive Client Handshake Secret
Derive Server Handshake Secret
Derive Client Key
Derive Server Key
Derive Client IV
Derive Server IV
Derive SN Client key
Derive SN Server key
wolfSSL Entering Dtls13SetEpochKeys
wolfSSL Entering Dtls13SetEpochKeys
growing output buffer
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
wolfSSL Entering Dtls13RtxNewRecord
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering Dtls13RtxAddRecord
wolfSSL Leaving SendTls13EncryptedExtensions, return 0
accept state SERVER_EXTENSIONS_SENT
wolfSSL Entering SendTls13CertificateRequest
growing output buffer
Signature Algorithms extension to write
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
wolfSSL Entering Dtls13RtxNewRecord
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering Dtls13RtxAddRecord
wolfSSL Leaving SendTls13CertificateRequest, return 0
accept state CERT_REQ_SENT
wolfSSL Entering SendTls13Certificate
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
CheckAvailableSize() flushing buffer to make room for new message
growing output buffer
wolfSSL Entering Dtls13RtxFlushAcks
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
CheckAvailableSize() flushing buffer to make room for new message
Shrinking output buffer
growing output buffer
wolfSSL Entering Dtls13RtxNewRecord
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering Dtls13RtxAddRecord
growing output buffer
wolfSSL Entering Dtls13RtxNewRecord
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering Dtls13RtxAddRecord
wolfSSL Leaving SendTls13Certificate, return 0
accept state CERT_SENT
wolfSSL Entering SendTls13CertificateVerify
growing output buffer
Trying RSA private key
wolfSSL Entering GetAlgoId
Using RSA private key
wolfSSL Entering RsaSign
wolfSSL Using RSA PSS padding
wolfSSL Leaving RsaSign, return 0
wolfSSL Entering VerifyRsaSign
wolfSSL Using RSA PSS un-padding
wolfSSL Leaving VerifyRsaSign, return 0
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
wolfSSL Entering Dtls13RtxNewRecord
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering Dtls13RtxAddRecord
wolfSSL Leaving SendTls13CertificateVerify, return 0
accept state CERT_VERIFY_SENT
wolfSSL Entering SendTls13Finished
growing output buffer
Derive Finished Secret
Derive Finished Secret
wolfSSL Entering Dtls13RtxFlushAcks
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
wolfSSL Entering Dtls13RtxNewRecord
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering Dtls13RtxAddRecord
Derive Master Secret
Derive Client Traffic Secret
Derive Server Traffic Secret
Derive Client Key
Derive Server Key
Derive Client IV
Derive Server IV
Derive SN Client key
Derive SN Server key
wolfSSL Entering Dtls13SetEpochKeys
wolfSSL Entering Dtls13SetEpochKeys
wolfSSL Leaving SendTls13Finished, return 0
accept state ACCEPT_FINISHED_SENT
accept state  TICKET_SENT
growing input buffer
wolfSSL Leaving wolfSSL_dtls_get_current_timeout(), return 1
wolfSSL Entering EmbedReceiveFrom()
wolfSSL Entering wolfSSL_dtls_get_using_nonblock
wolfSSL Entering Dtls13SetEpochKeys
wolfSSL Entering DecryptTls13
wolfSSL Entering Dtls13RtxAddAck
received record layer msg
got HANDSHAKE
wolfSSL Entering Dtls13RtxMsgRecvd
wolfSSL Entering Dtls13RtxFlushBuffered
wolfSSL Entering DoTls13HandShakeMsgType
processing certificate
wolfSSL Entering DoTls13Certificate
wolfSSL Entering ProcessPeerCerts
Loading peer's cert chain
    Parsing 0 bytes of cert extensions
    Put another cert into chain
Verifying Peer's cert
wolfSSL Entering GetExplicitVersion
wolfSSL Entering wc_GetSerialNumber
Got Cert Header
wolfSSL Entering GetObjectId()
Got Algo ID
Getting Name
Getting Cert Name
Getting Name
Getting Cert Name
Got Subject Name
wolfSSL Entering GetAlgoId
wolfSSL Entering GetObjectId()
Got Key
Parsed Past Key
wolfSSL Entering DecodeCertExtensions
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeSubjKeyId
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeAuthKeyId
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeBasicCaConstraint
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeAltNames
    Unsupported name type, skipping
wolfSSL Entering GetObjectId()
wolfSSL Entering DecodeExtKeyUsage
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
wolfSSL Entering GetObjectId()
CA found
wolfSSL Entering ConfirmSignature
wolfSSL Leaving ConfirmSignature, return 0
Verified Peer's cert
wolfSSL Leaving ProcessPeerCerts, return 0
wolfSSL Leaving DoTls13Certificate, return 0
wolfSSL Leaving DoTls13HandShakeMsgType(), return 0
Shrinking input buffer
wolfSSL Entering Dtls13DoScheduledWork
growing input buffer
wolfSSL Leaving wolfSSL_dtls_get_current_timeout(), return 1
wolfSSL Entering EmbedReceiveFrom()
wolfSSL Entering wolfSSL_dtls_get_using_nonblock
wolfSSL Entering DecryptTls13
wolfSSL Entering Dtls13RtxAddAck
received record layer msg
got HANDSHAKE
wolfSSL Entering Dtls13RtxMsgRecvd
wolfSSL Entering Dtls13RtxFlushBuffered
wolfSSL Entering DoTls13HandShakeMsgType
processing certificate verify
wolfSSL Entering DoTls13CertificateVerify
Peer sent RSA sig
wolfSSL Entering RsaVerify
wolfSSL Using RSA PSS un-padding
wolfSSL Leaving RsaVerify, return 64
wolfSSL Leaving DoTls13CertificateVerify, return 0
wolfSSL Leaving DoTls13HandShakeMsgType(), return 0
Shrinking input buffer
wolfSSL Entering Dtls13DoScheduledWork
growing input buffer
wolfSSL Leaving wolfSSL_dtls_get_current_timeout(), return 1
wolfSSL Entering EmbedReceiveFrom()
wolfSSL Entering wolfSSL_dtls_get_using_nonblock
wolfSSL Entering DecryptTls13
wolfSSL Entering Dtls13RtxAddAck
received record layer msg
got HANDSHAKE
wolfSSL Entering Dtls13RtxMsgRecvd
wolfSSL Entering Dtls13RtxFlushBuffered
wolfSSL Entering DoTls13HandShakeMsgType
processing finished
wolfSSL Entering DoTls13Finished
wolfSSL Leaving DoTls13Finished, return 0
wolfSSL Leaving DoTls13HandShakeMsgType(), return 0
Shrinking input buffer
wolfSSL Entering Dtls13DoScheduledWork
wolfSSL Entering SendDtls13Ack
growing output buffer
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering Dtls13RtxFlushAcks
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
accept state ACCEPT_FINISHED_DONE
accept state TICKET_SENT
wolfSSL Entering FreeHandshakeResources
wolfSSL Leaving SSL_accept(), return 1
wolfSSL Entering wolfSSL_get_version
wolfSSL Entering SSL_get_current_cipher
wolfSSL Entering wolfSSL_CIPHER_get_name
wolfSSL Entering wolfSSL_session_reused
wolfSSL Leaving wolfSSL_session_reused, return 0
wolfSSL Entering wolfSSL_read()
wolfSSL Entering wolfSSL_read_internal()
wolfSSL Entering ReceiveData()
growing input buffer
wolfSSL Leaving wolfSSL_dtls_get_current_timeout(), return 1
wolfSSL Entering EmbedReceiveFrom()
wolfSSL Entering wolfSSL_dtls_get_using_nonblock
wolfSSL Entering Dtls13SetEpochKeys
wolfSSL Entering DecryptTls13
received record layer msg
got app DATA
wolfSSL Entering Dtls13DoScheduledWork
Shrinking input buffer
wolfSSL Leaving ReceiveData(), return 14
wolfSSL Leaving wolfSSL_read_internal(), return 14
wolfSSL Entering SSL_get_error
wolfSSL Leaving SSL_get_error, return 0
wolfSSL Entering SSL_get_fd
wolfSSL Leaving SSL_get_fd, return 3
wolfSSL Entering SSL_get_error
wolfSSL Leaving SSL_get_error, return 0
wolfSSL Entering SSL_write()
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
growing output buffer
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
wolfSSL Leaving SSL_write(), return 22
wolfSSL Entering SSL_shutdown()
wolfSSL Entering SendAlert
growing output buffer
wolfSSL Entering BuildMessage
wolfSSL Entering BuildTls13Message
wolfSSL Entering EncryptTls13
wolfSSL Leaving BuildTls13Message, return 0
wolfSSL Entering EmbedSendTo()
Shrinking output buffer
wolfSSL Leaving SendAlert, return 0
wolfSSL Leaving SSL_shutdown(), return 2
wolfSSL Entering SSL_free
Free'ing server ssl
wolfSSL Entering DtlsMsgPoolReset()
wolfSSL Entering ClientSessionToSession
wolfSSL Entering Dtls13RtxFlushAcks
wolfSSL Entering Dtls13RtxFlushBuffered
CTX ref count not 0 yet, no free
wolfSSL Leaving SSL_free, return 0
wolfSSL Entering SSL_CTX_free
CTX ref count down to 0, doing full free
wolfSSL Entering wolfSSL_CertManagerFree
wolfSSL Leaving SSL_CTX_free, return 0
wolfSSL Entering wolfSSL_Cleanup
wolfSSL Entering wolfCrypt_Cleanup
dgarske commented 1 year ago

@Franko5040 is it possible this issue is solved with PR https://github.com/wolfSSL/wolfssl/pull/5716 ? @rizlik can you review this bug report?

rizlik commented 1 year ago

Hi @Franko5040 Thanks for the report. When the HelloRetryRequest is used to perform a return-routability check (as in this case) the KeyShare is not mandatory. Moreover, if the client already provided a good KeyShare the server MUST NOT send a KeyShare extension asking for the same key share in the HelloRetryRequest. Otherwise the (2) in : In https://www.rfc-editor.org/rfc/rfc8446#section-4.2.8:

Upon receipt of this extension in a HelloRetryRequest, the client
   MUST verify that (1) the selected_group field corresponds to a group
   which was provided in the "supported_groups" extension in the
   original ClientHello and (2) the selected_group field does not
   correspond to a group which was provided in the "key_share" extension
   in the original ClientHello.

will be violated. Of course, if the client doesn't provide a good key share in the first ClientHello, the KeyShare extension needs to be present in the HelloRetryRequest (together with the cookie).

Does it make sense to you? Marco

FrantisekKrenzelok commented 1 year ago

I see, Thanks for the explanation and you time!