Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SmartContract: catch exception on multisignature contract parsing #3211

Merged
merged 1 commit into from
May 5, 2024

Conversation

AnnaShaleva
Copy link
Member

@AnnaShaleva AnnaShaleva commented May 4, 2024

Description

IsMultiSigContract should return proper true/false result even if some garbage is provided as an input. Without this commit an exception is possible during IsMultiSigContract execution during subsequent public key decoding from compressed form:

  Failed TestIsMultiSigContract [16 ms]
  Error Message:
   Test method Neo.UnitTests.SmartContract.UT_Helper.TestIsMultiSigContract threw exception:
System.FormatException: Invalid point encoding 221
  Stack Trace:
      at Neo.Cryptography.ECC.ECPoint.DecodePoint(ReadOnlySpan`1 encoded, ECCurve curve) in /home/anna/Documents/GitProjects/neo-project/neo/src/Neo/Cryptography/ECC/ECPoint.cs:line 98
   at Neo.SmartContract.Helper.IsMultiSigContract(ReadOnlySpan`1 script, Int32& m, Int32& n, List`1 points) in /home/anna/Documents/GitProjects/neo-project/neo/src/Neo/SmartContract/Helper.cs:line 189
   at Neo.SmartContract.Helper.IsMultiSigContract(ReadOnlySpan`1 script) in /home/anna/Documents/GitProjects/neo-project/neo/src/Neo/SmartContract/Helper.cs:line 123
   at Neo.UnitTests.SmartContract.UT_Helper.TestIsMultiSigContract() in /home/anna/Documents/GitProjects/neo-project/neo/tests/Neo.UnitTests/SmartContract/UT_Helper.cs:line 65
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Note that this change is compatible wrt the callers' behaviour. We need this change to properly handle non-Secp256r1-based witness scripts, ref. #3209.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Unit test TestIsMultiSigContract_WrongCurve
  • Unit test TestIsSignatureContract_WrongCurve

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

IsMultiSigContract should return proper true/false result even if some
garbage is provided as an input. Without this commit an exception is
possible during IsMultiSigContract execution during subsequent public
key decoding from compressed form:
```
  Failed TestIsMultiSigContract [16 ms]
  Error Message:
   Test method Neo.UnitTests.SmartContract.UT_Helper.TestIsMultiSigContract threw exception:
System.FormatException: Invalid point encoding 221
  Stack Trace:
      at Neo.Cryptography.ECC.ECPoint.DecodePoint(ReadOnlySpan`1 encoded, ECCurve curve) in /home/anna/Documents/GitProjects/neo-project/neo/src/Neo/Cryptography/ECC/ECPoint.cs:line 98
   at Neo.SmartContract.Helper.IsMultiSigContract(ReadOnlySpan`1 script, Int32& m, Int32& n, List`1 points) in /home/anna/Documents/GitProjects/neo-project/neo/src/Neo/SmartContract/Helper.cs:line 189
   at Neo.SmartContract.Helper.IsMultiSigContract(ReadOnlySpan`1 script) in /home/anna/Documents/GitProjects/neo-project/neo/src/Neo/SmartContract/Helper.cs:line 123
   at Neo.UnitTests.SmartContract.UT_Helper.TestIsMultiSigContract() in /home/anna/Documents/GitProjects/neo-project/neo/tests/Neo.UnitTests/SmartContract/UT_Helper.cs:line 65
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
```

Note that this change is compatible wrt the callers' behaviour. We need
this change to properly handle non-Secp256r1-based witness scripts, ref.
#3209.

Signed-off-by: Anna Shaleva <[email protected]>
Copy link
Member

@vncoelho vncoelho left a comment

Choose a reason for hiding this comment

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

I think it is not "(non-breaking change which fixes an issue)", @AnnaShaleva .

Perhaps that without a proper version control an attacker could try to use this function and change behavior of past executions.
But I did not test yet.

Copy link
Member

@cschuchardt88 cschuchardt88 left a comment

Choose a reason for hiding this comment

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

Please write test for IVerifable.VerifyStateIndependent and IVeriable.VerifyWitnesses just to make sure they work with changes.

else if (IsMultiSigContract(witnesses[i].VerificationScript.Span, out var m, out ECPoint[] points))

public static bool VerifyWitnesses(this IVerifiable verifiable, ProtocolSettings settings, DataCache snapshot, long gas)

Copy link
Member

@vncoelho vncoelho left a comment

Choose a reason for hiding this comment

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

@AnnaShaleva,

I double checked here,
perhaps it does not need version control. In fact, it looks like it is just internal for fee calculations and transaction creation. Thus, it would not affect the understanding of previous transactions.

Copy link
Contributor

@roman-khimov roman-khimov left a comment

Choose a reason for hiding this comment

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

Correct fix (and likely more important than just to "properly handle non-Secp256r1-based witness scripts"), but I fear we may have more cases like this in the codebase (like VerifySignature).

@roman-khimov roman-khimov added this to the v3.7.0 milestone May 4, 2024
@roman-khimov roman-khimov added Bug Used to tag confirmed bugs Critical Issues (bugs) that need to be fixed ASAP labels May 4, 2024
@cschuchardt88
Copy link
Member

@roman-khimov

Correct fix (and likely more important than just to "properly handle non-Secp256r1-based witness scripts"), but I fear we may have more cases like this in the codebase (like VerifySignature).

Hints my tests for IVerifable.VerifyStateIndependent if it errors it should return VerifyResult.Succeed.

#3211 (review)

@shargon shargon merged commit f6c26cb into master May 5, 2024
6 checks passed
@shargon shargon deleted the fix-contract-checks branch May 5, 2024 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Used to tag confirmed bugs Critical Issues (bugs) that need to be fixed ASAP
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants