You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
var item = (AsymmetricSignatureFormatter)CryptoHelpersCreateFromName.Invoke(null, new object[] { FormatterAlgorithm });
Where CryptoHelpersCreateFromName is fetched from an internal .NET core assembly using reflection:
var helperType = Type.GetType("System.Security.Cryptography.Xml.CryptoHelpers, System.Security.Cryptography.Xml");
CryptoHelpersCreateFromName = helperType.GetTypeInfo().GetDeclaredMethod("CreateFromName");
I believe the error is being raised because, in current versions of .NET core, the CreateFromName method is generic, but the generic type parameter is not being instantiated before the method is Invoke'd. It looks to me like originally, when this code was written, the method was not generic, but in .NET core 2.0.8 it was made generic.
As a workaround, I changed the call to the public method CryptoConfig.CreateFromName, and this seemed to make signing work correctly in my case. This has slightly different behaviour than the old reflection call, though.
I have a few ideas for fixes, but would appreciate some guidance:
Update the existing code to instantiate the generic parameter before Invokeing the method. This would most closely match the previous behaviour, but would still depend on an internal method that may unexpectedly change again in the future.
Call a different, public method like CryptoConfig.CreateFromName (I have no idea if the change in behaviour is important!)
Reproduce the code from the internal CryptoHelpers class inside this project, to keep the previous behaviour without needing to call the internal code
I lean towards the third option, but am unsure. I'm happy to open a PR for any of these, or a different solution. Any thoughts on the best approach?
The text was updated successfully, but these errors were encountered:
Thanks for looking into this. I'm sure you're right in your analysis as this code hasn't been touched in a long time. I'm sure that changes in the underlying runtime broke this.
I'm not sure if the change in behavior is relevant? If you're able to get it working and have VSTO working, then that's all that really matters, I think. I'd gladly take a PR.
mgiles
pushed a commit
to mgiles/SignService
that referenced
this issue
Aug 10, 2020
dotnet#266
The previous code attempts to invoke an internal method in .NET Core as
if it's non-generic, but in recent framework versions it _is_ generic.
This commit replaces the call with a non-reflective call on a public
method to avoid similar backwards-breaking changes in the future.
Note: There are some special cases handled by the internal method
System.Security.Cryptography.Xml.CryptoHelpers.CreateFromName that
are not handled by the replacement method, CryptoConfig.CreateFromName.
However, the only names used in CryptoConfigShims are for
RSAPKCS1SignatureFormatter and RSAPKCS1SignatureDeformatter, neither of
which appear to be in the list of special cases. So for the purposes of
CryptoConfigShims, I think the new behaviour is equivalent.
When attempting to sign a VSTO ClickOnce archive, I encounter the following error:
Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.
In my case, this is being raised from line 35 in CryptoConfigShims:
var item = (AsymmetricSignatureFormatter)CryptoHelpersCreateFromName.Invoke(null, new object[] { FormatterAlgorithm });
Where
CryptoHelpersCreateFromName
is fetched from an internal .NET core assembly using reflection:I believe the error is being raised because, in current versions of .NET core, the
CreateFromName
method is generic, but the generic type parameter is not being instantiated before the method isInvoke
'd. It looks to me like originally, when this code was written, the method was not generic, but in .NET core 2.0.8 it was made generic.As a workaround, I changed the call to the public method CryptoConfig.CreateFromName, and this seemed to make signing work correctly in my case. This has slightly different behaviour than the old reflection call, though.
I have a few ideas for fixes, but would appreciate some guidance:
Invoke
ing the method. This would most closely match the previous behaviour, but would still depend on an internal method that may unexpectedly change again in the future.CryptoConfig.CreateFromName
(I have no idea if the change in behaviour is important!)CryptoHelpers
class inside this project, to keep the previous behaviour without needing to call the internal codeI lean towards the third option, but am unsure. I'm happy to open a PR for any of these, or a different solution. Any thoughts on the best approach?
The text was updated successfully, but these errors were encountered: