kubeadm: add validation to verify that the CertificateKey is a valid hex encoded AES key

This commit is contained in:
SataQiu 2023-08-19 11:33:29 +08:00
parent db64cc4a55
commit 75a80d5aba
2 changed files with 58 additions and 2 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package validation
import (
"encoding/hex"
"fmt"
"net"
"net/url"
@ -54,7 +55,7 @@ func ValidateInitConfiguration(c *kubeadm.InitConfiguration) field.ErrorList {
allErrs = append(allErrs, ValidateClusterConfiguration(&c.ClusterConfiguration)...)
// TODO(Arvinderpal): update advertiseAddress validation for dual-stack once it's implemented.
allErrs = append(allErrs, ValidateAPIEndpoint(&c.LocalAPIEndpoint, field.NewPath("localAPIEndpoint"))...)
// TODO: Maybe validate that .CertificateKey is a valid hex encoded AES key
allErrs = append(allErrs, ValidateCertificateKey(c.CertificateKey, field.NewPath("certificateKey"))...)
return allErrs
}
@ -98,7 +99,7 @@ func ValidateJoinControlPlane(c *kubeadm.JoinControlPlane, fldPath *field.Path)
allErrs := field.ErrorList{}
if c != nil {
allErrs = append(allErrs, ValidateAPIEndpoint(&c.LocalAPIEndpoint, fldPath.Child("localAPIEndpoint"))...)
// TODO: Maybe validate that .CertificateKey is a valid hex encoded AES key
allErrs = append(allErrs, ValidateCertificateKey(c.CertificateKey, field.NewPath("certificateKey"))...)
}
return allErrs
}
@ -594,6 +595,25 @@ func ValidateAPIEndpoint(c *kubeadm.APIEndpoint, fldPath *field.Path) field.Erro
return allErrs
}
// ValidateCertificateKey validates the certificate key is a valid hex encoded AES key
func ValidateCertificateKey(certificateKey string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(certificateKey) > 0 {
decodedKey, err := hex.DecodeString(certificateKey)
if err != nil {
return append(allErrs, field.Invalid(fldPath, certificateKey, fmt.Sprintf("certificate key decoding error: %v", err)))
}
k := len(decodedKey)
if k != constants.CertificateKeySize {
allErrs = append(allErrs, field.Invalid(fldPath, certificateKey, fmt.Sprintf("invalid certificate key size %d, the key must be an AES key of size %d", k, constants.CertificateKeySize)))
}
}
return allErrs
}
// ValidateIgnorePreflightErrors validates duplicates in:
// - ignore-preflight-errors flag and
// - ignorePreflightErrors field in {Init,Join}Configuration files.

View File

@ -455,6 +455,42 @@ func TestValidateAPIEndpoint(t *testing.T) {
}
}
func TestValidateCertificateKey(t *testing.T) {
var tests = []struct {
name string
certificateKey string
expected bool
}{
{
name: "Valid certificate key",
certificateKey: "e6a2eb8581237ab72a4f494f30285ec12a9694d750b9785706a83bfcbbbd2204",
expected: true,
},
{
name: "Invalid hex encoded string",
certificateKey: "z6a2eb8581237ab72a4f494f30285ec12a9694d750b9785706a83bfcbbbd2204",
expected: false,
},
{
name: "Invalid AES key size",
certificateKey: "e6a2",
expected: false,
},
}
for _, rt := range tests {
actual := ValidateCertificateKey(rt.certificateKey, nil)
t.Log(actual)
if (len(actual) == 0) != rt.expected {
t.Errorf(
"%s test case failed:\n\texpected: %t\n\t actual: %t",
rt.name,
rt.expected,
(len(actual) == 0),
)
}
}
}
// TODO: Create a separated test for ValidateClusterConfiguration
func TestValidateInitConfiguration(t *testing.T) {
nodename := "valid-nodename"