summaryrefslogtreecommitdiff
path: root/src/lib/libssl/d1_pkt.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* Improve DTLS hello request handling code.jsing2021-09-041-2/+8
| | | | | | | Rather than manually checking multiple bytes, actually parse the DTLS handshake message header, then check the values against what we parsed. ok inoguchi@ tb@
* Change dtls1_get_message_header() to take a CBS.jsing2021-09-041-2/+4
| | | | | | The callers know the actual length and can initialise a CBS correctly. ok inoguchi@ tb@
* Improve DTLS record header parsing.jsing2021-09-041-7/+7
| | | | | | | | Rather than pulling out the epoch and then six bytes of sequence number, pull out SSL3_SEQUENCE_SIZE for the sequence number, then pull the epoch off the start of the sequence number. ok inoguchi@ tb@
* Defragment DTLS.jsing2021-08-311-115/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In normal TLS, it is possible for record fragments to be sent that contain one byte of alert or handshake message payload. In this case we have to read and collate multiple message fragments before we can decide what to do with the record. However, in the case of DTLS, one record is effectively one packet and while it is possible to send handshake messages across multiple records/packets, the minimum payload is the DTLS handshake message header (plus one byte of data if the handshake message has a payload) - without this, there is insufficient information available to be able to reassemble the handshake message. Likewise, splitting an alert across multiple DTLS records simply does not work, as we have no way of knowing if we're collating the same alert or two different alerts that we lost half of each from (unfortunately, these details are not really specified in the DTLS RFC). This means that for DTLS we can expect to receive a full alert message (a whole two bytes) or a handshake record with at least the handshake message header (12 bytes). If we receive messages with less than these lengths we discard them and carry on (which is what the DTLS code already does). Remove all of the pointless fragment handling code from DTLS, while also fixing an issue where one case used rr->data instead of the handshake fragment. ok inoguchi@ tb@
* Remove a nonsensical s->version == TLS1_VERSION from DTLS code.jsing2021-08-311-6/+1
| | | | ok inoguchi@ tb@ (as part of a larger diff)
* Clean up and simplify info and msg callbacks.jsing2021-08-301-21/+8
| | | | | | | | | The info and msg callbacks result in duplication - both for code that refers to the function pointers and for the call sites. Avoid this by providing typedefs for the function pointers and pulling the calling sequences into their own functions. ok inoguchi@ tb@
* Replace DTLS r_epoch with the read epoch from the TLSv1.2 record layer.jsing2021-08-301-9/+13
| | | | ok inoguchi@ tb@
* We have defines for alert levels - use them instead of magic numbers.jsing2021-07-311-5/+3
|
* Dedup dtls1_dispatch_alert()/ssl3_dispatch_alert().jsing2021-07-261-38/+2
| | | | | | | | The code for dtls1_dispatch_alert() and ssl3_dispatch_alert() is largely identical - with a bit of reshuffling we can use ssl3_dispatch_alert() for both protocols and remove the ssl_dispatch_alert function pointer. ok inoguchi@ tb@
* Remove DTLS processed_rcds queue.jsing2021-07-211-38/+19
| | | | | | | | | | | | | | | | | | | When DTLS handshake records are received from the next epoch, we will potentially queue them on the unprocessed_rcds queue - this is usually a Finished message that has been received without the ChangeCipherSuite (CCS) message (which may have been dropped or reordered). After the epoch increments (due to the CCS being received), the current code processes all records on the unprocessed queue and immediate queues them on the processed queue, which dtls1_get_record() then pulls from. This form of processing only adds more complexity and another queue. Instead, once the epoch increments, pull a single record from the unprocessed queue and process it, allowing the contents to be consumed by the caller. We repeat this process until the unprocessed queue is empty, at which point we go back to consuming messages from the wire. ok inoguchi@ tb@
* Silently discard invalid DTLS records.jsing2021-07-211-4/+11
| | | | | | | | | | | Per RFC 6347 section 4.1.2.1, DTLS should silently discard invalid records, including those that have a bad MAC. When converting to the new record layer, we inadvertantly switched to standard TLS behaviour, where an invalid record is fatal. This restores the previous behaviour. Issue noted by inoguchi@ ok inoguchi@
* Mop up dtls1_get_ccs_header() and struct ccs_header_st.jsing2021-07-191-5/+1
| | | | | | | | All this code does is read one byte from memory with an unknown length, potentially being a one byte overread... and then nothing is actually done with the value. ok tb@
* Inline DTLS1_CCS_HEADER_LENGTH rather than having a single use variable.jsing2021-07-191-3/+2
| | | | ok tb@
* Correctly handle epoch wrapping in dtls1_get_bitmap().jsing2021-06-191-2/+3
| | | | | | | | | | | | | | | | | | | | | | Due to a type bug that has been present in DTLS since the code was first committed in 2005, dtls1_get_bitmap() fails to handle next epoch correctly when the epoch is currently 0xffff (and wraps to zero). For various reasons unknown, the epoch field in the SSL3_RECORD_INTERNAL (formerly SSL3_RECORD) was added as unsigned long (even though the value is an unsigned 16 bit value on the wire, hence cannot exceed 0xffff), however was added to other code as unsigned short. Due to integer promotion, the r_epoch value is incremented by one to become 0x10000, before being cast to an unsigned long and compared to the value pulled from the DTLS record header (which is zero). Strangely 0x10000 != 0, meaning that we drop the DTLS record, instead of queueing it for the next epoch. Fix this issue by using more appropriate types and pulling up the calculation of the next epoch value for improved readability. ok inoguchi@ tb@
* Mop up part of dtls1_dispatch_alert().jsing2021-06-151-9/+2
| | | | | | | | | | | | The original DTLS code had some strange alert handling code (basically one type of alert included extra data) - a few years later this was "fixed", however the rest of the code was left as is. This means that rather than sending the alert data from send_alert (like ssl3_dispatch_alert() does), we have a local buffer on the stack, which we memset, copy the send_alert bytes into, then send from. ok inoguchi@ tb@
* Indent all labels with a single space.jsing2021-06-111-4/+4
| | | | | | This ensures that diff reports the correct function prototype. Prompted by tb@
* Move DTLS structs/definitions/prototypes to dtls_locl.h.jsing2021-05-161-4/+4
| | | | | | | | Now that the DTLS structs are opaque, add a dtls_locl.h header and move internal-only structs from dtls1.h, along with prototypes from ssl_locl.h. Only pull this header in where DTLS code actually exists. ok inoguchi@ tb@
* Replace DTLS w_epoch with epoch from TLSv1.2 record layer.jsing2021-05-051-8/+1
| | | | ok inoguchi@ tb@
* Clean up dtls1_reset_seq_numbers().jsing2021-05-021-14/+12
| | | | | | | | | | Rather than doing flag gymnastics, split dtls1_reset_seq_numbers() into separate read and write functions. Move the calls of these functions into tls1_change_cipher_state() so they directly follow the change of cipher state in the record layer, which avoids having to duplicate the calls in the client and server. ok inoguchi@ tb@
* Rename f_err into fatal_err.tb2021-02-201-12/+12
| | | | discussed with jsing
* Use dtls1_retrieve_buffered_record() to load buffered application data.jsing2021-02-081-11/+3
| | | | | | | Replace the current copy of dtls1_retrieve_buffered_record() with a call to it instead. ok tb@
* Move sequence numbers into the new TLSv1.2 record layer.jsing2021-01-261-12/+1
| | | | | | | This allows for all of the DTLS sequence number save/restore code to be removed. ok inoguchi@ "whee!" tb@
* Add code to handle change of cipher state in the new TLSv1.2 record layer.jsing2021-01-191-2/+2
| | | | | | | | | | This provides the basic framework for handling change of cipher state in the new TLSv1.2 record layer, creating new record protection. In the DTLS case we retain the previous write record protection and can switch back to it when retransmitting. This will allow the record layer to start owning sequence numbers and encryption/decryption state. ok inoguchi@ tb@
* Provide functions to determine if TLSv1.2 record protection is engaged.jsing2021-01-191-6/+5
| | | | | | | | | | Call these functions from code that needs to know if we've changed cipher state and enabled record protection, rather than inconsistently checking various pointers from other places in the code base. This also fixes a minor bug where the wrong pointers are checked if we're operating with AEAD. ok inoguchi@ tb@
* Clean up dtls1_reset_seq_numbers()jsing2021-01-131-10/+7
| | | | | | Inline/remove some variables and use sizeof with the correct variables. ok inoguchi@ tb@
* Clean up read sequence handling in DTLS.jsing2021-01-131-19/+21
| | | | | | | | | | Pass the explicit DTLS read sequence number to dtls1_record_bitmap_update() and dtls1_record_replay_check(), rather than expecting it to be in S3I(s)->read_sequence. Also, store the read sequence number into S3I(s)->rrec.seq_num when we're processing the record header, rather than having dtls1_record_replay_check() be responsible for copying it. ok inoguchi@ tb@
* Clean up sequence number handing in the new TLSv1.2 record layer.jsing2021-01-131-2/+1
| | | | | | | | | | | | Handle protocol specific (DTLS vs TLS) sequence number differences in the open/seal record functions and propagate the sequence number through to the called functions. This means that DTLS specific knowledge is limited to two functions and also avoids building sequence numbers multiple times over. As a result, the DTLS explicit sequence number is now extracted from the record header and passed through for processing, which makes the read epoch handling redundant. ok inoguchi@ tb@
* Reimplement the TLSv1.2 record handling for the read side.jsing2020-10-031-112/+22
| | | | | | | | | | | | This is the next step in replacing the TLSv1.2 record layer. The existing record handling code does decryption and processing in place, which is not ideal for various reasons, however it is retained for now as other code depends on this behaviour. Additionally, CBC requires special handling to avoid timing oracles - for now the existing timing safe code is largely retained. ok beck@ inoguchi@ tb@
* Make dtls1_copy_record() take a DTLS1_RECORD_DATA_INTERNAL *.jsing2020-10-031-10/+4
| | | | | | This removes the need for extra variables and casts. ok inoguchi@ tb@
* Inline two macros that are only used in one place each.jsing2020-10-031-16/+6
| | | | | | | This improves readability - while here also add a missing return value check (although it cannot currently fail). ok inoguchi@ tb@
* Release read and write buffers using freezero().jsing2020-09-241-3/+3
| | | | | | | | | Provide a ssl3_release_buffer() function that correctly frees a buffer and call it from the appropriate locations. While here also change ssl3_release_{read,write}_buffer() to void since they cannot fail and no callers check the return value currently. ok beck@ inoguchi@ tb@
* Start replacing the existing TLSv1.2 record layer.jsing2020-08-301-85/+5
| | | | | | | | | | This takes the same design/approach used in TLSv1.3 and provides an opaque struct that is self contained and cannot reach back into other layers. For now this just implements/replaces the writing of records for DTLSv1/TLSv1.0/TLSv1.1/TLSv1.2. In doing so we stop copying the plaintext into the same buffer that is used to transmit to the wire. ok inoguchi@ tb@
* Increment the epoch in the same place for both read and write.jsing2020-08-111-3/+3
| | | | ok inoguchi@ tb@
* Use 0 instead of 0x00 for memset() calls.jsing2020-08-111-4/+4
| | | | ok inoguchi@ tb@
* Use CBB more correctly when writing SSL3/DTLS records.jsing2020-08-091-25/+43
| | | | | | | | | | | | Previously we used CBB to build the record headers, but not the entire record. Use CBB_init_fixed() upfront, then build the record header and add space for the record content. However, in order to do this we need to determine the length of the record upfront. This simplifies the code, removes a number of manual bounds checks and makes way for further improvements. ok inoguchi@ tb@
* Make the explicit IV length handling in DTLS the same as SSL3/TLS.jsing2020-08-091-8/+13
| | | | ok inoguchi@ tb@
* Check the return value of tls1_enc() in the write path.jsing2020-08-021-3/+3
| | | | | | | | | The write path can return a failure in the AEAD path and there is no reason not to check a return value. Spotted by tb@ during another review. ok tb@
* Clean up/simplify more of the dtls1/ssl3 record writing code:jsing2020-08-011-48/+25
| | | | | | | | | | | | - Make the DTLS code much more consistent with the ssl3 code. - Avoid assigning wr->input and wr->length just so they can be used as arguments to memcpy(). - Remove the arc4random_buf() call for the explicit IV, since tls1_enc() already does this for us. ok tb@
* Clean up and simplify some of the SSL3/DTLS1 record writing code.jsing2020-07-301-19/+14
| | | | | | | | | | | This will allow for further changes to be made with less complexity and easier review. In particular, decide if we need an empty fragment early on and only do the alignment calculation once (rather than in two separate parts of the function. ok tb@ inoguchi@
* Remove dtls1_enc().jsing2020-03-131-4/+4
| | | | | | | | | | | | | Like much of the original DTLS code, dtls1_enc() is effectively a renamed copy of tls1_enc(). Since then tls1_enc() has been modified, however the non-AEAD code remains largely the same. As such, remove dtls1_enc() and instead call tls1_enc() from the DTLS code. The tls1_enc() AEAD code does not currently work correctly with DTLS, however this is a non-issue since we do not support AEAD cipher suites with DTLS currently. ok tb@
* Stop overloading the record type for padding length.jsing2020-03-121-3/+2
| | | | | | | | Currently the CBC related code stuffs the padding length in the upper bits of the type field... stop doing that and add a padding_length field to the record struct instead. ok inoguchi@ tb@
* Use internal versions of SSL3_BUFFER, SSL3_RECORD and DTLS1_RECORD_DATA.jsing2020-03-121-20/+19
| | | | | | | | | SSL3_BUFFER, SSL3_RECORD and DTLS1_RECORD_DATA are currently still in public headers, even though their usage is internal. This moves to using _INTERNAL suffixed versions that are in internal headers, which then allows us to change them without any potential public API fallout. ok inoguchi@ tb@
* Remove the enc function pointers.jsing2020-03-101-6/+4
| | | | | | | The enc function pointers do not serve any purpose these days - remove a layer of indirection and call dtls1_enc()/tls1_enc() directly. ok inoguchi@ tb@
* Convert the DTLS header creation code to CBB.jsing2020-02-211-20/+27
| | | | | | | Also consolidate it into the one place, since there is no reason to write the epoch and sequence out later. ok inoguchi@ tb@
* Remove some commented code, remove some pointless comments and move somejsing2020-02-211-17/+6
| | | | | | comments to their correct places. ok inoguchi@ tb@
* Remove prefix_len, since it is always zero.jsing2020-02-211-4/+3
| | | | ok inoguchi@ tb@
* Send SSL_AD_DECODE alerts in the case of a bad hello request or antb2018-12-031-7/+7
| | | | | | | invalid change cipher spec. Found due to dead assignment warnings by the Clang static analyzer. ok inoguchi (previous version), jsing
* Make more of libssl's record layer state internal.jsing2018-10-241-18/+18
| | | | | | | | | | In January 2017, we changed large amounts of libssl's data structures to be non-visible/internal, however intentionally left things that the software ecosystem was needing to use. The four or so applications that reached into libssl for record layer related state now implement alternative code. As such, make these data structures internal. ok tb@
* unifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE.jsing2018-08-241-21/+2
| | | | | | This code has been rotting since 2006. ok bcook@ tb@
* Move state from ssl->internal to the handshake structure.beck2017-05-071-10/+10
| | | | | | | while we are at it, convert SSLerror to use a function internally, so that we may later allocate the handshake structure and check for it ok jsing@