github.com/secure-build/gitlab-runner@v12.5.0+incompatible/helpers/tls/ca_chain/resolver_verify_test.go (about)

     1  package ca_chain
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/x509"
     6  	"errors"
     7  	"testing"
     8  
     9  	"github.com/sirupsen/logrus"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  type verifierMockFactory func(t *testing.T) verifier
    14  
    15  func newVerifierMock(inputCert *x509.Certificate, chain [][]*x509.Certificate, err error) verifierMockFactory {
    16  	return func(t *testing.T) verifier {
    17  		return func(cert *x509.Certificate) ([][]*x509.Certificate, error) {
    18  			assert.Equal(t, inputCert, cert)
    19  
    20  			return chain, err
    21  		}
    22  	}
    23  }
    24  
    25  func TestVerifyResolver_Resolve(t *testing.T) {
    26  	testError := errors.New("test-error")
    27  	testUnknownAuthorityError := x509.UnknownAuthorityError{}
    28  
    29  	testCACertificate := loadCertificate(t, testCACert)
    30  	testCertificate := loadCertificate(t, testCert)
    31  
    32  	tests := map[string]struct {
    33  		certs          []*x509.Certificate
    34  		mockVerifier   verifierMockFactory
    35  		expectedError  string
    36  		expectedCerts  []*x509.Certificate
    37  		expectedOutput []string
    38  	}{
    39  		"empty input chain": {
    40  			certs:          nil,
    41  			expectedError:  "",
    42  			expectedCerts:  nil,
    43  			expectedOutput: nil,
    44  		},
    45  		"last certificate is self signed": {
    46  			certs:          []*x509.Certificate{testCACertificate},
    47  			expectedError:  "",
    48  			expectedCerts:  []*x509.Certificate{testCACertificate},
    49  			expectedOutput: nil,
    50  		},
    51  		"last certificate is not self signed, verifier fails with unknown authority": {
    52  			certs:         []*x509.Certificate{testCertificate},
    53  			mockVerifier:  newVerifierMock(testCertificate, [][]*x509.Certificate{{testCACertificate}}, testUnknownAuthorityError),
    54  			expectedError: "",
    55  			expectedCerts: []*x509.Certificate{testCertificate},
    56  			expectedOutput: []string{
    57  				"Verifying last certificate to find the final root certificate",
    58  				"Last certificate signed by unknown authority; will not update the chain",
    59  			},
    60  		},
    61  		"last certificate is not self signed, verifier fails with unexpected error": {
    62  			certs:         []*x509.Certificate{testCertificate},
    63  			mockVerifier:  newVerifierMock(testCertificate, [][]*x509.Certificate{{testCACertificate}}, testError),
    64  			expectedError: "error while verifying last certificate from the chain: test-error",
    65  			expectedCerts: nil,
    66  			expectedOutput: []string{
    67  				"Verifying last certificate to find the final root certificate",
    68  			},
    69  		},
    70  		"last certificate is not self signed, duplicate of input certificate in verify chain": {
    71  			certs:         []*x509.Certificate{testCertificate},
    72  			mockVerifier:  newVerifierMock(testCertificate, [][]*x509.Certificate{{testCertificate, testCertificate}, {testCertificate}}, nil),
    73  			expectedError: "",
    74  			expectedCerts: []*x509.Certificate{testCertificate},
    75  			expectedOutput: []string{
    76  				"Verifying last certificate to find the final root certificate",
    77  			},
    78  		},
    79  		"last certificate is not self signed, other certificates in verify chain": {
    80  			certs:         []*x509.Certificate{testCertificate},
    81  			mockVerifier:  newVerifierMock(testCertificate, [][]*x509.Certificate{{testCACertificate}, {testCertificate}}, nil),
    82  			expectedError: "",
    83  			expectedCerts: []*x509.Certificate{testCertificate, testCACertificate},
    84  			expectedOutput: []string{
    85  				"Verifying last certificate to find the final root certificate",
    86  				"Adding cert from verify chain to the final chain",
    87  			},
    88  		},
    89  	}
    90  
    91  	for tn, tc := range tests {
    92  		t.Run(tn, func(t *testing.T) {
    93  			out := new(bytes.Buffer)
    94  
    95  			logger := logrus.New()
    96  			logger.SetLevel(logrus.DebugLevel)
    97  			logger.SetOutput(out)
    98  
    99  			r := newVerifyResolver(logger).(*verifyResolver)
   100  
   101  			if tc.mockVerifier != nil {
   102  				r.verifier = tc.mockVerifier(t)
   103  			}
   104  
   105  			newCerts, err := r.Resolve(tc.certs)
   106  
   107  			if tc.expectedError != "" {
   108  				assert.EqualError(t, err, tc.expectedError)
   109  			} else {
   110  				assert.NoError(t, err)
   111  			}
   112  
   113  			assert.Equal(t, tc.expectedCerts, newCerts)
   114  
   115  			output := out.String()
   116  			if len(tc.expectedOutput) > 0 {
   117  				for _, expectedLine := range tc.expectedOutput {
   118  					assert.Contains(t, output, expectedLine)
   119  				}
   120  			} else {
   121  				assert.Empty(t, output)
   122  			}
   123  		})
   124  	}
   125  }