github.com/letsencrypt/boulder@v0.20251208.0/linter/lints/common_test.go (about)

     1  package lints
     2  
     3  import (
     4  	"testing"
     5  
     6  	"golang.org/x/crypto/cryptobyte"
     7  	"golang.org/x/crypto/cryptobyte/asn1"
     8  
     9  	"github.com/letsencrypt/boulder/test"
    10  )
    11  
    12  var onlyContainsUserCertsTag = asn1.Tag(1).ContextSpecific()
    13  var onlyContainsCACertsTag = asn1.Tag(2).ContextSpecific()
    14  
    15  func TestReadOptionalASN1BooleanWithTag(t *testing.T) {
    16  	t.Parallel()
    17  
    18  	testCases := []struct {
    19  		name string
    20  		// incoming will be mutated by the function under test
    21  		incoming     []byte
    22  		out          bool
    23  		defaultValue bool
    24  		asn1Tag      asn1.Tag
    25  		expectedOk   bool
    26  		// expectedTrailer counts the remaining bytes from incoming after having
    27  		// been advanced by the function under test
    28  		expectedTrailer int
    29  		expectedOut     bool
    30  	}{
    31  		{
    32  			name:            "Good: onlyContainsUserCerts",
    33  			incoming:        cryptobyte.String([]byte{0x81, 0x01, 0xFF}),
    34  			asn1Tag:         onlyContainsUserCertsTag,
    35  			expectedOk:      true,
    36  			expectedTrailer: 0,
    37  			expectedOut:     true,
    38  		},
    39  		{
    40  			name:            "Good: onlyContainsCACerts",
    41  			incoming:        cryptobyte.String([]byte{0x82, 0x01, 0xFF}),
    42  			asn1Tag:         onlyContainsCACertsTag,
    43  			expectedOk:      true,
    44  			expectedTrailer: 0,
    45  			expectedOut:     true,
    46  		},
    47  		{
    48  			name:            "Good: Bytes are read and trailer remains",
    49  			incoming:        cryptobyte.String([]byte{0x82, 0x01, 0xFF, 0xC0, 0xFF, 0xEE, 0xCA, 0xFE}),
    50  			asn1Tag:         onlyContainsCACertsTag,
    51  			expectedOk:      true,
    52  			expectedTrailer: 5,
    53  			expectedOut:     true,
    54  		},
    55  		{
    56  			name:            "Bad: Read the tag, but out should be false, no trailer",
    57  			incoming:        cryptobyte.String([]byte{0x82, 0x01, 0x00}),
    58  			asn1Tag:         onlyContainsCACertsTag,
    59  			expectedOk:      true,
    60  			expectedTrailer: 0,
    61  			expectedOut:     false,
    62  		},
    63  		{
    64  			name:            "Bad: Read the tag, but out should be false, trailer remains",
    65  			incoming:        cryptobyte.String([]byte{0x82, 0x01, 0x00, 0x99}),
    66  			asn1Tag:         onlyContainsCACertsTag,
    67  			expectedOk:      true,
    68  			expectedTrailer: 1,
    69  			expectedOut:     false,
    70  		},
    71  		{
    72  			name:            "Bad: Wrong asn1Tag compared to incoming bytes, no bytes read",
    73  			incoming:        cryptobyte.String([]byte{0x81, 0x01, 0xFF}),
    74  			asn1Tag:         onlyContainsCACertsTag,
    75  			expectedOk:      true,
    76  			expectedTrailer: 3,
    77  			expectedOut:     false,
    78  		},
    79  	}
    80  
    81  	for _, tc := range testCases {
    82  		t.Run(tc.name, func(t *testing.T) {
    83  			t.Parallel()
    84  
    85  			// ReadOptionalASN1BooleanWithTag accepts nil as a valid outParam to
    86  			// maintain the style of upstream x/crypto/cryptobyte, but we
    87  			// currently don't pass nil. Instead we use a reference to a
    88  			// pre-existing boolean here and in the lint code. Passing in nil
    89  			// will _do the wrong thing (TM)_ in our CRL lints.
    90  			var outParam bool
    91  			ok := ReadOptionalASN1BooleanWithTag((*cryptobyte.String)(&tc.incoming), &outParam, tc.asn1Tag, false)
    92  			t.Log("Check if reading the tag was successful:")
    93  			test.AssertEquals(t, ok, tc.expectedOk)
    94  			t.Log("Check value of the optional boolean:")
    95  			test.AssertEquals(t, outParam, tc.expectedOut)
    96  			t.Log("Bytes should be popped off of incoming as they're successfully read:")
    97  			test.AssertEquals(t, len(tc.incoming), tc.expectedTrailer)
    98  		})
    99  	}
   100  }