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

x/crypto/cryptobyte: ReadOptionalASN1Boolean doesn't work as expected #43019

Closed
rolandshoemaker opened this issue Dec 5, 2020 · 9 comments
Closed
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Proposal Proposal-Accepted Proposal-Crypto Proposal related to crypto packages or other security issues
Milestone

Comments

@rolandshoemaker
Copy link
Member

rolandshoemaker commented Dec 5, 2020

ReadOptionalASN1Boolean doesn't work like the other ReadOptionalASN1* methods, nor does it work in the way it seems to be intended.

ReadOptionalASN1Boolean seems to expect to support reading a example BOOLEAN OPTIONAL field that does not use context-specific tags, unlike the other ReadOptionalASN1* methods, but will in fact only work when reading a structure containing two subsequent BOOLEAN fields, i.e.

example-a BOOLEAN OPTIONAL
example-b BOOLEAN

as it continues reading from the source cryptobyte.String, rather than the optional field.

There are two possible solutions for this. (1) fix the method to support optional fields without context-specific tags (which are rather rare), or (2) fix the method to support optional fields with context-specific tags (which matches the other ReadOptionalASN1* methods). I think (2) makes the most sense since it aligns with the other methods in the package and is more likely to be used in the real world, but it does require breaking the existing API by adding an argument for the expected context-specific tag.

As far as I can tell there are no uses of this method in the standard library, and after a quick search of GitHub I was unable to find any third-party packages using this (if any are, they are likely quite broken since this method should never really work).

@gopherbot gopherbot added this to the Unreleased milestone Dec 5, 2020
@cagedmantis cagedmantis added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 7, 2020
@gopherbot
Copy link

Change https://golang.org/cl/274242 mentions this issue: cryptobyte: fix ReadOptionalASN1Boolean

@katiehockman katiehockman modified the milestones: Unreleased, Go1.17 Apr 6, 2021
@FiloSottile FiloSottile changed the title x/crypto/cryptobyte: ReadOptionalASN1Boolean doesn't work as expected proposal: x/crypto/cryptobyte: ReadOptionalASN1Boolean doesn't work as expected Dec 5, 2022
@FiloSottile
Copy link
Contributor

Indeed, ReadOptionalASN1Boolean is completely broken at the moment, and it seems to be fully unused.

I support fixing it before tagging v1 of x/crypto, despite considering x/crypto stable already, because 1) nothing will break as far as I can tell and 2) anything that breaks was very broken already.

The proposal is to change it to this

(s *String) ReadOptionalASN1Boolean(out *bool, tag asn1.Tag, defaultValue bool) bool

Note that adding the tag asn1.Tag argument and breaking the API is not actually necessary to fix the bug, but 1) it makes ReadOptionalASN1Boolean actually useful since OPTIONALs are commonly explicitly tagged, 2) it makes it consistent with other ReadOptionalASN1, and 3) it prevents confusion with the previous ReadOptionalASN1Boolean implementation.

Over to @golang/proposal-review since it's an API change.

@ianlancetaylor ianlancetaylor added the Proposal-Crypto Proposal related to crypto packages or other security issues label Dec 7, 2022
@rsc
Copy link
Contributor

rsc commented Aug 30, 2023

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc
Copy link
Contributor

rsc commented Sep 6, 2023

Given that the function fails today (does not do what it should) and cannot do what it should without a new argument and for that reason appears to be completely unused, it seems OK to make an API breaking change here.

We did this in the past for a function in syscall that was impossible to call because it took an argument of unexported type. This is not quite that strictly impossible but still seems reasonable.

@rsc
Copy link
Contributor

rsc commented Oct 11, 2023

Have all remaining concerns about this proposal been addressed?

@rolandshoemaker
Copy link
Member Author

I believe so.

@rsc
Copy link
Contributor

rsc commented Oct 25, 2023

I still had some hesitation about making a breaking change, so I scanned the latest version of each module available on the module proxy for ReadOptionalASN1Boolean (about a million modules). I found 779 copies of the code but zero calls to it. This does seem to be the exceptional case where we can reasonably redefine the existing API.

@rsc
Copy link
Contributor

rsc commented Oct 26, 2023

Based on the discussion above, this proposal seems like a likely accept.
— rsc for the proposal review group

In package cryptobyte, change the (*String).ReadOptionalASN1Boolean method signature to:

(s *String) ReadOptionalASN1Boolean(out *bool, tag asn1.Tag, defaultValue bool) bool

This adds a new “tag” parameter so that the code can tell whether the optional boolean is present or not. The current function signature is unfixably broken and impossible to use correctly.

Even unfixably broken and impossible to use correctly is not enough to merit an actual breaking API change. We also scanned all public Go code in the module proxy and found not a single use of this method, suggesting that it really is safe to redefine.

(It is not surprising no one uses it, since if they did, the code wouldn’t work! But that doesn’t always stop people. In this case, the method is also obscure enough that we seem to have gotten lucky.)

@rsc
Copy link
Contributor

rsc commented Nov 2, 2023

No change in consensus, so accepted. 🎉
This issue now tracks the work of implementing the proposal.
— rsc for the proposal review group

In package cryptobyte, change the (*String).ReadOptionalASN1Boolean method signature to:

(s *String) ReadOptionalASN1Boolean(out *bool, tag asn1.Tag, defaultValue bool) bool

This adds a new “tag” parameter so that the code can tell whether the optional boolean is present or not. The current function signature is unfixably broken and impossible to use correctly.

Even unfixably broken and impossible to use correctly is not enough to merit an actual breaking API change. We also scanned all public Go code in the module proxy and found not a single use of this method, suggesting that it really is safe to redefine.

(It is not surprising no one uses it, since if they did, the code wouldn’t work! But that doesn’t always stop people. In this case, the method is also obscure enough that we seem to have gotten lucky.)

@rsc rsc changed the title proposal: x/crypto/cryptobyte: ReadOptionalASN1Boolean doesn't work as expected x/crypto/cryptobyte: ReadOptionalASN1Boolean doesn't work as expected Nov 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Proposal Proposal-Accepted Proposal-Crypto Proposal related to crypto packages or other security issues
Projects
Status: Accepted
Development

No branches or pull requests

7 participants