boulder/linter/lints/common_test.go

101 lines
3.1 KiB
Go

package lints
import (
"testing"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
"github.com/letsencrypt/boulder/test"
)
var onlyContainsUserCertsTag = asn1.Tag(1).ContextSpecific()
var onlyContainsCACertsTag = asn1.Tag(2).ContextSpecific()
func TestReadOptionalASN1BooleanWithTag(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
// incoming will be mutated by the function under test
incoming []byte
out bool
defaultValue bool
asn1Tag asn1.Tag
expectedOk bool
// expectedTrailer counts the remaining bytes from incoming after having
// been advanced by the function under test
expectedTrailer int
expectedOut bool
}{
{
name: "Good: onlyContainsUserCerts",
incoming: cryptobyte.String([]byte{0x81, 0x01, 0xFF}),
asn1Tag: onlyContainsUserCertsTag,
expectedOk: true,
expectedTrailer: 0,
expectedOut: true,
},
{
name: "Good: onlyContainsCACerts",
incoming: cryptobyte.String([]byte{0x82, 0x01, 0xFF}),
asn1Tag: onlyContainsCACertsTag,
expectedOk: true,
expectedTrailer: 0,
expectedOut: true,
},
{
name: "Good: Bytes are read and trailer remains",
incoming: cryptobyte.String([]byte{0x82, 0x01, 0xFF, 0xC0, 0xFF, 0xEE, 0xCA, 0xFE}),
asn1Tag: onlyContainsCACertsTag,
expectedOk: true,
expectedTrailer: 5,
expectedOut: true,
},
{
name: "Bad: Read the tag, but out should be false, no trailer",
incoming: cryptobyte.String([]byte{0x82, 0x01, 0x00}),
asn1Tag: onlyContainsCACertsTag,
expectedOk: true,
expectedTrailer: 0,
expectedOut: false,
},
{
name: "Bad: Read the tag, but out should be false, trailer remains",
incoming: cryptobyte.String([]byte{0x82, 0x01, 0x00, 0x99}),
asn1Tag: onlyContainsCACertsTag,
expectedOk: true,
expectedTrailer: 1,
expectedOut: false,
},
{
name: "Bad: Wrong asn1Tag compared to incoming bytes, no bytes read",
incoming: cryptobyte.String([]byte{0x81, 0x01, 0xFF}),
asn1Tag: onlyContainsCACertsTag,
expectedOk: true,
expectedTrailer: 3,
expectedOut: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
// ReadOptionalASN1BooleanWithTag accepts nil as a valid outParam to
// maintain the style of upstream x/crypto/cryptobyte, but we
// currently don't pass nil. Instead we use a reference to a
// pre-existing boolean here and in the lint code. Passing in nil
// will _do the wrong thing (TM)_ in our CRL lints.
var outParam bool
ok := ReadOptionalASN1BooleanWithTag((*cryptobyte.String)(&tc.incoming), &outParam, tc.asn1Tag, false)
t.Log("Check if reading the tag was successful:")
test.AssertEquals(t, ok, tc.expectedOk)
t.Log("Check value of the optional boolean:")
test.AssertEquals(t, outParam, tc.expectedOut)
t.Log("Bytes should be popped off of incoming as they're successfully read:")
test.AssertEquals(t, len(tc.incoming), tc.expectedTrailer)
})
}
}