Skip to content

Commit

Permalink
implement SelfSignedCertProvisioner
Browse files Browse the repository at this point in the history
  • Loading branch information
Mengqi Yu committed Jun 6, 2018
1 parent fea9e3a commit f79791f
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Package certprovisioner provides an interface and implementation to provision ce
Create a implementation instance of certprovisioner.
cp := SelfSignedCertProvisioner{
// your configuration
CommonName: "foo.bar.com"
}
Provision the certificates.
Expand Down
68 changes: 68 additions & 0 deletions pkg/webhook/certprovisioner/selfsignedcertprovisioner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright 2018 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 certprovisioner

import (
"crypto/x509"
"fmt"

"k8s.io/client-go/util/cert"
)

// SelfSignedCertProvisioner implements the CertProvisioner interface.
// It provisions self-signed certificates.
type SelfSignedCertProvisioner struct {
// Required Common Name
CommonName string
}

var _ CertProvisioner = &SelfSignedCertProvisioner{}

// ProvisionServingCert creates and returns a CA certificate and certificate and
// key for the server. serverKey and serverCert are used by the server
// to establish trust for clients, CA certificate is used by the
// client to verify the server authentication chain.
// The cert will be valid for 365 days.
func (cp *SelfSignedCertProvisioner) ProvisionServingCert() (serverKey, serverCert, caCert []byte, err error) {
signingKey, err := cert.NewPrivateKey()
if err != nil {
return nil, nil, nil,
fmt.Errorf("failed to create the CA private key: %v", err)
}
signingCert, err := cert.NewSelfSignedCACert(cert.Config{CommonName: "webhook-cert-ca"}, signingKey)
if err != nil {
return nil, nil, nil,
fmt.Errorf("failed to create the CA cert: %v", err)
}
key, err := cert.NewPrivateKey()
if err != nil {
return nil, nil, nil,
fmt.Errorf("failed to create the private key: %v", err)
}
signedCert, err := cert.NewSignedCert(
cert.Config{
CommonName: cp.CommonName,
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
},
key, signingCert, signingKey,
)
if err != nil {
return nil, nil, nil,
fmt.Errorf("failed to create the cert: %v", err)
}
return cert.EncodePrivateKeyPEM(key), cert.EncodeCertPEM(signedCert), cert.EncodeCertPEM(signingCert), nil
}
56 changes: 56 additions & 0 deletions pkg/webhook/certprovisioner/selfsignedcertprovisioner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
Copyright 2018 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 certprovisioner

import (
"crypto/x509"
"encoding/pem"
"testing"
)

func TestProvisionServingCert(t *testing.T) {
CN := "mysvc.myns.svc"
cp := SelfSignedCertProvisioner{CommonName: CN}
_, certPEM, caPEM, err := cp.ProvisionServingCert()

// First, create the set of root certificates. For this example we only
// have one. It's also possible to omit this in order to use the
// default root set of the current operating system.
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM([]byte(caPEM))
if !ok {
t.Fatalf("failed to parse root certificate: %s", caPEM)
}

block, _ := pem.Decode(certPEM)
if block == nil {
t.Fatalf("failed to parse certificate PEM: %s", certPEM)
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
t.Fatalf("failed to parse certificate: %v", err)
}

opts := x509.VerifyOptions{
DNSName: CN,
Roots: roots,
}

if _, err := cert.Verify(opts); err != nil {
t.Fatalf("failed to verify certificate: %v", err)
}
}
30 changes: 0 additions & 30 deletions pkg/webhook/internal/certprovisioner/example_test.go

This file was deleted.

36 changes: 0 additions & 36 deletions pkg/webhook/internal/certprovisioner/selfsignedcertprovisioner.go

This file was deleted.

0 comments on commit f79791f

Please sign in to comment.