mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-28 16:37:24 +02:00
* core/ci: update linting * re-add exportloopref * re-add gocheckcompilerdirectives * re-add stylecheck * re-add usestdlibvars * upgrade lint --------- Co-authored-by: Denis Mishin <dmishin@pomerium.com>
220 lines
5.4 KiB
Go
220 lines
5.4 KiB
Go
package criteria
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/open-policy-agent/opa/ast"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/pomerium/pomerium/pkg/policy/parser"
|
|
)
|
|
|
|
const testCert = `
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIBYTCCAQigAwIBAgICEAEwCgYIKoZIzj0EAwIwGjEYMBYGA1UEAxMPVHJ1c3Rl
|
|
ZCBSb290IENBMCAYDzAwMDEwMTAxMDAwMDAwWhcNMzMwNzMxMTUzMzE5WjAeMRww
|
|
GgYDVQQDExN0cnVzdGVkIGNsaWVudCBjZXJ0MFkwEwYHKoZIzj0CAQYIKoZIzj0D
|
|
AQcDQgAEfAYP3ZwiKJgk9zXpR/CMHYlAxjweJaMJihIS2FTA5gb0xBcTEe5AGpNF
|
|
CHWPk4YCB25VeHg9GmY9Q1+qDD1hdqM4MDYwEwYDVR0lBAwwCgYIKwYBBQUHAwIw
|
|
HwYDVR0jBBgwFoAUXep6D8FTP6+5ZdR/HjP3pYfmxkwwCgYIKoZIzj0EAwIDRwAw
|
|
RAIgProROtxpvKS/qjrjonSvacnhdU0JwoXj2DgYvF/qjrUCIAXlHkdEzyXmTLuu
|
|
/YxuOibV35vlaIzj21GRj4pYmVR1
|
|
-----END CERTIFICATE-----`
|
|
|
|
func TestClientCertificate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cases := []struct {
|
|
label string
|
|
policy string
|
|
cert string
|
|
expected A
|
|
}{
|
|
{
|
|
"no certificate",
|
|
`allow:
|
|
or:
|
|
- client_certificate:
|
|
fingerprint: 17859273e8a980631d367b2d5a6a6635412b0f22835f69e47b3f65624546a704`,
|
|
"",
|
|
A{false, A{ReasonClientCertificateUnauthorized}, M{}},
|
|
},
|
|
{
|
|
"no fingerprint match",
|
|
`allow:
|
|
or:
|
|
- client_certificate:
|
|
fingerprint: df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a`,
|
|
testCert,
|
|
A{false, A{ReasonClientCertificateUnauthorized}, M{}},
|
|
},
|
|
{
|
|
"fingerprint match",
|
|
`allow:
|
|
or:
|
|
- client_certificate:
|
|
fingerprint: 17859273e8a980631d367b2d5a6a6635412b0f22835f69e47b3f65624546a704`,
|
|
testCert,
|
|
A{true, A{ReasonClientCertificateOK}, M{}},
|
|
},
|
|
{
|
|
"fingerprint list match",
|
|
`allow:
|
|
or:
|
|
- client_certificate:
|
|
fingerprint:
|
|
- 17859273e8a980631d367b2d5a6a6635412b0f22835f69e47b3f65624546a704
|
|
- df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a`,
|
|
testCert,
|
|
A{true, A{ReasonClientCertificateOK}, M{}},
|
|
},
|
|
{
|
|
"spki hash match",
|
|
`allow:
|
|
or:
|
|
- client_certificate:
|
|
spki_hash: FsDbM0rUYIiL3V339eIKqiz6HPSB+Pz2WeAWhqlqh8U=`,
|
|
testCert,
|
|
A{true, A{ReasonClientCertificateOK}, M{}},
|
|
},
|
|
{
|
|
"spki hash list match",
|
|
`allow:
|
|
or:
|
|
- client_certificate:
|
|
spki_hash:
|
|
- FsDbM0rUYIiL3V339eIKqiz6HPSB+Pz2WeAWhqlqh8U=
|
|
- NvqYIYSbgK2vCJpQhObf77vv+bQWtc5ek5RIOwPiC9A=`,
|
|
testCert,
|
|
A{true, A{ReasonClientCertificateOK}, M{}},
|
|
},
|
|
}
|
|
|
|
for i := range cases {
|
|
c := cases[i]
|
|
t.Run(c.label, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
input := Input{
|
|
HTTP: InputHTTP{
|
|
ClientCertificate: ClientCertificateInfo{
|
|
Leaf: c.cert,
|
|
},
|
|
},
|
|
}
|
|
res, err := evaluate(t, c.policy, nil, input)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, c.expected, res["allow"])
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCanonicalCertFingerprint(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cases := []struct {
|
|
label string
|
|
input string
|
|
output string
|
|
err string
|
|
}{
|
|
{
|
|
"object",
|
|
`{}`, "", "certificate fingerprint must be a string (was {})",
|
|
},
|
|
{
|
|
"empty",
|
|
`""`, "", "certificate fingerprint must not be empty",
|
|
},
|
|
{
|
|
"SHA-1 fingerprint",
|
|
`"B1:E6:A2:DC:DD:6B:87:A4:9B:C5:7C:3B:7C:7F:1C:74:9A:DB:88:36"`,
|
|
"", "unsupported certificate fingerprint format (B1:E6:A2:DC:DD:6B:87:A4:9B:C5:7C:3B:7C:7F:1C:74:9A:DB:88:36)",
|
|
},
|
|
{
|
|
"uppercase short",
|
|
`"DF6FF72FE9116521268F6F2DD4966F51DF479883FE7037B39F75916AC3049D1A"`,
|
|
"", "unsupported certificate fingerprint format (DF6FF72FE9116521268F6F2DD4966F51DF479883FE7037B39F75916AC3049D1A)",
|
|
},
|
|
{
|
|
"valid short",
|
|
`"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a"`,
|
|
"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a", "",
|
|
},
|
|
{
|
|
"lowercase long",
|
|
`"df:6f:f7:2f:e9:11:65:21:26:8f:6f:2d:d4:96:6f:51:df:47:98:83:fe:70:37:b3:9f:75:91:6a:c3:04:9d:1a"`,
|
|
"", "unsupported certificate fingerprint format (df:6f:f7:2f:e9:11:65:21:26:8f:6f:2d:d4:96:6f:51:df:47:98:83:fe:70:37:b3:9f:75:91:6a:c3:04:9d:1a)",
|
|
},
|
|
{
|
|
"valid long",
|
|
`"DF:6F:F7:2F:E9:11:65:21:26:8F:6F:2D:D4:96:6F:51:DF:47:98:83:FE:70:37:B3:9F:75:91:6A:C3:04:9D:1A"`,
|
|
"df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a", "",
|
|
},
|
|
}
|
|
|
|
for i := range cases {
|
|
c := cases[i]
|
|
t.Run(c.label, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
value, err := parser.ParseValue(strings.NewReader(c.input))
|
|
require.NoError(t, err)
|
|
|
|
f, err := canonicalCertFingerprint(value)
|
|
if c.err == "" {
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ast.String(c.output), f)
|
|
} else {
|
|
assert.Equal(t, c.err, err.Error())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSPKIHashFormatErrors(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cases := []struct {
|
|
label string
|
|
input string
|
|
err string
|
|
}{
|
|
{
|
|
"object",
|
|
`{}`, "certificate SPKI hash condition expects a string or array of strings",
|
|
},
|
|
{
|
|
"not base64",
|
|
`"not%valid%base64%data"`, "certificate SPKI hash must be a base64-encoded SHA-256 hash (was not%valid%base64%data)",
|
|
},
|
|
{
|
|
"SHA-1 hash",
|
|
`"VYby3BAoHawLLtsyckwo5Q=="`, "certificate SPKI hash must be a base64-encoded SHA-256 hash (was VYby3BAoHawLLtsyckwo5Q==)",
|
|
},
|
|
{
|
|
"valid",
|
|
`"FsDbM0rUYIiL3V339eIKqiz6HPSB+Pz2WeAWhqlqh8U="`, "",
|
|
},
|
|
}
|
|
|
|
for i := range cases {
|
|
c := cases[i]
|
|
t.Run(c.label, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
value, err := parser.ParseValue(strings.NewReader(c.input))
|
|
require.NoError(t, err)
|
|
|
|
var body ast.Body
|
|
err = addCertSPKIHashCondition(&body, value)
|
|
if c.err == "" {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Equal(t, c.err, err.Error())
|
|
}
|
|
})
|
|
}
|
|
}
|