mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
kubeadm: allow creating a cluster with ECDSA keys
The selected key type is defined by kubeadm's --feature-gates option: if it contains PublicKeysECDSA=true then ECDSA keys will be generated and used. By default RSA keys are used still. Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
This commit is contained in:
parent
ac25069a05
commit
109f5db5a3
@ -19,6 +19,7 @@ go_library(
|
|||||||
],
|
],
|
||||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm",
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm",
|
||||||
deps = [
|
deps = [
|
||||||
|
"//cmd/kubeadm/app/features:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
@ -17,8 +17,11 @@ limitations under the License.
|
|||||||
package kubeadm
|
package kubeadm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/x509"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
)
|
)
|
||||||
@ -400,6 +403,15 @@ func (cfg *ClusterConfiguration) GetControlPlaneImageRepository() string {
|
|||||||
return cfg.ImageRepository
|
return cfg.ImageRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PublicKeyAlgorithm returns the type of encryption keys used in the cluster.
|
||||||
|
func (cfg *ClusterConfiguration) PublicKeyAlgorithm() x509.PublicKeyAlgorithm {
|
||||||
|
if features.Enabled(cfg.FeatureGates, features.PublicKeysECDSA) {
|
||||||
|
return x509.ECDSA
|
||||||
|
}
|
||||||
|
|
||||||
|
return x509.RSA
|
||||||
|
}
|
||||||
|
|
||||||
// HostPathMount contains elements describing volumes that are mounted from the
|
// HostPathMount contains elements describing volumes that are mounted from the
|
||||||
// host.
|
// host.
|
||||||
type HostPathMount struct {
|
type HostPathMount struct {
|
||||||
|
@ -200,7 +200,7 @@ func runCertsSa(c workflow.RunData) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the new service account key (or use existing)
|
// create the new service account key (or use existing)
|
||||||
return certsphase.CreateServiceAccountKeyAndPublicKeyFiles(data.CertificateWriteDir())
|
return certsphase.CreateServiceAccountKeyAndPublicKeyFiles(data.CertificateWriteDir(), data.Cfg().ClusterConfiguration.PublicKeyAlgorithm())
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCerts(c workflow.RunData) error {
|
func runCerts(c workflow.RunData) error {
|
||||||
|
@ -35,7 +35,7 @@ go_test(
|
|||||||
srcs = ["features_test.go"],
|
srcs = ["features_test.go"],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
|
||||||
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
|
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -30,11 +30,14 @@ import (
|
|||||||
const (
|
const (
|
||||||
// IPv6DualStack is expected to be alpha in v1.16
|
// IPv6DualStack is expected to be alpha in v1.16
|
||||||
IPv6DualStack = "IPv6DualStack"
|
IPv6DualStack = "IPv6DualStack"
|
||||||
|
// PublicKeysECDSA is expected to be alpha in v1.19
|
||||||
|
PublicKeysECDSA = "PublicKeysECDSA"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitFeatureGates are the default feature gates for the init command
|
// InitFeatureGates are the default feature gates for the init command
|
||||||
var InitFeatureGates = FeatureList{
|
var InitFeatureGates = FeatureList{
|
||||||
IPv6DualStack: {FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Alpha}},
|
IPv6DualStack: {FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Alpha}},
|
||||||
|
PublicKeysECDSA: {FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Alpha}},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feature represents a feature being gated
|
// Feature represents a feature being gated
|
||||||
|
@ -20,8 +20,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
"k8s.io/component-base/featuregate"
|
"k8s.io/component-base/featuregate"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestKnownFeatures(t *testing.T) {
|
func TestKnownFeatures(t *testing.T) {
|
||||||
@ -129,7 +129,7 @@ func TestNewFeatureGate(t *testing.T) {
|
|||||||
func TestValidateVersion(t *testing.T) {
|
func TestValidateVersion(t *testing.T) {
|
||||||
var someFeatures = FeatureList{
|
var someFeatures = FeatureList{
|
||||||
"feature1": {FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Beta}},
|
"feature1": {FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Beta}},
|
||||||
"feature2": {FeatureSpec: featuregate.FeatureSpec{Default: true, PreRelease: featuregate.Alpha}, MinimumVersion: constants.MinimumControlPlaneVersion.WithPreRelease("alpha.1")},
|
"feature2": {FeatureSpec: featuregate.FeatureSpec{Default: true, PreRelease: featuregate.Alpha}, MinimumVersion: version.MustParseSemantic("v1.17.0").WithPreRelease("alpha.1")},
|
||||||
}
|
}
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
@ -146,7 +146,7 @@ func TestValidateVersion(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "min version but correct value given",
|
name: "min version but correct value given",
|
||||||
requestedFeatures: map[string]bool{"feature2": true},
|
requestedFeatures: map[string]bool{"feature2": true},
|
||||||
requestedVersion: constants.MinimumControlPlaneVersion.String(),
|
requestedVersion: "v1.17.0",
|
||||||
expectedError: false,
|
expectedError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type configMutatorsFunc func(*kubeadmapi.InitConfiguration, *certutil.Config) error
|
type configMutatorsFunc func(*kubeadmapi.InitConfiguration, *pkiutil.CertConfig) error
|
||||||
|
|
||||||
// KubeadmCert represents a certificate that Kubeadm will create to function properly.
|
// KubeadmCert represents a certificate that Kubeadm will create to function properly.
|
||||||
type KubeadmCert struct {
|
type KubeadmCert struct {
|
||||||
@ -39,17 +39,18 @@ type KubeadmCert struct {
|
|||||||
// Some attributes will depend on the InitConfiguration, only known at runtime.
|
// Some attributes will depend on the InitConfiguration, only known at runtime.
|
||||||
// These functions will be run in series, passed both the InitConfiguration and a cert Config.
|
// These functions will be run in series, passed both the InitConfiguration and a cert Config.
|
||||||
configMutators []configMutatorsFunc
|
configMutators []configMutatorsFunc
|
||||||
config certutil.Config
|
config pkiutil.CertConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConfig returns the definition for the given cert given the provided InitConfiguration
|
// GetConfig returns the definition for the given cert given the provided InitConfiguration
|
||||||
func (k *KubeadmCert) GetConfig(ic *kubeadmapi.InitConfiguration) (*certutil.Config, error) {
|
func (k *KubeadmCert) GetConfig(ic *kubeadmapi.InitConfiguration) (*pkiutil.CertConfig, error) {
|
||||||
for _, f := range k.configMutators {
|
for _, f := range k.configMutators {
|
||||||
if err := f(ic, &k.config); err != nil {
|
if err := f(ic, &k.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
k.config.PublicKeyAlgorithm = ic.ClusterConfiguration.PublicKeyAlgorithm()
|
||||||
return &k.config, nil
|
return &k.config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,8 +240,10 @@ var (
|
|||||||
Name: "ca",
|
Name: "ca",
|
||||||
LongName: "self-signed Kubernetes CA to provision identities for other Kubernetes components",
|
LongName: "self-signed Kubernetes CA to provision identities for other Kubernetes components",
|
||||||
BaseName: kubeadmconstants.CACertAndKeyBaseName,
|
BaseName: kubeadmconstants.CACertAndKeyBaseName,
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: "kubernetes",
|
Config: certutil.Config{
|
||||||
|
CommonName: "kubernetes",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// KubeadmCertAPIServer is the definition of the cert used to serve the Kubernetes API.
|
// KubeadmCertAPIServer is the definition of the cert used to serve the Kubernetes API.
|
||||||
@ -249,9 +252,11 @@ var (
|
|||||||
LongName: "certificate for serving the Kubernetes API",
|
LongName: "certificate for serving the Kubernetes API",
|
||||||
BaseName: kubeadmconstants.APIServerCertAndKeyBaseName,
|
BaseName: kubeadmconstants.APIServerCertAndKeyBaseName,
|
||||||
CAName: "ca",
|
CAName: "ca",
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: kubeadmconstants.APIServerCertCommonName,
|
Config: certutil.Config{
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
CommonName: kubeadmconstants.APIServerCertCommonName,
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
configMutators: []configMutatorsFunc{
|
configMutators: []configMutatorsFunc{
|
||||||
makeAltNamesMutator(pkiutil.GetAPIServerAltNames),
|
makeAltNamesMutator(pkiutil.GetAPIServerAltNames),
|
||||||
@ -263,10 +268,12 @@ var (
|
|||||||
LongName: "certificate for the API server to connect to kubelet",
|
LongName: "certificate for the API server to connect to kubelet",
|
||||||
BaseName: kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName,
|
||||||
CAName: "ca",
|
CAName: "ca",
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: kubeadmconstants.APIServerKubeletClientCertCommonName,
|
Config: certutil.Config{
|
||||||
Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
|
CommonName: kubeadmconstants.APIServerKubeletClientCertCommonName,
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,8 +282,10 @@ var (
|
|||||||
Name: "front-proxy-ca",
|
Name: "front-proxy-ca",
|
||||||
LongName: "self-signed CA to provision identities for front proxy",
|
LongName: "self-signed CA to provision identities for front proxy",
|
||||||
BaseName: kubeadmconstants.FrontProxyCACertAndKeyBaseName,
|
BaseName: kubeadmconstants.FrontProxyCACertAndKeyBaseName,
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: "front-proxy-ca",
|
Config: certutil.Config{
|
||||||
|
CommonName: "front-proxy-ca",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,9 +295,11 @@ var (
|
|||||||
BaseName: kubeadmconstants.FrontProxyClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.FrontProxyClientCertAndKeyBaseName,
|
||||||
LongName: "certificate for the front proxy client",
|
LongName: "certificate for the front proxy client",
|
||||||
CAName: "front-proxy-ca",
|
CAName: "front-proxy-ca",
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: kubeadmconstants.FrontProxyClientCertCommonName,
|
Config: certutil.Config{
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
CommonName: kubeadmconstants.FrontProxyClientCertCommonName,
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,8 +308,10 @@ var (
|
|||||||
Name: "etcd-ca",
|
Name: "etcd-ca",
|
||||||
LongName: "self-signed CA to provision identities for etcd",
|
LongName: "self-signed CA to provision identities for etcd",
|
||||||
BaseName: kubeadmconstants.EtcdCACertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdCACertAndKeyBaseName,
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: "etcd-ca",
|
Config: certutil.Config{
|
||||||
|
CommonName: "etcd-ca",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// KubeadmCertEtcdServer is the definition of the cert used to serve etcd to clients.
|
// KubeadmCertEtcdServer is the definition of the cert used to serve etcd to clients.
|
||||||
@ -307,12 +320,14 @@ var (
|
|||||||
LongName: "certificate for serving etcd",
|
LongName: "certificate for serving etcd",
|
||||||
BaseName: kubeadmconstants.EtcdServerCertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdServerCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
// TODO: etcd 3.2 introduced an undocumented requirement for ClientAuth usage on the
|
Config: certutil.Config{
|
||||||
// server cert: https://github.com/coreos/etcd/issues/9785#issuecomment-396715692
|
// TODO: etcd 3.2 introduced an undocumented requirement for ClientAuth usage on the
|
||||||
// Once the upstream issue is resolved, this should be returned to only allowing
|
// server cert: https://github.com/coreos/etcd/issues/9785#issuecomment-396715692
|
||||||
// ServerAuth usage.
|
// Once the upstream issue is resolved, this should be returned to only allowing
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
// ServerAuth usage.
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
configMutators: []configMutatorsFunc{
|
configMutators: []configMutatorsFunc{
|
||||||
makeAltNamesMutator(pkiutil.GetEtcdAltNames),
|
makeAltNamesMutator(pkiutil.GetEtcdAltNames),
|
||||||
@ -325,8 +340,10 @@ var (
|
|||||||
LongName: "certificate for etcd nodes to communicate with each other",
|
LongName: "certificate for etcd nodes to communicate with each other",
|
||||||
BaseName: kubeadmconstants.EtcdPeerCertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdPeerCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
Config: certutil.Config{
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
configMutators: []configMutatorsFunc{
|
configMutators: []configMutatorsFunc{
|
||||||
makeAltNamesMutator(pkiutil.GetEtcdPeerAltNames),
|
makeAltNamesMutator(pkiutil.GetEtcdPeerAltNames),
|
||||||
@ -339,10 +356,12 @@ var (
|
|||||||
LongName: "certificate for liveness probes to healthcheck etcd",
|
LongName: "certificate for liveness probes to healthcheck etcd",
|
||||||
BaseName: kubeadmconstants.EtcdHealthcheckClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdHealthcheckClientCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: kubeadmconstants.EtcdHealthcheckClientCertCommonName,
|
Config: certutil.Config{
|
||||||
Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
|
CommonName: kubeadmconstants.EtcdHealthcheckClientCertCommonName,
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// KubeadmCertEtcdAPIClient is the definition of the cert used by the API server to access etcd.
|
// KubeadmCertEtcdAPIClient is the definition of the cert used by the API server to access etcd.
|
||||||
@ -351,16 +370,18 @@ var (
|
|||||||
LongName: "certificate the apiserver uses to access etcd",
|
LongName: "certificate the apiserver uses to access etcd",
|
||||||
BaseName: kubeadmconstants.APIServerEtcdClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.APIServerEtcdClientCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
CommonName: kubeadmconstants.APIServerEtcdClientCertCommonName,
|
Config: certutil.Config{
|
||||||
Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
|
CommonName: kubeadmconstants.APIServerEtcdClientCertCommonName,
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeAltNamesMutator(f func(*kubeadmapi.InitConfiguration) (*certutil.AltNames, error)) configMutatorsFunc {
|
func makeAltNamesMutator(f func(*kubeadmapi.InitConfiguration) (*certutil.AltNames, error)) configMutatorsFunc {
|
||||||
return func(mc *kubeadmapi.InitConfiguration, cc *certutil.Config) error {
|
return func(mc *kubeadmapi.InitConfiguration, cc *pkiutil.CertConfig) error {
|
||||||
altNames, err := f(mc)
|
altNames, err := f(mc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -371,7 +392,7 @@ func makeAltNamesMutator(f func(*kubeadmapi.InitConfiguration) (*certutil.AltNam
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setCommonNameToNodeName() configMutatorsFunc {
|
func setCommonNameToNodeName() configMutatorsFunc {
|
||||||
return func(mc *kubeadmapi.InitConfiguration, cc *certutil.Config) error {
|
return func(mc *kubeadmapi.InitConfiguration, cc *pkiutil.CertConfig) error {
|
||||||
cc.CommonName = mc.NodeRegistration.Name
|
cc.CommonName = mc.NodeRegistration.Name
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
|
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCertListOrder(t *testing.T) {
|
func TestCertListOrder(t *testing.T) {
|
||||||
@ -160,16 +161,18 @@ func TestCreateCertificateChain(t *testing.T) {
|
|||||||
|
|
||||||
caCfg := Certificates{
|
caCfg := Certificates{
|
||||||
{
|
{
|
||||||
config: certutil.Config{},
|
config: pkiutil.CertConfig{},
|
||||||
Name: "test-ca",
|
Name: "test-ca",
|
||||||
BaseName: "test-ca",
|
BaseName: "test-ca",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
config: certutil.Config{
|
config: pkiutil.CertConfig{
|
||||||
AltNames: certutil.AltNames{
|
Config: certutil.Config{
|
||||||
DNSNames: []string{"test-domain.space"},
|
AltNames: certutil.AltNames{
|
||||||
|
DNSNames: []string{"test-domain.space"},
|
||||||
|
},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
},
|
},
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
||||||
},
|
},
|
||||||
configMutators: []configMutatorsFunc{
|
configMutators: []configMutatorsFunc{
|
||||||
setCommonNameToNodeName(),
|
setCommonNameToNodeName(),
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
|
||||||
"k8s.io/client-go/util/keyutil"
|
"k8s.io/client-go/util/keyutil"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
@ -61,12 +60,12 @@ func CreatePKIAssets(cfg *kubeadmapi.InitConfiguration) error {
|
|||||||
fmt.Printf("[certs] Valid certificates and keys now exist in %q\n", cfg.CertificatesDir)
|
fmt.Printf("[certs] Valid certificates and keys now exist in %q\n", cfg.CertificatesDir)
|
||||||
|
|
||||||
// Service accounts are not x509 certs, so handled separately
|
// Service accounts are not x509 certs, so handled separately
|
||||||
return CreateServiceAccountKeyAndPublicKeyFiles(cfg.CertificatesDir)
|
return CreateServiceAccountKeyAndPublicKeyFiles(cfg.CertificatesDir, cfg.ClusterConfiguration.PublicKeyAlgorithm())
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateServiceAccountKeyAndPublicKeyFiles creates new public/private key files for signing service account users.
|
// CreateServiceAccountKeyAndPublicKeyFiles creates new public/private key files for signing service account users.
|
||||||
// If the sa public/private key files already exist in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
// If the sa public/private key files already exist in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
||||||
func CreateServiceAccountKeyAndPublicKeyFiles(certsDir string) error {
|
func CreateServiceAccountKeyAndPublicKeyFiles(certsDir string, keyType x509.PublicKeyAlgorithm) error {
|
||||||
klog.V(1).Infoln("creating new public/private key files for signing service account users")
|
klog.V(1).Infoln("creating new public/private key files for signing service account users")
|
||||||
_, err := keyutil.PrivateKeyFromFile(filepath.Join(certsDir, kubeadmconstants.ServiceAccountPrivateKeyName))
|
_, err := keyutil.PrivateKeyFromFile(filepath.Join(certsDir, kubeadmconstants.ServiceAccountPrivateKeyName))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -80,7 +79,7 @@ func CreateServiceAccountKeyAndPublicKeyFiles(certsDir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The key does NOT exist, let's generate it now
|
// The key does NOT exist, let's generate it now
|
||||||
key, err := pkiutil.NewPrivateKey()
|
key, err := pkiutil.NewPrivateKey(keyType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -215,7 +214,7 @@ func writeCertificateAuthorityFilesIfNotExist(pkiDir string, baseName string, ca
|
|||||||
// If there already is a certificate file at the given path; kubeadm tries to load it and check if the values in the
|
// If there already is a certificate file at the given path; kubeadm tries to load it and check if the values in the
|
||||||
// existing and the expected certificate equals. If they do; kubeadm will just skip writing the file as it's up-to-date,
|
// existing and the expected certificate equals. If they do; kubeadm will just skip writing the file as it's up-to-date,
|
||||||
// otherwise this function returns an error.
|
// otherwise this function returns an error.
|
||||||
func writeCertificateFilesIfNotExist(pkiDir string, baseName string, signingCert *x509.Certificate, cert *x509.Certificate, key crypto.Signer, cfg *certutil.Config) error {
|
func writeCertificateFilesIfNotExist(pkiDir string, baseName string, signingCert *x509.Certificate, cert *x509.Certificate, key crypto.Signer, cfg *pkiutil.CertConfig) error {
|
||||||
|
|
||||||
// Checks if the signed certificate exists in the PKI directory
|
// Checks if the signed certificate exists in the PKI directory
|
||||||
if pkiutil.CertOrKeyExist(pkiDir, baseName) {
|
if pkiutil.CertOrKeyExist(pkiDir, baseName) {
|
||||||
@ -426,7 +425,7 @@ func validatePrivatePublicKey(l certKeyLocation) error {
|
|||||||
|
|
||||||
// validateCertificateWithConfig makes sure that a given certificate is valid at
|
// validateCertificateWithConfig makes sure that a given certificate is valid at
|
||||||
// least for the SANs defined in the configuration.
|
// least for the SANs defined in the configuration.
|
||||||
func validateCertificateWithConfig(cert *x509.Certificate, baseName string, cfg *certutil.Config) error {
|
func validateCertificateWithConfig(cert *x509.Certificate, baseName string, cfg *pkiutil.CertConfig) error {
|
||||||
for _, dnsName := range cfg.AltNames.DNSNames {
|
for _, dnsName := range cfg.AltNames.DNSNames {
|
||||||
if err := cert.VerifyHostname(dnsName); err != nil {
|
if err := cert.VerifyHostname(dnsName); err != nil {
|
||||||
return errors.Wrapf(err, "certificate %s is invalid", baseName)
|
return errors.Wrapf(err, "certificate %s is invalid", baseName)
|
||||||
|
@ -42,8 +42,10 @@ import (
|
|||||||
|
|
||||||
func createTestCSR(t *testing.T) (*x509.CertificateRequest, crypto.Signer) {
|
func createTestCSR(t *testing.T) (*x509.CertificateRequest, crypto.Signer) {
|
||||||
csr, key, err := pkiutil.NewCSRAndKey(
|
csr, key, err := pkiutil.NewCSRAndKey(
|
||||||
&certutil.Config{
|
&pkiutil.CertConfig{
|
||||||
CommonName: "testCert",
|
Config: certutil.Config{
|
||||||
|
CommonName: "testCert",
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't create test cert: %v", err)
|
t.Fatalf("couldn't create test cert: %v", err)
|
||||||
@ -344,7 +346,7 @@ func TestCreateServiceAccountKeyAndPublicKeyFiles(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := CreateServiceAccountKeyAndPublicKeyFiles(dir)
|
err := CreateServiceAccountKeyAndPublicKeyFiles(dir, x509.RSA)
|
||||||
if (err != nil) != tt.expectedErr {
|
if (err != nil) != tt.expectedErr {
|
||||||
t.Fatalf("expected error: %v, got: %v, error: %v", tt.expectedErr, err != nil, err)
|
t.Fatalf("expected error: %v, got: %v, error: %v", tt.expectedErr, err != nil, err)
|
||||||
} else if tt.expectedErr {
|
} else if tt.expectedErr {
|
||||||
|
@ -52,7 +52,7 @@ func NewAPIRenewer(client clientset.Interface) *APIRenewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Renew a certificate using the K8s certificate API
|
// Renew a certificate using the K8s certificate API
|
||||||
func (r *APIRenewer) Renew(cfg *certutil.Config) (*x509.Certificate, crypto.Signer, error) {
|
func (r *APIRenewer) Renew(cfg *pkiutil.CertConfig) (*x509.Certificate, crypto.Signer, error) {
|
||||||
reqTmp := &x509.CertificateRequest{
|
reqTmp := &x509.CertificateRequest{
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
CommonName: cfg.CommonName,
|
CommonName: cfg.CommonName,
|
||||||
@ -62,7 +62,7 @@ func (r *APIRenewer) Renew(cfg *certutil.Config) (*x509.Certificate, crypto.Sign
|
|||||||
IPAddresses: cfg.AltNames.IPs,
|
IPAddresses: cfg.AltNames.IPs,
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := pkiutil.NewPrivateKey()
|
key, err := pkiutil.NewPrivateKey(cfg.PublicKeyAlgorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "couldn't create new private key")
|
return nil, nil, errors.Wrap(err, "couldn't create new private key")
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestAPIRenewer(t *testing.T) {
|
func TestAPIRenewer(t *testing.T) {
|
||||||
caCertCfg := &certutil.Config{CommonName: "kubernetes"}
|
caCertCfg := &pkiutil.CertConfig{
|
||||||
|
Config: certutil.Config{CommonName: "kubernetes"},
|
||||||
|
}
|
||||||
caCert, caKey, err := pkiutil.NewCertificateAuthority(caCertCfg)
|
caCert, caKey, err := pkiutil.NewCertificateAuthority(caCertCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't create CA: %v", err)
|
t.Fatalf("couldn't create CA: %v", err)
|
||||||
@ -55,12 +57,14 @@ func TestAPIRenewer(t *testing.T) {
|
|||||||
// override the timeout so tests are faster
|
// override the timeout so tests are faster
|
||||||
watchTimeout = time.Second
|
watchTimeout = time.Second
|
||||||
|
|
||||||
certCfg := &certutil.Config{
|
certCfg := &pkiutil.CertConfig{
|
||||||
CommonName: "test-certs",
|
Config: certutil.Config{
|
||||||
AltNames: certutil.AltNames{
|
CommonName: "test-certs",
|
||||||
DNSNames: []string{"test-domain.space"},
|
AltNames: certutil.AltNames{
|
||||||
|
DNSNames: []string{"test-domain.space"},
|
||||||
|
},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
},
|
},
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renewer := &APIRenewer{
|
renewer := &APIRenewer{
|
||||||
@ -92,12 +96,14 @@ func defaultReactionFunc(obj runtime.Object) k8stesting.ReactionFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getCertReq(t *testing.T, caCert *x509.Certificate, caKey crypto.Signer) *certsapi.CertificateSigningRequest {
|
func getCertReq(t *testing.T, caCert *x509.Certificate, caKey crypto.Signer) *certsapi.CertificateSigningRequest {
|
||||||
cert, _, err := pkiutil.NewCertAndKey(caCert, caKey, &certutil.Config{
|
cert, _, err := pkiutil.NewCertAndKey(caCert, caKey, &pkiutil.CertConfig{
|
||||||
CommonName: "testcert",
|
Config: certutil.Config{
|
||||||
AltNames: certutil.AltNames{
|
CommonName: "testcert",
|
||||||
DNSNames: []string{"test-domain.space"},
|
AltNames: certutil.AltNames{
|
||||||
|
DNSNames: []string{"test-domain.space"},
|
||||||
|
},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
},
|
},
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't generate cert: %v", err)
|
t.Fatalf("couldn't generate cert: %v", err)
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"crypto"
|
"crypto"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
|
||||||
certutil "k8s.io/client-go/util/cert"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -39,6 +38,6 @@ func NewFileRenewer(caCert *x509.Certificate, caKey crypto.Signer) *FileRenewer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Renew a certificate using a given CA cert and key
|
// Renew a certificate using a given CA cert and key
|
||||||
func (r *FileRenewer) Renew(cfg *certutil.Config) (*x509.Certificate, crypto.Signer, error) {
|
func (r *FileRenewer) Renew(cfg *pkiutil.CertConfig) (*x509.Certificate, crypto.Signer, error) {
|
||||||
return pkiutil.NewCertAndKey(r.caCert, r.caKey, cfg)
|
return pkiutil.NewCertAndKey(r.caCert, r.caKey, cfg)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
|
pkiutil "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFileRenewer(t *testing.T) {
|
func TestFileRenewer(t *testing.T) {
|
||||||
@ -28,12 +29,14 @@ func TestFileRenewer(t *testing.T) {
|
|||||||
fr := NewFileRenewer(testCACert, testCAKey)
|
fr := NewFileRenewer(testCACert, testCAKey)
|
||||||
|
|
||||||
// renews a certificate
|
// renews a certificate
|
||||||
certCfg := &certutil.Config{
|
certCfg := &pkiutil.CertConfig{
|
||||||
CommonName: "test-certs",
|
Config: certutil.Config{
|
||||||
AltNames: certutil.AltNames{
|
CommonName: "test-certs",
|
||||||
DNSNames: []string{"test-domain.space"},
|
AltNames: certutil.AltNames{
|
||||||
|
DNSNames: []string{"test-domain.space"},
|
||||||
|
},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
},
|
},
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, _, err := fr.Renew(certCfg)
|
cert, _, err := fr.Renew(certCfg)
|
||||||
|
@ -224,7 +224,10 @@ func (rm *Manager) RenewUsingLocalCA(name string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract the certificate config
|
// extract the certificate config
|
||||||
cfg := certToConfig(cert)
|
cfg := &pkiutil.CertConfig{
|
||||||
|
Config: certToConfig(cert),
|
||||||
|
PublicKeyAlgorithm: rm.cfg.PublicKeyAlgorithm(),
|
||||||
|
}
|
||||||
|
|
||||||
// reads the CA
|
// reads the CA
|
||||||
caCert, caKey, err := certsphase.LoadCertificateAuthority(rm.cfg.CertificatesDir, handler.CABaseName)
|
caCert, caKey, err := certsphase.LoadCertificateAuthority(rm.cfg.CertificatesDir, handler.CABaseName)
|
||||||
@ -264,7 +267,10 @@ func (rm *Manager) RenewUsingCSRAPI(name string, client clientset.Interface) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract the certificate config
|
// extract the certificate config
|
||||||
cfg := certToConfig(cert)
|
cfg := &pkiutil.CertConfig{
|
||||||
|
Config: certToConfig(cert),
|
||||||
|
PublicKeyAlgorithm: rm.cfg.PublicKeyAlgorithm(),
|
||||||
|
}
|
||||||
|
|
||||||
// create a new certificate with the same config
|
// create a new certificate with the same config
|
||||||
newCert, newKey, err := NewAPIRenewer(client).Renew(cfg)
|
newCert, newKey, err := NewAPIRenewer(client).Renew(cfg)
|
||||||
@ -298,7 +304,10 @@ func (rm *Manager) CreateRenewCSR(name, outdir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extracts the certificate config
|
// extracts the certificate config
|
||||||
cfg := certToConfig(cert)
|
cfg := &pkiutil.CertConfig{
|
||||||
|
Config: certToConfig(cert),
|
||||||
|
PublicKeyAlgorithm: rm.cfg.PublicKeyAlgorithm(),
|
||||||
|
}
|
||||||
|
|
||||||
// generates the CSR request and save it
|
// generates the CSR request and save it
|
||||||
csr, key, err := pkiutil.NewCSRAndKey(cfg)
|
csr, key, err := pkiutil.NewCSRAndKey(cfg)
|
||||||
@ -407,8 +416,8 @@ func (rm *Manager) IsExternallyManaged(caBaseName string) (bool, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func certToConfig(cert *x509.Certificate) *certutil.Config {
|
func certToConfig(cert *x509.Certificate) certutil.Config {
|
||||||
return &certutil.Config{
|
return certutil.Config{
|
||||||
CommonName: cert.Subject.CommonName,
|
CommonName: cert.Subject.CommonName,
|
||||||
Organization: cert.Subject.Organization,
|
Organization: cert.Subject.Organization,
|
||||||
AltNames: certutil.AltNames{
|
AltNames: certutil.AltNames{
|
||||||
|
@ -34,18 +34,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testCACertCfg = &certutil.Config{CommonName: "kubernetes"}
|
testCACertCfg = &pkiutil.CertConfig{
|
||||||
|
Config: certutil.Config{CommonName: "kubernetes"},
|
||||||
|
}
|
||||||
|
|
||||||
testCACert, testCAKey, _ = pkiutil.NewCertificateAuthority(testCACertCfg)
|
testCACert, testCAKey, _ = pkiutil.NewCertificateAuthority(testCACertCfg)
|
||||||
|
|
||||||
testCertCfg = &certutil.Config{
|
testCertCfg = &pkiutil.CertConfig{
|
||||||
CommonName: "test-common-name",
|
Config: certutil.Config{
|
||||||
Organization: []string{"sig-cluster-lifecycle"},
|
CommonName: "test-common-name",
|
||||||
AltNames: certutil.AltNames{
|
Organization: []string{"sig-cluster-lifecycle"},
|
||||||
IPs: []net.IP{net.ParseIP("10.100.0.1")},
|
AltNames: certutil.AltNames{
|
||||||
DNSNames: []string{"test-domain.space"},
|
IPs: []net.IP{net.ParseIP("10.100.0.1")},
|
||||||
|
DNSNames: []string{"test-domain.space"},
|
||||||
|
},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
},
|
},
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -154,13 +154,15 @@ func writeTestCertificate(t *testing.T, dir, name string, caCert *x509.Certifica
|
|||||||
// writeTestKubeconfig is a utility for creating a test kubeconfig with an embedded certificate
|
// writeTestKubeconfig is a utility for creating a test kubeconfig with an embedded certificate
|
||||||
func writeTestKubeconfig(t *testing.T, dir, name string, caCert *x509.Certificate, caKey crypto.Signer) *x509.Certificate {
|
func writeTestKubeconfig(t *testing.T, dir, name string, caCert *x509.Certificate, caKey crypto.Signer) *x509.Certificate {
|
||||||
|
|
||||||
cfg := &certutil.Config{
|
cfg := &pkiutil.CertConfig{
|
||||||
CommonName: "test-common-name",
|
Config: certutil.Config{
|
||||||
Organization: []string{"sig-cluster-lifecycle"},
|
CommonName: "test-common-name",
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Organization: []string{"sig-cluster-lifecycle"},
|
||||||
AltNames: certutil.AltNames{
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
IPs: []net.IP{net.ParseIP("10.100.0.1")},
|
AltNames: certutil.AltNames{
|
||||||
DNSNames: []string{"test-domain.space"},
|
IPs: []net.IP{net.ParseIP("10.100.0.1")},
|
||||||
|
DNSNames: []string{"test-domain.space"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, cfg)
|
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, cfg)
|
||||||
|
@ -182,10 +182,12 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, create a client certs
|
// otherwise, create a client certs
|
||||||
clientCertConfig := certutil.Config{
|
clientCertConfig := pkiutil.CertConfig{
|
||||||
CommonName: spec.ClientName,
|
Config: certutil.Config{
|
||||||
Organization: spec.ClientCertAuth.Organizations,
|
CommonName: spec.ClientName,
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Organization: spec.ClientCertAuth.Organizations,
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, &clientCertConfig)
|
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, &clientCertConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,7 +32,9 @@ import (
|
|||||||
// SetupCertificateAuthority is a utility function for kubeadm testing that creates a
|
// SetupCertificateAuthority is a utility function for kubeadm testing that creates a
|
||||||
// CertificateAuthority cert/key pair
|
// CertificateAuthority cert/key pair
|
||||||
func SetupCertificateAuthority(t *testing.T) (*x509.Certificate, crypto.Signer) {
|
func SetupCertificateAuthority(t *testing.T) (*x509.Certificate, crypto.Signer) {
|
||||||
caCert, caKey, err := pkiutil.NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
caCert, caKey, err := pkiutil.NewCertificateAuthority(&pkiutil.CertConfig{
|
||||||
|
Config: certutil.Config{CommonName: "kubernetes"},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failure while generating CA certificate and key: %v", err)
|
t.Fatalf("failure while generating CA certificate and key: %v", err)
|
||||||
}
|
}
|
||||||
@ -132,7 +134,7 @@ func AssertCertificateHasIPAddresses(t *testing.T, cert *x509.Certificate, IPAdd
|
|||||||
|
|
||||||
// CreateCACert creates a generic CA cert.
|
// CreateCACert creates a generic CA cert.
|
||||||
func CreateCACert(t *testing.T) (*x509.Certificate, crypto.Signer) {
|
func CreateCACert(t *testing.T) (*x509.Certificate, crypto.Signer) {
|
||||||
certCfg := &certutil.Config{CommonName: "kubernetes"}
|
certCfg := &pkiutil.CertConfig{Config: certutil.Config{CommonName: "kubernetes"}}
|
||||||
cert, key, err := pkiutil.NewCertificateAuthority(certCfg)
|
cert, key, err := pkiutil.NewCertificateAuthority(certCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't create CA: %v", err)
|
t.Fatalf("couldn't create CA: %v", err)
|
||||||
@ -141,11 +143,13 @@ func CreateCACert(t *testing.T) (*x509.Certificate, crypto.Signer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateTestCert makes a generic certificate with the given CA and alternative names.
|
// CreateTestCert makes a generic certificate with the given CA and alternative names.
|
||||||
func CreateTestCert(t *testing.T, caCert *x509.Certificate, caKey crypto.Signer, altNames certutil.AltNames) (*x509.Certificate, crypto.Signer, *certutil.Config) {
|
func CreateTestCert(t *testing.T, caCert *x509.Certificate, caKey crypto.Signer, altNames certutil.AltNames) (*x509.Certificate, crypto.Signer, *pkiutil.CertConfig) {
|
||||||
config := &certutil.Config{
|
config := &pkiutil.CertConfig{
|
||||||
CommonName: "testCert",
|
Config: certutil.Config{
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
|
CommonName: "testCert",
|
||||||
AltNames: altNames,
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
|
||||||
|
AltNames: altNames,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, config)
|
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,6 +19,7 @@ package pkiutil
|
|||||||
import (
|
import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
cryptorand "crypto/rand"
|
cryptorand "crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
@ -56,14 +57,20 @@ const (
|
|||||||
rsaKeySize = 2048
|
rsaKeySize = 2048
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CertConfig is a wrapper around certutil.Config extending it with PublicKeyAlgorithm.
|
||||||
|
type CertConfig struct {
|
||||||
|
certutil.Config
|
||||||
|
PublicKeyAlgorithm x509.PublicKeyAlgorithm
|
||||||
|
}
|
||||||
|
|
||||||
// NewCertificateAuthority creates new certificate and private key for the certificate authority
|
// NewCertificateAuthority creates new certificate and private key for the certificate authority
|
||||||
func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, crypto.Signer, error) {
|
func NewCertificateAuthority(config *CertConfig) (*x509.Certificate, crypto.Signer, error) {
|
||||||
key, err := NewPrivateKey()
|
key, err := NewPrivateKey(config.PublicKeyAlgorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "unable to create private key while generating CA certificate")
|
return nil, nil, errors.Wrap(err, "unable to create private key while generating CA certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, err := certutil.NewSelfSignedCACert(*config, key)
|
cert, err := certutil.NewSelfSignedCACert(config.Config, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "unable to create self-signed CA certificate")
|
return nil, nil, errors.Wrap(err, "unable to create self-signed CA certificate")
|
||||||
}
|
}
|
||||||
@ -72,8 +79,8 @@ func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, crypto
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCertAndKey creates new certificate and key by passing the certificate authority certificate and key
|
// NewCertAndKey creates new certificate and key by passing the certificate authority certificate and key
|
||||||
func NewCertAndKey(caCert *x509.Certificate, caKey crypto.Signer, config *certutil.Config) (*x509.Certificate, crypto.Signer, error) {
|
func NewCertAndKey(caCert *x509.Certificate, caKey crypto.Signer, config *CertConfig) (*x509.Certificate, crypto.Signer, error) {
|
||||||
key, err := NewPrivateKey()
|
key, err := NewPrivateKey(config.PublicKeyAlgorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "unable to create private key")
|
return nil, nil, errors.Wrap(err, "unable to create private key")
|
||||||
}
|
}
|
||||||
@ -87,8 +94,8 @@ func NewCertAndKey(caCert *x509.Certificate, caKey crypto.Signer, config *certut
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCSRAndKey generates a new key and CSR and that could be signed to create the given certificate
|
// NewCSRAndKey generates a new key and CSR and that could be signed to create the given certificate
|
||||||
func NewCSRAndKey(config *certutil.Config) (*x509.CertificateRequest, crypto.Signer, error) {
|
func NewCSRAndKey(config *CertConfig) (*x509.CertificateRequest, crypto.Signer, error) {
|
||||||
key, err := NewPrivateKey()
|
key, err := NewPrivateKey(config.PublicKeyAlgorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "unable to create private key")
|
return nil, nil, errors.Wrap(err, "unable to create private key")
|
||||||
}
|
}
|
||||||
@ -496,7 +503,7 @@ func CertificateRequestFromFile(file string) (*x509.CertificateRequest, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCSR creates a new CSR
|
// NewCSR creates a new CSR
|
||||||
func NewCSR(cfg certutil.Config, key crypto.Signer) (*x509.CertificateRequest, error) {
|
func NewCSR(cfg CertConfig, key crypto.Signer) (*x509.CertificateRequest, error) {
|
||||||
template := &x509.CertificateRequest{
|
template := &x509.CertificateRequest{
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
CommonName: cfg.CommonName,
|
CommonName: cfg.CommonName,
|
||||||
@ -538,12 +545,16 @@ func EncodePublicKeyPEM(key crypto.PublicKey) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewPrivateKey creates an RSA private key
|
// NewPrivateKey creates an RSA private key
|
||||||
func NewPrivateKey() (crypto.Signer, error) {
|
func NewPrivateKey(keyType x509.PublicKeyAlgorithm) (crypto.Signer, error) {
|
||||||
|
if keyType == x509.ECDSA {
|
||||||
|
return ecdsa.GenerateKey(elliptic.P256(), cryptorand.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
return rsa.GenerateKey(cryptorand.Reader, rsaKeySize)
|
return rsa.GenerateKey(cryptorand.Reader, rsaKeySize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSignedCert creates a signed certificate using the given CA certificate and key
|
// NewSignedCert creates a signed certificate using the given CA certificate and key
|
||||||
func NewSignedCert(cfg *certutil.Config, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
|
func NewSignedCert(cfg *CertConfig, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
|
||||||
serial, err := cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64))
|
serial, err := cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -33,7 +33,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNewCertificateAuthority(t *testing.T) {
|
func TestNewCertificateAuthority(t *testing.T) {
|
||||||
cert, key, err := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
cert, key, err := NewCertificateAuthority(&CertConfig{
|
||||||
|
Config: certutil.Config{CommonName: "kubernetes"},
|
||||||
|
})
|
||||||
|
|
||||||
if cert == nil {
|
if cert == nil {
|
||||||
t.Error("failed NewCertificateAuthority, cert == nil")
|
t.Error("failed NewCertificateAuthority, cert == nil")
|
||||||
@ -86,10 +88,12 @@ func TestNewCertAndKey(t *testing.T) {
|
|||||||
t.Fatalf("Couldn't create Private Key")
|
t.Fatalf("Couldn't create Private Key")
|
||||||
}
|
}
|
||||||
caCert := &x509.Certificate{}
|
caCert := &x509.Certificate{}
|
||||||
config := &certutil.Config{
|
config := &CertConfig{
|
||||||
CommonName: "test",
|
Config: certutil.Config{
|
||||||
Organization: []string{"test"},
|
CommonName: "test",
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Organization: []string{"test"},
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
_, _, actual := NewCertAndKey(caCert, caKey, config)
|
_, _, actual := NewCertAndKey(caCert, caKey, config)
|
||||||
if (actual == nil) != rt.expected {
|
if (actual == nil) != rt.expected {
|
||||||
@ -104,26 +108,41 @@ func TestNewCertAndKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestHasServerAuth(t *testing.T) {
|
func TestHasServerAuth(t *testing.T) {
|
||||||
caCert, caKey, _ := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
caCert, caKey, _ := NewCertificateAuthority(&CertConfig{Config: certutil.Config{CommonName: "kubernetes"}})
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
config certutil.Config
|
config CertConfig
|
||||||
expected bool
|
expected bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "has ServerAuth",
|
name: "has ServerAuth",
|
||||||
config: certutil.Config{
|
config: CertConfig{
|
||||||
CommonName: "test",
|
Config: certutil.Config{
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
CommonName: "test",
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "has ServerAuth ECDSA",
|
||||||
|
config: CertConfig{
|
||||||
|
Config: certutil.Config{
|
||||||
|
CommonName: "test",
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
},
|
||||||
|
PublicKeyAlgorithm: x509.ECDSA,
|
||||||
},
|
},
|
||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "doesn't have ServerAuth",
|
name: "doesn't have ServerAuth",
|
||||||
config: certutil.Config{
|
config: CertConfig{
|
||||||
CommonName: "test",
|
Config: certutil.Config{
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
CommonName: "test",
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
@ -285,7 +304,9 @@ func TestTryLoadCertAndKeyFromDisk(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
caCert, caKey, err := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
caCert, caKey, err := NewCertificateAuthority(&CertConfig{
|
||||||
|
Config: certutil.Config{CommonName: "kubernetes"},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed to create cert and key with an error: %v",
|
"failed to create cert and key with an error: %v",
|
||||||
@ -340,7 +361,9 @@ func TestTryLoadCertFromDisk(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
caCert, _, err := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
caCert, _, err := NewCertificateAuthority(&CertConfig{
|
||||||
|
Config: certutil.Config{CommonName: "kubernetes"},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed to create cert and key with an error: %v",
|
"failed to create cert and key with an error: %v",
|
||||||
|
@ -356,6 +356,10 @@ func TestCmdInitFeatureGates(t *testing.T) {
|
|||||||
name: "feature gate IPv6DualStack=true",
|
name: "feature gate IPv6DualStack=true",
|
||||||
args: "--feature-gates=IPv6DualStack=true",
|
args: "--feature-gates=IPv6DualStack=true",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "feature gate PublicKeysECDSA=true",
|
||||||
|
args: "--feature-gates=PublicKeysECDSA=true",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range initTest {
|
for _, rt := range initTest {
|
||||||
|
Loading…
Reference in New Issue
Block a user