certificates: support allowed usage
This commit is contained in:
@@ -32,6 +32,7 @@ go_library(
|
||||
"//pkg/util/workqueue:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//vendor:github.com/cloudflare/cfssl/config",
|
||||
"//vendor:github.com/cloudflare/cfssl/helpers",
|
||||
"//vendor:github.com/cloudflare/cfssl/signer",
|
||||
"//vendor:github.com/cloudflare/cfssl/signer/local",
|
||||
"//vendor:github.com/golang/glog",
|
||||
|
@@ -33,9 +33,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
|
||||
"github.com/cloudflare/cfssl/config"
|
||||
"github.com/cloudflare/cfssl/signer"
|
||||
"github.com/cloudflare/cfssl/signer/local"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
@@ -43,6 +40,10 @@ type AutoApprover interface {
|
||||
AutoApprove(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, error)
|
||||
}
|
||||
|
||||
type Signer interface {
|
||||
Sign(csr *certificates.CertificateSigningRequest) ([]byte, error)
|
||||
}
|
||||
|
||||
type CertificateController struct {
|
||||
kubeClient clientset.Interface
|
||||
|
||||
@@ -53,8 +54,7 @@ type CertificateController struct {
|
||||
syncHandler func(csrKey string) error
|
||||
|
||||
approver AutoApprover
|
||||
|
||||
signer *local.Signer
|
||||
signer Signer
|
||||
|
||||
queue workqueue.RateLimitingInterface
|
||||
}
|
||||
@@ -65,12 +65,7 @@ func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Du
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.Core().Events("")})
|
||||
|
||||
// Configure cfssl signer
|
||||
// TODO: support non-default policy and remote/pkcs11 signing
|
||||
policy := &config.Signing{
|
||||
Default: config.DefaultConfig(),
|
||||
}
|
||||
ca, err := local.NewSignerFromFile(caCertFile, caKeyFile, policy)
|
||||
s, err := NewCFSSLSigner(caCertFile, caKeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -78,7 +73,7 @@ func NewCertificateController(kubeClient clientset.Interface, syncPeriod time.Du
|
||||
cc := &CertificateController{
|
||||
kubeClient: kubeClient,
|
||||
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "certificate"),
|
||||
signer: ca,
|
||||
signer: s,
|
||||
approver: approver,
|
||||
}
|
||||
|
||||
@@ -209,9 +204,7 @@ func (cc *CertificateController) maybeSignCertificate(key string) error {
|
||||
// 3. Update the Status subresource
|
||||
|
||||
if csr.Status.Certificate == nil && IsCertificateRequestApproved(csr) {
|
||||
pemBytes := csr.Spec.Request
|
||||
req := signer.SignRequest{Request: string(pemBytes)}
|
||||
certBytes, err := cc.signer.Sign(req)
|
||||
certBytes, err := cc.signer.Sign(csr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
99
pkg/controller/certificates/cfssl_signer.go
Normal file
99
pkg/controller/certificates/cfssl_signer.go
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package certificates
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
certificates "k8s.io/kubernetes/pkg/apis/certificates/v1alpha1"
|
||||
|
||||
"github.com/cloudflare/cfssl/config"
|
||||
"github.com/cloudflare/cfssl/helpers"
|
||||
"github.com/cloudflare/cfssl/signer"
|
||||
"github.com/cloudflare/cfssl/signer/local"
|
||||
)
|
||||
|
||||
var onlySigningPolicy = &config.Signing{
|
||||
Default: &config.SigningProfile{
|
||||
Usage: []string{"signing"},
|
||||
Expiry: helpers.OneYear,
|
||||
ExpiryString: "8760h",
|
||||
},
|
||||
}
|
||||
|
||||
type CFSSLSigner struct {
|
||||
ca *x509.Certificate
|
||||
priv crypto.Signer
|
||||
sigAlgo x509.SignatureAlgorithm
|
||||
}
|
||||
|
||||
func NewCFSSLSigner(caFile, caKeyFile string) (*CFSSLSigner, error) {
|
||||
ca, err := ioutil.ReadFile(caFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cakey, err := ioutil.ReadFile(caKeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parsedCa, err := helpers.ParseCertificatePEM(ca)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
strPassword := os.Getenv("CFSSL_CA_PK_PASSWORD")
|
||||
password := []byte(strPassword)
|
||||
if strPassword == "" {
|
||||
password = nil
|
||||
}
|
||||
|
||||
priv, err := helpers.ParsePrivateKeyPEMWithPassword(cakey, password)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Malformed private key %v", err)
|
||||
}
|
||||
return &CFSSLSigner{
|
||||
priv: priv,
|
||||
ca: parsedCa,
|
||||
sigAlgo: signer.DefaultSigAlgo(priv),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cs *CFSSLSigner) Sign(csr *certificates.CertificateSigningRequest) ([]byte, error) {
|
||||
var usages []string
|
||||
for _, usage := range csr.Spec.Usages {
|
||||
usages = append(usages, string(usage))
|
||||
}
|
||||
policy := &config.Signing{
|
||||
Default: &config.SigningProfile{
|
||||
Usage: usages,
|
||||
Expiry: helpers.OneYear,
|
||||
ExpiryString: "8760h",
|
||||
},
|
||||
}
|
||||
s, err := local.NewSigner(cs.priv, cs.ca, cs.sigAlgo, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.Sign(signer.SignRequest{
|
||||
Request: string(csr.Spec.Request),
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user