Eventing TLS: validate that Destination.CACerts is a PEM encoded cert (#2743)

* added check to cacerts

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* added test

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* added csr test

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* OR to AND

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

---------

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>
This commit is contained in:
Vishal Choudhary 2023-05-18 20:13:13 +05:30 committed by GitHub
parent dfb4bf0463
commit a170a07b34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 189 additions and 0 deletions

View File

@ -18,6 +18,8 @@ package v1
import (
"context"
"crypto/x509"
"encoding/pem"
"knative.dev/pkg/apis"
)
@ -53,6 +55,7 @@ func (d *Destination) Validate(ctx context.Context) *apis.FieldError {
func ValidateDestination(ctx context.Context, dest Destination) *apis.FieldError {
ref := dest.Ref
uri := dest.URI
caCerts := dest.CACerts
if ref == nil && uri == nil {
return apis.ErrGeneric("expected at least one, got none", "ref", "uri")
}
@ -67,6 +70,9 @@ func ValidateDestination(ctx context.Context, dest Destination) *apis.FieldError
if ref != nil && uri == nil {
return ref.Validate(ctx).ViaField("ref")
}
if caCerts != nil {
return validateCACerts(caCerts)
}
return nil
}
@ -88,3 +94,20 @@ func (d *Destination) SetDefaults(ctx context.Context) {
d.Ref.Namespace = apis.ParentMeta(ctx).Namespace
}
}
func validateCACerts(CACert *string) *apis.FieldError {
// Check the object.
var errs *apis.FieldError
block, err := pem.Decode([]byte(*CACert))
if err != nil && block == nil {
errs = errs.Also(apis.ErrInvalidValue("CA Cert provided is invalid", "caCert"))
return errs
}
if block.Type != "CERTIFICATE" {
errs = errs.Also(apis.ErrInvalidValue("CA Cert provided is not a certificate", "caCert"))
} else if _, err := x509.ParseCertificate(block.Bytes); err != nil {
errs = errs.Also(apis.ErrInvalidValue("CA Cert provided is invalid", "caCert"))
}
return errs
}

View File

@ -32,6 +32,51 @@ const (
namespace = "b-namespace"
)
var (
testCert = `-----BEGIN CERTIFICATE-----
MIIDmjCCAoKgAwIBAgIUYzA4bTMXevuk3pl2Mn8hpCYL2C0wDQYJKoZIhvcNAQEL
BQAwLzELMAkGA1UEBhMCVVMxIDAeBgNVBAMMF0tuYXRpdmUtRXhhbXBsZS1Sb290
LUNBMB4XDTIzMDQwNTEzMTUyNFoXDTI2MDEyMzEzMTUyNFowbTELMAkGA1UEBhMC
VVMxEjAQBgNVBAgMCVlvdXJTdGF0ZTERMA8GA1UEBwwIWW91ckNpdHkxHTAbBgNV
BAoMFEV4YW1wbGUtQ2VydGlmaWNhdGVzMRgwFgYDVQQDDA9sb2NhbGhvc3QubG9j
YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5teo+En6U5nhqn7Sc
uanqswUmPlgs9j/8l21Rhb4T+ezlYKGQGhbJyFFMuiCE1Rjn8bpCwi7Nnv12Y2nz
FhEv2Jx0yL3Tqx0Q593myqKDq7326EtbO7wmDT0XD03twH5i9XZ0L0ihPWn1mjUy
WxhnHhoFpXrsnQECJorZY6aTrFbGVYelIaj5AriwiqyL0fET8pueI2GwLjgWHFSH
X8XsGAlcLUhkQG0Z+VO9usy4M1Wpt+cL6cnTiQ+sRmZ6uvaj8fKOT1Slk/oUeAi4
WqFkChGzGzLik0QrhKGTdw3uUvI1F2sdQj0GYzXaWqRz+tP9qnXdzk1GrszKKSlm
WBTLAgMBAAGjcDBuMB8GA1UdIwQYMBaAFJJcCftus4vj98N0zQQautsjEu82MAkG
A1UdEwQCMAAwCwYDVR0PBAQDAgTwMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNV
HQ4EFgQUnu/3vqA3VEzm128x/hLyZzR9JlgwDQYJKoZIhvcNAQELBQADggEBAFc+
1cKt/CNjHXUsirgEhry2Mm96R6Yxuq//mP2+SEjdab+FaXPZkjHx118u3PPX5uTh
gTT7rMfka6J5xzzQNqJbRMgNpdEFH1bbc11aYuhi0khOAe0cpQDtktyuDJQMMv3/
3wu6rLr6fmENo0gdcyUY9EiYrglWGtdXhlo4ySRY8UZkUScG2upvyOhHTxVCAjhP
efbMkNjmDuZOMK+wqanqr5YV6zMPzkQK7DspfRgasMAQmugQu7r2MZpXg8Ilhro1
s/wImGnMVk5RzpBVrq2VB9SkX/ThTVYEC/Sd9BQM364MCR+TA1l8/ptaLFLuwyw8
O2dgzikq8iSy1BlRsVw=
-----END CERTIFICATE-----`
csr = `-----BEGIN CERTIFICATE REQUEST-----
MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV
BAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGln
aUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmo
wp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c
1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiI
WDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZ
wIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPR
BPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJ
KoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6D
hJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpY
Q4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/
ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn
29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO2
97Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=
-----END CERTIFICATE REQUEST-----`
invaidCert = "certificate"
)
func TestValidateDestination(t *testing.T) {
ctx := context.Background()
@ -117,6 +162,32 @@ func TestValidateDestination(t *testing.T) {
},
Ref: &validRef,
},
}, "valid, CACert is valid": {
dest: &Destination{
URI: &apis.URL{
Path: "/handler",
},
Ref: &validRef,
CACerts: &testCert,
},
}, "invalid,CACert is invalid": {
dest: &Destination{
URI: &apis.URL{
Path: "/handler",
},
Ref: &validRef,
CACerts: &invaidCert,
},
want: "invalid value: CA Cert provided is invalid: caCert",
}, "invalid,CSR provided not CA Cert": {
dest: &Destination{
URI: &apis.URL{
Path: "/handler",
},
Ref: &validRef,
CACerts: &csr,
},
want: "invalid value: CA Cert provided is not a certificate: caCert",
}}
for name, tc := range tests {

View File

@ -18,6 +18,8 @@ package v1beta1
import (
"context"
"crypto/x509"
"encoding/pem"
corev1 "k8s.io/api/core/v1"
"knative.dev/pkg/apis"
@ -117,6 +119,9 @@ func ValidateDestination(dest Destination, allowDeprecatedFields bool) *apis.Fie
}
return validateDestinationRef(*ref)
}
if dest.CACerts != nil {
return validateCACerts(dest.CACerts)
}
return nil
}
@ -162,3 +167,19 @@ func validateDestinationRef(ref corev1.ObjectReference) *apis.FieldError {
return errs
}
func validateCACerts(CACert *string) *apis.FieldError {
// Check the object.
var errs *apis.FieldError
block, err := pem.Decode([]byte(*CACert))
if err != nil && block == nil {
errs = errs.Also(apis.ErrInvalidValue("CA Cert provided is invalid", "caCert"))
return errs
}
if block.Type != "CERTIFICATE" {
errs = errs.Also(apis.ErrInvalidValue("CA Cert provided is not a certificate", "caCert"))
} else if _, err := x509.ParseCertificate(block.Bytes); err != nil {
errs = errs.Also(apis.ErrInvalidValue("CA Cert provided is invalid", "caCert"))
}
return errs
}

