Uh oh!
There was an error while loading. Please reload this page.
der: allow SetOf* duplicates - #2272
Merged
Merged
Conversation
tarcieri
reviewed
Apr 2, 2026
| /// Ensure set elements are lexicographically ordered using [`DerOrd`]. | ||
| fn check_der_ordering<T: DerOrd>(a: &T, b: &T) -> Result<(), Error> { | ||
| match a.der_cmp(b)? { |
Member
There was a problem hiding this comment.
This can probably just change to:
Suggested change
| match a.der_cmp(b)? { | |
| if a.der_cmp(b)? == Ordering::Greater{ |
tarcieri
reviewed
Apr 2, 2026
| @@ -531,8 +510,7 @@ fn der_sort<T: DerOrd>(slice: &mut [T]) -> Result<(), Error> { | |||
| while j > 0 { | |||
| match slice[j - 1].der_cmp(&slice[j])? { | |||
Member
There was a problem hiding this comment.
Likewise this can probably switch to an if statement
tarcieri
commented
Apr 2, 2026
Member
@kraemv would you also mind adding a |
tarcieri
commented
Apr 3, 2026
Member
I'll go ahead and fix up my suggestions after merging |
Uh oh!
There was an error while loading. Please reload this page.
kraemv
commented
Apr 4, 2026
ContributorAuthor
Thank you for doing the remaining fixes @tarcieri ! |
tarcieri pushed a commit
that referenced
this pull request
Jun 5, 2026
`der_sort` was a hand-rolled insertion sort. On reverse-sorted input it performs n(n-1)/2 comparisons and swaps, so a crafted SET OF turns a single decode into quadratic-time work. SetOfVec::decode_value runs this on every DER decode, which makes it a denial-of-service vector on any SetOfVec parsed from untrusted DER (for example RelativeDistinguishedName in x509-cert, and DigestAlgorithmIdentifiers / CertificateSet / SignerInfos in cms). A ~246 KB reverse-sorted SET OF with 18k elements took roughly 11 seconds to decode. Switch to slice::sort_unstable_by, an in-place O(n log n) introsort that is available in core, so it still works on heapless no_std targets where the stable slice::sort_by (which needs alloc) is not. The first der_cmp error is captured and returned after the sort, preserving the existing error-bubbling behavior. Sorting unstably does not change the result: two elements that compare Equal under DerOrd have identical DER encodings, so their relative order does not affect the serialized output. Duplicates are still preserved (no deduplication), matching the decoder behavior after #2272. Adds regression tests that cross-check the new ordering against the original insertion sort on randomized and adversarial inputs, assert the DER SET OF ordering invariant, verify duplicate preservation, and decode a large reverse-sorted SET OF end to end. Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hello everyone,
this PR addresses #2271 and disables checks for duplicate elements in SetOf* structs.
The main change is removing the check_duplicate function and changing the behavior for Ordering::Equal results.
I also changed the reject_duplicates tests to allow_duplicate tests that check if duplicates are valid.
I am happy to receive feedback on the changes!