Skip to content

Commit a2edfb5

Browse files
rolandshoemakergopherbot
authored andcommittedNov 9, 2023
cryptobyte: fix ReadOptionalASN1Boolean
ReadOptionalASN1Boolean was completely broken, it would only work when there were two BOOLEAN fields in a row, with the first being OPTIONAL (which is itself invalid ASN.1 due to the ambiguity). This fixes it to properly expect a BOOLEAN wrapped in a context-specific tag, as is the case for all of the other ReadOptionalASN1* methods, and updates its doc string. This is a breaking change as it requires adding the tag field to properly support context-specific tags. Given the method would previously not work this seems like a reasonable breakage. Fixes golang/go#43019 Change-Id: I42398256216c59988e249c90bc7aa668f64df945 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/274242 Reviewed-by: Filippo Valsorda <filippo@golang.org> Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Roland Shoemaker <roland@golang.org>
1 parent ff15cd5 commit a2edfb5

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed
 

‎cryptobyte/asn1.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -733,13 +733,14 @@ func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag
733733
return true
734734
}
735735

736-
// ReadOptionalASN1Boolean sets *out to the value of the next ASN.1 BOOLEAN or,
737-
// if the next bytes are not an ASN.1 BOOLEAN, to the value of defaultValue.
738-
// It reports whether the operation was successful.
739-
func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
736+
// ReadOptionalASN1Boolean attempts to read an optional ASN.1 BOOLEAN
737+
// explicitly tagged with tag into out and advances. If no element with a
738+
// matching tag is present, it sets "out" to defaultValue instead. It reports
739+
// whether the read was successful.
740+
func (s *String) ReadOptionalASN1Boolean(out *bool, tag asn1.Tag, defaultValue bool) bool {
740741
var present bool
741742
var child String
742-
if !s.ReadOptionalASN1(&child, &present, asn1.BOOLEAN) {
743+
if !s.ReadOptionalASN1(&child, &present, tag) {
743744
return false
744745
}
745746

@@ -748,7 +749,7 @@ func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
748749
return true
749750
}
750751

751-
return s.ReadASN1Boolean(out)
752+
return child.ReadASN1Boolean(out)
752753
}
753754

754755
func (s *String) readASN1(out *String, outTag *asn1.Tag, skipHeader bool) bool {

‎cryptobyte/asn1_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,28 @@ func TestReadASN1OptionalInteger(t *testing.T) {
115115
}
116116
}
117117

118+
const defaultBool = false
119+
120+
var optionalBoolTestData = []readASN1Test{
121+
{"empty", []byte{}, 0xa0, true, false},
122+
{"invalid", []byte{0xa1, 0x3, 0x1, 0x2, 0x7f}, 0xa1, false, defaultBool},
123+
{"missing", []byte{0xa1, 0x3, 0x1, 0x1, 0x7f}, 0xa0, true, defaultBool},
124+
{"present", []byte{0xa1, 0x3, 0x1, 0x1, 0xff}, 0xa1, true, true},
125+
}
126+
127+
func TestReadASN1OptionalBoolean(t *testing.T) {
128+
for _, test := range optionalBoolTestData {
129+
t.Run(test.name, func(t *testing.T) {
130+
in := String(test.in)
131+
var out bool
132+
ok := in.ReadOptionalASN1Boolean(&out, test.tag, defaultBool)
133+
if ok != test.ok || ok && out != test.out.(bool) {
134+
t.Errorf("in.ReadOptionalASN1Boolean() = %v, want %v; out = %v, want %v", ok, test.ok, out, test.out)
135+
}
136+
})
137+
}
138+
}
139+
118140
func TestReadASN1IntegerSigned(t *testing.T) {
119141
testData64 := []struct {
120142
in []byte

0 commit comments

Comments
 (0)
Please sign in to comment.