diff --git a/cmd/kubeadm/app/util/pkiutil/pki_helpers.go b/cmd/kubeadm/app/util/pkiutil/pki_helpers.go index d733a6c6bcc..cb5f8dc2d0f 100644 --- a/cmd/kubeadm/app/util/pkiutil/pki_helpers.go +++ b/cmd/kubeadm/app/util/pkiutil/pki_helpers.go @@ -340,11 +340,20 @@ func TryLoadPrivatePublicKeyFromDisk(pkiPath, name string) (crypto.PrivateKey, c } // Allow RSA and ECDSA formats only + mismatchErrFmt := "the private key file %[2]s is in %[1]s format but the public key file %[3]s is not in %[1]s format" switch k := privKey.(type) { case *rsa.PrivateKey: - return k, pubKeys[0].(*rsa.PublicKey), nil + pubKey, ok := pubKeys[0].(*rsa.PublicKey) + if !ok { + return nil, nil, errors.Errorf(mismatchErrFmt, "RSA", privateKeyPath, publicKeyPath) + } + return k, pubKey, nil case *ecdsa.PrivateKey: - return k, pubKeys[0].(*ecdsa.PublicKey), nil + pubKey, ok := pubKeys[0].(*ecdsa.PublicKey) + if !ok { + return nil, nil, errors.Errorf(mismatchErrFmt, "ECDSA", privateKeyPath, publicKeyPath) + } + return k, pubKey, nil default: return nil, nil, errors.Errorf("the private key file %s is neither in RSA nor ECDSA format", privateKeyPath) } diff --git a/cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go b/cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go index 9ec4b3efbb7..5b75c91c33c 100644 --- a/cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go +++ b/cmd/kubeadm/app/util/pkiutil/pki_helpers_test.go @@ -566,6 +566,77 @@ func TestTryLoadKeyFromDisk(t *testing.T) { } } +func TestTryLoadPrivatePublicKeyFromDisk(t *testing.T) { + tests := []struct { + desc string + privateKey crypto.Signer + publicKey crypto.PublicKey + writePub bool + wantErr bool + }{ + { + desc: "RSA private key and RSA public key", + privateKey: rootCAKey, + publicKey: rootCAKey.Public(), + writePub: true, + wantErr: false, + }, + { + desc: "ECDSA private key and ECDSA public key", + privateKey: ecdsaP256Key, + publicKey: ecdsaP256Key.Public(), + writePub: true, + wantErr: false, + }, + { + desc: "RSA private key and ECDSA public key", + privateKey: rootCAKey, + publicKey: ecdsaP256Key.Public(), + writePub: true, + wantErr: true, + }, + { + desc: "ECDSA private key and RSA public key", + privateKey: ecdsaP256Key, + publicKey: rootCAKey.Public(), + writePub: true, + wantErr: true, + }, + { + desc: "missing public key file", + privateKey: rootCAKey, + writePub: false, + wantErr: true, + }, + } + + for _, rt := range tests { + t.Run(rt.desc, func(t *testing.T) { + tmpdir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatalf("Couldn't create tmpdir") + } + defer func() { _ = os.RemoveAll(tmpdir) }() + + err = WriteKey(tmpdir, "foo", rt.privateKey) + if err != nil { + t.Fatalf("failed to write private key: %v", err) + } + if rt.writePub { + err = WritePublicKey(tmpdir, "foo", rt.publicKey) + if err != nil { + t.Fatalf("failed to write public key: %v", err) + } + } + + _, _, actual := TryLoadPrivatePublicKeyFromDisk(tmpdir, "foo") + if (actual != nil) != rt.wantErr { + t.Fatalf("TryLoadPrivatePublicKeyFromDisk() error = %v, wantErr %v", actual, rt.wantErr) + } + }) + } +} + func TestPathsForCertAndKey(t *testing.T) { crtPath, keyPath := PathsForCertAndKey("/foo", "bar") expectedPath := filepath.FromSlash("/foo/bar.crt")