View File

@ -31,6 +31,51 @@ const (
name = "a-name"
)
var (
testCert = `-----BEGIN CERTIFICATE-----
MIIDmjCCAoKgAwIBAgIUYzA4bTMXevuk3pl2Mn8hpCYL2C0wDQYJKoZIhvcNAQEL
BQAwLzELMAkGA1UEBhMCVVMxIDAeBgNVBAMMF0tuYXRpdmUtRXhhbXBsZS1Sb290
LUNBMB4XDTIzMDQwNTEzMTUyNFoXDTI2MDEyMzEzMTUyNFowbTELMAkGA1UEBhMC
VVMxEjAQBgNVBAgMCVlvdXJTdGF0ZTERMA8GA1UEBwwIWW91ckNpdHkxHTAbBgNV
BAoMFEV4YW1wbGUtQ2VydGlmaWNhdGVzMRgwFgYDVQQDDA9sb2NhbGhvc3QubG9j
YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5teo+En6U5nhqn7Sc
uanqswUmPlgs9j/8l21Rhb4T+ezlYKGQGhbJyFFMuiCE1Rjn8bpCwi7Nnv12Y2nz
FhEv2Jx0yL3Tqx0Q593myqKDq7326EtbO7wmDT0XD03twH5i9XZ0L0ihPWn1mjUy
WxhnHhoFpXrsnQECJorZY6aTrFbGVYelIaj5AriwiqyL0fET8pueI2GwLjgWHFSH
X8XsGAlcLUhkQG0Z+VO9usy4M1Wpt+cL6cnTiQ+sRmZ6uvaj8fKOT1Slk/oUeAi4
WqFkChGzGzLik0QrhKGTdw3uUvI1F2sdQj0GYzXaWqRz+tP9qnXdzk1GrszKKSlm
WBTLAgMBAAGjcDBuMB8GA1UdIwQYMBaAFJJcCftus4vj98N0zQQautsjEu82MAkG
A1UdEwQCMAAwCwYDVR0PBAQDAgTwMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNV
HQ4EFgQUnu/3vqA3VEzm128x/hLyZzR9JlgwDQYJKoZIhvcNAQELBQADggEBAFc+
1cKt/CNjHXUsirgEhry2Mm96R6Yxuq//mP2+SEjdab+FaXPZkjHx118u3PPX5uTh
gTT7rMfka6J5xzzQNqJbRMgNpdEFH1bbc11aYuhi0khOAe0cpQDtktyuDJQMMv3/
3wu6rLr6fmENo0gdcyUY9EiYrglWGtdXhlo4ySRY8UZkUScG2upvyOhHTxVCAjhP
efbMkNjmDuZOMK+wqanqr5YV6zMPzkQK7DspfRgasMAQmugQu7r2MZpXg8Ilhro1
s/wImGnMVk5RzpBVrq2VB9SkX/ThTVYEC/Sd9BQM364MCR+TA1l8/ptaLFLuwyw8
O2dgzikq8iSy1BlRsVw=
-----END CERTIFICATE-----`
csr = `-----BEGIN CERTIFICATE REQUEST-----
MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV
BAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGln
aUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmo
wp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c
1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiI
WDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZ
wIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPR
BPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJ
KoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6D
hJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpY
Q4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/
ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn
29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO2
97Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=
-----END CERTIFICATE REQUEST-----`
invaidCert = "certificate"
)
func TestValidateDestination(t *testing.T) {
ctx := context.Background()
@ -187,6 +232,35 @@ func TestValidateDestination(t *testing.T) {
DeprecatedName: name,
},
},
"valid, CACert is valid": {
dest: &Destination{
URI: &apis.URL{
Path: "/handler",
},
Ref: &validRef,
CACerts: &testCert,
},
},
"invalid,CACert is invalid": {
dest: &Destination{
URI: &apis.URL{
Path: "/handler",
},
Ref: &validRef,
CACerts: &invaidCert,
},
want: "invalid value: CA Cert provided is invalid: caCert",
},
"invalid,CSR provided not CA Cert": {
dest: &Destination{
URI: &apis.URL{
Path: "/handler",
},
Ref: &validRef,
CACerts: &csr,
},
want: "invalid value: CA Cert provided is not a certificate: caCert",
},
}
for name, tc := range tests {