Skip to content

Commit

Permalink
internal/dag: validate each pem block
Browse files Browse the repository at this point in the history
During certificate validation, walk the PEM and validate each
appropriate block.

closes #1702

Signed-off-by: Matt Alberts <[email protected]>
  • Loading branch information
Matt Alberts authored and davecheney committed Oct 18, 2019
1 parent bc7fbe3 commit cba7fe0
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 26 deletions.
24 changes: 24 additions & 0 deletions internal/dag/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,30 @@ func TestKubernetesCacheInsert(t *testing.T) {
},
want: true,
},
"insert secret referenced by ingress with multiple pem blocks": {
pre: []interface{}{
&v1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "www",
Namespace: "default",
},
Spec: v1beta1.IngressSpec{
TLS: []v1beta1.IngressTLS{{
SecretName: "secret",
}},
},
},
},
obj: &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "default",
},
Type: v1.SecretTypeTLS,
Data: secretdata(EC_CERTIFICATE, EC_PRIVATE_KEY),
},
want: true,
},
"insert secret w/ wrong type referenced by ingress": {
pre: []interface{}{
&v1beta1.Ingress{
Expand Down
76 changes: 52 additions & 24 deletions internal/dag/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,35 +50,63 @@ func isValidSecret(secret *v1.Secret) (bool, error) {
}

func validateCertificate(data []byte) error {
cert, err := decodePEM(data)
if err != nil {
return err
var exists bool
for len(data) > 0 {
var block *pem.Block
block, data = pem.Decode(data)
if block == nil {
return errors.New("failed to parse PEM block")
}
if block.Type != "CERTIFICATE" {
return errors.New("unexpected block type in certificate: " + block.Type)
}
if _, err := x509.ParseCertificate(block.Bytes); err != nil {
return err
}
exists = true
}
_, err = x509.ParseCertificate(cert.Bytes)
return err
if !exists {
return errors.New("failed to locate certificate")
}
return nil
}

func validatePrivateKey(data []byte) error {
key, err := decodePEM(data)
if err != nil {
return nil
}
if _, err := x509.ParsePKCS1PrivateKey(key.Bytes); err == nil {
return nil
}
if _, err := x509.ParsePKCS8PrivateKey(key.Bytes); err == nil {
return nil
var keys int
for len(data) > 0 {
var block *pem.Block
block, data = pem.Decode(data)
if block == nil {
return errors.New("failed to parse PEM block")
}
switch block.Type {
case "PRIVATE KEY":
if _, err := x509.ParsePKCS8PrivateKey(block.Bytes); err == nil {
return err
}
keys++
case "RSA PRIVATE KEY":
if _, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {
return err
}
keys++
case "EC PRIVATE KEY":
if _, err := x509.ParseECPrivateKey(block.Bytes); err != nil {
return err
}
keys++
case "EC PARAMETERS":
// ignored
default:
return errors.New("unexpected block type in private key: " + block.Type)
}
}
if _, err := x509.ParseECPrivateKey(key.Bytes); err == nil {
switch keys {
case 0:
return errors.New("failed to locate private key")
case 1:
return nil
default:
return errors.New("multiple private keys")
}
return errors.New("unknown private key encoding")
}

func decodePEM(in []byte) (*pem.Block, error) {
block, _ := pem.Decode(in)
if block == nil {
return nil, errors.New("failed to parse PEM")
}
return block, nil
}
27 changes: 25 additions & 2 deletions internal/dag/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ package dag

import v1 "k8s.io/api/core/v1"

// sample data from https://8gwifi.org/PemParserFunctions.jsp

const (
// sample data from https://8gwifi.org/PemParserFunctions.jsp
CERTIFICATE = `-----BEGIN CERTIFICATE-----
MIIFtTCCA52gAwIBAgIJAO0cq2lJPZZJMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
Expand Down Expand Up @@ -103,6 +102,30 @@ KMkcE4BT8IZIHQ+wIMhmYLAdSQCVVv8x78jN0sZCC0fjqVuyPdYQ8sIc3OHsJZcW
lzewFW72lfsiB/RxWZ/XwXONXeW5Quf+XwbGGboTofyzTxzsYSwn1U9Kt8iaY8zr
z7Z5SQCSf2Js9V9lJcodYswWlxrdtoRKA/WgrvQkZhGGAePTUVoO5Lab29M8
-----END RSA PRIVATE KEY-----`

// sample elliptical curve data generated
// openssl ecparam -name prime256v1 -genkey -out ec_key.pem
// openssl req -new -x509 -key ec_key.pem -out ec_crt.pem -days 3650
EC_CERTIFICATE = `-----BEGIN CERTIFICATE-----
MIIBbjCCARQCCQCPA0hmRaqduTAKBggqhkjOPQQDAjA/MQswCQYDVQQGEwJVUzEL
MAkGA1UECAwCQ0ExEjAQBgNVBAcMCVBhbG8gQWx0bzEPMA0GA1UECgwGVk1XYXJl
MB4XDTE5MTAxNTAzMzkzM1oXDTI5MTAxMjAzMzkzM1owPzELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlQYWxvIEFsdG8xDzANBgNVBAoMBlZNV2Fy
ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFUOHv4hnLcopcYdjojx2j/FmFX6
MOLVVNsNpZ4SpmcGKN2zGp0SyAQgNhY0gGojC0g+VVYrh8X3GQAXYdvIjfMwCgYI
KoZIzj0EAwIDSAAwRQIhAJudFacSiwcRtyQ2aNYAPbDJnnwbUTXRCVRlgLysgP5G
AiALPSbO8d0wa24Z0AU2oXocuNkDaH8qEyp2yhL5LKI3Dw==
-----END CERTIFICATE-----
`
EC_PRIVATE_KEY = `-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOlYOKzXGQTYlKDkuM62/U84DjxEOa8T3XGYlVmycFJroAoGCCqGSM49
AwEHoUQDQgAEVQ4e/iGctyilxh2OiPHaP8WYVfow4tVU2w2lnhKmZwYo3bManRLI
BCA2FjSAaiMLSD5VViuHxfcZABdh28iN8w==
-----END EC PRIVATE KEY-----
`
)

func secretdata(cert, key string) map[string][]byte {
Expand Down

0 comments on commit cba7fe0

Please sign in to comment.