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