Skip to content

Conversation

vcsjones
Copy link
Member

@vcsjones vcsjones commented Aug 14, 2025

The internal cryptographic wrapper, ECDsaWrapper, RSAWrapper, ECDiffieHellmanWrapper, and DSAWrapper implemented Equals in such a way that it was never going to be true. It delegated equals to "what was wrapped", but since you can't get what is wrapped out, you would end up comparing a wrapper to a wrapped.

This violated FDG 8.9.1

DO comply with the contract defined for Object.Equals when overriding the method.
For convenience, the contract taken directly from the System.Object documentation is provided here.

  • x.Equals(x) returns true.

Excerpt From
Framework Design Guidelines

Instead, let's let wrappers compare what is being wrapped.

Fixes #118701

@Copilot Copilot AI review requested due to automatic review settings August 14, 2025 01:04
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a fundamental issue with the Equals method implementation in cryptographic wrapper classes (RSAWrapper, ECDsaWrapper, and ECDiffieHellmanWrapper), which violated the Object.Equals contract by never returning true for self-comparison.

Key changes:

  • Updated Equals method in all three wrapper classes to properly compare the wrapped instances when both objects are wrappers
  • Added comprehensive unit tests to verify correct equality behavior for all cryptographic factory methods

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
RSAWrapper.cs Fixed Equals implementation to compare wrapped instances when both objects are RSAWrapper
ECDsaWrapper.cs Fixed Equals implementation to compare wrapped instances when both objects are ECDsaWrapper
ECDiffieHellmanWrapper.cs Fixed Equals implementation to compare wrapped instances when both objects are ECDiffieHellmanWrapper
RSAFactoryTests.cs Added tests verifying RSA instances satisfy reflexive equality and different instances are not equal
ECDsaFactoryTests.cs Added tests verifying ECDsa instances satisfy reflexive equality and different instances are not equal
ECDiffieHellmanFactoryTests.cs Added tests verifying ECDiffieHellman instances satisfy reflexive equality and different instances are not equal
*.Tests.csproj Updated test project files to include the new factory test files

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

@vcsjones
Copy link
Member Author

A final, final possible solution is to not do anything and say "Cryptographic primitives are like NaN!"

No? Bad idea? Okay.

@skyoxZ
Copy link
Contributor

skyoxZ commented Aug 14, 2025

One more:

public override bool Equals(object? obj) => _wrapped.Equals(obj);

@vcsjones
Copy link
Member Author

One more:

public override bool Equals(object? obj) => _wrapped.Equals(obj);

Thanks!

Copy link
Member

@bartonjs bartonjs left a comment

Choose a reason for hiding this comment

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

Looks good aside from one copy/paste/bad-edit

…thmImplementations/DSA/DSAFactoryTests.cs

Co-authored-by: Jeremy Barton <jbarton@microsoft.com>
@vcsjones vcsjones enabled auto-merge (squash) August 14, 2025 18:28
@vcsjones vcsjones merged commit 9fd7c39 into dotnet:main Aug 14, 2025
79 of 82 checks passed
@vcsjones vcsjones added this to the 10.0.0 milestone Aug 16, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Sep 15, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

.NET 8.0 - In Linux, RSAOpenSsl.Equals does not return true when comparing an instance with itself
4 participants