Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kuma-cp) Intermediate CA support #2575

Merged
merged 1 commit into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 22 additions & 27 deletions pkg/plugins/ca/provided/ca_cert_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,28 @@ func validateCaCert(signingPair util_tls.KeyPair) (verr validators.ValidationErr
verr.AddViolation("cert", fmt.Sprintf("not a valid TLS key pair: %s", err))
return
}
if len(tlsKeyPair.Certificate) != 1 {
verr.AddViolation("cert", "certificate must be a root CA (certificate chains are not allowed)") // Envoy constraint
return
}
cert, err := x509.ParseCertificate(tlsKeyPair.Certificate[0])
if err != nil {
verr.AddViolation("cert", fmt.Sprintf("not a valid x509 certificate: %s", err))
return
}
if cert.Issuer.String() != cert.Subject.String() {
verr.AddViolation("cert", "certificate must be self-signed (intermediate CAs are not allowed)") // Envoy constraint
}
if !cert.IsCA {
verr.AddViolation("cert", "basic constraint 'CA' must be set to 'true' (see X509-SVID: 4.1. Basic Constraints)")
for i, certificate := range tlsKeyPair.Certificate {
path := validators.RootedAt("cert").Index(i)
cert, err := x509.ParseCertificate(certificate)
if err != nil {
verr.AddViolationAt(path, fmt.Sprintf("not a valid x509 certificate: %s", err))
return
}
if !cert.IsCA {
verr.AddViolationAt(path, "basic constraint 'CA' must be set to 'true' (see X509-SVID: 4.1. Basic Constraints)")
}
if cert.KeyUsage&x509.KeyUsageCertSign == 0 {
verr.AddViolationAt(path, "key usage extension 'keyCertSign' must be set (see X509-SVID: 4.3. Key Usage)")
}
if cert.KeyUsage&x509.KeyUsageDigitalSignature != 0 {
verr.AddViolationAt(path, "key usage extension 'digitalSignature' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)")
}
if cert.KeyUsage&x509.KeyUsageKeyAgreement != 0 {
verr.AddViolationAt(path, "key usage extension 'keyAgreement' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)")
}
if cert.KeyUsage&x509.KeyUsageKeyEncipherment != 0 {
verr.AddViolationAt(path, "key usage extension 'keyEncipherment' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)")
}
}
if cert.KeyUsage&x509.KeyUsageCertSign == 0 {
verr.AddViolation("cert", "key usage extension 'keyCertSign' must be set (see X509-SVID: 4.3. Key Usage)")
}
if cert.KeyUsage&x509.KeyUsageDigitalSignature != 0 {
verr.AddViolation("cert", "key usage extension 'digitalSignature' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)")
}
if cert.KeyUsage&x509.KeyUsageKeyAgreement != 0 {
verr.AddViolation("cert", "key usage extension 'keyAgreement' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)")
}
if cert.KeyUsage&x509.KeyUsageKeyEncipherment != 0 {
verr.AddViolation("cert", "key usage extension 'keyEncipherment' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)")
}

return
}
164 changes: 11 additions & 153 deletions pkg/plugins/ca/provided/ca_cert_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,148 +126,6 @@ LG//nB619RAlzta6BxweiCmFxPyB+oqJl3X9NfWC7988CzfZAqHA+CqO6tJS5i53
WMciH6+W7o9wdsBrfFVx2tGZqc4bZgoZptHFieqz7YBnT0Ozg+NwBU6apAtAc5Ym
DMoTRP2Vo+BEm4uS4GcIFZYqrOsPuuyMuBd0NDE33g==
-----END CERTIFICATE-----
`),
KeyPEM: []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvh4DhQDuE/oXjEJzt1TmgmM6s5DtsIYIEPssxdDiDEjmJzhG
APd0BmAfrz3/fXZ6CqqqfAvTKkTDGjSN0hGtt1thF72weNfmQX9c1gUukEA0gERS
OsSWlzp8Azc5fjXtl5jiQkvaapNoQ8PljLc8SEsgndvdxD1tDVWN6h90bMgtuqyK
M7Fn/1+nwhRExKRTOSlR0iS9eddWPcN3HNGrl3vjCF0oUF/79+nJJqeaXawt0+2P
CMkxY6T6yzFaS/h0Oy3mXLOQ1H5n3cZ2MSEMKQSs9ff8gzeHpWyXpgB1XEKNcUvi
rVKfaJ/WE5v0rieG89B/YnQTduQnrwmPVuwm4wIDAQABAoIBAQCxKKrC7+DqwKvc
ybem6Ph8HBeBaNX1HpC5sjVAiKt8IxpFBc1F7VEy97POywkfUp3a/rorKaG2y6i6
7KoTTOIB8KcDRoIBub4Y3qQV03JWfV3vALtXhAWIGrmhDX8Hux0RnSeJ+8EmewI3
034+qCkGfOuB7nYy/cJ3IHhD6NfG3Q3FrBrGfsI2TGEeGmPJ2Xi8ZyfbluRb/1Bt
NesS6pDbRpZ5/IoauLUtITY3bazpzghm2tJNdrJIP7ohaoMF0WYciPyD5xpNlykt
V8Q2jzNmPYVXuUpi4oPekq4Mg1vd/LPS/JE558Am1LEiXrycelGNrDvJW7hTDLVx
DLRFuMMxAoGBAMkjupL3mxAfNytXM++WxJbdWPuw/vvAeN60ifFu6RUrMs/aXocn
4xSunNF58O2aRfSq/B9LJ+pXtmdITV+Bu0Y1XefKtNUNoqIapAbA8gAWUcFSkDRd
999rh0vWPbx4d3k69iS6xIjVaRcxeuaBbKRWqUcrxDuAydhwTLIRMD1vAoGBAPH4
quLGkr1MdTeZ3qPAWc9mGelp0LhHukjnLB+nMdI73OH7IlX5or11yr6La/+sTmmQ
fI+oITLuCyey7VnWBDhrPmWFGA1BmZIVDqjkJJNwyWQO7N27rQEQoNKm5n6Q+boy
StNKa/ljduYXCjsBndOmF1wSrAwL+u9rQ3x4k9vNAoGAGY5vm1LYofDFar1WvP90
FRMkxj4T99rZwLpBuKp19RmbCCvfzN51jOAuzrLmuNncP50mEbfT54OjinX2Vsc+
C0qmltf7qAJmgqBN7QnA9d/gHWcnKXAzGXEpLKqZB4Rq8b1bHwmYBSbQhoDj87vI
GQ1lzsQx17mia9zA8fMbJQMCgYB0D+2PpuW9rM3QpJp4+wtZAsVNAzddHPKKg2/T
ovOvvoz9S+M1T+8yZyyfZuqfkTtvQSGuGlwKPMnW+ekFHTWbBj3Ani1iNmP+AOGu
OvgcTI4c01fkJ2AdUaeCQxHuBYXzPKpNXLYbwgzG4qhCk0zrtxAfVsl1Yc20R0Pw
kTmCxQKBgQCzd/OOLm7vDEUqYNUNgKlf8I9xM84IwUy+pJP8RaeFDtFj7tVDpY2P
GXHBXcIBDRPnmBxC7cGHCB3KBWJp11smw2qA0ZgmBIShNm1RDHf/1h0yOxSz2+fB
bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
-----END RSA PRIVATE KEY-----
`),
},
}
}),
Entry("chain of CAs", func() testCase {
return testCase{
expectedErr: `
violations:
- field: cert
message: "certificate must be a root CA (certificate chains are not allowed)"
`,
input: util_tls.KeyPair{
CertPEM: []byte(`
-----BEGIN CERTIFICATE-----
MIIDKzCCAhOgAwIBAgIBADANBgkqhkiG9w0BAQsFADAwMQ0wCwYDVQQKEwRLdW1h
MQ0wCwYDVQQLEwRNZXNoMRAwDgYDVQQDEwdkZWZhdWx0MB4XDTIwMDEyOTE2MDgw
NFoXDTMwMDEyNjE2MDgxNFowQDENMAsGA1UEChMES3VtYTEdMAsGA1UECxMETWVz
aDAOBgNVBAsTB2xldmVsLTExEDAOBgNVBAMTB2RlZmF1bHQwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC+HgOFAO4T+heMQnO3VOaCYzqzkO2whggQ+yzF
0OIMSOYnOEYA93QGYB+vPf99dnoKqqp8C9MqRMMaNI3SEa23W2EXvbB41+ZBf1zW
BS6QQDSARFI6xJaXOnwDNzl+Ne2XmOJCS9pqk2hDw+WMtzxISyCd293EPW0NVY3q
H3RsyC26rIozsWf/X6fCFETEpFM5KVHSJL1511Y9w3cc0auXe+MIXShQX/v36ckm
p5pdrC3T7Y8IyTFjpPrLMVpL+HQ7LeZcs5DUfmfdxnYxIQwpBKz19/yDN4elbJem
AHVcQo1xS+KtUp9on9YTm/SuJ4bz0H9idBN25CevCY9W7CbjAgMBAAGjQDA+MA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MBsGA1UdEQQUMBKGEHNwaWZm
ZTovL2RlZmF1bHQwDQYJKoZIhvcNAQELBQADggEBACVXnYWCCrji551pbJsOCGYJ
GEqlvcwNnnYdykas4GrfsbW2rglmaXv0uG8iH2sAH+4/MjGjnlQ6Y6Fj7mDFnidj
ugU964sEDnLuU0CtaIpHl7VZ13I0EzmfY+GsCrcIXIxbAxwWTJhz77XqbHe3baLx
Sh9wHgz/aZuy99rq9OoAvUALEaIfxrvUsVs25jLuv0Xzy57B2Dpqo0odshDA4WSS
MynQnSX7aFg1jqZQL4YjPHryEQQRj8mgjqiWp8M4/PHq5s09zDMB0DCag0QtdC/k
ydtqRoojiRS2fXY8DhFRqqRVBqLvA+7eTEKpzfjUTyEovMqxIM2n4U5MSGKQlbM=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDGzCCAgOgAwIBAgIBADANBgkqhkiG9w0BAQsFADAwMQ0wCwYDVQQKEwRLdW1h
MQ0wCwYDVQQLEwRNZXNoMRAwDgYDVQQDEwdkZWZhdWx0MB4XDTIwMDEyOTE2MDgw
NFoXDTMwMDEyNjE2MDgxNFowMDENMAsGA1UEChMES3VtYTENMAsGA1UECxMETWVz
aDEQMA4GA1UEAxMHZGVmYXVsdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBANhewNnHZI0f+55vsm+iGej9NAYFtCb2FNzFHZlGcu0F07YSAyorPJuM+6V3
BFcY2IkWHL8WOooNmJ0X/yzBd4RSrb3TacGKtaDayRjTo8JOW7Nlh+WvwR18KHjC
QXDjlqkmfExdYIUZjOqJOhu9nO59fqz0SJFvo2WKkkP7CaTLQXt1p3+Hm1Xo5WCX
ZfD7W57YhNBZZLljip/N8pDL7b2Vkhe+txbv/PqVrDRMGoyRBnPNAfS7SPocRbcE
S9th2CesNu+Iwltu4gJBOQbpydBIjJvr1zrx/zxbxM+EbqbGr6gwquGvKTyXHq20
u5CE4tWy3GKSh5LEVItPS066d5UCAwEAAaNAMD4wDgYDVR0PAQH/BAQDAgEGMA8G
A1UdEwEB/wQFMAMBAf8wGwYDVR0RBBQwEoYQc3BpZmZlOi8vZGVmYXVsdDANBgkq
hkiG9w0BAQsFAAOCAQEAMvMqCzbjEveuMlTch9q+/6KcFVUkwQcTcxxs0MPnw5Lw
hY6xo7FvIHNLJDRlShoAyjI6OJZobJ7PFaFnIXWlNcN1F+gA9OZSSWYgJNJl4zee
eS2pHgbxZ6OJqCbDGYWekF3d1vEcI3gaRfxFDVa8eJFBq+B0v2Pho8A2bY5srO0S
LG//nB619RAlzta6BxweiCmFxPyB+oqJl3X9NfWC7988CzfZAqHA+CqO6tJS5i53
WMciH6+W7o9wdsBrfFVx2tGZqc4bZgoZptHFieqz7YBnT0Ozg+NwBU6apAtAc5Ym
DMoTRP2Vo+BEm4uS4GcIFZYqrOsPuuyMuBd0NDE33g==
-----END CERTIFICATE-----
`),
KeyPEM: []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvh4DhQDuE/oXjEJzt1TmgmM6s5DtsIYIEPssxdDiDEjmJzhG
APd0BmAfrz3/fXZ6CqqqfAvTKkTDGjSN0hGtt1thF72weNfmQX9c1gUukEA0gERS
OsSWlzp8Azc5fjXtl5jiQkvaapNoQ8PljLc8SEsgndvdxD1tDVWN6h90bMgtuqyK
M7Fn/1+nwhRExKRTOSlR0iS9eddWPcN3HNGrl3vjCF0oUF/79+nJJqeaXawt0+2P
CMkxY6T6yzFaS/h0Oy3mXLOQ1H5n3cZ2MSEMKQSs9ff8gzeHpWyXpgB1XEKNcUvi
rVKfaJ/WE5v0rieG89B/YnQTduQnrwmPVuwm4wIDAQABAoIBAQCxKKrC7+DqwKvc
ybem6Ph8HBeBaNX1HpC5sjVAiKt8IxpFBc1F7VEy97POywkfUp3a/rorKaG2y6i6
7KoTTOIB8KcDRoIBub4Y3qQV03JWfV3vALtXhAWIGrmhDX8Hux0RnSeJ+8EmewI3
034+qCkGfOuB7nYy/cJ3IHhD6NfG3Q3FrBrGfsI2TGEeGmPJ2Xi8ZyfbluRb/1Bt
NesS6pDbRpZ5/IoauLUtITY3bazpzghm2tJNdrJIP7ohaoMF0WYciPyD5xpNlykt
V8Q2jzNmPYVXuUpi4oPekq4Mg1vd/LPS/JE558Am1LEiXrycelGNrDvJW7hTDLVx
DLRFuMMxAoGBAMkjupL3mxAfNytXM++WxJbdWPuw/vvAeN60ifFu6RUrMs/aXocn
4xSunNF58O2aRfSq/B9LJ+pXtmdITV+Bu0Y1XefKtNUNoqIapAbA8gAWUcFSkDRd
999rh0vWPbx4d3k69iS6xIjVaRcxeuaBbKRWqUcrxDuAydhwTLIRMD1vAoGBAPH4
quLGkr1MdTeZ3qPAWc9mGelp0LhHukjnLB+nMdI73OH7IlX5or11yr6La/+sTmmQ
fI+oITLuCyey7VnWBDhrPmWFGA1BmZIVDqjkJJNwyWQO7N27rQEQoNKm5n6Q+boy
StNKa/ljduYXCjsBndOmF1wSrAwL+u9rQ3x4k9vNAoGAGY5vm1LYofDFar1WvP90
FRMkxj4T99rZwLpBuKp19RmbCCvfzN51jOAuzrLmuNncP50mEbfT54OjinX2Vsc+
C0qmltf7qAJmgqBN7QnA9d/gHWcnKXAzGXEpLKqZB4Rq8b1bHwmYBSbQhoDj87vI
GQ1lzsQx17mia9zA8fMbJQMCgYB0D+2PpuW9rM3QpJp4+wtZAsVNAzddHPKKg2/T
ovOvvoz9S+M1T+8yZyyfZuqfkTtvQSGuGlwKPMnW+ekFHTWbBj3Ani1iNmP+AOGu
OvgcTI4c01fkJ2AdUaeCQxHuBYXzPKpNXLYbwgzG4qhCk0zrtxAfVsl1Yc20R0Pw
kTmCxQKBgQCzd/OOLm7vDEUqYNUNgKlf8I9xM84IwUy+pJP8RaeFDtFj7tVDpY2P
GXHBXcIBDRPnmBxC7cGHCB3KBWJp11smw2qA0ZgmBIShNm1RDHf/1h0yOxSz2+fB
bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
-----END RSA PRIVATE KEY-----
`),
},
}
}),
Entry("not a self-signed certificate", func() testCase {
return testCase{
expectedErr: `
violations:
- field: cert
message: "certificate must be self-signed (intermediate CAs are not allowed)"
`,
input: util_tls.KeyPair{
CertPEM: []byte(`
-----BEGIN CERTIFICATE-----
MIIDKzCCAhOgAwIBAgIBADANBgkqhkiG9w0BAQsFADAwMQ0wCwYDVQQKEwRLdW1h
MQ0wCwYDVQQLEwRNZXNoMRAwDgYDVQQDEwdkZWZhdWx0MB4XDTIwMDEyOTE2MDgw
NFoXDTMwMDEyNjE2MDgxNFowQDENMAsGA1UEChMES3VtYTEdMAsGA1UECxMETWVz
aDAOBgNVBAsTB2xldmVsLTExEDAOBgNVBAMTB2RlZmF1bHQwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC+HgOFAO4T+heMQnO3VOaCYzqzkO2whggQ+yzF
0OIMSOYnOEYA93QGYB+vPf99dnoKqqp8C9MqRMMaNI3SEa23W2EXvbB41+ZBf1zW
BS6QQDSARFI6xJaXOnwDNzl+Ne2XmOJCS9pqk2hDw+WMtzxISyCd293EPW0NVY3q
H3RsyC26rIozsWf/X6fCFETEpFM5KVHSJL1511Y9w3cc0auXe+MIXShQX/v36ckm
p5pdrC3T7Y8IyTFjpPrLMVpL+HQ7LeZcs5DUfmfdxnYxIQwpBKz19/yDN4elbJem
AHVcQo1xS+KtUp9on9YTm/SuJ4bz0H9idBN25CevCY9W7CbjAgMBAAGjQDA+MA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MBsGA1UdEQQUMBKGEHNwaWZm
ZTovL2RlZmF1bHQwDQYJKoZIhvcNAQELBQADggEBACVXnYWCCrji551pbJsOCGYJ
GEqlvcwNnnYdykas4GrfsbW2rglmaXv0uG8iH2sAH+4/MjGjnlQ6Y6Fj7mDFnidj
ugU964sEDnLuU0CtaIpHl7VZ13I0EzmfY+GsCrcIXIxbAxwWTJhz77XqbHe3baLx
Sh9wHgz/aZuy99rq9OoAvUALEaIfxrvUsVs25jLuv0Xzy57B2Dpqo0odshDA4WSS
MynQnSX7aFg1jqZQL4YjPHryEQQRj8mgjqiWp8M4/PHq5s09zDMB0DCag0QtdC/k
ydtqRoojiRS2fXY8DhFRqqRVBqLvA+7eTEKpzfjUTyEovMqxIM2n4U5MSGKQlbM=
-----END CERTIFICATE-----

`),
KeyPEM: []byte(`
-----BEGIN RSA PRIVATE KEY-----
Expand Down Expand Up @@ -314,9 +172,9 @@ bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
return testCase{
expectedErr: `
violations:
- field: cert
- field: cert[0]
message: "basic constraint 'CA' must be set to 'true' (see X509-SVID: 4.1. Basic Constraints)"
- field: cert
- field: cert[0]
message: "key usage extension 'keyCertSign' must be set (see X509-SVID: 4.3. Key Usage)"
`,
input: *keyPair,
Expand All @@ -337,7 +195,7 @@ bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
return testCase{
expectedErr: `
violations:
- field: cert
- field: cert[0]
message: "key usage extension 'keyCertSign' must be set (see X509-SVID: 4.3. Key Usage)"
`,
input: *keyPair,
Expand All @@ -360,7 +218,7 @@ bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
return testCase{
expectedErr: `
violations:
- field: cert
- field: cert[0]
message: "key usage extension 'digitalSignature' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)"
`,
input: *keyPair,
Expand All @@ -383,7 +241,7 @@ bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
return testCase{
expectedErr: `
violations:
- field: cert
- field: cert[0]
message: "key usage extension 'keyAgreement' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)"
`,
input: *keyPair,
Expand All @@ -406,7 +264,7 @@ bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
return testCase{
expectedErr: `
violations:
- field: cert
- field: cert[0]
message: "key usage extension 'keyEncipherment' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)"
`,
input: *keyPair,
Expand All @@ -428,15 +286,15 @@ bgeEDefxTxoTMgJ1urwl0KX6R9dbv9YWZWJXk2DQj6UwkMEyXpc+kw==
return testCase{
expectedErr: `
violations:
- field: cert
- field: cert[0]
message: "basic constraint 'CA' must be set to 'true' (see X509-SVID: 4.1. Basic Constraints)"
- field: cert
- field: cert[0]
message: "key usage extension 'keyCertSign' must be set (see X509-SVID: 4.3. Key Usage)"
- field: cert
- field: cert[0]
message: "key usage extension 'digitalSignature' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)"
- field: cert
- field: cert[0]
message: "key usage extension 'keyAgreement' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)"
- field: cert
- field: cert[0]
message: "key usage extension 'keyEncipherment' must NOT be set (see X509-SVID: Appendix A. X.509 Field Reference)"
`,
input: *keyPair,
Expand Down
16 changes: 16 additions & 0 deletions test/e2e/mtls/universal/e2e_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package universal_test

import (
"testing"

"github.com/kumahq/kuma/pkg/test"
"github.com/kumahq/kuma/test/framework"
)

func TestE2EMTLSUniversal(t *testing.T) {
if framework.IsK8sClustersStarted() {
test.RunSpecs(t, "mTLS Universal Suite")
} else {
t.SkipNow()
}
}
Loading